From 1055cee83232e7beb7cadb7cd3b327b158a27846 Mon Sep 17 00:00:00 2001 From: pettershao-ragilenetworks Date: Mon, 27 Mar 2023 04:36:50 -0400 Subject: [PATCH 1/4] [Platform/Ragile] Adapt kernel 5.10 for broadcom Signed-off-by: pettershao-ragilenetworks --- .../td3-ra-b6510-32c-32x100G.config.bcm | 31 +- .../x86_64-ragile_ra-b6510-32c-r0/dev.xml | 535 ++- .../dev_exhaust.xml | 431 +++ .../x86_64-ragile_ra-b6510-32c-r0/fru.py | 115 +- .../installer.conf | 1 - .../x86_64-ragile_ra-b6510-32c-r0/monitor.py | 419 +- .../x86_64-ragile_ra-b6510-32c-r0/pcie.yaml | 440 +++ .../plugins/sfputil.py | 145 +- .../plugins/ssd_util.py | 309 ++ .../system_health_monitoring_config.json | 0 .../RA-B6510-48V8C/port_config.ini | 114 +- .../RA-B6510-48V8C/sai.profile | 2 +- ...d3-ra-b6510-48v8c-48x25G+8x100G.config.bcm | 602 +++ .../custom_led.bin | Bin 300 -> 236 bytes .../x86_64-ragile_ra-b6510-48v8c-r0/dev.xml | 508 ++- .../dev_exhaust.xml | 418 ++ .../x86_64-ragile_ra-b6510-48v8c-r0/fru.py | 961 +++++ .../monitor.py | 376 +- .../x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml | 21 +- .../plugins/sfputil.py | 243 ++ .../plugins/ssd_util.py | 309 ++ .../pmon_daemon_control.json | 8 +- .../system_health_monitoring_config.json | 0 .../th2-ra-b6910-64c-64x100G.config.bcm | 5 + .../x86_64-ragile_ra-b6910-64c-r0/dev.xml | 178 +- .../x86_64-ragile_ra-b6910-64c-r0/fantlv.py | 192 + .../x86_64-ragile_ra-b6910-64c-r0/fru.py | 961 +++++ .../x86_64-ragile_ra-b6910-64c-r0/monitor.py | 445 ++- .../plugins/sfputil.py | 390 +- .../plugins/ssd_util.py | 309 ++ .../pmon_daemon_control.json | 6 +- .../system_health_monitoring_config.json | 0 .../RA-B6920-4S/cust_plp.cfg | 843 +++++ .../th3-ra-b6920-4s-128x100G.config.bcm | 233 +- .../x86_64-ragile_ra-b6920-4s-r0/dev.xml | 734 +++- .../x86_64-ragile_ra-b6920-4s-r0/fru.py | 961 +++++ .../x86_64-ragile_ra-b6920-4s-r0/monitor.py | 416 +- .../x86_64-ragile_ra-b6920-4s-r0/pcie.yaml | 441 +++ .../plugins/sfputil.py | 149 +- .../plugins/ssd_util.py | 277 +- .../system_health_monitoring_config.json | 0 platform/broadcom/platform-modules-ragile.mk | 2 +- platform/broadcom/rules.mk | 2 +- .../sonic-platform-modules-ragile/LICENSE | 1 - .../common/Makefile | 27 +- .../common/app/Makefile | 25 + .../common/app/dev_util/Makefile | 30 + .../common/app/dev_util/dfd_debug.c | 43 + .../common/app/dev_util/dfd_utest.c | 1802 +++++++++ .../common/app/dev_util/dfd_utest.h | 103 + .../common/app/firmware_upgrade/Makefile | 19 + .../common/app/firmware_upgrade/Rules.mk | 42 + .../firmware_upgrade/firmware_driver/Makefile | 19 + .../firmware_driver_cpld/Makefile | 23 + .../firmware_driver_cpld/firmware.c | 144 + .../firmware_driver_cpld/firmware_cpld.c | 384 ++ .../firmware_cpld_upgrade.c | 1879 +++++++++ .../firmware_driver_cpld/include/firmware.h | 82 + .../include/firmware_cpld.h | 64 + .../firmware_driver_cpld/include/jbi.h | 15 + .../firmware_driver_cpld/jbicomp.c | 438 +++ .../firmware_driver_cpld/jbicomp.h | 37 + .../firmware_driver_cpld/jbiexprt.h | 224 ++ .../firmware_driver_cpld/jbijtag.c | 1679 ++++++++ .../firmware_driver_cpld/jbijtag.h | 146 + .../firmware_driver_cpld/jbimain.c | 3362 +++++++++++++++++ .../firmware_driver_cpld/jbiport.h | 45 + .../firmware_driver_cpld/jbistub.c | 2518 ++++++++++++ .../firmware_driver_cpld/jbistub.h | 95 + .../firmware_driver_ispvme/Makefile | 22 + .../firmware_cpld_ispvme.c | 450 +++ .../firmware_cpld_upgrade_ispvme.c | 691 ++++ .../firmware_driver_ispvme/firmware_ispvme.c | 140 + .../include/firmware_cpld_ispvme.h | 70 + .../include/firmware_ispvme.h | 86 + .../firmware_driver_sysfs/Makefile | 22 + .../firmware_driver_sysfs/firmware.c | 143 + .../firmware_driver_sysfs/firmware_sysfs.c | 495 +++ .../firmware_sysfs_upgrade.c | 258 ++ .../include/firmware_sysfs.h | 88 + .../include/firmware_sysfs_upgrade.h | 72 + .../include/firmware_upgrade.h | 57 + .../firmware_upgrade/Makefile | 33 + .../firmware_upgrade/firmware_upgrade/crc32.c | 216 ++ .../firmware_upgrade/firmware_upgrade/debug.c | 60 + .../firmware_upgrade/firmware_app.c | 985 +++++ .../fw_upg_gpio_vme/hardware.c | 263 ++ .../fw_upg_gpio_vme/ispvm_ui.c | 837 ++++ .../fw_upg_gpio_vme/ivm_core.c | 3097 +++++++++++++++ .../fw_upg_isc/firmware_upgrade_isc.c | 68 + .../fw_upg_mtd/firmware_upgrade_mtd.c | 446 +++ .../fw_upg_mtd/firmware_upgrade_mtd.h | 32 + .../firmware_upgrade/fw_upg_mtd/mtd-abi.h | 259 ++ .../fw_upg_sysfs/firmware_upgrade_sysfs.c | 285 ++ .../fw_upg_sysfs/firmware_upgrade_sysfs.h | 16 + .../fw_upg_sysfs/fw_upg_spi_logic_dev.c | 1181 ++++++ .../fw_upg_sysfs/fw_upg_spi_logic_dev.h | 90 + .../firmware_upgrade/include/debug.h | 34 + .../firmware_upgrade/include/firmware_app.h | 172 + .../firmware_upgrade/include/vmopcode.h | 192 + .../common/app/fw_upgrade/Makefile | 18 + .../common/app/fw_upgrade/Rules.mk | 42 + .../common/app/fw_upgrade/fw_upgrade/Makefile | 39 + .../app/fw_upgrade/fw_upgrade/fw_upgrade.c | 1632 ++++++++ .../fw_upgrade/fw_upgrade/fw_upgrade_debug.c | 51 + .../fw_upgrade/include/fw_upgrade.h | 230 ++ .../fw_upgrade/include/fw_upgrade_debug.h | 25 + .../common/lib/algorithm/__init__.py | 0 .../common/lib/algorithm/hysteresis.py | 169 + .../common/lib/algorithm/openloop.py | 104 + .../common/lib/algorithm/pid.py | 106 + .../common/lib/eepromutil/fantlv.py | 76 +- .../common/lib/eepromutil/fru.py | 121 +- .../common/lib/eepromutil/onietlv.py | 441 +++ .../common/lib/plat_hal/__init__.py | 0 .../common/lib/plat_hal/baseutil.py | 164 + .../common/lib/plat_hal/chassisbase.py | 318 ++ .../common/lib/plat_hal/component.py | 33 + .../common/lib/plat_hal/cpld.py | 66 + .../common/lib/plat_hal/cpu.py | 34 + .../common/lib/plat_hal/dcdc.py | 11 + .../common/lib/plat_hal/devicebase.py | 355 ++ .../common/lib/plat_hal/fan.py | 413 ++ .../common/lib/plat_hal/interface.py | 1311 +++++++ .../common/lib/plat_hal/led.py | 52 + .../common/lib/plat_hal/onie_e2.py | 127 + .../common/lib/plat_hal/osutil.py | 440 +++ .../common/lib/plat_hal/psu.py | 607 +++ .../common/lib/plat_hal/rotor.py | 149 + .../common/lib/plat_hal/sensor.py | 219 ++ .../common/lib/plat_hal/temp.py | 139 + .../common/lib/wbutil/__init__.py | 0 .../common/lib/wbutil/baseutil.py | 38 + .../common/lib/wbutil/smbus.py | 772 ++++ .../kernel_drivers_blacklist.conf | 5 + .../common/modules/Makefile | 70 +- .../common/modules/dfd_tlveeprom.c | 516 +++ .../common/modules/dfd_tlveeprom.h | 121 + .../common/modules/fpga_i2c.h | 133 + .../common/modules/intel_spi/Makefile | 21 + .../modules/intel_spi/include/intel_spi.h | 23 + .../common/modules/intel_spi/intel_spi.c | 969 +++++ .../modules/intel_spi/intel_spi_platform.c | 167 + .../common/modules/linux-5.10/Makefile | 34 + .../common/modules/linux-5.10/wb_at24.c | 861 +++++ .../common/modules/linux-5.10/wb_csu550.c | 238 ++ .../modules/linux-5.10/wb_i2c_algo_bit.c | 725 ++++ .../common/modules/linux-5.10/wb_i2c_gpio.c | 431 +++ .../modules/linux-5.10/wb_i2c_gpio_device.c | 110 + .../common/modules/linux-5.10/wb_i2c_i801.c | 2114 +++++++++++ .../modules/linux-5.10/wb_i2c_mux_pca954x.c | 1343 +++++++ .../modules/linux-5.10/wb_i2c_mux_pca954x.h | 67 + .../modules/linux-5.10/wb_i2c_mux_pca9641.c | 1375 +++++++ .../modules/linux-5.10/wb_i2c_mux_pca9641.h | 64 + .../common/modules/linux-5.10/wb_ina3221.c | 1031 +++++ .../common/modules/linux-5.10/wb_isl68137.c | 572 +++ .../common/modules/linux-5.10/wb_lm75.c | 987 +++++ .../common/modules/linux-5.10/wb_lm75.h | 40 + .../common/modules/linux-5.10/wb_pmbus.h | 535 +++ .../common/modules/linux-5.10/wb_pmbus_core.c | 2780 ++++++++++++++ .../common/modules/linux-5.10/wb_tmp401.c | 798 ++++ .../common/modules/linux-5.10/wb_tps53622.c | 265 ++ .../common/modules/linux-5.10/wb_ucd9000.c | 675 ++++ .../common/modules/plat_sysfs/Makefile | 20 + .../modules/plat_sysfs/dev_cfg/Makefile | 25 + .../modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c | 812 ++++ .../plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c | 351 ++ .../plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c | 236 ++ .../plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c | 587 +++ .../plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c | 82 + .../plat_sysfs/dev_cfg/dfd_fan_driver.c | 170 + .../modules/plat_sysfs/dev_cfg/dfd_module.c | 95 + .../plat_sysfs/dev_cfg/dfd_psu_driver.c | 70 + .../plat_sysfs/dev_cfg/dfd_sensors_driver.c | 149 + .../plat_sysfs/dev_cfg/dfd_sff_driver.c | 56 + .../plat_sysfs/dev_cfg/dfd_slot_driver.c | 27 + .../plat_sysfs/dev_cfg/include/dfd_cfg.h | 97 + .../dev_cfg/include/dfd_cfg_adapter.h | 46 + .../plat_sysfs/dev_cfg/include/dfd_cfg_file.h | 37 + .../plat_sysfs/dev_cfg/include/dfd_cfg_info.h | 109 + .../dev_cfg/include/dfd_cfg_listnode.h | 30 + .../dev_cfg/include/dfd_fan_driver.h | 18 + .../plat_sysfs/dev_cfg/include/dfd_module.h | 96 + .../dev_cfg/include/dfd_psu_driver.h | 10 + .../dev_cfg/include/dfd_sensors_driver.h | 10 + .../dev_cfg/include/dfd_sff_driver.h | 8 + .../dev_cfg/include/dfd_slot_driver.h | 6 + .../modules/plat_sysfs/dev_sysfs/Makefile | 21 + .../dev_sysfs/include/plat_switch.h | 86 + .../dev_sysfs/include/sysfs_common.h | 90 + .../modules/plat_sysfs/dev_sysfs/plat_fan.c | 505 +++ .../modules/plat_sysfs/dev_sysfs/plat_psu.c | 430 +++ .../plat_sysfs/dev_sysfs/plat_sensor.c | 457 +++ .../modules/plat_sysfs/dev_sysfs/plat_sff.c | 291 ++ .../modules/plat_sysfs/dev_sysfs/plat_slot.c | 667 ++++ .../plat_sysfs/dev_sysfs/plat_switch.c | 135 + .../common/modules/platform_common.h | 74 + .../common/modules/platform_common_module.c | 210 + .../common/modules/spi-bitbang-txrx.h | 107 + .../common/modules/wb_eeprom_93xx46.c | 558 +++ .../common/modules/wb_fpga_i2c_bus_drv.c | 1103 ++++++ .../common/modules/wb_fpga_pca954x_drv.c | 525 +++ .../common/modules/wb_fpga_pcie.c | 164 + .../common/modules/wb_gpio_d1500.c | 367 ++ .../common/modules/wb_gpio_device.c | 54 + .../common/modules/wb_i2c_dev.c | 774 ++++ .../common/modules/wb_i2c_dev.h | 20 + .../common/modules/wb_i2c_ocores.c | 1143 ++++++ .../common/modules/wb_i2c_ocores.h | 28 + .../common/modules/wb_io_dev.c | 571 +++ .../common/modules/wb_io_dev.h | 21 + .../common/modules/wb_lpc_drv.c | 166 + .../common/modules/wb_lpc_drv.h | 18 + .../common/modules/wb_mac_bsc.c | 660 ++++ .../common/modules/wb_optoe.c | 1192 ++++++ .../common/modules/wb_pcie_dev.c | 770 ++++ .../common/modules/wb_pcie_dev.h | 26 + .../common/modules/wb_platform_i2c_dev.c | 749 ++++ .../common/modules/wb_platform_i2c_dev.h | 19 + .../common/modules/wb_spi_93xx46.c | 111 + .../common/modules/wb_spi_dev.c | 583 +++ .../common/modules/wb_spi_dev.h | 16 + .../common/modules/wb_spi_gpio.c | 477 +++ .../common/modules/wb_spi_gpio_device.c | 153 + .../common/modules/wb_spi_nor_device.c | 87 + .../common/modules/wb_spi_ocores.c | 1025 +++++ .../common/modules/wb_spi_ocores.h | 21 + .../common/modules/wb_uio_irq.c | 282 ++ .../common/modules/wb_wdt.c | 1038 +++++ .../common/modules/wb_wdt.h | 46 + .../common/modules/wb_xdpe132g5c.c | 574 +++ .../common/script/auto_update.py | 196 + .../common/script/avscontrol.py | 236 +- .../common/script/dev_monitor.py | 303 ++ .../common/script/generate_airflow.py | 236 ++ .../common/script/hal_fanctrl.py | 1135 ++++++ .../common/script/hal_ledctrl.py | 830 ++++ .../common/script/hal_pltfm.py | 475 +++ .../common/script/intelligent_monitor.py | 144 + .../script/intelligent_monitor/monitor_fan.py | 284 ++ .../common/script/platform_common.py | 178 + .../common/script/platform_config.py | 184 + .../common/script/platform_driver.py | 258 ++ .../common/script/platform_e2.py | 434 +++ .../common/script/platform_intf.py | 367 ++ .../common/script/platform_ipmi.py | 92 + .../common/script/platform_manufacturer.py | 591 +++ .../common/script/platform_process.py | 396 ++ .../common/script/platform_sensors.py | 253 ++ .../common/script/platform_test.py | 142 + .../common/script/platform_util.py | 845 +++++ .../common/script/pmon_syslog.py | 519 +++ .../common/script/reboot_cause.py | 183 + .../common/script/reboot_ctrl.py | 150 + .../common/script/sensors | 8 + .../common/script/sfp_highest_temperatue.py | 148 + .../common/script/slot_monitor.py | 242 ++ .../common/script/ssdmon | 82 + .../common/script/tty_console.py | 91 + .../common/script/upgrade.py | 991 +++++ .../common/script/warm_upgrade.py | 514 +++ .../common/service/platform_driver.service | 15 + .../common/service/platform_process.service | 15 + .../common/sonic_platform/__init__.py | 2 + .../common/sonic_platform/chassis.py | 520 +++ .../common/sonic_platform/component.py | 211 ++ .../common/sonic_platform/dcdc.py | 85 + .../common/sonic_platform/eeprom.py | 92 + .../common/sonic_platform/fan.py | 308 ++ .../common/sonic_platform/fan_drawer.py | 167 + .../common/sonic_platform/pcie.py | 21 + .../common/sonic_platform/platform.py | 24 + .../common/sonic_platform/psu.py | 359 ++ .../common/sonic_platform/sfp.py | 480 +++ .../common/sonic_platform/thermal.py | 234 ++ .../common/sonic_platform/watchdog.py | 236 ++ .../debian/compat | 2 +- .../debian/control | 6 +- .../debian/copyright | 1 - ...form-modules-ragile-ra-b6510-48v8c.install | 2 +- ...orm-modules-ragile-ra-b6510-48v8c.postinst | 7 - ...latform-modules-ragile-ra-b6920-4s.install | 2 +- .../debian/rules | 63 +- .../.upgrade_test/cpld_test_header.vme | Bin 0 -> 413 bytes .../.upgrade_test/fpga_test_header.bin | 10 + .../ra-b6510-32c/Makefile | 16 +- .../x86_64_ragile_ra_b6510_32c_r0_config.py | 1288 +++++-- ...6_64_ragile_ra_b6510_32c_r0_port_config.py | 7 + .../x86_64_ragile_ra_b6510_32c_r0_device.py | 1241 ++++++ ...4_ragile_ra_b6510_32c_r0_exhaust_device.py | 1240 ++++++ .../x86_64_ragile_ra_b6510_32c_r0_monitor.py | 150 + .../ra-b6510-32c/modules/driver/Makefile | 19 +- .../driver/wb_firmware_upgrade_device.c | 178 + .../modules/driver/wb_i2c_dev_device.c | 125 + .../driver/wb_i2c_mux_pca954x_device.c | 224 ++ .../modules/driver/wb_i2c_ocores_device.c | 423 +++ .../modules/driver/wb_io_dev_device.c | 103 + .../modules/driver/wb_lpc_drv_device.c | 130 + .../modules/driver/wb_pcie_dev_device.c | 93 + .../plat_sysfs_cfg/WB_PLAT_CPLD.cfg | 38 + .../plat_sysfs_cfg/WB_PLAT_FAN.cfg | 372 ++ .../plat_sysfs_cfg/WB_PLAT_PSU.cfg | 64 + .../plat_sysfs_cfg/WB_PLAT_SFF.cfg | 306 ++ .../ra-b6510-32c/plat_sysfs_cfg/cfg_file_name | 4 + .../ra-b6510-32c/setup.py | 18 +- .../.upgrade_test/cpld_test_header.vme | Bin 0 -> 406 bytes .../.upgrade_test/fpga_test_header.bin | 10 + .../ra-b6510-48v8c/Makefile | 15 +- .../x86_64_ragile_ra_b6510_48v8c_r0_config.py | 1481 +++++--- ...64_ragile_ra_b6510_48v8c_r0_port_config.py | 7 + .../x86_64_ragile_ra_b6510_48v8c_r0_device.py | 1212 ++++++ ...ragile_ra_b6510_48v8c_r0_exhaust_device.py | 1211 ++++++ ...x86_64_ragile_ra_b6510_48v8c_r0_monitor.py | 204 + .../ra-b6510-48v8c/modules/driver/Makefile | 16 +- .../driver/wb_firmware_upgrade_device.c | 178 + .../modules/driver/wb_i2c_dev_device.c | 140 + .../driver/wb_i2c_mux_pca954x_device.c | 296 ++ .../modules/driver/wb_i2c_ocores_device.c | 423 +++ .../modules/driver/wb_io_dev_device.c | 103 + .../modules/driver/wb_lpc_drv_device.c | 130 + .../modules/driver/wb_pcie_dev_device.c | 93 + .../plat_sysfs_cfg/WB_PLAT_CPLD.cfg | 41 + .../plat_sysfs_cfg/WB_PLAT_FAN.cfg | 304 ++ .../plat_sysfs_cfg/WB_PLAT_PSU.cfg | 64 + .../plat_sysfs_cfg/WB_PLAT_SFF.cfg | 521 +++ .../plat_sysfs_cfg/cfg_file_name | 4 + .../ra-b6510-48v8c/setup.py | 18 +- .../.upgrade_test/cpld_test_header.vme | Bin 0 -> 357 bytes .../ra-b6910-64c/Makefile | 15 +- .../x86_64_ragile_ra_b6910_64c_r0_config.py | 1169 ++++-- ...6_64_ragile_ra_b6910_64c_r0_port_config.py | 7 + .../x86_64_ragile_ra_b6910_64c_r0_device.py | 700 ++++ .../x86_64_ragile_ra_b6910_64c_r0_monitor.py | 115 + .../ra-b6910-64c/modules/driver/Makefile | 15 +- .../modules/driver/platform_common.h | 113 + .../driver/wb_firmware_upgrade_device.c | 155 + .../driver/wb_i2c_mux_pca954x_device.c | 278 ++ .../driver/wb_i2c_mux_pca9641_device.c | 99 + .../modules/driver/wb_io_dev_device.c | 88 + .../modules/driver/wb_lpc_drv_device.c | 92 + .../driver/wb_platform_i2c_dev_device.c | 199 + .../plat_sysfs_cfg/WB_PLAT_CPLD.cfg | 48 + .../plat_sysfs_cfg/WB_PLAT_FAN.cfg | 145 + .../plat_sysfs_cfg/WB_PLAT_PSU.cfg | 64 + .../plat_sysfs_cfg/WB_PLAT_SENSOR.cfg | 225 ++ .../plat_sysfs_cfg/WB_PLAT_SFF.cfg | 592 +++ .../ra-b6910-64c/plat_sysfs_cfg/cfg_file_name | 5 + .../ra-b6910-64c/setup.py | 19 +- .../.upgrade_test/board_cpld_test_header.vme | Bin 0 -> 470 bytes .../.upgrade_test/slot_cpld_test_header.vme | Bin 0 -> 316 bytes .../ra-b6920-4s/Makefile | 16 +- .../x86_64_ragile_ra_b6920_4s_r0_config.py | 2075 +++++++--- ...86_64_ragile_ra_b6920_4s_r0_port_config.py | 7 + .../x86_64_ragile_ra_b6920_4s_r0_device.py | 1247 ++++++ .../x86_64_ragile_ra_b6920_4s_r0_monitor.py | 113 + .../ra-b6920-4s/modules/driver/Makefile | 22 +- .../modules/driver/platform_common.h | 113 + .../driver/wb_firmware_upgrade_device.c | 243 ++ .../driver/wb_i2c_mux_pca954x_device.c | 632 ++++ .../modules/driver/wb_i2c_ocores_device.c | 178 + .../modules/driver/wb_io_dev_device.c | 118 + .../modules/driver/wb_lpc_drv_device.c | 130 + .../driver/wb_platform_i2c_dev_device.c | 263 ++ .../plat_sysfs_cfg/WB_PLAT_CPLD.cfg | 61 + .../plat_sysfs_cfg/WB_PLAT_FAN.cfg | 440 +++ .../plat_sysfs_cfg/WB_PLAT_PSU.cfg | 118 + .../plat_sysfs_cfg/WB_PLAT_SENSOR.cfg | 365 ++ .../plat_sysfs_cfg/WB_PLAT_SFF.cfg | 1169 ++++++ .../plat_sysfs_cfg/WB_PLAT_SLOT.cfg | 1316 +++++++ .../ra-b6920-4s/plat_sysfs_cfg/cfg_file_name | 6 + .../ra-b6920-4s/setup.py | 18 +- src/sonic-device-data/tests/permitted_list | 6 + 372 files changed, 116660 insertions(+), 3589 deletions(-) create mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev_exhaust.xml create mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/pcie.yaml create mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py create mode 100755 device/ragile/x86_64-ragile_ra-b6510-32c-r0/system_health_monitoring_config.json create mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm mode change 100755 => 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml create mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev_exhaust.xml create mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/fru.py mode change 100755 => 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py create mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/sfputil.py create mode 100755 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/ssd_util.py create mode 100755 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/system_health_monitoring_config.json create mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/fantlv.py create mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/fru.py create mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/plugins/ssd_util.py create mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/system_health_monitoring_config.json create mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/RA-B6920-4S/cust_plp.cfg create mode 100755 device/ragile/x86_64-ragile_ra-b6920-4s-r0/fru.py create mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/pcie.yaml create mode 100755 device/ragile/x86_64-ragile_ra-b6920-4s-r0/system_health_monitoring_config.json mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-ragile/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_debug.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Rules.mk create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld_upgrade.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware_cpld.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/jbi.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiexprt.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbimain.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiport.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_ispvme.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_upgrade_ispvme.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_ispvme.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_cpld_ispvme.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_ispvme.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs_upgrade.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs_upgrade.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/include/firmware_upgrade.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/crc32.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/debug.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/firmware_app.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/hardware.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ispvm_ui.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ivm_core.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_isc/firmware_upgrade_isc.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/mtd-abi.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/debug.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/firmware_app.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/vmopcode.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Rules.mk create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/hysteresis.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/openloop.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/pid.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/onietlv.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/baseutil.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/chassisbase.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/component.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpld.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpu.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/dcdc.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/devicebase.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/interface.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/led.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/onie_e2.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/osutil.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/rotor.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/sensor.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/temp.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/baseutil.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/smbus.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modprobe_conf/kernel_drivers_blacklist.conf mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/include/intel_spi.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi_platform.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_at24.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_csu550.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_algo_bit.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_i801.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ina3221.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_isl68137.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus_core.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tmp401.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tps53622.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ucd9000.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_module.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_fan.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sff.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_slot.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_switch.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common_module.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/spi-bitbang-txrx.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_eeprom_93xx46.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_i2c_bus_drv.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pca954x_drv.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pcie.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_d1500.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_mac_bsc.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_optoe.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_93xx46.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_nor_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_uio_irq.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_xdpe132g5c.c create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/auto_update.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/dev_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/generate_airflow.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/hal_fanctrl.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/hal_ledctrl.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/hal_pltfm.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor/monitor_fan.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_common.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_config.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_driver.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_e2.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_intf.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_ipmi.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_manufacturer.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_process.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_test.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_util.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/pmon_syslog.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_cause.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_ctrl.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/sensors create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/sfp_highest_temperatue.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/slot_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/ssdmon create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/tty_console.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/upgrade.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/warm_upgrade.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/service/platform_driver.service create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/service/platform_process.service create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/dcdc.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan_drawer.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/pcie.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/thermal.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/watchdog.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/.upgrade_test/cpld_test_header.vme create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/.upgrade_test/fpga_test_header.bin mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/config/x86_64_ragile_ra_b6510_32c_r0_port_config.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/hal-config/x86_64_ragile_ra_b6510_32c_r0_device.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/hal-config/x86_64_ragile_ra_b6510_32c_r0_exhaust_device.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/hal-config/x86_64_ragile_ra_b6510_32c_r0_monitor.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_ocores_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_io_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_lpc_drv_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_pcie_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_PSU.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_SFF.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/cfg_file_name create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/cpld_test_header.vme create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/fpga_test_header.bin mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_port_config.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_device.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_exhaust_device.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_monitor.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_ocores_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_io_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_lpc_drv_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_pcie_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_PSU.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_SFF.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/cfg_file_name create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/.upgrade_test/cpld_test_header.vme create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/config/x86_64_ragile_ra_b6910_64c_r0_port_config.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/hal-config/x86_64_ragile_ra_b6910_64c_r0_device.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/hal-config/x86_64_ragile_ra_b6910_64c_r0_monitor.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/platform_common.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca9641_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_io_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_lpc_drv_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_platform_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_PSU.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SFF.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/cfg_file_name mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/.upgrade_test/board_cpld_test_header.vme create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/.upgrade_test/slot_cpld_test_header.vme create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_port_config.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_device.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_monitor.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/platform_common.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_ocores_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_io_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_lpc_drv_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_platform_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_PSU.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SFF.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SLOT.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/cfg_file_name mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/RA-B6510-32C/td3-ra-b6510-32c-32x100G.config.bcm b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/RA-B6510-32C/td3-ra-b6510-32c-32x100G.config.bcm index 30780ab6ec71..c81f3b6f3310 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/RA-B6510-32C/td3-ra-b6510-32c-32x100G.config.bcm +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/RA-B6510-32C/td3-ra-b6510-32c-32x100G.config.bcm @@ -5,6 +5,8 @@ l3_alpm_enable=2 ipv6_lpm_128b_enable=0x1 l2xmsg_mode=0 l3_max_ecmp_mode=1 +svi_my_station_optimization=1 +sai_nbr_bcast_ifp_optimized=2 bcm_num_cos=8 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 @@ -447,7 +449,32 @@ serdes_if_type_127=14 serdes_if_type_123=14 reglist_enable=1 -scache_filename=/tmp/scache +scache_filename=/var/warmboot/wbscache schan_intr_enable=0 -stable_size=0x5500000 +stable_size=0x55000000 +stable_location=3 +warmboot_knet_shutdown_mode=1 tdma_timeout_usec=3000000 + +#vxlan flex flow mode +flow_init_mode=1 + +riot_enable=1 +riot_overlay_l3_intf_mem_size=4096 +riot_overlay_l3_egress_mem_size=32768 +riot_overlay_ecmp_resilient_hash_size=16384 + +l3_ecmp_levels=2 + +use_all_splithorizon_groups=1 +sai_tunnel_support=1 + +#This property allows to enable L2 FDB entry to discard based on Source Mac +sai_fdb_entry_l2_discard_src_enable=1 + +#RDMA +sai_pfc_defaults_disable=1 +sai_optimized_mmu=1 + +#ACL wb count +ctr_evict_enable=0 \ No newline at end of file diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev.xml b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev.xml index 7438d26a39c7..66bc7a92f7fc 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev.xml +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev.xml @@ -7,130 +7,425 @@ --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev_exhaust.xml b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev_exhaust.xml new file mode 100644 index 000000000000..779bbeecd952 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev_exhaust.xml @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/fru.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/fru.py index 3f1bef50af25..f95164e03601 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/fru.py +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/fru.py @@ -1,15 +1,14 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- +#!/usr/bin/python3 import collections -from bitarray import bitarray from datetime import datetime, timedelta -import sys +from bitarray import bitarray + __DEBUG__ = "N" class FruException(Exception): - def __init__(self, message='fruerror', code=-100): + def __init__(self, message='fruerror', code=-100): err = 'errcode: {0} message:{1}'.format(code, message) Exception.__init__(self, err) self.code = code @@ -21,7 +20,7 @@ def e_print(err): def d_print(debug_info): - if(__DEBUG__ == "Y"): + if __DEBUG__ == "Y": print(debug_info) @@ -40,7 +39,7 @@ def minToData(): starttime = datetime(1996, 1, 1, 0, 0, 0) endtime = datetime.now() seconds = (endtime - starttime).total_seconds() - mins = seconds / 60 + mins = seconds // 60 m = int(round(mins)) return m @@ -50,7 +49,7 @@ def getTimeFormat(): @staticmethod def getTypeLength(value): - if value is None: + if value is None or len(value) == 0: return 0 a = bitarray(8) a.setall(False) @@ -62,8 +61,8 @@ def getTypeLength(value): @staticmethod def checksum(b): result = 0 - for i in range(len(b)): - result += ord(b[i]) + for item in b: + result += ord(item) return (0x100 - (result & 0xff)) & 0xff @@ -86,7 +85,6 @@ def __init__(self, name="", size=0, offset=0): self._size = size self._isPresent = False self._data = b'\x00' * size - self.__dataoffset = 0 @property def childList(self): @@ -141,6 +139,9 @@ class BoardInfoArea(BaseArea): _boardTime = None _fields = None _mfg_date = None + areaversion = None + _boardversion = None + _language = None def __str__(self): formatstr = "version : %x\n" \ @@ -227,7 +228,6 @@ def decodedata(self): index += templen + 1 d_print("decode fruFileId:%s" % self.fruFileId) - for i in range(1, 11): valtmp = "boardextra%d" % i if self.data[index] != chr(0xc1): @@ -239,6 +239,11 @@ def decodedata(self): else: break + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + def recalcute(self): d_print("boardInfoArea version:%x" % ord(self.boardversion)) d_print("boardInfoArea length:%d" % self.size) @@ -247,7 +252,7 @@ def recalcute(self): d_print("boardInfoArea mfg_date:%x" % self.mfg_date) self.data = chr(ord(self.boardversion)) + \ - chr(self.size / 8) + chr(self.language) + chr(self.size // 8) + chr(self.language) self.data += chr(self.mfg_date & 0xFF) self.data += chr((self.mfg_date >> 8) & 0xFF) @@ -280,9 +285,7 @@ def recalcute(self): valtmpval = getattr(self, valtmp) d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) self.data += chr(FruUtil.getTypeLength(valtmpval)) - if valtmpval is None: - pass - else: + if valtmpval is not None: self.data += valtmpval else: break @@ -290,14 +293,14 @@ def recalcute(self): self.data += chr(0xc1) if len(self.data) > (self.size - 1): - incr = (len(self.data) - self.size) / 8 + 1 + incr = (len(self.data) - self.size) // 8 + 1 self.size += incr * 8 - self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:] + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] d_print("self data:%d" % len(self.data)) d_print("self size:%d" % self.size) d_print("adjust size:%d" % (self.size - len(self.data) - 1)) - self.data = self.data.ljust((self.size - 1), self.INITVALUE) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) # checksum checksum = FruUtil.checksum(self.data) @@ -388,6 +391,7 @@ class ProductInfoArea(BaseArea): _productManufacturer = None _productAssetTag = None _FRUFileID = None + _language = None def __str__(self): formatstr = "version : %x\n" \ @@ -564,12 +568,17 @@ def fruFileId(self): def fruFileId(self, name): self._FRUFileID = name + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + def recalcute(self): d_print("product version:%x" % ord(self.areaversion)) d_print("product length:%d" % self.size) d_print("product language:%x" % self.language) self.data = chr(ord(self.areaversion)) + \ - chr(self.size / 8) + chr(self.language) + chr(self.size // 8) + chr(self.language) typelength = FruUtil.getTypeLength(self.productManufacturer) self.data += chr(typelength) @@ -600,22 +609,20 @@ def recalcute(self): valtmpval = getattr(self, valtmp) d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) self.data += chr(FruUtil.getTypeLength(valtmpval)) - if valtmpval is None: - pass - else: + if valtmpval is not None: self.data += valtmpval else: break self.data += chr(0xc1) if len(self.data) > (self.size - 1): - incr = (len(self.data) - self.size) / 8 + 1 + incr = (len(self.data) - self.size) // 8 + 1 self.size += incr * 8 d_print("self.data:%d" % len(self.data)) d_print("self.size:%d" % self.size) - self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:] - self.data = self.data.ljust((self.size - 1), self.INITVALUE) + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) checksum = FruUtil.checksum(self.data) d_print("board info checksum:%x" % checksum) self.data += chr(checksum) @@ -631,17 +638,13 @@ def __init__(self, fieldType="ASCII", fieldData=""): self.fieldData = fieldData self.fieldType = fieldType - @property - def data(self): - return self._data - @property def fieldType(self): - return self._fieldType + return self.fieldType @property def fieldData(self): - return self._fieldData + return self.fieldData class ipmifru(BaseArea): @@ -659,6 +662,7 @@ class ipmifru(BaseArea): _bodybin = None _version = BaseArea.COMMON_HEAD_VERSION _zeroCheckSum = None + _frusize = 256 def __str__(self): tmpstr = "" @@ -673,13 +677,13 @@ def __str__(self): def decodeBin(self, eeprom): commonHead = eeprom[0:8] d_print("decode version %x" % ord(commonHead[0])) - if self.COMMON_HEAD_VERSION != commonHead[0]: + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): raise FruException("HEAD VERSION error,not Fru format!", -10) if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): strtemp = "check header checksum error [cal:%02x data:%02x]" % ( FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) raise FruException(strtemp, -3) - if commonHead[1] != self.INITVALUE: + if ord(commonHead[1]) != ord(self.INITVALUE): d_print("Internal Use Area is present") self.internalUseArea = InternalUseArea( name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) @@ -687,7 +691,7 @@ def decodeBin(self, eeprom): self.internalUserAreaOffset = ord(commonHead[1]) self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( self.internalUserAreaOffset * 8 + self.internalUseArea.size)] - if commonHead[2] != self.INITVALUE: + if ord(commonHead[2]) != ord(self.INITVALUE): d_print("Chassis Info Area is present") self.chassisInfoArea = ChassisInfoArea( name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) @@ -695,7 +699,7 @@ def decodeBin(self, eeprom): self.chassicInfoAreaOffset = ord(commonHead[2]) self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] - if commonHead[3] != self.INITVALUE: + if ord(commonHead[3]) != ord(self.INITVALUE): self.boardInfoArea = BoardInfoArea( name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) self.boardInfoArea.isPresent = True @@ -707,12 +711,12 @@ def decodeBin(self, eeprom): self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): - print "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ (FruUtil.checksum( self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) - sys.exit(-1) + raise FruException(strtmp, -3) self.boardInfoArea.decodedata() - if commonHead[4] != self.INITVALUE: + if ord(commonHead[4]) != ord(self.INITVALUE): d_print("Product Info Area is present") self.productInfoArea = ProductInfoArea( name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) @@ -732,7 +736,7 @@ def decodeBin(self, eeprom): FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) raise FruException(strtmp, -3) self.productInfoArea.decodedata() - if commonHead[5] != self.INITVALUE: + if ord(commonHead[5]) != ord(self.INITVALUE): self.multiRecordArea = MultiRecordArea( name="MultiRecord record Area ") d_print("MultiRecord record present") @@ -748,7 +752,6 @@ def initDefault(self): self.boardInfoAreaOffset = self.INITVALUE self.productinfoAreaOffset = self.INITVALUE self.multiRecordAreaOffset = self.INITVALUE - self.PAD = self.INITVALUE self.zeroCheckSum = self.INITVALUE self.offset = self.SUGGESTED_SIZE_COMMON_HEADER self.productInfoArea = None @@ -874,30 +877,31 @@ def recalcuteCommonHead(self): self.bindata = "" self.offset = self.SUGGESTED_SIZE_COMMON_HEADER d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) if self.internalUseArea is not None and self.internalUseArea.isPresent: - self.internalUserAreaOffset = self.offset / 8 + self.internalUserAreaOffset = self.offset // 8 self.offset += self.internalUseArea.size d_print("internalUseArea is present offset:%d" % self.offset) if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: - self.chassicInfoAreaOffset = self.offset / 8 + self.chassicInfoAreaOffset = self.offset // 8 self.offset += self.chassisInfoArea.size d_print("chassisInfoArea is present offset:%d" % self.offset) if self.boardInfoArea is not None and self.boardInfoArea.isPresent: - self.boardInfoAreaOffset = self.offset / 8 + self.boardInfoAreaOffset = self.offset // 8 self.offset += self.boardInfoArea.size d_print("boardInfoArea is present offset:%d" % self.offset) d_print("boardInfoArea is present size:%d" % self.boardInfoArea.size) if self.productInfoArea is not None and self.productInfoArea.isPresent: - self.productinfoAreaOffset = self.offset / 8 + self.productinfoAreaOffset = self.offset // 8 self.offset += self.productInfoArea.size d_print("productInfoArea is present offset:%d" % self.offset) if self.multiRecordArea is not None and self.multiRecordArea.isPresent: - self.multiRecordAreaOffset = self.offset / 8 + self.multiRecordAreaOffset = self.offset // 8 d_print("multiRecordArea is present offset:%d" % self.offset) if self.internalUserAreaOffset == self.INITVALUE: @@ -914,16 +918,17 @@ def recalcuteCommonHead(self): self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff d_print("zerochecksum:%x" % self.zeroCheckSum) - self.data = self.version + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( - self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + self.INITVALUE + chr(self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) self.bindata = self.data + self.bodybin totallen = len(self.bindata) d_print("totallen %d" % totallen) - if (totallen < 256): - self.bindata = self.bindata.ljust(256, self.INITVALUE) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) else: - raise FruException('bin data more than 256', -2) + raise FruException('bin data more than %d' % self._frusize, -2) def recalcutebin(self): self.bodybin = "" @@ -945,6 +950,12 @@ def recalcutebin(self): d_print("multiRecordArea present") self.bodybin += self.productInfoArea.data - def recalcute(self): + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size self.recalcutebin() self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/installer.conf b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/installer.conf index df846113776d..5e62742c11bf 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/installer.conf +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/installer.conf @@ -1,2 +1 @@ CONSOLE_SPEED=115200 -ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_pstate=disable intel_idle.max_cstate=0 modprobe.blacklist=fpga_pcie_i2c" diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/monitor.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/monitor.py index ab4d14ec3daa..c50d6c248b5a 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/monitor.py +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/monitor.py @@ -1,5 +1,4 @@ -#!/usr/bin/python -# -*- coding: UTF-8 -*- +#!/usr/bin/python3 # * onboard temperature sensors # * FAN trays # * PSU @@ -7,97 +6,154 @@ import os import xml.etree.ElementTree as ET import glob -from fru import * -from fantlv import * - +import json +from decimal import Decimal +from fru import ipmifru MAILBOX_DIR = "/sys/bus/i2c/devices/" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + CONFIG_NAME = "dev.xml" + +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + return val + + +def get_board_id(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +boardid = get_board_id() +boardairflow = getboardairflow() + + +DEV_XML_FILE_LIST = [ + "dev_" + boardid + "_" + boardairflow + ".xml", + "dev_" + boardid + ".xml", + "dev_" + boardairflow + ".xml", +] + + +def dev_file_read(path, offset, read_len): + retval = "ERR" + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + return False, "%s %s not found" % (retval, path) + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, "%s %s" % (retval, msg) + finally: + if fd > 0: + os.close(fd) + return True, val_list + + def getPMCreg(location): retval = 'ERR' - if (not os.path.isfile(location)): - return "%s %s notfound"% (retval , location) + if not os.path.isfile(location): + return "%s %s notfound" % (retval, location) try: with open(location, 'r') as fd: retval = fd.read() except Exception as error: - pass + return "ERR %s" % str(error) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval + + # Get a mailbox register def get_pmc_register(reg_name): retval = 'ERR' - mb_reg_file = MAILBOX_DIR + reg_name + mb_reg_file = reg_name filepath = glob.glob(mb_reg_file) - if(len(filepath) == 0): - return "%s %s notfound"% (retval , mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) mb_reg_file = filepath[0] - if (not os.path.isfile(mb_reg_file)): - #print mb_reg_file, 'not found !' - return "%s %s notfound"% (retval , mb_reg_file) + if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' + return "%s %s notfound" % (retval, mb_reg_file) try: - with open(mb_reg_file, 'r') as fd: + with open(mb_reg_file, 'rb') as fd: retval = fd.read() + retval = typeTostr(retval) except Exception as error: - pass + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval + class checktype(): def __init__(self, test1): self.test1 = test1 + @staticmethod - def check(name,location, bit, value, tips , err1): - psu_status = int(get_pmc_register(location),16) - val = (psu_status & (1<< bit)) >> bit - if (val != value): - err1["errmsg"] = tips - err1["code"] = -1 - return -1 - else: - err1["errmsg"] = "none" - err1["code"] = 0 - return 0 - @staticmethod - def getValue(location, bit , type): - value_t = get_pmc_register(location) - if value_t.startswith("ERR") : + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) return value_t - if (type == 1): - return float(value_t)/1000 - elif (type == 2): - return float(value_t)/100 - elif (type == 3): - psu_status = int(value_t,16) - return (psu_status & (1<< bit)) >> bit - elif (type == 4): - return int(value_t,10) - elif (type == 5): - return float(value_t)/1000/1000 - else: - return value_t; -#######temp - @staticmethod - def getTemp(self, name, location , ret_t): - ret2 = self.getValue(location + "temp1_input" ," " ,1); - ret3 = self.getValue(location + "temp1_max" ," ", 1); - ret4 = self.getValue(location + "temp1_max_hyst" ," ", 1); - ret_t["temp1_input"] = ret2 - ret_t["temp1_max"] = ret3 - ret_t["temp1_max_hyst"] = ret4 - @staticmethod - def getLM75(name, location, result): - c1=checktype - r1={} - c1.getTemp(c1, name, location, r1) - result[name] = r1 -##########fanFRU + except Exception as e: + value_t = "ERR %s" % str(e) + return value_t + + # fanFRU @staticmethod def decodeBinByValue(retval): fru = ipmifru() @@ -105,67 +161,70 @@ def decodeBinByValue(retval): return fru @staticmethod - def printbinvalue(b): - index = 0 - print " ", - for width in range(16): - print "%02x " % width, - print "" - for i in range(0, len(b)): - if index % 16 == 0: - print " " - print " %02x " % i, - print "%02x " % ord(b[i]), - index += 1 - print "" - - @staticmethod - def getfruValue(val): + def getfruValue(prob_t, root, val): try: - binval = checktype.getValue(val, 0 , 0) - if binval.startswith("ERR"): - return binval + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) fanpro = {} ret = checktype.decodeBinByValue(binval) - fanpro['fan_type'] = ret.productInfoArea.productName - fanpro['hw_version'] = ret.productInfoArea.productVersion - fanpro['sn'] = ret.productInfoArea.productSerialNumber - fanpro['fanid'] = ret.productInfoArea.productextra2 + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = ret.productInfoArea.productVersion + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] return fanpro except Exception as error: return "ERR " + str(error) @staticmethod - def getslottlvValue(val): + def getslotfruValue(val): try: - binval = checktype.getValue(val, 0 , 0) + binval = checktype.getValue(val, 0, 0) if binval.startswith("ERR"): return binval slotpro = {} - slottlv = fan_tlv() - rets = slottlv.decode(binval) - if len(rets) == 0: - raise Exception("decode fan tlv fail") - slotpro['slot_type'] = slottlv.typename - slotpro['hw_version'] = slottlv.typehwinfo - slotpro['sn'] = slottlv.typesn - slotpro['slotid'] = slottlv.typedevtype + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber return slotpro except Exception as error: return "ERR " + str(error) @staticmethod - def getslotfruValue(val): + def getpsufruValue(prob_t, root, val): try: - binval = checktype.getValue(val, 0 , 0) + psu_match = False + binval = checktype.getValue(val, 0, 0) if binval.startswith("ERR"): return binval - slotpro = {} + psupro = {} ret = checktype.decodeBinByValue(binval) - slotpro['slot_type'] = ret.boardInfoArea.boardProductName - slotpro['hw_version'] = ret.boardInfoArea.boardextra1 - slotpro['sn'] = ret.boardInfoArea.boardSerialNumber - return slotpro + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name in psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro except Exception as error: return "ERR " + str(error) @@ -178,120 +237,139 @@ def __init__(self, productname): def getETroot(filename): tree = ET.parse(filename) root = tree.getroot() - return root; + return root @staticmethod def getDecodValue(collection, decode): decodes = collection.find('decode') testdecode = decodes.find(decode) - test={} + test = {} + if testdecode is None: + return test for neighbor in testdecode.iter('code'): - test[neighbor.attrib["key"]]=neighbor.attrib["value"] + test[neighbor.attrib["key"]] = neighbor.attrib["value"] return test + @staticmethod def getfileValue(location): - return checktype.getValue(location," "," ") + return checktype.getValue(location, " ", " ") + @staticmethod def getETValue(a, filename, tagname): root = status.getETroot(filename) for neighbor in root.iter(tagname): prob_t = {} prob_t = neighbor.attrib - prob_t['errcode']= 0 + prob_t['errcode'] = 0 prob_t['errmsg'] = '' for pros in neighbor.iter("property"): - ret = dict(neighbor.attrib.items() + pros.attrib.items()) + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) if ret.get('e2type') == 'fru' and ret.get("name") == "fru": - fruval = checktype.getfruValue(ret["location"]) - if isinstance(fruval, str) and fruval.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= fruval - else: - prob_t.update(fruval) - if ret.get("name") == "slot" and ret.get('e2type') == 'tlv': - slotval = checktype.getslottlvValue(ret["location"]) - if isinstance(slotval, str) and slotval.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= slotval - else: - prob_t.update(slotval) - if ret.get("name") == "slot" and ret.get('e2type') == 'fru': - slotval = checktype.getslotfruValue(ret["location"]) - if isinstance(slotval, str) and slotval.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= slotval - else: - prob_t.update(slotval) - - if ('type' not in ret.keys()): - val = "0"; + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break + prob_t.update(fruval) + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): + val = "0" else: val = ret["type"] - if ('bit' not in ret.keys()): - bit = "0"; + if 'bit' not in ret.keys(): + bit = "0" else: bit = ret["bit"] - s = checktype.getValue(ret["location"], int(bit),int(val)) - if isinstance(s, str) and s.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= s - if ('default' in ret.keys()): - rt = status.getDecodValue(root,ret['decode']) - prob_t['errmsg']= rt[str(s)] + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) + if isinstance(s, str) and s.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] if str(s) != ret["default"]: - prob_t['errcode']= -1 - break; + prob_t['errcode'] = -1 + break else: - if ('decode' in ret.keys()): - rt = status.getDecodValue(root,ret['decode']) - if(ret['decode'] == "psutype" and s.replace("\x00","").rstrip() not in rt.keys()): - prob_t['errcode']= -1 - prob_t['errmsg'] = '%s'% ("Not supported PSU type") + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) else: - s = rt[str(s).replace("\x00","").rstrip()] + s = rt[str(s).replace("\x00", "").rstrip()] name = ret["name"] - prob_t[name]=str(s) + prob_t[name] = str(s) a.append(prob_t) + @staticmethod def getCPUValue(a, filename, tagname): root = status.getETroot(filename) for neighbor in root.iter(tagname): - location = neighbor.attrib["location"] - L=[] + location = neighbor.attrib["location"] + L = [] for dirpath, dirnames, filenames in os.walk(location): - for file in filenames : + for file in filenames: if file.endswith("input"): L.append(os.path.join(dirpath, file)) - L =sorted(L,reverse=False) + L = sorted(L, reverse=False) for i in range(len(L)): prob_t = {} - prob_t["name"] = getPMCreg("%s/temp%d_label"%(location,i+1)) - prob_t["temp"] = float(getPMCreg("%s/temp%d_input"%(location,i+1)))/1000 - prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm"%(location,i+1)))/1000 - prob_t["crit"] = float(getPMCreg("%s/temp%d_crit"%(location,i+1)))/1000 - prob_t["max"] = float(getPMCreg("%s/temp%d_max"%(location,i+1)))/1000 + prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 + prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 a.append(prob_t) @staticmethod def getFileName(): - return os.path.dirname(os.path.realpath(__file__)) + "/"+ CONFIG_NAME - @staticmethod - def getFan(ret): - _filename = status.getFileName() - _tagname = "fan" - status.getvalue(ret, _filename, _tagname) + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME + @staticmethod def checkFan(ret): _filename = status.getFileName() # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "fan" status.getETValue(ret, _filename, _tagname) + @staticmethod def getTemp(ret): _filename = status.getFileName() - #_filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "temp" status.getETValue(ret, _filename, _tagname) + @staticmethod def getPsu(ret): _filename = status.getFileName() @@ -306,10 +384,19 @@ def getcputemp(ret): status.getCPUValue(ret, _filename, _tagname) @staticmethod - def checkSlot(ret): + def getDcdc(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() - _tagname = "slot" + _tagname = "dcdc" status.getETValue(ret, _filename, _tagname) + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + @staticmethod + def getmacpower(ret): + _filename = status.getFileName() + _tagname = "macpower" + status.getETValue(ret, _filename, _tagname) diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pcie.yaml b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pcie.yaml new file mode 100644 index 000000000000..ab6315b6f5e2 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pcie.yaml @@ -0,0 +1,440 @@ +- 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: '01' + fn: '1' + id: 6f03 + 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: '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: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: '16' + fn: '0' + id: 8c3a + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #1 (rev 04)' +- bus: '00' + dev: '16' + fn: '1' + id: 8c3b + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #2 (rev 04)' +- 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: 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: '01' + dev: '00' + fn: '0' + id: b870 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b870 (rev 01)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '04' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '04' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '07' + dev: '00' + fn: '0' + id: '1537' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Backplane Connection + (rev 03)' +- bus: 08 + dev: '00' + fn: '0' + id: '7022' + name: 'Memory controller: Xilinx Corporation Device 7022' +- 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: 0c + fn: '2' + id: 6fe2 + 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: '3' + id: 6fe3 + 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/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/sfputil.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/sfputil.py index 51285b5401b7..df3799f314ce 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/sfputil.py +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/sfputil.py @@ -6,6 +6,7 @@ try: import time import os + import traceback from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -22,12 +23,8 @@ class SfpUtil(SfpUtilBase): QSFP_DEVICE_TYPE = "optoe1" I2C_MAX_ATTEMPT = 3 - SFP_STATUS_INSERTED = '1' - SFP_STATUS_REMOVED = '0' - _port_to_eeprom_mapping = {} port_to_i2cbus_mapping ={} - port_dict = {} @property def port_start(self): @@ -47,7 +44,7 @@ def port_to_eeprom_mapping(self): def __init__(self): for x in range(self.PORT_START, self.PORTS_IN_BLOCK): - self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) + self.port_to_i2cbus_mapping[x] = x + self.EEPROM_OFFSET SfpUtilBase.__init__(self) def _sfp_read_file_path(self, file_path, offset, num_bytes): @@ -59,8 +56,7 @@ def _sfp_read_file_path(self, file_path, offset, num_bytes): except Exception: attempts += 1 time.sleep(0.05) - else: - return True, read_buf + return True, read_buf return False, None def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): @@ -70,20 +66,18 @@ def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): return False - else: - with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: - rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) - return rv + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): try: sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path # Write device address to new_device file - nd_file = open(sysfs_nd_path, "w") nd_str = "%s %s" % (devtype, hex(devaddr)) - nd_file.write(nd_str) - nd_file.close() + with open(sysfs_nd_path, "w") as nd_file: + nd_file.write(nd_str) except Exception as err: print("Error writing to new device file: %s" % str(err)) @@ -94,7 +88,7 @@ def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): def _get_port_eeprom_path(self, port_num, devid): sysfs_i2c_adapter_base_path = "" - if port_num in self.port_to_eeprom_mapping.keys(): + if port_num in self.port_to_eeprom_mapping: sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] else: sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" @@ -139,12 +133,12 @@ def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): eeprom_raw.append("0x00") rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) - if rv == False: + if rv is False: return None try: for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) except Exception: return None @@ -154,41 +148,28 @@ 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.IDENTITY_EEPROM_ADDR, 256) + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256) def get_presence(self, port_num): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - if port_num <= 7: - presence_path = "/sys/bus/i2c/devices/8-0030/sfp_presence1" - elif port_num >= 8 and port_num <= 15: - presence_path = "/sys/bus/i2c/devices/8-0030/sfp_presence2" - elif port_num >= 16 and port_num <= 23: - presence_path = "/sys/bus/i2c/devices/8-0031/sfp_presence3" - elif port_num >= 24 and port_num <= 31: - presence_path = "/sys/bus/i2c/devices/8-0031/sfp_presence4" - else: - return False + #The sff number starts from 1 + presence_path = "/sys/wb_plat/sff/sff%d/present" % (port_num + 1) try: - data = open(presence_path, "rb") + with open(presence_path, "rb") as data: + presence_data = data.read(2) + if presence_data == "": + return False + result = int(presence_data, 16) except IOError: return False - presence_data = data.read(2) - if presence_data == "": - return False - result = int(presence_data, 16) - data.close() - - # ModPrsL is active low - if result & (1 << (port_num % 8)) == 0: + if result == 1: return True - return False def get_low_power_mode(self, port_num): @@ -209,47 +190,55 @@ def reset(self, port_num): return True def get_transceiver_change_event(self, timeout=0): + return False, {} - start_time = time.time() - currernt_port_dict = {} - forever = False + def get_highest_temperature(self): + offset = 0 + hightest_temperature = -9999 - if timeout == 0: - forever = True - elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs - else: - print ("get_transceiver_change_event:Invalid timeout value", timeout) - return False, {} + presence_flag = False + read_eeprom_flag = False + temperature_valid_flag = False - end_time = start_time + timeout - if start_time > end_time: - print ('get_transceiver_change_event:' \ - 'time wrap / invalid timeout value', timeout) + for port in range(0, self.PORTS_IN_BLOCK): + if self.get_presence(port) is False: + continue - return False, {} # Time wrap or possibly incorrect timeout + presence_flag = True - while timeout >= 0: - # Check for OIR events and return updated port_dict - for x in range(self.PORT_START, self.PORTS_IN_BLOCK): - if self.get_presence(x): - currernt_port_dict[x] = self.SFP_STATUS_INSERTED - else: - currernt_port_dict[x] = self.SFP_STATUS_REMOVED - if (currernt_port_dict == self.port_dict): - if forever: - time.sleep(1) - else: - timeout = end_time - time.time() - if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity - else: - if timeout > 0: - time.sleep(timeout) - return True, {} + if port in self.qsfp_ports: + offset = 22 else: - # Update reg value - self.port_dict = currernt_port_dict - return True, self.port_dict - print ("get_transceiver_change_event: Should not reach here.") - return False, {} + offset = 96 + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = float(result / 256.0) + if -50 <= result <= 200: + temperature_valid_flag = True + hightest_temperature = max(hightest_temperature, result) + except BaseException: + print(traceback.format_exc()) + + # all port not presence + if presence_flag is False: + hightest_temperature = -10000 + + # all port read eeprom fail + elif read_eeprom_flag is False: + hightest_temperature = -9999 + + # all port temperature invalid + elif read_eeprom_flag is True and temperature_valid_flag is False: + hightest_temperature = -10000 + + hightest_temperature = round(hightest_temperature, 2) + + return hightest_temperature diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py new file mode 100644 index 000000000000..e92782a0969b --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py @@ -0,0 +1,309 @@ +# +# ssd_util.py +# +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium + +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_ssd.ssd_base import SsdBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SMARTCTL = "smartctl {} -a" +INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + +NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 + +class SsdUtil(SsdBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE + + def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + + """ + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" + """ + self.model_attr = { + "ER2-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n231\s+(.+?)\n" } + } + + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = "[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" + + def _execute_shell(self, cmd): + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None + return output + + def _parse_re(self, pattern, buffer): + res_list = re.findall(pattern, str(buffer)) + return res_list[0] if res_list else NOT_AVAILABLE + + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re('Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re('Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re('Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re('Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re('\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re('SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re('Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re('Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + + def get_health(self): + """ + Retrieves current disk health in percentages + + Returns: + A float number of current ssd health + e.g. 83.5 + """ + return float(self.health) + + def get_temperature(self): + """ + Retrieves current disk temperature in Celsius + + Returns: + A float number of current temperature in Celsius + e.g. 40.1 + """ + return float(self.temperature) + + def get_model(self): + """ + Retrieves model for the given disk device + + Returns: + A string holding disk model as provided by the manufacturer + """ + return self.model + + def get_firmware(self): + """ + Retrieves firmware version for the given disk device + + Returns: + A string holding disk firmware version as provided by the manufacturer + """ + return self.firmware + + def get_serial(self): + """ + Retrieves serial number for the given disk device + + Returns: + A string holding disk serial number as provided by the manufacturer + """ + return self.serial + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life + def get_vendor_output(self): + """ + Retrieves vendor specific data for the given disk device + + Returns: + A string holding some vendor specific disk information + """ + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re('{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/system_health_monitoring_config.json b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/system_health_monitoring_config.json new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/port_config.ini b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/port_config.ini index 823f53160c33..b71ad39648c9 100755 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/port_config.ini +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/port_config.ini @@ -1,57 +1,57 @@ -# name lanes alias index speed admin_status -Ethernet1 1 twentyfiveGigE0/1 0 25000 up -Ethernet2 2 twentyfiveGigE0/2 1 25000 up -Ethernet3 3 twentyfiveGigE0/3 2 25000 up -Ethernet4 4 twentyfiveGigE0/4 3 25000 up -Ethernet5 5 twentyfiveGigE0/5 4 25000 up -Ethernet6 6 twentyfiveGigE0/6 5 25000 up -Ethernet7 7 twentyfiveGigE0/7 6 25000 up -Ethernet8 8 twentyfiveGigE0/8 7 25000 up -Ethernet9 13 twentyfiveGigE0/9 8 25000 up -Ethernet10 14 twentyfiveGigE0/10 9 25000 up -Ethernet11 15 twentyfiveGigE0/11 10 25000 up -Ethernet12 16 twentyfiveGigE0/12 11 25000 up -Ethernet13 21 twentyfiveGigE0/13 12 25000 up -Ethernet14 22 twentyfiveGigE0/14 13 25000 up -Ethernet15 23 twentyfiveGigE0/15 14 25000 up -Ethernet16 24 twentyfiveGigE0/16 15 25000 up -Ethernet17 29 twentyfiveGigE0/17 16 25000 up -Ethernet18 30 twentyfiveGigE0/18 17 25000 up -Ethernet19 31 twentyfiveGigE0/19 18 25000 up -Ethernet20 32 twentyfiveGigE0/20 19 25000 up -Ethernet21 33 twentyfiveGigE0/21 20 25000 up -Ethernet22 34 twentyfiveGigE0/22 21 25000 up -Ethernet23 35 twentyfiveGigE0/23 22 25000 up -Ethernet24 36 twentyfiveGigE0/24 23 25000 up -Ethernet25 41 twentyfiveGigE0/25 24 25000 up -Ethernet26 42 twentyfiveGigE0/26 25 25000 up -Ethernet27 43 twentyfiveGigE0/27 26 25000 up -Ethernet28 44 twentyfiveGigE0/28 27 25000 up -Ethernet29 49 twentyfiveGigE0/29 28 25000 up -Ethernet30 50 twentyfiveGigE0/30 29 25000 up -Ethernet31 51 twentyfiveGigE0/31 30 25000 up -Ethernet32 52 twentyfiveGigE0/32 31 25000 up -Ethernet33 57 twentyfiveGigE0/33 32 25000 up -Ethernet34 58 twentyfiveGigE0/34 33 25000 up -Ethernet35 59 twentyfiveGigE0/35 34 25000 up -Ethernet36 60 twentyfiveGigE0/36 35 25000 up -Ethernet37 61 twentyfiveGigE0/37 36 25000 up -Ethernet38 62 twentyfiveGigE0/38 37 25000 up -Ethernet39 63 twentyfiveGigE0/39 38 25000 up -Ethernet40 64 twentyfiveGigE0/40 39 25000 up -Ethernet41 65 twentyfiveGigE0/41 40 25000 up -Ethernet42 66 twentyfiveGigE0/42 41 25000 up -Ethernet43 67 twentyfiveGigE0/43 42 25000 up -Ethernet44 68 twentyfiveGigE0/44 43 25000 up -Ethernet45 69 twentyfiveGigE0/45 44 25000 up -Ethernet46 70 twentyfiveGigE0/46 45 25000 up -Ethernet47 71 twentyfiveGigE0/47 46 25000 up -Ethernet48 72 twentyfiveGigE0/48 47 25000 up -Ethernet49 85,86,87,88 hundredGigE0/1 48 100000 up -Ethernet50 77,78,79,80 hundredGigE0/2 49 100000 up -Ethernet51 97,98,99,100 hundredGigE0/3 50 100000 up -Ethernet52 93,94,95,96 hundredGigE0/4 51 100000 up -Ethernet53 113,114,115,116 hundredGigE0/5 52 100000 up -Ethernet54 105,106,107,108 hundredGigE0/6 53 100000 up -Ethernet55 121,122,123,124 hundredGigE0/7 54 100000 up -Ethernet56 125,126,127,128 hundredGigE0/8 55 100000 up +# name lanes alias index speed admin_status +Ethernet1 57 twentyfiveGigE0/1 1 25000 up +Ethernet2 58 twentyfiveGigE0/2 2 25000 up +Ethernet3 59 twentyfiveGigE0/3 3 25000 up +Ethernet4 60 twentyfiveGigE0/4 4 25000 up +Ethernet5 61 twentyfiveGigE0/5 5 25000 up +Ethernet6 62 twentyfiveGigE0/6 6 25000 up +Ethernet7 63 twentyfiveGigE0/7 7 25000 up +Ethernet8 64 twentyfiveGigE0/8 8 25000 up +Ethernet9 1 twentyfiveGigE0/9 9 25000 up +Ethernet10 2 twentyfiveGigE0/10 10 25000 up +Ethernet11 3 twentyfiveGigE0/11 11 25000 up +Ethernet12 4 twentyfiveGigE0/12 12 25000 up +Ethernet13 5 twentyfiveGigE0/13 13 25000 up +Ethernet14 6 twentyfiveGigE0/14 14 25000 up +Ethernet15 7 twentyfiveGigE0/15 15 25000 up +Ethernet16 8 twentyfiveGigE0/16 16 25000 up +Ethernet17 13 twentyfiveGigE0/17 17 25000 up +Ethernet18 14 twentyfiveGigE0/18 18 25000 up +Ethernet19 15 twentyfiveGigE0/19 19 25000 up +Ethernet20 16 twentyfiveGigE0/20 20 25000 up +Ethernet21 21 twentyfiveGigE0/21 21 25000 up +Ethernet22 22 twentyfiveGigE0/22 22 25000 up +Ethernet23 23 twentyfiveGigE0/23 23 25000 up +Ethernet24 24 twentyfiveGigE0/24 24 25000 up +Ethernet25 29 twentyfiveGigE0/25 25 25000 up +Ethernet26 30 twentyfiveGigE0/26 26 25000 up +Ethernet27 31 twentyfiveGigE0/27 27 25000 up +Ethernet28 32 twentyfiveGigE0/28 28 25000 up +Ethernet29 33 twentyfiveGigE0/29 29 25000 up +Ethernet30 34 twentyfiveGigE0/30 30 25000 up +Ethernet31 35 twentyfiveGigE0/31 31 25000 up +Ethernet32 36 twentyfiveGigE0/32 32 25000 up +Ethernet33 41 twentyfiveGigE0/33 33 25000 up +Ethernet34 42 twentyfiveGigE0/34 34 25000 up +Ethernet35 43 twentyfiveGigE0/35 35 25000 up +Ethernet36 44 twentyfiveGigE0/36 36 25000 up +Ethernet37 49 twentyfiveGigE0/37 37 25000 up +Ethernet38 50 twentyfiveGigE0/38 38 25000 up +Ethernet39 51 twentyfiveGigE0/39 39 25000 up +Ethernet40 52 twentyfiveGigE0/40 40 25000 up +Ethernet41 65 twentyfiveGigE0/41 41 25000 up +Ethernet42 66 twentyfiveGigE0/42 42 25000 up +Ethernet43 67 twentyfiveGigE0/43 43 25000 up +Ethernet44 68 twentyfiveGigE0/44 44 25000 up +Ethernet45 69 twentyfiveGigE0/45 45 25000 up +Ethernet46 70 twentyfiveGigE0/46 46 25000 up +Ethernet47 71 twentyfiveGigE0/47 47 25000 up +Ethernet48 72 twentyfiveGigE0/48 48 25000 up +Ethernet49 85,86,87,88 hundredGigE0/1 49 100000 up +Ethernet50 77,78,79,80 hundredGigE0/2 50 100000 up +Ethernet51 97,98,99,100 hundredGigE0/3 51 100000 up +Ethernet52 93,94,95,96 hundredGigE0/4 52 100000 up +Ethernet53 113,114,115,116 hundredGigE0/5 53 100000 up +Ethernet54 105,106,107,108 hundredGigE0/6 54 100000 up +Ethernet55 121,122,123,124 hundredGigE0/7 55 100000 up +Ethernet56 125,126,127,128 hundredGigE0/8 56 100000 up diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/sai.profile b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/sai.profile index 042c8060d587..352e8c50b053 100755 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/sai.profile +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-b6510-48vs8cq-48x25G+8x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm new file mode 100644 index 000000000000..e86eb1b9fa36 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm @@ -0,0 +1,602 @@ +cancun_dir=/usr/share/sonic/platform/cancun/sdk_6.5.16/ +l2_mem_entries=32768 +l3_mem_entries=16384 +l3_alpm_enable=2 +ipv6_lpm_128b_enable=0x1 +l2xmsg_mode=0 +l3_max_ecmp_mode=1 +svi_my_station_optimization=1 +sai_nbr_bcast_ifp_optimized=2 +bcm_num_cos=8 +bcm_stat_interval=2000000 +cdma_timeout_usec=3000000 +core_clock_frequency=1525 +dpp_clock_ratio=2:3 +help_cli_enable=1 +ifp_inports_support_enable=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 +pbmp_gport_stack.0=0x0000000000000000000000000000000000000000000000000000000000000000 +#pbmp_xport_xe.0=0x00000000000000000000000000000000888ffffffffffff9fffffffffffffffe +pbmp_xport_xe=0xffffffffffffffffffffffffffffffffffffffffe +port_flex_enable=1 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_tx_lane_map_physical{61.0}=0x0123 +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_tx_lane_map_physical{5.0}=0x0123 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_tx_lane_map_physical{33.0}=0x0123 +phy_chain_tx_lane_map_physical{41.0}=0x0123 +phy_chain_tx_lane_map_physical{49.0}=0x0123 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_tx_lane_map_physical{69.0}=0x3210 +phy_chain_tx_lane_map_physical{85.0}=0x3210 +phy_chain_tx_lane_map_physical{77.0}=0x0213 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_tx_lane_map_physical{93.0}=0x0213 +phy_chain_tx_lane_map_physical{113.0}=0x3210 +phy_chain_tx_lane_map_physical{105.0}=0x0213 +phy_chain_tx_lane_map_physical{121.0}=0x3120 +phy_chain_tx_lane_map_physical{125.0}=0x1203 + +phy_chain_rx_lane_map_physical{57.0}=0x1032 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_rx_lane_map_physical{1.0}=0x1032 +phy_chain_rx_lane_map_physical{5.0}=0x1032 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_rx_lane_map_physical{49.0}=0x1032 +phy_chain_rx_lane_map_physical{65.0}=0x2301 +phy_chain_rx_lane_map_physical{69.0}=0x2301 +phy_chain_rx_lane_map_physical{85.0}=0x1032 +phy_chain_rx_lane_map_physical{77.0}=0x1032 +phy_chain_rx_lane_map_physical{97.0}=0x1032 +phy_chain_rx_lane_map_physical{93.0}=0x1032 +phy_chain_rx_lane_map_physical{113.0}=0x1032 +phy_chain_rx_lane_map_physical{105.0}=0x1032 +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_rx_lane_map_physical{125.0}=0x1023 + +portmap_57=57:25 +portmap_58=58:25 +portmap_59=59:25 +portmap_60=60:25 +portmap_61=61:25 +portmap_62=62:25 +portmap_63=63:25 +portmap_64=64:25 +portmap_1=1:25 +portmap_2=2:25 +portmap_3=3:25 +portmap_4=4:25 +portmap_5=5:25 +portmap_6=6:25 +portmap_7=7:25 +portmap_8=8:25 +portmap_13=13:25 +portmap_14=14:25 +portmap_15=15:25 +portmap_16=16:25 +portmap_21=21:25 +portmap_22=22:25 +portmap_23=23:25 +portmap_24=24:25 +portmap_29=29:25 +portmap_30=30:25 +portmap_31=31:25 +portmap_32=32:25 +portmap_33=33:25 +portmap_34=34:25 +portmap_35=35:25 +portmap_36=36:25 +portmap_41=41:25 +portmap_42=42:25 +portmap_43=43:25 +portmap_44=44:25 +portmap_49=49:25 +portmap_50=50:25 +portmap_51=51:25 +portmap_52=52:25 +portmap_67=65:25 +portmap_68=66:25 +portmap_69=67:25 +portmap_70=68:25 +portmap_71=69:25 +portmap_72=70:25 +portmap_73=71:25 +portmap_74=72:25 +portmap_87=85:100 +portmap_79=77:100 +portmap_99=97:100 +portmap_95=93:100 +portmap_115=113:100 +portmap_107=105:100 +portmap_123=121:100 +portmap_127=125:100 + +dport_map_port_57=1 +dport_map_port_58=2 +dport_map_port_59=3 +dport_map_port_60=4 +dport_map_port_61=5 +dport_map_port_62=6 +dport_map_port_63=7 +dport_map_port_64=8 +dport_map_port_1=9 +dport_map_port_2=10 +dport_map_port_3=11 +dport_map_port_4=12 +dport_map_port_5=13 +dport_map_port_6=14 +dport_map_port_7=15 +dport_map_port_8=16 +dport_map_port_13=17 +dport_map_port_14=18 +dport_map_port_15=19 +dport_map_port_16=20 +dport_map_port_21=21 +dport_map_port_22=22 +dport_map_port_23=23 +dport_map_port_24=24 +dport_map_port_29=25 +dport_map_port_30=26 +dport_map_port_31=27 +dport_map_port_32=28 +dport_map_port_33=29 +dport_map_port_34=30 +dport_map_port_35=31 +dport_map_port_36=32 +dport_map_port_41=33 +dport_map_port_42=34 +dport_map_port_43=35 +dport_map_port_44=36 +dport_map_port_49=37 +dport_map_port_50=38 +dport_map_port_51=39 +dport_map_port_52=40 +dport_map_port_67=41 +dport_map_port_68=42 +dport_map_port_69=43 +dport_map_port_70=44 +dport_map_port_71=45 +dport_map_port_72=46 +dport_map_port_73=47 +dport_map_port_74=48 +dport_map_port_87=49 +dport_map_port_79=50 +dport_map_port_99=51 +dport_map_port_95=52 +dport_map_port_115=53 +dport_map_port_107=54 +dport_map_port_123=55 +dport_map_port_127=56 + +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 + +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 +phy_chain_rx_polarity_flip_physical{1.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +serdes_preemphasis_lane0_57=0x0f480d +serdes_preemphasis_lane1_57=0x0f480d +serdes_preemphasis_lane2_57=0x0f480d +serdes_preemphasis_lane3_57=0x0f480d +serdes_preemphasis_lane0_58=0x0f480d +serdes_preemphasis_lane1_58=0x0f480d +serdes_preemphasis_lane2_58=0x0f480d +serdes_preemphasis_lane3_58=0x0f480d +serdes_preemphasis_lane0_59=0x0f480d +serdes_preemphasis_lane1_59=0x0f480d +serdes_preemphasis_lane2_59=0x0f480d +serdes_preemphasis_lane3_59=0x0f480d +serdes_preemphasis_lane0_60=0x0f480d +serdes_preemphasis_lane1_60=0x0f480d +serdes_preemphasis_lane2_60=0x0f480d +serdes_preemphasis_lane3_60=0x0f480d +serdes_preemphasis_lane0_61=0x0f480d +serdes_preemphasis_lane1_61=0x0f480d +serdes_preemphasis_lane2_61=0x0f480d +serdes_preemphasis_lane3_61=0x0f480d +serdes_preemphasis_lane0_62=0x0f480d +serdes_preemphasis_lane1_62=0x0f480d +serdes_preemphasis_lane2_62=0x0f480d +serdes_preemphasis_lane3_62=0x0f480d +serdes_preemphasis_lane0_63=0x0f480d +serdes_preemphasis_lane1_63=0x0f480d +serdes_preemphasis_lane2_63=0x0f480d +serdes_preemphasis_lane3_63=0x0f480d +serdes_preemphasis_lane0_64=0x0f480d +serdes_preemphasis_lane1_64=0x0f480d +serdes_preemphasis_lane2_64=0x0f480d +serdes_preemphasis_lane3_64=0x0f480d +serdes_preemphasis_lane0_1=0x0f480d +serdes_preemphasis_lane1_1=0x0f480d +serdes_preemphasis_lane2_1=0x0f480d +serdes_preemphasis_lane3_1=0x0f480d +serdes_preemphasis_lane0_2=0x0d4b0c +serdes_preemphasis_lane1_2=0x0d4b0c +serdes_preemphasis_lane2_2=0x0d4b0c +serdes_preemphasis_lane3_2=0x0d4b0c +serdes_preemphasis_lane0_3=0x0f480d +serdes_preemphasis_lane1_3=0x0f480d +serdes_preemphasis_lane2_3=0x0f480d +serdes_preemphasis_lane3_3=0x0f480d +serdes_preemphasis_lane0_4=0x0d4b0c +serdes_preemphasis_lane1_4=0x0d4b0c +serdes_preemphasis_lane2_4=0x0d4b0c +serdes_preemphasis_lane3_4=0x0d4b0c +serdes_preemphasis_lane0_5=0x0f480d +serdes_preemphasis_lane1_5=0x0f480d +serdes_preemphasis_lane2_5=0x0f480d +serdes_preemphasis_lane3_5=0x0f480d +serdes_preemphasis_lane0_6=0x0d4b0c +serdes_preemphasis_lane1_6=0x0d4b0c +serdes_preemphasis_lane2_6=0x0d4b0c +serdes_preemphasis_lane3_6=0x0d4b0c +serdes_preemphasis_lane0_7=0x0f480d +serdes_preemphasis_lane1_7=0x0f480d +serdes_preemphasis_lane2_7=0x0f480d +serdes_preemphasis_lane3_7=0x0f480d +serdes_preemphasis_lane0_8=0x0d4b0c +serdes_preemphasis_lane1_8=0x0d4b0c +serdes_preemphasis_lane2_8=0x0d4b0c +serdes_preemphasis_lane3_8=0x0d4b0c +serdes_preemphasis_lane0_13=0x0f480d +serdes_preemphasis_lane1_13=0x0f480d +serdes_preemphasis_lane2_13=0x0f480d +serdes_preemphasis_lane3_13=0x0f480d +serdes_preemphasis_lane0_14=0x0d4b0c +serdes_preemphasis_lane1_14=0x0d4b0c +serdes_preemphasis_lane2_14=0x0d4b0c +serdes_preemphasis_lane3_14=0x0d4b0c +serdes_preemphasis_lane0_15=0x0f480d +serdes_preemphasis_lane1_15=0x0f480d +serdes_preemphasis_lane2_15=0x0f480d +serdes_preemphasis_lane3_15=0x0f480d +serdes_preemphasis_lane0_16=0x0d4b0c +serdes_preemphasis_lane1_16=0x0d4b0c +serdes_preemphasis_lane2_16=0x0d4b0c +serdes_preemphasis_lane3_16=0x0d4b0c +serdes_preemphasis_lane0_21=0x0d4b0c +serdes_preemphasis_lane1_21=0x0d4b0c +serdes_preemphasis_lane2_21=0x0d4b0c +serdes_preemphasis_lane3_21=0x0d4b0c +serdes_preemphasis_lane0_22=0x0d4b0c +serdes_preemphasis_lane1_22=0x0d4b0c +serdes_preemphasis_lane2_22=0x0d4b0c +serdes_preemphasis_lane3_22=0x0d4b0c +serdes_preemphasis_lane0_23=0x0d4b0c +serdes_preemphasis_lane1_23=0x0d4b0c +serdes_preemphasis_lane2_23=0x0d4b0c +serdes_preemphasis_lane3_23=0x0d4b0c +serdes_preemphasis_lane0_24=0x0d4b0c +serdes_preemphasis_lane1_24=0x0d4b0c +serdes_preemphasis_lane2_24=0x0d4b0c +serdes_preemphasis_lane3_24=0x0d4b0c +serdes_preemphasis_lane0_29=0x0d4b0c +serdes_preemphasis_lane1_29=0x0d4b0c +serdes_preemphasis_lane2_29=0x0d4b0c +serdes_preemphasis_lane3_29=0x0d4b0c +serdes_preemphasis_lane0_30=0x0d4b0c +serdes_preemphasis_lane1_30=0x0d4b0c +serdes_preemphasis_lane2_30=0x0d4b0c +serdes_preemphasis_lane3_30=0x0d4b0c +serdes_preemphasis_lane0_31=0x0d4b0c +serdes_preemphasis_lane1_31=0x0d4b0c +serdes_preemphasis_lane2_31=0x0d4b0c +serdes_preemphasis_lane3_31=0x0d4b0c +serdes_preemphasis_lane0_32=0x0d4b0c +serdes_preemphasis_lane1_32=0x0d4b0c +serdes_preemphasis_lane2_32=0x0d4b0c +serdes_preemphasis_lane3_32=0x0d4b0c +serdes_preemphasis_lane0_33=0x0d4b0c +serdes_preemphasis_lane1_33=0x0d4b0c +serdes_preemphasis_lane2_33=0x0d4b0c +serdes_preemphasis_lane3_33=0x0d4b0c +serdes_preemphasis_lane0_34=0x0d4b0c +serdes_preemphasis_lane1_34=0x0d4b0c +serdes_preemphasis_lane2_34=0x0d4b0c +serdes_preemphasis_lane3_34=0x0d4b0c +serdes_preemphasis_lane0_35=0x0d4b0c +serdes_preemphasis_lane1_35=0x0d4b0c +serdes_preemphasis_lane2_35=0x0d4b0c +serdes_preemphasis_lane3_35=0x0d4b0c +serdes_preemphasis_lane0_36=0x0d4b0c +serdes_preemphasis_lane1_36=0x0d4b0c +serdes_preemphasis_lane2_36=0x0d4b0c +serdes_preemphasis_lane3_36=0x0d4b0c +serdes_preemphasis_lane0_41=0x0d4b0c +serdes_preemphasis_lane1_41=0x0d4b0c +serdes_preemphasis_lane2_41=0x0d4b0c +serdes_preemphasis_lane3_41=0x0d4b0c +serdes_preemphasis_lane0_42=0x0d4b0c +serdes_preemphasis_lane1_42=0x0d4b0c +serdes_preemphasis_lane2_42=0x0d4b0c +serdes_preemphasis_lane3_42=0x0d4b0c +serdes_preemphasis_lane0_43=0x0d4b0c +serdes_preemphasis_lane1_43=0x0d4b0c +serdes_preemphasis_lane2_43=0x0d4b0c +serdes_preemphasis_lane3_43=0x0d4b0c +serdes_preemphasis_lane0_44=0x0d4b0c +serdes_preemphasis_lane1_44=0x0d4b0c +serdes_preemphasis_lane2_44=0x0d4b0c +serdes_preemphasis_lane3_44=0x0d4b0c +serdes_preemphasis_lane0_49=0x0f480d +serdes_preemphasis_lane1_49=0x0f480d +serdes_preemphasis_lane2_49=0x0f480d +serdes_preemphasis_lane3_49=0x0f480d +serdes_preemphasis_lane0_50=0x0d4b0c +serdes_preemphasis_lane1_50=0x0d4b0c +serdes_preemphasis_lane2_50=0x0d4b0c +serdes_preemphasis_lane3_50=0x0d4b0c +serdes_preemphasis_lane0_51=0x0f480d +serdes_preemphasis_lane1_51=0x0f480d +serdes_preemphasis_lane2_51=0x0f480d +serdes_preemphasis_lane3_51=0x0f480d +serdes_preemphasis_lane0_52=0x0d4b0c +serdes_preemphasis_lane1_52=0x0d4b0c +serdes_preemphasis_lane2_52=0x0d4b0c +serdes_preemphasis_lane3_52=0x0d4b0c +serdes_preemphasis_lane0_67=0x0d4b0c +serdes_preemphasis_lane1_67=0x0d4b0c +serdes_preemphasis_lane2_67=0x0d4b0c +serdes_preemphasis_lane3_67=0x0d4b0c +serdes_preemphasis_lane0_68=0x0d4b0c +serdes_preemphasis_lane1_68=0x0d4b0c +serdes_preemphasis_lane2_68=0x0d4b0c +serdes_preemphasis_lane3_68=0x0d4b0c +serdes_preemphasis_lane0_69=0x0d4b0c +serdes_preemphasis_lane1_69=0x0d4b0c +serdes_preemphasis_lane2_69=0x0d4b0c +serdes_preemphasis_lane3_69=0x0d4b0c +serdes_preemphasis_lane0_70=0x0d4b0c +serdes_preemphasis_lane1_70=0x0d4b0c +serdes_preemphasis_lane2_70=0x0d4b0c +serdes_preemphasis_lane3_70=0x0d4b0c +serdes_preemphasis_lane0_71=0x0d4b0c +serdes_preemphasis_lane1_71=0x0d4b0c +serdes_preemphasis_lane2_71=0x0d4b0c +serdes_preemphasis_lane3_71=0x0d4b0c +serdes_preemphasis_lane0_72=0x0d4b0c +serdes_preemphasis_lane1_72=0x0d4b0c +serdes_preemphasis_lane2_72=0x0d4b0c +serdes_preemphasis_lane3_72=0x0d4b0c +serdes_preemphasis_lane0_73=0x0d4b0c +serdes_preemphasis_lane1_73=0x0d4b0c +serdes_preemphasis_lane2_73=0x0d4b0c +serdes_preemphasis_lane3_73=0x0d4b0c +serdes_preemphasis_lane0_74=0x0d4b0c +serdes_preemphasis_lane1_74=0x0d4b0c +serdes_preemphasis_lane2_74=0x0d4b0c +serdes_preemphasis_lane3_74=0x0d4b0c +serdes_preemphasis_lane0_87=0x0d4b0c +serdes_preemphasis_lane1_87=0x0d4b0c +serdes_preemphasis_lane2_87=0x0d4b0c +serdes_preemphasis_lane3_87=0x0d4b0c +serdes_preemphasis_lane0_79=0x0d4b0c +serdes_preemphasis_lane1_79=0x0d4b0c +serdes_preemphasis_lane2_79=0x0d4b0c +serdes_preemphasis_lane3_79=0x0d4b0c +serdes_preemphasis_lane0_99=0x0d4b0c +serdes_preemphasis_lane1_99=0x0d4b0c +serdes_preemphasis_lane2_99=0x0d4b0c +serdes_preemphasis_lane3_99=0x0d4b0c +serdes_preemphasis_lane0_95=0x0d4b0c +serdes_preemphasis_lane1_95=0x0d4b0c +serdes_preemphasis_lane2_95=0x0d4b0c +serdes_preemphasis_lane3_95=0x0d4b0c +serdes_preemphasis_lane0_115=0x0d4b0c +serdes_preemphasis_lane1_115=0x0d4b0c +serdes_preemphasis_lane2_115=0x0d4b0c +serdes_preemphasis_lane3_115=0x0d4b0c +serdes_preemphasis_lane0_107=0x0d4b0c +serdes_preemphasis_lane1_107=0x0d4b0c +serdes_preemphasis_lane2_107=0x0d4b0c +serdes_preemphasis_lane3_107=0x0d4b0c +serdes_preemphasis_lane0_123=0x14460a +serdes_preemphasis_lane1_123=0x14460a +serdes_preemphasis_lane2_123=0x14460a +serdes_preemphasis_lane3_123=0x14460a +serdes_preemphasis_lane0_127=0x14460a +serdes_preemphasis_lane1_127=0x14460a +serdes_preemphasis_lane2_127=0x14460a +serdes_preemphasis_lane3_127=0x14460a + + +reglist_enable=1 +scache_filename=/var/warmboot/wbscache +schan_intr_enable=0 +stable_size=0x55000000 +stable_location=3 +warmboot_knet_shutdown_mode=1 +tdma_timeout_usec=3000000 + +#vxlan flex flow mode +flow_init_mode=1 + +riot_enable=1 +riot_overlay_l3_intf_mem_size=4096 +riot_overlay_l3_egress_mem_size=32768 +riot_overlay_ecmp_resilient_hash_size=16384 + +l3_ecmp_levels=2 + +use_all_splithorizon_groups=1 +sai_tunnel_support=1 + +#This property allows to enable L2 FDB entry to discard based on Source Mac +sai_fdb_entry_l2_discard_src_enable=1 + +#RDMA +sai_pfc_defaults_disable=1 +sai_optimized_mmu=1 + +#ACL wb count +ctr_evict_enable=0 diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/custom_led.bin b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/custom_led.bin index 1fe5585e07796a7e30facd1faf391c9969ab8b08..e02f94e7ed87ffe60524721f4aec68d661880e7c 100644 GIT binary patch delta 152 zcmV;J0B8TK0_*{Q@U>S)Mn=H23jiBR765QI03?7X10je;0wo7m zf?>j80Wkq$A2C5q?Rz^)mL`LwmgRlw!DNAr6j7FS903-q@5HW~GeK|TnlSUN) zY95tAsvQB6*+v?ORvxwh1!#6#g=nfqQbYkd5_q~p1u6v5LPjz|Cea5X4B$mZH9%@Y zYC)2+04)X3F+u~-O-2AM0MG#zlh diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml old mode 100755 new mode 100644 index f5e871564350..3be013889ce5 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml @@ -7,116 +7,412 @@ --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev_exhaust.xml b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev_exhaust.xml new file mode 100644 index 000000000000..496a7dee80cc --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev_exhaust.xml @@ -0,0 +1,418 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/fru.py b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/fru.py new file mode 100644 index 000000000000..f95164e03601 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/fru.py @@ -0,0 +1,961 @@ +#!/usr/bin/python3 +import collections +from datetime import datetime, timedelta +from bitarray import bitarray + + +__DEBUG__ = "N" + + +class FruException(Exception): + def __init__(self, message='fruerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +def e_print(err): + print("ERROR: " + err) + + +def d_print(debug_info): + if __DEBUG__ == "Y": + print(debug_info) + + +class FruUtil(): + @staticmethod + def decodeLength(value): + a = bitarray(8) + a.setall(True) + a[0:1] = 0 + a[1:2] = 0 + x = ord(a.tobytes()) + return x & ord(value) + + @staticmethod + def minToData(): + starttime = datetime(1996, 1, 1, 0, 0, 0) + endtime = datetime.now() + seconds = (endtime - starttime).total_seconds() + mins = seconds // 60 + m = int(round(mins)) + return m + + @staticmethod + def getTimeFormat(): + return datetime.now().strftime('%Y-%m-%d') + + @staticmethod + def getTypeLength(value): + if value is None or len(value) == 0: + return 0 + a = bitarray(8) + a.setall(False) + a[0:1] = 1 + a[1:2] = 1 + x = ord(a.tobytes()) + return x | len(value) + + @staticmethod + def checksum(b): + result = 0 + for item in b: + result += ord(item) + return (0x100 - (result & 0xff)) & 0xff + + +class BaseArea(object): + SUGGESTED_SIZE_COMMON_HEADER = 8 + SUGGESTED_SIZE_INTERNAL_USE_AREA = 72 + SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32 + SUGGESTED_SIZE_BOARD_INFO_AREA = 80 + SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80 + + INITVALUE = b'\x00' + resultvalue = INITVALUE * 256 + COMMON_HEAD_VERSION = b'\x01' + __childList = None + + def __init__(self, name="", size=0, offset=0): + self.__childList = [] + self._offset = offset + self.name = name + self._size = size + self._isPresent = False + self._data = b'\x00' * size + + @property + def childList(self): + return self.__childList + + @childList.setter + def childList(self, value): + self.__childList = value + + @property + def offset(self): + return self._offset + + @offset.setter + def offset(self, value): + self._offset = value + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + self._size = value + + @property + def data(self): + return self._data + + @data.setter + def data(self, value): + self._data = value + + @property + def isPresent(self): + return self._isPresent + + @isPresent.setter + def isPresent(self, value): + self._isPresent = value + + +class InternalUseArea(BaseArea): + pass + + +class ChassisInfoArea(BaseArea): + pass + + +class BoardInfoArea(BaseArea): + _boardTime = None + _fields = None + _mfg_date = None + areaversion = None + _boardversion = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "mfg_date : %s \n" \ + "boardManufacturer : %s \n" \ + "boardProductName : %s \n" \ + "boardSerialNumber : %s \n" \ + "boardPartNumber : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.boardversion), self.size, + self.language, self.getMfgRealData(), + self.boardManufacturer, self.boardProductName, + self.boardSerialNumber, self.boardPartNumber, + self.fruFileId) + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "boardextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["boardversion"] = ord(self.boardversion) + dic["boardlength"] = self.size + dic["boardlanguage"] = self.language + dic["boardmfg_date"] = self.getMfgRealData() + dic["boardManufacturer"] = self.boardManufacturer + dic["boardProductName"] = self.boardProductName + dic["boardSerialNumber"] = self.boardSerialNumber + dic["boardPartNumber"] = self.boardPartNumber + dic["boardfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] + index += 1 + d_print("decode length :%d class size:%d" % + ((ord(self.data[index]) * 8), self.size)) + index += 2 + + timetmp = self.data[index: index + 3] + self.mfg_date = ord(timetmp[0]) | ( + ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16) + d_print("decode getMfgRealData :%s" % self.getMfgRealData()) + index += 3 + + templen = FruUtil.decodeLength(self.data[index]) + self.boardManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardManufacturer:%s" % self.boardManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardProductName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardProductName:%s" % self.boardProductName) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardSerialNumber:%s" % self.boardSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardPartNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardPartNumber:%s" % self.boardPartNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if self.data[index] != chr(0xc1): + templen = FruUtil.decodeLength(self.data[index]) + tmpval = self.data[index + 1: index + templen + 1] + setattr(self, valtmp, tmpval) + index += templen + 1 + d_print("decode boardextra%d:%s" % (i, tmpval)) + else: + break + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("boardInfoArea version:%x" % ord(self.boardversion)) + d_print("boardInfoArea length:%d" % self.size) + d_print("boardInfoArea language:%x" % self.language) + self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea mfg_date:%x" % self.mfg_date) + + self.data = chr(ord(self.boardversion)) + \ + chr(self.size // 8) + chr(self.language) + + self.data += chr(self.mfg_date & 0xFF) + self.data += chr((self.mfg_date >> 8) & 0xFF) + self.data += chr((self.mfg_date >> 16) & 0xFF) + + d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer) + typelength = FruUtil.getTypeLength(self.boardManufacturer) + self.data += chr(typelength) + self.data += self.boardManufacturer + + d_print("boardInfoArea boardProductName:%s" % self.boardProductName) + self.data += chr(FruUtil.getTypeLength(self.boardProductName)) + self.data += self.boardProductName + + d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber) + self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber)) + self.data += self.boardSerialNumber + + d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber) + self.data += chr(FruUtil.getTypeLength(self.boardPartNumber)) + self.data += self.boardPartNumber + + d_print("boardInfoArea fruFileId:%s" % self.fruFileId) + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + d_print("self data:%d" % len(self.data)) + d_print("self size:%d" % self.size) + d_print("adjust size:%d" % (self.size - len(self.data) - 1)) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + + # checksum + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + def getMfgRealData(self): + starttime = datetime(1996, 1, 1, 0, 0, 0) + mactime = starttime + timedelta(minutes=self.mfg_date) + return mactime + + @property + def language(self): + self._language = 25 + return self._language + + @property + def mfg_date(self): + return self._mfg_date + + @mfg_date.setter + def mfg_date(self, val): + self._mfg_date = val + + @property + def boardversion(self): + self._boardversion = self.COMMON_HEAD_VERSION + return self._boardversion + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, val): + self._FRUFileID = val + + @property + def boardPartNumber(self): + return self._boardPartNumber + + @boardPartNumber.setter + def boardPartNumber(self, val): + self._boardPartNumber = val + + @property + def boardSerialNumber(self): + return self._boardSerialNumber + + @boardSerialNumber.setter + def boardSerialNumber(self, val): + self._boardSerialNumber = val + + @property + def boardProductName(self): + return self._boradProductName + + @boardProductName.setter + def boardProductName(self, val): + self._boradProductName = val + + @property + def boardManufacturer(self): + return self._boardManufacturer + + @boardManufacturer.setter + def boardManufacturer(self, val): + self._boardManufacturer = val + + @property + def boardTime(self): + return self._boardTime + + @boardTime.setter + def boardTime(self, val): + self._boardTime = val + + @property + def fields(self): + return self._fields + + @fields.setter + def fields(self, val): + self._fields = val + + +class ProductInfoArea(BaseArea): + _productManufacturer = None + _productAssetTag = None + _FRUFileID = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "productAssetTag : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.areaversion), self.size, + self.language, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, + self.productAssetTag, self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "productextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["productversion"] = ord(self.areaversion) + dic["productlength"] = self.size + dic["productlanguage"] = self.language + dic["productManufacturer"] = self.productManufacturer + dic["productName"] = self.productName + dic["productPartModelName"] = self.productPartModelName + dic["productVersion"] = int(self.productVersion, 16) + dic["productSerialNumber"] = self.productSerialNumber + dic["productAssetTag"] = self.productAssetTag + dic["productfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] # 0 + index += 1 + d_print("decode length %d" % (ord(self.data[index]) * 8)) + d_print("class size %d" % self.size) + index += 2 + + templen = FruUtil.decodeLength(self.data[index]) + self.productManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productManufacturer:%s" % self.productManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.productName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productName:%s" % self.productName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productPartModelName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productPartModelName:%s" % self.productPartModelName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productVersion = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productVersion:%s" % self.productVersion) + + templen = FruUtil.decodeLength(self.data[index]) + self.productSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productSerialNumber:%s" % self.productSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.productAssetTag = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productAssetTag:%s" % self.productAssetTag) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if self.data[index] != chr(0xc1) and index < self.size - 1: + templen = FruUtil.decodeLength(self.data[index]) + if templen == 0: + break + tmpval = self.data[index + 1: index + templen + 1] + d_print("decode boardextra%d:%s" % (i, tmpval)) + setattr(self, valtmp, tmpval) + index += templen + 1 + else: + break + + @property + def productVersion(self): + return self._productVersion + + @productVersion.setter + def productVersion(self, name): + self._productVersion = name + + @property + def areaversion(self): + self._areaversion = self.COMMON_HEAD_VERSION + return self._areaversion + + @areaversion.setter + def areaversion(self, name): + self._areaversion = name + + @property + def language(self): + self._language = 25 + return self._language + + @property + def productManufacturer(self): + return self._productManufacturer + + @productManufacturer.setter + def productManufacturer(self, name): + self._productManufacturer = name + + @property + def productName(self): + return self._productName + + @productName.setter + def productName(self, name): + self._productName = name + + @property + def productPartModelName(self): + return self._productPartModelName + + @productPartModelName.setter + def productPartModelName(self, name): + self._productPartModelName = name + + @property + def productSerialNumber(self): + return self._productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, name): + self._productSerialNumber = name + + @property + def productAssetTag(self): + return self._productAssetTag + + @productAssetTag.setter + def productAssetTag(self, name): + self._productAssetTag = name + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, name): + self._FRUFileID = name + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("product version:%x" % ord(self.areaversion)) + d_print("product length:%d" % self.size) + d_print("product language:%x" % self.language) + self.data = chr(ord(self.areaversion)) + \ + chr(self.size // 8) + chr(self.language) + + typelength = FruUtil.getTypeLength(self.productManufacturer) + self.data += chr(typelength) + self.data += self.productManufacturer + + self.data += chr(FruUtil.getTypeLength(self.productName)) + self.data += self.productName + + self.data += chr(FruUtil.getTypeLength(self.productPartModelName)) + self.data += self.productPartModelName + + self.data += chr(FruUtil.getTypeLength(self.productVersion)) + self.data += self.productVersion + + self.data += chr(FruUtil.getTypeLength(self.productSerialNumber)) + self.data += self.productSerialNumber + + self.data += chr(FruUtil.getTypeLength(self.productAssetTag)) + if self.productAssetTag is not None: + self.data += self.productAssetTag + + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + d_print("self.data:%d" % len(self.data)) + d_print("self.size:%d" % self.size) + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + +class MultiRecordArea(BaseArea): + pass + + +class Field(object): + + def __init__(self, fieldType="ASCII", fieldData=""): + self.fieldData = fieldData + self.fieldType = fieldType + + @property + def fieldType(self): + return self.fieldType + + @property + def fieldData(self): + return self.fieldData + + +class ipmifru(BaseArea): + _BoardInfoArea = None + _ProductInfoArea = None + _InternalUseArea = None + _ChassisInfoArea = None + _multiRecordArea = None + _productinfoAreaOffset = BaseArea.INITVALUE + _boardInfoAreaOffset = BaseArea.INITVALUE + _internalUserAreaOffset = BaseArea.INITVALUE + _chassicInfoAreaOffset = BaseArea.INITVALUE + _multiRecordAreaOffset = BaseArea.INITVALUE + _bindata = None + _bodybin = None + _version = BaseArea.COMMON_HEAD_VERSION + _zeroCheckSum = None + _frusize = 256 + + def __str__(self): + tmpstr = "" + if self.boardInfoArea.isPresent: + tmpstr += "\nboardinfoarea: \n" + tmpstr += self.boardInfoArea.__str__() + if self.productInfoArea.isPresent: + tmpstr += "\nproductinfoarea: \n" + tmpstr += self.productInfoArea.__str__() + return tmpstr + + def decodeBin(self, eeprom): + commonHead = eeprom[0:8] + d_print("decode version %x" % ord(commonHead[0])) + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): + raise FruException("HEAD VERSION error,not Fru format!", -10) + if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): + strtemp = "check header checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) + raise FruException(strtemp, -3) + if ord(commonHead[1]) != ord(self.INITVALUE): + d_print("Internal Use Area is present") + self.internalUseArea = InternalUseArea( + name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) + self.internalUseArea.isPresent = True + self.internalUserAreaOffset = ord(commonHead[1]) + self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( + self.internalUserAreaOffset * 8 + self.internalUseArea.size)] + if ord(commonHead[2]) != ord(self.INITVALUE): + d_print("Chassis Info Area is present") + self.chassisInfoArea = ChassisInfoArea( + name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) + self.chassisInfoArea.isPresent = True + self.chassicInfoAreaOffset = ord(commonHead[2]) + self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( + self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] + if ord(commonHead[3]) != ord(self.INITVALUE): + self.boardInfoArea = BoardInfoArea( + name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) + self.boardInfoArea.isPresent = True + self.boardInfoAreaOffset = ord(commonHead[3]) + self.boardInfoArea.size = ord( + eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8 + d_print("Board Info Area is present size:%d" % + (self.boardInfoArea.size)) + self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( + self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] + if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + (FruUtil.checksum( + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.boardInfoArea.decodedata() + if ord(commonHead[4]) != ord(self.INITVALUE): + d_print("Product Info Area is present") + self.productInfoArea = ProductInfoArea( + name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) + self.productInfoArea.isPresent = True + self.productinfoAreaOffset = ord(commonHead[4]) + d_print("length offset value: %02x" % + ord(eeprom[self.productinfoAreaOffset * 8 + 1])) + self.productInfoArea.size = ord( + eeprom[self.productinfoAreaOffset * 8 + 1]) * 8 + d_print("Product Info Area is present size:%d" % + (self.productInfoArea.size)) + + self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: ( + self.productinfoAreaOffset * 8 + self.productInfoArea.size)] + if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]): + strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.productInfoArea.decodedata() + if ord(commonHead[5]) != ord(self.INITVALUE): + self.multiRecordArea = MultiRecordArea( + name="MultiRecord record Area ") + d_print("MultiRecord record present") + self.multiRecordArea.isPresent = True + self.multiRecordAreaOffset = ord(commonHead[5]) + self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: ( + self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)] + + def initDefault(self): + self.version = self.COMMON_HEAD_VERSION + self.internalUserAreaOffset = self.INITVALUE + self.chassicInfoAreaOffset = self.INITVALUE + self.boardInfoAreaOffset = self.INITVALUE + self.productinfoAreaOffset = self.INITVALUE + self.multiRecordAreaOffset = self.INITVALUE + self.zeroCheckSum = self.INITVALUE + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + self.productInfoArea = None + self.internalUseArea = None + self.boardInfoArea = None + self.chassisInfoArea = None + self.multiRecordArea = None + # self.recalcute() + + @property + def version(self): + return self._version + + @version.setter + def version(self, name): + self._version = name + + @property + def internalUserAreaOffset(self): + return self._internalUserAreaOffset + + @internalUserAreaOffset.setter + def internalUserAreaOffset(self, obj): + self._internalUserAreaOffset = obj + + @property + def chassicInfoAreaOffset(self): + return self._chassicInfoAreaOffset + + @chassicInfoAreaOffset.setter + def chassicInfoAreaOffset(self, obj): + self._chassicInfoAreaOffset = obj + + @property + def productinfoAreaOffset(self): + return self._productinfoAreaOffset + + @productinfoAreaOffset.setter + def productinfoAreaOffset(self, obj): + self._productinfoAreaOffset = obj + + @property + def boardInfoAreaOffset(self): + return self._boardInfoAreaOffset + + @boardInfoAreaOffset.setter + def boardInfoAreaOffset(self, obj): + self._boardInfoAreaOffset = obj + + @property + def multiRecordAreaOffset(self): + return self._multiRecordAreaOffset + + @multiRecordAreaOffset.setter + def multiRecordAreaOffset(self, obj): + self._multiRecordAreaOffset = obj + + @property + def zeroCheckSum(self): + return self._zeroCheckSum + + @zeroCheckSum.setter + def zeroCheckSum(self, obj): + self._zeroCheckSum = obj + + @property + def productInfoArea(self): + return self._ProductInfoArea + + @productInfoArea.setter + def productInfoArea(self, obj): + self._ProductInfoArea = obj + + @property + def internalUseArea(self): + return self._InternalUseArea + + @internalUseArea.setter + def internalUseArea(self, obj): + self.internalUseArea = obj + + @property + def boardInfoArea(self): + return self._BoardInfoArea + + @boardInfoArea.setter + def boardInfoArea(self, obj): + self._BoardInfoArea = obj + + @property + def chassisInfoArea(self): + return self._ChassisInfoArea + + @chassisInfoArea.setter + def chassisInfoArea(self, obj): + self._ChassisInfoArea = obj + + @property + def multiRecordArea(self): + return self._multiRecordArea + + @multiRecordArea.setter + def multiRecordArea(self, obj): + self._multiRecordArea = obj + + @property + def bindata(self): + return self._bindata + + @bindata.setter + def bindata(self, obj): + self._bindata = obj + + @property + def bodybin(self): + return self._bodybin + + @bodybin.setter + def bodybin(self, obj): + self._bodybin = obj + + def recalcuteCommonHead(self): + self.bindata = "" + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) + if self.internalUseArea is not None and self.internalUseArea.isPresent: + self.internalUserAreaOffset = self.offset // 8 + self.offset += self.internalUseArea.size + d_print("internalUseArea is present offset:%d" % self.offset) + + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + self.chassicInfoAreaOffset = self.offset // 8 + self.offset += self.chassisInfoArea.size + d_print("chassisInfoArea is present offset:%d" % self.offset) + + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + self.boardInfoAreaOffset = self.offset // 8 + self.offset += self.boardInfoArea.size + d_print("boardInfoArea is present offset:%d" % self.offset) + d_print("boardInfoArea is present size:%d" % + self.boardInfoArea.size) + + if self.productInfoArea is not None and self.productInfoArea.isPresent: + self.productinfoAreaOffset = self.offset // 8 + self.offset += self.productInfoArea.size + d_print("productInfoArea is present offset:%d" % self.offset) + + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + self.multiRecordAreaOffset = self.offset // 8 + d_print("multiRecordArea is present offset:%d" % self.offset) + + if self.internalUserAreaOffset == self.INITVALUE: + self.internalUserAreaOffset = 0 + if self.productinfoAreaOffset == self.INITVALUE: + self.productinfoAreaOffset = 0 + if self.chassicInfoAreaOffset == self.INITVALUE: + self.chassicInfoAreaOffset = 0 + if self.boardInfoAreaOffset == self.INITVALUE: + self.boardInfoAreaOffset = 0 + if self.multiRecordAreaOffset == self.INITVALUE: + self.multiRecordAreaOffset = 0 + + self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset + - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff + d_print("zerochecksum:%x" % self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) + + self.bindata = self.data + self.bodybin + totallen = len(self.bindata) + d_print("totallen %d" % totallen) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) + else: + raise FruException('bin data more than %d' % self._frusize, -2) + + def recalcutebin(self): + self.bodybin = "" + if self.internalUseArea is not None and self.internalUseArea.isPresent: + d_print("internalUseArea present") + self.bodybin += self.internalUseArea.data + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + d_print("chassisInfoArea present") + self.bodybin += self.chassisInfoArea.data + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + d_print("boardInfoArea present") + self.boardInfoArea.recalcute() + self.bodybin += self.boardInfoArea.data + if self.productInfoArea is not None and self.productInfoArea.isPresent: + d_print("productInfoAreapresent") + self.productInfoArea.recalcute() + self.bodybin += self.productInfoArea.data + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + d_print("multiRecordArea present") + self.bodybin += self.productInfoArea.data + + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size + self.recalcutebin() + self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py old mode 100755 new mode 100644 index f9cbb31be401..e300df137ef9 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py @@ -1,113 +1,235 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- -""" -* onboard temperature sensors -* FAN trays -* PSU -""" +# * onboard temperature sensors +# * FAN trays +# * PSU +# import os import xml.etree.ElementTree as ET import glob +import json +from decimal import Decimal +from fru import ipmifru + MAILBOX_DIR = "/sys/bus/i2c/devices/" -PORTS_DIR = "/sys/class/net/" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + CONFIG_NAME = "dev.xml" -def getPMCreg(location): +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + return val + + +def get_board_id(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +boardid = get_board_id() +boardairflow = getboardairflow() + + +DEV_XML_FILE_LIST = [ + "dev_" + boardid + "_" + boardairflow + ".xml", + "dev_" + boardid + ".xml", + "dev_" + boardairflow + ".xml", +] + + +def dev_file_read(path, offset, read_len): retval = "ERR" + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + return False, "%s %s not found" % (retval, path) + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, "%s %s" % (retval, msg) + finally: + if fd > 0: + os.close(fd) + return True, val_list + + +def getPMCreg(location): + retval = 'ERR' if not os.path.isfile(location): return "%s %s notfound" % (retval, location) try: - with open(location, "r") as fd: + with open(location, 'r') as fd: retval = fd.read() - except Exception: - pass - # logging.error("Unable to open ", location, "file !") + except Exception as error: + return "ERR %s" % str(error) - retval = retval.rstrip("\r\n") + retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval # Get a mailbox register def get_pmc_register(reg_name): - retval = "ERR" - if reg_name[0:4] == "/rif" or reg_name[0:4] == "/ma1" or reg_name[0:4] == "/eth": - mb_reg_file = PORTS_DIR + reg_name - else: - mb_reg_file = MAILBOX_DIR + reg_name + retval = 'ERR' + mb_reg_file = reg_name filepath = glob.glob(mb_reg_file) if len(filepath) == 0: return "%s %s notfound" % (retval, mb_reg_file) - mb_reg_file = filepath[0] # use first found patch + mb_reg_file = filepath[0] if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' return "%s %s notfound" % (retval, mb_reg_file) try: - with open(mb_reg_file, "r") as fd: + with open(mb_reg_file, 'rb') as fd: retval = fd.read() - except Exception: - pass - # logging.error("Unable to open ", mb_reg_file, "file !") + retval = typeTostr(retval) + except Exception as error: + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) - retval = retval.rstrip("\r\n") + retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval -class checktype: +class checktype(): def __init__(self, test1): self.test1 = test1 @staticmethod - def check(name, location, bit, value, tips, err1): - psu_status = int(get_pmc_register(location), 16) - val = (psu_status & (1 << bit)) >> bit - if val != value: - err1["errmsg"] = tips - err1["code"] = -1 - return -1 - else: - err1["errmsg"] = "none" - err1["code"] = 0 - return 0 - - @staticmethod - def getValue(location, bit, type): - value_t = get_pmc_register(location) - if value_t.startswith("ERR"): + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) return value_t - if type == 1: - return float(value_t) / 1000 - elif type == 2: - return float(value_t) / 100 - elif type == 3: - psu_status = int(value_t, 16) - return (psu_status & (1 << bit)) >> bit - elif type == 4: - return int(value_t, 10) - else: + except Exception as e: + value_t = "ERR %s" % str(e) return value_t - # temperature + # fanFRU @staticmethod - def getTemp(self, name, location, ret_t): - ret2 = self.getValue(location + "temp1_input", " ", 1) - ret3 = self.getValue(location + "temp1_max", " ", 1) - ret4 = self.getValue(location + "temp1_max_hyst", " ", 1) - ret_t["temp1_input"] = ret2 - ret_t["temp1_max"] = ret3 - ret_t["temp1_max_hyst"] = ret4 + def decodeBinByValue(retval): + fru = ipmifru() + fru.decodeBin(retval) + return fru @staticmethod - def getLM75(name, location, result): - c1 = checktype - r1 = {} - c1.getTemp(c1, name, location, r1) - result[name] = r1 + def getfruValue(prob_t, root, val): + try: + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) + fanpro = {} + ret = checktype.decodeBinByValue(binval) + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = str(int(ret.productInfoArea.productVersion, 16)) + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] + return fanpro + except Exception as error: + return "ERR " + str(error) + @staticmethod + def getslotfruValue(val): + try: + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + slotpro = {} + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber + return slotpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getpsufruValue(prob_t, root, val): + try: + psu_match = False + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + psupro = {} + ret = checktype.decodeBinByValue(binval) + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name in psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro + except Exception as error: + return "ERR " + str(error) -class status: + +class status(): def __init__(self, productname): self.productname = productname @@ -119,10 +241,12 @@ def getETroot(filename): @staticmethod def getDecodValue(collection, decode): - decodes = collection.find("decode") + decodes = collection.find('decode') testdecode = decodes.find(decode) test = {} - for neighbor in testdecode.iter("code"): + if testdecode is None: + return test + for neighbor in testdecode.iter('code'): test[neighbor.attrib["key"]] = neighbor.attrib["value"] return test @@ -136,37 +260,67 @@ def getETValue(a, filename, tagname): for neighbor in root.iter(tagname): prob_t = {} prob_t = neighbor.attrib - prob_t["errcode"] = 0 - prob_t["errmsg"] = "" + prob_t['errcode'] = 0 + prob_t['errmsg'] = '' for pros in neighbor.iter("property"): - ret = dict(neighbor.attrib.items() + pros.attrib.items()) - if "type" not in ret.keys(): + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) + if ret.get('e2type') == 'fru' and ret.get("name") == "fru": + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break + prob_t.update(fruval) + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): val = "0" else: val = ret["type"] - if "bit" not in ret.keys(): + if 'bit' not in ret.keys(): bit = "0" else: bit = ret["bit"] - s = checktype.getValue(ret["location"], int(bit), int(val)) + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) if isinstance(s, str) and s.startswith("ERR"): - prob_t["errcode"] = -1 - prob_t["errmsg"] = s - if "default" in ret.keys(): - rt = status.getDecodValue(root, ret["decode"]) - prob_t["errmsg"] = rt[str(s)] + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] if str(s) != ret["default"]: - prob_t["errcode"] = -1 + prob_t['errcode'] = -1 break else: - if "decode" in ret.keys(): - rt = status.getDecodValue(root, ret["decode"]) - if ( - ret["decode"] == "psutype" - and s.replace("\x00", "").rstrip() not in rt.keys() - ): # PSU type detect - prob_t["errcode"] = -1 - prob_t["errmsg"] = "%s" % ("The power type does not match, please check whether the power is correct!") + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) else: s = rt[str(s).replace("\x00", "").rstrip()] name = ret["name"] @@ -187,46 +341,39 @@ def getCPUValue(a, filename, tagname): for i in range(len(L)): prob_t = {} prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) - prob_t["temp"] = ( - float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 - ) - prob_t["alarm"] = ( - float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 - ) - prob_t["crit"] = ( - float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 - ) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 a.append(prob_t) @staticmethod def getFileName(): - return os.path.dirname(os.path.realpath(__file__)) + "/" + CONFIG_NAME - - @staticmethod - def getFan(ret): - _filename = status.getFileName() - _tagname = "fan" - status.getvalue(ret, _filename, _tagname) + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME @staticmethod def checkFan(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "fan" status.getETValue(ret, _filename, _tagname) @staticmethod def getTemp(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "temp" status.getETValue(ret, _filename, _tagname) @staticmethod def getPsu(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "psu" status.getETValue(ret, _filename, _tagname) @@ -237,8 +384,19 @@ def getcputemp(ret): status.getCPUValue(ret, _filename, _tagname) @staticmethod - def getMgmtRx(ret): + def getDcdc(ret): + _filename = status.getFileName() + _tagname = "dcdc" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmacpower(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() - _tagname = "mgmt_rx" + _tagname = "macpower" status.getETValue(ret, _filename, _tagname) diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml index 90ebf1740641..7b026cec395e 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml @@ -82,6 +82,12 @@ 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: 1d fn: '0' @@ -109,9 +115,8 @@ - bus: '01' dev: '00' fn: '0' - id: '1533' - name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev - 03)' + id: b873 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b873 (rev 01)' - bus: '03' dev: '00' fn: '0' @@ -149,8 +154,14 @@ - bus: '07' dev: '00' fn: '0' - id: b873 - name: 'Ethernet controller: Broadcom Limited Device b873 (rev 01)' + id: '1537' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Backplane Connection + (rev 03)' +- bus: 08 + dev: '00' + fn: '0' + id: '7022' + name: 'Memory controller: Xilinx Corporation Device 7022' - bus: ff dev: 0b fn: '0' diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/sfputil.py b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/sfputil.py new file mode 100644 index 000000000000..5415a0930c89 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/sfputil.py @@ -0,0 +1,243 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import os + import traceback + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 56 + PORTS_IN_BLOCK = 57 + + EEPROM_OFFSET = 32 + SFP_DEVICE_TYPE = "optoe2" + QSFP_DEVICE_TYPE = "optoe1" + I2C_MAX_ATTEMPT = 3 + + _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(49, self.PORTS_IN_BLOCK) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + self.port_to_i2cbus_mapping[x] = x + self.EEPROM_OFFSET - 1 + SfpUtilBase.__init__(self) + + def _sfp_read_file_path(self, file_path, offset, num_bytes): + attempts = 0 + while attempts < self.I2C_MAX_ATTEMPT: + try: + file_path.seek(offset) + read_buf = file_path.read(num_bytes) + except: + attempts += 1 + time.sleep(0.05) + return True, read_buf + return False, None + + def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): + """Tries to read the eeprom file to determine if the + device/sfp is present or not. If sfp present, the read returns + valid bytes. If not, read returns error 'Connection timed out""" + + if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): + return False + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv + + def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): + try: + sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path + + # Write device address to new_device file + nd_str = "%s %s" % (devtype, hex(devaddr)) + with open(sysfs_nd_path, "w") as nd_file: + nd_file.write(nd_str) + + except Exception as err: + print("Error writing to new device file: %s" % str(err)) + return 1 + else: + return 0 + + def _get_port_eeprom_path(self, port_num, devid): + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + + if port_num in self.port_to_eeprom_mapping: + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] + else: + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + + i2c_adapter_id = self._get_port_i2c_adapter_id(port_num) + if i2c_adapter_id is None: + print("Error getting i2c bus num") + return None + + # Get i2c virtual bus path for the sfp + sysfs_sfp_i2c_adapter_path = "%s/i2c-%s" % (sysfs_i2c_adapter_base_path, + str(i2c_adapter_id)) + + # If i2c bus for port does not exist + if not os.path.exists(sysfs_sfp_i2c_adapter_path): + print("Could not find i2c bus %s. Driver not loaded?" % sysfs_sfp_i2c_adapter_path) + return None + + sysfs_sfp_i2c_client_path = "%s/%s-00%s" % (sysfs_sfp_i2c_adapter_path, + str(i2c_adapter_id), + hex(devid)[-2:]) + + # If sfp device is not present on bus, Add it + if not os.path.exists(sysfs_sfp_i2c_client_path): + if port_num in self.qsfp_ports: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DEVICE_TYPE) + else: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.SFP_DEVICE_TYPE) + if ret != 0: + print("Error adding sfp device") + return None + + sysfs_sfp_i2c_client_eeprom_path = "%s/eeprom" % sysfs_sfp_i2c_client_path + + return sysfs_sfp_i2c_client_eeprom_path + + def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) + if rv is False: + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + except: + return None + + return eeprom_raw + + 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 + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + presence_path = "/sys/wb_plat/sff/sff%d/present" % port_num + + try: + with open(presence_path, "rb") as data: + presence_data = data.read(2) + if presence_data == "": + return False + result = int(presence_data, 16) + except IOError: + return False + + if result == 1: + return True + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + + return True + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return True + + def get_transceiver_change_event(self, timeout=0): + return False, {} + + def get_highest_temperature(self): + offset = 0 + hightest_temperature = -9999 + + presence_flag = False + read_eeprom_flag = False + temperature_valid_flag = False + + for port in range(49, self.PORTS_IN_BLOCK): + if self.get_presence(port) is False: + continue + + presence_flag = True + + if port in self.qsfp_ports: + offset = 22 + else: + offset = 96 + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = float(result / 256.0) + if -50 <= result <= 200: + temperature_valid_flag = True + hightest_temperature = max(hightest_temperature, result) + except BaseException: + print(traceback.format_exc()) + + # all port not presence + if presence_flag is False: + hightest_temperature = -10000 + + # all port read eeprom fail + elif read_eeprom_flag is False: + hightest_temperature = -9999 + + # all port temperature invalid + elif read_eeprom_flag is True and temperature_valid_flag is False: + hightest_temperature = -10000 + + hightest_temperature = round(hightest_temperature, 2) + + return hightest_temperature diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/ssd_util.py b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/ssd_util.py new file mode 100755 index 000000000000..e92782a0969b --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/ssd_util.py @@ -0,0 +1,309 @@ +# +# ssd_util.py +# +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium + +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_ssd.ssd_base import SsdBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SMARTCTL = "smartctl {} -a" +INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + +NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 + +class SsdUtil(SsdBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE + + def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + + """ + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" + """ + self.model_attr = { + "ER2-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n231\s+(.+?)\n" } + } + + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = "[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" + + def _execute_shell(self, cmd): + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None + return output + + def _parse_re(self, pattern, buffer): + res_list = re.findall(pattern, str(buffer)) + return res_list[0] if res_list else NOT_AVAILABLE + + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re('Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re('Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re('Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re('Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re('\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re('SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re('Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re('Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + + def get_health(self): + """ + Retrieves current disk health in percentages + + Returns: + A float number of current ssd health + e.g. 83.5 + """ + return float(self.health) + + def get_temperature(self): + """ + Retrieves current disk temperature in Celsius + + Returns: + A float number of current temperature in Celsius + e.g. 40.1 + """ + return float(self.temperature) + + def get_model(self): + """ + Retrieves model for the given disk device + + Returns: + A string holding disk model as provided by the manufacturer + """ + return self.model + + def get_firmware(self): + """ + Retrieves firmware version for the given disk device + + Returns: + A string holding disk firmware version as provided by the manufacturer + """ + return self.firmware + + def get_serial(self): + """ + Retrieves serial number for the given disk device + + Returns: + A string holding disk serial number as provided by the manufacturer + """ + return self.serial + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life + def get_vendor_output(self): + """ + Retrieves vendor specific data for the given disk device + + Returns: + A string holding some vendor specific disk information + """ + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re('{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pmon_daemon_control.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pmon_daemon_control.json index 590def37b276..94592fa8cebc 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pmon_daemon_control.json +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pmon_daemon_control.json @@ -1,5 +1,3 @@ -{ - "skip_ledd": true, - "skip_xcvrd": false, - "skip_psud": false -} \ No newline at end of file +{ + "skip_ledd": true +} diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/system_health_monitoring_config.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/system_health_monitoring_config.json new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/RA-B6910-64C/th2-ra-b6910-64c-64x100G.config.bcm b/device/ragile/x86_64-ragile_ra-b6910-64c-r0/RA-B6910-64C/th2-ra-b6910-64c-64x100G.config.bcm index 787c851bcc2e..4f8424684a10 100644 --- a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/RA-B6910-64C/th2-ra-b6910-64c-64x100G.config.bcm +++ b/device/ragile/x86_64-ragile_ra-b6910-64c-r0/RA-B6910-64C/th2-ra-b6910-64c-64x100G.config.bcm @@ -1,3 +1,8 @@ +scache_filename=/var/warmboot/wbscache +stable_size=0x55000000 +stable_location=3 +warmboot_knet_shutdown_mode=1 + core_clock_frequency=1700 dpp_clock_ratio=2:3 table_dma_enable=1 diff --git a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/dev.xml b/device/ragile/x86_64-ragile_ra-b6910-64c-r0/dev.xml index 55d37fffd8eb..592658ab3af3 100644 --- a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/dev.xml +++ b/device/ragile/x86_64-ragile_ra-b6910-64c-r0/dev.xml @@ -8,28 +8,22 @@ - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - + + - - + + + - - + + - - + + + - - + + - - + + + - - + + - - + + + - - + + - - + + + - - + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + - - - - - - - + + + + - - - + + + + - - - - - - - + + + + - - - + + + + - - - - - - - + + + + - - - + + + + - - - - - - - + + + + - - + + + - - - - + + + - + + + - - - - + + + - + + + - - - - + + + - + + + - - - - + + + - + + + - + + - + + - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - - - - - - + + + + - - + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/fru.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/fru.py new file mode 100755 index 000000000000..f95164e03601 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/fru.py @@ -0,0 +1,961 @@ +#!/usr/bin/python3 +import collections +from datetime import datetime, timedelta +from bitarray import bitarray + + +__DEBUG__ = "N" + + +class FruException(Exception): + def __init__(self, message='fruerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +def e_print(err): + print("ERROR: " + err) + + +def d_print(debug_info): + if __DEBUG__ == "Y": + print(debug_info) + + +class FruUtil(): + @staticmethod + def decodeLength(value): + a = bitarray(8) + a.setall(True) + a[0:1] = 0 + a[1:2] = 0 + x = ord(a.tobytes()) + return x & ord(value) + + @staticmethod + def minToData(): + starttime = datetime(1996, 1, 1, 0, 0, 0) + endtime = datetime.now() + seconds = (endtime - starttime).total_seconds() + mins = seconds // 60 + m = int(round(mins)) + return m + + @staticmethod + def getTimeFormat(): + return datetime.now().strftime('%Y-%m-%d') + + @staticmethod + def getTypeLength(value): + if value is None or len(value) == 0: + return 0 + a = bitarray(8) + a.setall(False) + a[0:1] = 1 + a[1:2] = 1 + x = ord(a.tobytes()) + return x | len(value) + + @staticmethod + def checksum(b): + result = 0 + for item in b: + result += ord(item) + return (0x100 - (result & 0xff)) & 0xff + + +class BaseArea(object): + SUGGESTED_SIZE_COMMON_HEADER = 8 + SUGGESTED_SIZE_INTERNAL_USE_AREA = 72 + SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32 + SUGGESTED_SIZE_BOARD_INFO_AREA = 80 + SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80 + + INITVALUE = b'\x00' + resultvalue = INITVALUE * 256 + COMMON_HEAD_VERSION = b'\x01' + __childList = None + + def __init__(self, name="", size=0, offset=0): + self.__childList = [] + self._offset = offset + self.name = name + self._size = size + self._isPresent = False + self._data = b'\x00' * size + + @property + def childList(self): + return self.__childList + + @childList.setter + def childList(self, value): + self.__childList = value + + @property + def offset(self): + return self._offset + + @offset.setter + def offset(self, value): + self._offset = value + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + self._size = value + + @property + def data(self): + return self._data + + @data.setter + def data(self, value): + self._data = value + + @property + def isPresent(self): + return self._isPresent + + @isPresent.setter + def isPresent(self, value): + self._isPresent = value + + +class InternalUseArea(BaseArea): + pass + + +class ChassisInfoArea(BaseArea): + pass + + +class BoardInfoArea(BaseArea): + _boardTime = None + _fields = None + _mfg_date = None + areaversion = None + _boardversion = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "mfg_date : %s \n" \ + "boardManufacturer : %s \n" \ + "boardProductName : %s \n" \ + "boardSerialNumber : %s \n" \ + "boardPartNumber : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.boardversion), self.size, + self.language, self.getMfgRealData(), + self.boardManufacturer, self.boardProductName, + self.boardSerialNumber, self.boardPartNumber, + self.fruFileId) + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "boardextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["boardversion"] = ord(self.boardversion) + dic["boardlength"] = self.size + dic["boardlanguage"] = self.language + dic["boardmfg_date"] = self.getMfgRealData() + dic["boardManufacturer"] = self.boardManufacturer + dic["boardProductName"] = self.boardProductName + dic["boardSerialNumber"] = self.boardSerialNumber + dic["boardPartNumber"] = self.boardPartNumber + dic["boardfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] + index += 1 + d_print("decode length :%d class size:%d" % + ((ord(self.data[index]) * 8), self.size)) + index += 2 + + timetmp = self.data[index: index + 3] + self.mfg_date = ord(timetmp[0]) | ( + ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16) + d_print("decode getMfgRealData :%s" % self.getMfgRealData()) + index += 3 + + templen = FruUtil.decodeLength(self.data[index]) + self.boardManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardManufacturer:%s" % self.boardManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardProductName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardProductName:%s" % self.boardProductName) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardSerialNumber:%s" % self.boardSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardPartNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardPartNumber:%s" % self.boardPartNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if self.data[index] != chr(0xc1): + templen = FruUtil.decodeLength(self.data[index]) + tmpval = self.data[index + 1: index + templen + 1] + setattr(self, valtmp, tmpval) + index += templen + 1 + d_print("decode boardextra%d:%s" % (i, tmpval)) + else: + break + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("boardInfoArea version:%x" % ord(self.boardversion)) + d_print("boardInfoArea length:%d" % self.size) + d_print("boardInfoArea language:%x" % self.language) + self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea mfg_date:%x" % self.mfg_date) + + self.data = chr(ord(self.boardversion)) + \ + chr(self.size // 8) + chr(self.language) + + self.data += chr(self.mfg_date & 0xFF) + self.data += chr((self.mfg_date >> 8) & 0xFF) + self.data += chr((self.mfg_date >> 16) & 0xFF) + + d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer) + typelength = FruUtil.getTypeLength(self.boardManufacturer) + self.data += chr(typelength) + self.data += self.boardManufacturer + + d_print("boardInfoArea boardProductName:%s" % self.boardProductName) + self.data += chr(FruUtil.getTypeLength(self.boardProductName)) + self.data += self.boardProductName + + d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber) + self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber)) + self.data += self.boardSerialNumber + + d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber) + self.data += chr(FruUtil.getTypeLength(self.boardPartNumber)) + self.data += self.boardPartNumber + + d_print("boardInfoArea fruFileId:%s" % self.fruFileId) + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + d_print("self data:%d" % len(self.data)) + d_print("self size:%d" % self.size) + d_print("adjust size:%d" % (self.size - len(self.data) - 1)) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + + # checksum + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + def getMfgRealData(self): + starttime = datetime(1996, 1, 1, 0, 0, 0) + mactime = starttime + timedelta(minutes=self.mfg_date) + return mactime + + @property + def language(self): + self._language = 25 + return self._language + + @property + def mfg_date(self): + return self._mfg_date + + @mfg_date.setter + def mfg_date(self, val): + self._mfg_date = val + + @property + def boardversion(self): + self._boardversion = self.COMMON_HEAD_VERSION + return self._boardversion + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, val): + self._FRUFileID = val + + @property + def boardPartNumber(self): + return self._boardPartNumber + + @boardPartNumber.setter + def boardPartNumber(self, val): + self._boardPartNumber = val + + @property + def boardSerialNumber(self): + return self._boardSerialNumber + + @boardSerialNumber.setter + def boardSerialNumber(self, val): + self._boardSerialNumber = val + + @property + def boardProductName(self): + return self._boradProductName + + @boardProductName.setter + def boardProductName(self, val): + self._boradProductName = val + + @property + def boardManufacturer(self): + return self._boardManufacturer + + @boardManufacturer.setter + def boardManufacturer(self, val): + self._boardManufacturer = val + + @property + def boardTime(self): + return self._boardTime + + @boardTime.setter + def boardTime(self, val): + self._boardTime = val + + @property + def fields(self): + return self._fields + + @fields.setter + def fields(self, val): + self._fields = val + + +class ProductInfoArea(BaseArea): + _productManufacturer = None + _productAssetTag = None + _FRUFileID = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "productAssetTag : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.areaversion), self.size, + self.language, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, + self.productAssetTag, self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "productextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["productversion"] = ord(self.areaversion) + dic["productlength"] = self.size + dic["productlanguage"] = self.language + dic["productManufacturer"] = self.productManufacturer + dic["productName"] = self.productName + dic["productPartModelName"] = self.productPartModelName + dic["productVersion"] = int(self.productVersion, 16) + dic["productSerialNumber"] = self.productSerialNumber + dic["productAssetTag"] = self.productAssetTag + dic["productfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] # 0 + index += 1 + d_print("decode length %d" % (ord(self.data[index]) * 8)) + d_print("class size %d" % self.size) + index += 2 + + templen = FruUtil.decodeLength(self.data[index]) + self.productManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productManufacturer:%s" % self.productManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.productName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productName:%s" % self.productName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productPartModelName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productPartModelName:%s" % self.productPartModelName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productVersion = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productVersion:%s" % self.productVersion) + + templen = FruUtil.decodeLength(self.data[index]) + self.productSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productSerialNumber:%s" % self.productSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.productAssetTag = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productAssetTag:%s" % self.productAssetTag) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if self.data[index] != chr(0xc1) and index < self.size - 1: + templen = FruUtil.decodeLength(self.data[index]) + if templen == 0: + break + tmpval = self.data[index + 1: index + templen + 1] + d_print("decode boardextra%d:%s" % (i, tmpval)) + setattr(self, valtmp, tmpval) + index += templen + 1 + else: + break + + @property + def productVersion(self): + return self._productVersion + + @productVersion.setter + def productVersion(self, name): + self._productVersion = name + + @property + def areaversion(self): + self._areaversion = self.COMMON_HEAD_VERSION + return self._areaversion + + @areaversion.setter + def areaversion(self, name): + self._areaversion = name + + @property + def language(self): + self._language = 25 + return self._language + + @property + def productManufacturer(self): + return self._productManufacturer + + @productManufacturer.setter + def productManufacturer(self, name): + self._productManufacturer = name + + @property + def productName(self): + return self._productName + + @productName.setter + def productName(self, name): + self._productName = name + + @property + def productPartModelName(self): + return self._productPartModelName + + @productPartModelName.setter + def productPartModelName(self, name): + self._productPartModelName = name + + @property + def productSerialNumber(self): + return self._productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, name): + self._productSerialNumber = name + + @property + def productAssetTag(self): + return self._productAssetTag + + @productAssetTag.setter + def productAssetTag(self, name): + self._productAssetTag = name + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, name): + self._FRUFileID = name + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("product version:%x" % ord(self.areaversion)) + d_print("product length:%d" % self.size) + d_print("product language:%x" % self.language) + self.data = chr(ord(self.areaversion)) + \ + chr(self.size // 8) + chr(self.language) + + typelength = FruUtil.getTypeLength(self.productManufacturer) + self.data += chr(typelength) + self.data += self.productManufacturer + + self.data += chr(FruUtil.getTypeLength(self.productName)) + self.data += self.productName + + self.data += chr(FruUtil.getTypeLength(self.productPartModelName)) + self.data += self.productPartModelName + + self.data += chr(FruUtil.getTypeLength(self.productVersion)) + self.data += self.productVersion + + self.data += chr(FruUtil.getTypeLength(self.productSerialNumber)) + self.data += self.productSerialNumber + + self.data += chr(FruUtil.getTypeLength(self.productAssetTag)) + if self.productAssetTag is not None: + self.data += self.productAssetTag + + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + d_print("self.data:%d" % len(self.data)) + d_print("self.size:%d" % self.size) + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + +class MultiRecordArea(BaseArea): + pass + + +class Field(object): + + def __init__(self, fieldType="ASCII", fieldData=""): + self.fieldData = fieldData + self.fieldType = fieldType + + @property + def fieldType(self): + return self.fieldType + + @property + def fieldData(self): + return self.fieldData + + +class ipmifru(BaseArea): + _BoardInfoArea = None + _ProductInfoArea = None + _InternalUseArea = None + _ChassisInfoArea = None + _multiRecordArea = None + _productinfoAreaOffset = BaseArea.INITVALUE + _boardInfoAreaOffset = BaseArea.INITVALUE + _internalUserAreaOffset = BaseArea.INITVALUE + _chassicInfoAreaOffset = BaseArea.INITVALUE + _multiRecordAreaOffset = BaseArea.INITVALUE + _bindata = None + _bodybin = None + _version = BaseArea.COMMON_HEAD_VERSION + _zeroCheckSum = None + _frusize = 256 + + def __str__(self): + tmpstr = "" + if self.boardInfoArea.isPresent: + tmpstr += "\nboardinfoarea: \n" + tmpstr += self.boardInfoArea.__str__() + if self.productInfoArea.isPresent: + tmpstr += "\nproductinfoarea: \n" + tmpstr += self.productInfoArea.__str__() + return tmpstr + + def decodeBin(self, eeprom): + commonHead = eeprom[0:8] + d_print("decode version %x" % ord(commonHead[0])) + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): + raise FruException("HEAD VERSION error,not Fru format!", -10) + if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): + strtemp = "check header checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) + raise FruException(strtemp, -3) + if ord(commonHead[1]) != ord(self.INITVALUE): + d_print("Internal Use Area is present") + self.internalUseArea = InternalUseArea( + name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) + self.internalUseArea.isPresent = True + self.internalUserAreaOffset = ord(commonHead[1]) + self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( + self.internalUserAreaOffset * 8 + self.internalUseArea.size)] + if ord(commonHead[2]) != ord(self.INITVALUE): + d_print("Chassis Info Area is present") + self.chassisInfoArea = ChassisInfoArea( + name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) + self.chassisInfoArea.isPresent = True + self.chassicInfoAreaOffset = ord(commonHead[2]) + self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( + self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] + if ord(commonHead[3]) != ord(self.INITVALUE): + self.boardInfoArea = BoardInfoArea( + name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) + self.boardInfoArea.isPresent = True + self.boardInfoAreaOffset = ord(commonHead[3]) + self.boardInfoArea.size = ord( + eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8 + d_print("Board Info Area is present size:%d" % + (self.boardInfoArea.size)) + self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( + self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] + if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + (FruUtil.checksum( + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.boardInfoArea.decodedata() + if ord(commonHead[4]) != ord(self.INITVALUE): + d_print("Product Info Area is present") + self.productInfoArea = ProductInfoArea( + name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) + self.productInfoArea.isPresent = True + self.productinfoAreaOffset = ord(commonHead[4]) + d_print("length offset value: %02x" % + ord(eeprom[self.productinfoAreaOffset * 8 + 1])) + self.productInfoArea.size = ord( + eeprom[self.productinfoAreaOffset * 8 + 1]) * 8 + d_print("Product Info Area is present size:%d" % + (self.productInfoArea.size)) + + self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: ( + self.productinfoAreaOffset * 8 + self.productInfoArea.size)] + if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]): + strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.productInfoArea.decodedata() + if ord(commonHead[5]) != ord(self.INITVALUE): + self.multiRecordArea = MultiRecordArea( + name="MultiRecord record Area ") + d_print("MultiRecord record present") + self.multiRecordArea.isPresent = True + self.multiRecordAreaOffset = ord(commonHead[5]) + self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: ( + self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)] + + def initDefault(self): + self.version = self.COMMON_HEAD_VERSION + self.internalUserAreaOffset = self.INITVALUE + self.chassicInfoAreaOffset = self.INITVALUE + self.boardInfoAreaOffset = self.INITVALUE + self.productinfoAreaOffset = self.INITVALUE + self.multiRecordAreaOffset = self.INITVALUE + self.zeroCheckSum = self.INITVALUE + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + self.productInfoArea = None + self.internalUseArea = None + self.boardInfoArea = None + self.chassisInfoArea = None + self.multiRecordArea = None + # self.recalcute() + + @property + def version(self): + return self._version + + @version.setter + def version(self, name): + self._version = name + + @property + def internalUserAreaOffset(self): + return self._internalUserAreaOffset + + @internalUserAreaOffset.setter + def internalUserAreaOffset(self, obj): + self._internalUserAreaOffset = obj + + @property + def chassicInfoAreaOffset(self): + return self._chassicInfoAreaOffset + + @chassicInfoAreaOffset.setter + def chassicInfoAreaOffset(self, obj): + self._chassicInfoAreaOffset = obj + + @property + def productinfoAreaOffset(self): + return self._productinfoAreaOffset + + @productinfoAreaOffset.setter + def productinfoAreaOffset(self, obj): + self._productinfoAreaOffset = obj + + @property + def boardInfoAreaOffset(self): + return self._boardInfoAreaOffset + + @boardInfoAreaOffset.setter + def boardInfoAreaOffset(self, obj): + self._boardInfoAreaOffset = obj + + @property + def multiRecordAreaOffset(self): + return self._multiRecordAreaOffset + + @multiRecordAreaOffset.setter + def multiRecordAreaOffset(self, obj): + self._multiRecordAreaOffset = obj + + @property + def zeroCheckSum(self): + return self._zeroCheckSum + + @zeroCheckSum.setter + def zeroCheckSum(self, obj): + self._zeroCheckSum = obj + + @property + def productInfoArea(self): + return self._ProductInfoArea + + @productInfoArea.setter + def productInfoArea(self, obj): + self._ProductInfoArea = obj + + @property + def internalUseArea(self): + return self._InternalUseArea + + @internalUseArea.setter + def internalUseArea(self, obj): + self.internalUseArea = obj + + @property + def boardInfoArea(self): + return self._BoardInfoArea + + @boardInfoArea.setter + def boardInfoArea(self, obj): + self._BoardInfoArea = obj + + @property + def chassisInfoArea(self): + return self._ChassisInfoArea + + @chassisInfoArea.setter + def chassisInfoArea(self, obj): + self._ChassisInfoArea = obj + + @property + def multiRecordArea(self): + return self._multiRecordArea + + @multiRecordArea.setter + def multiRecordArea(self, obj): + self._multiRecordArea = obj + + @property + def bindata(self): + return self._bindata + + @bindata.setter + def bindata(self, obj): + self._bindata = obj + + @property + def bodybin(self): + return self._bodybin + + @bodybin.setter + def bodybin(self, obj): + self._bodybin = obj + + def recalcuteCommonHead(self): + self.bindata = "" + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) + if self.internalUseArea is not None and self.internalUseArea.isPresent: + self.internalUserAreaOffset = self.offset // 8 + self.offset += self.internalUseArea.size + d_print("internalUseArea is present offset:%d" % self.offset) + + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + self.chassicInfoAreaOffset = self.offset // 8 + self.offset += self.chassisInfoArea.size + d_print("chassisInfoArea is present offset:%d" % self.offset) + + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + self.boardInfoAreaOffset = self.offset // 8 + self.offset += self.boardInfoArea.size + d_print("boardInfoArea is present offset:%d" % self.offset) + d_print("boardInfoArea is present size:%d" % + self.boardInfoArea.size) + + if self.productInfoArea is not None and self.productInfoArea.isPresent: + self.productinfoAreaOffset = self.offset // 8 + self.offset += self.productInfoArea.size + d_print("productInfoArea is present offset:%d" % self.offset) + + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + self.multiRecordAreaOffset = self.offset // 8 + d_print("multiRecordArea is present offset:%d" % self.offset) + + if self.internalUserAreaOffset == self.INITVALUE: + self.internalUserAreaOffset = 0 + if self.productinfoAreaOffset == self.INITVALUE: + self.productinfoAreaOffset = 0 + if self.chassicInfoAreaOffset == self.INITVALUE: + self.chassicInfoAreaOffset = 0 + if self.boardInfoAreaOffset == self.INITVALUE: + self.boardInfoAreaOffset = 0 + if self.multiRecordAreaOffset == self.INITVALUE: + self.multiRecordAreaOffset = 0 + + self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset + - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff + d_print("zerochecksum:%x" % self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) + + self.bindata = self.data + self.bodybin + totallen = len(self.bindata) + d_print("totallen %d" % totallen) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) + else: + raise FruException('bin data more than %d' % self._frusize, -2) + + def recalcutebin(self): + self.bodybin = "" + if self.internalUseArea is not None and self.internalUseArea.isPresent: + d_print("internalUseArea present") + self.bodybin += self.internalUseArea.data + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + d_print("chassisInfoArea present") + self.bodybin += self.chassisInfoArea.data + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + d_print("boardInfoArea present") + self.boardInfoArea.recalcute() + self.bodybin += self.boardInfoArea.data + if self.productInfoArea is not None and self.productInfoArea.isPresent: + d_print("productInfoAreapresent") + self.productInfoArea.recalcute() + self.bodybin += self.productInfoArea.data + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + d_print("multiRecordArea present") + self.bodybin += self.productInfoArea.data + + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size + self.recalcutebin() + self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/monitor.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/monitor.py index 3aa8fd3f2901..93332a92ad29 100644 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/monitor.py +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/monitor.py @@ -1,5 +1,4 @@ -#!/usr/bin/python -# -*- coding: UTF-8 -*- +#!/usr/bin/python3 # * onboard temperature sensors # * FAN trays # * PSU @@ -7,92 +6,154 @@ import os import xml.etree.ElementTree as ET import glob -from eepromutil.fru import * +import json +from decimal import Decimal +from fru import ipmifru + MAILBOX_DIR = "/sys/bus/i2c/devices/" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + CONFIG_NAME = "dev.xml" + +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + return val + + +def get_board_id(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +boardid = get_board_id() +boardairflow = getboardairflow() + + +DEV_XML_FILE_LIST = [ + "dev_" + boardid + "_" + boardairflow + ".xml", + "dev_" + boardid + ".xml", + "dev_" + boardairflow + ".xml", +] + + +def dev_file_read(path, offset, read_len): + retval = "ERR" + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + return False, "%s %s not found" % (retval, path) + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, "%s %s" % (retval, msg) + finally: + if fd > 0: + os.close(fd) + return True, val_list + + def getPMCreg(location): retval = 'ERR' - if (not os.path.isfile(location)): - return "%s %s notfound"% (retval , location) + if not os.path.isfile(location): + return "%s %s notfound" % (retval, location) try: with open(location, 'r') as fd: retval = fd.read() except Exception as error: - pass + return "ERR %s" % str(error) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval + + # Get a mailbox register def get_pmc_register(reg_name): retval = 'ERR' mb_reg_file = reg_name filepath = glob.glob(mb_reg_file) - if(len(filepath) == 0): - return "%s %s notfound"% (retval , mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) mb_reg_file = filepath[0] - if (not os.path.isfile(mb_reg_file)): - #print mb_reg_file, 'not found !' - return "%s %s notfound"% (retval , mb_reg_file) + if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' + return "%s %s notfound" % (retval, mb_reg_file) try: - with open(mb_reg_file, 'r') as fd: + with open(mb_reg_file, 'rb') as fd: retval = fd.read() + retval = typeTostr(retval) except Exception as error: - pass + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval + class checktype(): def __init__(self, test1): self.test1 = test1 + @staticmethod - def check(name,location, bit, value, tips , err1): - psu_status = int(get_pmc_register(location),16) - val = (psu_status & (1<< bit)) >> bit - if (val != value): - err1["errmsg"] = tips - err1["code"] = -1 - return -1 - else: - err1["errmsg"] = "none" - err1["code"] = 0 - return 0 - @staticmethod - def getValue(location, bit , type): - value_t = get_pmc_register(location) - if value_t.startswith("ERR") : + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) + return value_t + except Exception as e: + value_t = "ERR %s" % str(e) return value_t - if (type == 1): - return float(value_t)/1000 - elif (type == 2): - return float(value_t)/100 - elif (type == 3): - psu_status = int(value_t,16) - return (psu_status & (1<< bit)) >> bit - elif (type == 4): - return int(value_t,10) - else: - return value_t; -#######temp - @staticmethod - def getTemp(self, name, location , ret_t): - ret2 = self.getValue(location + "temp1_input" ," " ,1); - ret3 = self.getValue(location + "temp1_max" ," ", 1); - ret4 = self.getValue(location + "temp1_max_hyst" ," ", 1); - ret_t["temp1_input"] = ret2 - ret_t["temp1_max"] = ret3 - ret_t["temp1_max_hyst"] = ret4 - @staticmethod - def getLM75(name, location, result): - c1=checktype - r1={} - c1.getTemp(c1, name, location, r1) - result[name] = r1 -##########fanFRU + + # fanFRU @staticmethod def decodeBinByValue(retval): fru = ipmifru() @@ -100,30 +161,72 @@ def decodeBinByValue(retval): return fru @staticmethod - def printbinvalue(b): - index = 0 - print " ", - for width in range(16): - print "%02x " % width, - print "" - for i in range(0, len(b)): - if index % 16 == 0: - print " " - print " %02x " % i, - print "%02x " % ord(b[i]), - index += 1 - print "" - - @staticmethod - def getfruValue(val): - binval = checktype.getValue(val, 0 , 0) - fanpro = {} - ret = checktype.decodeBinByValue(binval) - fanpro['fan_type'] = ret.productInfoArea.productName - fanpro['hw_version'] = int(ret.productInfoArea.productVersion, 16) - fanpro['sn'] = ret.productInfoArea.productSerialNumber - fanpro['fanid'] = ret.productInfoArea.productextra2 - return fanpro + def getfruValue(prob_t, root, val): + try: + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) + fanpro = {} + ret = checktype.decodeBinByValue(binval) + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = ret.productInfoArea.productVersion + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] + return fanpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getslotfruValue(val): + try: + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + slotpro = {} + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber + return slotpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getpsufruValue(prob_t, root, val): + try: + psu_match = False + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + psupro = {} + ret = checktype.decodeBinByValue(binval) + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name in psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro + except Exception as error: + return "ERR " + str(error) class status(): @@ -134,101 +237,148 @@ def __init__(self, productname): def getETroot(filename): tree = ET.parse(filename) root = tree.getroot() - return root; + return root @staticmethod def getDecodValue(collection, decode): decodes = collection.find('decode') testdecode = decodes.find(decode) - test={} + test = {} + if testdecode is None: + return test for neighbor in testdecode.iter('code'): - test[neighbor.attrib["key"]]=neighbor.attrib["value"] + test[neighbor.attrib["key"]] = neighbor.attrib["value"] return test + @staticmethod def getfileValue(location): - return checktype.getValue(location," "," ") + return checktype.getValue(location, " ", " ") + @staticmethod def getETValue(a, filename, tagname): root = status.getETroot(filename) for neighbor in root.iter(tagname): prob_t = {} prob_t = neighbor.attrib - prob_t['errcode']= 0 + prob_t['errcode'] = 0 prob_t['errmsg'] = '' for pros in neighbor.iter("property"): - ret = dict(neighbor.attrib.items() + pros.attrib.items()) + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) if ret.get('e2type') == 'fru' and ret.get("name") == "fru": - fruval = checktype.getfruValue(ret["location"]) + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break prob_t.update(fruval) - if ('type' not in ret.keys()): - val = "0"; + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("name") == "slot" and ret.get('e2type') == 'fru': + slotval = checktype.getslotfruValue( ret["location"]) + if isinstance(slotval, str) and slotval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = slotval + break + prob_t.update(slotval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): + val = "0" else: val = ret["type"] - if ('bit' not in ret.keys()): - bit = "0"; + if 'bit' not in ret.keys(): + bit = "0" else: bit = ret["bit"] - s = checktype.getValue(ret["location"], int(bit),int(val)) - if isinstance(s, str) and s.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= s - if ('default' in ret.keys()): - rt = status.getDecodValue(root,ret['decode']) - prob_t['errmsg']= rt[str(s)] + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) + if isinstance(s, str) and s.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] if str(s) != ret["default"]: - prob_t['errcode']= -1 - break; + prob_t['errcode'] = -1 + break else: - if ('decode' in ret.keys()): - rt = status.getDecodValue(root,ret['decode']) - if(ret['decode'] == "psutype" and s.replace("\x00","").rstrip() not in rt.keys()): - prob_t['errcode']= -1 - prob_t['errmsg'] = '%s'% ("Not supported PSU") + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) else: - s = rt[str(s).replace("\x00","").rstrip()] + s = rt[str(s).replace("\x00", "").rstrip()] name = ret["name"] - prob_t[name]=str(s) + prob_t[name] = str(s) a.append(prob_t) + @staticmethod def getCPUValue(a, filename, tagname): root = status.getETroot(filename) for neighbor in root.iter(tagname): - location = neighbor.attrib["location"] - L=[] + location = neighbor.attrib["location"] + L = [] for dirpath, dirnames, filenames in os.walk(location): - for file in filenames : + for file in filenames: if file.endswith("input"): L.append(os.path.join(dirpath, file)) - L =sorted(L,reverse=False) + L = sorted(L, reverse=False) for i in range(len(L)): prob_t = {} - prob_t["name"] = getPMCreg("%s/temp%d_label"%(location,i+1)) - prob_t["temp"] = float(getPMCreg("%s/temp%d_input"%(location,i+1)))/1000 - prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm"%(location,i+1)))/1000 - prob_t["crit"] = float(getPMCreg("%s/temp%d_crit"%(location,i+1)))/1000 - prob_t["max"] = float(getPMCreg("%s/temp%d_max"%(location,i+1)))/1000 + prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 + prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 a.append(prob_t) @staticmethod def getFileName(): - return os.path.dirname(os.path.realpath(__file__)) + "/"+ CONFIG_NAME - @staticmethod - def getFan(ret): - _filename = status.getFileName() - _tagname = "fan" - status.getvalue(ret, _filename, _tagname) + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME + @staticmethod def checkFan(ret): _filename = status.getFileName() # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "fan" status.getETValue(ret, _filename, _tagname) + @staticmethod def getTemp(ret): _filename = status.getFileName() - #_filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "temp" status.getETValue(ret, _filename, _tagname) + @staticmethod def getPsu(ret): _filename = status.getFileName() @@ -236,6 +386,13 @@ def getPsu(ret): _tagname = "psu" status.getETValue(ret, _filename, _tagname) + @staticmethod + def checkSlot(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "slot" + status.getETValue(ret, _filename, _tagname) + @staticmethod def getcputemp(ret): _filename = status.getFileName() @@ -243,10 +400,19 @@ def getcputemp(ret): status.getCPUValue(ret, _filename, _tagname) @staticmethod - def checkSlot(ret): + def getDcdc(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() - _tagname = "slot" + _tagname = "dcdc" status.getETValue(ret, _filename, _tagname) + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + @staticmethod + def getmacpower(ret): + _filename = status.getFileName() + _tagname = "macpower" + status.getETValue(ret, _filename, _tagname) diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pcie.yaml b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pcie.yaml new file mode 100644 index 000000000000..0dcb12e3d354 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pcie.yaml @@ -0,0 +1,441 @@ +- 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: '01' + fn: '1' + id: 6f03 + 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: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: '16' + fn: '0' + id: 8c3a + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #1 (rev 04)' +- bus: '00' + dev: '16' + fn: '1' + id: 8c3b + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #2 (rev 04)' +- 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: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '04' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '04' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '06' + dev: '00' + fn: '0' + id: b980 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b980 (rev 11)' +- bus: '07' + dev: '00' + fn: '0' + id: '1537' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Backplane 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: 0c + fn: '2' + id: 6fe2 + 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: '3' + id: 6fe3 + 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/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/sfputil.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/sfputil.py index afa98329a25c..9926f1296a2d 100644 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/sfputil.py +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/sfputil.py @@ -6,17 +6,16 @@ try: import time import os + import traceback from sonic_sfp.sfputilbase import SfpUtilBase 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 = 127 - PORT_QSFP_START = 0 PORTS_IN_BLOCK = 128 EEPROM_OFFSET = 71 @@ -24,12 +23,8 @@ class SfpUtil(SfpUtilBase): QSFP_DEVICE_TYPE = "optoe1" I2C_MAX_ATTEMPT = 3 - SFP_STATUS_INSERTED = '1' - SFP_STATUS_REMOVED = '0' - _port_to_eeprom_mapping = {} port_to_i2cbus_mapping ={} - port_dict = {} @property def port_start(self): @@ -41,7 +36,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_QSFP_START, self.PORTS_IN_BLOCK) + return range(0, self.PORTS_IN_BLOCK) @property def port_to_eeprom_mapping(self): @@ -49,11 +44,7 @@ def port_to_eeprom_mapping(self): def __init__(self): for x in range(self.PORT_START, self.PORTS_IN_BLOCK): - self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) - if self.get_presence(x): - self.port_dict[x] = self.SFP_STATUS_INSERTED - else: - self.port_dict[x] = self.SFP_STATUS_REMOVED + self.port_to_i2cbus_mapping[x] = x + self.EEPROM_OFFSET SfpUtilBase.__init__(self) def _sfp_read_file_path(self, file_path, offset, num_bytes): @@ -65,8 +56,7 @@ def _sfp_read_file_path(self, file_path, offset, num_bytes): except Exception: attempts += 1 time.sleep(0.05) - else: - return True, read_buf + return True, read_buf return False, None def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): @@ -76,20 +66,18 @@ def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): return False - else: - with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: - rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) - return rv + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): try: sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path # Write device address to new_device file - nd_file = open(sysfs_nd_path, "w") nd_str = "%s %s" % (devtype, hex(devaddr)) - nd_file.write(nd_str) - nd_file.close() + with open(sysfs_nd_path, "w") as nd_file: + nd_file.write(nd_str) except Exception as err: print("Error writing to new device file: %s" % str(err)) @@ -100,7 +88,7 @@ def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): def _get_port_eeprom_path(self, port_num, devid): sysfs_i2c_adapter_base_path = "" - if port_num in self.port_to_eeprom_mapping.keys(): + if port_num in self.port_to_eeprom_mapping: sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] else: sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" @@ -145,12 +133,12 @@ def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): eeprom_raw.append("0x00") rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) - if rv == False: + if rv is False: return None try: for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) except Exception: return None @@ -160,35 +148,28 @@ 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.IDENTITY_EEPROM_ADDR, 256) + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256) def get_presence(self, port_num): # Check for invalid port_num - #return True if port_num < self.port_start or port_num > self.port_end: return False - PRESENCE_OFFSET = 3 - presence_path = "/sys/bus/i2c/devices/%d-003%d/sfp_presence%d" % ((PRESENCE_OFFSET + (port_num // 32)), - ((port_num % 32) // 16), (((port_num % 32) // 8) + 1)) + #The sff number starts from 1 + presence_path = "/sys/wb_plat/sff/sff%d/present" % (port_num + 1) + try: - data = open(presence_path, "rb") + with open(presence_path, "rb") as data: + presence_data = data.read(2) + if presence_data == "": + return False + result = int(presence_data, 16) except IOError: return False - presence_data = data.read(2) - if presence_data != "": - result = int(presence_data, 16) - else : - return False - data.close() - - # ModPrsL is active low - if result & (1 << (port_num % 8)) == 0: + if result == 1: return True - return False def get_low_power_mode(self, port_num): @@ -209,47 +190,55 @@ def reset(self, port_num): return True def get_transceiver_change_event(self, timeout=0): + return False, {} - start_time = time.time() - currernt_port_dict = {} - forever = False + def get_highest_temperature(self): + offset = 0 + hightest_temperature = -9999 - if timeout == 0: - forever = True - elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs - else: - print ("get_transceiver_change_event:Invalid timeout value", timeout) - return False, {} + presence_flag = False + read_eeprom_flag = False + temperature_valid_flag = False - end_time = start_time + timeout - if start_time > end_time: - print ('get_transceiver_change_event:' \ - 'time wrap / invalid timeout value', timeout) + for port in range(0, self.PORTS_IN_BLOCK): + if self.get_presence(port) is False: + continue - return False, {} # Time wrap or possibly incorrect timeout + presence_flag = True - while timeout >= 0: - # Check for OIR events and return updated port_dict - for x in range(self.PORT_START, self.PORTS_IN_BLOCK): - if self.get_presence(x): - currernt_port_dict[x] = self.SFP_STATUS_INSERTED - else: - currernt_port_dict[x] = self.SFP_STATUS_REMOVED - if (currernt_port_dict == self.port_dict): - if forever: - time.sleep(1) - else: - timeout = end_time - time.time() - if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity - else: - if timeout > 0: - time.sleep(timeout) - return True, {} + if port in self.qsfp_ports: + offset = 22 else: - # Update reg value - self.port_dict = currernt_port_dict - return True, self.port_dict - print ("get_transceiver_change_event: Should not reach here.") - return False, {} + offset = 96 + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = float(result / 256.0) + if -50 <= result <= 200: + temperature_valid_flag = True + hightest_temperature = max(hightest_temperature, result) + except BaseException: + print(traceback.format_exc()) + + # all port not presence + if presence_flag is False: + hightest_temperature = -10000 + + # all port read eeprom fail + elif read_eeprom_flag is False: + hightest_temperature = -9999 + + # all port temperature invalid + elif read_eeprom_flag is True and temperature_valid_flag is False: + hightest_temperature = -10000 + + hightest_temperature = round(hightest_temperature, 2) + + return hightest_temperature diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/ssd_util.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/ssd_util.py index b6e5d6d3dd46..e92782a0969b 100644 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/ssd_util.py +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/ssd_util.py @@ -1,73 +1,222 @@ # -# ssd_health +# ssd_util.py # +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium -from sonic_platform_base.sonic_ssd.ssd_base import SsdBase -from subprocess import Popen, PIPE -from re import findall -from os.path import exists +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_ssd.ssd_base import SsdBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") +SMARTCTL = "smartctl {} -a" INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 class SsdUtil(SsdBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + """ - Constructor - Args: - diskdev: Linux device name to get parameters for + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" """ - if not isinstance(diskdev, str): - raise TypeError("disk dev type wrong {}".format(type(diskdev))) - - if not exists(diskdev): - raise RuntimeError("disk dev {} not found".format(diskdev)) - - self.model = NOT_AVAILABLE - self.serial = NOT_AVAILABLE - self.firmware = NOT_AVAILABLE - self.temperature = NOT_AVAILABLE - self.health = NOT_AVAILABLE + self.model_attr = { + "ER2-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n231\s+(.+?)\n" } + } - self.ssd_info = self._execute_shell(INNODISK.format(diskdev)) - - self.model = self._parse_re(r'Model Name:\s*(.+?)\n', self.ssd_info) - self.serial = self._parse_re(r'Serial Number:\s*(.+?)\n', self.ssd_info) - self.firmware = self._parse_re(r'FW Version:\s*(.+?)\n', self.ssd_info) - self.temperature = self._parse_re(r'Temperature\s*\[\s*(.+?)\]', self.ssd_info) - self.health = self._parse_re(r'Health:\s*(.+?)', self.ssd_info) + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = "[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" def _execute_shell(self, cmd): - process = Popen(cmd.split(), universal_newlines=True, stdout=PIPE) - output, _ = process.communicate() + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None return output def _parse_re(self, pattern, buffer): - res_list = findall(pattern, buffer) + res_list = re.findall(pattern, str(buffer)) return res_list[0] if res_list else NOT_AVAILABLE + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re('Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re('Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re('Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re('Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re('\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re('SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re('Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re('Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + def get_health(self): """ Retrieves current disk health in percentages + Returns: A float number of current ssd health e.g. 83.5 """ - return self.health + return float(self.health) def get_temperature(self): """ Retrieves current disk temperature in Celsius + Returns: A float number of current temperature in Celsius e.g. 40.1 """ - return self.temperature + return float(self.temperature) def get_model(self): """ Retrieves model for the given disk device + Returns: A string holding disk model as provided by the manufacturer """ @@ -76,6 +225,7 @@ def get_model(self): def get_firmware(self): """ Retrieves firmware version for the given disk device + Returns: A string holding disk firmware version as provided by the manufacturer """ @@ -84,15 +234,76 @@ def get_firmware(self): def get_serial(self): """ Retrieves serial number for the given disk device + Returns: A string holding disk serial number as provided by the manufacturer """ return self.serial - + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life def get_vendor_output(self): """ Retrieves vendor specific data for the given disk device + Returns: A string holding some vendor specific disk information """ - return self.ssd_info + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re('{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/system_health_monitoring_config.json b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/system_health_monitoring_config.json new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/platform-modules-ragile.mk b/platform/broadcom/platform-modules-ragile.mk index 74ce1b04f475..12236b1e72ce 100644 --- a/platform/broadcom/platform-modules-ragile.mk +++ b/platform/broadcom/platform-modules-ragile.mk @@ -4,7 +4,7 @@ export RAGILE_RA_B6510_48V8C_PLATFORM_MODULE_VERSION RAGILE_RA_B6510_48V8C_PLATFORM_MODULE = platform-modules-ragile-ra-b6510-48v8c_$(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE_VERSION)_amd64.deb $(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-ragile -$(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(PDDF_PLATFORM_MODULE) $(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE)_PLATFORM = x86_64-ragile_ra-b6510-48v8c-r0 SONIC_DPKG_DEBS += $(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE) SONIC_STRETCH_DEBS += $(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE) diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index 5f3172ca0305..938d741d188d 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -14,7 +14,7 @@ include $(PLATFORM_PATH)/platform-modules-cel.mk include $(PLATFORM_PATH)/platform-modules-juniper.mk #include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk #include $(PLATFORM_PATH)/platform-modules-ruijie.mk -#include $(PLATFORM_PATH)/platform-modules-ragile.mk +include $(PLATFORM_PATH)/platform-modules-ragile.mk include $(PLATFORM_PATH)/docker-syncd-brcm.mk include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk include $(PLATFORM_PATH)/docker-saiserver-brcm.mk diff --git a/platform/broadcom/sonic-platform-modules-ragile/LICENSE b/platform/broadcom/sonic-platform-modules-ragile/LICENSE old mode 100755 new mode 100644 index d37122689f3e..5681cac34476 --- a/platform/broadcom/sonic-platform-modules-ragile/LICENSE +++ b/platform/broadcom/sonic-platform-modules-ragile/LICENSE @@ -1,5 +1,4 @@ Copyright (C) 2016 Microsoft, Inc -Copyright (C) 2018 Ragile Network 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 2 diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/Makefile index 6daf3d2b2fd1..578d65b3bf3e 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/common/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/common/Makefile @@ -9,33 +9,34 @@ SUB_BUILD_DIR = $(PWD)/build DIR_KERNEL_SRC = $(PWD)/modules SCRIPT_DIR = $(PWD)/script SERVICE_DIR = $(PWD)/service -DEPMOD_CONF_DIR = $(PWD)/depmod_conf +BLACK_DRIVER_CONF_DIR = $(PWD)/modprobe_conf -KBUILD_EXTRA_SYMBOLS += $(DIR_KERNEL_SRC)/Module.symvers -export KBUILD_EXTRA_SYMBOLS +app_dir = $(PWD)/app +app_build_dir = $(app_dir)/build +modules_build_dir = $(DIR_KERNEL_SRC)/build INSTALL_MODULE_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system -INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3.7/dist-packages -INSTALL_DEPMOD_CONF = $(SUB_BUILD_DIR)/etc/depmod.d +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_BLACK_DRIVER = $(SUB_BUILD_DIR)/etc/modprobe.d all: - $(MAKE) -C $(KERNEL_SRC)/build M=$(DIR_KERNEL_SRC) modules + $(MAKE) -C $(app_dir) + $(MAKE) -C $(DIR_KERNEL_SRC) @if [ ! -d ${INSTALL_MODULE_DIR} ]; then mkdir -p ${INSTALL_MODULE_DIR} ;fi @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi @if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi @if [ -d $(PWD)/lib/ ]; then cp -r $(PWD)/lib/* ${INSTALL_LIB_DIR} ;fi - @if [ -d $(PWD)/lib/ ]; then cp -r $(PWD)/lib/* ${INSTALL_LIB_DIR2} ;fi - @if [ ! -d ${INSTALL_DEPMOD_CONF} ]; then mkdir -p ${INSTALL_DEPMOD_CONF} ;fi - cp -r $(DEPMOD_CONF_DIR)/* $(INSTALL_DEPMOD_CONF) - cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_MODULE_DIR) + @if [ -d $(PWD)/sonic_platform/ ]; then cp -rf $(PWD)/sonic_platform ${INSTALL_LIB_DIR} ;fi + cp -r $(app_build_dir)/module/*.ko $(INSTALL_MODULE_DIR) + cp -r $(modules_build_dir)/*.ko $(INSTALL_MODULE_DIR) + cp -r $(app_dir)/build/app/* $(INSTALL_SCRIPT_DIR) cp -r $(SCRIPT_DIR)/* $(INSTALL_SCRIPT_DIR) cp -r $(SERVICE_DIR)/* $(INSTALL_SERVICE_DIR) @if [ -d $(INSTALL_SCRIPT_DIR) ]; then chmod +x $(INSTALL_SCRIPT_DIR)/* ;fi + @if [ ! -d ${INSTALL_BLACK_DRIVER} ]; then mkdir -p ${INSTALL_BLACK_DRIVER} ;fi + cp -r $(BLACK_DRIVER_CONF_DIR)/* $(INSTALL_BLACK_DRIVER) clean: - rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd - rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order - rm -rf ${DIR_KERNEL_SRC}/.tmp_versions rm -rf $(SUB_BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/Makefile new file mode 100644 index 000000000000..25ba3c5a9156 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/Makefile @@ -0,0 +1,25 @@ +pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST)) +pes_parent_dir:=$(shell dirname $(pes_parent_dir)) + +SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "build") print $$9}') +INC = -I./inc + +COMMON_OUT_PUT := $(shell pwd)/build +common_out_put_dir := $(COMMON_OUT_PUT)/app +common_module_dir := $(COMMON_OUT_PUT)/module/ +export common_out_put_dir common_module_dir + +all : CHECK $(SUBDIRS) +CHECK : + @echo $(pes_parent_dir) + +$(SUBDIRS):ECHO + #@echo $@ + make -C $@ + +ECHO: + @echo $(SUBDIRS) + +.PHONY : clean +clean : + -rm -rf $(COMMON_OUT_PUT) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/Makefile new file mode 100644 index 000000000000..e4078716eb33 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/Makefile @@ -0,0 +1,30 @@ +top_srcdir:=$(shell pwd) +#include $(top_srcdir)/Rules.mk +DIR=$(shell pwd) +BUILD_OUTPUT=$(DIR)/tmp +SRCS=$(wildcard *.c) +OBJS=$(patsubst %.c, $(BUILD_OUTPUT)/%.o, $(SRCS)) +DEPS=$(patsubst %.o, %.d, $(OBJS)) +CFLAGS+=-Wall -W -g -I$(DIR)/include +LDFLAGS= +PROGRAM=dfd_debug + +.PHONY: all + +all:$(OBJS) + $(CC) $(OBJS) $(LDFLAGS) -o $(BUILD_OUTPUT)/$(PROGRAM) + @if [ ! -d ${common_out_put_dir} ]; then mkdir -p ${common_out_put_dir} ;fi + cp -p $(BUILD_OUTPUT)/$(PROGRAM) $(common_out_put_dir) + +$(OBJS):$(SRCS) + @if [ ! -d ${BUILD_OUTPUT} ]; then mkdir -p ${BUILD_OUTPUT} ;fi + $(CC) -c $(CFLAGS) $(INCLUDE) $(*F).c -o $@ + +.PHONY: install +install: + @mkdir -p $(common_out_put_dir) + cp -p $(BUILD_OUTPUT)/$(PROGRAM) $(common_out_put_dir) + +rebuild: clean all +clean: + @rm -rf $(BUILD_OUTPUT)/* diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_debug.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_debug.c new file mode 100644 index 000000000000..93ed6066efed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_debug.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "dfd_utest.h" + +int g_dfd_debug_sw = 0; +int g_dfd_debugpp_sw = 0; + +void dfd_debug_set_init(void) +{ + FILE *fp; + char buf[10]; + + mem_clear(buf, sizeof(buf)); + fp = fopen(DFD_DEBUGP_DEBUG_FILE, "r"); + if (fp != NULL) { + + g_dfd_debug_sw = 1; + fclose(fp); + } + + fp = fopen(DFD_DEBUGPP_DEBUG_FILE, "r"); + if (fp != NULL) { + + g_dfd_debugpp_sw = 1; + fclose(fp); + } + + return; +} + +int main(int argc, char* argv[]) +{ + dfd_debug_set_init(); + dfd_utest_cmd_main(argc, argv); + + return 0; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.c new file mode 100644 index 000000000000..9c711830958e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.c @@ -0,0 +1,1802 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dfd_utest.h" + +#define DFD_UTEST_MAX_RDWR_NUM (256) +#define DFD_UTEST_DEFAULT_WR_NUM (1) + +#define DEV_MEM_NAME "/dev/mem" +#define DEV_KMEM_NAME "/dev/kmem" + +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) +#define DFD_UTEST_MAX_BIT_WIDTH (4) + +#ifdef DFD_UTEST_ITEM +#undef DFD_UTEST_ITEM +#endif +#define DFD_UTEST_ITEM(_id, _type_str, _help_info, _help_info_detail) {_id, #_type_str, dfd_utest_##_type_str, _help_info, _help_info_detail}, +static dfd_utest_t g_dfd_unit_test[] = { + DFD_UTEST_ITEM_ALL +}; + +static int g_sys_page_size; +#define SYS_PAGE_SIZE g_sys_page_size +#define SYS_PAGE_MASK (~(SYS_PAGE_SIZE - 1)) + +void dfd_utest_print_cmd(int argc, char* argv[]) +{ + int i; + + for (i = 1; i < argc; i++) { + if (i != 1) { + printf(" "); + } + printf("%s", argv[i]); + } + return; +} + +void dfd_utest_print_all_help(void) +{ + int i, tbl_size; + + tbl_size = sizeof(g_dfd_unit_test) / sizeof(g_dfd_unit_test[0]); + + for (i = 0; i < tbl_size; i++) { + printf("%-20s\t\t\t%s\r\n", g_dfd_unit_test[i].type_str, g_dfd_unit_test[i].help_info); + } + + return; +} + +void dfd_utest_printf_single_help(int utest_type) +{ + int i, tbl_size; + + tbl_size = sizeof(g_dfd_unit_test) / sizeof(g_dfd_unit_test[0]); + for (i = 0; i < tbl_size; i++) { + if (g_dfd_unit_test[i].utest_type == utest_type) { + printf("%-20s\t\t\t%s\r\n", g_dfd_unit_test[i].type_str, g_dfd_unit_test[i].help_info_detail); + return; + } + } + + DFD_DEBUG_DBG("type: %d not match.\n", utest_type); + return; + +} + +void dfd_utest_printf_reg(uint8_t *buf, int buf_len, uint32_t offset_addr) +{ + int i, j, tmp; + + j = offset_addr % 16; + tmp = j; + offset_addr -= j; + printf("\n "); + + for (i = 0; i < 16; i++) { + printf("%2x ", i); + } + + for (i = 0; i < buf_len + j; i++) { + if ((i % 16) == 0) { + printf("\n0x%08x ", offset_addr); + offset_addr = offset_addr + 16; + } + if (tmp) { + printf(" "); + tmp--; + } else { + printf("%02x ", buf[i-j]); + } + } + + printf("\n"); + return; +} + +#define I2C_RETRIES 0x0701 +#define I2C_TIMEOUT 0x0702 +#define I2C_RDWR 0x0707 + +#define I2C_SLAVE 0x0703 /* Use this slave address */ + +#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it + is already in use by a driver! */ +#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */ +#define I2C_SMBUS 0x0720 /* SMBus transfer */ + +struct i2c_msg +{ + unsigned short addr; + unsigned short flags; +#define I2C_M_TEN 0x0010 +#define I2C_M_RD 0x0001 + unsigned short len; + unsigned char *buf; +}; + +struct i2c_rdwr_ioctl_data +{ + struct i2c_msg *msgs; + int nmsgs; + +}; + +#define DFD_I2C_SHORT_ADDR_TYPE 0 +#define DFD_I2C_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define DFD_I2C_RETRY_TIME (50000 / DFD_I2C_RETRY_SLEEP_TIME) +/* i2c_smbus_xfer read or write markers */ +#define I2C_SMBUS_READ 1 +#define I2C_SMBUS_WRITE 0 + +/* SMBus transaction types (size parameter in the above functions) + Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */ +#define I2C_SMBUS_QUICK 0 +#define I2C_SMBUS_BYTE 1 +#define I2C_SMBUS_BYTE_DATA 2 +#define I2C_SMBUS_WORD_DATA 3 +#define I2C_SMBUS_PROC_CALL 4 +#define I2C_SMBUS_BLOCK_DATA 5 +#define I2C_SMBUS_I2C_BLOCK_BROKEN 6 +#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS_I2C_BLOCK_DATA 8 + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,36) +/* fix tjm */ + +#ifndef __ASSEMBLY__ +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long __s64; +typedef unsigned long __u64; + +#endif /* __ASSEMBLY__ */ + +#else +/* do noting add tjm */ +#endif + +/* + * Data for SMBus Messages + */ +#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ +union i2c_smbus_data { + __u8 byte; + __u16 word; + __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ + /* and one more for user-space compatibility */ +}; + +/* This is the structure as used in the I2C_SMBUS ioctl call */ +struct i2c_smbus_ioctl_data { + __u8 read_write; + __u8 command; + __u32 size; + union i2c_smbus_data *data; +}; +int32_t dfd_read_port_i2c_one_time_smbus(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *recv_buf, int32_t size, int addr_type) +{ + union i2c_smbus_data data; + struct i2c_smbus_ioctl_data ioctl_data; + unsigned long addr = dev_addr; + int fd; + int rc; + int rv; + int i; + + mem_clear(&ioctl_data, sizeof(struct i2c_smbus_ioctl_data)); + if (i2c_name == NULL || recv_buf == NULL) { + DFD_DEBUG_ERROR("i2c_num = NULL, recv_buf = NULL\r\n"); + return -1; + } + + DFD_DEBUG_DBG("i2c name: %s, dev_addr: 0x%x, offset_addr: 0x%x, size: %d, addr_type: %d.\n", i2c_name, dev_addr, + offset_addr, size, addr_type); + + rv = 0; + fd = open(i2c_name, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd %d\n", fd); + rv = fd; + goto err; + } + if (ioctl(fd, I2C_SLAVE_FORCE , addr) < 0) { + DFD_DEBUG_ERROR("ioctl 2C_SLAVE_FORCE %d.\n", errno); + rv =-1; + goto fail; + } + for (i = 0 ;i < size; i++) { + data.byte = 0; + ioctl_data.read_write = I2C_SMBUS_READ; + ioctl_data.command = (offset_addr + i); + ioctl_data.size = I2C_SMBUS_BYTE_DATA; + ioctl_data.data= &data; + + rc = ioctl(fd, I2C_SMBUS, &ioctl_data); + if (rc < 0) { + DFD_DEBUG_ERROR("read, I2C_SMBUS failed: %d.\n", errno); + rv = -1; + goto fail; + } + *(recv_buf + i) = data.byte; + } + fail: + close(fd); + err: + return rv; + +} + +int32_t dfd_read_port_i2c_one_time(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *recv_buf, int32_t size, int addr_type) +{ + + int32_t fd, rv; + struct i2c_rdwr_ioctl_data ioctl_data; + struct i2c_msg msgs[2]; + uint8_t buf[2]; + + if (i2c_name == NULL || recv_buf == NULL) { + DFD_DEBUG_ERROR("i2c_num = NULL, recv_buf = NULL\r\n"); + return -1; + } + + DFD_DEBUG_DBG("i2c name %s, dev_addr 0x%x, offset_addr 0x%x, size %d, addr_type %d.\n", i2c_name, dev_addr, + offset_addr, size, addr_type); + + rv = 0; + fd = open(i2c_name, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd %d\n", fd); + return -1; + } + mem_clear(&ioctl_data, sizeof(ioctl_data)); + mem_clear(msgs, sizeof(msgs)); + mem_clear(buf, sizeof(buf)); + if (ioctl(fd, I2C_SLAVE, dev_addr) < 0) { + + DFD_DEBUG_ERROR("%s %dioctl fail(ret:%d, errno:%s)!\r\n", __func__ , __LINE__, rv, strerror(errno)); + rv = -1; + goto fail; + } + + buf[0] = (uint8_t)(offset_addr); + msgs[0].addr= dev_addr; + msgs[0].len= 2; + msgs[0].buf= buf; + msgs[1].addr= dev_addr; + msgs[1].flags|= I2C_M_RD; + msgs[1].len= 1; + msgs[1].buf= recv_buf; + ioctl_data.nmsgs= 1; + ioctl_data.msgs= msgs; + + rv = ioctl(fd, I2C_RDWR, &ioctl_data); + if(rv < 0) { + DFD_DEBUG_ERROR("%s %dioctl fail(ret:%d, errno:%s)!\r\n", __func__ , __LINE__, rv, strerror(errno)); + goto fail; + } + ioctl_data.msgs= &msgs[1]; + DFD_DEBUG_DBG("ioctlread, return :%d/n", ioctl(fd, I2C_RDWR, &ioctl_data)); + DFD_DEBUG_DBG("dfd_read_port_i2c addr: 0x%X, offset: 0x%X, value: 0x%X\n", dev_addr, offset_addr, *recv_buf); + fail: + close(fd); + return rv; + +} + +int32_t dfd_read_port_i2c(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *recv_buf, int32_t size) +{ + int i; + int rv; + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + rv = dfd_read_port_i2c_one_time_smbus(i2c_name, dev_addr, offset_addr, recv_buf, size, DFD_I2C_SHORT_ADDR_TYPE); + if (rv < 0) { + DFD_DEBUG_ERROR("(read times %d)i2c name %s, dev_addr 0x%X, offset_addr 0x%X, addr_type %d\n", i, i2c_name, dev_addr, offset_addr, DFD_I2C_SHORT_ADDR_TYPE); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + return rv; +} + +int32_t dfd_write_port_i2c_one_time(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *write_buf, int32_t size,int addr_type) +{ + int32_t fd, rv; + int index; + struct i2c_smbus_ioctl_data ioctl_data; + union i2c_smbus_data data; + uint8_t addr_buf[2]; + uint8_t write_buf_tmp[256]; + + if (i2c_name == NULL || write_buf == NULL ) { + DFD_DEBUG_ERROR("i2c_num = NULL \r\n"); + return -1; + } + + if (size <= 0) { + DFD_DEBUG_ERROR("error:size\n"); + return -1; + } + DFD_DEBUG_DBG("i2c name %s, dev_addr 0x%x, offset_addr 0x%x, size %d, addr_type %d\n",i2c_name, dev_addr, + offset_addr, size, addr_type); + mem_clear(&ioctl_data, sizeof(ioctl_data)); + mem_clear(addr_buf, sizeof(addr_buf)); + mem_clear(write_buf_tmp, sizeof(write_buf_tmp)); + + rv = 0; + + fd = open(i2c_name, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd %d\n", fd); + return -1; + } + + if (ioctl(fd, I2C_SLAVE_FORCE, dev_addr) < 0) { + DFD_DEBUG_ERROR("ioctl, I2C_SLAVE failed: %d.\n", errno); + rv = -1; + goto fail; + } + + for (index = 0; index < size; index++) { + data.byte = *(write_buf + index); + ioctl_data.read_write = I2C_SMBUS_WRITE; + ioctl_data.command = (offset_addr + index); + ioctl_data.size = I2C_SMBUS_BYTE_DATA; + ioctl_data.data= &data; + rv = ioctl(fd, I2C_SMBUS, (unsigned long)&ioctl_data); + if(rv < 0) { + DFD_DEBUG_ERROR("ioctl fail(ret:%d, errno:%s %d) !\r\n", rv, strerror(errno),errno); + break; + } + DFD_DEBUG_DBG("ret:%d value:0x%02x\n", rv, data.byte); + usleep(5000); + } + +fail: + close(fd); + return rv; +} + +int32_t dfd_write_port_i2c(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *write_buf, int32_t size) +{ + int i; + int rv; + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + rv = dfd_write_port_i2c_one_time(i2c_name, dev_addr, offset_addr, write_buf,size, DFD_I2C_SHORT_ADDR_TYPE); + if (rv < 0) { + DFD_DEBUG_ERROR("(write times %d)i2c name %s, dev_addr 0x%X, offset_addr 0x%X, addr_type %d\n", + i, i2c_name, dev_addr, offset_addr, DFD_I2C_SHORT_ADDR_TYPE); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + return rv; +} + +static int dfd_read_io_port(uint16_t offset_addr, uint8_t *recv_buf, int32_t size) +{ + int fd; + int ret; + + fd = open("/dev/port", O_RDWR); + if (fd < 0) { + printf("open failed ret %d.\n", fd); + return -1; + } + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek failed ret %d.\n", ret); + goto exit; + } + + ret = read(fd, recv_buf, size); + if (ret != size) { + printf("read failed ret %d size %d.\n", ret, size); + ret = -1; + goto exit; + } + +exit: + close(fd); + return ret; +} + +static int dfd_write_io_port(uint16_t offset_addr, uint8_t *write_buf, int32_t size) +{ + int fd; + int ret; + + fd = open("/dev/port", O_RDWR); + if (fd < 0) { + printf("open failed ret %d.\n", fd); + return -1; + } + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek failed ret %d.\n", ret); + goto exit; + } + + ret = write(fd, write_buf, size); + if (ret != size) { + printf("write failed ret %d size %d.\n", ret, size); + ret = -1; + goto exit; + } + +exit: + close(fd); + return ret; +} + +static int dfd_process_mem(char *dev_name, char is_wr, char width, off_t offset, uint8_t *buf, int32_t size) +{ + int mfd, ret = 0; + void *base; + int i, j; + unsigned int val; + off_t map_offset; + size_t map_size; + + if (size & (width - 1)) { + printf("size %d invalid.\n", size); + return -1; + } + + mfd = open(dev_name, O_RDWR); + if (mfd < 0) { + printf("Cannot open %s.\n", dev_name); + return -1; + } + + g_sys_page_size = getpagesize(); + map_offset = offset & SYS_PAGE_MASK; + map_size = size + offset - map_offset; + base = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, map_offset); + if (base == MAP_FAILED) { + printf("mmap offset 0x%lx failed error(%s).\n", map_offset, strerror(errno)); + close(mfd); + return -1; + } + printf("width %d map_offset 0x%lx, offset 0x%lx, mmap base %p, g_sys_page_size %d\n", + width, map_offset, offset, base, g_sys_page_size); + + if (is_wr) { + for (i = 0; i < size; i = i + width) { + val = 0; + for (j = 0; j < width; j++) { + val |= buf[i + j] << (8 * j); + } + switch (width) { + case 1: + *((volatile unsigned char*)(base + i + offset - map_offset)) = val; + break; + case 2: + *((volatile unsigned short*)(base + i + offset - map_offset)) = val; + break; + case 4: + *((volatile unsigned int*)(base + i + offset - map_offset)) = val; + break; + default: + ret = -1; + printf("Not support width %d.\n", width); + goto exit; + } + } + } else { + for (i = 0; i < size; i = i + width) { + switch (width) { + case 1: + val = *((volatile unsigned char*)(base + i + offset - map_offset)); + break; + case 2: + val = *((volatile unsigned short*)(base + i + offset - map_offset)); + break; + case 4: + val = *((volatile unsigned int*)(base + i + offset - map_offset)); + break; + default: + ret = -1; + printf("Not support width %d.\n", width); + goto exit; + } + for (j = 0; j < width; j++) { + buf[i + j] = (val >> (8 * j)) & 0xff; + } + } + } +exit: + munmap(base, map_size); + close(mfd); + return ret; +} + +int32_t dfd_i2c_gen_read_one_time(char *i2c_path, uint32_t dev_addr, uint32_t addr_bitwidth, + uint32_t offset_addr, uint8_t *recv_buf, int32_t rd_len) +{ + int32_t fd, rv, i; + struct i2c_rdwr_ioctl_data ioctl_data; + struct i2c_msg msgs[2]; + uint8_t buf[DFD_UTEST_MAX_BIT_WIDTH]; + + fd = open(i2c_path, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd:%d\n", fd); + return -1; + } + mem_clear(&ioctl_data, sizeof(ioctl_data)); + mem_clear(msgs, sizeof(msgs)); + mem_clear(buf, sizeof(buf)); + + i = 0; + + switch (addr_bitwidth) { + case WIDTH_4Byte: + buf[i++] = (offset_addr >> 24) & 0xFF; + buf[i++] = (offset_addr >> 16) & 0xFF; + buf[i++] = (offset_addr >> 8) & 0xFF; + buf[i++] = offset_addr & 0xFF; + break; + case WIDTH_2Byte: + buf[i++] = (offset_addr >> 8) & 0xFF; + buf[i++] = offset_addr & 0xFF; + break; + case WIDTH_1Byte: + buf[i++] = offset_addr & 0xFF; + break; + default: + DFD_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set %u addr_bitwidth \n", addr_bitwidth); + rv = -1; + goto fail; + } + + msgs[0].addr = dev_addr; + msgs[0].flags = 0; + msgs[0].len = addr_bitwidth; + msgs[0].buf = buf; + msgs[1].addr = dev_addr; + msgs[1].flags |= I2C_M_RD; + msgs[1].len = rd_len; + msgs[1].buf = recv_buf; + ioctl_data.nmsgs = 2; + ioctl_data.msgs = msgs; + + rv = ioctl(fd, I2C_RDWR, &ioctl_data); + if(rv < 0) { + DFD_DEBUG_ERROR("%s %d Error: Sending messages failed:(ret:%d, errno:%s)!\n", __func__ , __LINE__, rv, strerror(errno)); + goto fail; + } + +fail: + close(fd); + return rv; +} + +int32_t dfd_i2c_gen_read(char *i2c_path, uint32_t dev_addr, uint32_t addr_bitwidth, + uint32_t offset_addr, uint8_t *recv_buf, int32_t rd_len) +{ + int i; + int rv; + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + rv = dfd_i2c_gen_read_one_time(i2c_path, dev_addr, addr_bitwidth, offset_addr, recv_buf, rd_len); + if (rv < 0) { + DFD_DEBUG_ERROR("(read times:%d) i2c_path:%s, dev_addr:0x%x, addr_bitwidth:%u, offset_addr:0x%x, rd_len:%u\n", + i, i2c_path, dev_addr, addr_bitwidth, offset_addr, rd_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + return rv; +} + +int dfd_utest_i2c_gen_rd(int argc, char* argv[]) +{ + int ret; + uint32_t i2c_bus, dev_addr, addr_bitwidth, offset_addr, data_bitwidth, rd_len, i, j; + char *stopstring; + char i2c_path[32]; + uint8_t tmp_value[DFD_UTEST_MAX_RDWR_NUM]; + uint8_t rd_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc != 8) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_GEN_RD); + goto exit; + } + + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + addr_bitwidth = strtol(argv[4], &stopstring, 10); + offset_addr = strtol(argv[5], &stopstring, 16); + data_bitwidth = strtol(argv[6], &stopstring, 10); + rd_len = strtol(argv[7], &stopstring, 10); + + if (rd_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", rd_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_GEN_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + mem_clear(tmp_value, sizeof(tmp_value)); + ret = dfd_i2c_gen_read(i2c_path, dev_addr, addr_bitwidth, offset_addr, tmp_value, rd_len); + if (ret < 0) { + printf("read failed. ret:%d\n", ret); + goto exit; + } + + mem_clear(rd_value, sizeof(rd_value)); + if (data_bitwidth == WIDTH_1Byte) { + memcpy(rd_value, tmp_value, rd_len); + } else { + for (i = 0; i < rd_len; i += data_bitwidth) { + for (j = 0; (j < data_bitwidth) && (i + j < rd_len); j++) { + rd_value[i + data_bitwidth - j - 1] = tmp_value[i + j]; + } + } + } + + dfd_utest_printf_reg(rd_value, rd_len, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int32_t dfd_i2c_gen_write_one_time(char *i2c_path, uint32_t dev_addr, uint32_t addr_bitwidth, + uint32_t offset_addr, uint8_t *wr_value, uint32_t wr_len) +{ + int32_t fd, rv, i; + struct i2c_rdwr_ioctl_data ioctl_data; + struct i2c_msg msgs[1]; + uint8_t buf[DFD_UTEST_MAX_BIT_WIDTH + DFD_UTEST_MAX_RDWR_NUM]; + + fd = open(i2c_path, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd %d\n", fd); + return -1; + } + mem_clear(&ioctl_data, sizeof(ioctl_data)); + mem_clear(msgs, sizeof(msgs)); + mem_clear(buf, sizeof(buf)); + + i = 0; + + switch (addr_bitwidth) { + case WIDTH_4Byte: + buf[i++] = (offset_addr >> 24) & 0xFF; + buf[i++] = (offset_addr >> 16) & 0xFF; + buf[i++] = (offset_addr >> 8) & 0xFF; + buf[i++] = offset_addr & 0xFF; + break; + case WIDTH_2Byte: + buf[i++] = (offset_addr >> 8) & 0xFF; + buf[i++] = offset_addr & 0xFF; + break; + case WIDTH_1Byte: + buf[i++] = offset_addr & 0xFF; + break; + default: + DFD_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set %u addr_bitwidth \r\n", addr_bitwidth); + rv = -1; + goto fail; + } + + memcpy(buf + addr_bitwidth, wr_value, wr_len); + + msgs[0].addr= dev_addr; + msgs[0].flags = 0; + msgs[0].len= addr_bitwidth + wr_len; + msgs[0].buf= buf; + + ioctl_data.nmsgs= 1; + ioctl_data.msgs= msgs; + + rv = ioctl(fd, I2C_RDWR, &ioctl_data); + if(rv < 0) { + DFD_DEBUG_ERROR("%s %dError: Sending messages failed:(ret:%d, errno:%s)!\n", __func__ , __LINE__, rv, strerror(errno)); + goto fail; + } else if (rv < ioctl_data.nmsgs) { + DFD_DEBUG_ERROR("%s %dWarning: only %d/%d messages were sent\n", __func__ , __LINE__, rv, ioctl_data.nmsgs); + } + +fail: + close(fd); + return rv; +} + +int32_t dfd_i2c_gen_write(char *i2c_path, uint32_t dev_addr, uint32_t addr_bitwidth, + uint32_t offset_addr, uint8_t *wr_value, uint32_t wr_len) +{ + int i; + int rv; + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + rv = dfd_i2c_gen_write_one_time(i2c_path, dev_addr, addr_bitwidth, offset_addr, wr_value, wr_len); + if (rv < 0) { + DFD_DEBUG_ERROR("(write times:%d)i2c_path:%s, dev_addr:0x%x, addr_bitwidth:%u, offset_addr:0x%x, wr_len:%u\n", + i, i2c_path, dev_addr, addr_bitwidth, offset_addr, wr_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + return rv; +} + +int dfd_utest_i2c_gen_wr(int argc, char* argv[]) +{ + int ret; + uint32_t i2c_bus, dev_addr, addr_bitwidth, offset_addr, data_bitwidth, wr_len, tmp_data, para_len, i, j; + char *stopstring; + char i2c_path[32]; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 8) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_GEN_WR); + goto exit; + } + + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + addr_bitwidth = strtol(argv[4], &stopstring, 10); + offset_addr = strtol(argv[5], &stopstring, 16); + data_bitwidth = strtol(argv[6], &stopstring, 10); + + para_len = argc - 7; + wr_len = para_len * data_bitwidth; + + if (wr_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", wr_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_GEN_WR); + goto exit; + } + + if (data_bitwidth == WIDTH_1Byte) { + for (i = 0; i < para_len; i++) { + wr_value[i] = strtol(argv[7 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value 0x%x\n", i , wr_value[i]); + } + } else { + for (i = 0; i < para_len; i++) { + tmp_data = strtol(argv[7 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value 0x%x\n", i , tmp_data); + for (j = 0; j < data_bitwidth; j++) { + tmp_data = strtol(argv[7 + i], &stopstring, 16); + wr_value[j + i * data_bitwidth] = (tmp_data >> (24 - 8 * j)) & 0xFF; + } + } + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + + ret = dfd_i2c_gen_write(i2c_path, dev_addr, addr_bitwidth, offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("write failed. ret:%d\n", ret); + } else { + printf("write success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_i2c_rd(int argc, char* argv[]) +{ + int ret; + uint8_t value[DFD_UTEST_MAX_RDWR_NUM]; + uint16_t dev_addr, offset_addr; + char *stopstring; + int num, i2c_bus; + char i2c_path[32]; + + if (argc != 6) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_RD); + goto exit; + } + + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + offset_addr = strtol(argv[4], &stopstring, 16); + num = strtol(argv[5], &stopstring, 10); + + if (num > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", num); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + mem_clear(value, sizeof(value)); + ret = dfd_read_port_i2c(i2c_path, dev_addr, offset_addr, value, num); + if (ret < 0) { + printf("failed ret %d\n", ret); + goto exit; + } + + dfd_utest_printf_reg(value, num, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; + +} + +int dfd_utest_i2c_wr(int argc, char* argv[]) +{ + int ret; + uint16_t dev_addr, offset_addr; + char *stopstring; + int i2c_bus; + char i2c_path[32]; + uint8_t wr_len,i; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 6) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_WR); + goto exit; + } + + wr_len = argc - 5; + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + offset_addr = strtol(argv[4], &stopstring, 16); + + for (i = 0; i < wr_len; i++) { + wr_value[i] = strtol(argv[5+i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value %x\n", i , wr_value[i]); + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + + ret = dfd_write_port_i2c(i2c_path, dev_addr, offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_io_rd(int argc, char* argv[]) +{ + int ret; + uint8_t value[DFD_UTEST_MAX_RDWR_NUM]; + uint16_t offset_addr; + char *stopstring; + int num; + + if (argc != 4) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_IO_RD); + goto exit; + } + + offset_addr = strtol(argv[2], &stopstring, 16); + num = strtol(argv[3], &stopstring, 10); + + if (num > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", num); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_IO_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + mem_clear(value, sizeof(value)); + ret = dfd_read_io_port(offset_addr, value, num); + if (ret < 0) { + printf("failed ret %d\n", ret); + goto exit; + } + + dfd_utest_printf_reg(value, num, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_io_wr(int argc, char* argv[]) +{ + int ret; + uint16_t offset_addr; + char *stopstring; + int32_t wr_len,i; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 4) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_IO_WR); + goto exit; + } + + wr_len = argc - 3; + if (wr_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", wr_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_IO_WR); + goto exit; + } + + offset_addr = strtol(argv[2], &stopstring, 16); + + for (i = 0; i < wr_len; i++) { + wr_value[i] = strtol(argv[3 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value %x\n", i , wr_value[i]); + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + ret = dfd_write_io_port(offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_phymem_rd(int argc, char* argv[]) +{ + int ret, width; + uint8_t value[DFD_UTEST_MAX_RDWR_NUM]; + off_t offset_addr; + char *stopstring; + int num; + + if (argc != 5) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_PHYMEM_RD); + goto exit; + } + + width = strtol(argv[2], &stopstring, 10); + offset_addr = strtol(argv[3], &stopstring, 16); + num = strtol(argv[4], &stopstring, 10); + + if (num > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", num); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_PHYMEM_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + mem_clear(value, sizeof(value)); + ret = dfd_process_mem(DEV_MEM_NAME, 0, width, offset_addr, value, num); + if (ret < 0) { + printf("failed ret %d\n", ret); + goto exit; + } + + dfd_utest_printf_reg(value, num, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_phymem_wr(int argc, char* argv[]) +{ + int ret, width; + off_t offset_addr; + char *stopstring; + int32_t wr_len,i; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 5) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_PHYMEM_WR); + goto exit; + } + + wr_len = argc - 4; + if (wr_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", wr_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_PHYMEM_WR); + goto exit; + } + + width = strtol(argv[2], &stopstring, 10); + offset_addr = strtol(argv[3], &stopstring, 16); + + for (i = 0; i < wr_len; i++) { + wr_value[i] = strtol(argv[4 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value %x\n", i , wr_value[i]); + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + ret = dfd_process_mem(DEV_MEM_NAME, 1, width, offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_kmem_rd(int argc, char* argv[]) +{ + int ret, width; + uint8_t value[DFD_UTEST_MAX_RDWR_NUM]; + uint16_t offset_addr; + char *stopstring; + int num; + + if (argc != 5) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_KMEM_RD); + goto exit; + } + + width = strtol(argv[2], &stopstring, 10); + offset_addr = strtol(argv[3], &stopstring, 16); + num = strtol(argv[4], &stopstring, 10); + + if (num > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", num); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_KMEM_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + mem_clear(value, sizeof(value)); + ret = dfd_process_mem(DEV_KMEM_NAME, 0, width, offset_addr, value, num); + if (ret < 0) { + printf("failed ret %d\n", ret); + goto exit; + } + + dfd_utest_printf_reg(value, num, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_kmem_wr(int argc, char* argv[]) +{ + int ret; + uint16_t offset_addr, width; + char *stopstring; + int32_t wr_len,i; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 5) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_KMEM_WR); + goto exit; + } + + wr_len = argc - 4; + if (wr_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", wr_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_KMEM_WR); + goto exit; + } + + width = strtol(argv[2], &stopstring, 10); + offset_addr = strtol(argv[3], &stopstring, 16); + + for (i = 0; i < wr_len; i++) { + wr_value[i] = strtol(argv[4 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value %x\n", i , wr_value[i]); + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + ret = dfd_process_mem(DEV_KMEM_NAME, 1, width, offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +static unsigned long dfd_utest_get_file_size(const char *path) +{ + unsigned long filesize; + struct stat statbuff; + + if (stat(path, &statbuff) < 0) { + filesize = -1; + } else { + filesize = statbuff.st_size; + } + + return filesize; +} + +int dfd_utest_i2c_file_wr(int argc, char* argv[]) +{ + int ret; + uint16_t dev_addr, offset_addr; + char *stopstring; + int i2c_bus; + char i2c_path[32]; + char *file_name; + unsigned long filesize; + int fd; + uint8_t wr_buf[DFD_UTEST_MAX_RDWR_NUM]; + int len; + int bpt; /* byte per times*/ + int page_left; + + if (argc != 7) { + printf("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_FILE_WR); + goto exit; + } + + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + offset_addr = strtol(argv[4], &stopstring, 16); + bpt = strtol(argv[5], &stopstring, 10); + file_name = argv[6]; + + if ((bpt <= 0) || (bpt > DFD_UTEST_MAX_RDWR_NUM)) { + bpt = DFD_UTEST_MAX_RDWR_NUM; + } + + if ((bpt & (bpt - 1)) != 0) { + printf("Bytes per times %d isn't power of two.\n",bpt); + goto exit; + } + + filesize = dfd_utest_get_file_size(file_name); + if (filesize <= 0) { + printf("Input invalid file %s, filesize %lu.\n", file_name, filesize); + goto exit; + } + + fd = open(file_name, O_RDONLY); + if (fd < 0) { + printf("open file[%s] fail.\n", file_name); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + + while (filesize > 0) { + mem_clear(wr_buf, DFD_UTEST_MAX_RDWR_NUM); + len = bpt; + if (offset_addr & (bpt - 1)) { + page_left = bpt - (offset_addr & (bpt - 1)); + len = len > page_left ? page_left : len; + } + + len = read(fd, wr_buf, len); + + ret = dfd_write_port_i2c(i2c_path, dev_addr, offset_addr, wr_buf, len); + if (ret < 0) { + break; + } + offset_addr += len; + filesize -= len; + } + + close(fd); + + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } + +exit: + return DFD_RV_MODE_NOTSUPPORT; + +} + +/* compare with sys_flie_wr, One more step is read back verification */ +int dfd_utest_sysfs_file_upg(int argc, char* argv[]) +{ + int ret = 0; + uint32_t offset_addr; + char *file_name; + char *sysfs_loc; + char *stopstring; + unsigned long filesize; + int fd, file_fd; + uint8_t wr_buf[DFD_UTEST_MAX_RDWR_NUM]; + int len, write_len, per_wr_len; + int i; + uint8_t reread_buf[DFD_UTEST_MAX_RDWR_NUM]; + int reback_len, reread_len; + int j = 0; + + if (argc != 5 && argc != 6) { + printf("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_SYSFS_FILE_UPG); + goto exit; + } + + sysfs_loc = argv[2]; + offset_addr = strtol(argv[3], &stopstring, 16); + file_name = argv[4]; + + if (argc == 6) { + per_wr_len = strtol(argv[5], &stopstring, 10); + if (per_wr_len > DFD_UTEST_MAX_RDWR_NUM || per_wr_len <= 0) { + printf("per_wr_byte %d invalid, not in range (0, 256]\n", per_wr_len); + goto exit; + } + } else { + per_wr_len = DFD_UTEST_DEFAULT_WR_NUM; + } + DFD_DEBUG_DBG("per_wr_byte: %d\n", per_wr_len); + filesize = dfd_utest_get_file_size(file_name); + if (filesize <= 0) { + printf("Input invalid file %s, filesize %lu.\n", file_name, filesize); + goto exit; + } + + fd = open(sysfs_loc, O_RDWR | O_SYNC); + if (fd < 0) { + printf("open file[%s] fail.\n", sysfs_loc); + goto exit; + } + + file_fd = open(file_name, O_RDONLY); + if (file_fd < 0) { + printf("open file[%s] fail.\n", file_name); + goto open_dev_err; + } + + dfd_utest_print_cmd(argc, argv); + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek file[%s offset=%d] fail,\n", sysfs_loc, offset_addr); + goto fail; + } + + printf(":\n"); + while (filesize > 0) { + if (filesize > (unsigned long)per_wr_len) { + len = per_wr_len; + } else { + len = filesize; + } + + mem_clear(wr_buf, DFD_UTEST_MAX_RDWR_NUM); + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + len = read(file_fd, wr_buf, len); + if (len < 0) { + DFD_DEBUG_ERROR("read file[%s] fail, offset = 0x%x retrytimes = %d ret = %d\n", + sysfs_loc, offset_addr, i ,len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == DFD_I2C_RETRY_TIME) { + printf("read file[%s] fail, offset = 0x%x, ret = %d\n", sysfs_loc, offset_addr, len); + goto fail; + } + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + write_len = write(fd, wr_buf, len); + if (write_len != len) { + DFD_DEBUG_ERROR("write file[%s] fail,offset = 0x%x retrytimes = %d len = %d,write_len =%d\n", + sysfs_loc, offset_addr, i ,len, write_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == DFD_I2C_RETRY_TIME) { + printf("write file[%s] fail, offset = 0x%x, len = %d,write_len =%d\n", + sysfs_loc, offset_addr, len, write_len); + goto fail; + } + + reback_len = write_len; + ret = lseek(fd, -reback_len, SEEK_CUR); + if (ret < 0) { + printf("reread lseek file[%s offset=%d] fail,lseek len=%d\n", + sysfs_loc, offset_addr, reback_len); + goto fail; + } + + mem_clear(reread_buf, DFD_UTEST_MAX_RDWR_NUM); + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + reread_len = read(fd, reread_buf, reback_len); + if (reread_len != reback_len) { + DFD_DEBUG_ERROR("reread file[%s] fail,offset = 0x%x retrytimes = %d reread_len = %d,reback_len =%d\n", + sysfs_loc, offset_addr, i ,reread_len, reback_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == DFD_I2C_RETRY_TIME) { + printf("reread file[%s] fail, offset = 0x%x, reread_len = %d,reback_len = %d\n", + sysfs_loc, offset_addr, reread_len, reback_len); + goto fail; + } + + if (memcmp(reread_buf, wr_buf, reread_len) != 0) { + if (j < DFD_I2C_RETRY_TIME) { + DFD_DEBUG_ERROR("memcmp file[%s] fail,offset = 0x%x retrytimes = %d\n", + sysfs_loc, offset_addr, j); + j++; + ret = lseek(file_fd, -len, SEEK_CUR); + if (ret < 0) { + printf("retry file_fd lseek fail,lseek len=%d\n", len); + goto fail; + } + ret = lseek(fd, -write_len, SEEK_CUR); + if (ret < 0) { + printf("retry fd lseek fail,lseek len=%d\n", write_len); + goto fail; + } + continue; + } + + printf("upgrade file[%s] fail, offset = 0x%x.\n", sysfs_loc, offset_addr); + printf("want to write buf :\n"); + for (i = 0; i < reread_len; i++) { + printf("0x%x ", wr_buf[i]); + } + printf("\n"); + + printf("actually reread buf :\n"); + for (i = 0; i < reread_len; i++) { + printf("0x%x ", reread_buf[i]); + } + printf("\n"); + + goto fail; + } + + offset_addr += len; + filesize -= len; + usleep(5000); + } + + printf("success\n"); + close(file_fd); + close(fd); + return DFD_RV_OK; + +fail: + close(file_fd); +open_dev_err: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_sysfs_file_wr(int argc, char* argv[]) +{ + int ret = 0; + uint32_t offset_addr; + char *file_name; + char *sysfs_loc; + char *stopstring; + unsigned long filesize; + int fd, file_fd; + uint8_t wr_buf[DFD_UTEST_MAX_RDWR_NUM]; + int len, write_len, per_wr_len; + int i; + + if (argc != 5 && argc != 6) { + printf("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_SYSFS_FILE_WR); + goto exit; + } + + sysfs_loc = argv[2]; + offset_addr = strtol(argv[3], &stopstring, 16); + file_name = argv[4]; + + if (argc == 6) { + per_wr_len = strtol(argv[5], &stopstring, 10); + if (per_wr_len > DFD_UTEST_MAX_RDWR_NUM || per_wr_len <= 0) { + printf("per_wr_byte %d invalid, not in range (0, 256]\n", per_wr_len); + goto exit; + } + } else { + per_wr_len = DFD_UTEST_DEFAULT_WR_NUM; + } + DFD_DEBUG_DBG("per_wr_byte: %d\n", per_wr_len); + filesize = dfd_utest_get_file_size(file_name); + if (filesize <= 0) { + printf("Input invalid file %s, filesize %lu.\n", file_name, filesize); + goto exit; + } + + fd = open(sysfs_loc, O_RDWR | O_SYNC); + if (fd < 0) { + printf("open file[%s] fail.\n", sysfs_loc); + goto exit; + } + + file_fd = open(file_name, O_RDONLY); + if (file_fd < 0) { + printf("open file[%s] fail.\n", file_name); + goto open_dev_err; + } + + dfd_utest_print_cmd(argc, argv); + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek file[%s offset=%d] fail,\n", sysfs_loc, offset_addr); + goto fail; + } + + printf(":\n"); + while (filesize > 0) { + if (filesize > (unsigned long)per_wr_len) { + len = per_wr_len; + } else { + len = filesize; + } + + mem_clear(wr_buf, DFD_UTEST_MAX_RDWR_NUM); + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + len = read(file_fd, wr_buf, len); + if (len < 0) { + DFD_DEBUG_ERROR("read file[%s] fail, offset = 0x%x retrytimes = %d ret = %d\n", + sysfs_loc, offset_addr, i ,len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == DFD_I2C_RETRY_TIME) { + printf("read file[%s] fail, offset = 0x%x, ret = %d\n", sysfs_loc, offset_addr, len); + goto fail; + } + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + write_len = write(fd, wr_buf, len); + if (write_len != len) { + DFD_DEBUG_ERROR("write file[%s] fail,offset = 0x%x retrytimes = %d len = %d,write_len =%d\n", sysfs_loc, offset_addr, i ,len, write_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + if(i == DFD_I2C_RETRY_TIME) { + printf("write file[%s] fail, offset = 0x%x, len = %d,write_len =%d\n", sysfs_loc, offset_addr, len, write_len); + ret = -1; + goto fail; + } + offset_addr += len; + filesize -= len; + usleep(5000); + } + + printf("success\n"); + close(file_fd); + close(fd); + return DFD_RV_OK; + +fail: + close(file_fd); +open_dev_err: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_sysfs_file_rd(int argc, char* argv[]) +{ + int ret = 0; + uint32_t offset_addr; + char *sysfs_loc; + char *stopstring; + int fd; + uint8_t rd_buf[DFD_UTEST_MAX_RDWR_NUM]; + int len, read_len;; + + if (argc != 5) { + printf("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_SYSFS_FILE_RD); + goto exit; + } + + sysfs_loc = argv[2]; + offset_addr = strtol(argv[3], &stopstring, 16); + len = strtol(argv[4], &stopstring, 10); + + if (len > DFD_UTEST_MAX_RDWR_NUM) { + printf("Input num %d exceed max 256.\n", len); + goto exit; + } + + fd = open(sysfs_loc, O_RDONLY); + if (fd < 0) { + printf("open file[%s] fail.\n", sysfs_loc); + goto exit; + } + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek failed ret %d.\n", ret); + goto fail; + } + + mem_clear(rd_buf, DFD_UTEST_MAX_RDWR_NUM); + read_len = read(fd, rd_buf, len); + if (read_len != len) { + printf("read failed read_len %d len %d.\n", read_len, len); + goto fail; + } + dfd_utest_printf_reg(rd_buf, read_len, offset_addr); + close(fd); + return DFD_RV_OK; + +fail: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_msr_rd(int argc, char* argv[]) +{ + int fd; + char msr_file_name[64]; + uint64_t data; + uint64_t read_result; + char *stopstring; + uint8_t cpu_index, width; + uint64_t offset; + + if (argc != 5) { + printf("rdmsr failed: Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_MSR_RD); + goto exit; + } + + cpu_index = strtol(argv[2], &stopstring, 10); + offset = strtol(argv[3], &stopstring, 16); + width = strtol(argv[4], &stopstring, 10); + + if (width != 8 && width != 16 && width != 32 && width != 64) { + printf("rdmsr failed: width:%u Input invalid.only support 8 16 32 64\n", width); + goto exit; + } + + mem_clear(msr_file_name, sizeof(msr_file_name)); + sprintf(msr_file_name, "/dev/cpu/%u/msr", cpu_index); + + fd = open(msr_file_name, O_RDONLY); + if (fd < 0) { + if (errno == ENXIO) { + fprintf(stderr, "rdmsr failed: No CPU %u\n", cpu_index); + } else if (errno == EIO) { + fprintf(stderr, "rdmsr failed: CPU %u doesn't support MSRs\n", cpu_index); + } else if (errno == ENOENT) { + fprintf(stderr, "rdmsr failed: can't find %s file, Please check if modprobe msr driver already\n", msr_file_name); + } else { + printf("rdmsr failed: %s open failed. errno:%d\n", msr_file_name, errno); + } + goto exit; + } + + if (pread(fd, &data, sizeof(data), offset) != sizeof(data)) { + fprintf(stderr, "rdmsr failed: CPU:%u offset:0x%lx read failed\n", cpu_index, offset); + goto fail; + } + + switch (width) { + case 8: + read_result = (volatile uint8_t)data; + break; + case 16: + read_result = (volatile uint16_t)data; + break; + case 32: + read_result = (volatile uint32_t)data; + break; + case 64: + read_result = (volatile uint64_t)data; + break; + default: + printf("rdmsr failed: width:%u illegal width.\n", width); + goto fail; + } + + printf("0x%lx\n", read_result); + close(fd); + return DFD_RV_OK; + +fail: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_sysfs_data_wr(int argc, char* argv[]) +{ + uint32_t offset; + char *sysfs_loc; + char *stopstring; + uint8_t wr_buf[DFD_UTEST_MAX_RDWR_NUM]; + int ret, i; + int fd, len, write_len, index; + + if (argc < 5) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_SYSFS_DATA_WR); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + + sysfs_loc = argv[2]; + offset = strtol(argv[3], &stopstring, 16); + len = argc - 4; + mem_clear(wr_buf, sizeof(wr_buf)); + for (i = 0; i < len; i++) { + wr_buf[i] = strtol(argv[4 + i], &stopstring, 16); + DFD_DEBUG_DBG("index :%d value %x\n", i , wr_buf[i]); + } + + fd = open(sysfs_loc, O_RDWR | O_SYNC); + if (fd < 0) { + printf("open file[%s] fail.\n", sysfs_loc); + goto exit; + } + + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) { + printf("lseek file[%s offset=%d] fail,\n", sysfs_loc, offset); + goto fail; + } + index = 0; + while (len > 0) { + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + write_len = write(fd, &wr_buf[index], len); + if (write_len < 0) { + DFD_DEBUG_ERROR("write file[%s] fail, retrytimes: %d, offset: 0x%x, len: %d, write_len: %d\n", + sysfs_loc, offset, i, len, write_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + if (write_len == 0) { + DFD_DEBUG_ERROR("write file[%s] EOF, offset: 0x%x, len: %d, write_len: %d\n", + sysfs_loc, offset, len, write_len); + goto fail; + } + break; + } + if(i == DFD_I2C_RETRY_TIME) { + printf("write file[%s] fail, offset: 0x%x, len: %d, write_len: %d\n", + sysfs_loc, offset, len, write_len); + goto fail; + } + offset += write_len; + index += write_len; + len -= write_len; + usleep(5000); + } + printf("success\n"); + close(fd); + return DFD_RV_OK; +fail: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +dfd_utest_proc_fun dfd_utest_get_proc_func(char *type_str) +{ + int i, tbl_size; + + tbl_size = sizeof(g_dfd_unit_test) / sizeof(g_dfd_unit_test[0]); + + for (i = 0; i < tbl_size; i++) { + if (!strncmp(g_dfd_unit_test[i].type_str, type_str, strlen(g_dfd_unit_test[i].type_str))) { + return g_dfd_unit_test[i].utest_func; + } + } + DFD_DEBUG_DBG("type: %s not match.\n", type_str); + return NULL; +} + +void dfd_utest_cmd_main(int argc, char* argv[]) +{ + dfd_utest_proc_fun pfunc; + int ret; + + if (argc < 2) { + dfd_utest_print_all_help(); + return; + } + + pfunc = dfd_utest_get_proc_func(argv[1]); + if (pfunc == NULL) { + DFD_DEBUG_DBG("utest type %s in not support.\n", argv[1]); + dfd_utest_print_all_help(); + return; + } + ret = pfunc(argc, argv); + if ((ret != DFD_RV_MODE_NOTSUPPORT) && (ret != DFD_RV_INDEX_INVALID)) { + if (ret == DFD_RV_OK) { + DFD_DEBUG_DBG(" [SUCCESS]\n"); + } else { + DFD_DEBUG_DBG(" [FAIL(%d)]\n", ret); + } + } + + return; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.h new file mode 100644 index 000000000000..aa194a4dcdd7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.h @@ -0,0 +1,103 @@ +/* monitor_utest.h */ +#ifndef __DFD_UTEST_H__ +#define __DFD_UTEST_H__ + +#include + +extern int g_dfd_debug_sw; +extern int g_dfd_debugpp_sw; + +#define DFD_UTEST_TRUE_FALSE_STRING(flag) ((flag == true) ? "true" : "false") + +#define DFD_DEBUG_DBG(fmt, args...) do { \ + if (g_dfd_debug_sw) { \ + printf("" fmt,\ + ##args); \ + } \ +} while (0) + +#define DFD_DEBUG_ERROR(fmt, args...) do { \ + if (g_dfd_debugpp_sw) { \ + printf("" fmt,\ + ##args); \ + } \ +} while (0) + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef enum dfd_rv_s { + DFD_RV_OK = 0, + DFD_RV_INIT_ERR = 1, + DFD_RV_SLOT_INVALID = 2, + DFD_RV_MODE_INVALID = 3, + DFD_RV_MODE_NOTSUPPORT = 4, + DFD_RV_TYPE_ERR = 5, + DFD_RV_DEV_NOTSUPPORT = 6, + DFD_RV_DEV_FAIL = 7, + DFD_RV_INDEX_INVALID = 8, + DFD_RV_NO_INTF = 9, + DFD_RV_NO_NODE = 10, + DFD_RV_NODE_FAIL = 11, +} dfd_rv_t; + +#define DFD_DEBUG_BUF_LEN (32) +#define DFD_DEBUGP_DEBUG_FILE "/sbin/.dfd_debugp_flag" +#define DFD_DEBUGPP_DEBUG_FILE "/sbin/.dfd_debugpp_flag" + +#define DFD_UTEST_MAX_PARA_NUM (4) +#define DFD_UTEST_TYPE_STRING_LEN (64) +#define DFD_UTEST_MATCH_STRING_LEN (64) +#define DFD_UTEST_HELP_STRING_LEN (256) +#define DFD_UTEST_INVALID_PARA (-1) +#define DFD_UTEST_BUFF_LEN (64) + +typedef enum dfd_fpga_cpld_flag_e { + DFD_CPLD_RW_FLAG = 0x00, + DFD_FPGA_RW_FLAG = 0x01, +} dfd_fpga_cpld_flag_t; + +typedef int (* dfd_utest_proc_fun)(int argc, char* argv[]); + +#define DFD_UTEST_ITEM_ALL \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_RD, i2c_rd, "i2c_rd [i2c_bus] [slave_addr] [offset] [len]", "i2c_rd [i2c_bus] [slave_addr] [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_WR, i2c_wr, "i2c_wr [i2c_bus] [slave_addr] [offset] [data0] ... [dataN]", "i2c_wr [i2c_bus] [slave_addr] [offset] [data0] ... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_IO_RD, io_rd, "io_rd [offset] [len]", "io_rd [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_IO_WR, io_wr, "io_wr [offset] [data0]... [dataN]", "io_wr [offset] [data0]... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_PHYMEM_RD, phymem_rd, "phymem_rd [bit_width] [offset] [len]", "phymem_rd [bit_width] [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_PHYMEM_WR, phymem_wr, "phymem_wr [bit_width] [offset] [data0]... [dataN]", "phymem_wr [bit_width] [offset] [data0]... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_KMEM_RD, kmem_rd, "kmem_rd [bit_width] [offset] [len]", "kmem_rd [bit_width] [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_KMEM_WR, kmem_wr, "kmem_wr [bit_width][offset] [data0]... [dataN]", "kmem_wr [bit_width] [offset] [data0]... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_FILE_WR, i2c_file_wr, "i2c_file_wr [i2c_bus] [slave_addr] [offset] [bpt] [filename]", "i2c_file_wr [i2c_bus] [slave_addr] [offset] [bpt] [filename]\nbpt:bytes per times") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_SYSFS_FILE_WR, sysfs_file_wr, "sysfs_file_wr [sysfs_loc] [offset] [filename] [per_wr_byte]", "sysfs_file_wr [sysfs_loc] [offset] [filename] [per_wr_byte]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_SYSFS_FILE_RD, sysfs_file_rd, "sysfs_file_rd [sysfs_loc] [offset] [len]", "sysfs_file_rd [sysfs_loc] [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_SYSFS_FILE_UPG, sysfs_file_upg, "sysfs_file_upg [sysfs_loc] [offset] [filename] [per_wr_byte]", "sysfs_file_upg [sysfs_loc] [offset] [filename] [per_wr_byte]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_GEN_RD, i2c_gen_rd, "i2c_gen_rd [i2c_bus] [slave_addr] [addr_bitwidth] [offset] [data_bitwidth] [len]", "i2c_gen_rd [i2c_bus] [slave_addr] [addr_bitwidth] [offset] [data_bitwidth] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_GEN_WR, i2c_gen_wr, "i2c_gen_wr [i2c_bus] [slave_addr] [addr_bitwidth] [offset] [data_bitwidth] [data0]... [dataN]", "i2c_gen_wr [i2c_bus] [slave_addr] [addr_bitwidth] [offset] [data_bitwidth] [data0]... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_MSR_RD, msr_rd, "msr_rd [cpu_index] [offset] [width]", "msr_rd [cpu_index] [offset] [width]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_SYSFS_DATA_WR, sysfs_data_wr, "sysfs_data_wr [sysfs_loc] [offset] [data0] ... [dataN]", "sysfs_data_wr [sysfs_loc] [offset] [data0] ... [dataN]]") \ + +#ifdef DFD_UTEST_ITEM +#undef DFD_UTEST_ITEM +#endif +#define DFD_UTEST_ITEM(_id, _type_str, _help_info, _help_info_detail) _id, +typedef enum dfd_utest_item_id_s { + DFD_UTEST_ITEM_ALL +} dfd_utest_item_id_t; + +typedef struct { + int utest_type; + char type_str[DFD_UTEST_TYPE_STRING_LEN]; + dfd_utest_proc_fun utest_func; + char help_info[DFD_UTEST_HELP_STRING_LEN]; + char help_info_detail[DFD_UTEST_HELP_STRING_LEN]; +} dfd_utest_t; + +void dfd_utest_cmd_main(int argc, char* argv[]); + +#ifdef DFD_UTEST_ITEM +#undef DFD_UTEST_ITEM +#endif +#define DFD_UTEST_ITEM(_id, _type_str, _help_info, _help_info_detail) int dfd_utest_##_type_str(int argc, char* argv[]); +DFD_UTEST_ITEM_ALL + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Makefile new file mode 100644 index 000000000000..62663efdbbd5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Makefile @@ -0,0 +1,19 @@ +top_srcdir:=$(shell pwd) +include $(top_srcdir)/Rules.mk + +firmware-y:= +firmware-y += firmware_driver +firmware-y += firmware_upgrade + +.PHONY: all +all: build + +.PHONY: build +build: $(firmware-y) +$(foreach dir,$(firmware-y),$(eval $(call compile_dirs,$(dir)))) + +.PHONY: rpmpkg +rpmpkg: +ifeq ("$(CONFIG_CPLD_UPGRADE_ISPVME)", "y") + #$(RPMPKG) $(install_cpld_dir) firmware-cpld-ispvme.spec git +endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Rules.mk b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Rules.mk new file mode 100644 index 000000000000..5fb5a09d34fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Rules.mk @@ -0,0 +1,42 @@ +CC ?= $(CROSS)gcc +AR ?= $(CROSS)ar +AS ?= $(CROSS)as +LD ?= $(CROSS)ld +STRIP ?= $(CROSS)strip + +install_root:=${top_srcdir}/images + +install_header_dir:=${install_root}/header +install_adir:=$(install_root)/lib +install_symbol_dir:=$(install_root)/symbol +symbol_files:=$(shell find $(EXPORT_SYMBOL) -name 'Module.symvers') +# +# symbol_files += $(shell find $(install_symbol_dir) -name 'Module.symvers') +# KBUILD_EXTRA_SYMBOLS += $(symbol_files) +# export KBUILD_EXTRA_SYMBOLS + +# top root: install_rootfs_dir +install_rootfs_dir:=$(install_root)/rootfs + +install_sodir:=$(install_rootfs_dir)/$(INSTALL_SODIR) + +install_usr_bin_dir:=$(install_rootfs_dir)/usr/bin +install_sbin_dir:=$(install_rootfs_dir)/sbin +install_etc_dir:=$(install_rootfs_dir)/etc + +export INSTALL_MOD_PATH:=$(ROOT) + +BUILD_CFLAGS:=$(CFLAGS) -I$(install_header_dir) +BUILD_LDFLAGS:=$(LDFLAGS) -L/$(install_sodir) -L/$(install_adir) + +define compile_dirs +.PHONY: $(1) +$(1): + @echo;echo "building $(1)..." + @$(MAKE) -C ${1} +endef + +compile.c = $(CC) $(BUILD_CFLAGS) -d -c -o $@ $< +%.o: %.c + $(compile.c) + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/Makefile new file mode 100644 index 000000000000..e8879aeff5e7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/Makefile @@ -0,0 +1,19 @@ +include $(top_srcdir)/Rules.mk + +firmware-y:= +firmware-y += firmware_driver_ispvme +firmware-y += firmware_driver_cpld +firmware-y += firmware_driver_sysfs + +.PHONY: all +all: build + +.PHONY: build +build: $(firmware-y) +$(foreach dir,$(firmware-y),$(eval $(call compile_dirs,$(dir)))) + +.PHONY: rpmpkg +rpmpkg: +ifeq ("$(CONFIG_CPLD_UPGRADE_ISPVME)", "y") + #$(RPMPKG) $(install_cpld_dir) firmware-cpld-ispvme.spec git +endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/Makefile new file mode 100644 index 000000000000..0add28cb9056 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/Makefile @@ -0,0 +1,23 @@ +#include $(top_srcdir)/debian/rules +#KERNELDIR := ${KBUILD_OUTPUT} + +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../include) +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) +EXTRA_CFLAGS+= -Wall + +firmware_driver_cpld-objs := firmware.o +firmware_driver_cpld-objs += firmware_cpld.o firmware_cpld_upgrade.o +firmware_driver_cpld-objs += jbicomp.o jbijtag.o jbimain.o jbistub.o + +#ifndef CONFIG_FRM_PRODUCT_FILE + +$(warning $(firmware_driver_cpld-objs)) +obj-m := firmware_driver_cpld.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(common_module_dir) ]; then mkdir -p $(common_module_dir) ;fi + cp -p $(PWD)/*.ko $(common_module_dir) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware.c new file mode 100644 index 000000000000..db72b369465a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware.c @@ -0,0 +1,144 @@ +#include +#include +#include + +int g_firmware_driver_debug = 0; +module_param(g_firmware_driver_debug, int, S_IRUGO | S_IWUSR); + +static LIST_HEAD(drv_list); +static LIST_HEAD(dev_list); + +/** + * firmware_driver_register + * function:Registered Device Driver + * @fw_drv:param[in] Driver information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_driver_register(firmware_driver_t *fw_drv) +{ + int ret; + + if (fw_drv == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Parameter error.\n"); + return FIRMWARE_FAILED; + } + + ret = platform_driver_register(fw_drv->drv); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: failed to register firmware upgrade driver \n"); + return FIRMWARE_FAILED; + } + + /* Adds driver information to the driver list */ + list_add(&fw_drv->list, &drv_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware upgrade driver register sucess \n"); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_driver_unregister + * function:unregister Device Driver + * @fw_drv:param[in] Driver information + */ +void firmware_driver_unregister(firmware_driver_t *fw_drv) +{ + list_del_init(&fw_drv->list); + platform_driver_unregister(fw_drv->drv); +} + +/* + * firmware_get_device_by_minor + * function: Get device information based on minor + */ +firmware_device_t *firmware_get_device_by_minor(int minor) +{ + firmware_device_t *tmp; + + list_for_each_entry(tmp, &dev_list, list) { + if (tmp->dev.minor == minor) { + return tmp; + } + } + + return NULL; +} + +/** + * firmware_device_register + * function:Registered Driver Device + * @fw_dev: param[in] Driver information + * return value:success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_device_register(firmware_device_t *fw_dev) +{ + int ret; + firmware_device_t *tmp; + + if (fw_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Parameter error.\n"); + return FIRMWARE_FAILED; + } + /* Check whether the device file name already exists in the device linked list */ + list_for_each_entry(tmp, &dev_list, list) { + if (strcmp(tmp->name, fw_dev->name) == 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("devie %s already exists.\n", fw_dev->name); + return FIRMWARE_FAILED; + } + } + + /* Registere device */ + ret = misc_register(&fw_dev->dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("register misc error, ret=%d.\n", ret); + return FIRMWARE_FAILED; + } + + /* Adds a device to the device list */ + list_add(&fw_dev->list, &dev_list); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_device_unregister + * function: unregister Driver Device + */ +void firmware_device_unregister(firmware_device_t *fw_dev) +{ + list_del(&fw_dev->list); + misc_deregister(&fw_dev->dev); +} + +static int __init firmware_driver_init(void) +{ + int ret; + + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver init.\n"); + ret = firmware_cpld_init(); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware driver init failed.\n"); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +static void __exit firmware_driver_exit(void) +{ + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver exit.\n"); + firmware_cpld_exit(); + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + return; +} + +module_init(firmware_driver_init); +module_exit(firmware_driver_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Firmware upgrade driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld.c new file mode 100644 index 000000000000..18ec509d0f2e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld.c @@ -0,0 +1,384 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int firmware_cpld_open(struct inode *inode, struct file *file) +{ + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Open cpld device.\n"); + frm_dev = firmware_get_device_by_minor(MINOR(inode->i_rdev)); + if (frm_dev == NULL) { + return -ENXIO; + } + file->private_data = frm_dev; + + return FIRMWARE_SUCCESS; +} + +static ssize_t firmware_cpld_read (struct file *file, char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static ssize_t firmware_cpld_write (struct file *file, const char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static loff_t firmware_cpld_llseek(struct file *file, loff_t offset, int origin) +{ + return 0; +} + +/* + * firmware_cpld_ioctl + * function: ioctl command parsing function + * @file: param[in] device file name + * @cmd: param[in] command + * @arg: param[in] the parameters in the command + * return value: success-FIRMWARE_SUCCESS; fail:other value + */ +static long firmware_cpld_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + char *buf; + void __user *argp; + char version[FIRMWARE_NAME_LEN]; + char chip_name[FIRMWARE_NAME_LEN]; + cmd_info_t cmd_info; + firmware_device_t *frm_dev; + firmware_cpld_t *cpld_info; + + /* Get device private data */ + mem_clear(&cmd_info, sizeof(cmd_info_t)); + frm_dev = (firmware_device_t *)file->private_data; + cpld_info = NULL; + if (frm_dev != NULL) { + if (frm_dev->priv != NULL) { + cpld_info = (firmware_cpld_t *)frm_dev->priv; + } + } + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to frm_dev->priv sysfs info.\n"); + return FIRMWARE_FAILED; + } + argp = (void __user *)arg; + + switch (cmd) { + case FIRMWARE_GET_CHIPNAME: + /* get chip name */ + if (copy_from_user(&cmd_info, argp, sizeof(cmd_info_t))) { + return -EFAULT; + } + mem_clear(chip_name, FIRMWARE_NAME_LEN); + ret = fmw_cpld_upg_get_chip_name(frm_dev->chain, cpld_info, chip_name, FIRMWARE_NAME_LEN); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get chip name.\n"); + return -ENXIO; + } + if (copy_to_user(cmd_info.data, chip_name, cmd_info.size)) { + return -EFAULT; + } + break; + case FIRMWARE_PROGRAM: + case FIRMWARE_PROGRAM_JBI: + /* firmware upgrade */ + if (copy_from_user(&cmd_info, argp, sizeof(cmd_info_t))) { + return -EFAULT; + } + buf = (char *) kzalloc(cmd_info.size + 1, GFP_KERNEL); + if (buf == NULL) { + return -ENOMEM; + } + if (copy_from_user(buf, cmd_info.data, cmd_info.size)) { + kfree(buf); + return -EFAULT; + } + buf[cmd_info.size] = 0; + if (cmd == FIRMWARE_PROGRAM_JBI) { + /* JBI firmware upgrade */ + ret = fmw_cpld_upg_program_jbi(frm_dev->chain, cpld_info, buf, cmd_info.size); + } else { + /* ISC firmware upgrade */ + ret = fmw_cpld_upg_program(frm_dev->chain, cpld_info, buf, cmd_info.size); + } + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to program cpld.\n"); + kfree(buf); + return -ESRCH; + } + kfree(buf); + break; + case FIRMWARE_GET_VERSION: + /* get version */ + if (copy_from_user(&cmd_info, argp, sizeof(cmd_info_t))) { + return -EFAULT; + } + mem_clear(version, FIRMWARE_NAME_LEN); + ret = fmw_cpld_upg_get_version(frm_dev->chain, cpld_info, version, FIRMWARE_NAME_LEN); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get version.\n"); + return -ENXIO; + } + if (copy_to_user(cmd_info.data, version, cmd_info.size)) { + return -EFAULT; + } + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("not find cmd: %d\r\n", cmd); + return -ENOTTY; + } /* End of switch */ + + return FIRMWARE_SUCCESS; +} + +static int firmware_cpld_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations cpld_dev_fops = { + .owner = THIS_MODULE, + .llseek = firmware_cpld_llseek, + .read = firmware_cpld_read, + .write = firmware_cpld_write, + .unlocked_ioctl = firmware_cpld_ioctl, + .open = firmware_cpld_open, + .release = firmware_cpld_release, +}; + +static int of_firmware_upgrade_config_init(struct device *dev, firmware_cpld_t *cpld_info) +{ + int ret; + char *name; + int i; + char buf[64]; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_upgrade_config_init\r\n"); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + mem_clear(cpld_info, sizeof(firmware_cpld_t)); + ret = 0; + ret += of_property_read_string(dev->of_node, "type", (const char **)&name); + ret += of_property_read_u32(dev->of_node, "tdi", &cpld_info->tdi); + ret += of_property_read_u32(dev->of_node, "tck", &cpld_info->tck); + ret += of_property_read_u32(dev->of_node, "tms", &cpld_info->tms); + ret += of_property_read_u32(dev->of_node, "tdo", &cpld_info->tdo); + + ret += of_property_read_u32(dev->of_node, "chain", &cpld_info->chain); + ret += of_property_read_u32(dev->of_node, "chip_index", &cpld_info->chip_index); + + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config error, ret:%d.\n", ret); + return -ENXIO; + } + + strncpy(cpld_info->type, name, sizeof(cpld_info->type) - 1); + + ret = of_property_read_u32(dev->of_node, "tck_delay", &cpld_info->tck_delay); + if(ret != 0) { + cpld_info->tck_delay = 60; + } + + cpld_info->gpio_en_info_num = 0; + /* Enable through GPIO */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_gpio_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &cpld_info->gpio_en_info[i].en_gpio); + if(ret != 0) { + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_level_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &cpld_info->gpio_en_info[i].en_level); + if(ret != 0) { + break; + } + cpld_info->gpio_en_info_num++; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("type:%s, chain:%u, chip_index:%u, en_info_num:%u\n", + cpld_info->type, cpld_info->chain, cpld_info->chip_index, cpld_info->gpio_en_info_num); + FIRMWARE_DRIVER_DEBUG_VERBOSE("tdi:%u, tck:%u, tms:%u, tdo:%u tck_delay:%u.\n", + cpld_info->tdi, cpld_info->tck, cpld_info->tms, cpld_info->tdo, cpld_info->tck_delay); + + return 0; +} + +static int firmware_upgrade_config_init(struct device *dev, firmware_cpld_t *cpld_info) +{ + int i; + + firmware_upgrade_device_t *firmware_upgrade_device; + firmware_jtag_device_t jtag_upg_device; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_upgrade_config_init\r\n"); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + if (dev->platform_data == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("platform data config error.\n"); + return -1; + } + firmware_upgrade_device = dev->platform_data; + jtag_upg_device = firmware_upgrade_device->upg_type.jtag; + + mem_clear(cpld_info, sizeof(firmware_cpld_t)); + + strncpy(cpld_info->type, firmware_upgrade_device->type, sizeof(cpld_info->type) - 1); + cpld_info->tdi = jtag_upg_device.tdi; + cpld_info->tck = jtag_upg_device.tck; + cpld_info->tms = jtag_upg_device.tms; + cpld_info->tdo = jtag_upg_device.tdo; + cpld_info->chain = firmware_upgrade_device->chain; + cpld_info->chip_index = firmware_upgrade_device->chip_index; + + if (jtag_upg_device.tck_delay == 0) { + cpld_info->tck_delay = 60; + FIRMWARE_DRIVER_DEBUG_VERBOSE("no config tck_delay, use default value:%u\n", cpld_info->tck_delay); + } else { + cpld_info->tck_delay = jtag_upg_device.tck_delay; + } + + if (firmware_upgrade_device->en_gpio_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_gpio_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_gpio_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + cpld_info->gpio_en_info_num = firmware_upgrade_device->en_gpio_num; + /* Enable through GPIO */ + for (i = 0; i < cpld_info->gpio_en_info_num; i++) { + cpld_info->gpio_en_info[i].en_gpio = firmware_upgrade_device->en_gpio[i]; + cpld_info->gpio_en_info[i].en_level = firmware_upgrade_device->en_level[i]; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("type:%s, chain:%u, chip_index:%u, en_info_num:%u\n", + cpld_info->type, cpld_info->chain, cpld_info->chip_index, cpld_info->gpio_en_info_num); + FIRMWARE_DRIVER_DEBUG_VERBOSE("tdi:%u, tck:%u, tms:%u, tdo:%u tck_delay:%u.\n", + cpld_info->tdi, cpld_info->tck, cpld_info->tms, cpld_info->tdo, cpld_info->tck_delay); + + return 0; +} + +static int firmware_cpld_probe(struct platform_device *pdev) +{ + int ret; + firmware_cpld_t *cpld_info; + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_cpld_probe\r\n"); + /* Gets the information in the device tree */ + cpld_info = devm_kzalloc(&pdev->dev, sizeof(firmware_cpld_t), GFP_KERNEL); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc cpld device tree.\n"); + return -EPERM; + } + + if (pdev->dev.of_node) { + ret = of_firmware_upgrade_config_init(&pdev->dev, cpld_info); + } else { + ret = firmware_upgrade_config_init(&pdev->dev, cpld_info); + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("get config init from dts error.\n"); + return -EPERM; + } + + frm_dev = devm_kzalloc(&pdev->dev, sizeof(firmware_device_t), GFP_KERNEL); + if (frm_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc firmware device.\n"); + return -EPERM; + } + + /* Based on the link number, determine the name of the device file */ + frm_dev->chain = cpld_info->chain; + snprintf(frm_dev->name, FIRMWARE_NAME_LEN - 1, "firmware_cpld%d", frm_dev->chain); + strncpy(cpld_info->devname, frm_dev->name, strlen(frm_dev->name) + 1); + + INIT_LIST_HEAD(&frm_dev->list); + frm_dev->dev.minor = MISC_DYNAMIC_MINOR; + frm_dev->dev.name = frm_dev->name; + frm_dev->dev.fops = &cpld_dev_fops; + frm_dev->priv = cpld_info; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Register cpld firmware chain:%d, name:%s.\n", frm_dev->chain, frm_dev->name); + + ret = firmware_device_register(frm_dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to register firmware device.\n"); + return -EPERM; + } + + platform_set_drvdata(pdev, frm_dev); + return 0; +} + +static int __exit firmware_cpld_remove(struct platform_device *pdev) +{ + firmware_device_t *frm_dev; + + frm_dev = (firmware_device_t *)platform_get_drvdata(pdev); + firmware_device_unregister(frm_dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct of_device_id cpld_match[] = { + { + .compatible = "firmware_cpld", + }, + {}, +}; + +static struct platform_driver cpld_driver = { + .driver = { + .name = "firmware_cpld", + .owner = THIS_MODULE, + .of_match_table = cpld_match, + }, + .probe = firmware_cpld_probe, + .remove = firmware_cpld_remove, +}; + +static firmware_driver_t fmw_drv_cpld = { + .name = "firmware_cpld", + .drv = &cpld_driver, +}; + +int firmware_cpld_init(void) +{ + int ret; + + INIT_LIST_HEAD(&fmw_drv_cpld.list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("cpld upgrade driver register \n"); + ret = firmware_driver_register(&fmw_drv_cpld); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("cpld upgrade driver register failed.\n"); + return ret; + } + return 0; +} + +void firmware_cpld_exit(void) +{ + firmware_driver_unregister(&fmw_drv_cpld); + INIT_LIST_HEAD(&fmw_drv_cpld.list); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld_upgrade.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld_upgrade.c new file mode 100644 index 000000000000..8252c2a39bb2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld_upgrade.c @@ -0,0 +1,1879 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* CPLD file parses the relevant parameters */ +#define CPLD_HEX 16 +#define DEC_VAL 10 +#define CPLD_INIT_CNT 4 +#define CPLD_UNIT_SZ 4 +#define CPLD_HEAD_KEYWORD "Header" +#define CPLD_NAME_KEYWORD "Entity" +#define CPLD_INIT_KEYWORD "INITIALIZE" +#define CPLD_REPEAT_KEYWORD "REPEAT" +#define CPLD_END_CHAR ',' + +/* TCK clock MAX 16MHz */ +#define TCK_DELAY (current_fmw_cpld->tck_delay) + +/* + * The instruction format of the MAX II CPLD is 10 bits + * For shift_ir state machine use + */ +#define BYPASS 0x3FF +#define EXTEST 0xF +#define SAMPLE 0x5 +#define IDCODE 0x6 +#define USERCODE 0x7 +#define CLAMP 0xA +#define HIGHZ 0xB + +/* Following 7 instructions are IEEE 1532 instructions */ +#define ISC_ENABLE 0x2CC +#define ISC_DISABLE 0x201 +#define ISC_PROGRAM 0x2F4 +#define ISC_ERASE 0x2F2 +#define ISC_ADDRESS_SHIFT 0x203 +#define ISC_READ 0x205 +#define ISC_NOOP 0x210 + +/* + * MAX II devices support the real-time in-system programmability (ISP) + * feature that allows you to program the device while it is still in operation. + * when there is either a power cycle to the device (powering down and powering + * up again) or with the execution of certain ISP instructions to start the SRAM + * download process when realtime ISP has completed. + */ +#define RT_ISC_ENABLE 0x199 +#define RT_ISC_DISABLE 0x166 + +/* Chip ID */ +#define EPM240_G 0x020A10DD +#define EPM570_G 0x020A20DD +#define EPM1270_G 0x020A30DD +#define EPM2210_G 0x020A40DD +#define EPM240_Z 0x020A50DD +#define EPM570_Z 0x020A60DD + +/* The size of the output data for ID validation */ +#define VERIFY_IDCODE_SIZE 0x5 + +/* Erasure and programmatic delay handling */ +#define ERASE_DELAY 0x1024 +#define PROGRAM_DELAY 0x5 + +/* Chip instruction register */ +#define CPLD_INSTRUCTION_SIZE 10 + +/* + * Currently, only two connectors are supported + * The size of the instruction register needs to be changed + * when more than two connectors are used + */ +#ifndef CPLD_MAX_CHIP +#define CPLD_MAX_CHIP 2 +#endif + +typedef struct cpld_chip_id { + char *name; + uint id; + int addr_register_length; + int data_register_length; + int eeprom_array_length; + int first_blank_check_length; + int second_blank_check_length; + int first_erase_addr; + int second_erase_addr; + int third_erase_addr; + int verify_idcode_addr; +} cpld_chip_id_t; + +static cpld_chip_id_t cpld_id_table[] = { + {"EPM240T100", EPM240_G, 13, 16, 4604, 3327, 511, 0x0, 0x1, 0x11, 0x89}, + {"EPM570T144", EPM570_G, 14, 16, 8700, 3327, 511, 0x0, 0x1, 0x21, 0x111}, + {"EPM1270F256", EPM1270_G, 15, 16, 16892, 16383, 511, 0x0, 0x1, 0x41, 0x221}, + {"5M240Z", EPM240_Z, 13, 16, 4604, 3327, 511, 0x0, 0x1, 0x11, 0x89}, + {"5M570Z", EPM570_Z, 14, 16, 8700, 3327, 511, 0x0, 0x1, 0x21, 0x111}, + {NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + +static cpld_chip_id_t *chip_cpld_info = NULL; + +/* The following variables are used when cascading multiple chips */ +static int chip_num, current_chip_index; +static firmware_cpld_t *current_fmw_cpld; + +static int TDI_PULL_UP(void); +static int TDI_PULL_DOWN(void); +static int TMS_PULL_UP(void); +static int TMS_PULL_DOWN(void); +static int TCK_PULL_UP(void); +static int TCK_PULL_DOWN(void); + +/* + * set_currrent_cpld_info + * function: Save the current device information + * @info: param[in] Information about the device to be updated + */ +static void set_currrent_cpld_info(firmware_cpld_t *info) +{ + current_fmw_cpld = info; +} + +/* + * firmware_upgrade_en + * function: Upgrade access enabling switch + * @flag: !0:enable 0:disable + */ +static int firmware_upgrade_en(int flag) +{ + int i; + int ret; + + for (i = 0; i < current_fmw_cpld->gpio_en_info_num; i++) { + if (flag) { + ret = gpio_request(current_fmw_cpld->gpio_en_info[i].en_gpio, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade EN[%d] GPIO[%d] failed!\n", + i, current_fmw_cpld->gpio_en_info[i].en_gpio); + goto free_gpio; + } + gpio_direction_output(current_fmw_cpld->gpio_en_info[i].en_gpio, current_fmw_cpld->gpio_en_info[i].en_level); + current_fmw_cpld->gpio_en_info[i].flag = 1; + } else { + gpio_set_value(current_fmw_cpld->gpio_en_info[i].en_gpio, !current_fmw_cpld->gpio_en_info[i].en_level); + gpio_free(current_fmw_cpld->gpio_en_info[i].en_gpio); + current_fmw_cpld->gpio_en_info[i].flag = 0; + } + } + return 0; +free_gpio: + for (i = 0; i < current_fmw_cpld->gpio_en_info_num; i++) { + if (current_fmw_cpld->gpio_en_info[i].flag == 1) { + gpio_set_value(current_fmw_cpld->gpio_en_info[i].en_gpio, !current_fmw_cpld->gpio_en_info[i].en_level); + gpio_free(current_fmw_cpld->gpio_en_info[i].en_gpio); + current_fmw_cpld->gpio_en_info[i].flag = 0; + } else { + break; + } + } + + return -1; +} + +/* + * init_cpld + * function:Initialize CPLD + * return value: 0 success ; -1 fail + */ +static int init_cpld(void) +{ + int ret; + + if (current_fmw_cpld == NULL) { + return -1; + } + mdelay(10); + ret = gpio_request(current_fmw_cpld->tdi, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_upgrade TDI GPIO failed!\n"); + return ret; + } + ret = gpio_request(current_fmw_cpld->tck, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_upgrade TCK GPIO failed!\n"); + goto free_tdi; + } + ret = gpio_request(current_fmw_cpld->tms, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_upgrade TMS GPIO failed!\n"); + goto free_tck; + } + ret = gpio_request(current_fmw_cpld->tdo, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_upgrade TDO GPIO failed!\n"); + goto free_tms; + } + + gpio_direction_output(current_fmw_cpld->tdi, 1); + gpio_direction_output(current_fmw_cpld->tck, 1); + gpio_direction_output(current_fmw_cpld->tms, 1); + + gpio_direction_input(current_fmw_cpld->tdo); + ret = firmware_upgrade_en(1); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: open firmware upgrade en failed, ret %d.\n", ret); + goto free_tdo; + } + + /* test GPIO */ + if (TDI_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TDI_PULL_UP failed.\n"); + goto free_tdo; + } + if (TDI_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TDI_PULL_DOWN failed.\n"); + goto free_tdo; + } + if (TMS_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TMS_PULL_UP failed.\n"); + goto free_tdo; + } + if (TMS_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TMS_PULL_DOWN failed.\n"); + goto free_tdo; + } + if (TCK_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TCK_PULL_UP failed.\n"); + goto free_tdo; + } + if (TCK_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TCK_PULL_DOWN failed.\n"); + goto free_tdo; + } + + mdelay(10); + return 0; + +free_tdo: + gpio_free(current_fmw_cpld->tdo); +free_tms: + gpio_free(current_fmw_cpld->tms); +free_tck: + gpio_free(current_fmw_cpld->tck); +free_tdi: + gpio_free(current_fmw_cpld->tdi); + return ret; +} + +/* + * finish_cpld + * function: finish CPLD upgrade operation + * return value: 0 success ; -1 fail + */ +static int finish_cpld(void) +{ + int ret; + + if (current_fmw_cpld == NULL) { + return -1; + } + mdelay(10); + ret = firmware_upgrade_en(0); + if (ret < 0){ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: close firmware upgrade en failed, ret %d.\r\n", ret); + } + + gpio_free(current_fmw_cpld->tdi); + gpio_free(current_fmw_cpld->tck); + gpio_free(current_fmw_cpld->tms); + gpio_free(current_fmw_cpld->tdo); + mdelay(10); + return 0; +} + +/* Loop waiting for */ +static int pull_wait(int gpio, int value) { + int i, j; + /* Timeout time is two seconds */ + for (i = 0; i < 20; i++) { + for (j = 0; j < 100; j++) { + if (!!gpio_get_value(gpio) == !!value ) { + return 0; + } + /* The first loop does not delay, normally the first loop can immediately return the result */ + if (i) { + mdelay(1); + } + } + /* The CPU is released every 100ms */ + schedule(); + } + /* timeout */ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Wait gpio %d pull to %d failed.\n", gpio, value); + return -1; +} + +/* TDI pull-up */ +static int pull_tdi_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tdi, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tdi, 1); +} + +/* TDI pull-down */ +static int pull_tdi_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tdi, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tdi, 0); +} + +/* TCK pull-up */ +static int pull_tck_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tck, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tck, 1); +} + +/* TCK pull-down */ +static int pull_tck_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tck, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tck, 0); +} + +/* TMS pull-up */ +static int pull_tms_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tms, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tms, 1); +} + +/* TMS pull-down */ +static int pull_tms_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tms, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tms, 0); +} + +/* Read TDO */ +static int read_tdo(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + return gpio_get_value(current_fmw_cpld->tdo); +} + +static firmware_cpld_function_t function_fmw_cpld = { + .pull_tdi_up = pull_tdi_up, + .pull_tdi_down = pull_tdi_down, + .pull_tck_up = pull_tck_up, + .pull_tck_down = pull_tck_down, + .pull_tms_up = pull_tms_up, + .pull_tms_down = pull_tms_down, + .read_tdo = read_tdo, + .init_cpld = init_cpld, + .finish_cpld = finish_cpld, +}; + +/* + * TDI_PULL_DOWN + * function: Lower TDI + */ +static int TDI_PULL_DOWN(void) +{ + if ( function_fmw_cpld.pull_tdi_down != NULL) { + return function_fmw_cpld.pull_tdi_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDI_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TDI_PULL_UP + * function: High TDI + */ +static int TDI_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tdi_up != NULL) { + return function_fmw_cpld.pull_tdi_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDI_PULL_UP.\n"); + return -1; + } +} + +/* + * TCK_PULL_DOWN + * function: Lower TCK + */ +static int TCK_PULL_DOWN(void) +{ + if (function_fmw_cpld.pull_tck_down != NULL) { + return function_fmw_cpld.pull_tck_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TCK_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TCK_PULL_UP + * function: High TCK + */ +static int TCK_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tck_up != NULL) { + return function_fmw_cpld.pull_tck_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TCK_PULL_UP.\n"); + return -1; + } +} + +/* + * TMS_PULL_DOWN + * function: Lower TMS + */ +static int TMS_PULL_DOWN(void) +{ + if (function_fmw_cpld.pull_tms_down != NULL) { + return function_fmw_cpld.pull_tms_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TMS_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TMS_PULL_UP + * function: High TMS + */ +static int TMS_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tms_up != NULL) { + return function_fmw_cpld.pull_tms_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TMS_PULL_UP.\n"); + return -1; + } +} + +/* + * TDO_READ + * function:Read the TDO level + */ +static int TDO_READ(void) +{ + if (function_fmw_cpld.read_tdo != NULL) { + return function_fmw_cpld.read_tdo(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDO_READ.\n"); + return -1; + } +} + +/* + * tap_test_logic_reset + * function: reset JTAG + * No matter what the original state of the controoler, it will enter + * Test_Logic_Reset when TMS is held high for at least five rising + * edges of TCK (16MHz) + * The controller remains in this state while TMS is high + */ +static void tap_test_logic_reset(void) +{ + int i; + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + + for (i = 0; i < 5; i++) { + TCK_PULL_UP(); + ndelay(TCK_DELAY); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + } + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_run_test_idle + * function: A controller state between scan operations.Once entered, the controller + * will remain in the Run_Test/Idle state as long as TMS is held low. + */ +static void tap_run_test_idle(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_select_dr_scan + * function :This is a temporary controller state in which all test data registers + * selected by the current instruction retain their previous state. + */ +static void tap_select_dr_scan(void) +{ + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_capture_dr + * function : In this controller state data may be parallel-loaded into test data + * register selected by the current instruction on the rising edge of TCK + */ +static void tap_capture_dr(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_shift_dr + * function: In this controller state.the test data register connected between TDI + * and TDO as a result of the current instruction shifts one stage + * toward its serial output on each rising edge of TCK. + */ +static void tap_shift_dr(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_exit1_dr + * function: This is a temporary controller state. + */ +static void tap_exit1_dr(int data) +{ + int j; + if (data) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + + /* need to idle here */ + for (j = 1; j < current_chip_index; j++) { + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + } + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_update_dr + * function : Some test data registers may be provided with a latched parallel output to + * prevent changes at the parallel out-put while data is shifted in the + * associated whift-register path in response to certain instructions.Data is + * latched onto the parallel output of these test data registers from the + * shift-register path on the falling edge of TCK in the Update-DR controler state. + */ +static void tap_update_dr(void) +{ + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_select_ir_scan + * function:This is a temporarily controler state in which all test data register selected + * by the current instruction retain their previous state. + */ +static void tap_select_ir_scan(void) +{ + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_capture_ir + * function :In this controller state the shift-register contained in the instruction + * register loads a pattern of fixed logic values on the rising edge of + * TCK.design-specific data may be loaded into shift-register stages that + * are not required to be set to fixed values. + */ +static void tap_capture_ir(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_exit1_ir + * function : enter exit1 ir state. This is a temporary controller state. + */ +static void tap_exit1_ir(int data) +{ + if (data) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_shift_ir + * function: In this controller state the shift-register contained in the instruction + * register is connected between TDI and TDO and shifts data one stage + * toward its serial output on each rising edge of TCK. + */ +static void tap_shift_ir(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * The instruction shifted into the instruction register is latched onto the parallel output + * from the shift-register path on the falling edge of TCK in this controller state.Once the + * new instruction has been latched,it becomes the current instruction. + * + */ +static void tap_update_ir(void) +{ + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +static void tap_send_instruction(int instruction, int ins_len) +{ + int i; + for (i = 0; i < (ins_len - 1); i++) { + if (instruction & 0x1) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + instruction = instruction >> 1; + } +} + +static void tap_send_data(int data, int data_len) +{ + int i; + for (i = 0; i < (data_len - 1); i++) { + if (data & 0x1) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + data = data >> 1; + } +} + +/* + * tap_rcv_byte + * function : Receive data from the device side + * @data : param[out] Received data */ +static void tap_rcv_byte(u8 *data) +{ + int i; + u8 rec_data = 0; + unsigned char tmp; + ndelay(TCK_DELAY); + for (i = 0; i < 8; i++) { + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + tmp = TDO_READ(); + rec_data |= (tmp << i); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + } + *data = rec_data; +} + +/* + * tap_idle + * function :Used for state machine idling + */ +static void tap_idle(void) +{ + int i; + for (i = 0; i < 0x100; i++) { + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + + /* Timely release of CPU */ + schedule(); + } +} + +/* + * jtag_read_data + * function :Read the JTAG output data + * @size: param[in] buffer size + * @data: param[out] read data buffer + */ +static void jtag_read_data(u8 *buf, int size) +{ + int i, j; + /* JTAG state switching */ + tap_run_test_idle(); + tap_select_dr_scan(); + tap_capture_dr(); + tap_shift_dr(); + for (j = current_chip_index; j < chip_num; j++) { + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + } + /* Receive data from the device side */ + for (i = 0; i < size; i++) { + tap_rcv_byte(&buf[i]); + } + /* JTAG state switching */ + tap_exit1_dr(0); + tap_update_dr(); + tap_run_test_idle(); +} + +/* + * jtag_send_instruction + * function :JTAG instruction sending interface + * @instruction: param[in] Instruction to be sent + * @ins_length: param[in] Instruction length + */ +static void jtag_send_instruction(int instruction, int ins_length) +{ + int i, j; + i = 1 << (ins_length - 1); + /* JTAG state switching */ + tap_run_test_idle(); + tap_select_dr_scan(); + tap_select_ir_scan(); + tap_capture_ir(); + tap_shift_ir(); + + for (j = chip_num; j > 1; j--) { + if (j == current_chip_index) { + tap_send_instruction(instruction, ins_length + 1); + } else { + tap_send_instruction(BYPASS, ins_length + 1); + } + } + + if (current_chip_index == 1) { + tap_send_instruction(instruction, ins_length); + /* Gets the highest bit of the instruction */ + tap_exit1_ir((instruction & i) >> (ins_length - 1)); + } else { + tap_send_instruction(BYPASS, ins_length); + /* Gets the highest bit of the instruction */ + tap_exit1_ir((BYPASS & i) >> (ins_length - 1)); + } + + /* JTAG state switching */ + tap_update_ir(); + tap_run_test_idle(); +} + +/* + * jtag_send_data + * function :JTAG data sending interface + * @buf : param[in] Data that needs to be sent + * @data_length: param[in] Data length + */ +static void jtag_send_data(unsigned int buf, int data_length) +{ + int i; + i = 1 << (data_length - 1); + + /* JTAG state switching */ + tap_run_test_idle(); + tap_select_dr_scan(); + tap_capture_dr(); + tap_shift_dr(); + tap_send_data(buf, data_length); + /* Gets the highest bit of the instruction */ + tap_exit1_dr((buf & i) >> (data_length - 1)); + tap_update_dr(); + tap_run_test_idle(); +} + +/* + * jtag_program_donebit + * JTAG programming end point */ +static void jtag_program_donebit(void) +{ + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + + switch (chip_cpld_info->id) { + case EPM240_G: + case EPM570_G: + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x7BFF, chip_cpld_info->data_register_length); + tap_idle(); + break; + case EPM1270_G: + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x7FFF, chip_cpld_info->data_register_length); + tap_idle(); + + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0xFFFF, chip_cpld_info->data_register_length); + tap_idle(); + + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0xFFBF, chip_cpld_info->data_register_length); + tap_idle(); + + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0xFFFF, chip_cpld_info->data_register_length); + tap_idle(); + break; + default: + break; + } /* End of switch */ +} + +/* + * jtag_rt_disable + * JTAG Disable state machine under Real-Time ISP + */ +static void jtag_rt_disable(void) +{ + jtag_send_instruction(RT_ISC_DISABLE, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_instruction(BYPASS, CPLD_INSTRUCTION_SIZE); + tap_idle(); +} + +/* + * jtag_verify_idcode + * function :JTAG internal ID reading + */ +static void jtag_verify_idcode(void) +{ + int data, i; + u8 buf[2]; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(chip_cpld_info->verify_idcode_addr, + chip_cpld_info->addr_register_length); + tap_idle(); + for (i = 0; i < VERIFY_IDCODE_SIZE; i++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + + /* When validating the ID, the data is compared to the corresponding chip value, + which is retrieved from the BSDL file*/ + data = (buf[1] << 8) | buf[0]; + } +} + +/* + * jtag_rt_enable + * Enter Real-Time ISP mode; JTAG Enable State Machine under Real-Time ISP + */ +static void jtag_rt_enable(void) +{ + jtag_send_instruction(RT_ISC_ENABLE, CPLD_INSTRUCTION_SIZE); + tap_idle(); +} + +/* + * jtag_erase + * JTAG erases the timing + */ +static void jtag_erase(void) +{ + int i; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(chip_cpld_info->first_erase_addr, + chip_cpld_info->addr_register_length); + tap_idle(); + jtag_send_instruction(ISC_ERASE, CPLD_INSTRUCTION_SIZE); + tap_idle(); + for (i = 0; i < ERASE_DELAY; i++) { + tap_idle(); + tap_idle(); + } + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(chip_cpld_info->second_erase_addr, + chip_cpld_info->addr_register_length); + tap_idle(); + jtag_send_instruction(ISC_ERASE, CPLD_INSTRUCTION_SIZE); + tap_idle(); + for (i = 0; i < ERASE_DELAY; i++) { + tap_idle(); + tap_idle(); + } + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(chip_cpld_info->third_erase_addr, + chip_cpld_info->addr_register_length); + tap_idle(); + jtag_send_instruction(ISC_ERASE, CPLD_INSTRUCTION_SIZE); + tap_idle(); + for (i = 0; i < ERASE_DELAY; i++) { + tap_idle(); + tap_idle(); + } +} + +/* + * jtag_blank_check + * JTAG blank detection */ +static void jtag_blank_check(void) +{ + int j; + int data; + u8 buf[2]; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < chip_cpld_info->first_blank_check_length; j++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + data = (buf[1] << 8) | buf[0]; + } + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x1, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < chip_cpld_info->second_blank_check_length; j++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + data = (buf[1] << 8) | buf[0]; + } +} + +/* + * jtag_verify1 + * function :JTAG content validation + * @buffer : param[in] original data + * return value 0 validation success; -1 validation failed + */ +static int jtag_verify1(unsigned int *buffer) +{ + int j, ret = 0; + unsigned int data; + u8 buf[2]; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < chip_cpld_info->eeprom_array_length; j++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + data = (buf[1] << 8) | buf[0]; + + if (data != buffer[j]) { + FIRMWARE_DRIVER_DEBUG_ERROR("%d: %02x, %02x.\n", j, data, buffer[j]); + ret = -1; + break; + } + } + return ret; +} + +/* + * jtag_read_buffer + * function:JTAG internal data reading + * @size: param[in] Read size + * @buffer: param[out] Pointer to read data + */ +static void jtag_read_buffer(unsigned int *buffer, int size) +{ + int j; + int data; + u8 buf[2]; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < size; j++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + data = (buf[1] << 8) | buf[0]; + buffer[j] = data; + } +} + +/* + * jtag_program + * function:JTAG programming timing + * @buffer: param[in] data pointer to program + */ +static void jtag_program(unsigned int *buffer) +{ + int i, j; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < chip_cpld_info->eeprom_array_length; j++) { + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_send_data(buffer[j], chip_cpld_info->data_register_length); + for (i = 0; i < PROGRAM_DELAY; i++) { + tap_idle(); + tap_idle(); + } + } +} + +/* + * cpld_read_id + * function: CPLD chip ID read + * @chip: param[in] chip index + * id : param[out] ID point */ +static void cpld_read_id(int chip, unsigned int *id) +{ + u8 data[sizeof(int)]; + if (!chip_num || chip > chip_num) { + return; + } + current_chip_index = chip; + /* Send instructions */ + jtag_send_instruction(IDCODE, CPLD_INSTRUCTION_SIZE); + /* Read Data */ + jtag_read_data(data, sizeof(int)); + *id = (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]; +} + +/* + * chip_num_init + * function:CPLD number of chips initialized */ +static void chip_num_init(void) +{ + unsigned int i, id; + unsigned char buf[sizeof(int) * CPLD_MAX_CHIP]; + chip_num = 0; + + /* JTAG state switching */ + tap_run_test_idle(); + tap_select_dr_scan(); + tap_capture_dr(); + tap_shift_dr(); + + for (i = 0; i < sizeof(int) * CPLD_MAX_CHIP; i++) { + tap_rcv_byte(&buf[i]); + } + + /* JTAG state switching */ + tap_exit1_dr(0); + tap_update_dr(); + tap_run_test_idle(); + + for (i = 0; i < sizeof(int) * CPLD_MAX_CHIP; i += 4) { + id = (buf[i + 3] << 24) | (buf[i + 2] << 16) | (buf[i + 1] << 8) | buf[i]; + FIRMWARE_DRIVER_DEBUG_VERBOSE("ID: %04x\n", id); + if (id != 0xFFFFFFFF && id != 0) { + chip_num++; + } + } +} + +/* + * cpld_reset + * function: reset JTAG + * @chip: param[in] chip index + */ +static void cpld_reset(int chip) +{ + unsigned int chip_type_id = 0; + int i; + /* JTAG enters the reset state */ + tap_test_logic_reset(); + /* Gets the number of chips in the CPLD */ + chip_num_init(); + if (!chip_num) { + pr_notice("There is no CPLD chip or the chip is not supported!!\r\n"); + FIRMWARE_DRIVER_DEBUG_ERROR("chip_num == NULL.\n"); + } else { + FIRMWARE_DRIVER_DEBUG_VERBOSE("enter cpld read id.\n"); + current_chip_index = chip; + /* Read chip ID */ + cpld_read_id(current_chip_index, &chip_type_id); + FIRMWARE_DRIVER_DEBUG_VERBOSE("get cpld id: 0x%x.\n", chip_type_id); + for (i = 0; cpld_id_table[i].name != NULL; i++) { + if (cpld_id_table[i].id == chip_type_id) { + chip_cpld_info = &cpld_id_table[i]; + break; + } + } + } + current_chip_index = -1; + tap_test_logic_reset(); +} + +/* + * cpld_program + * function: CPLD programming interface + * @chip: param[in] Chip serial number/chip index + * @buffer: param[in] data pointer to program + * return value: 0 success; -1 fail + */ +static int cpld_program(int chip, unsigned int *buffer) +{ + int ret; + int counte; + + if (!chip_num || chip > chip_num + || chip_cpld_info == NULL) { + return -1; + } + current_chip_index = chip; + + /* Enter Real-Time ISP mode */ + jtag_rt_enable(); + /* JTAG internal ID reading */ + jtag_verify_idcode(); + /* JTAG erases */ + jtag_erase(); + /* JTAG blank detection */ + jtag_blank_check(); + /* JTAG programming timing */ + jtag_program(buffer); + + /* In the process of upgrade, there is a problem with reading data, + * which may occur in the process of reading. Some bit reading fails, + * but the reason is not found. + * Avoidance resolution: perform multiple checks */ + for (counte = 0; counte < 4; counte++) { + ret = jtag_verify1(buffer); + if (counte > 0) { + pr_notice("Verify again(%d).\n", counte + 1); + } + + if (ret == 0) { + break; + } + } + pr_notice("Write chip %d cpld success(%d).\n", chip, ret); + jtag_program_donebit(); + + /* JTAG Disable state machine under Real-Time ISP */ + jtag_rt_disable(); + + return ret; +} + +static void cpld_read_buffer(int chip, unsigned int *buffer, unsigned int size) +{ + if (!chip_num || chip > chip_num + || chip_cpld_info == NULL) { + return; + } + current_chip_index = chip; + + /* Enter Real-Time ISP mode */ + jtag_rt_enable(); + + /* JTAG internal ID reading */ + jtag_verify_idcode(); + + /* JTAG internal data reading */ + jtag_read_buffer(buffer, size); + + jtag_rt_disable(); + +} + +/* + * cpld_eeprom_size + * function:CPLD chip capacity size + * return value :Returns chip capacity on success, or 0 on failure + */ +static int cpld_eeprom_size(void) +{ + int ret; + + if (!chip_num || chip_cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("chip_num:%d or chip_cpld_info == NULL.\n", chip_num); + ret = 0; + } else { + ret = chip_cpld_info->eeprom_array_length; + FIRMWARE_DRIVER_DEBUG_ERROR("chip_cpld_info->eeprom_array_length = %d.\n", + chip_cpld_info->eeprom_array_length); + } + + return ret; +} + +/* + * cpld_read_name + * function: Gets the CPLD chip name + * @chip: param[in] Chip serial number/chip index + * return value :chip name */ +static char *cpld_read_name(int chip) +{ + uint chip_type_id; + int i; + + chip_type_id = 0; + cpld_read_id(chip, &chip_type_id); + for (i = 0; cpld_id_table[i].name != NULL; i++) { + if (cpld_id_table[i].id == chip_type_id) { + return cpld_id_table[i].name; + } + } + + return NULL; +} + +/* + * cpld_upgrade_init + * function:Initialize GPIO and CPLD + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int cpld_upgrade_init(void) +{ + int ret; + + if (function_fmw_cpld.init_cpld != NULL) { + ret = function_fmw_cpld.init_cpld(); + if (ret != FIRMWARE_SUCCESS) { + return ret; + } + } + + return FIRMWARE_SUCCESS; +} + +/* + * cpld_upgrade_finish + * function:Release GPIO and CPLD + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int cpld_upgrade_finish(void) +{ + int ret; + + if (function_fmw_cpld.finish_cpld != NULL) { + ret = function_fmw_cpld.finish_cpld(); + if (ret != FIRMWARE_SUCCESS) { + return ret; + } + } + + return FIRMWARE_SUCCESS; +} + +static int cpld_str_hex_to_dec(char *str, char end_char) +{ + int i; + int result; + + if (str == NULL) { + return FIRMWARE_FAILED; + } + + i = 0; + result = 0; + while (str[i] != end_char) { + /* Check for hexadecimal characters:0123456789abcdef */ + if (!isxdigit(str[i]) || i >= CPLD_UNIT_SZ) { + return FIRMWARE_FAILED; + } + /* Check for a number between 0 and 9 */ + if (isdigit(str[i])) { + result = result * CPLD_HEX + str[i] - '0'; + } + /* Check if the character is uppercase */ + else if (isupper(str[i])) { + result = result * CPLD_HEX + str[i] - 'A' + DEC_VAL; + } else { + result = result * CPLD_HEX + str[i] - 'a' + DEC_VAL; + } + + i++; + } + + return result; +} + +static int cpld_check_upgrade_data(char *src, int src_len, int *dst, int dst_len) +{ + int i, init_lcnt, tmp; + char *ptr; + int ret; + + if (src == NULL || dst == NULL) { + return FIRMWARE_FAILED; + } + /* Pointers the ptr pointer to the data following the CPLD_INIT_KEYWORD */ + ret = FIRMWARE_SUCCESS; + ptr = strstr(src, CPLD_INIT_KEYWORD); + if (ptr == NULL) { + return FIRMWARE_FAILED; + } else { + ptr += strlen(CPLD_INIT_KEYWORD); + while (*ptr == '(' || *ptr == '\r' || *ptr == '\n') { + ptr++; + } + } + + /* Converts a hexadecimal string to decimal, with 4 groups of 4 bytes each */ + i = 0; + init_lcnt = 0; + for (init_lcnt = 0; init_lcnt < CPLD_INIT_CNT; init_lcnt++) { + tmp = cpld_str_hex_to_dec(ptr, CPLD_END_CHAR); + if (tmp < 0) { + ret = tmp; + return ret; + } + /* int type is 4 bytes */ + dst[i++] = tmp; + if (i >= dst_len) { + return FIRMWARE_SUCCESS; + } + + ptr += CPLD_UNIT_SZ + 1; + + while (*ptr == '\r' || *ptr == '\n') { + ptr++; + } + } + + /* Point the ptr pointer to the data after CPLD_REPEAT_KEYWORD */ + ptr = strstr(src, CPLD_REPEAT_KEYWORD); + if (ptr == NULL) { + return FIRMWARE_FAILED; + } else { + ptr += strlen(CPLD_REPEAT_KEYWORD); + while (*ptr == '(' || *ptr == '\r' || *ptr == '\n') { + ptr++; + } + } + + while (1) { + /* Converts the 4 bytes before ',' to base 10 */ + tmp = cpld_str_hex_to_dec(ptr, CPLD_END_CHAR); + if (tmp < 0) { + ret = tmp; + break; + } + dst[i++] = tmp; + if (i >= dst_len) { + return FIRMWARE_SUCCESS; + } + + ptr += CPLD_UNIT_SZ + 1; + + while (*ptr == '\r' || *ptr == '\n') { + ptr++; + } + } + + return FIRMWARE_SUCCESS; +} + +/** + * fmw_cpld_upg_get_chip_name + * function:get chip name + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @len: param[in] chip name length + * @info: param[out] chip name + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_get_chip_name(int chain, firmware_cpld_t *cpld, char *info, int len) +{ + int ret; + char *name; + + /* Check the input and output parameters */ + if (chain < 0 || info == NULL || len <= 0) { + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to get chip name.\n"); + + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit." + "(chain = %d, current chain = %d, current name: %s)\n", + chain, current_fmw_cpld->chain, current_fmw_cpld->devname); + } + + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error:Failed to get chip name when init upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + /* reset JTAG */ + cpld_reset(current_fmw_cpld->chip_index); + /* Read chip name */ + name = cpld_read_name(current_fmw_cpld->chip_index); + if (name == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to get chip name when read name.(chain %d, index %d)\n", + chain, current_fmw_cpld->chip_index); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + /* Release GPIO */ + ret = cpld_upgrade_finish( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to get chip name when finish upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + strncpy(info, name, len); + + return FIRMWARE_SUCCESS; +} + +/** + * fmw_cpld_upg_program + * function:Upgrade CPLD(ISC file format) + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @info: param[in] Data to be written + * @len: param[in] Length of data to be written + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_program(int chain, firmware_cpld_t *cpld, char *info, int len) +{ + int i; + int time; + int ret; + int target_len; + int *target_buf; + + /* Check the input parameters */ + if (chain < 0 || info == NULL || len <= 0) { + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to program chip.\n"); + + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit.(chain = %d, current chain = %d)\n", + chain, current_fmw_cpld->chain); + } + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program when init upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + /* reset JTAG */ + cpld_reset(current_fmw_cpld->chip_index); + /* CPLD chip capacity size */ + target_len = cpld_eeprom_size(); + if (target_len <= 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to get cpld size.(chain = %d)\n", + chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + target_buf = (int *) kzalloc(target_len * sizeof(int), GFP_KERNEL); + if (target_buf == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to malloc target buffer.(chain = %d)\n", + chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("cpld_check_upgrade_data start.(chain = %d, %d)\n", + chain, target_len); + /* Remove extraneous information */ + ret = cpld_check_upgrade_data(info, len, target_buf, target_len); + if (ret < 0){ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to check data.(chain = %d)\n", + chain); + kfree(target_buf); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + for (i = 0; i < 16 * 8; i += 8) { + FIRMWARE_DRIVER_DEBUG_VERBOSE(" %x %x %x %x %x %x %x %x\n", + target_buf[i], target_buf[i + 1], + target_buf[i + 2], target_buf[i + 3], + target_buf[i + 4], target_buf[i + 5], + target_buf[i + 6], target_buf[i + 7]); + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("cpld_check_upgrade_data finish.(chain = %d)\n", chain); + + /* CPLD device writing */ + for (time = 0; time < 10; time++) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("Start upgrade cpld: %d.(chain = %d)\n", time, chain); + ret = cpld_program(current_fmw_cpld->chip_index, target_buf); + if (ret >= 0) { + break; + } + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program.(chain = %d)\n", chain); + kfree(target_buf); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("SUCCESS PROGRAM.\n"); + + /* Release GPIO */ + ret = cpld_upgrade_finish(); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to program when finish upgrade.(chain = %d)\n", + chain); + } + + kfree(target_buf); + return FIRMWARE_SUCCESS; +} + +/** + * fmw_cpld_upg_program_jbi + * function: Upgrade CPLD(JBI file format) + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @info: param[in] Data to be written + * @len: param[in] Length of data to be written + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_program_jbi(int chain, firmware_cpld_t *cpld, char *info, int len) +{ + int time, ret; + int argc = 3; + char *argv[] = { + "-r", + "-aprogram", + "-ddo_real_time_isp=1" + }; + + /* Check the input parameters */ + if (chain < 0 || info == NULL || len <= 0) { + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to program chip %d(%p,%p,%d).\n", + chain, cpld, info, len); + + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit.(chain = %d, current chain = %d)\n", + chain, current_fmw_cpld->chain); + } + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program when init upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + /* reset JTAG */ + cpld_reset(current_fmw_cpld->chip_index); + + for (time = 0; time < 30; time++) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("Start upgrade cpld: %d.(chain = %d)\n", time, chain); + ret = jbi_main((unsigned char *) info, (unsigned long) len, argc, argv); + if (ret == 0) { + break; + } + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program.(chain = %d)\n", chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + FIRMWARE_DRIVER_DEBUG_VERBOSE("SUCCESS PROGRAM.\n"); + + /* Release GPIO and CPLD */ + ret = cpld_upgrade_finish( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to program when finish upgrade.(chain = %d)\n", + chain); + } + + return FIRMWARE_SUCCESS; +} + +/** + * fmw_cpld_upg_get_version + * function: get version + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @len: param[in] Data length + * @info: param[out] Version information buffer + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_get_version(int chain, firmware_cpld_t *cpld, char *info, int len) +{ + int ret; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to get version.\n"); + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit.(chain = %d, current chain = %d)\n", + chain, current_fmw_cpld->chain); + } + + /* CPLD device can't get version */ + if (function_fmw_cpld.get_version != NULL) { + ret = function_fmw_cpld.get_version(chain, info, len); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed get version in chain: %d.\n", chain); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("The get_version is NULL in chain: %d.\n", chain); + } + + return FIRMWARE_FAILED; +} + +/** + * fmw_cpld_upg_get_chip_info + * function: Get chip content + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @len: param[in] Data length + * @info: param[out] Read Data Buffer + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_get_chip_info(int chain, firmware_cpld_t *cpld, void *info, int len) +{ + int i; + int ret; + int target_len; + int *target_buf; + + /* Check input and output parameters */ + if (chain < 0 || info == NULL || len <= 0) { + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to read chip.\n"); + + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to read chip: %s.\n",current_fmw_cpld->devname); + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit.(chain = %d, current chain = %d)\n", + chain, current_fmw_cpld->chain); + } + + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program when init upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + /* reset JTAG*/ + cpld_reset(current_fmw_cpld->chip_index); + /* CPLD chip capacity size */ + target_len = cpld_eeprom_size(); + if (target_len <= 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to get cpld size.(chain = %d)\n", + chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + target_buf = (int *) kzalloc(target_len * sizeof(int), GFP_KERNEL); + if (target_buf == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to malloc target buffer.(chain = %d)\n", + chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + /* Read chip */ + cpld_read_buffer(current_fmw_cpld->chip_index, target_buf, target_len); + + for (i = 0; i < 16 * 8; i += 8) { + FIRMWARE_DRIVER_DEBUG_VERBOSE(" %x %x %x %x %x %x %x %x\n", + target_buf[i], target_buf[i + 1], + target_buf[i + 2], target_buf[i + 3], + target_buf[i + 4], target_buf[i + 5], + target_buf[i + 6], target_buf[i + 7]); + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Success Read.\n"); + + /* Release GPIO and CPLD */ + ret = cpld_upgrade_finish( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to program when finish upgrade.(chain = %d)\n", + chain); + } + + if (copy_to_user(info, target_buf, (len > target_len) ? target_len : len)) { + kfree(target_buf); + return FIRMWARE_FAILED; + } + + kfree(target_buf); + return FIRMWARE_SUCCESS; +} + +/** + * jbi_jtag_io_ + * function: JBI GPIO operation + * @tms: param[in] TMS signal level + * @tdi: param[in] TDI signal level + * @read_tdo: param[in] Whether to read the level of the TDO + * return value : tdo + */ +int __attribute__ ((weak)) jbi_jtag_io_(int tms, int tdi, int read_tdo) +{ + int tdo = 0; + + if (tms) { + TMS_PULL_UP(); + } else { + TMS_PULL_DOWN(); + } + + if (tdi) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + + TCK_PULL_UP(); + ndelay(TCK_DELAY); + + if (read_tdo) { + tdo = TDO_READ(); + } + + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + + return tdo; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware.h new file mode 100644 index 000000000000..3a6ab117df5d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware.h @@ -0,0 +1,82 @@ +#ifndef __FIRMWARE_H__ +#define __FIRMWARE_H__ + +#include +#include + +#include + +/* Debug switch level */ +typedef enum { + FIRWMARE_VERBOSE, + FIRWMARE_WARN, + FIRWMARE_ERROR, + FIRWMARE_END, +} firmware_debug_level_t; + +#define FIRMWARE_DRIVER_DEBUG_VERBOSE(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_VERBOSE)) { \ + printk(KERN_INFO "[FIRMWARW_DRIVER_CPLD][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_DRIVER_DEBUG_ERROR(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_ERROR)) { \ + printk(KERN_ERR "[FIRMWARW_DRIVER_CPLD][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_NAME_LEN 48 + +#define FIRMWARE_FAILED (-1) +#define FIRMWARE_SUCCESS 0 + +/* ioctl publi command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_COMMON_TYPE 'C' +#define FIRMWARE_GET_CHIPNAME _IOR(FIRMWARE_COMMON_TYPE, 0, char) /* get the chip name */ +#define FIRMWARE_GET_VERSION _IOR(FIRMWARE_COMMON_TYPE, 2, int) /* get version */ + +/* firmware cpld driver ioctl command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_TYPE 'J' +#define FIRMWARE_PROGRAM _IOW(FIRMWARE_TYPE, 1, char) /* firmware upgrade ISC */ +#define FIRMWARE_READ_CHIP _IOR(FIRMWARE_TYPE, 5, int) /* read the contents of the chip */ +#define FIRMWARE_PROGRAM_JBI _IOW(FIRMWARE_TYPE, 6, char) /* firmware upgrade JBI */ + +typedef struct cmd_info_s { + uint32_t size; + void __user *data; +} cmd_info_t; + +typedef struct firmware_device_s { + struct list_head list; /* device list */ + uint32_t chain; /* chain number */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct miscdevice dev; /* device */ + void *priv; /* private data */ +} firmware_device_t; + +typedef struct firmware_driver_s { + struct list_head list; /* list */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct platform_driver *drv; /* driver */ + void *priv; /* private data */ +} firmware_driver_t; + +extern int g_firmware_driver_debug; + +/* Get device information based on minor */ +extern firmware_device_t *firmware_get_device_by_minor(int minor); +/* Registere device */ +extern int firmware_device_register(firmware_device_t *fw_dev); +/* Unregister device */ +extern void firmware_device_unregister(firmware_device_t *fw_dev); +/* Registere driver */ +extern int firmware_driver_register(firmware_driver_t *fw_drv); +/* Unregister driver */ +extern void firmware_driver_unregister(firmware_driver_t *fw_drv); +/* CPLD upgrade initialized */ +extern int firmware_cpld_init(void); +/* CPLD unload function */ +extern void firmware_cpld_exit(void); + +#endif /* end of __FIRMWARE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware_cpld.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware_cpld.h new file mode 100644 index 000000000000..ef69655a4b2e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware_cpld.h @@ -0,0 +1,64 @@ +#ifndef __FIRMWARE_CPLD_H__ +#define __FIRMWARE_CPLD_H__ + +#define FIRMWARE_DEV_NAME_LEN 32 +#define FIRMWARE_MAX_CPLD_NUM 16 +#define FIRMWARE_TYPE_LEN 10 +#define FIRMWARE_EN_INFO_MAX 16 +#define FIRMWARE_EN_INFO_BUF 128 + +typedef struct firmware_gpio_jtag_en_s { + uint32_t en_gpio; /* GPIO enable pin */ + uint32_t en_level; /* GPIO enable level */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_gpio_jtag_en_t; + +typedef struct firmware_cpld_s { + char devname[FIRMWARE_DEV_NAME_LEN]; /* Device name */ + char type[FIRMWARE_TYPE_LEN]; /* interface type */ + uint32_t tdi; /* TDI signal corresponding to GPIO pin information */ + uint32_t tck; /* TCK signal corresponding to GPIO pin information */ + uint32_t tms; /* TMS signal corresponding to GPIO pin information */ + uint32_t tdo; /* TDO signal corresponding to GPIO pin information */ + uint32_t chain; /* chain num */ + uint32_t chip_index; /* chip index */ + uint32_t tck_delay; /* Delay time */ + uint32_t gpio_en_info_num; /* GPIO Enable Number */ + firmware_gpio_jtag_en_t gpio_en_info[FIRMWARE_EN_INFO_MAX]; /* GPIO Enable Information */ +} firmware_cpld_t; + +typedef struct firmware_cpld_function_s{ + int (*pull_tdi_up)(void); /* TDI pull-up */ + int (*pull_tdi_down)(void); /* TDI pull-down */ + int (*pull_tck_up)(void); /* TCK pull-up */ + int (*pull_tck_down)(void); /* TCK pull-down */ + int (*pull_tms_up)(void); /* TMS pull-up */ + int (*pull_tms_down)(void); /* TCK pull-down */ + int (*read_tdo)(void); /* Read TDO */ + int (*init_cpld)(void); /* CPLD upgrade initializes the operation */ + int (*init_chip)(int chain); /* chip initializes the operation */ + int (*finish_chip)(int chain); /* chip completes the operation*/ + int (*finish_cpld)(void); /* CPLD upgrade completes the operation */ + int (*get_version)(int chain, char *ver, int len); /* get version */ +}firmware_cpld_function_t; + +/* get chip name */ +extern int fmw_cpld_upg_get_chip_name(int chain, firmware_cpld_t *cpld, char *info, int len); +/* ISC firmware upgrad */ +extern int fmw_cpld_upg_program(int chain, firmware_cpld_t *cpld, char *info, int len); +/* get version */ +extern int fmw_cpld_upg_get_version(int chain, firmware_cpld_t *cpld, char *info, int len); +/* Read the contents of Chip */ +extern int fmw_cpld_upg_get_chip_info(int chain, firmware_cpld_t *cpld, void *info, int len); +/* operate TDI */ +extern int fwm_cpld_tdi_op(int value); +/* operate TCK */ +extern int fwm_cpld_tck_op(int value); +/* operate TMS */ +extern int fwm_cpld_tms_op(int value); +/* operate TDO */ +extern int fwm_cpld_tdo_op(void); +/* JBI firmware upgrad */ +extern int fmw_cpld_upg_program_jbi(int chain, firmware_cpld_t *cpld, char *info, int len); + +#endif /* __FIRMWARE_CPLD_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/jbi.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/jbi.h new file mode 100644 index 000000000000..865c8d352174 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/jbi.h @@ -0,0 +1,15 @@ +#ifndef __JBI_H__ +#define __JBI_H__ + +#include + +/* JTAG operation interface*/ +extern int jbi_jtag_io_(int tms, int tdi, int read_tdo); +/* delay function */ +extern void jbi_jtag_udelay(unsigned long us); +/* Debug switch */ +extern int jbi_debug(int level); +/* JBI upgrade function */ +extern int jbi_main(unsigned char *addr, unsigned long size, int argc, char * const argv[]); + +#endif /* __JBI_JTAG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.c new file mode 100644 index 000000000000..064d0ae50ec4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.c @@ -0,0 +1,438 @@ +/****************************************************************************/ +/* */ +/* Module: jbicomp.c */ +/* */ +/* Copyright (C) Altera Corporation 1997-2001 */ +/* */ +/* Description: Contains the code for compressing and uncompressing */ +/* Boolean array data. */ +/* */ +/* This algorithm works by searching previous bytes in the */ +/* data that match the current data. If a match is found, */ +/* then the offset and length of the matching data can */ +/* replace the actual data in the output. */ +/* */ +/* Revisions: 2.2 fixed /W4 warnings */ +/* */ +/****************************************************************************/ + +#include "jbiport.h" +#include "jbiexprt.h" +#include "jbicomp.h" +#include "jbistub.h" + +#define SHORT_BITS 16 +#define CHAR_BITS 8 +#define DATA_BLOB_LENGTH 3 +#define MATCH_DATA_LENGTH 8192 +#define JBI_ACA_REQUEST_SIZE 1024 +#define JBI_ACA_BUFFER_SIZE (MATCH_DATA_LENGTH + JBI_ACA_REQUEST_SIZE) + +unsigned long jbi_in_length = 0L; +unsigned long jbi_in_index = 0L; /* byte index into compressed array */ +unsigned int jbi_bits_avail = CHAR_BITS; + +#if PORT == DOS +int jbi_current_variable_id = -1; +int jbi_current_page = -1; +int jbi_version = 0; +unsigned long jbi_out_length = 0L; +unsigned int jbi_out_index = 0; /* byte index into jbi_aca_out_buffer[] */ +unsigned long jbi_aca_in_offset = 0L; +unsigned char jbi_aca_out_buffer[JBI_ACA_BUFFER_SIZE]; +#endif + +/****************************************************************************/ +/* */ +/* The following functions implement incremental decompression of Boolean */ +/* array data, using a small memory window. */ +/* */ +/* This algorithm works by searching previous bytes in the data that match */ +/* the current data. If a match is found, then the offset and length of */ +/* the matching data can replace the actual data in the output. */ +/* */ +/* Memory usage is reduced by maintaining a "window" buffer which contains */ +/* the uncompressed data for one 8K page, plus some extra amount specified */ +/* by JBI_ACA_REQUEST_SIZE. The function jbi_uncompress_page() is used to */ +/* request a subrange of the uncompressed data, starting at a particular */ +/* bit position and extending a maximum of JBI_ACA_REQUEST_SIZE bytes. */ +/* */ +/****************************************************************************/ + +/****************************************************************************/ +/* */ + +unsigned int jbi_bits_required(unsigned int n) + +/* */ +/* Description: Calculate the minimum number of bits required to */ +/* represent n. */ +/* */ +/* Returns: Number of bits. */ +/* */ +/****************************************************************************/ +{ + unsigned int result = SHORT_BITS; + + if (n == 0) + { + result = 1; + } + else + { + /* Look for the highest non-zero bit position */ + while ((n & (1 << (SHORT_BITS - 1))) == 0) + { + n <<= 1; + --result; + } + } + + return (result); +} + +/****************************************************************************/ +/* */ + +unsigned int jbi_read_packed +( +#if PORT!=DOS + unsigned char *buffer, +#endif + unsigned int bits +) + +/* */ +/* Description: Read the next value from the input array "buffer". */ +/* Read only "bits" bits from the array. The amount of */ +/* bits that have already been read from "buffer" is */ +/* stored internally to this function. */ +/* */ +/* Returns: Up to 16 bit value. -1 if buffer overrun. */ +/* */ +/****************************************************************************/ +{ + unsigned int result = 0; + unsigned int shift = 0; + unsigned int databyte = 0; + + while (bits > 0) + { +#if PORT==DOS + databyte = GET_BYTE(jbi_aca_in_offset + jbi_in_index); +#else + databyte = buffer[jbi_in_index]; +#endif + result |= (((databyte >> (CHAR_BITS - jbi_bits_avail)) + & (0xFF >> (CHAR_BITS - jbi_bits_avail))) << shift); + + if (bits <= jbi_bits_avail) + { + result &= (0xFFFF >> (SHORT_BITS - (bits + shift))); + jbi_bits_avail -= bits; + bits = 0; + } + else + { + ++jbi_in_index; + shift += jbi_bits_avail; + bits -= jbi_bits_avail; + jbi_bits_avail = CHAR_BITS; + } + } + + return (result); +} + +#if PORT==DOS + +/****************************************************************************/ +/* */ + +void jbi_uncompress_next_page(int version) + +/* */ +/* Description: Uncompresses one page of compressed data, using */ +/* data page as reference for repeated sections. */ +/* Overwrites previous page of data in buffer. */ +/* */ +/* Returns: TRUE for success, FALSE if error encountered */ +/* */ +/****************************************************************************/ +{ + unsigned int i, j, offset, length; + unsigned int end_index; + unsigned long tmp_in_index = jbi_in_index; + unsigned int tmp_out_index = jbi_out_index; + unsigned int tmp_bits_avail = jbi_bits_avail; + unsigned int prev[3]; + unsigned long long_end; + unsigned int match_data_length = MATCH_DATA_LENGTH; + + if (version > 0) --match_data_length; + + if (jbi_current_page < 0) + { + /* this is the first page of the array */ + jbi_current_page = 0; + jbi_in_index = 4; /* skip over length field */ + jbi_out_index = 0; + end_index = (jbi_out_length < JBI_ACA_BUFFER_SIZE) ? + (unsigned int) jbi_out_length : JBI_ACA_BUFFER_SIZE; + } + else + { + /* this is not the first page */ + ++jbi_current_page; + jbi_out_index -= MATCH_DATA_LENGTH; + long_end = jbi_out_length - + ((long) jbi_current_page * (long) MATCH_DATA_LENGTH); + end_index = (long_end < JBI_ACA_BUFFER_SIZE) ? + (unsigned int) long_end : JBI_ACA_BUFFER_SIZE; + + /* copy extra data from end of circular buffer to beginning */ + for (i = 0; i < jbi_out_index; ++i) + { + jbi_aca_out_buffer[i] = jbi_aca_out_buffer[i + MATCH_DATA_LENGTH]; + } + } + + while (jbi_out_index < end_index) + { + /* save state so we can undo the last packet when we reach the end */ + tmp_in_index = jbi_in_index; + tmp_out_index = jbi_out_index; + tmp_bits_avail = jbi_bits_avail; + + /* A 0 bit indicates literal data. */ + if (jbi_read_packed(1) == 0) + { + for (i = 0; i < DATA_BLOB_LENGTH; ++i) + { + if (jbi_out_index < end_index) + { + if (version == 0) + { + prev[i] = jbi_aca_out_buffer[jbi_out_index] & 0xff; + } + jbi_aca_out_buffer[jbi_out_index++] = + (unsigned char) jbi_read_packed(CHAR_BITS); + } + } + } + else + { + /* A 1 bit indicates offset/length to follow. */ + offset = jbi_read_packed(jbi_bits_required( + (jbi_current_page > 0) ? match_data_length : + (jbi_out_index > match_data_length ? match_data_length : + jbi_out_index))); + length = jbi_read_packed(CHAR_BITS); + + if ((version == 0) && (offset == match_data_length + 3)) + { + jbi_aca_out_buffer[jbi_out_index++] = (unsigned char) prev[0]; + jbi_aca_out_buffer[jbi_out_index++] = (unsigned char) prev[1]; + jbi_aca_out_buffer[jbi_out_index++] = (unsigned char) prev[2]; + length -= 3; + } + + for (i = 0; i < length; ++i) + { + if (jbi_out_index < end_index) + { + if (offset > jbi_out_index) + { + j = jbi_out_index + MATCH_DATA_LENGTH - offset; + } + else j = jbi_out_index - offset; + jbi_aca_out_buffer[jbi_out_index] = jbi_aca_out_buffer[j]; + ++jbi_out_index; + } + } + + if (version == 0) + { + prev[0] = jbi_aca_out_buffer[jbi_out_index - 3] & 0xff; + prev[1] = jbi_aca_out_buffer[jbi_out_index - 2] & 0xff; + prev[2] = jbi_aca_out_buffer[jbi_out_index - 1] & 0xff; + } + } + } + + /* restore the state before the previous packet */ + jbi_in_index = tmp_in_index; + jbi_out_index = tmp_out_index; + jbi_bits_avail = tmp_bits_avail; +} + +/****************************************************************************/ +/* */ + +void jbi_uncompress_page +( + int variable_id, + int page, + int version +) + +/* */ +/* Description: Uncompress requested page of variable data. Stores */ +/* uncompressed data in jbi_aca_out_buffer[]. */ +/* */ +/* Returns: TRUE if successful, otherwise FALSE if: */ +/* 1) variable is not a compressed array */ +/* 2) compressed data is illegal or corrupted */ +/* 3) requested page is beyond the end of the array */ +/* 4) internal error in the code */ +/* */ +/****************************************************************************/ +{ + unsigned long symbol_table; + unsigned long data_section; + unsigned long offset; + unsigned long value; + int delta = version * 2; + + if (variable_id != jbi_current_variable_id) + { + /* initialize to uncompress the desired variable */ + symbol_table = GET_DWORD(16 + (version * 8)); + data_section = GET_DWORD(20 + (version * 8)); + offset = symbol_table + ((11 + delta) * variable_id); + value = GET_DWORD(offset + 3 + delta); + jbi_current_variable_id = variable_id; + jbi_current_page = -1; + jbi_bits_avail = CHAR_BITS; + jbi_in_length = GET_DWORD(offset + 7 + delta); + jbi_out_length = + (((unsigned long) GET_BYTE(data_section + value)) | + (((unsigned long) GET_BYTE(data_section + value + 1)) << 8) | + (((unsigned long) GET_BYTE(data_section + value + 2)) << 16) | + (((unsigned long) GET_BYTE(data_section + value + 3)) << 24)); + jbi_in_index = 4; /* skip over length field */ + jbi_out_index = 0; + jbi_aca_in_offset = data_section + value; + } + + /* to look back at an earlier page, start over at the beginning */ + if (page < jbi_current_page) + { + jbi_current_page = -1; + jbi_in_index = 4; /* skip over length field */ + jbi_bits_avail = CHAR_BITS; + } + + /* uncompress sequentially up to the desired page */ + while (page > jbi_current_page) + { + jbi_uncompress_next_page(version); + } +} + +#else + +/****************************************************************************/ +/* */ + +unsigned long jbi_uncompress +( + unsigned char *in, + unsigned long in_length, + unsigned char *out, + unsigned long out_length, + int version +) + +/* */ +/* Description: Uncompress data in "in" and write result to "out". */ +/* */ +/* Returns: Length of uncompressed data. -1 if: */ +/* 1) out_length is too small */ +/* 2) Internal error in the code */ +/* 3) in doesn't contain ACA compressed data. */ +/* */ +/****************************************************************************/ +{ +#ifdef CONFIG_64BIT + unsigned int data_length = 0; +#else + unsigned long data_length = 0L; +#endif + unsigned long i, j; + unsigned int offset, length; + unsigned int match_data_length = MATCH_DATA_LENGTH; + + if (version > 0) --match_data_length; + + jbi_in_length = in_length; + jbi_bits_avail = CHAR_BITS; + jbi_in_index = 0L; + for (i = 0; i < out_length; ++i) out[i] = 0; + + /* Read number of bytes in data. */ +#ifdef CONFIG_64BIT + for (i = 0; i < sizeof(unsigned int); ++i) + { + data_length = data_length | ((unsigned int) + jbi_read_packed(in, CHAR_BITS) << (i * CHAR_BITS)); + } +#else + for (i = 0; i < sizeof (in_length); ++i) + { + data_length = data_length | ((unsigned long) + jbi_read_packed(in, CHAR_BITS) << (i * CHAR_BITS)); + } +#endif + + if (data_length > out_length) + { +#ifdef CONFIG_64BIT + jbi_dbg(DEBUG_ERR, "data_length(0x%x,0x%lx)\n", + data_length, out_length); + data_length = 0; +#else + jbi_dbg(DEBUG_ERR, "data_length(0x%lx,0x%lx)\n", + data_length, out_length); + data_length = 0L; +#endif + } + else + { + i = 0; + while (i < data_length) + { + /* A 0 bit indicates literal data. */ + if (jbi_read_packed(in, 1) == 0) + { + for (j = 0; j < DATA_BLOB_LENGTH; ++j) + { + if (i < data_length) + { + out[i] = (unsigned char) jbi_read_packed(in, CHAR_BITS); + i++; + } + } + } + else + { + /* A 1 bit indicates offset/length to follow. */ + offset = jbi_read_packed(in, jbi_bits_required((short) (i > match_data_length ? match_data_length : i))); + length = jbi_read_packed(in, CHAR_BITS); + + for (j = 0; j < length; ++j) + { + if (i < data_length) + { + out[i] = out[i - offset]; + i++; + } + } + } + } + } + + return (data_length); +} + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.h new file mode 100644 index 000000000000..4dacdcd5d773 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.h @@ -0,0 +1,37 @@ +/****************************************************************************/ +/* */ +/* Module: jbicomp.h */ +/* */ +/* Copyright (C) Altera Corporation 1997-2001 */ +/* */ +/* Description: Contains the function prototypes for compressing */ +/* and uncompressing Boolean array data. */ +/* */ +/****************************************************************************/ + +#ifndef INC_JBICOMP_H +#define INC_JBICOMP_H + +#if PORT==DOS + +void jbi_uncompress_page +( + int variable_id, + int page, + int version +); + +#else + +unsigned long jbi_uncompress +( + unsigned char *in, + unsigned long in_length, + unsigned char *out, + unsigned long out_length, + int version +); + +#endif /* PORT==DOS */ + +#endif /* INC_JBICOMP_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiexprt.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiexprt.h new file mode 100644 index 000000000000..ef4699dd6db3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiexprt.h @@ -0,0 +1,224 @@ +/****************************************************************************/ +/* */ +/* Module: jbiexprt.h */ +/* */ +/* Copyright (C) Altera Corporation 1998-2001 */ +/* */ +/* Description: Jam STAPL ByteCode Player Export Header File */ +/* */ +/* Revisions: */ +/* */ +/****************************************************************************/ + +#ifndef INC_JBIEXPRT_H +#define INC_JBIEXPRT_H + +/****************************************************************************/ +/* */ +/* Return codes from most JBI functions */ +/* */ +/****************************************************************************/ + +#define JBI_RETURN_TYPE int + +#define JBIC_SUCCESS 0 +#define JBIC_OUT_OF_MEMORY 1 +#define JBIC_IO_ERROR 2 +/* #define JAMC_SYNTAX_ERROR 3 */ +#define JBIC_UNEXPECTED_END 4 +#define JBIC_UNDEFINED_SYMBOL 5 +/* #define JAMC_REDEFINED_SYMBOL 6 */ +#define JBIC_INTEGER_OVERFLOW 7 +#define JBIC_DIVIDE_BY_ZERO 8 +#define JBIC_CRC_ERROR 9 +#define JBIC_INTERNAL_ERROR 10 +#define JBIC_BOUNDS_ERROR 11 +/* #define JAMC_TYPE_MISMATCH 12 */ +/* #define JAMC_ASSIGN_TO_CONST 13 */ +/* #define JAMC_NEXT_UNEXPECTED 14 */ +/* #define JAMC_POP_UNEXPECTED 15 */ +/* #define JAMC_RETURN_UNEXPECTED 16 */ +/* #define JAMC_ILLEGAL_SYMBOL 17 */ +#define JBIC_VECTOR_MAP_FAILED 18 +#define JBIC_USER_ABORT 19 +#define JBIC_STACK_OVERFLOW 20 +#define JBIC_ILLEGAL_OPCODE 21 +/* #define JAMC_PHASE_ERROR 22 */ +/* #define JAMC_SCOPE_ERROR 23 */ +#define JBIC_ACTION_NOT_FOUND 24 + +/****************************************************************************/ +/* */ +/* Macro Definitions */ +/* */ +/****************************************************************************/ + +/* +* For DOS port, program data is stored in a set of 16K pages, accessed +* through a pointer table. For 32-bit version, the buffer is continuous. +* The macro GET_BYTE gets a single byte for either case. +*/ +#if PORT==DOS +#define PROGRAM_PTR unsigned char ** +#else +#define PROGRAM_PTR unsigned char * +#endif + +#if PORT==DOS +#define GET_BYTE(x) (jbi_program[(x) >> 14L][(x) & 0x3fffL]) +#else +#define GET_BYTE(x) (program[x]) +#endif + +#define GET_WORD(x) \ + (((((unsigned short) GET_BYTE(x)) << 8) & 0xFF00) | \ + (((unsigned short) GET_BYTE((x)+1)) & 0x00FF)) + +#define GET_DWORD(x) \ + (((((unsigned long) GET_BYTE(x)) << 24L) & 0xFF000000L) | \ + ((((unsigned long) GET_BYTE((x)+1)) << 16L) & 0x00FF0000L) | \ + ((((unsigned long) GET_BYTE((x)+2)) << 8L) & 0x0000FF00L) | \ + (((unsigned long) GET_BYTE((x)+3)) & 0x000000FFL)) + +/****************************************************************************/ +/* */ +/* Structured Types */ +/* */ +/****************************************************************************/ + +typedef struct JBI_PROCINFO_STRUCT +{ + char *name; + unsigned char attributes; + struct JBI_PROCINFO_STRUCT *next; +} +JBI_PROCINFO; + +/****************************************************************************/ +/* */ +/* Global Data Prototypes */ +/* */ +/****************************************************************************/ + +#if PORT==DOS +extern unsigned char jbi_aca_out_buffer[8192 + 1024]; +#endif + +extern PROGRAM_PTR jbi_program; + +extern char *jbi_workspace; + +extern long jbi_workspace_size; + +/****************************************************************************/ +/* */ +/* Function Prototypes */ +/* */ +/****************************************************************************/ + +JBI_RETURN_TYPE jbi_execute +( + PROGRAM_PTR program, + long program_size, + char *workspace, + long workspace_size, + char *action, + char **init_list, + int reset_jtag, + long *error_address, + int *exit_code, + int *format_version +); + +JBI_RETURN_TYPE jbi_get_note +( + PROGRAM_PTR program, + long program_size, + long *offset, + char *key, + char *value, + int length +); + +JBI_RETURN_TYPE jbi_check_crc +( + PROGRAM_PTR program, + long program_size, + unsigned short *expected_crc, + unsigned short *actual_crc +); + +JBI_RETURN_TYPE jbi_get_file_info +( + PROGRAM_PTR program, + long program_size, + int *format_version, + int *action_count, + int *procedure_count +); + +JBI_RETURN_TYPE jbi_get_action_info +( + PROGRAM_PTR program, + long program_size, + int index, + char **name, + char **description, + JBI_PROCINFO **procedure_list +); + +int jbi_jtag_io +( + int tms, + int tdi, + int read_tdo +); + +void jbi_message +( + char *message_text +); + +void jbi_export_integer +( + char *key, + long value +); + +void jbi_export_boolean_array +( + char *key, + unsigned char *data, + long count +); + +void jbi_delay +( + long microseconds +); + +int jbi_vector_map +( + int signal_count, + char **signals +); + +int jbi_vector_io +( + int signal_count, + long *dir_vect, + long *data_vect, + long *capture_vect +); + +void *jbi_malloc +( + unsigned int size +); + +void jbi_free +( + void *ptr +); + +#endif /* INC_JBIEXPRT_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.c new file mode 100644 index 000000000000..f013100eecb8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.c @@ -0,0 +1,1679 @@ +/****************************************************************************/ +/* */ +/* Module: jbijtag.c */ +/* */ +/* Copyright (C) Altera Corporation 1998-2001 */ +/* */ +/* Description: Contains JTAG interface functions */ +/* */ +/* Revisions: 2.2 updated state transition paths */ +/* 2.0 added multi-page scan code for 16-bit PORT */ +/* */ +/****************************************************************************/ + +#include "jbiport.h" +#include "jbiexprt.h" +#include "jbicomp.h" +#include "jbijtag.h" + +#define NULL 0 + +char *jbi_workspace = NULL; +long jbi_workspace_size = 0L; + +/****************************************************************************/ +/* */ +/* Enumerated Types */ +/* */ +/****************************************************************************/ + +/* maximum JTAG IR and DR lengths (in bits) */ +#define JBIC_MAX_JTAG_IR_PREAMBLE 256 +#define JBIC_MAX_JTAG_IR_POSTAMBLE 256 +#define JBIC_MAX_JTAG_IR_LENGTH 512 +#define JBIC_MAX_JTAG_DR_PREAMBLE 1024 +#define JBIC_MAX_JTAG_DR_POSTAMBLE 1024 +#define JBIC_MAX_JTAG_DR_LENGTH 2048 + +/* +* Global variable to store the current JTAG state +*/ +JBIE_JTAG_STATE jbi_jtag_state = JBI_ILLEGAL_JTAG_STATE; + +/* +* Store current stop-state for DR and IR scan commands +*/ +JBIE_JTAG_STATE jbi_drstop_state = IDLE; +JBIE_JTAG_STATE jbi_irstop_state = IDLE; + +/* +* Store current padding values +*/ +unsigned int jbi_dr_preamble = 0; +unsigned int jbi_dr_postamble = 0; +unsigned int jbi_ir_preamble = 0; +unsigned int jbi_ir_postamble = 0; +unsigned int jbi_dr_length = 0; +unsigned int jbi_ir_length = 0; +unsigned char *jbi_dr_preamble_data = NULL; +unsigned char *jbi_dr_postamble_data = NULL; +unsigned char *jbi_ir_preamble_data = NULL; +unsigned char *jbi_ir_postamble_data = NULL; +unsigned char *jbi_dr_buffer = NULL; +unsigned char *jbi_ir_buffer = NULL; + +/* +* This structure shows, for each JTAG state, which state is reached after +* a single TCK clock cycle with TMS high or TMS low, respectively. This +* describes all possible state transitions in the JTAG state machine. +*/ +struct JBIS_JTAG_MACHINE +{ + JBIE_JTAG_STATE tms_high; + JBIE_JTAG_STATE tms_low; +} jbi_jtag_state_transitions[] = +{ +/* RESET */ { RESET, IDLE }, +/* IDLE */ { DRSELECT, IDLE }, +/* DRSELECT */ { IRSELECT, DRCAPTURE }, +/* DRCAPTURE */ { DREXIT1, DRSHIFT }, +/* DRSHIFT */ { DREXIT1, DRSHIFT }, +/* DREXIT1 */ { DRUPDATE, DRPAUSE }, +/* DRPAUSE */ { DREXIT2, DRPAUSE }, +/* DREXIT2 */ { DRUPDATE, DRSHIFT }, +/* DRUPDATE */ { DRSELECT, IDLE }, +/* IRSELECT */ { RESET, IRCAPTURE }, +/* IRCAPTURE */ { IREXIT1, IRSHIFT }, +/* IRSHIFT */ { IREXIT1, IRSHIFT }, +/* IREXIT1 */ { IRUPDATE, IRPAUSE }, +/* IRPAUSE */ { IREXIT2, IRPAUSE }, +/* IREXIT2 */ { IRUPDATE, IRSHIFT }, +/* IRUPDATE */ { DRSELECT, IDLE } +}; + +/* +* This table contains the TMS value to be used to take the NEXT STEP on +* the path to the desired state. The array index is the current state, +* and the bit position is the desired endstate. To find out which state +* is used as the intermediate state, look up the TMS value in the +* jbi_jtag_state_transitions[] table. +*/ +unsigned short jbi_jtag_path_map[16] = +{ +/* RST RTI SDRS CDR SDR E1DR PDR E2DR */ + 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF, +/* UDR SIRS CIR SIR E1IR PIR E2IR UIR */ + 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD +}; + +/* +* Flag bits for jbi_jtag_io() function +*/ +#define TMS_HIGH 1 +#define TMS_LOW 0 +#define TDI_HIGH 1 +#define TDI_LOW 0 +#define READ_TDO 1 +#define IGNORE_TDO 0 + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_init_jtag() + +/* */ +/****************************************************************************/ +{ + /* initial JTAG state is unknown */ + jbi_jtag_state = JBI_ILLEGAL_JTAG_STATE; + + /* initialize global variables to default state */ + jbi_drstop_state = IDLE; + jbi_irstop_state = IDLE; + jbi_dr_preamble = 0; + jbi_dr_postamble = 0; + jbi_ir_preamble = 0; + jbi_ir_postamble = 0; + jbi_dr_length = 0; + jbi_ir_length = 0; + + if (jbi_workspace != NULL) + { + jbi_dr_preamble_data = (unsigned char *) jbi_workspace; + jbi_dr_postamble_data = &jbi_dr_preamble_data[JBIC_MAX_JTAG_DR_PREAMBLE / 8]; + jbi_ir_preamble_data = &jbi_dr_postamble_data[JBIC_MAX_JTAG_DR_POSTAMBLE / 8]; + jbi_ir_postamble_data = &jbi_ir_preamble_data[JBIC_MAX_JTAG_IR_PREAMBLE / 8]; + jbi_dr_buffer = &jbi_ir_postamble_data[JBIC_MAX_JTAG_IR_POSTAMBLE / 8]; + jbi_ir_buffer = &jbi_dr_buffer[JBIC_MAX_JTAG_DR_LENGTH / 8]; + } + else + { + jbi_dr_preamble_data = NULL; + jbi_dr_postamble_data = NULL; + jbi_ir_preamble_data = NULL; + jbi_ir_postamble_data = NULL; + jbi_dr_buffer = NULL; + jbi_ir_buffer = NULL; + } + + return (JBIC_SUCCESS); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_drstop_state +( + JBIE_JTAG_STATE state +) + +/* */ +/****************************************************************************/ +{ + jbi_drstop_state = state; + + return (JBIC_SUCCESS); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_irstop_state +( + JBIE_JTAG_STATE state +) + +/* */ +/****************************************************************************/ +{ + jbi_irstop_state = state; + + return (JBIC_SUCCESS); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_dr_preamble +( + unsigned int count, + unsigned int start_index, + unsigned char *preamble_data +) + +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int i; + unsigned int j; + + if (jbi_workspace != NULL) + { + if (count > JBIC_MAX_JTAG_DR_PREAMBLE) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_preamble = count; + } + } + else + { + if (count > jbi_dr_preamble) + { + jbi_free(jbi_dr_preamble_data); + jbi_dr_preamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3); + + if (jbi_dr_preamble_data == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_preamble = count; + } + } + else + { + jbi_dr_preamble = count; + } + } + + if (status == JBIC_SUCCESS) + { + for (i = 0; i < count; ++i) + { + j = i + start_index; + + if (preamble_data == NULL) + { + jbi_dr_preamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + if (preamble_data[j >> 3] & (1 << (j & 7))) + { + jbi_dr_preamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + jbi_dr_preamble_data[i >> 3] &= + ~(unsigned int) (1 << (i & 7)); + } + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_ir_preamble +( + unsigned int count, + unsigned int start_index, + unsigned char *preamble_data +) + +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int i; + unsigned int j; + + if (jbi_workspace != NULL) + { + if (count > JBIC_MAX_JTAG_IR_PREAMBLE) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_preamble = count; + } + } + else + { + if (count > jbi_ir_preamble) + { + jbi_free(jbi_ir_preamble_data); + jbi_ir_preamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3); + + if (jbi_ir_preamble_data == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_preamble = count; + } + } + else + { + jbi_ir_preamble = count; + } + } + + if (status == JBIC_SUCCESS) + { + for (i = 0; i < count; ++i) + { + j = i + start_index; + + if (preamble_data == NULL) + { + jbi_ir_preamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + if (preamble_data[j >> 3] & (1 << (j & 7))) + { + jbi_ir_preamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + jbi_ir_preamble_data[i >> 3] &= + ~(unsigned int) (1 << (i & 7)); + } + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_dr_postamble +( + unsigned int count, + unsigned int start_index, + unsigned char *postamble_data +) + +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int i; + unsigned int j; + + if (jbi_workspace != NULL) + { + if (count > JBIC_MAX_JTAG_DR_POSTAMBLE) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_postamble = count; + } + } + else + { + if (count > jbi_dr_postamble) + { + jbi_free(jbi_dr_postamble_data); + jbi_dr_postamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3); + + if (jbi_dr_postamble_data == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_postamble = count; + } + } + else + { + jbi_dr_postamble = count; + } + } + + if (status == JBIC_SUCCESS) + { + for (i = 0; i < count; ++i) + { + j = i + start_index; + + if (postamble_data == NULL) + { + jbi_dr_postamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + if (postamble_data[j >> 3] & (1 << (j & 7))) + { + jbi_dr_postamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + jbi_dr_postamble_data[i >> 3] &= + ~(unsigned int) (1 << (i & 7)); + } + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_ir_postamble +( + unsigned int count, + unsigned int start_index, + unsigned char *postamble_data +) + +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int i; + unsigned int j; + + if (jbi_workspace != NULL) + { + if (count > JBIC_MAX_JTAG_IR_POSTAMBLE) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_postamble = count; + } + } + else + { + if (count > jbi_ir_postamble) + { + jbi_free(jbi_ir_postamble_data); + jbi_ir_postamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3); + + if (jbi_ir_postamble_data == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_postamble = count; + } + } + else + { + jbi_ir_postamble = count; + } + } + + if (status == JBIC_SUCCESS) + { + for (i = 0; i < count; ++i) + { + j = i + start_index; + + if (postamble_data == NULL) + { + jbi_ir_postamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + if (postamble_data[j >> 3] & (1 << (j & 7))) + { + jbi_ir_postamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + jbi_ir_postamble_data[i >> 3] &= + ~(unsigned int) (1 << (i & 7)); + } + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +void jbi_jtag_reset_idle(void) + +/* */ +/****************************************************************************/ +{ + int i; + + /* + * Go to Test Logic Reset (no matter what the starting state may be) + */ + for (i = 0; i < 5; ++i) + { + jbi_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO); + } + + /* + * Now step to Run Test / Idle + */ + jbi_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO); + + jbi_jtag_state = IDLE; +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_goto_jtag_state +( + JBIE_JTAG_STATE state +) + +/* */ +/****************************************************************************/ +{ + int tms; + int count = 0; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int tmp_state; + + if (jbi_jtag_state == JBI_ILLEGAL_JTAG_STATE) + { + /* initialize JTAG chain to known state */ + jbi_jtag_reset_idle(); + } + + if (jbi_jtag_state == state) + { + /* + * We are already in the desired state. If it is a stable state, + * loop here. Otherwise do nothing (no clock cycles). + */ + if ((state == IDLE) || + (state == DRSHIFT) || + (state == DRPAUSE) || + (state == IRSHIFT) || + (state == IRPAUSE)) + { + jbi_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO); + } + else if (state == RESET) + { + jbi_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO); + } + } + else + { + while ((jbi_jtag_state != state) && (count < 9)) + { + /* + * Get TMS value to take a step toward desired state + */ + if (state < 0) { + tmp_state = 0; + } else { + tmp_state = state; + } + tms = (jbi_jtag_path_map[jbi_jtag_state] & (1 << tmp_state)) ? + TMS_HIGH : TMS_LOW; + + /* + * Take a step + */ + jbi_jtag_io(tms, TDI_LOW, IGNORE_TDO); + + if (tms) + { + jbi_jtag_state = + jbi_jtag_state_transitions[jbi_jtag_state].tms_high; + } + else + { + jbi_jtag_state = + jbi_jtag_state_transitions[jbi_jtag_state].tms_low; + } + + ++count; + } + } + + if (jbi_jtag_state != state) + { + status = JBIC_INTERNAL_ERROR; + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_wait_cycles +( + long cycles, + JBIE_JTAG_STATE wait_state +) + +/* */ +/* Description: Causes JTAG hardware to loop in the specified stable */ +/* state for the specified number of TCK clock cycles. */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int tms; + long count; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + + if (jbi_jtag_state != wait_state) + { + status = jbi_goto_jtag_state(wait_state); + } + + if (status == JBIC_SUCCESS) + { + /* + * Set TMS high to loop in RESET state + * Set TMS low to loop in any other stable state + */ + tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW; + + for (count = 0L; count < cycles; count++) + { + jbi_jtag_io(tms, TDI_LOW, IGNORE_TDO); + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_wait_microseconds +( + long microseconds, + JBIE_JTAG_STATE wait_state +) + +/* */ +/* Description: Causes JTAG hardware to sit in the specified stable */ +/* state for the specified duration of real time. If */ +/* no JTAG operations have been performed yet, then only */ +/* a delay is performed. This permits the WAIT USECS */ +/* statement to be used in VECTOR programs without causing */ +/* any JTAG operations. */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + + if ((jbi_jtag_state != JBI_ILLEGAL_JTAG_STATE) && + (jbi_jtag_state != wait_state)) + { + status = jbi_goto_jtag_state(wait_state); + } + + if (status == JBIC_SUCCESS) + { + /* + * Wait for specified time interval + */ + jbi_delay(microseconds); + } + + return (status); +} + +/****************************************************************************/ +/* */ + +void jbi_jtag_concatenate_data +( + unsigned char *buffer, + unsigned char *preamble_data, + unsigned int preamble_count, + unsigned char *target_data, + unsigned long start_index, + unsigned int target_count, + unsigned char *postamble_data, + unsigned int postamble_count +) + +/* */ +/* Description: Copies preamble data, target data, and postamble data */ +/* into one buffer for IR or DR scans. */ +/* */ +/* Returns: nothing */ +/* */ +/****************************************************************************/ +{ + unsigned long i; + unsigned long j; + unsigned long k; + + for (i = 0L; i < preamble_count; ++i) + { + if (preamble_data[i >> 3L] & (1L << (i & 7L))) + { + buffer[i >> 3L] |= (1L << (i & 7L)); + } + else + { + buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L)); + } + } + + j = start_index; + k = preamble_count + target_count; + for (; i < k; ++i, ++j) + { + if (target_data[j >> 3L] & (1L << (j & 7L))) + { + buffer[i >> 3L] |= (1L << (i & 7L)); + } + else + { + buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L)); + } + } + + j = 0L; + k = preamble_count + target_count + postamble_count; + for (; i < k; ++i, ++j) + { + if (postamble_data[j >> 3L] & (1L << (j & 7L))) + { + buffer[i >> 3L] |= (1L << (i & 7L)); + } + else + { + buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L)); + } + } +} + +int jbi_jtag_drscan +( + int start_state, + int count, + unsigned char *tdi, + unsigned char *tdo +) +{ + int i = 0; + int tdo_bit = 0; + int status = 1; + + /* + * First go to DRSHIFT state + */ + switch (start_state) + { + case 0: /* IDLE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(0, 0, 0); /* DRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* DRSHIFT */ + break; + + case 1: /* DRPAUSE */ + jbi_jtag_io(1, 0, 0); /* DREXIT2 */ + jbi_jtag_io(1, 0, 0); /* DRUPDATE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(0, 0, 0); /* DRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* DRSHIFT */ + break; + + case 2: /* IRPAUSE */ + jbi_jtag_io(1, 0, 0); /* IREXIT2 */ + jbi_jtag_io(1, 0, 0); /* IRUPDATE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(0, 0, 0); /* DRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* DRSHIFT */ + break; + + default: + status = 0; + } + + if (status) + { + /* loop in the SHIFT-DR state */ + for (i = 0; i < count; i++) + { + tdo_bit = jbi_jtag_io( + (i == count - 1), + tdi[i >> 3] & (1 << (i & 7)), + (tdo != NULL)); + + if (tdo != NULL) + { + if (tdo_bit) + { + tdo[i >> 3] |= (1 << (i & 7)); + } + else + { + tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7)); + } + } + } + + jbi_jtag_io(0, 0, 0); /* DRPAUSE */ + } + + return (status); +} + +int jbi_jtag_irscan +( + int start_state, + int count, + unsigned char *tdi, + unsigned char *tdo +) +{ + int i = 0; + int tdo_bit = 0; + int status = 1; + + /* + * First go to IRSHIFT state + */ + switch (start_state) + { + case 0: /* IDLE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(1, 0, 0); /* IRSELECT */ + jbi_jtag_io(0, 0, 0); /* IRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* IRSHIFT */ + break; + + case 1: /* DRPAUSE */ + jbi_jtag_io(1, 0, 0); /* DREXIT2 */ + jbi_jtag_io(1, 0, 0); /* DRUPDATE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(1, 0, 0); /* IRSELECT */ + jbi_jtag_io(0, 0, 0); /* IRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* IRSHIFT */ + break; + + case 2: /* IRPAUSE */ + jbi_jtag_io(1, 0, 0); /* IREXIT2 */ + jbi_jtag_io(1, 0, 0); /* IRUPDATE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(1, 0, 0); /* IRSELECT */ + jbi_jtag_io(0, 0, 0); /* IRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* IRSHIFT */ + break; + + default: + status = 0; + } + + if (status) + { + /* loop in the SHIFT-IR state */ + for (i = 0; i < count; i++) + { + tdo_bit = jbi_jtag_io( + (i == count - 1), + tdi[i >> 3] & (1 << (i & 7)), + (tdo != NULL)); + + if (tdo != NULL) + { + if (tdo_bit) + { + tdo[i >> 3] |= (1 << (i & 7)); + } + else + { + tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7)); + } + } + } + + jbi_jtag_io(0, 0, 0); /* IRPAUSE */ + } + + return (status); +} + +/****************************************************************************/ +/* */ + +void jbi_jtag_extract_target_data +( + unsigned char *buffer, + unsigned char *target_data, + unsigned int start_index, + unsigned int preamble_count, + unsigned int target_count +) + +/* */ +/* Description: Copies target data from scan buffer, filtering out */ +/* preamble and postamble data. */ +/* */ +/* Returns: nothing */ +/* */ +/****************************************************************************/ +{ + unsigned int i; + unsigned int j; + unsigned int k; + + j = preamble_count; + k = start_index + target_count; + for (i = start_index; i < k; ++i, ++j) + { + if (buffer[j >> 3] & (1 << (j & 7))) + { + target_data[i >> 3] |= (1 << (i & 7)); + } + else + { + target_data[i >> 3] &= ~(unsigned int) (1 << (i & 7)); + } + } +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_irscan +( + unsigned int count, + unsigned char *tdi_data, + unsigned int start_index +) + +/* */ +/* Description: Shifts data into instruction register */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int start_code = 0; + unsigned int alloc_chars = 0; + unsigned int shift_count = jbi_ir_preamble + count + jbi_ir_postamble; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE; + + switch (jbi_jtag_state) + { + case JBI_ILLEGAL_JTAG_STATE: + case RESET: + case IDLE: + start_code = 0; + start_state = IDLE; + break; + + case DRSELECT: + case DRCAPTURE: + case DRSHIFT: + case DREXIT1: + case DRPAUSE: + case DREXIT2: + case DRUPDATE: + start_code = 1; + start_state = DRPAUSE; + break; + + case IRSELECT: + case IRCAPTURE: + case IRSHIFT: + case IREXIT1: + case IRPAUSE: + case IREXIT2: + case IRUPDATE: + start_code = 2; + start_state = IRPAUSE; + break; + + default: + status = JBIC_INTERNAL_ERROR; + break; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_jtag_state != start_state) + { + status = jbi_goto_jtag_state(start_state); + } + } + + if (status == JBIC_SUCCESS) + { + if (jbi_workspace != NULL) + { + if (shift_count > JBIC_MAX_JTAG_IR_LENGTH) + { + status = JBIC_OUT_OF_MEMORY; + } + } + else if (shift_count > jbi_ir_length) + { + alloc_chars = (shift_count + 7) >> 3; + jbi_free(jbi_ir_buffer); + jbi_ir_buffer = (unsigned char *) jbi_malloc(alloc_chars); + + if (jbi_ir_buffer == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_length = alloc_chars * 8; + } + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Copy preamble data, IR data, and postamble data into a buffer + */ + jbi_jtag_concatenate_data + ( + jbi_ir_buffer, + jbi_ir_preamble_data, + jbi_ir_preamble, + tdi_data, + start_index, + count, + jbi_ir_postamble_data, + jbi_ir_postamble + ); + + /* + * Do the IRSCAN + */ + jbi_jtag_irscan + ( + start_code, + shift_count, + jbi_ir_buffer, + NULL + ); + + /* jbi_jtag_irscan() always ends in IRPAUSE state */ + jbi_jtag_state = IRPAUSE; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_irstop_state != IRPAUSE) + { + status = jbi_goto_jtag_state(jbi_irstop_state); + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_swap_ir +( + unsigned int count, + unsigned char *in_data, + unsigned int in_index, + unsigned char *out_data, + unsigned int out_index +) + +/* */ +/* Description: Shifts data into instruction register, capturing output */ +/* data */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int start_code = 0; + unsigned int alloc_chars = 0; + unsigned int shift_count = jbi_ir_preamble + count + jbi_ir_postamble; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE; + + switch (jbi_jtag_state) + { + case JBI_ILLEGAL_JTAG_STATE: + case RESET: + case IDLE: + start_code = 0; + start_state = IDLE; + break; + + case DRSELECT: + case DRCAPTURE: + case DRSHIFT: + case DREXIT1: + case DRPAUSE: + case DREXIT2: + case DRUPDATE: + start_code = 1; + start_state = DRPAUSE; + break; + + case IRSELECT: + case IRCAPTURE: + case IRSHIFT: + case IREXIT1: + case IRPAUSE: + case IREXIT2: + case IRUPDATE: + start_code = 2; + start_state = IRPAUSE; + break; + + default: + status = JBIC_INTERNAL_ERROR; + break; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_jtag_state != start_state) + { + status = jbi_goto_jtag_state(start_state); + } + } + + if (status == JBIC_SUCCESS) + { + if (jbi_workspace != NULL) + { + if (shift_count > JBIC_MAX_JTAG_IR_LENGTH) + { + status = JBIC_OUT_OF_MEMORY; + } + } + else if (shift_count > jbi_ir_length) + { + alloc_chars = (shift_count + 7) >> 3; + jbi_free(jbi_ir_buffer); + jbi_ir_buffer = (unsigned char *) jbi_malloc(alloc_chars); + + if (jbi_ir_buffer == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_length = alloc_chars * 8; + } + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Copy preamble data, IR data, and postamble data into a buffer + */ + jbi_jtag_concatenate_data + ( + jbi_ir_buffer, + jbi_ir_preamble_data, + jbi_ir_preamble, + in_data, + in_index, + count, + jbi_ir_postamble_data, + jbi_ir_postamble + ); + + /* + * Do the IRSCAN + */ + jbi_jtag_irscan + ( + start_code, + shift_count, + jbi_ir_buffer, + jbi_ir_buffer + ); + + /* jbi_jtag_irscan() always ends in IRPAUSE state */ + jbi_jtag_state = IRPAUSE; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_irstop_state != IRPAUSE) + { + status = jbi_goto_jtag_state(jbi_irstop_state); + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Now extract the returned data from the buffer + */ + jbi_jtag_extract_target_data + ( + jbi_ir_buffer, + out_data, + out_index, + jbi_ir_preamble, + count + ); + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_drscan +( + unsigned int count, + unsigned char *tdi_data, + unsigned long start_index +) + +/* */ +/* Description: Shifts data into data register (ignoring output data) */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int start_code = 0; + unsigned int alloc_chars = 0; + unsigned int shift_count = jbi_dr_preamble + count + jbi_dr_postamble; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE; + + switch (jbi_jtag_state) + { + case JBI_ILLEGAL_JTAG_STATE: + case RESET: + case IDLE: + start_code = 0; + start_state = IDLE; + break; + + case DRSELECT: + case DRCAPTURE: + case DRSHIFT: + case DREXIT1: + case DRPAUSE: + case DREXIT2: + case DRUPDATE: + start_code = 1; + start_state = DRPAUSE; + break; + + case IRSELECT: + case IRCAPTURE: + case IRSHIFT: + case IREXIT1: + case IRPAUSE: + case IREXIT2: + case IRUPDATE: + start_code = 2; + start_state = IRPAUSE; + break; + + default: + status = JBIC_INTERNAL_ERROR; + break; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_jtag_state != start_state) + { + status = jbi_goto_jtag_state(start_state); + } + } + + if (status == JBIC_SUCCESS) + { + if (jbi_workspace != NULL) + { + if (shift_count > JBIC_MAX_JTAG_DR_LENGTH) + { + status = JBIC_OUT_OF_MEMORY; + } + } + else if (shift_count > jbi_dr_length) + { + alloc_chars = (shift_count + 7) >> 3; + jbi_free(jbi_dr_buffer); + jbi_dr_buffer = (unsigned char *) jbi_malloc(alloc_chars); + + if (jbi_dr_buffer == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_length = alloc_chars * 8; + } + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Copy preamble data, DR data, and postamble data into a buffer + */ + jbi_jtag_concatenate_data + ( + jbi_dr_buffer, + jbi_dr_preamble_data, + jbi_dr_preamble, + tdi_data, + start_index, + count, + jbi_dr_postamble_data, + jbi_dr_postamble + ); + + /* + * Do the DRSCAN + */ + jbi_jtag_drscan + ( + start_code, + shift_count, + jbi_dr_buffer, + NULL + ); + + /* jbi_jtag_drscan() always ends in DRPAUSE state */ + jbi_jtag_state = DRPAUSE; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_drstop_state != DRPAUSE) + { + status = jbi_goto_jtag_state(jbi_drstop_state); + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_swap_dr +( + unsigned int count, + unsigned char *in_data, + unsigned long in_index, + unsigned char *out_data, + unsigned int out_index +) + +/* */ +/* Description: Shifts data into data register, capturing output data */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int start_code = 0; + unsigned int alloc_chars = 0; + unsigned int shift_count = jbi_dr_preamble + count + jbi_dr_postamble; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE; + + switch (jbi_jtag_state) + { + case JBI_ILLEGAL_JTAG_STATE: + case RESET: + case IDLE: + start_code = 0; + start_state = IDLE; + break; + + case DRSELECT: + case DRCAPTURE: + case DRSHIFT: + case DREXIT1: + case DRPAUSE: + case DREXIT2: + case DRUPDATE: + start_code = 1; + start_state = DRPAUSE; + break; + + case IRSELECT: + case IRCAPTURE: + case IRSHIFT: + case IREXIT1: + case IRPAUSE: + case IREXIT2: + case IRUPDATE: + start_code = 2; + start_state = IRPAUSE; + break; + + default: + status = JBIC_INTERNAL_ERROR; + break; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_jtag_state != start_state) + { + status = jbi_goto_jtag_state(start_state); + } + } + + if (status == JBIC_SUCCESS) + { + if (jbi_workspace != NULL) + { + if (shift_count > JBIC_MAX_JTAG_DR_LENGTH) + { + status = JBIC_OUT_OF_MEMORY; + } + } + else if (shift_count > jbi_dr_length) + { + alloc_chars = (shift_count + 7) >> 3; + jbi_free(jbi_dr_buffer); + jbi_dr_buffer = (unsigned char *) jbi_malloc(alloc_chars); + + if (jbi_dr_buffer == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_length = alloc_chars * 8; + } + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Copy preamble data, DR data, and postamble data into a buffer + */ + jbi_jtag_concatenate_data + ( + jbi_dr_buffer, + jbi_dr_preamble_data, + jbi_dr_preamble, + in_data, + in_index, + count, + jbi_dr_postamble_data, + jbi_dr_postamble + ); + + /* + * Do the DRSCAN + */ + jbi_jtag_drscan + ( + start_code, + shift_count, + jbi_dr_buffer, + jbi_dr_buffer + ); + + /* jbi_jtag_drscan() always ends in DRPAUSE state */ + jbi_jtag_state = DRPAUSE; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_drstop_state != DRPAUSE) + { + status = jbi_goto_jtag_state(jbi_drstop_state); + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Now extract the returned data from the buffer + */ + jbi_jtag_extract_target_data + ( + jbi_dr_buffer, + out_data, + out_index, + jbi_dr_preamble, + count + ); + } + + return (status); +} + +/****************************************************************************/ +/* */ + +void jbi_free_jtag_padding_buffers(int reset_jtag) + +/* */ +/* Description: Frees memory allocated for JTAG IR and DR buffers */ +/* */ +/* Returns: nothing */ +/* */ +/****************************************************************************/ +{ + /* + * If the JTAG interface was used, reset it to TLR + */ + if (reset_jtag && (jbi_jtag_state != JBI_ILLEGAL_JTAG_STATE)) + { + jbi_jtag_reset_idle(); + } + + if (jbi_workspace == NULL) + { + if (jbi_dr_preamble_data != NULL) + { + jbi_free(jbi_dr_preamble_data); + jbi_dr_preamble_data = NULL; + } + + if (jbi_dr_postamble_data != NULL) + { + jbi_free(jbi_dr_postamble_data); + jbi_dr_postamble_data = NULL; + } + + if (jbi_dr_buffer != NULL) + { + jbi_free(jbi_dr_buffer); + jbi_dr_buffer = NULL; + } + + if (jbi_ir_preamble_data != NULL) + { + jbi_free(jbi_ir_preamble_data); + jbi_ir_preamble_data = NULL; + } + + if (jbi_ir_postamble_data != NULL) + { + jbi_free(jbi_ir_postamble_data); + jbi_ir_postamble_data = NULL; + } + + if (jbi_ir_buffer != NULL) + { + jbi_free(jbi_ir_buffer); + jbi_ir_buffer = NULL; + } + } +} + +#if PORT==DOS + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_drscan_multi_page +( + unsigned int variable_id, + unsigned long count, + unsigned long start_index, + int version +) + +/* */ +/* Description: Shifts data into data register (ignoring output data) */ +/* Scan data comes from compressed Boolean array. */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned long shift_count = jbi_dr_preamble + count + jbi_dr_postamble; + unsigned long i; + unsigned long j; + unsigned long k; + unsigned int bi; + + if (status == JBIC_SUCCESS) + { + status = jbi_goto_jtag_state(DRSHIFT); + } + + if (status == JBIC_SUCCESS) + { + /* + * Get preamble data, DR data, and postamble data one bit at a time + * and immediately scan it into the JTAG chain + */ + + for (i = 0L; i < jbi_dr_preamble; ++i) + { + jbi_jtag_io((i == shift_count - 1), + (int) (jbi_dr_preamble_data[i >> 3L] & (1L << (i & 7L))), 0); + } + + j = start_index; + k = jbi_dr_preamble + count; + + jbi_uncompress_page(variable_id, (unsigned int) (j >> 16L), version); + + for (; i < k; ++i, ++j) + { + bi = (unsigned int) (j & 0x0000ffffL); + + /* check for page boundary - load next page if necessary */ + if (bi == 0) + { + jbi_uncompress_page(variable_id, (unsigned int) (j >> 16L), version); + } + + jbi_jtag_io((i == shift_count - 1), + (int) (jbi_aca_out_buffer[bi >> 3] & (1 << (bi & 7))), 0); + } + + j = 0L; + k = jbi_dr_preamble + count + jbi_dr_postamble; + for (; i < k; ++i, ++j) + { + jbi_jtag_io((i == shift_count - 1), + (int) (jbi_dr_postamble_data[j >> 3L] & (1L << (j & 7L))), 0); + } + + jbi_jtag_io(0, 0, 0); /* DRPAUSE */ + + /* jbi_jtag_drscan() always ends in DRPAUSE state */ + jbi_jtag_state = DRPAUSE; + + if (jbi_drstop_state != DRPAUSE) + { + status = jbi_goto_jtag_state(jbi_drstop_state); + } + } + + return (status); +} + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.h new file mode 100644 index 000000000000..fab2dac0266a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.h @@ -0,0 +1,146 @@ +/****************************************************************************/ +/* */ +/* Module: jbijtag.h */ +/* */ +/* Copyright (C) Altera Corporation 1998-2001 */ +/* */ +/* Description: Definitions of JTAG constants, types, and functions */ +/* */ +/****************************************************************************/ + +#ifndef INC_JBIJTAG_H +#define INC_JBIJTAG_H + +/****************************************************************************/ +/* */ +/* Function Prototypes */ +/* */ +/****************************************************************************/ +typedef enum +{ + JBI_ILLEGAL_JTAG_STATE = -1, + RESET = 0, + IDLE = 1, + DRSELECT = 2, + DRCAPTURE = 3, + DRSHIFT = 4, + DREXIT1 = 5, + DRPAUSE = 6, + DREXIT2 = 7, + DRUPDATE = 8, + IRSELECT = 9, + IRCAPTURE = 10, + IRSHIFT = 11, + IREXIT1 = 12, + IRPAUSE = 13, + IREXIT2 = 14, + IRUPDATE = 15 + +} JBIE_JTAG_STATE; + +JBI_RETURN_TYPE jbi_init_jtag +( + void +); + +JBI_RETURN_TYPE jbi_set_drstop_state +( + JBIE_JTAG_STATE state +); + +JBI_RETURN_TYPE jbi_set_irstop_state +( + JBIE_JTAG_STATE state +); + +JBI_RETURN_TYPE jbi_set_dr_preamble +( + unsigned int count, + unsigned int start_index, + unsigned char *preamble_data +); + +JBI_RETURN_TYPE jbi_set_ir_preamble +( + unsigned int count, + unsigned int start_index, + unsigned char *preamble_data +); + +JBI_RETURN_TYPE jbi_set_dr_postamble +( + unsigned int count, + unsigned int start_index, + unsigned char *postamble_data +); + +JBI_RETURN_TYPE jbi_set_ir_postamble +( + unsigned int count, + unsigned int start_index, + unsigned char *postamble_data +); + +JBI_RETURN_TYPE jbi_goto_jtag_state +( + JBIE_JTAG_STATE state +); + +JBI_RETURN_TYPE jbi_do_wait_cycles +( + long cycles, + JBIE_JTAG_STATE wait_state +); + +JBI_RETURN_TYPE jbi_do_wait_microseconds +( + long microseconds, + JBIE_JTAG_STATE wait_state +); + +JBI_RETURN_TYPE jbi_do_irscan +( + unsigned int count, + unsigned char *tdi_data, + unsigned int start_index +); + +JBI_RETURN_TYPE jbi_swap_ir +( + unsigned int count, + unsigned char *in_data, + unsigned int in_index, + unsigned char *out_data, + unsigned int out_index +); + +JBI_RETURN_TYPE jbi_do_drscan +( + unsigned int count, + unsigned char *tdi_data, + unsigned long start_index +); + +JBI_RETURN_TYPE jbi_swap_dr +( + unsigned int count, + unsigned char *in_data, + unsigned long in_index, + unsigned char *out_data, + unsigned int out_index +); + +void jbi_free_jtag_padding_buffers +( + int reset_jtag +); + +JBI_RETURN_TYPE jbi_do_drscan_multi_page +( + unsigned int variable_id, + unsigned long long_count, + unsigned long long_index, + int version +); + +#endif /* INC_JBIJTAG_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbimain.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbimain.c new file mode 100644 index 000000000000..b8cab4857074 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbimain.c @@ -0,0 +1,3362 @@ +/****************************************************************************/ +/* */ +/* Module: jbimain.c */ +/* */ +/* Copyright (C) Altera Corporation 1998-2001 */ +/* */ +/* Description: Jam STAPL ByteCode Player (Interpreter) */ +/* */ +/* Revisions: 2.2 fixed /W4 warnings */ +/* 2.0 added support for STAPL ByteCode format */ +/* */ +/****************************************************************************/ + +#include "jbiport.h" +#include "jbiexprt.h" +#include "jbijtag.h" +#include "jbicomp.h" +#include "jbistub.h" + +/****************************************************************************/ +/* */ +/* MACROS */ +/* */ +/****************************************************************************/ + +#ifndef NULL +#define NULL 0 +#endif + +#define JBI_STACK_SIZE 128 + +#define JBIC_MESSAGE_LENGTH 1024 + +/* +* This macro checks if enough parameters are available on the stack. The +* argument is the number of parameters needed. +*/ +#define IF_CHECK_STACK(x) \ + if (stack_ptr < (int) (x)) \ + { \ + status = JBIC_STACK_OVERFLOW; \ + } \ + else + +/* +* This macro checks if a code address is inside the code section +*/ +#define CHECK_PC \ + if ((pc < code_section) || (pc >= debug_section)) \ + { \ + status = JBIC_BOUNDS_ERROR; \ + } + +/****************************************************************************/ +/* */ +/* GLOBAL VARIABLES */ +/* */ +/****************************************************************************/ + +#if PORT==DOS +/* +* jbi_program is a global pointer used by macros GET_BYTE, GET_WORD, and +* GET_DWORD to read data from the JBC file +*/ +PROGRAM_PTR jbi_program; +#endif + +/****************************************************************************/ +/* */ +/* UTILITY FUNCTIONS */ +/* */ +/****************************************************************************/ + +int jbi_strlen(char *string) +{ + int len = 0; + + while (string[len] != '\0') ++len; + + return (len); +} + +long jbi_atol(char *buffer) +{ + long result = 0L; + int index = 0; + + while ((buffer[index] >= '0') && (buffer[index] <= '9')) + { + result = (result * 10) + (buffer[index] - '0'); + ++index; + } + + return (result); +} + +void jbi_ltoa(char *buffer, long number) +{ + int index = 0; + int rev_index = 0; + char reverse[32]; + + if (number < 0L) + { + buffer[index++] = '-'; + number = 0 - number; + } + else if (number == 0) + { + buffer[index++] = '0'; + } + + while (number != 0) + { + reverse[rev_index++] = (char) ((number % 10) + '0'); + number /= 10; + } + + while (rev_index > 0) + { + buffer[index++] = reverse[--rev_index]; + } + + buffer[index] = '\0'; +} + +char jbi_toupper(char ch) +{ + return ((char) (((ch >= 'a') && (ch <= 'z')) ? (ch + 'A' - 'a') : ch)); +} + +int jbi_stricmp(char *left, char *right) +{ + int result = 0; + char l, r; + + do + { + l = jbi_toupper(*left); + r = jbi_toupper(*right); + result = l - r; + ++left; + ++right; + } + while ((result == 0) && (l != '\0') && (r != '\0')); + + return (result); +} + +void jbi_strncpy(char *left, char *right, int count) +{ + char ch; + + do + { + *left = *right; + ch = *right; + ++left; + ++right; + --count; + } + while ((ch != '\0') && (count != 0)); +} + +void jbi_make_dword(unsigned char *buf, unsigned long num) +{ + buf[0] = (unsigned char) num; + buf[1] = (unsigned char) (num >> 8L); + buf[2] = (unsigned char) (num >> 16L); + buf[3] = (unsigned char) (num >> 24L); +} + +unsigned long jbi_get_dword(unsigned char *buf) +{ + return + (((unsigned long) buf[0]) | + (((unsigned long) buf[1]) << 8L) | + (((unsigned long) buf[2]) << 16L) | + (((unsigned long) buf[3]) << 24L)); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_execute +( + PROGRAM_PTR program, + long program_size, + char *workspace, + long workspace_size, + char *action, + char **init_list, + int reset_jtag, + long *error_address, + int *exit_code, + int *format_version +) + +/* */ +/* Description: */ +/* */ +/* Returns: */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned long first_word = 0L; + unsigned long action_table = 0L; + unsigned long proc_table = 0L; + unsigned long string_table = 0L; + unsigned long symbol_table = 0L; + unsigned long data_section = 0L; + unsigned long code_section = 0L; + unsigned long debug_section = 0L; + unsigned long action_count = 0L; + unsigned long proc_count = 0L; + unsigned long symbol_count = 0L; + /*char message_buffer[JBIC_MESSAGE_LENGTH + 1];*/ + char *message_buffer; + addr_t *variables = NULL; + long *variable_size = NULL; + char *attributes = NULL; + unsigned char *proc_attributes = NULL; + unsigned long pc; + unsigned long opcode_address; + unsigned long args[3]; + unsigned int opcode; + unsigned long name_id; + addr_t stack[JBI_STACK_SIZE] = {0}; + unsigned char charbuf[4]; + long long_temp; + unsigned int variable_id; + unsigned char *charptr_temp; + unsigned char *charptr_temp2; + long *longptr_temp; + int version = 0; + int delta = 0; + int stack_ptr = 0; + unsigned int arg_count; + int done = 0; + int bad_opcode = 0; + unsigned int count; + unsigned int index; + unsigned int index2; + long long_count; + long long_index; + long long_index2; + unsigned int i; + unsigned int j; + unsigned long uncompressed_size, uncompressed_result; + unsigned int offset; + unsigned long value; + int current_proc = 0; + char *equal_ptr; + int length; + int reverse; + + unsigned long debug_cnt = 0; + +#if PORT==DOS + char name[33]; +#else + char *name; +#endif + + jbi_workspace = workspace; + jbi_workspace_size = workspace_size; + +#if PORT==DOS + jbi_program = program; +#endif + + /* Resolve compilation warnings: the frame size of 1664 bytes is larger than 1024 bytes */ + message_buffer = (char *) kzalloc(JBIC_MESSAGE_LENGTH + 1, GFP_KERNEL); + if (message_buffer == NULL) { + jbi_dbg(DEBUG_DETAIL, "Memory not enough jbi_execute \n"); + return JBIC_OUT_OF_MEMORY; + } + + /* + * Read header information + */ + if (program_size > 52L) + { + first_word = GET_DWORD(0); + version = (int) (first_word & 1L); + *format_version = version + 1; + delta = version * 8; + + action_table = GET_DWORD(4); + proc_table = GET_DWORD(8); + string_table = GET_DWORD(4 + delta); + symbol_table = GET_DWORD(16 + delta); + data_section = GET_DWORD(20 + delta); + code_section = GET_DWORD(24 + delta); + debug_section = GET_DWORD(28 + delta); + action_count = GET_DWORD(40 + delta); + proc_count = GET_DWORD(44 + delta); + symbol_count = GET_DWORD(48 + (2 * delta)); + + jbi_dbg(DEBUG_DETAIL, "version: %d\n", version); + jbi_dbg(DEBUG_DETAIL, "delta: %d\n", delta); + jbi_dbg(DEBUG_DETAIL, "action_table: 0x%08lx\n", action_table); + jbi_dbg(DEBUG_DETAIL, "proc_table: 0x%08lx\n", proc_table); + jbi_dbg(DEBUG_DETAIL, "string_table: 0x%08lx\n", string_table); + jbi_dbg(DEBUG_DETAIL, "symbol_table: 0x%08lx\n", symbol_table); + jbi_dbg(DEBUG_DETAIL, "data_section: 0x%08lx\n", data_section); + jbi_dbg(DEBUG_DETAIL, "code_section: 0x%08lx\n", code_section); + jbi_dbg(DEBUG_DETAIL, "debug_section: 0x%08lx\n", debug_section); + jbi_dbg(DEBUG_DETAIL, "action_count: 0x%08lx\n", action_count); + jbi_dbg(DEBUG_DETAIL, "proc_count: 0x%08lx\n", proc_count); + jbi_dbg(DEBUG_DETAIL, "symbol_count: 0x%08lx\n", symbol_count); + jbi_dbg(DEBUG_DETAIL, "\n"); + } + + if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) + { + jbi_dbg(DEBUG_ERR, "first_word 0x%lx\n", first_word); + done = 1; + status = JBIC_IO_ERROR; + } + + if ((status == JBIC_SUCCESS) && (symbol_count > 0)) + { + variables = (addr_t *) jbi_malloc( + (unsigned int) symbol_count * sizeof(long)); + + if (variables == NULL) status = JBIC_OUT_OF_MEMORY; + + if (status == JBIC_SUCCESS) + { + variable_size = (long *) jbi_malloc( + (unsigned int) symbol_count * sizeof(long)); + + if (variable_size == NULL) status = JBIC_OUT_OF_MEMORY; + } + + if (status == JBIC_SUCCESS) + { + attributes = (char *) jbi_malloc((unsigned int) symbol_count); + + if (attributes == NULL) status = JBIC_OUT_OF_MEMORY; + } + + if ((status == JBIC_SUCCESS) && (version > 0)) + { + proc_attributes = (unsigned char *) jbi_malloc((unsigned int) proc_count); + + if (proc_attributes == NULL) status = JBIC_OUT_OF_MEMORY; + } + + if (status == JBIC_SUCCESS) + { + delta = version * 2; + + for (i = 0; i < (unsigned int) symbol_count; ++i) + { + offset = (unsigned int) (symbol_table + ((11 + delta) * i)); + + value = GET_DWORD(offset + 3 + delta); + + attributes[i] = GET_BYTE(offset); + + /* use bit 7 of attribute byte to indicate that this buffer */ + /* was dynamically allocated and should be freed later */ + attributes[i] &= 0x7f; + + variable_size[i] = GET_DWORD(offset + 7 + delta); + + jbi_dbg(DEBUG_NOISY, "symbol %03d: 0x%02x,0x%08lx,0x%08lx\n", + i, attributes[i], value, variable_size[i]); + + /* + * Attribute bits: + * bit 0: 0 = read-only, 1 = read-write + * bit 1: 0 = not compressed, 1 = compressed + * bit 2: 0 = not initialized, 1 = initialized + * bit 3: 0 = scalar, 1 = array + * bit 4: 0 = Boolean, 1 = integer + * bit 5: 0 = declared variable, + * 1 = compiler created temporary variable + */ + + if ((attributes[i] & 0x0c) == 0x04) + { + /* initialized scalar variable */ + variables[i] = value; + } + else if ((attributes[i] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ +#if PORT==DOS + /* for DOS port, get the size but do not uncompress */ + long_index = data_section + value; + uncompressed_size = + (((unsigned long) GET_BYTE(long_index)) | + (((unsigned long) GET_BYTE(long_index + 1L)) << 8L) | + (((unsigned long) GET_BYTE(long_index + 2L)) << 16L) | + (((unsigned long) GET_BYTE(long_index + 3L)) << 24L)); + variable_size[i] = uncompressed_size; +#else + uncompressed_size = jbi_get_dword( + &program[data_section + value]); + + /* allocate a buffer for the uncompressed data */ + variables[i] = (addr_t) jbi_malloc(uncompressed_size); + + if (variables[i] == (addr_t) 0L) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + /* set flag so buffer will be freed later */ + attributes[i] |= 0x80; + + /* uncompress the data */ + uncompressed_result = + jbi_uncompress( + &program[data_section + value], + variable_size[i], + (unsigned char *) variables[i], + uncompressed_size, + version); + if (uncompressed_result != uncompressed_size) + { + /* decompression failed */ + jbi_dbg(DEBUG_ERR, "uncompress fail(0x%lx,0x%lx,0x%lx)(0x%lx)\n", + variable_size[i], uncompressed_result, uncompressed_size, value); + status = JBIC_IO_ERROR; + } + else + { + variable_size[i] = uncompressed_size * 8L; + } + } +#endif + } + else if ((attributes[i] & 0x1e) == 0x0c) + { + /* initialized Boolean array */ +#if PORT==DOS + /* flag attributes so that memory is freed */ + attributes[i] |= 0x80; + + if (variable_size[i] > 0) + { + unsigned int size = (unsigned int) + ((variable_size[i] + 7L) / 8L); + + variables[i] = (long) jbi_malloc(size); + + if (variables[i] == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + unsigned char *p = (unsigned char *) variables[i]; + /* copy array values into buffer */ + for (j = 0; j < size; ++j) + { + p[j] = GET_BYTE(data_section + value + j); + } + } + } + else + { + variables[i] = 0; + } +#else + variables[i] = value + data_section + (addr_t) program; +#endif + } + else if ((attributes[i] & 0x1c) == 0x1c) + { + /* initialized integer array */ + variables[i] = value + data_section; + } + else if ((attributes[i] & 0x0c) == 0x08) + { + /* uninitialized array */ + + /* flag attributes so that memory is freed */ + attributes[i] |= 0x80; + + if (variable_size[i] > 0) + { + unsigned int size; + + if (attributes[i] & 0x10) + { + /* integer array */ + size = (unsigned int) + (variable_size[i] * sizeof(long)); + } + else + { + /* Boolean array */ + size = (unsigned int) + ((variable_size[i] + 7L) / 8L); + } + + variables[i] = (addr_t) jbi_malloc(size); + + if (variables[i] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + /* zero out memory */ + for (j = 0; j < size; ++j) + { + ((unsigned char *)(variables[i]))[j] = 0; + } + } + } + else + { + variables[i] = 0; + } + } + else + { + variables[i] = 0; + } + + jbi_dbg(DEBUG_NOISY, " variables: 0x%08lx,0x%016llx\n", + variable_size[i], (long long) variables[i]); + } + } + + jbi_dbg(DEBUG_NOISY, "\n"); + } + + /* + * Initialize variables listed in init_list + */ + if ((status == JBIC_SUCCESS) && (init_list != NULL) && (version == 0)) + { + delta = version * 2; + count = 0; + while (init_list[count] != NULL) + { + equal_ptr = init_list[count]; + length = 0; + while ((*equal_ptr != '=') && (*equal_ptr != '\0')) + { + ++equal_ptr; + ++length; + } + if (*equal_ptr == '=') + { + ++equal_ptr; + value = jbi_atol(equal_ptr); + jbi_strncpy(message_buffer, init_list[count], length); + message_buffer[length] = '\0'; + for (i = 0; i < (unsigned int) symbol_count; ++i) + { + offset = (unsigned int) (symbol_table + ((11 + delta) * i)); + name_id = (version == 0) ? GET_WORD(offset + 1) : + GET_DWORD(offset + 1); +#if PORT==DOS + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + name_id]; +#endif + + if (jbi_stricmp(message_buffer, name) == 0) + { + variables[i] = value; + } + + jbi_dbg(DEBUG_NOISY, "init_list %03d: 0x%08lx,%s,0x%016llx\n", + i, name_id, name, (long long) variables[i]); + } + } + + ++count; + } + + jbi_dbg(DEBUG_NOISY, "\n"); + } + + if (status != JBIC_SUCCESS) done = 1; + + jbi_init_jtag(); + + pc = code_section; + message_buffer[0] = '\0'; + + /* + * For JBC version 2, we will execute the procedures corresponding to + * the selected ACTION + */ + if (version > 0) + { + if (action == NULL) + { + status = JBIC_ACTION_NOT_FOUND; + done = 1; + } + else + { + int action_found = 0; + + for (i = 0; (i < action_count) && !action_found; ++i) + { + name_id = GET_DWORD(action_table + (12 * i)); + +#if PORT==DOS + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + name_id]; +#endif + + if (jbi_stricmp(action, name) == 0) + { + action_found = 1; + current_proc = (int) GET_DWORD(action_table + (12 * i) + 8); + } + + jbi_dbg(DEBUG_NOISY, "action %03d: 0x%08lx,%s, %d,%d\n", + i, name_id, name, action_found, current_proc); + } + + if (!action_found) + { + status = JBIC_ACTION_NOT_FOUND; + done = 1; + } + } + + if (status == JBIC_SUCCESS) + { + int first_time = 1; + i = current_proc; + while ((i != 0) || first_time) + { + first_time = 0; + /* check procedure attribute byte */ + proc_attributes[i] = (unsigned char) + (GET_BYTE(proc_table + (13 * i) + 8) & 0x03); + + jbi_dbg(DEBUG_NOISY, " proc_attributes %03d: 0x%02x\n", + i, proc_attributes[i]); + + if (proc_attributes[i] != 0) + { + /* + * BIT0 - OPTIONAL + * BIT1 - RECOMMENDED + * BIT6 - FORCED OFF + * BIT7 - FORCED ON + */ + if (init_list != NULL) + { + name_id = GET_DWORD(proc_table + (13 * i)); +#if PORT==DOS + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + name_id]; +#endif + + jbi_dbg(DEBUG_NOISY, " init_list %03d: 0x%08lx,%s\n", + i, name_id, name); + + count = 0; + while (init_list[count] != NULL) + { + equal_ptr = init_list[count]; + length = 0; + while ((*equal_ptr != '=') && (*equal_ptr != '\0')) + { + ++equal_ptr; + ++length; + } + if (*equal_ptr == '=') + { + ++equal_ptr; + jbi_strncpy(message_buffer, init_list[count], length); + message_buffer[length] = '\0'; + + if (jbi_stricmp(message_buffer, name) == 0) + { + if (jbi_atol(equal_ptr) == 0) + { + proc_attributes[i] |= 0x40; + } + else + { + proc_attributes[i] |= 0x80; + } + } + } + + jbi_dbg(DEBUG_NOISY, " proc_attributes %03d: 0x%02x\n", + i, proc_attributes[i]); + + ++count; + } + } + } + + i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4); + } + + /* + * Set current_proc to the first procedure to be executed + */ + i = current_proc; + while ((i != 0) && + ((proc_attributes[i] == 1) || + ((proc_attributes[i] & 0xc0) == 0x40))) + { + i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4); + } + + if ((i != 0) || ((i == 0) && (current_proc == 0) && + ((proc_attributes[0] != 1) && + ((proc_attributes[0] & 0xc0) != 0x40)))) + { + current_proc = i; + pc = code_section + GET_DWORD(proc_table + (13 * i) + 9); + CHECK_PC; + } + else + { + /* there are no procedures to execute! */ + done = 1; + } + } + + jbi_dbg(DEBUG_NOISY, "\n"); + } + + message_buffer[0] = '\0'; + + jbi_dbg(DEBUG_NOISY, "excute pc: 0x%lx,%d\n", pc, current_proc); + while (!done) + { + opcode = (unsigned int) (GET_BYTE(pc) & 0xff); + debug_cnt++; + jbi_dbg(DEBUG_NOISY, "op: 0x%02x(%03d:0x%08lx,%08lx)", + opcode, stack_ptr, pc, debug_cnt); + opcode_address = pc; + ++pc; + + arg_count = (opcode >> 6) & 3; + jbi_dbg(DEBUG_NOISY, " - %u:", arg_count); + for (i = 0; i < arg_count; ++i) + { + args[i] = GET_DWORD(pc); + jbi_dbg(DEBUG_NOISY, " 0x%08lx", args[i]); + pc += 4; + } + jbi_dbg(DEBUG_NOISY, "\n"); + + switch (opcode) + { + case 0x00: /* NOP */ + /* do nothing */ + break; + + case 0x01: /* DUP */ + IF_CHECK_STACK(1) + { + stack[stack_ptr] = stack[stack_ptr - 1]; + ++stack_ptr; + } + break; + + case 0x02: /* SWP */ + IF_CHECK_STACK(2) + { + long_temp = stack[stack_ptr - 2]; + stack[stack_ptr - 2] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + break; + + case 0x03: /* ADD */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] += stack[stack_ptr]; + } + break; + + case 0x04: /* SUB */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] -= stack[stack_ptr]; + } + break; + + case 0x05: /* MULT */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] *= stack[stack_ptr]; + } + break; + + case 0x06: /* DIV */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] /= stack[stack_ptr]; + } + break; + + case 0x07: /* MOD */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] %= stack[stack_ptr]; + } + break; + + case 0x08: /* SHL */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] <<= stack[stack_ptr]; + } + break; + + case 0x09: /* SHR */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] >>= stack[stack_ptr]; + } + break; + + case 0x0A: /* NOT */ + IF_CHECK_STACK(1) + { + stack[stack_ptr - 1] ^= (-1L); + } + break; + + case 0x0B: /* AND */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] &= stack[stack_ptr]; + } + break; + + case 0x0C: /* OR */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] |= stack[stack_ptr]; + } + break; + + case 0x0D: /* XOR */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] ^= stack[stack_ptr]; + } + break; + + case 0x0E: /* INV */ + IF_CHECK_STACK(1) + { + stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L; + } + break; + + case 0x0F: /* GT */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] = + (stack[stack_ptr - 1] > stack[stack_ptr]) ? 1L : 0L; + } + break; + + case 0x10: /* LT */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] = + (stack[stack_ptr - 1] < stack[stack_ptr]) ? 1L : 0L; + } + break; + + case 0x11: /* RET */ + if ((version > 0) && (stack_ptr == 0)) + { + /* + * We completed one of the main procedures of an ACTION. + * Find the next procedure to be executed and jump to it. + * If there are no more procedures, then EXIT. + */ + i = (unsigned int) GET_DWORD(proc_table + (13 * current_proc) + 4); + while ((i != 0) && + ((proc_attributes[i] == 1) || + ((proc_attributes[i] & 0xc0) == 0x40))) + { + i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4); + } + + if (i == 0) + { + /* there are no procedures to execute! */ + done = 1; + *exit_code = 0; /* success */ + } + else + { + current_proc = i; + pc = code_section + GET_DWORD(proc_table + (13 * i) + 9); + CHECK_PC; + } + } + else IF_CHECK_STACK(1) + { + pc = stack[--stack_ptr] + code_section; + CHECK_PC; + if (pc == code_section) + { + status = JBIC_BOUNDS_ERROR; + } + } + break; + + case 0x12: /* CMPS */ + /* + * Array short compare + * ...stack 0 is source 1 value + * ...stack 1 is source 2 value + * ...stack 2 is mask value + * ...stack 3 is count + */ + IF_CHECK_STACK(4) + { + long a = stack[--stack_ptr]; + long b = stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[stack_ptr - 1]; + + if ((count < 1) || (count > 32)) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + long_temp &= ((-1L) >> (32 - count)); + + stack[stack_ptr - 1] = + ((a & long_temp) == (b & long_temp)) ? 1L : 0L; + } + } + break; + + case 0x13: /* PINT */ + /* + * PRINT add integer + * ...stack 0 is integer value + */ + IF_CHECK_STACK(1) + { + jbi_ltoa(&message_buffer[jbi_strlen(message_buffer)], + stack[--stack_ptr]); + } + break; + + case 0x14: /* PRNT */ + /* + * PRINT finish + */ + jbi_message(message_buffer); + message_buffer[0] = '\0'; + break; + + case 0x15: /* DSS */ + /* + * DRSCAN short + * ...stack 0 is scan data + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_do_drscan(count, charbuf, 0); + } + break; + + case 0x16: /* DSSC */ + /* + * DRSCAN short with capture + * ...stack 0 is scan data + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[stack_ptr - 1]; + jbi_make_dword(charbuf, long_temp); + status = jbi_swap_dr(count, charbuf, 0, charbuf, 0); + stack[stack_ptr - 1] = jbi_get_dword(charbuf); + } + break; + + case 0x17: /* ISS */ + /* + * IRSCAN short + * ...stack 0 is scan data + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_do_irscan(count, charbuf, 0); + } + break; + + case 0x18: /* ISSC */ + /* + * IRSCAN short with capture + * ...stack 0 is scan data + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[stack_ptr - 1]; + jbi_make_dword(charbuf, long_temp); + status = jbi_swap_ir(count, charbuf, 0, charbuf, 0); + stack[stack_ptr - 1] = jbi_get_dword(charbuf); + } + break; + + case 0x19: /* VSS */ + /* + * VECTOR short + * ...stack 0 is scan data + * ...stack 1 is count + */ + bad_opcode = 1; + break; + + case 0x1A: /* VSSC */ + /* + * VECTOR short with capture + * ...stack 0 is scan data + * ...stack 1 is count + */ + bad_opcode = 1; + break; + + case 0x1B: /* VMPF */ + /* + * VMAP finish + */ + bad_opcode = 1; + break; + + case 0x1C: /* DPR */ + IF_CHECK_STACK(1) + { + count = (unsigned int) stack[--stack_ptr]; + status = jbi_set_dr_preamble(count, 0, NULL); + } + break; + + case 0x1D: /* DPRL */ + /* + * DRPRE with literal data + * ...stack 0 is count + * ...stack 1 is literal data + */ + IF_CHECK_STACK(2) + { + count = (unsigned int) stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_set_dr_preamble(count, 0, charbuf); + } + break; + + case 0x1E: /* DPO */ + /* + * DRPOST + * ...stack 0 is count + */ + IF_CHECK_STACK(1) + { + count = (unsigned int) stack[--stack_ptr]; + status = jbi_set_dr_postamble(count, 0, NULL); + } + break; + + case 0x1F: /* DPOL */ + /* + * DRPOST with literal data + * ...stack 0 is count + * ...stack 1 is literal data + */ + IF_CHECK_STACK(2) + { + count = (unsigned int) stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_set_dr_postamble(count, 0, charbuf); + } + break; + + case 0x20: /* IPR */ + IF_CHECK_STACK(1) + { + count = (unsigned int) stack[--stack_ptr]; + status = jbi_set_ir_preamble(count, 0, NULL); + } + break; + + case 0x21: /* IPRL */ + /* + * IRPRE with literal data + * ...stack 0 is count + * ...stack 1 is literal data + */ + IF_CHECK_STACK(2) + { + count = (unsigned int) stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_set_ir_preamble(count, 0, charbuf); + } + break; + + case 0x22: /* IPO */ + /* + * IRPOST + * ...stack 0 is count + */ + IF_CHECK_STACK(1) + { + count = (unsigned int) stack[--stack_ptr]; + status = jbi_set_ir_postamble(count, 0, NULL); + } + break; + + case 0x23: /* IPOL */ + /* + * IRPOST with literal data + * ...stack 0 is count + * ...stack 1 is literal data + */ + IF_CHECK_STACK(2) + { + count = (unsigned int) stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_set_ir_postamble(count, 0, charbuf); + } + break; + + case 0x24: /* PCHR */ + IF_CHECK_STACK(1) + { + unsigned char ch; + count = jbi_strlen(message_buffer); + ch = (char) stack[--stack_ptr]; + if ((ch < 1) || (ch > 127)) + { + /* character code out of range */ + /* instead of flagging an error, force the value to 127 */ + ch = 127; + } + message_buffer[count] = ch; + message_buffer[count + 1] = '\0'; + } + break; + + case 0x25: /* EXIT */ + IF_CHECK_STACK(1) + { + *exit_code = (int) stack[--stack_ptr]; + } + done = 1; + break; + + case 0x26: /* EQU */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] = + (stack[stack_ptr - 1] == stack[stack_ptr]) ? 1L : 0L; + } + break; + + case 0x27: /* POPT */ + IF_CHECK_STACK(1) + { + --stack_ptr; + } + break; + + case 0x28: /* TRST */ + bad_opcode = 1; + break; + + case 0x29: /* FRQ */ + bad_opcode = 1; + break; + + case 0x2A: /* FRQU */ + bad_opcode = 1; + break; + + case 0x2B: /* PD32 */ + bad_opcode = 1; + break; + + case 0x2C: /* ABS */ + IF_CHECK_STACK(1) + { + if (stack[stack_ptr - 1] < 0) + { + stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1]; + } + } + break; + + case 0x2D: /* BCH0 */ + /* + * Batch operation 0 + * SWP + * SWPN 7 + * SWP + * SWPN 6 + * DUPN 8 + * SWPN 2 + * SWP + * DUPN 6 + * DUPN 6 + */ + + /* SWP */ + IF_CHECK_STACK(2) + { + long_temp = stack[stack_ptr - 2]; + stack[stack_ptr - 2] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* SWPN 7 */ + index = 7 + 1; + IF_CHECK_STACK(index) + { + long_temp = stack[stack_ptr - index]; + stack[stack_ptr - index] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* SWP */ + IF_CHECK_STACK(2) + { + long_temp = stack[stack_ptr - 2]; + stack[stack_ptr - 2] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* SWPN 6 */ + index = 6 + 1; + IF_CHECK_STACK(index) + { + long_temp = stack[stack_ptr - index]; + stack[stack_ptr - index] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* DUPN 8 */ + index = 8 + 1; + IF_CHECK_STACK(index) + { + stack[stack_ptr] = stack[stack_ptr - index]; + ++stack_ptr; + } + + /* SWPN 2 */ + index = 2 + 1; + IF_CHECK_STACK(index) + { + long_temp = stack[stack_ptr - index]; + stack[stack_ptr - index] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* SWP */ + IF_CHECK_STACK(2) + { + long_temp = stack[stack_ptr - 2]; + stack[stack_ptr - 2] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* DUPN 6 */ + index = 6 + 1; + IF_CHECK_STACK(index) + { + stack[stack_ptr] = stack[stack_ptr - index]; + ++stack_ptr; + } + + /* DUPN 6 */ + index = 6 + 1; + IF_CHECK_STACK(index) + { + stack[stack_ptr] = stack[stack_ptr - index]; + ++stack_ptr; + } + break; + + case 0x2E: /* BCH1 */ + /* + * Batch operation 1 + * SWPN 8 + * SWP + * SWPN 9 + * SWPN 3 + * SWP + * SWPN 2 + * SWP + * SWPN 7 + * SWP + * SWPN 6 + * DUPN 5 + * DUPN 5 + */ + bad_opcode = 1; + break; + + case 0x2F: /* PSH0 */ + stack[stack_ptr++] = 0; + break; + + case 0x40: /* PSHL */ + stack[stack_ptr++] = (long) args[0]; + break; + + case 0x41: /* PSHV */ + stack[stack_ptr++] = variables[args[0]]; + break; + + case 0x42: /* JMP */ + pc = args[0] + code_section; + CHECK_PC; + break; + + case 0x43: /* CALL */ + stack[stack_ptr++] = pc; + pc = args[0] + code_section; + CHECK_PC; + break; + + case 0x44: /* NEXT */ + /* + * Process FOR / NEXT loop + * ...argument 0 is variable ID + * ...stack 0 is step value + * ...stack 1 is end value + * ...stack 2 is top address + */ + IF_CHECK_STACK(3) + { + long step = stack[stack_ptr - 1]; + long end = stack[stack_ptr - 2]; + long top = stack[stack_ptr - 3]; + long iterator = variables[args[0]]; + int break_out = 0; + + if (step < 0) + { + if (iterator <= end) break_out = 1; + } + else + { + if (iterator >= end) break_out = 1; + } + + if (break_out) + { + stack_ptr -= 3; + } + else + { + variables[args[0]] = iterator + step; + pc = top + code_section; + CHECK_PC; + } + } + break; + + case 0x45: /* PSTR */ + /* + * PRINT add string + * ...argument 0 is string ID + */ +#if PORT==DOS + long_index = string_table + args[0]; + index2 = jbi_strlen(message_buffer); + + do + { + i = GET_BYTE(long_index); + message_buffer[index2] = (char) i; + ++long_index; + ++index2; + } + while ((i != '\0') && (index2 < JBIC_MESSAGE_LENGTH)); +#else + count = jbi_strlen(message_buffer); + jbi_strncpy(&message_buffer[count], + (char *) &program[string_table + args[0]], + JBIC_MESSAGE_LENGTH - count); +#endif + message_buffer[JBIC_MESSAGE_LENGTH] = '\0'; + break; + + case 0x46: /* VMAP */ + /* + * VMAP add signal name + * ...argument 0 is string ID + */ + bad_opcode = 1; + break; + + case 0x47: /* SINT */ + /* + * STATE intermediate state + * ...argument 0 is state code + */ + status = jbi_goto_jtag_state((int) args[0]); + break; + + case 0x48: /* ST */ + /* + * STATE final state + * ...argument 0 is state code + */ + status = jbi_goto_jtag_state((int) args[0]); + break; + + case 0x49: /* ISTP */ + /* + * IRSTOP state + * ...argument 0 is state code + */ + status = jbi_set_irstop_state((int) args[0]); + break; + + case 0x4A: /* DSTP */ + /* + * DRSTOP state + * ...argument 0 is state code + */ + status = jbi_set_drstop_state((int) args[0]); + break; + + case 0x4B: /* SWPN */ + /* + * Exchange top with Nth stack value + * ...argument 0 is 0-based stack entry to swap with top element + */ + index = ((int) args[0]) + 1; + IF_CHECK_STACK(index) + { + long_temp = stack[stack_ptr - index]; + stack[stack_ptr - index] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + break; + + case 0x4C: /* DUPN */ + /* + * Duplicate Nth stack value + * ...argument 0 is 0-based stack entry to duplicate + */ + index = ((int) args[0]) + 1; + IF_CHECK_STACK(index) + { + stack[stack_ptr] = stack[stack_ptr - index]; + ++stack_ptr; + } + break; + + case 0x4D: /* POPV */ + /* + * Pop stack into scalar variable + * ...argument 0 is variable ID + * ...stack 0 is value + */ + IF_CHECK_STACK(1) + { + variables[args[0]] = stack[--stack_ptr]; + } + break; + + case 0x4E: /* POPE */ + /* + * Pop stack into integer array element + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is value + */ + IF_CHECK_STACK(2) + { + variable_id = (unsigned int) args[0]; + + /* + * If variable is read-only, convert to writable array + */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x1c)) + { + /* + * Allocate a writable buffer for this array + */ + count = (unsigned int) variable_size[variable_id]; + long_temp = variables[variable_id]; + longptr_temp = (long *) jbi_malloc(count * sizeof(long)); + variables[variable_id] = (addr_t) longptr_temp; + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + /* copy previous contents into buffer */ + for (i = 0; i < count; ++i) + { + longptr_temp[i] = GET_DWORD(long_temp); + long_temp += 4L; + } + + /* set bit 7 - buffer was dynamically allocated */ + attributes[variable_id] |= 0x80; + + /* clear bit 2 - variable is writable */ + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } + } + +#if PORT==DOS + /* for 16-bit version, allow writing in allocated buffers */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x9c)) + { + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } +#endif + + /* check that variable is a writable integer array */ + if ((attributes[variable_id] & 0x1c) != 0x18) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + longptr_temp = (long *) variables[variable_id]; + + /* pop the array index */ + index = (unsigned int) stack[--stack_ptr]; + + /* pop the value and store it into the array */ + longptr_temp[index] = stack[--stack_ptr]; + } + } + break; + + case 0x4F: /* POPA */ + /* + * Pop stack into Boolean array + * ...argument 0 is variable ID + * ...stack 0 is count + * ...stack 1 is array index + * ...stack 2 is value + */ + IF_CHECK_STACK(3) + { + variable_id = (unsigned int) args[0]; + + /* + * If variable is read-only, convert to writable array + */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x0c)) + { + /* + * Allocate a writable buffer for this array + */ + long_temp = (variable_size[variable_id] + 7L) >> 3L; + charptr_temp2 = (unsigned char *) variables[variable_id]; + charptr_temp = jbi_malloc((unsigned int) long_temp); + variables[variable_id] = (addr_t) charptr_temp; + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + /* zero the buffer */ + for (long_index = 0L; + long_index < long_temp; + ++long_index) + { + charptr_temp[long_index] = 0; + } + + /* copy previous contents into buffer */ + for (long_index = 0L; + long_index < variable_size[variable_id]; + ++long_index) + { +#if PORT==DOS + if ((attributes[variable_id] & 0x02) && + ((long_index & 0x0000FFFF) == 0L)) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + charptr_temp = jbi_aca_out_buffer; + long_index2 = long_index & 0xFFFF; + } +#else + long_index2 = long_index; +#endif + + if (charptr_temp2[long_index2 >> 3] & + (1 << (long_index2 & 7))) + { + charptr_temp[long_index >> 3] |= + (1 << (long_index & 7)); + } + } + + /* set bit 7 - buffer was dynamically allocated */ + attributes[variable_id] |= 0x80; + + /* clear bit 2 - variable is writable */ + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } + } + +#if PORT==DOS + /* for 16-bit version, allow writing in allocated buffers */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x8c)) + { + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } +#endif + + /* check that variable is a writable Boolean array */ + if ((attributes[variable_id] & 0x1c) != 0x08) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + charptr_temp = (unsigned char *) variables[variable_id]; + + /* pop the count (number of bits to copy) */ + long_count = stack[--stack_ptr]; + + /* pop the array index */ + long_index = stack[--stack_ptr]; + + reverse = 0; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + + if (long_index > long_count) + { + reverse = 1; + long_temp = long_count; + long_count = 1 + long_index - long_count; + long_index = long_temp; + + /* reverse POPA is not supported */ + status = JBIC_BOUNDS_ERROR; + break; + } + else + { + long_count = 1 + long_count - long_index; + } + } + + /* pop the data */ + long_temp = stack[--stack_ptr]; + + if (long_count < 1) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + for (i = 0; i < (unsigned int) long_count; ++i) + { + if (long_temp & (1L << (long) i)) + { + charptr_temp[long_index >> 3L] |= + (1L << (long_index & 7L)); + } + else + { + charptr_temp[long_index >> 3L] &= + ~ (unsigned int) (1L << (long_index & 7L)); + } + ++long_index; + } + } + } + } + break; + + case 0x50: /* JMPZ */ + /* + * Pop stack and branch if zero + * ...argument 0 is address + * ...stack 0 is condition value + */ + IF_CHECK_STACK(1) + { + if (stack[--stack_ptr] == 0) + { + pc = args[0] + code_section; + CHECK_PC; + } + } + break; + + case 0x51: /* DS */ + case 0x52: /* IS */ + /* + * DRSCAN + * IRSCAN + * ...argument 0 is scan data variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_index = stack[--stack_ptr]; + long_count = stack[--stack_ptr]; + + reverse = 0; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + /* stack 2 = count */ + long_temp = long_count; + long_count = stack[--stack_ptr]; + + if (long_index > long_temp) + { + reverse = 1; + long_index = long_temp; + } + } + +#if PORT==DOS + if (((long_index & 0xFFFF0000) == 0) && + ((long_count & 0xFFFF0000) == 0)) + { + variable_id = (unsigned int) args[0]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + long_index &= 0x0000ffff; + charptr_temp = jbi_aca_out_buffer; + } + else + { + charptr_temp = (unsigned char *) variables[variable_id]; + } + + if (reverse) + { + /* allocate a buffer and reverse the data order */ + charptr_temp2 = charptr_temp; + charptr_temp = jbi_malloc((unsigned int) + ((long_count >> 3L) + 1L)); + + if (charptr_temp == NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + long_temp = long_index + long_count - 1; + long_index2 = 0; + while (long_index2 < long_count) + { + if (charptr_temp2[long_temp >> 3] & + (1 << (long_temp & 7))) + { + charptr_temp[long_index2 >> 3] |= + (1 << (long_index2 & 7)); + } + else + { + charptr_temp[long_index2 >> 3] &= + ~(1 << (long_index2 & 7)); + } + + --long_temp; + ++long_index2; + } + } + } + + if (opcode == 0x51) /* DS */ + { + status = jbi_do_drscan((unsigned int) long_count, + charptr_temp, (unsigned long) long_index); + } + else /* IS */ + { + status = jbi_do_irscan((unsigned int) long_count, + charptr_temp, (unsigned int) long_index); + } + + if (reverse) jbi_free(charptr_temp); + } + else if ((opcode == 0x51) && !reverse) + { + status = jbi_do_drscan_multi_page( + (unsigned int) args[0], + (unsigned long) long_count, + (unsigned long) long_index, version); + } + else + { + /* reverse multi-page scans are not supported */ + /* multi-page IR scans are not supported */ + status = JBIC_BOUNDS_ERROR; + } +#else + charptr_temp = (unsigned char *) variables[args[0]]; + + if (reverse) + { + /* allocate a buffer and reverse the data order */ + charptr_temp2 = charptr_temp; + charptr_temp = jbi_malloc((long_count >> 3) + 1); + if (charptr_temp == NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + long_temp = long_index + long_count - 1; + long_index2 = 0; + while (long_index2 < long_count) + { + if (charptr_temp2[long_temp >> 3] & + (1 << (long_temp & 7))) + { + charptr_temp[long_index2 >> 3] |= + (1 << (long_index2 & 7)); + } + else + { + charptr_temp[long_index2 >> 3] &= + ~(1 << (long_index2 & 7)); + } + + --long_temp; + ++long_index2; + } + } + } + + if (opcode == 0x51) /* DS */ + { + status = jbi_do_drscan((unsigned int) long_count, + charptr_temp, (unsigned long) long_index); + } + else /* IS */ + { + status = jbi_do_irscan((unsigned int) long_count, + charptr_temp, (unsigned int) long_index); + } +#endif + + if (reverse && (charptr_temp != NULL)) + { + jbi_free(charptr_temp); + } + } + break; + + case 0x53: /* DPRA */ + /* + * DRPRE with array data + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + index = (unsigned int) stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + charptr_temp = (unsigned char *) variables[args[0]]; + status = jbi_set_dr_preamble(count, index, charptr_temp); + } + break; + + case 0x54: /* DPOA */ + /* + * DRPOST with array data + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + index = (unsigned int) stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + charptr_temp = (unsigned char *) variables[args[0]]; + status = jbi_set_dr_postamble(count, index, charptr_temp); + } + break; + + case 0x55: /* IPRA */ + /* + * IRPRE with array data + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + index = (unsigned int) stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + charptr_temp = (unsigned char *) variables[args[0]]; + status = jbi_set_ir_preamble(count, index, charptr_temp); + } + break; + + case 0x56: /* IPOA */ + /* + * IRPOST with array data + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + index = (unsigned int) stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + charptr_temp = (unsigned char *) variables[args[0]]; + status = jbi_set_ir_postamble(count, index, charptr_temp); + } + break; + + case 0x57: /* EXPT */ + /* + * EXPORT + * ...argument 0 is string ID + * ...stack 0 is integer expression + */ + IF_CHECK_STACK(1) + { +#if PORT==DOS + name_id = args[0]; + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + args[0]]; +#endif + long_temp = stack[--stack_ptr]; + jbi_export_integer(name, long_temp); + } + break; + + case 0x58: /* PSHE */ + /* + * Push integer array element + * ...argument 0 is variable ID + * ...stack 0 is array index + */ + IF_CHECK_STACK(1) + { + variable_id = (unsigned int) args[0]; + index = (unsigned int) stack[stack_ptr - 1]; + + /* check variable type */ + if ((attributes[variable_id] & 0x1f) == 0x19) + { + /* writable integer array */ + longptr_temp = (long *) variables[variable_id]; + stack[stack_ptr - 1] = longptr_temp[index]; + } + else if ((attributes[variable_id] & 0x1f) == 0x1c) + { + /* read-only integer array */ + long_temp = variables[variable_id] + (4L * index); + stack[stack_ptr - 1] = GET_DWORD(long_temp); + } + else + { + status = JBIC_BOUNDS_ERROR; + } + } + break; + + case 0x59: /* PSHA */ + /* + * Push Boolean array + * ...argument 0 is variable ID + * ...stack 0 is count + * ...stack 1 is array index + */ + IF_CHECK_STACK(2) + { + variable_id = (unsigned int) args[0]; + + /* check that variable is a Boolean array */ + if ((attributes[variable_id] & 0x18) != 0x08) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + charptr_temp = (unsigned char *) variables[variable_id]; + + /* pop the count (number of bits to copy) */ + count = (unsigned int) stack[--stack_ptr]; + + /* pop the array index */ + index = (unsigned int) stack[stack_ptr - 1]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + if ((count < 1) || (count > 32)) + { + status = JBIC_BOUNDS_ERROR; + } + else + { +#if PORT==DOS + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (stack[stack_ptr - 1] >> 16), version); + charptr_temp = jbi_aca_out_buffer; + } +#endif + long_temp = 0L; + + for (i = 0; i < count; ++i) + { + if (charptr_temp[(i + index) >> 3] & + (1 << ((i + index) & 7))) + { + long_temp |= (1L << i); + } + } + + stack[stack_ptr - 1] = long_temp; + } + } + } + break; + + case 0x5A: /* DYNA */ + /* + * Dynamically change size of array + * ...argument 0 is variable ID + * ...stack 0 is new size + */ + IF_CHECK_STACK(1) + { + variable_id = (unsigned int) args[0]; + long_temp = stack[--stack_ptr]; + + if (long_temp > variable_size[variable_id]) + { + variable_size[variable_id] = long_temp; + + if (attributes[variable_id] & 0x10) + { + /* allocate integer array */ + long_temp *= 4; + } + else + { + /* allocate Boolean array */ + long_temp = (long_temp + 7) >> 3; + } + + /* + * If the buffer was previously allocated, free it + */ + if ((attributes[variable_id] & 0x80) && + (variables[variable_id] != (addr_t) NULL)) + { + jbi_free((void *) variables[variable_id]); + variables[variable_id] = (addr_t) NULL; + } + + /* + * Allocate a new buffer of the requested size + */ + variables[variable_id] = (addr_t) + jbi_malloc((unsigned int) long_temp); + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + /* + * Set the attribute bit to indicate that this buffer + * was dynamically allocated and should be freed later + */ + attributes[variable_id] |= 0x80; + + /* zero out memory */ + count = (unsigned int) + ((variable_size[variable_id] + 7L) / 8L); + charptr_temp = (unsigned char *) + (variables[variable_id]); + for (index = 0; index < count; ++index) + { + charptr_temp[index] = 0; + } + } + } + } + break; + + case 0x5B: /* EXPR */ + bad_opcode = 1; + break; + + case 0x5C: /* EXPV */ + /* + * Export Boolean array + * ...argument 0 is string ID + * ...stack 0 is variable ID + * ...stack 1 is array right index + * ...stack 2 is array left index + */ + IF_CHECK_STACK(3) + { + if (version == 0) + { + /* EXPV is not supported in JBC 1.0 */ + bad_opcode = 1; + break; + } +#if PORT==DOS + name_id = args[0]; + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + args[0]]; +#endif + variable_id = (unsigned int) stack[--stack_ptr]; + long_index = stack[--stack_ptr]; /* right index */ + long_index2 = stack[--stack_ptr]; /* left index */ + + if (long_index > long_index2) + { + /* reverse indices not supported */ + status = JBIC_BOUNDS_ERROR; + break; + } + + long_count = 1 + long_index2 - long_index; + + charptr_temp = (unsigned char *) variables[variable_id]; + charptr_temp2 = NULL; + +#if PORT==DOS + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + charptr_temp = jbi_aca_out_buffer; + long_index &= 0x0000FFFF; + } +#endif + + if ((long_index & 7L) != 0) + { + charptr_temp2 = jbi_malloc((unsigned int) + ((long_count + 7L) / 8L)); + if (charptr_temp2 == NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + long k = long_index; + for (i = 0; i < (unsigned int) long_count; ++i) + { + if (charptr_temp[k >> 3] & (1 << (k & 7))) + { + charptr_temp2[i >> 3] |= (1 << (i & 7)); + } + else + { + charptr_temp2[i >> 3] &= ~(1 << (i & 7)); + } + + ++k; + } + charptr_temp = charptr_temp2; + } + } + else if (long_index != 0) + { + charptr_temp = &charptr_temp[long_index >> 3]; + } + + jbi_export_boolean_array(name, charptr_temp, long_count); + + /* free allocated buffer */ + if (((long_index & 7L) != 0) && (charptr_temp2 != NULL)) + { + jbi_free(charptr_temp2); + } + } + break; + + case 0x80: /* COPY */ + /* + * Array copy + * ...argument 0 is dest ID + * ...argument 1 is source ID + * ...stack 0 is count + * ...stack 1 is dest index + * ...stack 2 is source index + */ + IF_CHECK_STACK(3) + { + long copy_count = stack[--stack_ptr]; + long copy_index = stack[--stack_ptr]; + long copy_index2 = stack[--stack_ptr]; + long destleft; + long src_count; + long dest_count; + int src_reverse = 0; + int dest_reverse = 0; + + reverse = 0; + + if (version > 0) + { + /* stack 0 = source right index */ + /* stack 1 = source left index */ + /* stack 2 = destination right index */ + /* stack 3 = destination left index */ + destleft = stack[--stack_ptr]; + + if (copy_count > copy_index) + { + src_reverse = 1; + reverse = 1; + src_count = 1 + copy_count - copy_index; + /* copy_index = source start index */ + } + else + { + src_count = 1 + copy_index - copy_count; + copy_index = copy_count; /* source start index */ + } + + if (copy_index2 > destleft) + { + dest_reverse = 1; + reverse = !reverse; + dest_count = 1 + copy_index2 - destleft; + copy_index2 = destleft; /* destination start index */ + } + else + { + dest_count = 1 + destleft - copy_index2; + /* copy_index2 = destination start index */ + } + + copy_count = (src_count < dest_count) ? src_count : dest_count; + + if ((src_reverse || dest_reverse) && + (src_count != dest_count)) + { + /* If either the source or destination is reversed, */ + /* we can't tolerate a length mismatch, because we */ + /* "left justify" the arrays when copying. This */ + /* won't work correctly with reversed arrays. */ + status = JBIC_BOUNDS_ERROR; + } + } + + count = (unsigned int) copy_count; + index = (unsigned int) copy_index; + index2 = (unsigned int) copy_index2; + + /* + * If destination is a read-only array, allocate a buffer + * and convert it to a writable array + */ + variable_id = (unsigned int) args[1]; + if ((version > 0) && ((attributes[variable_id] & 0x9c) == 0x0c)) + { + /* + * Allocate a writable buffer for this array + */ + long_temp = (variable_size[variable_id] + 7L) >> 3L; + charptr_temp2 = (unsigned char *) variables[variable_id]; + charptr_temp = jbi_malloc((unsigned int) long_temp); + variables[variable_id] = (addr_t) charptr_temp; + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + /* zero the buffer */ + for (long_index = 0L; + long_index < long_temp; + ++long_index) + { + charptr_temp[long_index] = 0; + } + + /* copy previous contents into buffer */ + for (long_index = 0L; + long_index < variable_size[variable_id]; + ++long_index) + { +#if PORT==DOS + if ((attributes[variable_id] & 0x02) && + ((long_index & 0x0000FFFF) == 0L)) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + charptr_temp = jbi_aca_out_buffer; + long_index2 = long_index & 0xFFFF; + } +#else + long_index2 = long_index; +#endif + + if (charptr_temp2[long_index2 >> 3] & + (1 << (long_index2 & 7))) + { + charptr_temp[long_index >> 3] |= + (1 << (long_index & 7)); + } + } + + /* set bit 7 - buffer was dynamically allocated */ + attributes[variable_id] |= 0x80; + + /* clear bit 2 - variable is writable */ + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } + } + +#if PORT==DOS + /* for 16-bit version, allow writing in allocated buffers */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x8c)) + { + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } +#endif + + charptr_temp = (unsigned char *) variables[args[1]]; + charptr_temp2 = (unsigned char *) variables[args[0]]; + +#if PORT==DOS + variable_id = (unsigned int) args[0]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (copy_index >> 16), version); + charptr_temp2 = jbi_aca_out_buffer; + } +#endif + + /* check that destination is a writable Boolean array */ + if ((attributes[args[1]] & 0x1c) != 0x08) + { + status = JBIC_BOUNDS_ERROR; + break; + } + + if (count < 1) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + if (reverse) + { + index2 += (count - 1); + } + + for (i = 0; i < count; ++i) + { + if (charptr_temp2[index >> 3] & (1 << (index & 7))) + { + charptr_temp[index2 >> 3] |= (1 << (index2 & 7)); + } + else + { + charptr_temp[index2 >> 3] &= + ~(unsigned int) (1 << (index2 & 7)); + } + ++index; + if (reverse) --index2; else ++index2; + } + } + } + break; + + case 0x81: /* REVA */ + /* + * ARRAY COPY reversing bit order + * ...argument 0 is dest ID + * ...argument 1 is source ID + * ...stack 0 is dest index + * ...stack 1 is source index + * ...stack 2 is count + */ + bad_opcode = 1; + break; + + case 0x82: /* DSC */ + case 0x83: /* ISC */ + /* + * DRSCAN with capture + * IRSCAN with capture + * ...argument 0 is scan data variable ID + * ...argument 1 is capture variable ID + * ...stack 0 is capture index + * ...stack 1 is scan data index + * ...stack 2 is count + */ + IF_CHECK_STACK(3) + { + long scan_right, scan_left; + long capture_count = 0; + long scan_count = 0; + long capture_index = stack[--stack_ptr]; + long scan_index = stack[--stack_ptr]; + if (version > 0) + { + /* stack 0 = capture right index */ + /* stack 1 = capture left index */ + /* stack 2 = scan right index */ + /* stack 3 = scan left index */ + /* stack 4 = count */ + scan_right = stack[--stack_ptr]; + scan_left = stack[--stack_ptr]; + capture_count = 1 + scan_index - capture_index; + scan_count = 1 + scan_left - scan_right; + scan_index = scan_right; + } + long_count = stack[--stack_ptr]; + + /* + * If capture array is read-only, allocate a buffer + * and convert it to a writable array + */ + variable_id = (unsigned int) args[1]; + if ((version > 0) && ((attributes[variable_id] & 0x9c) == 0x0c)) + { + /* + * Allocate a writable buffer for this array + */ + long_temp = (variable_size[variable_id] + 7L) >> 3L; + charptr_temp2 = (unsigned char *) variables[variable_id]; + charptr_temp = jbi_malloc((unsigned int) long_temp); + variables[variable_id] = (addr_t) charptr_temp; + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + /* zero the buffer */ + for (long_index = 0L; + long_index < long_temp; + ++long_index) + { + charptr_temp[long_index] = 0; + } + + /* copy previous contents into buffer */ + for (long_index = 0L; + long_index < variable_size[variable_id]; + ++long_index) + { +#if PORT==DOS + if ((attributes[variable_id] & 0x02) && + ((long_index & 0x0000FFFF) == 0L)) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + charptr_temp = jbi_aca_out_buffer; + long_index2 = long_index & 0xFFFF; + } +#else + long_index2 = long_index; +#endif + + if (charptr_temp2[long_index2 >> 3] & + (1 << (long_index2 & 7))) + { + charptr_temp[long_index >> 3] |= + (1 << (long_index & 7)); + } + } + + /* set bit 7 - buffer was dynamically allocated */ + attributes[variable_id] |= 0x80; + + /* clear bit 2 - variable is writable */ + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } + } + +#if PORT==DOS + /* for 16-bit version, allow writing in allocated buffers */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x8c)) + { + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } +#endif + + charptr_temp = (unsigned char *) variables[args[0]]; + charptr_temp2 = (unsigned char *) variables[args[1]]; + +#if PORT==DOS + variable_id = (unsigned int) args[0]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (scan_index >> 16), version); + scan_index &= 0x0000ffff; + charptr_temp = jbi_aca_out_buffer; + } +#endif + + if ((version > 0) && + ((long_count > capture_count) || (long_count > scan_count))) + { + status = JBIC_BOUNDS_ERROR; + } + + /* check that capture array is a writable Boolean array */ + if ((attributes[args[1]] & 0x1c) != 0x08) + { + status = JBIC_BOUNDS_ERROR; + } + + if (status == JBIC_SUCCESS) + { + if (opcode == 0x82) /* DSC */ + { + status = jbi_swap_dr((unsigned int) long_count, + charptr_temp, (unsigned long) scan_index, + charptr_temp2, (unsigned int) capture_index); + } + else /* ISC */ + { + status = jbi_swap_ir((unsigned int) long_count, + charptr_temp, (unsigned int) scan_index, + charptr_temp2, (unsigned int) capture_index); + } + } + } + break; + + case 0x84: /* WAIT */ + /* + * WAIT + * ...argument 0 is wait state + * ...argument 1 is end state + * ...stack 0 is cycles + * ...stack 1 is microseconds + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + + if (long_temp != 0L) + { + status = jbi_do_wait_cycles(long_temp, (unsigned int) args[0]); + } + + long_temp = stack[--stack_ptr]; + + if ((status == JBIC_SUCCESS) && (long_temp != 0L)) + { + status = jbi_do_wait_microseconds(long_temp, (unsigned int) args[0]); + } + + if ((status == JBIC_SUCCESS) && (args[1] != args[0])) + { + status = jbi_goto_jtag_state((unsigned int) args[1]); + } + + if (version > 0) + { + --stack_ptr; /* throw away MAX cycles */ + --stack_ptr; /* throw away MAX microseconds */ + } + } + break; + + case 0x85: /* VS */ + /* + * VECTOR + * ...argument 0 is dir data variable ID + * ...argument 1 is scan data variable ID + * ...stack 0 is dir array index + * ...stack 1 is scan array index + * ...stack 2 is count + */ + bad_opcode = 1; + break; + + case 0xC0: /* CMPA */ + /* + * Array compare + * ...argument 0 is source 1 ID + * ...argument 1 is source 2 ID + * ...argument 2 is mask ID + * ...stack 0 is source 1 index + * ...stack 1 is source 2 index + * ...stack 2 is mask index + * ...stack 3 is count + */ + IF_CHECK_STACK(4) + { + long a, b; + unsigned char *source1 = (unsigned char *) variables[args[0]]; + unsigned char *source2 = (unsigned char *) variables[args[1]]; + unsigned char *mask = (unsigned char *) variables[args[2]]; + unsigned long index1 = stack[--stack_ptr]; + unsigned long index2 = stack[--stack_ptr]; + unsigned long mask_index = stack[--stack_ptr]; + long_count = stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = source 1 right index */ + /* stack 1 = source 1 left index */ + /* stack 2 = source 2 right index */ + /* stack 3 = source 2 left index */ + /* stack 4 = mask right index */ + /* stack 5 = mask left index */ + long mask_right = stack[--stack_ptr]; + long mask_left = stack[--stack_ptr]; + a = 1 + index2 - index1; /* source 1 count */ + b = 1 + long_count - mask_index; /* source 2 count */ + a = (a < b) ? a : b; + b = 1 + mask_left - mask_right; /* mask count */ + a = (a < b) ? a : b; + index2 = mask_index; /* source 2 start index */ + mask_index = mask_right; /* mask start index */ + long_count = a; + } + + long_temp = 1L; + + if (long_count < 1) + { + status = JBIC_BOUNDS_ERROR; + } + else + { +#if PORT==DOS + variable_id = (unsigned int) args[0]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + jbi_uncompress_page(variable_id, + (int) (index1 >> 16), version); + index1 &= 0x0000ffff; + source1 = jbi_aca_out_buffer; + } + + variable_id = (unsigned int) args[1]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + jbi_uncompress_page(variable_id, + (int) (index2 >> 16), version); + index2 &= 0x0000ffff; + source2 = jbi_aca_out_buffer; + } +#endif + count = (unsigned int) long_count; + + for (i = 0; i < count; ++i) + { + if (mask[mask_index >> 3] & (1 << (mask_index & 7))) + { + a = source1[index1 >> 3] & (1 << (index1 & 7)) + ? 1 : 0; + b = source2[index2 >> 3] & (1 << (index2 & 7)) + ? 1 : 0; + + if (a != b) long_temp = 0L; /* failure */ + } + ++index1; + ++index2; + ++mask_index; + } + } + + stack[stack_ptr++] = long_temp; + } + break; + + case 0xC1: /* VSC */ + /* + * VECTOR with capture + * ...argument 0 is dir data variable ID + * ...argument 1 is scan data variable ID + * ...argument 2 is capture variable ID + * ...stack 0 is capture index + * ...stack 1 is scan data index + * ...stack 2 is dir data index + * ...stack 3 is count + */ + bad_opcode = 1; + break; + + default: + /* + * Unrecognized opcode -- ERROR! + */ + bad_opcode = 1; + break; + } + + if (bad_opcode) + { + status = JBIC_ILLEGAL_OPCODE; + } + + if ((stack_ptr < 0) || (stack_ptr >= JBI_STACK_SIZE)) + { + status = JBIC_STACK_OVERFLOW; + } + + if (status != JBIC_SUCCESS) + { + done = 1; + *error_address = (long) (opcode_address - code_section); + } + } + jbi_dbg(DEBUG_DETAIL, "debug_cnt(total): 0x%lx\n", debug_cnt); + + jbi_dbg(DEBUG_NOISY, "jbi_free_jtag_padding_buffers\n"); + jbi_free_jtag_padding_buffers(reset_jtag); + + /* + * Free all dynamically allocated arrays + */ + jbi_dbg(DEBUG_NOISY, "jbi_free_attributes\n"); + if ((attributes != NULL) && (variables != NULL)) + { + for (i = 0; i < (unsigned int) symbol_count; ++i) + { + if ((attributes[i] & 0x80) && (variables[i] != (addr_t) NULL) + && (variables[i] != (addr_t) 1)) + { + jbi_free((void *) variables[i]); + } + } + } + + if (variables != NULL) jbi_free(variables); + + if (variable_size != NULL) jbi_free(variable_size); + + if (attributes != NULL) jbi_free(attributes); + + if (proc_attributes != NULL) jbi_free(proc_attributes); + + jbi_dbg(DEBUG_NOISY, "return status %d\n", status); + kfree(message_buffer); + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_get_note +( + PROGRAM_PTR program, + long program_size, + long *offset, + char *key, + char *value, + int length +) + +/* */ +/* Description: Gets key and value of NOTE fields in the JBC file. */ +/* Can be called in two modes: if offset pointer is NULL, */ +/* then the function searches for note fields which match */ +/* the key string provided. If offset is not NULL, then */ +/* the function finds the next note field of any key, */ +/* starting at the offset specified by the offset pointer. */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_UNEXPECTED_END; + unsigned long note_strings = 0L; + unsigned long note_table = 0L; + unsigned long note_count = 0L; + unsigned long first_word = 0L; + int version = 0; + int delta = 0; + char *key_ptr; + char *value_ptr; + int i; + +#if PORT==DOS + int count = 0; + int done = 0; + long long_index = 0; + char key_buffer[256]; + char value_buffer[256]; + + jbi_program = program; +#endif + + /* + * Read header information + */ + if (program_size > 52L) + { + first_word = GET_DWORD(0); + version = (int) (first_word & 1L); + delta = version * 8; + + note_strings = GET_DWORD(8 + delta); + note_table = GET_DWORD(12 + delta); + note_count = GET_DWORD(44 + (2 * delta)); + } + + if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) + { + status = JBIC_IO_ERROR; + } + else if (note_count > 0L) + { + if (offset == NULL) + { + /* + * We will search for the first note with a specific key, and + * return only the value + */ + for (i = 0; (i < (int) note_count) && (status != JBIC_SUCCESS); ++i) + { +#if PORT==DOS + done = 0; + count = 0; + long_index = note_strings + GET_DWORD(note_table + (8 * i)); + while ((count < 255) && !done) + { + key_buffer[count] = GET_BYTE(long_index); + if (key_buffer[count] == '\0') done = 1; + ++long_index; + ++count; + } + key_buffer[255] = '\0'; + key_ptr = key_buffer; +#else + key_ptr = (char *) &program[note_strings + + GET_DWORD(note_table + (8 * i))]; +#endif + if ((key != NULL) && (jbi_stricmp(key, key_ptr) == 0)) + { + status = JBIC_SUCCESS; + +#if PORT==DOS + done = 0; + count = 0; + long_index = note_strings + GET_DWORD(note_table + (8 * i) + 4); + while ((count < 255) && !done) + { + value_buffer[count] = GET_BYTE(long_index); + if (value_buffer[count] == '\0') done = 1; + ++long_index; + ++count; + } + value_buffer[255] = '\0'; + value_ptr = value_buffer; +#else + value_ptr = (char *) &program[note_strings + + GET_DWORD(note_table + (8 * i) + 4)]; +#endif + + if (value != NULL) + { + jbi_strncpy(value, value_ptr, length); + } + } + } + } + else + { + /* + * We will search for the next note, regardless of the key, and + * return both the value and the key + */ + + i = (int) *offset; + + if ((i >= 0) && (i < (int) note_count)) + { + status = JBIC_SUCCESS; + + if (key != NULL) + { +#if PORT==DOS + done = 0; + count = 0; + long_index = note_strings + + GET_DWORD(note_table + (8 * i)); + + while ((count < length) && !done) + { + key[count] = GET_BYTE(long_index); + if (key[count] == '\0') done = 1; + ++long_index; + ++count; + } +#else + jbi_strncpy(key, (char *) &program[note_strings + + GET_DWORD(note_table + (8 * i))], length); +#endif + } + + if (value != NULL) + { +#if PORT==DOS + done = 0; + count = 0; + long_index = note_strings + + GET_DWORD(note_table + (8 * i) + 4); + + while ((count < length) && !done) + { + value[count] = GET_BYTE(long_index); + if (value[count] == '\0') done = 1; + ++long_index; + ++count; + } +#else + jbi_strncpy(value, (char *) &program[note_strings + + GET_DWORD(note_table + (8 * i) + 4)], length); +#endif + } + + *offset = i + 1; + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_check_crc +( + PROGRAM_PTR program, + long program_size, + unsigned short *expected_crc, + unsigned short *actual_crc +) + +/* */ +/* Description: This function reads the entire input file and computes */ +/* the CRC of everything up to the CRC field. */ +/* */ +/* Returns: JBIC_SUCCESS for success, JBIC_CRC_ERROR for failure */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned short local_expected, local_actual, shift_reg = 0xffff; + int bit, feedback; + unsigned char databyte; + unsigned long i; + unsigned long crc_section = 0L; + unsigned long first_word = 0L; + int version = 0; + int delta = 0; + +#if PORT==DOS + jbi_program = program; +#endif + + if (program_size > 52L) + { + first_word = GET_DWORD(0); + version = (int) (first_word & 1L); + delta = version * 8; + + crc_section = GET_DWORD(32 + delta); + } + + if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) + { + status = JBIC_IO_ERROR; + } + + if (crc_section >= (unsigned long) program_size) + { + status = JBIC_IO_ERROR; + } + + if (status == JBIC_SUCCESS) + { + local_expected = (unsigned short) GET_WORD(crc_section); + if (expected_crc != NULL) *expected_crc = local_expected; + + for (i = 0; i < crc_section; ++i) + { + databyte = GET_BYTE(i); + for (bit = 0; bit < 8; bit++) /* compute for each bit */ + { + feedback = (databyte ^ shift_reg) & 0x01; + shift_reg >>= 1; /* shift the shift register */ + if (feedback) shift_reg ^= 0x8408; /* invert selected bits */ + databyte >>= 1; /* get the next bit of input_byte */ + } + } + + local_actual = (unsigned short) ~shift_reg; + if (actual_crc != NULL) *actual_crc = local_actual; + + if (local_expected != local_actual) + { + status = JBIC_CRC_ERROR; + } + } + + return (status); +} + +JBI_RETURN_TYPE jbi_get_file_info +( + PROGRAM_PTR program, + long program_size, + int *format_version, + int *action_count, + int *procedure_count +) +{ + JBI_RETURN_TYPE status = JBIC_IO_ERROR; + unsigned long first_word = 0; + int version = 0; + +#if PORT==DOS + jbi_program = program; +#endif + + /* + * Read header information + */ + if (program_size > 52L) + { + first_word = GET_DWORD(0); + + if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) + { + status = JBIC_SUCCESS; + + version = (int) (first_word & 1L); + *format_version = version + 1; + + if (version > 0) + { + *action_count = (int) GET_DWORD(48); + *procedure_count = (int) GET_DWORD(52); + } + } + + } + + return (status); +} + +JBI_RETURN_TYPE jbi_get_action_info +( + PROGRAM_PTR program, + long program_size, + int index, + char **name, + char **description, + JBI_PROCINFO **procedure_list +) +{ + JBI_RETURN_TYPE status = JBIC_IO_ERROR; + JBI_PROCINFO *procptr = NULL; + JBI_PROCINFO *tmpptr = NULL; + unsigned long first_word = 0L; + unsigned long action_table = 0L; + unsigned long proc_table = 0L; + unsigned long string_table = 0L; + unsigned long note_strings = 0L; + unsigned long action_count = 0L; + unsigned long proc_count = 0L; + unsigned long act_name_id = 0L; + unsigned long act_desc_id = 0L; + unsigned long act_proc_id = 0L; + unsigned long act_proc_name = 0L; + unsigned char act_proc_attribute = 0; + +#if PORT==DOS + int i, length; + jbi_program = program; +#endif + + /* + * Read header information + */ + if (program_size > 52L) + { + first_word = GET_DWORD(0); + + if (first_word == 0x4A414D01L) + { + action_table = GET_DWORD(4); + proc_table = GET_DWORD(8); + string_table = GET_DWORD(12); + note_strings = GET_DWORD(16); + action_count = GET_DWORD(48); + proc_count = GET_DWORD(52); + + if (index < (int) action_count) + { + act_name_id = GET_DWORD(action_table + (12 * index)); + act_desc_id = GET_DWORD(action_table + (12 * index) + 4); + act_proc_id = GET_DWORD(action_table + (12 * index) + 8); + +#if PORT==DOS + length = 0; + while (GET_BYTE(string_table + act_name_id + length) != 0) ++length; + *name = jbi_malloc(length + 1); + if (*name == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + for (i = 0; i < length; ++i) + { + (*name)[i] = GET_BYTE(string_table + act_name_id + i); + } + (*name)[length] = '\0'; + } +#else + *name = (char *) &program[string_table + act_name_id]; +#endif + + if (act_desc_id < (note_strings - string_table)) + { +#if PORT==DOS + length = 0; + while (GET_BYTE(string_table + act_desc_id + length) != 0) ++length; + *description = jbi_malloc(length + 1); + if (*description == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + for (i = 0; i < length; ++i) + { + (*description)[i] = GET_BYTE(string_table + act_desc_id + i); + } + (*description)[length] = '\0'; + } +#else + *description = (char *) &program[string_table + act_desc_id]; +#endif + } + + do + { + act_proc_name = GET_DWORD(proc_table + (13 * act_proc_id)); + act_proc_attribute = (unsigned char) + (GET_BYTE(proc_table + (13 * act_proc_id) + 8) & 0x03); + + procptr = (JBI_PROCINFO *) jbi_malloc(sizeof(JBI_PROCINFO)); + + if (procptr == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { +#if PORT==DOS + length = 0; + while (GET_BYTE(string_table + act_proc_name + length) != 0) ++length; + procptr->name = jbi_malloc(length + 1); + if (procptr->name == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + for (i = 0; i < length; ++i) + { + procptr->name[i] = + GET_BYTE(string_table + act_proc_name + i); + } + procptr->name[length] = '\0'; + } +#else + procptr->name = (char *) + &program[string_table + act_proc_name]; +#endif + procptr->attributes = act_proc_attribute; + procptr->next = NULL; + + /* add record to end of linked list */ + if (*procedure_list == NULL) + { + *procedure_list = procptr; + } + else + { + tmpptr = *procedure_list; + while (tmpptr->next != NULL) tmpptr = tmpptr->next; + tmpptr->next = procptr; + } + } + + act_proc_id = + GET_DWORD(proc_table + (13 * act_proc_id) + 4); + } + while ((act_proc_id != 0) && (act_proc_id < proc_count)); + } + } + + } + + return (status); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiport.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiport.h new file mode 100644 index 000000000000..28669dc81ff6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiport.h @@ -0,0 +1,45 @@ +/****************************************************************************/ +/* */ +/* Module: jbiport.h */ +/* */ +/* Copyright (C) Altera Corporation 2000-2001 */ +/* */ +/* Description: Defines porting macros */ +/* */ +/****************************************************************************/ + +#ifndef INC_JBIPORT_H +#define INC_JBIPORT_H + +/* +* PORT defines the target platform: DOS, WINDOWS, UNIX, or EMBEDDED +* +* PORT = DOS means a 16-bit DOS console-mode application +* +* PORT = WINDOWS means a 32-bit WIN32 console-mode application for +* Windows 95, 98, 2000, ME or NT. On NT this will use the +* DeviceIoControl() API to access the Parallel Port. +* +* PORT = UNIX means any UNIX system. BitBlaster access is support via +* the standard ANSI system calls open(), read(), write(). +* The ByteBlaster is not supported. +* +* PORT = EMBEDDED means all DOS, WINDOWS, and UNIX code is excluded. +* Remaining code supports 16 and 32-bit compilers. +* Additional porting steps may be necessary. See readme +* file for more details. +*/ + +#define DOS 2 +#define WINDOWS 3 +#define UNIX 4 +#define EMBEDDED 5 + +#define PORT EMBEDDED + +#ifndef PORT +/* change this line to build a different port */ +#define PORT WINDOWS +#endif + +#endif /* INC_JBIPORT_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.c new file mode 100644 index 000000000000..396c92caca2b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.c @@ -0,0 +1,2518 @@ +/****************************************************************************/ +/* */ +/* Module: jbistub.c */ +/* */ +/* Copyright (C) Altera Corporation 1997-2001 */ +/* */ +/* Description: Jam STAPL ByteCode Player main source file */ +/* */ +/* Supports Altera ByteBlaster hardware download cable */ +/* on Windows 95 and Windows NT operating systems. */ +/* (A device driver is required for Windows NT.) */ +/* */ +/* Also supports BitBlaster hardware download cable on */ +/* Windows 95, Windows NT, and UNIX platforms. */ +/* */ +/* Revisions: 1.1 fixed control port initialization for ByteBlaster */ +/* 2.0 added support for STAPL bytecode format, added code */ +/* to get printer port address from Windows registry */ +/* 2.1 improved messages, fixed delay-calibration bug in */ +/* 16-bit DOS port, added support for "alternative */ +/* cable X", added option to control whether to reset */ +/* the TAP after execution, moved porting macros into */ +/* jbiport.h */ +/* 2.2 added support for static memory */ +/* fixed /W4 warnings */ +/* */ +/****************************************************************************/ + +#ifndef NO_ALTERA_STDIO +#define NO_ALTERA_STDIO +#endif + +#if 0 +#if ( _MSC_VER >= 800 ) +#pragma warning(disable:4115) +#pragma warning(disable:4201) +#pragma warning(disable:4214) +#pragma warning(disable:4514) +#endif +#endif + +#include "jbiport.h" + +#if PORT == WINDOWS +#include +#else +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +#if PORT == EMBEDDED +typedef unsigned int DWORD; +#else +typedef unsigned long DWORD; +#endif +#define TRUE 1 +#define FALSE 0 +#endif + +#if PORT != EMBEDDED +#include +#include +#include +#include +#include +#include +#endif + +#include + +#include "jbiexprt.h" +#include "jbistub.h" + +#if defined(USE_STATIC_MEMORY) + #define N_STATIC_MEMORY_KBYTES ((unsigned int) USE_STATIC_MEMORY) + #define N_STATIC_MEMORY_BYTES (N_STATIC_MEMORY_KBYTES * 1024) + #define POINTER_ALIGNMENT sizeof(DWORD) +#else /* USE_STATIC_MEMORY */ + /* #include */ + #define POINTER_ALIGNMENT sizeof(BYTE) +#endif /* USE_STATIC_MEMORY */ + +#if PORT != EMBEDDED +#include +#include +#include +#include +#include +#endif + +#if PORT == DOS +#include +#endif + +int jbi_debug_level = DEBUG_NONE; +static long jbi_delay_us = 0, jbi_delay_count = 0, jbi_peak_us = 0; + +void __jbi_jtag_udelay(unsigned long us) +{ + udelay(us); +} +void jbi_jtag_udelay(unsigned long us) __attribute__((weak, alias("__jbi_jtag_udelay"))); + +#if PORT == WINDOWS +#define PGDC_IOCTL_GET_DEVICE_INFO_PP 0x00166A00L +#define PGDC_IOCTL_READ_PORT_PP 0x00166A04L +#define PGDC_IOCTL_WRITE_PORT_PP 0x0016AA08L +#define PGDC_IOCTL_PROCESS_LIST_PP 0x0016AA1CL +#define PGDC_READ_INFO 0x0a80 +#define PGDC_READ_PORT 0x0a81 +#define PGDC_WRITE_PORT 0x0a82 +#define PGDC_PROCESS_LIST 0x0a87 +#define PGDC_HDLC_NTDRIVER_VERSION 2 +#define PORT_IO_BUFFER_SIZE 256 +#endif + +#if PORT == WINDOWS +#ifdef __BORLANDC__ +/* create dummy inp() and outp() functions for Borland 32-bit compile */ +WORD inp(WORD address) { address = address; return(0); } +void outp(WORD address, WORD data) { address = address; data = data; } +#else +#pragma intrinsic (inp, outp) +#endif +#endif + +/* +* For Borland C compiler (16-bit), set the stack size +*/ +#if PORT == DOS +#ifdef __BORLANDC__ +extern unsigned int _stklen = 50000; +#endif +#endif + +/************************************************************************ +* +* Global variables +*/ + +/* file buffer for Jam STAPL ByteCode input file */ +#if PORT == DOS +unsigned char **file_buffer = NULL; +#else +unsigned char *file_buffer = NULL; +#endif +long file_pointer = 0L; +long file_length = 0L; + +/* delay count for one millisecond delay */ +long one_ms_delay = 0L; + +/* serial port interface available on all platforms */ +BOOL jtag_hardware_initialized = FALSE; +char *serial_port_name = NULL; +BOOL specified_com_port = FALSE; +int com_port = -1; +void initialize_jtag_hardware(void); +void close_jtag_hardware(void); + +#if defined(USE_STATIC_MEMORY) + unsigned char static_memory_heap[N_STATIC_MEMORY_BYTES] = { 0 }; +#endif /* USE_STATIC_MEMORY */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + unsigned int n_bytes_allocated = 0; +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(MEM_TRACKER) + unsigned int peak_memory_usage = 0; + unsigned int peak_allocations = 0; + unsigned int n_allocations = 0; +#if defined(USE_STATIC_MEMORY) + unsigned int n_bytes_not_recovered = 0; +#endif /* USE_STATIC_MEMORY */ + const DWORD BEGIN_GUARD = 0x01234567; + const DWORD END_GUARD = 0x76543210; +#endif /* MEM_TRACKER */ + +#if PORT == WINDOWS || PORT == DOS +/* parallel port interface available on PC only */ +BOOL specified_lpt_port = FALSE; +BOOL specified_lpt_addr = FALSE; +int lpt_port = 1; +int initial_lpt_ctrl = 0; +WORD lpt_addr = 0x3bc; +WORD lpt_addr_table[3] = { 0x3bc, 0x378, 0x278 }; +BOOL alternative_cable_l = FALSE; +BOOL alternative_cable_x = FALSE; +void write_byteblaster(int port, int data); +int read_byteblaster(int port); +#endif + +#if PORT==WINDOWS +#ifndef __BORLANDC__ +WORD lpt_addresses_from_registry[4] = { 0 }; +#endif +#endif + +#if PORT == WINDOWS +/* variables to manage cached I/O under Windows NT */ +BOOL windows_nt = FALSE; +int port_io_count = 0; +HANDLE nt_device_handle = INVALID_HANDLE_VALUE; +struct PORT_IO_LIST_STRUCT +{ + USHORT command; + USHORT data; +} port_io_buffer[PORT_IO_BUFFER_SIZE]; +extern void flush_ports(void); +BOOL initialize_nt_driver(void); +#endif + +/* function prototypes to allow forward reference */ +extern void delay_loop(long count); + +/* +* This structure stores information about each available vector signal +*/ +struct VECTOR_LIST_STRUCT +{ + char *signal_name; + int hardware_bit; + int vector_index; +}; + +struct VECTOR_LIST_STRUCT vector_list[] = +{ + /* add a record here for each vector signal */ + { "", 0, -1 } +}; + +#define VECTOR_SIGNAL_COUNT ((int)(sizeof(vector_list)/sizeof(vector_list[0]))) + +BOOL verbose = FALSE; + +/************************************************************************ +* +* Customized interface functions for Jam STAPL ByteCode Player I/O: +* +* jbi_jtag_io() +* jbi_message() +* jbi_delay() +*/ + +int jbi_jtag_io(int tms, int tdi, int read_tdo) +{ +#if PORT == WINDOWS || PORT == DOS + int data = 0; +#endif + int tdo = 0; + int i = 0; + int result = 0; + char ch_data = 0; + + if (!jtag_hardware_initialized) + { + initialize_jtag_hardware(); + jtag_hardware_initialized = TRUE; + } + + if (specified_com_port) + { + ch_data = (char) + ((tdi ? 0x01 : 0) | (tms ? 0x02 : 0) | 0x60); + + write(com_port, &ch_data, 1); + + if (read_tdo) + { + ch_data = 0x7e; + write(com_port, &ch_data, 1); + for (i = 0; (i < 100) && (result != 1); ++i) + { + result = read(com_port, &ch_data, 1); + } + if (result == 1) + { + tdo = ch_data & 0x01; + } + else + { + fprintf(stderr, "Error: BitBlaster not responding\n"); + } + } + + ch_data = (char) + ((tdi ? 0x01 : 0) | (tms ? 0x02 : 0) | 0x64); + + write(com_port, &ch_data, 1); + } + else + { +#if PORT == WINDOWS || PORT == DOS + data = (alternative_cable_l ? ((tdi ? 0x01 : 0) | (tms ? 0x04 : 0)) : + (alternative_cable_x ? ((tdi ? 0x01 : 0) | (tms ? 0x04 : 0) | 0x10) : + ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0)))); + + write_byteblaster(0, data); + + if (read_tdo) + { + tdo = read_byteblaster(1); + tdo = (alternative_cable_l ? ((tdo & 0x40) ? 1 : 0) : + (alternative_cable_x ? ((tdo & 0x10) ? 1 : 0) : + ((tdo & 0x80) ? 0 : 1))); + } + + write_byteblaster(0, data | (alternative_cable_l ? 0x02 : (alternative_cable_x ? 0x02: 0x01))); + + write_byteblaster(0, data); +#elif PORT == EMBEDDED + /* Output variables TDI, TMS to the corresponding pin; As read_tdo, return the corresponding pin to the variable tdo */ + tdo = jbi_jtag_io_(tms, tdi, read_tdo); +#else + /* parallel port interface not available */ + tdo = 0; +#endif + } + + return (tdo); +} + +void jbi_message(char *message_text) +{ + puts(message_text); + puts("\n"); + fflush(stdout); +} + +void jbi_export_integer(char *key, long value) +{ + if (verbose) + { + printf("Export: key = \"%s\", value = %ld\n", key, value); + fflush(stdout); + } +} + +#define HEX_LINE_CHARS 72 +#define HEX_LINE_BITS (HEX_LINE_CHARS * 4) + +char conv_to_hex(unsigned long value) +{ + char c; + + if (value > 9) + { + c = (char) (value + ('A' - 10)); + } + else + { + c = (char) (value + '0'); + } + + return (c); +} + +void jbi_export_boolean_array(char *key, unsigned char *data, long count) +{ + char string[HEX_LINE_CHARS + 1]; + long i, offset; + unsigned long size, line, lines, linebits, value, j, k; + + if (verbose) + { + if (count > HEX_LINE_BITS) + { + printf("Export: key = \"%s\", %ld bits, value = HEX\n", key, count); + lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS; + + for (line = 0; line < lines; ++line) + { + if (line < (lines - 1)) + { + linebits = HEX_LINE_BITS; + size = HEX_LINE_CHARS; + offset = count - ((line + 1) * HEX_LINE_BITS); + } + else + { + linebits = count - ((lines - 1) * HEX_LINE_BITS); + size = (linebits + 3) / 4; + offset = 0L; + } + + string[size] = '\0'; + j = size - 1; + value = 0; + + for (k = 0; k < linebits; ++k) + { + i = k + offset; + if (data[i >> 3] & (1 << (i & 7))) value |= (1 << (i & 3)); + if ((i & 3) == 3) + { + string[j] = conv_to_hex(value); + value = 0; + --j; + } + } + if ((k & 3) > 0) string[j] = conv_to_hex(value); + + printf("%s\n", string); + } + + fflush(stdout); + } + else + { + size = (count + 3) / 4; + string[size] = '\0'; + j = size - 1; + value = 0; + + for (i = 0; i < count; ++i) + { + if (data[i >> 3] & (1 << (i & 7))) value |= (1 << (i & 3)); + if ((i & 3) == 3) + { + string[j] = conv_to_hex(value); + value = 0; + --j; + } + } + if ((i & 3) > 0) string[j] = conv_to_hex(value); + + printf("Export: key = \"%s\", %ld bits, value = HEX %s\n", + key, count, string); + fflush(stdout); + } + } +} + +void jbi_delay(long microseconds) +{ + if (jbi_peak_us < microseconds) { + jbi_peak_us = microseconds; + } + jbi_delay_us += microseconds; + jbi_delay_count++; + +#if PORT == WINDOWS + /* if Windows NT, flush I/O cache buffer before delay loop */ + if (windows_nt && (port_io_count > 0)) flush_ports(); +#endif + +#if PORT == EMBEDDED + udelay(microseconds); +#else + delay_loop(microseconds * + ((one_ms_delay / 1000L) + ((one_ms_delay % 1000L) ? 1 : 0))); +#endif +} + +int jbi_vector_map +( + int signal_count, + char **signals +) +{ + int signal, vector, ch_index, diff; + int matched_count = 0; + char l, r; + + for (vector = 0; (vector < VECTOR_SIGNAL_COUNT); ++vector) + { + vector_list[vector].vector_index = -1; + } + + for (signal = 0; signal < signal_count; ++signal) + { + diff = 1; + for (vector = 0; (diff != 0) && (vector < VECTOR_SIGNAL_COUNT); + ++vector) + { + if (vector_list[vector].vector_index == -1) + { + ch_index = 0; + do + { + l = signals[signal][ch_index]; + r = vector_list[vector].signal_name[ch_index]; + diff = (((l >= 'a') && (l <= 'z')) ? (l - ('a' - 'A')) : l) + - (((r >= 'a') && (r <= 'z')) ? (r - ('a' - 'A')) : r); + ++ch_index; + } + while ((diff == 0) && (l != '\0') && (r != '\0')); + + if (diff == 0) + { + vector_list[vector].vector_index = signal; + ++matched_count; + } + } + } + } + + return (matched_count); +} + +int jbi_vector_io +( + int signal_count, + long *dir_vect, + long *data_vect, + long *capture_vect +) +{ + int signal, vector, bit; + int matched_count = 0; + int data = 0; + int mask = 0; + int dir = 0; + int i = 0; + int result = 0; + char ch_data = 0; + + if (!jtag_hardware_initialized) + { + initialize_jtag_hardware(); + jtag_hardware_initialized = TRUE; + } + + /* + * Collect information about output signals + */ + for (vector = 0; vector < VECTOR_SIGNAL_COUNT; ++vector) + { + signal = vector_list[vector].vector_index; + + if ((signal >= 0) && (signal < signal_count)) + { + bit = (1 << vector_list[vector].hardware_bit); + + mask |= bit; + if (data_vect[signal >> 5] & (1L << (signal & 0x1f))) data |= bit; + if (dir_vect[signal >> 5] & (1L << (signal & 0x1f))) dir |= bit; + + ++matched_count; + } + } + + /* + * Write outputs to hardware interface, if any + */ + if (dir != 0) + { + if (specified_com_port) + { + ch_data = (char) (((data >> 6) & 0x01) | (data & 0x02) | + ((data << 2) & 0x04) | ((data << 3) & 0x08) | 0x60); + write(com_port, &ch_data, 1); + } + else + { +#if PORT == WINDOWS || PORT == DOS + + write_byteblaster(0, data); + +#endif + } + } + + /* + * Read the input signals and save information in capture_vect[] + */ + if ((dir != mask) && (capture_vect != NULL)) + { + if (specified_com_port) + { + ch_data = 0x7e; + write(com_port, &ch_data, 1); + for (i = 0; (i < 100) && (result != 1); ++i) + { + result = read(com_port, &ch_data, 1); + } + if (result == 1) + { + data = ((ch_data << 7) & 0x80) | ((ch_data << 3) & 0x10); + } + else + { + fprintf(stderr, "Error: BitBlaster not responding\n"); + } + } + else + { +#if PORT == WINDOWS || PORT == DOS + + data = read_byteblaster(1) ^ 0x80; /* parallel port inverts bit 7 */ + +#endif + } + + for (vector = 0; vector < VECTOR_SIGNAL_COUNT; ++vector) + { + signal = vector_list[vector].vector_index; + + if ((signal >= 0) && (signal < signal_count)) + { + bit = (1 << vector_list[vector].hardware_bit); + + if ((dir & bit) == 0) /* if it is an input signal... */ + { + if (data & bit) + { + capture_vect[signal >> 5] |= (1L << (signal & 0x1f)); + } + else + { + capture_vect[signal >> 5] &= ~(unsigned long) + (1L << (signal & 0x1f)); + } + } + } + } + } + + return (matched_count); +} + +void *jbi_malloc(unsigned int size) +{ + unsigned int n_bytes_to_allocate = +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + sizeof(unsigned int) + +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ +#if defined(MEM_TRACKER) + (2 * sizeof(DWORD)) + +#endif /* MEM_TRACKER */ + (POINTER_ALIGNMENT * ((size + POINTER_ALIGNMENT - 1) / POINTER_ALIGNMENT)); + + unsigned char *ptr = 0; + +#if defined(MEM_TRACKER) + if ((n_bytes_allocated + n_bytes_to_allocate) > peak_memory_usage) + { + peak_memory_usage = n_bytes_allocated + n_bytes_to_allocate; + } + if ((n_allocations + 1) > peak_allocations) + { + peak_allocations = n_allocations + 1; + } +#endif /* MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) + if ((n_bytes_allocated + n_bytes_to_allocate) <= N_STATIC_MEMORY_BYTES) + { + ptr = (&(static_memory_heap[n_bytes_allocated])); + } +#else /* USE_STATIC_MEMORY */ + ptr = (unsigned char *) malloc(n_bytes_to_allocate); +#endif /* USE_STATIC_MEMORY */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + if (ptr != 0) + { + unsigned int i = 0; + +#if defined(MEM_TRACKER) + for (i = 0; i < sizeof(DWORD); ++i) + { + *ptr = (unsigned char) (BEGIN_GUARD >> (8 * i)); + ++ptr; + } +#endif /* MEM_TRACKER */ + + for (i = 0; i < sizeof(unsigned int); ++i) + { + *ptr = (unsigned char) (size >> (8 * i)); + ++ptr; + } + +#if defined(MEM_TRACKER) + for (i = 0; i < sizeof(DWORD); ++i) + { + *(ptr + size + i) = (unsigned char) (END_GUARD >> (8 * i)); + /* don't increment ptr */ + } + + ++n_allocations; +#endif /* MEM_TRACKER */ + + n_bytes_allocated += n_bytes_to_allocate; + } +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + + jbi_dbg(DEBUG_MM, "malloc 0x%p(%d,%d)\n", ptr, size, n_bytes_to_allocate); + + return ptr; +} + +void jbi_free(void *ptr) +{ + jbi_dbg(DEBUG_MM, "free 0x%p\n", ptr); + + if + ( +#if defined(MEM_TRACKER) + (n_allocations > 0) && +#endif /* MEM_TRACKER */ + (ptr != 0) + ) + { + unsigned char *tmp_ptr = (unsigned char *) ptr; + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + unsigned int n_bytes_to_free = 0; + unsigned int i = 0; + unsigned int size = 0; +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ +#if defined(MEM_TRACKER) + DWORD begin_guard = 0; + DWORD end_guard = 0; + + tmp_ptr -= sizeof(DWORD); +#endif /* MEM_TRACKER */ +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + tmp_ptr -= sizeof(unsigned int); +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + ptr = tmp_ptr; + +#if defined(MEM_TRACKER) + for (i = 0; i < sizeof(DWORD); ++i) + { + begin_guard |= (((DWORD)(*tmp_ptr)) << (8 * i)); + ++tmp_ptr; + } +#endif /* MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + for (i = 0; i < sizeof(unsigned int); ++i) + { + size |= (((unsigned int)(*tmp_ptr)) << (8 * i)); + ++tmp_ptr; + } +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(MEM_TRACKER) + tmp_ptr += size; + + for (i = 0; i < sizeof(DWORD); ++i) + { + end_guard |= (((DWORD)(*tmp_ptr)) << (8 * i)); + ++tmp_ptr; + } + + if ((begin_guard != BEGIN_GUARD) || (end_guard != END_GUARD)) + { + fprintf(stderr, "Error: memory corruption detected for allocation #%d... bad %s guard\n", + n_allocations, (begin_guard != BEGIN_GUARD) ? "begin" : "end"); + } + + --n_allocations; +#endif /* MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + n_bytes_to_free = +#if defined(MEM_TRACKER) + (2 * sizeof(DWORD)) + +#endif /* MEM_TRACKER */ + sizeof(unsigned int) + + (POINTER_ALIGNMENT * ((size + POINTER_ALIGNMENT - 1) / POINTER_ALIGNMENT)); +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) + if ((((unsigned long) ptr - (unsigned long) static_memory_heap) + n_bytes_to_free) == (unsigned long) n_bytes_allocated) + { + n_bytes_allocated -= n_bytes_to_free; + } +#if defined(MEM_TRACKER) + else + { + n_bytes_not_recovered += n_bytes_to_free; + } +#endif /* MEM_TRACKER */ +#else /* USE_STATIC_MEMORY */ +#if defined(MEM_TRACKER) + n_bytes_allocated -= n_bytes_to_free; +#endif /* MEM_TRACKER */ + free(ptr); +#endif /* USE_STATIC_MEMORY */ + } +#if defined(MEM_TRACKER) + else + { + if (ptr != 0) + { + fprintf(stderr, "Error: attempt to free unallocated memory\n"); + } + } +#endif /* MEM_TRACKER */ +} + +#if PORT == WINDOWS || PORT == DOS +/************************************************************************ +* +* get_tick_count() -- Get system tick count in milliseconds +* +* for DOS, use BIOS function _bios_timeofday() +* for WINDOWS use GetTickCount() function +* for UNIX use clock() system function +*/ +DWORD get_tick_count(void) +{ + DWORD tick_count = 0L; + +#if PORT == WINDOWS + tick_count = GetTickCount(); +#elif PORT == DOS + _bios_timeofday(_TIME_GETCLOCK, (long *)&tick_count); + tick_count *= 55L; /* convert to milliseconds */ +#else + /* assume clock() function returns microseconds */ + tick_count = (DWORD) (clock() / 1000L); +#endif + + return (tick_count); +} +#endif + +#define DELAY_SAMPLES 10 +#define DELAY_CHECK_LOOPS 10000 + +void calibrate_delay(void) +{ +#if PORT == WINDOWS || PORT == DOS + int sample = 0; + int count = 0; + DWORD tick_count1 = 0L; + DWORD tick_count2 = 0L; +#endif + + one_ms_delay = 0L; + +#if PORT == WINDOWS || PORT == DOS + for (sample = 0; sample < DELAY_SAMPLES; ++sample) + { + count = 0; + tick_count1 = get_tick_count(); + while ((tick_count2 = get_tick_count()) == tick_count1) {}; + do { delay_loop(DELAY_CHECK_LOOPS); count++; } while + ((tick_count1 = get_tick_count()) == tick_count2); + one_ms_delay += ((DELAY_CHECK_LOOPS * (DWORD)count) / + (tick_count1 - tick_count2)); + } + + one_ms_delay /= DELAY_SAMPLES; +#else + /* This is system-dependent! Update this number for target system */ + one_ms_delay = 1000L; +#endif +} + +char *error_text[] = +{ +/* JBIC_SUCCESS 0 */ "success", +/* JBIC_OUT_OF_MEMORY 1 */ "out of memory", +/* JBIC_IO_ERROR 2 */ "file access error", +/* JAMC_SYNTAX_ERROR 3 */ "syntax error", +/* JBIC_UNEXPECTED_END 4 */ "unexpected end of file", +/* JBIC_UNDEFINED_SYMBOL 5 */ "undefined symbol", +/* JAMC_REDEFINED_SYMBOL 6 */ "redefined symbol", +/* JBIC_INTEGER_OVERFLOW 7 */ "integer overflow", +/* JBIC_DIVIDE_BY_ZERO 8 */ "divide by zero", +/* JBIC_CRC_ERROR 9 */ "CRC mismatch", +/* JBIC_INTERNAL_ERROR 10 */ "internal error", +/* JBIC_BOUNDS_ERROR 11 */ "bounds error", +/* JAMC_TYPE_MISMATCH 12 */ "type mismatch", +/* JAMC_ASSIGN_TO_CONST 13 */ "assignment to constant", +/* JAMC_NEXT_UNEXPECTED 14 */ "NEXT unexpected", +/* JAMC_POP_UNEXPECTED 15 */ "POP unexpected", +/* JAMC_RETURN_UNEXPECTED 16 */ "RETURN unexpected", +/* JAMC_ILLEGAL_SYMBOL 17 */ "illegal symbol name", +/* JBIC_VECTOR_MAP_FAILED 18 */ "vector signal name not found", +/* JBIC_USER_ABORT 19 */ "execution cancelled", +/* JBIC_STACK_OVERFLOW 20 */ "stack overflow", +/* JBIC_ILLEGAL_OPCODE 21 */ "illegal instruction code", +/* JAMC_PHASE_ERROR 22 */ "phase error", +/* JAMC_SCOPE_ERROR 23 */ "scope error", +/* JBIC_ACTION_NOT_FOUND 24 */ "action not found", +}; + +#define MAX_ERROR_CODE (int)(sizeof(error_text)/sizeof(error_text[0])) + +/************************************************************************/ + +#if 0 +int main(int argc, char **argv) +{ + BOOL help = FALSE; + BOOL error = FALSE; + char *filename = NULL; + long offset = 0L; + long error_address = 0L; + JBI_RETURN_TYPE crc_result = JBIC_SUCCESS; + JBI_RETURN_TYPE exec_result = JBIC_SUCCESS; + unsigned short expected_crc = 0; + unsigned short actual_crc = 0; + char key[33] = {0}; + char value[257] = {0}; + int exit_status = 0; + int arg = 0; + int exit_code = 0; + int format_version = 0; + time_t start_time = 0; + time_t end_time = 0; + int time_delta = 0; + char *workspace = NULL; + char *action = NULL; + char *init_list[10]; + int init_count = 0; + FILE *fp = NULL; + struct stat sbuf; + long workspace_size = 0; + char *exit_string = NULL; + int reset_jtag = 1; + int execute_program = 1; + int action_count = 0; + int procedure_count = 0; + int index = 0; + char *action_name = NULL; + char *description = NULL; + JBI_PROCINFO *procedure_list = NULL; + JBI_PROCINFO *procptr = NULL; + + verbose = FALSE; + + init_list[0] = NULL; + + /* print out the version string and copyright message */ + fprintf(stderr, "Jam STAPL ByteCode Player Version 2.2\nCopyright (C) 1998-2001 Altera Corporation\n\n"); + + for (arg = 1; arg < argc; arg++) + { +#if PORT == UNIX + if (argv[arg][0] == '-') +#else + if ((argv[arg][0] == '-') || (argv[arg][0] == '/')) +#endif + { + switch(toupper(argv[arg][1])) + { + case 'A': /* set action name */ + if (action == NULL) + { + action = &argv[arg][2]; + } + else + { + error = TRUE; + } + break; + +#if PORT == WINDOWS || PORT == DOS + case 'C': /* Use alternative ISP download cable */ + if(toupper(argv[arg][2]) == 'L') + alternative_cable_l = TRUE; + else if(toupper(argv[arg][2]) == 'X') + alternative_cable_x = TRUE; + break; +#endif + + case 'D': /* initialization list */ + if (argv[arg][2] == '"') + { + init_list[init_count] = &argv[arg][3]; + } + else + { + init_list[init_count] = &argv[arg][2]; + } + init_list[++init_count] = NULL; + break; + +#if PORT == WINDOWS || PORT == DOS + case 'P': /* set LPT port address */ + specified_lpt_port = TRUE; + if (sscanf(&argv[arg][2], "%d", &lpt_port) != 1) error = TRUE; + if ((lpt_port < 1) || (lpt_port > 3)) error = TRUE; + if (error) + { + if (sscanf(&argv[arg][2], "%x", &lpt_port) == 1) + { + if ((lpt_port == 0x3bc) || + (lpt_port == 0x378) || + (lpt_port == 0x278)) + { + error = FALSE; + specified_lpt_addr = TRUE; + lpt_addr = (WORD) lpt_port; + lpt_port = 1; + } + } + } + break; +#endif + + case 'R': /* don't reset the JTAG chain after use */ + reset_jtag = 0; + break; + + case 'S': /* set serial port address */ + serial_port_name = &argv[arg][2]; + specified_com_port = TRUE; + break; + + case 'M': /* set memory size */ + if (sscanf(&argv[arg][2], "%ld", &workspace_size) != 1) + error = TRUE; + if (workspace_size == 0) error = TRUE; + break; + + case 'H': /* help */ + help = TRUE; + break; + + case 'V': /* verbose */ + verbose = TRUE; + break; + + case 'I': /* show info only, do not execute */ + verbose = TRUE; + execute_program = 0; + break; + + default: + error = TRUE; + break; + } + } + else + { + /* it's a filename */ + if (filename == NULL) + { + filename = argv[arg]; + } + else + { + /* error -- we already found a filename */ + error = TRUE; + } + } + + if (error) + { + fprintf(stderr, "Illegal argument: \"%s\"\n", argv[arg]); + help = TRUE; + error = FALSE; + } + } + +#if PORT == WINDOWS || PORT == DOS + if (specified_lpt_port && specified_com_port) + { + fprintf(stderr, "Error: -s and -p options may not be used together\n\n"); + help = TRUE; + } +#endif + + if (help || (filename == NULL)) + { + fprintf(stderr, "Usage: jbi [options] \n"); + fprintf(stderr, "\nAvailable options:\n"); + fprintf(stderr, " -h : show help message\n"); + fprintf(stderr, " -v : show verbose messages\n"); + fprintf(stderr, " -i : show file info only - does not execute any action\n"); + fprintf(stderr, " -a : specify an action name (Jam STAPL)\n"); + fprintf(stderr, " -d : initialize variable to specified value (Jam 1.1)\n"); + fprintf(stderr, " -d : enable optional procedure (Jam STAPL)\n"); + fprintf(stderr, " -d : disable recommended procedure (Jam STAPL)\n"); +#if PORT == WINDOWS || PORT == DOS + fprintf(stderr, " -p : parallel port number or address (for ByteBlaster)\n"); + fprintf(stderr, " -c : alternative download cable compatibility: -cl or -cx\n"); +#endif + fprintf(stderr, " -s : serial port name (for BitBlaster)\n"); + fprintf(stderr, " -r : don't reset JTAG TAP after use\n"); + exit_status = 1; + } + else if ((workspace_size > 0) && + ((workspace = (char *) jbi_malloc((size_t) workspace_size)) == NULL)) + { + fprintf(stderr, "Error: can't allocate memory (%d Kbytes)\n", + (int) (workspace_size / 1024L)); + exit_status = 1; + } + else if (access(filename, 0) != 0) + { + fprintf(stderr, "Error: can't access file \"%s\"\n", filename); + exit_status = 1; + } + else + { + /* get length of file */ + if (stat(filename, &sbuf) == 0) file_length = sbuf.st_size; + + if ((fp = fopen(filename, "rb")) == NULL) + { + fprintf(stderr, "Error: can't open file \"%s\"\n", filename); + exit_status = 1; + } + else + { + /* + * Read entire file into a buffer + */ +#if PORT == DOS + int pages = 1 + (int) (file_length >> 14L); + int page; + file_buffer = (unsigned char **) jbi_malloc( + (size_t) (pages * sizeof(char *))); + + for (page = 0; page < pages; ++page) + { + /* allocate enough 16K blocks to store the file */ + file_buffer[page] = (unsigned char *) jbi_malloc (0x4000); + if (file_buffer[page] == NULL) + { + /* flag error and break out of loop */ + file_buffer = NULL; + page = pages; + } + } +#else + file_buffer = (unsigned char *) jbi_malloc((size_t) file_length); +#endif + + if (file_buffer == NULL) + { + fprintf(stderr, "Error: can't allocate memory (%d Kbytes)\n", + (int) (file_length / 1024L)); + exit_status = 1; + } + else + { +#if PORT == DOS + int pages = 1 + (int) (file_length >> 14L); + int page; + size_t page_size = 0x4000; + for (page = 0; (page < pages) && (exit_status == 0); ++page) + { + if (page == (pages - 1)) + { + /* last page may not be full 16K bytes */ + page_size = (size_t) (file_length & 0x3fffL); + } + if (fread(file_buffer[page], 1, page_size, fp) != page_size) + { + fprintf(stderr, "Error reading file \"%s\"\n", filename); + exit_status = 1; + } + } +#else + if (fread(file_buffer, 1, (size_t) file_length, fp) != + (size_t) file_length) + { + fprintf(stderr, "Error reading file \"%s\"\n", filename); + exit_status = 1; + } +#endif + } + + fclose(fp); + } + + if (exit_status == 0) + { + /* + * Get Operating System type + */ +#if PORT == WINDOWS + windows_nt = !(GetVersion() & 0x80000000); +#endif + + /* + * Calibrate the delay loop function + */ + calibrate_delay(); + + /* + * Check CRC + */ + crc_result = jbi_check_crc(file_buffer, file_length, + &expected_crc, &actual_crc); + + if (verbose || (crc_result == JBIC_CRC_ERROR)) + { + switch (crc_result) + { + case JBIC_SUCCESS: + printf("CRC matched: CRC value = %04X\n", actual_crc); + break; + + case JBIC_CRC_ERROR: + printf("CRC mismatch: expected %04X, actual %04X\n", + expected_crc, actual_crc); + break; + + case JBIC_UNEXPECTED_END: + printf("Expected CRC not found, actual CRC value = %04X\n", + actual_crc); + break; + + case JBIC_IO_ERROR: + printf("Error: File format is not recognized.\n"); + exit(1); + break; + + default: + printf("CRC function returned error code %d\n", crc_result); + break; + } + } + + if (verbose) + { + /* + * Display file format version + */ + jbi_get_file_info(file_buffer, file_length, + &format_version, &action_count, &procedure_count); + + printf("File format is %s ByteCode format\n", + (format_version == 2) ? "Jam STAPL" : "pre-standardized Jam 1.1"); + + /* + * Dump out NOTE fields + */ + while (jbi_get_note(file_buffer, file_length, + &offset, key, value, 256) == 0) + { + printf("NOTE \"%s\" = \"%s\"\n", key, value); + } + + /* + * Dump the action table + */ + if ((format_version == 2) && (action_count > 0)) + { + printf("\nActions available in this file:\n"); + + for (index = 0; index < action_count; ++index) + { + jbi_get_action_info(file_buffer, file_length, + index, &action_name, &description, &procedure_list); + + if (description == NULL) + { + printf("%s\n", action_name); + } + else + { + printf("%s \"%s\"\n", action_name, description); + } + +#if PORT == DOS + if (action_name != NULL) jbi_free(action_name); + if (description != NULL) jbi_free(description); +#endif + + procptr = procedure_list; + while (procptr != NULL) + { + if (procptr->attributes != 0) + { + printf(" %s (%s)\n", procptr->name, + (procptr->attributes == 1) ? + "optional" : "recommended"); + } + +#if PORT == DOS + if (procptr->name != NULL) jbi_free(procptr->name); +#endif + + procedure_list = procptr->next; + jbi_free(procptr); + procptr = procedure_list; + } + } + + /* add a blank line before execution messages */ + if (execute_program) printf("\n"); + } + } + + if (execute_program) + { + /* + * Execute the Jam STAPL ByteCode program + */ + time(&start_time); + exec_result = jbi_execute(file_buffer, file_length, workspace, + workspace_size, action, init_list, reset_jtag, + &error_address, &exit_code, &format_version); + time(&end_time); + + if (exec_result == JBIC_SUCCESS) + { + if (format_version == 2) + { + switch (exit_code) + { + case 0: exit_string = "Success"; break; + case 1: exit_string = "Checking chain failure"; break; + case 2: exit_string = "Reading IDCODE failure"; break; + case 3: exit_string = "Reading USERCODE failure"; break; + case 4: exit_string = "Reading UESCODE failure"; break; + case 5: exit_string = "Entering ISP failure"; break; + case 6: exit_string = "Unrecognized device"; break; + case 7: exit_string = "Device revision is not supported"; break; + case 8: exit_string = "Erase failure"; break; + case 9: exit_string = "Device is not blank"; break; + case 10: exit_string = "Device programming failure"; break; + case 11: exit_string = "Device verify failure"; break; + case 12: exit_string = "Read failure"; break; + case 13: exit_string = "Calculating checksum failure"; break; + case 14: exit_string = "Setting security bit failure"; break; + case 15: exit_string = "Querying security bit failure"; break; + case 16: exit_string = "Exiting ISP failure"; break; + case 17: exit_string = "Performing system test failure"; break; + default: exit_string = "Unknown exit code"; break; + } + } + else + { + switch (exit_code) + { + case 0: exit_string = "Success"; break; + case 1: exit_string = "Illegal initialization values"; break; + case 2: exit_string = "Unrecognized device"; break; + case 3: exit_string = "Device revision is not supported"; break; + case 4: exit_string = "Device programming failure"; break; + case 5: exit_string = "Device is not blank"; break; + case 6: exit_string = "Device verify failure"; break; + case 7: exit_string = "SRAM configuration failure"; break; + default: exit_string = "Unknown exit code"; break; + } + } + + printf("Exit code = %d... %s\n", exit_code, exit_string); + } + else if ((format_version == 2) && + (exec_result == JBIC_ACTION_NOT_FOUND)) + { + if ((action == NULL) || (*action == '\0')) + { + printf("Error: no action specified for Jam STAPL file.\nProgram terminated.\n"); + } + else + { + printf("Error: action \"%s\" is not supported for this Jam STAPL file.\nProgram terminated.\n", action); + } + } + else if (exec_result < MAX_ERROR_CODE) + { + printf("Error at address %ld: %s.\nProgram terminated.\n", + error_address, error_text[exec_result]); + } + else + { + printf("Unknown error code %ld\n", exec_result); + } + + /* + * Print out elapsed time + */ + if (verbose) + { + time_delta = (int) (end_time - start_time); + printf("Elapsed time = %02u:%02u:%02u\n", + time_delta / 3600, /* hours */ + (time_delta % 3600) / 60, /* minutes */ + time_delta % 60); /* seconds */ + } + } + } + } + + if (jtag_hardware_initialized) close_jtag_hardware(); + + if (workspace != NULL) jbi_free(workspace); + if (file_buffer != NULL) jbi_free(file_buffer); + +#if defined(MEM_TRACKER) + if (verbose) + { +#if defined(USE_STATIC_MEMORY) + fprintf(stdout, "Memory Usage Info: static memory size = %ud (%dKB)\n", N_STATIC_MEMORY_BYTES, N_STATIC_MEMORY_KBYTES); +#endif /* USE_STATIC_MEMORY */ + fprintf(stdout, "Memory Usage Info: peak memory usage = %ud (%dKB)\n", peak_memory_usage, (peak_memory_usage + 1023) / 1024); + fprintf(stdout, "Memory Usage Info: peak allocations = %d\n", peak_allocations); +#if defined(USE_STATIC_MEMORY) + if ((n_bytes_allocated - n_bytes_not_recovered) != 0) + { + fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", (n_bytes_allocated - n_bytes_not_recovered), ((n_bytes_allocated - n_bytes_not_recovered) + 1023) / 1024); + } +#else /* USE_STATIC_MEMORY */ + if (n_bytes_allocated != 0) + { + fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", n_bytes_allocated, (n_bytes_allocated + 1023) / 1024); + } +#endif /* USE_STATIC_MEMORY */ + if (n_allocations != 0) + { + fprintf(stdout, "Memory Usage Info: allocations not freed = %d\n", n_allocations); + } + } +#endif /* MEM_TRACKER */ + + return (exit_status); +} +#endif + +#if PORT==WINDOWS +#ifndef __BORLANDC__ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* SEARCH_DYN_DATA +* +* Searches recursively in Windows 95/98 Registry for parallel port info +* under HKEY_DYN_DATA registry key. Called by search_local_machine(). +*/ +void search_dyn_data +( + char *dd_path, + char *hardware_key, + int lpt +) +{ + DWORD index; + DWORD size; + DWORD type; + LONG result; + HKEY key; + int length; + WORD address; + char buffer[1024]; + FILETIME last_write = {0}; + WORD *word_ptr; + int i; + + length = strlen(dd_path); + + if (RegOpenKeyEx( + HKEY_DYN_DATA, + dd_path, + 0L, + KEY_READ, + &key) + == ERROR_SUCCESS) + { + size = 1023; + + if (RegQueryValueEx( + key, + "HardWareKey", + NULL, + &type, + (unsigned char *) buffer, + &size) + == ERROR_SUCCESS) + { + if ((type == REG_SZ) && (stricmp(buffer, hardware_key) == 0)) + { + size = 1023; + + if (RegQueryValueEx( + key, + "Allocation", + NULL, + &type, + (unsigned char *) buffer, + &size) + == ERROR_SUCCESS) + { + /* + * By "inspection", I have found five cases: size 32, 48, + * 56, 60, and 80 bytes. The port address seems to be + * located at different offsets in the buffer for these + * five cases, as shown below. If a valid port address + * is not found, or the size is not one of these known + * sizes, then I search through the entire buffer and + * look for a value which is a valid port address. + */ + + word_ptr = (WORD *) buffer; + + if ((type == REG_BINARY) && (size == 32)) + { + address = word_ptr[10]; + } + else if ((type == REG_BINARY) && (size == 48)) + { + address = word_ptr[18]; + } + else if ((type == REG_BINARY) && (size == 56)) + { + address = word_ptr[22]; + } + else if ((type == REG_BINARY) && (size == 60)) + { + address = word_ptr[24]; + } + else if ((type == REG_BINARY) && (size == 80)) + { + address = word_ptr[24]; + } + else address = 0; + + /* if not found, search through entire buffer */ + i = 0; + while ((i < (int) (size / 2)) && + (address != 0x278) && + (address != 0x27C) && + (address != 0x378) && + (address != 0x37C) && + (address != 0x3B8) && + (address != 0x3BC)) + { + if ((word_ptr[i] == 0x278) || + (word_ptr[i] == 0x27C) || + (word_ptr[i] == 0x378) || + (word_ptr[i] == 0x37C) || + (word_ptr[i] == 0x3B8) || + (word_ptr[i] == 0x3BC)) + { + address = word_ptr[i]; + } + ++i; + } + + if ((address == 0x278) || + (address == 0x27C) || + (address == 0x378) || + (address == 0x37C) || + (address == 0x3B8) || + (address == 0x3BC)) + { + lpt_addresses_from_registry[lpt] = address; + } + } + } + } + + index = 0; + + do + { + size = 1023; + + result = RegEnumKeyEx( + key, + index++, + buffer, + &size, + NULL, + NULL, + NULL, + &last_write); + + if (result == ERROR_SUCCESS) + { + dd_path[length] = '\\'; + dd_path[length + 1] = '\0'; + strcpy(&dd_path[length + 1], buffer); + + search_dyn_data(dd_path, hardware_key, lpt); + + dd_path[length] = '\0'; + } + } + while (result == ERROR_SUCCESS); + + RegCloseKey(key); + } +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* SEARCH_LOCAL_MACHINE +* +* Searches recursively in Windows 95/98 Registry for parallel port info +* under HKEY_LOCAL_MACHINE\Enum. When parallel port is found, calls +* search_dyn_data() to get the port address. +*/ +void search_local_machine +( + char *lm_path, + char *dd_path +) +{ + DWORD index; + DWORD size; + DWORD type; + LONG result; + HKEY key; + int length; + char buffer[1024]; + FILETIME last_write = {0}; + + length = strlen(lm_path); + + if (RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + lm_path, + 0L, + KEY_READ, + &key) + == ERROR_SUCCESS) + { + size = 1023; + + if (RegQueryValueEx( + key, + "PortName", + NULL, + &type, + (unsigned char *) buffer, + &size) + == ERROR_SUCCESS) + { + if ((type == REG_SZ) && + (size == 5) && + (buffer[0] == 'L') && + (buffer[1] == 'P') && + (buffer[2] == 'T') && + (buffer[3] >= '1') && + (buffer[3] <= '4') && + (buffer[4] == '\0')) + { + /* we found the entry in HKEY_LOCAL_MACHINE, now we need to */ + /* find the corresponding entry under HKEY_DYN_DATA. */ + /* add 5 to lm_path to skip over "Enum" and backslash */ + search_dyn_data(dd_path, &lm_path[5], (buffer[3] - '1')); + } + } + + index = 0; + + do + { + size = 1023; + + result = RegEnumKeyEx( + key, + index++, + buffer, + &size, + NULL, + NULL, + NULL, + &last_write); + + if (result == ERROR_SUCCESS) + { + lm_path[length] = '\\'; + lm_path[length + 1] = '\0'; + strcpy(&lm_path[length + 1], buffer); + + search_local_machine(lm_path, dd_path); + + lm_path[length] = '\0'; + } + } + while (result == ERROR_SUCCESS); + + RegCloseKey(key); + } +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* GET_LPT_ADDRESSES_FROM_REGISTRY +* +* Searches Win95/98 registry recursively to get I/O port addresses for +* parallel ports. +*/ +void get_lpt_addresses_from_registry() +{ + char lm_path[1024]; + char dd_path[1024]; + + strcpy(lm_path, "Enum"); + strcpy(dd_path, "Config Manager"); + search_local_machine(lm_path, dd_path); +} +#endif +#endif + +void initialize_jtag_hardware() +{ + if (specified_com_port) + { + com_port = open(serial_port_name, O_RDWR); + if (com_port == -1) + { + fprintf(stderr, "Error: can't open serial port \"%s\"\n", + serial_port_name); + } + else + { + int i = 0, result = 0; + char data = 0; + + data = 0x7e; + write(com_port, &data, 1); + + for (i = 0; (i < 100) && (result != 1); ++i) + { + result = read(com_port, &data, 1); + } + + if (result == 1) + { + data = 0x70; write(com_port, &data, 1); /* TDO echo off */ + data = 0x72; write(com_port, &data, 1); /* auto LEDs off */ + data = 0x74; write(com_port, &data, 1); /* ERROR LED off */ + data = 0x76; write(com_port, &data, 1); /* DONE LED off */ + data = 0x60; write(com_port, &data, 1); /* signals low */ + } + else + { + fprintf(stderr, "Error: BitBlaster is not responding on %s\n", + serial_port_name); + close(com_port); + com_port = -1; + } + } + } + else + { +#if PORT == WINDOWS || PORT == DOS + +#if PORT == WINDOWS + if (windows_nt) + { + initialize_nt_driver(); + } + else + { +#ifdef __BORLANDC__ + fprintf(stderr, "Error: parallel port access is not available\n"); +#else + if (!specified_lpt_addr) + { + get_lpt_addresses_from_registry(); + + lpt_addr = 0; + + if (specified_lpt_port) + { + lpt_addr = lpt_addresses_from_registry[lpt_port - 1]; + } + + if (lpt_addr == 0) + { + if (lpt_addresses_from_registry[3] != 0) + lpt_addr = lpt_addresses_from_registry[3]; + if (lpt_addresses_from_registry[2] != 0) + lpt_addr = lpt_addresses_from_registry[2]; + if (lpt_addresses_from_registry[1] != 0) + lpt_addr = lpt_addresses_from_registry[1]; + if (lpt_addresses_from_registry[0] != 0) + lpt_addr = lpt_addresses_from_registry[0]; + } + + if (lpt_addr == 0) + { + if (specified_lpt_port) + { + lpt_addr = lpt_addr_table[lpt_port - 1]; + } + else + { + lpt_addr = lpt_addr_table[0]; + } + } + } + initial_lpt_ctrl = windows_nt ? 0x0c : read_byteblaster(2); +#endif + } +#endif + +#if PORT == DOS + /* + * Read word at specific memory address to get the LPT port address + */ + WORD *bios_address = (WORD *) 0x00400008; + + if (!specified_lpt_addr) + { + lpt_addr = bios_address[lpt_port - 1]; + + if ((lpt_addr != 0x278) && + (lpt_addr != 0x27c) && + (lpt_addr != 0x378) && + (lpt_addr != 0x37c) && + (lpt_addr != 0x3b8) && + (lpt_addr != 0x3bc)) + { + lpt_addr = lpt_addr_table[lpt_port - 1]; + } + } + initial_lpt_ctrl = read_byteblaster(2); +#endif + + /* set AUTO-FEED low to enable ByteBlaster (value to port inverted) */ + /* set DIRECTION low for data output from parallel port */ + write_byteblaster(2, (initial_lpt_ctrl | 0x02) & 0xDF); +#endif + } +} + +void close_jtag_hardware() +{ + if (specified_com_port) + { + if (com_port != -1) close(com_port); + } + else + { +#if PORT == WINDOWS || PORT == DOS + /* set AUTO-FEED high to disable ByteBlaster */ + write_byteblaster(2, initial_lpt_ctrl & 0xfd); + +#if PORT == WINDOWS + if (windows_nt && (nt_device_handle != INVALID_HANDLE_VALUE)) + { + if (port_io_count > 0) flush_ports(); + + CloseHandle(nt_device_handle); + } +#endif +#endif + } +} + +#if PORT == WINDOWS +/**************************************************************************/ +/* */ + +BOOL initialize_nt_driver() + +/* */ +/* Uses CreateFile() to open a connection to the Windows NT device */ +/* driver. */ +/* */ +/**************************************************************************/ +{ + BOOL status = FALSE; + + ULONG buffer[1]; + ULONG returned_length = 0; + char nt_lpt_str[] = { '\\', '\\', '.', '\\', + 'A', 'L', 'T', 'L', 'P', 'T', '1', '\0' }; + + nt_lpt_str[10] = (char) ('1' + (lpt_port - 1)); + + nt_device_handle = CreateFile( + nt_lpt_str, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (nt_device_handle == INVALID_HANDLE_VALUE) + { + fprintf(stderr, + "I/O error: cannot open device %s\nCheck port number and device driver installation", + nt_lpt_str); + } + else + { + if (DeviceIoControl( + nt_device_handle, /* Handle to device */ + PGDC_IOCTL_GET_DEVICE_INFO_PP, /* IO Control code */ + (ULONG *)NULL, /* Buffer to driver. */ + 0, /* Length of buffer in bytes. */ + &buffer, /* Buffer from driver. */ + sizeof(ULONG), /* Length of buffer in bytes. */ + &returned_length, /* Bytes placed in data_buffer. */ + NULL)) /* Wait for operation to complete */ + { + if (returned_length == sizeof(ULONG)) + { + if (buffer[0] == PGDC_HDLC_NTDRIVER_VERSION) + { + status = TRUE; + } + else + { + fprintf(stderr, + "I/O error: device driver %s is not compatible\n(Driver version is %lu, expected version %lu.\n", + nt_lpt_str, + (unsigned long) buffer[0], + (unsigned long) PGDC_HDLC_NTDRIVER_VERSION); + } + } + else + { + fprintf(stderr, "I/O error: device driver %s is not compatible.\n", + nt_lpt_str); + } + } + + if (!status) + { + CloseHandle(nt_device_handle); + nt_device_handle = INVALID_HANDLE_VALUE; + } + } + + if (!status) + { + /* error message already given */ + exit(1); + } + + return (status); +} +#endif + +#if PORT == WINDOWS || PORT == DOS +/**************************************************************************/ +/* */ + +void write_byteblaster +( + int port, + int data +) + +/* */ +/**************************************************************************/ +{ +#if PORT == WINDOWS + BOOL status = FALSE; + + int returned_length = 0; + int buffer[2]; + + if (windows_nt) + { + /* + * On Windows NT, access hardware through device driver + */ + if (port == 0) + { + port_io_buffer[port_io_count].data = (USHORT) data; + port_io_buffer[port_io_count].command = PGDC_WRITE_PORT; + ++port_io_count; + + if (port_io_count >= PORT_IO_BUFFER_SIZE) flush_ports(); + } + else + { + if (port_io_count > 0) flush_ports(); + + buffer[0] = port; + buffer[1] = data; + + status = DeviceIoControl( + nt_device_handle, /* Handle to device */ + PGDC_IOCTL_WRITE_PORT_PP, /* IO Control code for write */ + (ULONG *)&buffer, /* Buffer to driver. */ + 2 * sizeof(int), /* Length of buffer in bytes. */ + (ULONG *)NULL, /* Buffer from driver. Not used. */ + 0, /* Length of buffer in bytes. */ + (ULONG *)&returned_length, /* Bytes returned. Should be zero. */ + NULL); /* Wait for operation to complete */ + + if ((!status) || (returned_length != 0)) + { + fprintf(stderr, "I/O error: Cannot access ByteBlaster hardware\n"); + CloseHandle(nt_device_handle); + exit(1); + } + } + } + else +#endif + { + /* + * On Windows 95, access hardware directly + */ + outp((WORD)(port + lpt_addr), (WORD)data); + } +} + +/**************************************************************************/ +/* */ + +int read_byteblaster +( + int port +) + +/* */ +/**************************************************************************/ +{ + int data = 0; + +#if PORT == WINDOWS + + BOOL status = FALSE; + + int returned_length = 0; + + if (windows_nt) + { + /* flush output cache buffer before reading from device */ + if (port_io_count > 0) flush_ports(); + + /* + * On Windows NT, access hardware through device driver + */ + status = DeviceIoControl( + nt_device_handle, /* Handle to device */ + PGDC_IOCTL_READ_PORT_PP, /* IO Control code for Read */ + (ULONG *)&port, /* Buffer to driver. */ + sizeof(int), /* Length of buffer in bytes. */ + (ULONG *)&data, /* Buffer from driver. */ + sizeof(int), /* Length of buffer in bytes. */ + (ULONG *)&returned_length, /* Bytes placed in data_buffer. */ + NULL); /* Wait for operation to complete */ + + if ((!status) || (returned_length != sizeof(int))) + { + fprintf(stderr, "I/O error: Cannot access ByteBlaster hardware\n"); + CloseHandle(nt_device_handle); + exit(1); + } + } + else +#endif + { + /* + * On Windows 95, access hardware directly + */ + data = inp((WORD)(port + lpt_addr)); + } + + return (data & 0xff); +} + +#if PORT == WINDOWS +void flush_ports(void) +{ + ULONG n_writes = 0L; + BOOL status; + + status = DeviceIoControl( + nt_device_handle, /* handle to device */ + PGDC_IOCTL_PROCESS_LIST_PP, /* IO control code */ + (LPVOID)port_io_buffer, /* IN buffer (list buffer) */ + port_io_count * sizeof(struct PORT_IO_LIST_STRUCT),/* length of IN buffer in bytes */ + (LPVOID)port_io_buffer, /* OUT buffer (list buffer) */ + port_io_count * sizeof(struct PORT_IO_LIST_STRUCT),/* length of OUT buffer in bytes */ + &n_writes, /* number of writes performed */ + 0); /* wait for operation to complete */ + + if ((!status) || ((port_io_count * sizeof(struct PORT_IO_LIST_STRUCT)) != n_writes)) + { + fprintf(stderr, "I/O error: Cannot access ByteBlaster hardware\n"); + CloseHandle(nt_device_handle); + exit(1); + } + + port_io_count = 0; +} +#endif /* PORT == WINDOWS */ +#endif /* PORT == WINDOWS || PORT == DOS */ + +#if 0 +#if !defined (DEBUG) +#pragma optimize ("ceglt", off) +#endif +#endif + +void delay_loop(long count) +{ + while (count != 0L) count--; +} + +#if PORT == EMBEDDED + +static void jbi_init_mm(void) +{ +#if defined(USE_STATIC_MEMORY) + int i; +#endif /* USE_STATIC_MEMORY */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + n_bytes_allocated = 0; +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(MEM_TRACKER) + peak_memory_usage = 0; + peak_allocations = 0; + n_allocations = 0; +#if defined(USE_STATIC_MEMORY) + n_bytes_not_recovered = 0; +#endif /* USE_STATIC_MEMORY */ +#endif /* MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) + jbi_dbg(DEBUG_DETAIL, "static_memory_heap: 0x%p(0x%x)\n", + static_memory_heap, N_STATIC_MEMORY_BYTES); + for (i = 0; i < N_STATIC_MEMORY_BYTES; i++) { + static_memory_heap[i] = 0; + } +#endif /* USE_STATIC_MEMORY */ + + jbi_delay_us = 0; + jbi_delay_count = 0; + jbi_peak_us = 0; +} + +static void jbi_exit_mm(void) +{ +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + jbi_dbg(DEBUG_DETAIL, "n_bytes_allocated: %u\n", n_bytes_allocated); + n_bytes_allocated = 0; +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(MEM_TRACKER) + jbi_dbg(DEBUG_DETAIL, "peak_memory_usage: %u\n", peak_memory_usage); + jbi_dbg(DEBUG_DETAIL, "peak_allocations: %u\n", peak_allocations); + jbi_dbg(DEBUG_DETAIL, "n_allocations: %u\n", n_allocations); + peak_memory_usage = 0; + peak_allocations = 0; + n_allocations = 0; +#if defined(USE_STATIC_MEMORY) + jbi_dbg(DEBUG_DETAIL, "n_bytes_not_recovered: %u\n", n_bytes_not_recovered); + n_bytes_not_recovered = 0; +#endif /* USE_STATIC_MEMORY */ +#endif /* MEM_TRACKER */ + + jbi_dbg(DEBUG_DETAIL, "jbi_delay: %ld us, %ld count, peak %ld us\n", + jbi_delay_us, jbi_delay_count, jbi_peak_us); +} + +static char *get_exit_string(int format_version, int exit_code) +{ + char *exit_string = NULL; + + if (format_version == 2){ + switch (exit_code) { + case 0: + exit_string = "Success"; + break; + case 1: + exit_string = "Checking chain failure"; + break; + case 2: + exit_string = "Reading IDCODE failure"; + break; + case 3: + exit_string = "Reading USERCODE failure"; + break; + case 4: + exit_string = "Reading UESCODE failure"; + break; + case 5: + exit_string = "Entering ISP failure"; + break; + case 6: + exit_string = "Unrecognized device"; + break; + case 7: + exit_string = "Device revision is not supported"; + break; + case 8: + exit_string = "Erase failure"; + break; + case 9: + exit_string = "Device is not blank"; + break; + case 10: + exit_string = "Device programming failure"; + break; + case 11: + exit_string = "Device verify failure"; + break; + case 12: + exit_string = "Read failure"; break; + case 13: + exit_string = "Calculating checksum failure"; + break; + case 14: + exit_string = "Setting security bit failure"; + break; + case 15: + exit_string = "Querying security bit failure"; + break; + case 16: + exit_string = "Exiting ISP failure"; + break; + case 17: + exit_string = "Performing system test failure"; + break; + default: + exit_string = "Unknown exit code"; + break; + } + } else { + switch (exit_code) { + case 0: + exit_string = "Success"; + break; + case 1: + exit_string = "Illegal initialization values"; + break; + case 2: + exit_string = "Unrecognized device"; + break; + case 3: + exit_string = "Device revision is not supported"; + break; + case 4: + exit_string = "Device programming failure"; + break; + case 5: + exit_string = "Device is not blank"; + break; + case 6: + exit_string = "Device verify failure"; + break; + case 7: + exit_string = "SRAM configuration failure"; + break; + default: + exit_string = "Unknown exit code"; + break; + } + } + + return exit_string; +} + +static void jbi_help(void) +{ + fprintf(stderr, "Usage: jbi [options]\n"); + fprintf(stderr, "\nAvailable options:\n"); + fprintf(stderr, " -h : show help message\n"); + fprintf(stderr, " -v : show verbose messages\n"); + fprintf(stderr, " -i : show file info only - does not execute any action\n"); + fprintf(stderr, " -a : specify an action name (Jam STAPL)\n"); + fprintf(stderr, " -d : initialize variable to specified value (Jam 1.1)\n"); + fprintf(stderr, " -d : enable optional procedure (Jam STAPL)\n"); + fprintf(stderr, " -d : disable recommended procedure (Jam STAPL)\n"); + fprintf(stderr, " -r : don't reset JTAG TAP after use\n"); +} + +int jbi_debug(int level) +{ + jbi_debug_level = level; + + return 0; +} + +int jbi_main(unsigned char *addr, unsigned long size, int argc, char * const argv[]) +{ + BOOL help = FALSE; + BOOL error = FALSE; + long offset = 0L; + long error_address = 0L; + JBI_RETURN_TYPE crc_result = JBIC_SUCCESS; + JBI_RETURN_TYPE exec_result = JBIC_SUCCESS; + unsigned short expected_crc = 0; + unsigned short actual_crc = 0; + char key[33] = {0}; + char value[257] = {0}; + int exit_status = 0; + int arg = 0; + int exit_code = 0; + int format_version = 0; + char *workspace = NULL; + char *action = NULL; + char *init_list[10]; + int init_count = 0; + long workspace_size = 0; + char *exit_string = NULL; + int reset_jtag = 1; + int execute_program = 1; + int action_count = 0; + int procedure_count = 0; + int index = 0; + char *action_name = NULL; + char *description = NULL; + JBI_PROCINFO *procedure_list = NULL; + JBI_PROCINFO *procptr = NULL; + char *endp = NULL; + + verbose = FALSE; + + init_list[0] = NULL; + + /* print out the version string and copyright message */ + printf("Jam STAPL ByteCode Player Version 2.2\n"); + printf("Copyright (C) 1998-2001 Altera Corporation\n\n"); + + for (arg = 0; arg < argc; arg++) { + if (argv[arg][0] == '-') { + switch (toupper(argv[arg][1])) { + case 'A': /* set action name */ + if (action == NULL) { + action = &argv[arg][2]; + } else { + error = TRUE; + } + break; + case 'D': /* initialization list */ + if (argv[arg][2] == '"') { + init_list[init_count] = &argv[arg][3]; + } else { + init_list[init_count] = &argv[arg][2]; + } + init_list[++init_count] = NULL; + break; + case 'R': /* don't reset the JTAG chain after use */ + reset_jtag = 0; + break; + case 'M': /* set memory size */ + workspace = (char *) simple_strtoul(&argv[arg][2], &endp, 16); + if (workspace == NULL) { + printf("Error workspace\n"); + error = TRUE; + } else { + if (*endp == '.') { + workspace_size = simple_strtoul(endp + 1, &endp, 16); + if (*endp != '\0') { + printf("Error workspace size end\n"); + error = TRUE; + } + } else { + printf("No workspace size\n"); + error = TRUE; + } + } + break; + case 'H': /* help */ + help = TRUE; + break; + case 'V': /* verbose */ + verbose = TRUE; + break; + case 'I': /* show info only, do not execute */ + verbose = TRUE; + execute_program = 0; + break; + default: + error = TRUE; + break; + } + } else { + error = TRUE; + } + + if (error) { + fprintf(stderr, "Illegal argument: \"%s\"\n", argv[arg]); + help = TRUE; + error = FALSE; + } + } + + if (help) { + jbi_help(); + return 0; + } + + /* Calibrate the delay loop function */ + calibrate_delay(); + + jbi_init_mm(); + + /* Check CRC */ + crc_result = jbi_check_crc(addr, size, &expected_crc, &actual_crc); + if (verbose || (crc_result == JBIC_CRC_ERROR)) { + switch (crc_result) { + case JBIC_SUCCESS: + printf("CRC matched: CRC value = %04X\n", actual_crc); + break; + case JBIC_CRC_ERROR: + printf("CRC mismatch: expected %04X, actual %04X\n", expected_crc, actual_crc); + return -1; + case JBIC_UNEXPECTED_END: + printf("Expected CRC not found, actual CRC value = %04X\n", actual_crc); + return -1; + case JBIC_IO_ERROR: + printf("Error: File format is not recognized.\n"); + return -1; + default: + printf("CRC function returned error code %d\n", crc_result); + return -1; + } + } + + if (verbose) { + /* Display file format version */ + jbi_get_file_info(addr, size, &format_version, + &action_count, &procedure_count); + + printf("File format is %s ByteCode format\n", + (format_version == 2) ? "Jam STAPL" : "pre-standardized Jam 1.1"); + + /* Dump out NOTE fields */ + while (jbi_get_note(addr, size, &offset, key, value, 256) == 0) { + printf("NOTE \"%s\" = \"%s\"\n", key, value); + } + + /* Dump the action table */ + if ((format_version == 2) && (action_count > 0)) { + printf("\nActions available in this file:\n"); + + for (index = 0; index < action_count; ++index) { + jbi_get_action_info(addr, size, + index, &action_name, &description, &procedure_list); + + if (description == NULL) { + printf("%s\n", action_name); + } else { + printf("%s \"%s\"\n", action_name, description); + } + + procptr = procedure_list; + while (procptr != NULL) { + if (procptr->attributes != 0) { + printf(" %s (%s)\n", procptr->name, + (procptr->attributes == 1) ? "optional" : "recommended"); + } + + procedure_list = procptr->next; + jbi_free(procptr); + procptr = procedure_list; + } + } + + /* add a blank line before execution messages */ + if (execute_program) + printf("\n"); + } + } + + if (execute_program) { + /* Execute the Jam STAPL ByteCode program */ + exec_result = jbi_execute(addr, size, workspace, + workspace_size, action, init_list, reset_jtag, + &error_address, &exit_code, &format_version); + if (exec_result == JBIC_SUCCESS) { + exit_string = get_exit_string(format_version, exit_code); + printf("Exit code = %d... %s\n", exit_code, exit_string); + } else if ((format_version == 2) && (exec_result == JBIC_ACTION_NOT_FOUND)) { + if ((action == NULL) || (*action == '\0')) { + printf("Error: no action specified for Jam STAPL file.\n" + "Program terminated.\n"); + } else { + printf("Error: action \"%s\" is not supported for this Jam STAPL file.\n" + "Program terminated.\n", action); + } + } else if (exec_result < MAX_ERROR_CODE) { + printf("Error at address %ld: %s.\nProgram terminated.\n", + error_address, error_text[exec_result]); + } else { + printf("Unknown error code %d\n", exec_result); + } + } + + if (jtag_hardware_initialized) { + close_jtag_hardware(); + jtag_hardware_initialized = FALSE; + } + +#if defined(MEM_TRACKER) + if (verbose) { +#if defined(USE_STATIC_MEMORY) + fprintf(stdout, "Memory Usage Info: static memory size = %uBytes (%dKB)\n", + N_STATIC_MEMORY_BYTES, N_STATIC_MEMORY_KBYTES); +#endif /* USE_STATIC_MEMORY */ + fprintf(stdout, "Memory Usage Info: peak memory usage = %uBytes (%dKB)\n", + peak_memory_usage, (peak_memory_usage + 1023) / 1024); + fprintf(stdout, "Memory Usage Info: peak allocations = %u\n", + peak_allocations); +#if defined(USE_STATIC_MEMORY) + if ((n_bytes_allocated - n_bytes_not_recovered) != 0) { + fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", + (n_bytes_allocated - n_bytes_not_recovered), + ((n_bytes_allocated - n_bytes_not_recovered) + 1023) / 1024); + } +#else /* USE_STATIC_MEMORY */ + if (n_bytes_allocated != 0) { + fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", + n_bytes_allocated, (n_bytes_allocated + 1023) / 1024); + } +#endif /* USE_STATIC_MEMORY */ + if (n_allocations != 0) { + fprintf(stdout, "Memory Usage Info: allocations not freed = %d\n", n_allocations); + } + } +#endif /* MEM_TRACKER */ + + jbi_exit_mm(); + + if (exec_result != JBIC_SUCCESS) { + return (-exec_result); + } + + if (exit_code != 0) { + return (exit_code); + } + + return (exit_status); +} + +#endif /* PORT == EMBEDDED */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.h new file mode 100644 index 000000000000..5e5c5332f385 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.h @@ -0,0 +1,95 @@ +#ifndef __JBISTUB_H__ +#define __JBISTUB_H__ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_64BIT +typedef s64 addr_t; +#else +typedef s32 addr_t; +#endif +/* typedef long addr_t; */ + +/* #define USE_STATIC_MEMORY 100 */ +/* #define MEM_TRACKER */ + +/* #define O_RDWR 1 */ + +#define stdout (1) +#define stderr (2) + +#define puts printk +#define printf printk + +#define fprintf(std, fmt, arg...) \ + do { \ + printf(fmt, ##arg); \ + } while (0) + +#define DEBUG_NONE 0 +#define DEBUG_ERR 1 +#define DEBUG_DETAIL 2 +#define DEBUG_NOISY 3 +#define DEBUG_MM 4 + +#define jbi_dbg(level, fmt, arg...) \ + do { \ + if (level <= jbi_debug_level) { \ + printf(fmt, ##arg); \ + } \ + } while (0) + +extern int jbi_debug_level; + +static inline int open(char *path, int flag) +{ + return 0; +} + +static inline int close(int fd) +{ + return 0; +} + +static inline int read(int fd, char *buf, int count) +{ + return 0; +} + +static inline int write(int fd, char *buf, int count) +{ + return 0; +} + +static inline int fflush(int fd) +{ + return 0; +} + +static inline int clock(void) +{ + return 0; +} + +static inline int atoi(const char *nptr) +{ + return (int) simple_strtol(nptr, (char **) NULL, 10); +} + +static inline void *malloc(size_t size) +{ + return kmalloc(size, GFP_KERNEL); +} + +static inline void free(void *ptr) +{ + kfree(ptr); +} + +#endif /* __JBISTUB_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/Makefile new file mode 100644 index 000000000000..caad44948030 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/Makefile @@ -0,0 +1,22 @@ +#include $(top_srcdir)/debian/rules +#KERNELDIR := ${KBUILD_OUTPUT} + +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../include) +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) +EXTRA_CFLAGS+= -Wall + +firmware_driver_ispvme-objs := firmware_ispvme.o +firmware_driver_ispvme-objs += firmware_cpld_ispvme.o firmware_cpld_upgrade_ispvme.o + +#ifndef CONFIG_FRM_PRODUCT_FILE + +$(warning $(firmware_driver_ispvme-objs)) +obj-m := firmware_driver_ispvme.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(common_module_dir) ]; then mkdir -p $(common_module_dir) ;fi + cp -p $(PWD)/*.ko $(common_module_dir) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_ispvme.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_ispvme.c new file mode 100644 index 000000000000..9841782290c1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_ispvme.c @@ -0,0 +1,450 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int firmware_cpld_open(struct inode *inode, struct file *file) +{ + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Open cpld device.\n"); + frm_dev = firmware_get_device_by_minor(MINOR(inode->i_rdev)); + if (frm_dev == NULL) { + return -ENXIO; + } + file->private_data = frm_dev; + + return FIRMWARE_SUCCESS; +} + +static ssize_t firmware_cpld_read (struct file *file, char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static ssize_t firmware_cpld_write (struct file *file, const char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static loff_t firmware_cpld_llseek(struct file *file, loff_t offset, int origin) +{ + return 0; +} + +/* + * firmware_cpld_ioctl + * function: ispvme driver ioctl command parsing function + * @file: param[in] device file name + * @cmd: param[in] command + * @arg: param[in] the parameters in the command + * return value: success-FIRMWARE_SUCCESS; fail:other value + */ +static long firmware_cpld_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + void __user *argp; + firmware_device_t *frm_dev; + firmware_cpld_t *cpld_info; + char value; + + /* Get device private data */ + frm_dev = (firmware_device_t *)file->private_data; + cpld_info = NULL; + if (frm_dev != NULL) { + if (frm_dev->priv != NULL) { + cpld_info = (firmware_cpld_t *)frm_dev->priv; + } + } + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to frm_dev->priv sysfs info.\n"); + return FIRMWARE_FAILED; + } + argp = (void __user *)arg; + + switch (cmd) { + case FIRMWARE_JTAG_TDI: + /* Set the TDI signal */ + if (copy_from_user(&value, argp, sizeof(value))) { + return -EFAULT; + } + if (fwm_cpld_tdi_op(value) < 0 ) { + return -EFAULT; + } + break; + case FIRMWARE_JTAG_TCK: + /* Set the TCK signal */ + if (copy_from_user(&value, argp, sizeof(value))) { + return -EFAULT; + } + if (fwm_cpld_tck_op(value) < 0) { + return -EFAULT; + } + break; + case FIRMWARE_JTAG_TMS: + /* Set the TMS signal */ + if (copy_from_user(&value, argp, sizeof(value))) { + return -EFAULT; + } + if (fwm_cpld_tms_op(value) < 0) { + return -EFAULT; + } + break; + case FIRMWARE_JTAG_TDO: + /* Read the TDO signal */ + value = fwm_cpld_tdo_op(); + if (copy_to_user(argp, &value, sizeof(value))) { + return -EFAULT; + } + break; + case FIRMWARE_JTAG_INIT: + /* The VME upgrade mode initializes the operation */ + ret=firmware_init_vme(cpld_info); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to init upgrade.(chain = %d)\n", + frm_dev != NULL ? frm_dev->chain : -1); + return FIRMWARE_FAILED; + } + break; + case FIRMWARE_JTAG_FINISH: + /* The VME upgrade mode completes the operation */ + ret=firmware_finish_vme(cpld_info); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to release upgrade.(chain = %d)\n", + frm_dev != NULL ? frm_dev->chain : -1); + return FIRMWARE_FAILED; + } + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("not find cmd: %d\r\n", cmd); + return -ENOTTY; + } /* End of switch */ + + return FIRMWARE_SUCCESS; +} + +static int firmware_cpld_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations cpld_dev_fops = { + .owner = THIS_MODULE, + .llseek = firmware_cpld_llseek, + .read = firmware_cpld_read, + .write = firmware_cpld_write, + .unlocked_ioctl = firmware_cpld_ioctl, + .open = firmware_cpld_open, + .release = firmware_cpld_release, +}; + +static int of_firmware_upgrade_config_init(struct device *dev, firmware_cpld_t *cpld_info) +{ + int ret; + char *name; + int i; + char buf[64]; + firmware_logic_dev_en_t *firmware_logic_dev_en_point; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_upgrade_config_init\r\n"); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + mem_clear(cpld_info, sizeof(firmware_cpld_t)); + ret = 0; + ret += of_property_read_string(dev->of_node, "type", (const char **)&name); + ret += of_property_read_u32(dev->of_node, "tdi", &cpld_info->tdi); + ret += of_property_read_u32(dev->of_node, "tck", &cpld_info->tck); + ret += of_property_read_u32(dev->of_node, "tms", &cpld_info->tms); + ret += of_property_read_u32(dev->of_node, "tdo", &cpld_info->tdo); + + ret += of_property_read_u32(dev->of_node, "chain", &cpld_info->chain); + ret += of_property_read_u32(dev->of_node, "chip_index", &cpld_info->chip_index); + + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config error, ret:%d.\n", ret); + return -ENXIO; + } + + strncpy(cpld_info->type, name, sizeof(cpld_info->type) - 1); + + ret = of_property_read_u32(dev->of_node, "tck_delay", &cpld_info->tck_delay); + if(ret != 0) { + cpld_info->tck_delay = 60; + } + + cpld_info->gpio_en_info_num = 0; + /* Enable through GPIO */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_gpio_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &cpld_info->gpio_en_info[i].en_gpio); + if(ret != 0) { + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_level_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &cpld_info->gpio_en_info[i].en_level); + if(ret != 0) { + break; + } + cpld_info->gpio_en_info_num++; + } + + cpld_info->logic_dev_en_num = 0; + /* Enable through register */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + firmware_logic_dev_en_point = &cpld_info->logic_dev_en_info[i]; + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_dev_%d", i); + ret = 0; + ret += of_property_read_string(dev->of_node, buf, (const char **)&name); + if(ret != 0) { + /* Failure to resolve to EN_LOGIC_DEV means no logical device is enabled. No failure is returned */ + ret = 0; + break; + } + strncpy(firmware_logic_dev_en_point->dev_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_addr_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->addr); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_addr_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_mask_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->mask); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_mask_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_en_val_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->en_val); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_en_val_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_dis_val_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->dis_val); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_dis_val_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_width_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->width); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_width_%d ret =%d.\n", i, ret); + break; + } + + cpld_info->logic_dev_en_num++; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("type:%s, chain:%u, chip_index:%u, gpio_en_info_num:%u logic_dev_en_num:%u\n", + cpld_info->type, cpld_info->chain, cpld_info->chip_index, cpld_info->gpio_en_info_num, cpld_info->logic_dev_en_num); + FIRMWARE_DRIVER_DEBUG_VERBOSE("tdi:%u, tck:%u, tms:%u, tdo:%u tck_delay:%u.\n", + cpld_info->tdi, cpld_info->tck, cpld_info->tms, cpld_info->tdo, cpld_info->tck_delay); + + return 0; +} + +static int firmware_upgrade_config_init(struct device *dev, firmware_cpld_t *cpld_info) +{ + int i; + + firmware_logic_dev_en_t *firmware_logic_dev_en_point; + firmware_upgrade_device_t *firmware_upgrade_device; + firmware_jtag_device_t jtag_upg_device; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_upgrade_config_init\r\n"); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + if (dev->platform_data == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("platform data config error.\n"); + return -1; + } + firmware_upgrade_device = dev->platform_data; + jtag_upg_device = firmware_upgrade_device->upg_type.jtag; + + mem_clear(cpld_info, sizeof(firmware_cpld_t)); + strncpy(cpld_info->type, firmware_upgrade_device->type, sizeof(cpld_info->type) - 1); + cpld_info->tdi = jtag_upg_device.tdi; + cpld_info->tck = jtag_upg_device.tck; + cpld_info->tms = jtag_upg_device.tms; + cpld_info->tdo = jtag_upg_device.tdo; + cpld_info->chain = firmware_upgrade_device->chain; + cpld_info->chip_index = firmware_upgrade_device->chip_index; + + if (jtag_upg_device.tck_delay == 0) { + cpld_info->tck_delay = 60; + FIRMWARE_DRIVER_DEBUG_VERBOSE("no config tck_delay, use default value:%u\n", cpld_info->tck_delay); + } else { + cpld_info->tck_delay = jtag_upg_device.tck_delay; + } + + if (firmware_upgrade_device->en_gpio_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_gpio_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_gpio_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + cpld_info->gpio_en_info_num = firmware_upgrade_device->en_gpio_num; + /* Enable through GPIO */ + for (i = 0; i < cpld_info->gpio_en_info_num; i++) { + cpld_info->gpio_en_info[i].en_gpio = firmware_upgrade_device->en_gpio[i]; + cpld_info->gpio_en_info[i].en_level = firmware_upgrade_device->en_level[i]; + } + + if (firmware_upgrade_device->en_logic_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_logic_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_logic_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + cpld_info->logic_dev_en_num = firmware_upgrade_device->en_logic_num; + /* Enable through register */ + for (i = 0; i < cpld_info->logic_dev_en_num; i++) { + firmware_logic_dev_en_point = &cpld_info->logic_dev_en_info[i]; + strncpy(firmware_logic_dev_en_point->dev_name, firmware_upgrade_device->en_logic_dev[i], + FIRMWARE_DEV_NAME_LEN - 1); + firmware_logic_dev_en_point->addr = firmware_upgrade_device->en_logic_addr[i]; + firmware_logic_dev_en_point->mask = firmware_upgrade_device->en_logic_mask[i]; + firmware_logic_dev_en_point->en_val = firmware_upgrade_device->en_logic_en_val[i]; + firmware_logic_dev_en_point->dis_val = firmware_upgrade_device->en_logic_dis_val[i]; + firmware_logic_dev_en_point->width = firmware_upgrade_device->en_logic_width[i]; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("type:%s, chain:%u, chip_index:%u, gpio_en_info_num:%u logic_dev_en_num:%u\n", + cpld_info->type, cpld_info->chain, cpld_info->chip_index, cpld_info->gpio_en_info_num, cpld_info->logic_dev_en_num); + FIRMWARE_DRIVER_DEBUG_VERBOSE("tdi:%u, tck:%u, tms:%u, tdo:%u tck_delay:%u.\n", + cpld_info->tdi, cpld_info->tck, cpld_info->tms, cpld_info->tdo, cpld_info->tck_delay); + + return 0; +} + +static int firmware_cpld_probe(struct platform_device *pdev) +{ + int ret; + firmware_cpld_t *cpld_info; + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_cpld_probe\r\n"); + /* Gets the information in the device tree */ + cpld_info = devm_kzalloc(&pdev->dev, sizeof(firmware_cpld_t), GFP_KERNEL); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc cpld device tree.\n"); + return -EPERM; + } + + if (pdev->dev.of_node) { + ret = of_firmware_upgrade_config_init(&pdev->dev, cpld_info); + } else { + ret = firmware_upgrade_config_init(&pdev->dev, cpld_info); + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("get config init from dts error.\n"); + return -EPERM; + } + + frm_dev = devm_kzalloc(&pdev->dev, sizeof(firmware_device_t), GFP_KERNEL); + if (frm_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc firmware device.\n"); + return -EPERM; + } + + /* Based on the link number, determine the name of the device file */ + frm_dev->chain = cpld_info->chain; + snprintf(frm_dev->name, FIRMWARE_NAME_LEN - 1, "firmware_cpld_ispvme%d", frm_dev->chain); + strncpy(cpld_info->devname, frm_dev->name, strlen(frm_dev->name) + 1); + + INIT_LIST_HEAD(&frm_dev->list); + frm_dev->dev.minor = MISC_DYNAMIC_MINOR; + frm_dev->dev.name = frm_dev->name; + frm_dev->dev.fops = &cpld_dev_fops; + frm_dev->priv = cpld_info; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Register cpld firmware chain:%d, name:%s.\n", frm_dev->chain, frm_dev->name); + + ret = firmware_device_register(frm_dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to register firmware device.\n"); + return -EPERM; + } + + platform_set_drvdata(pdev, frm_dev); + return 0; +} + +static int __exit firmware_cpld_remove(struct platform_device *pdev) +{ + firmware_device_t *frm_dev; + + frm_dev = (firmware_device_t *)platform_get_drvdata(pdev); + firmware_device_unregister(frm_dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct of_device_id cpld_match[] = { + { + .compatible = "firmware_cpld_ispvme", + }, + {}, +}; + +static struct platform_driver cpld_driver = { + .driver = { + .name = "firmware_cpld_ispvme", + .owner = THIS_MODULE, + .of_match_table = cpld_match, + }, + .probe = firmware_cpld_probe, + .remove = firmware_cpld_remove, +}; + +static firmware_driver_t fmw_drv_cpld = { + .name = "firmware_cpld_ispvme", + .drv = &cpld_driver, +}; + +int firmware_cpld_init(void) +{ + int ret; + + INIT_LIST_HEAD(&fmw_drv_cpld.list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("ispvme upgrade driver register \n"); + ret = firmware_driver_register(&fmw_drv_cpld); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("ispvme upgrade driver register failed\n"); + return ret; + } + return 0; +} + +void firmware_cpld_exit(void) +{ + firmware_driver_unregister(&fmw_drv_cpld); + INIT_LIST_HEAD(&fmw_drv_cpld.list); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_upgrade_ispvme.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_upgrade_ispvme.c new file mode 100644 index 000000000000..b8896ed75f38 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_upgrade_ispvme.c @@ -0,0 +1,691 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* TCK clock MAX 16MHz */ +#define TCK_DELAY (current_fmw_cpld->tck_delay) + +#if 0 +static firmware_cpld_t default_fmw_cpld; +#endif + +static firmware_cpld_t *current_fmw_cpld; + +static int TDI_PULL_UP(void); +static int TDI_PULL_DOWN(void); +static int TMS_PULL_UP(void); +static int TMS_PULL_DOWN(void); +static int TCK_PULL_UP(void); +static int TCK_PULL_DOWN(void); + +/* + * set_currrent_cpld_info + * function: Save the current device information + * @info: param[in] Information about the device to be updated + */ +static void set_currrent_cpld_info(firmware_cpld_t *info) +{ + current_fmw_cpld = info; +} + +static int firmware_file_read(const char *path, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + FIRMWARE_DRIVER_DEBUG_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + pos = (loff_t)addr; + ret = kernel_read(filp, val, size, &pos); + if (ret != size) { + FIRMWARE_DRIVER_DEBUG_ERROR("read kernel_read failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, addr, size, ret); + goto exit; + } + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int firmware_file_write(const char *path, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + FIRMWARE_DRIVER_DEBUG_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + pos = (loff_t)addr; + ret = kernel_write(filp, (void*)val, size, &pos); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("write kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, addr, size, ret); + goto exit; + } + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +/* + * firmware_file_do_work + * function: Sets logical register values + * @path:param[in] Logic device descriptor + * @addr:param[in] Logic device address + * @value:param[in] the register value needs to be set + * @mask:param[in] register mask + * @width:param[in] register bit width + * return: 0:success, <0:failed + */ +static int firmware_file_do_work(char *path, uint32_t addr, uint32_t value, uint32_t mask, + int32_t width) +{ + int ret; + uint8_t read_value[4], write_value[4]; + uint8_t tmp_read8, tmp_write8, tmp_mask8; + uint32_t tmp_read32, tmp_write32; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("path=%s, addr=0x%x, value=0x%x mask=0x%x\r\n", path, addr, value, mask); + if ((width > 4) || (width < 0)) { + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + } + ret = 0; + mem_clear(read_value, sizeof(read_value)); + mem_clear(write_value, sizeof(write_value)); + ret = firmware_file_read(path, addr, read_value, width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware sysfs read.\r\n"); + return -1; + } + + switch (width) { + case 1: + tmp_read8 = read_value[0]; + tmp_mask8 = (uint8_t)(mask) & 0xFF; + tmp_write8 = (uint8_t)value & 0xFF; + write_value[0] = (tmp_read8 & tmp_mask8) | tmp_write8; + FIRMWARE_DRIVER_DEBUG_VERBOSE("1 byte write val[0]:0x%x", write_value[0]); + break; + case 2: + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + case 4: + memcpy((uint8_t *)&tmp_read32, read_value, 4); + tmp_write32 = (tmp_read32 & mask) | value; + memcpy(write_value, (uint8_t *)&tmp_write32, 4); + FIRMWARE_DRIVER_DEBUG_VERBOSE("4 byte write val[0]:0x%x, val[1]:0x%x, val[2]:0x%x, val[3]:0x%x", + write_value[0], write_value[1], write_value[2], write_value[3]); + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("write logic dev[%s] addr[0x%x].\r\n", path, addr); + ret = firmware_file_write(path, addr, write_value, width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware_file_write %s addr 0x%x failed, ret=%d.\r\n", path, addr, ret); + return -1; + } + + return 0; +} + +/* + * firmware_upgrade_en + * function: Upgrade access enabling switch + * @flag: !0:enable 0:disable + */ +static int firmware_upgrade_en(int flag) +{ + int i; + firmware_logic_dev_en_t *firmware_logic_dev_en_info; + int ret, rv; + char *dev_name; + + ret = 0; + FIRMWARE_DRIVER_DEBUG_VERBOSE("%s en switch: gpio en num %d, logic reg en num %d.\n", + flag ? "Open" : "Close", current_fmw_cpld->gpio_en_info_num, current_fmw_cpld->logic_dev_en_num); + for (i = 0; i < current_fmw_cpld->gpio_en_info_num; i++) { + if (flag) { + ret = gpio_request(current_fmw_cpld->gpio_en_info[i].en_gpio, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade EN[%d] GPIO[%d] failed!\n", + i, current_fmw_cpld->gpio_en_info[i].en_gpio); + goto free_gpio; + } + gpio_direction_output(current_fmw_cpld->gpio_en_info[i].en_gpio, current_fmw_cpld->gpio_en_info[i].en_level); + current_fmw_cpld->gpio_en_info[i].flag = 1; + } else { + gpio_set_value(current_fmw_cpld->gpio_en_info[i].en_gpio, !current_fmw_cpld->gpio_en_info[i].en_level); + gpio_free(current_fmw_cpld->gpio_en_info[i].en_gpio); + current_fmw_cpld->gpio_en_info[i].flag = 0; + } + } + + for (i = 0; i < current_fmw_cpld->logic_dev_en_num; i++) { + firmware_logic_dev_en_info = ¤t_fmw_cpld->logic_dev_en_info[i]; + dev_name = firmware_logic_dev_en_info->dev_name; + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware sysfs [%d] dev_name[%s] addr[0x%x] mask[0x%x]" + " en_val[0x%x] dis_val[0x%x] width[%d]\n", + i , firmware_logic_dev_en_info->dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->mask, firmware_logic_dev_en_info->en_val, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->width); + if (flag) { + ret = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->en_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Open logic register [%d] EN failed, ret %d.\n", i, ret); + goto free_logic_dev; + } else { + firmware_logic_dev_en_info->flag = 1; + } + } else { + rv = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (rv < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Close logic register [%d] EN failed, ret %d.\n", i, rv); + ret = -1; + } + firmware_logic_dev_en_info->flag = 0; + } + } + + return ret; +free_logic_dev: + for (i = 0; i < current_fmw_cpld->logic_dev_en_num; i++) { + firmware_logic_dev_en_info = ¤t_fmw_cpld->logic_dev_en_info[i]; + dev_name = firmware_logic_dev_en_info->dev_name; + if (firmware_logic_dev_en_info->flag == 1) { + ret = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Close logic register [%d] EN failed, ret %d.\n", i, ret); + } + firmware_logic_dev_en_info->flag = 0; + } else { + break; + } + } +free_gpio: + for (i = 0; i < current_fmw_cpld->gpio_en_info_num; i++) { + if (current_fmw_cpld->gpio_en_info[i].flag == 1) { + gpio_set_value(current_fmw_cpld->gpio_en_info[i].en_gpio, !current_fmw_cpld->gpio_en_info[i].en_level); + gpio_free(current_fmw_cpld->gpio_en_info[i].en_gpio); + current_fmw_cpld->gpio_en_info[i].flag = 0; + } else { + break; + } + } + + return -1; +} + +/* + * init_cpld + * function:Initialize CPLD + * return value: 0 success ; -1 fail + */ +static int init_cpld(void) +{ + int ret; + if (current_fmw_cpld == NULL) { + return -1; + } + mdelay(10); + ret = 0; + ret = gpio_request(current_fmw_cpld->tdi, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade TDI GPIO failed!\n"); + return ret; + } + ret = gpio_request(current_fmw_cpld->tck, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade TCK GPIO failed!\n"); + goto free_tdi; + } + ret = gpio_request(current_fmw_cpld->tms, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade TMS GPIO failed!\n"); + goto free_tck; + } + ret = gpio_request(current_fmw_cpld->tdo, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade TDO GPIO failed!\n"); + goto free_tms; + } + + gpio_direction_output(current_fmw_cpld->tdi, 1); + gpio_direction_output(current_fmw_cpld->tck, 1); + gpio_direction_output(current_fmw_cpld->tms, 1); + + gpio_direction_input(current_fmw_cpld->tdo); + ret = firmware_upgrade_en(1); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: open firmware upgrade en failed, ret %d.\n", ret); + goto free_tdo; + } +#if 0 + /* test GPIO */ + if (TDI_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TDI_PULL_UP failed.\n"); + goto free_tdo; + } + if (TDI_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TDI_PULL_DOWN failed.\n"); + goto free_tdo; + } + if (TMS_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TMS_PULL_UP failed.\n"); + goto free_tdo; + } + if (TMS_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TMS_PULL_DOWN failed.\n"); + goto free_tdo; + } + if (TCK_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TCK_PULL_UP failed.\n"); + goto free_tdo; + } + if (TCK_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TCK_PULL_DOWN failed.\n"); + goto free_tdo; + } +#endif + mdelay(10); + return 0; + +free_tdo: + gpio_free(current_fmw_cpld->tdo); +free_tms: + gpio_free(current_fmw_cpld->tms); +free_tck: + gpio_free(current_fmw_cpld->tck); +free_tdi: + gpio_free(current_fmw_cpld->tdi); + return ret; +} + +/* + * finish_cpld + * function: finish CPLD upgrade operation + * return value: 0 success ; -1 fail + */ +static int finish_cpld(void) +{ + int ret; + + if (current_fmw_cpld == NULL) { + return -1; + } + mdelay(10); + ret = firmware_upgrade_en(0); + if (ret < 0){ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: close firmware upgrade en failed, ret %d.\r\n", ret); + } + + gpio_free(current_fmw_cpld->tdi); + gpio_free(current_fmw_cpld->tck); + gpio_free(current_fmw_cpld->tms); + gpio_free(current_fmw_cpld->tdo); + mdelay(10); + return 0; +} + +/* Loop waiting for */ +static int pull_wait(int gpio, int value) { + int i, j; + /* Timeout time is two seconds */ + for (i = 0; i < 20; i++) { + for (j = 0; j < 100; j++) { + if (!!gpio_get_value(gpio) == !!value ) { + return 0; + } + /* The first loop does not delay, normally the first loop can immediately return the result */ + if (i) { + mdelay(1); + } + } + /* The CPU is released every 100ms */ + schedule(); + } + /* timeout */ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Wait gpio %d pull to %d failed.\n", gpio, value); + return -1; +} + +/* TDI pull-up */ +static int pull_tdi_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tdi, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tdi, 1); +} + +/* TDI pull-down */ +static int pull_tdi_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tdi, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tdi, 0); +} + +/* TCK pull-up */ +static int pull_tck_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tck, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tck, 1); +} + +/* TCK pull-down */ +static int pull_tck_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tck, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tck, 0); +} + +/* TMS pull-up */ +static int pull_tms_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tms, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tms, 1); +} + +/* TMS pull-down */ +static int pull_tms_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tms, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tms, 0); +} + +/* Read TDO */ +static int read_tdo(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + return gpio_get_value(current_fmw_cpld->tdo); +} + +static firmware_cpld_function_t function_fmw_cpld = { + .pull_tdi_up = pull_tdi_up, + .pull_tdi_down = pull_tdi_down, + .pull_tck_up = pull_tck_up, + .pull_tck_down = pull_tck_down, + .pull_tms_up = pull_tms_up, + .pull_tms_down = pull_tms_down, + .read_tdo = read_tdo, + .init_cpld = init_cpld, + .finish_cpld = finish_cpld, +}; + +/* + * TDI_PULL_DOWN + * function: Lower TDI + */ +static int TDI_PULL_DOWN(void) +{ + if ( function_fmw_cpld.pull_tdi_down != NULL) { + return function_fmw_cpld.pull_tdi_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDI_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TDI_PULL_UP + * function: High TDI + */ +static int TDI_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tdi_up != NULL) { + return function_fmw_cpld.pull_tdi_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDI_PULL_UP.\n"); + return -1; + } +} + +/* + * TCK_PULL_DOWN + * function: Lower TCK + */ +static int TCK_PULL_DOWN(void) +{ + if (function_fmw_cpld.pull_tck_down != NULL) { + return function_fmw_cpld.pull_tck_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TCK_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TCK_PULL_UP + * function: High TCK + */ +static int TCK_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tck_up != NULL) { + return function_fmw_cpld.pull_tck_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TCK_PULL_UP.\n"); + return -1; + } +} + +/* + * TMS_PULL_DOWN + * function: Lower TMS + */ +static int TMS_PULL_DOWN(void) +{ + if (function_fmw_cpld.pull_tms_down != NULL) { + return function_fmw_cpld.pull_tms_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TMS_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TMS_PULL_UP + * function: High TMS + */ +static int TMS_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tms_up != NULL) { + return function_fmw_cpld.pull_tms_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TMS_PULL_UP.\n"); + return -1; + } +} + +/* + * TDO_READ + * function:Read the TDO level + */ +static int TDO_READ(void) +{ + if (function_fmw_cpld.read_tdo != NULL) { + return function_fmw_cpld.read_tdo(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDO_READ.\n"); + return -1; + } +} + +/* + * cpld_upgrade_init + * function:Initialize GPIO and CPLD + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int cpld_upgrade_init(void) +{ + int ret; + + if (function_fmw_cpld.init_cpld != NULL) { + ret = function_fmw_cpld.init_cpld(); + if (ret != FIRMWARE_SUCCESS) { + return ret; + } + } + + return FIRMWARE_SUCCESS; +} + +/* + * cpld_upgrade_finish + * function:Release GPIO and CPLD + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int cpld_upgrade_finish(void) +{ + int ret; + + if (function_fmw_cpld.finish_cpld != NULL) { + ret = function_fmw_cpld.finish_cpld(); + if (ret != FIRMWARE_SUCCESS) { + return ret; + } + } + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_init_vme + * function: Initialize GPIO, + * @cpld_info: param[in] Information about the device to be written to + */ +int firmware_init_vme(firmware_cpld_t *cpld_info){ + int ret; + set_currrent_cpld_info(cpld_info); + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init(); + return ret; +} + +/** + * firmware_finish_vme + * function: Release GPIO + * @cpld_info: param[in] Information about the device to be written to + */ +int firmware_finish_vme(firmware_cpld_t *cpld_info){ + int ret; + set_currrent_cpld_info(cpld_info); + ret = cpld_upgrade_finish(); + return ret; +} + +/** + * fwm_cpld_tdi_op + * function: Operate TDI + * @value: param[in] TDI level */ +int fwm_cpld_tdi_op(int value) +{ + if (value) { + return TDI_PULL_UP(); + } else { + return TDI_PULL_DOWN(); + } +} + +/** + * fwm_cpld_tck_op + * function: Operate TCK + * @value: param[in] TCK level */ +int fwm_cpld_tck_op(int value) +{ + if (value) { + return TCK_PULL_UP(); + } else { + return TCK_PULL_DOWN(); + } +} + +/** + * fwm_cpld_tms_op + * function: Operate TMS + * value: param[in] TMS level */ +int fwm_cpld_tms_op(int value) +{ + if (value) { + return TMS_PULL_UP(); + } else { + return TMS_PULL_DOWN(); + } +} + +/** + * fwm_cpld_tdo_op + * function: Read TDO + */ +int fwm_cpld_tdo_op() +{ + return TDO_READ(); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_ispvme.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_ispvme.c new file mode 100644 index 000000000000..e8f75844ae34 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_ispvme.c @@ -0,0 +1,140 @@ +#include +#include +#include + +int g_firmware_driver_debug = 0; +module_param(g_firmware_driver_debug, int, S_IRUGO | S_IWUSR); + +static LIST_HEAD(drv_list); +static LIST_HEAD(dev_list); + +/** + * firmware_driver_register + * function:Registered Device Driver + * @fw_drv:param[in] Driver information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_driver_register(firmware_driver_t *fw_drv) +{ + int ret; + + if (fw_drv == NULL) { + return FIRMWARE_FAILED; + } + + ret = platform_driver_register(fw_drv->drv); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: failed to register firmware upgrade driver \n"); + return FIRMWARE_FAILED; + } + + /* Adds driver information to the driver list */ + list_add(&fw_drv->list, &drv_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware upgrade driver register sucess \n"); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_driver_unregister + * function:unregister Device Driver + * @fw_drv:param[in] Driver information + */ +void firmware_driver_unregister(firmware_driver_t *fw_drv) +{ + list_del_init(&fw_drv->list); + platform_driver_unregister(fw_drv->drv); +} + +/* + * firmware_get_device_by_minor + * function: Get device information based on minor + */ +firmware_device_t *firmware_get_device_by_minor(int minor) +{ + firmware_device_t *tmp; + + list_for_each_entry(tmp, &dev_list, list) { + if (tmp->dev.minor == minor) { + return tmp; + } + } + + return NULL; +} + +/** + * firmware_device_register + * function:Registered Driver Device + * @fw_dev: param[in] Driver information + * return value:success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_device_register(firmware_device_t *fw_dev) +{ + int ret; + firmware_device_t *tmp; + + if (fw_dev == NULL) { + return FIRMWARE_FAILED; + } + /* Check whether the device file name already exists in the device linked list */ + list_for_each_entry(tmp, &dev_list, list) { + if (strcmp(tmp->name, fw_dev->name) == 0) { + return FIRMWARE_FAILED; + } + } + + /* Registere device */ + ret = misc_register(&fw_dev->dev); + if (ret < 0) { + return FIRMWARE_FAILED; + } + + /* Adds a device to the device list */ + list_add(&fw_dev->list, &dev_list); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_device_unregister + * function: unregister Driver Device + */ +void firmware_device_unregister(firmware_device_t *fw_dev) +{ + list_del(&fw_dev->list); + misc_deregister(&fw_dev->dev); +} + +static int __init firmware_driver_init(void) +{ + int ret; + + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver ispvme init.\n"); + ret = firmware_cpld_init(); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware driver ispvme init failed.\n"); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +static void __exit firmware_driver_exit(void) +{ + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver ispvme exit.\n"); + firmware_cpld_exit(); + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + return; +} + +module_init(firmware_driver_init); +module_exit(firmware_driver_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Firmware upgrade ispvme driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_cpld_ispvme.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_cpld_ispvme.h new file mode 100644 index 000000000000..eb737d3a56ed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_cpld_ispvme.h @@ -0,0 +1,70 @@ +#ifndef __FIRMWARE_CPLD_H__ +#define __FIRMWARE_CPLD_H__ + +#define FIRMWARE_DEV_NAME_LEN 32 +#define FIRMWARE_MAX_CPLD_NUM 16 +#define FIRMWARE_TYPE_LEN 10 +#define FIRMWARE_EN_INFO_MAX 16 +#define FIRMWARE_EN_INFO_BUF 128 + +typedef struct firmware_gpio_jtag_en_s { + uint32_t en_gpio; /* GPIO enable pin */ + uint32_t en_level; /* GPIO enable level */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_gpio_jtag_en_t; + +typedef struct firmware_logic_dev_en_s { + char dev_name[FIRMWARE_DEV_NAME_LEN]; /* Logical device name */ + uint32_t addr; /* Enable register address */ + uint32_t mask; /* mask */ + uint32_t en_val; /* Enable value */ + uint32_t dis_val; /* Disable value*/ + uint32_t width; /* width */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_logic_dev_en_t; + +typedef struct firmware_cpld_s { + char devname[FIRMWARE_DEV_NAME_LEN]; /* Device name */ + char type[FIRMWARE_TYPE_LEN]; /* interface type */ + uint32_t tdi; /* TDI signal corresponding to GPIO pin information */ + uint32_t tck; /* TCK signal corresponding to GPIO pin information */ + uint32_t tms; /* TMS signal corresponding to GPIO pin information */ + uint32_t tdo; /* TDO signal corresponding to GPIO pin information */ + uint32_t chain; /* chain num */ + uint32_t chip_index; /* chip index */ + uint32_t tck_delay; /* Delay time */ + uint32_t gpio_en_info_num; /* GPIO Enable Number */ + firmware_gpio_jtag_en_t gpio_en_info[FIRMWARE_EN_INFO_MAX]; /* GPIO Enable Information */ + uint32_t logic_dev_en_num; /* Register Enable Number */ + firmware_logic_dev_en_t logic_dev_en_info[FIRMWARE_EN_INFO_MAX]; /* Register Enable Information */ +} firmware_cpld_t; + +typedef struct firmware_cpld_function_s{ + int (*pull_tdi_up)(void); /* TDI pull-up */ + int (*pull_tdi_down)(void); /* TDI pull-down */ + int (*pull_tck_up)(void); /* TCK pull-up */ + int (*pull_tck_down)(void); /* TCK pull-down */ + int (*pull_tms_up)(void); /* TMS pull-up */ + int (*pull_tms_down)(void); /* TCK pull-down */ + int (*read_tdo)(void); /* Read TDO */ + int (*init_cpld)(void); /* CPLD upgrade initializes the operation */ + int (*init_chip)(int chain); /* chip initializes the operation */ + int (*finish_chip)(int chain); /* chip completes the operation*/ + int (*finish_cpld)(void); /* CPLD upgrade completes the operation */ + int (*get_version)(int chain, char *ver, int len); /* get version */ +}firmware_cpld_function_t; + +/* operate TDI */ +extern int fwm_cpld_tdi_op(int value); +/* operate TCK */ +extern int fwm_cpld_tck_op(int value); +/* operate TMS */ +extern int fwm_cpld_tms_op(int value); +/* operate TDO */ +extern int fwm_cpld_tdo_op(void); +/* VME upgrade mode completes the operation*/ +extern int firmware_finish_vme(firmware_cpld_t *cpld_info); +/* VME upgrade mode initializes the operation*/ +extern int firmware_init_vme(firmware_cpld_t *cpld_info); + +#endif /* __FIRMWARE_CPLD_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_ispvme.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_ispvme.h new file mode 100644 index 000000000000..39baf3f30717 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_ispvme.h @@ -0,0 +1,86 @@ +#ifndef __FIRMWARE_H__ +#define __FIRMWARE_H__ + +#include +#include + +#include + +/* Debug switch level */ +typedef enum { + FIRWMARE_VERBOSE, + FIRWMARE_WARN, + FIRWMARE_ERROR, + FIRWMARE_END, +} firmware_debug_level_t; + +#define FIRMWARE_DRIVER_DEBUG_VERBOSE(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_VERBOSE)) { \ + printk(KERN_INFO "[FIRMWARW_DRIVER_ISPVME][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_DRIVER_DEBUG_ERROR(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_ERROR)) { \ + printk(KERN_ERR "[FIRMWARW_DRIVER_ISPVME][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_NAME_LEN 48 + +#define FIRMWARE_FAILED (-1) +#define FIRMWARE_SUCCESS 0 + +/* ioctl publi command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_COMMON_TYPE 'C' +#define FIRMWARE_GET_CHIPNAME _IOR(FIRMWARE_COMMON_TYPE, 0, char) /* get the chip name */ +#define FIRMWARE_GET_VERSION _IOR(FIRMWARE_COMMON_TYPE, 2, int) /* get version */ + +/* firmware cpld ispvme driver ioctl command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_VME_TYPE 'V' +#define FIRMWARE_JTAG_TDI _IOR(FIRMWARE_VME_TYPE, 0, char) +#define FIRMWARE_JTAG_TDO _IOR(FIRMWARE_VME_TYPE, 1, char) +#define FIRMWARE_JTAG_TCK _IOR(FIRMWARE_VME_TYPE, 2, char) +#define FIRMWARE_JTAG_TMS _IOR(FIRMWARE_VME_TYPE, 3, char) +#define FIRMWARE_JTAG_EN _IOR(FIRMWARE_VME_TYPE, 4, char) +#define FIRMWARE_JTAG_INIT _IOR(FIRMWARE_VME_TYPE, 7, char) /* enable upgrade access */ +#define FIRMWARE_JTAG_FINISH _IOR(FIRMWARE_VME_TYPE, 8, char) /* disable upgrade access */ + +typedef struct cmd_info_s { + uint32_t size; + void __user *data; +} cmd_info_t; + +typedef struct firmware_device_s { + struct list_head list; /* device list */ + uint32_t chain; /* chain number */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct miscdevice dev; /* device */ + void *priv; /* private data */ +} firmware_device_t; + +typedef struct firmware_driver_s { + struct list_head list; /* list */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct platform_driver *drv; /* driver */ + void *priv; /* private data */ +} firmware_driver_t; + +extern int g_firmware_driver_debug; + +/* Get device information based on minor */ +extern firmware_device_t *firmware_get_device_by_minor(int minor); +/* Registere device */ +extern int firmware_device_register(firmware_device_t *fw_dev); +/* Unregister device */ +extern void firmware_device_unregister(firmware_device_t *fw_dev); +/* Registere driver */ +extern int firmware_driver_register(firmware_driver_t *fw_drv); +/* Unregister driver */ +extern void firmware_driver_unregister(firmware_driver_t *fw_drv); +/* CPLD upgrade initialized */ +extern int firmware_cpld_init(void); +/* CPLD unload function */ +extern void firmware_cpld_exit(void); + +#endif /* end of __FIRMWARE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/Makefile new file mode 100644 index 000000000000..a1d6d2e2ef68 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/Makefile @@ -0,0 +1,22 @@ +#include $(top_srcdir)/debian/rules +#KERNELDIR := ${KBUILD_OUTPUT} + +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../include) +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) +EXTRA_CFLAGS+= -Wall + +firmware_driver_sysfs-objs := firmware.o +firmware_driver_sysfs-objs += firmware_sysfs.o firmware_sysfs_upgrade.o + +#ifndef CONFIG_FRM_PRODUCT_FILE + +$(warning $(firmware_driver_sysfs-objs)) +obj-m := firmware_driver_sysfs.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(common_module_dir) ]; then mkdir -p $(common_module_dir) ;fi + cp -p $(PWD)/*.ko $(common_module_dir) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware.c new file mode 100644 index 000000000000..fec51d6238a6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware.c @@ -0,0 +1,143 @@ +#include +#include +#include + +int g_firmware_driver_debug = 0; +module_param(g_firmware_driver_debug, int, S_IRUGO | S_IWUSR); + +static LIST_HEAD(drv_list); +static LIST_HEAD(dev_list); + +/** + * firmware_driver_register + * function:Registered Device Driver + * @fw_drv:param[in] Driver information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_driver_register(firmware_driver_t *fw_drv) +{ + int ret; + + if (fw_drv == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Parameter error.\n"); + return FIRMWARE_FAILED; + } + + ret = platform_driver_register(fw_drv->drv); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: failed to register firmware upgrade driver \n"); + return FIRMWARE_FAILED; + } + + /* Adds driver information to the driver list */ + list_add(&fw_drv->list, &drv_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware upgrade driver register sucess \n"); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_driver_unregister + * function:unregister Device Driver + * @fw_drv:param[in] Driver information + */ +void firmware_driver_unregister(firmware_driver_t *fw_drv) +{ + list_del_init(&fw_drv->list); + platform_driver_unregister(fw_drv->drv); +} + +/* + * firmware_get_device_by_minor + * function: Get device information based on minor + */ +firmware_device_t *firmware_get_device_by_minor(int minor) +{ + firmware_device_t *tmp; + + list_for_each_entry(tmp, &dev_list, list) { + if (tmp->dev.minor == minor) { + return tmp; + } + } + + return NULL; +} + +/** + * firmware_device_register + * function:Registered Driver Device + * @fw_dev: param[in] Driver information + * return value:success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_device_register(firmware_device_t *fw_dev) +{ + int ret; + firmware_device_t *tmp; + + if (fw_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Parameter error.\n"); + return FIRMWARE_FAILED; + } + /* Check whether the device file name already exists in the device linked list */ + list_for_each_entry(tmp, &dev_list, list) { + if (strcmp(tmp->name, fw_dev->name) == 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("devie %s already exists.\n", fw_dev->name); + return FIRMWARE_FAILED; + } + } + + ret = misc_register(&fw_dev->dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("register misc error, ret=%d.\n", ret); + return FIRMWARE_FAILED; + } + + /* Adds driver information to the driver list */ + list_add(&fw_dev->list, &dev_list); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_device_unregister + * function: unregister Driver Device + */ +void firmware_device_unregister(firmware_device_t *fw_dev) +{ + list_del(&fw_dev->list); + misc_deregister(&fw_dev->dev); +} + +static int __init firmware_driver_init(void) +{ + int ret; + + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver sysfs init.\n"); + ret = firmware_sysfs_init(); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware driver sysfs init failed.\n"); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +static void __exit firmware_driver_exit(void) +{ + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver sysfs exit.\n"); + firmware_sysfs_exit(); + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + return; +} + +module_init(firmware_driver_init); +module_exit(firmware_driver_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Firmware upgrade driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs.c new file mode 100644 index 000000000000..a823cdc4f294 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs.c @@ -0,0 +1,495 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int firmware_sysfs_open(struct inode *inode, struct file *file) +{ + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Open device.\n"); + frm_dev = firmware_get_device_by_minor(MINOR(inode->i_rdev)); + if (frm_dev == NULL) { + return -ENXIO; + } + file->private_data = frm_dev; + + return FIRMWARE_SUCCESS; +} + +static ssize_t firmware_sysfs_read (struct file *file, char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static ssize_t firmware_sysfs_write (struct file *file, const char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static loff_t firmware_sysfs_llseek(struct file *file, loff_t offset, int origin) +{ + return 0; +} + +/* firmware_sysfs_ioctl +* function:ioctl command parsing function +* @file: param[in] device file name +* @cmd: param[in] command +* @arg: param[in] the parameters in the command +* return value: success-FIRMWARE_SUCCESS; fail:other value +*/ +static long firmware_sysfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + void __user *argp; + firmware_device_t *frm_dev; + firmware_sysfs_t *sysfs_info; + int ret; + + /* Get device private data */ + frm_dev = (firmware_device_t *)file->private_data; + sysfs_info = NULL; + if (frm_dev != NULL) { + if (frm_dev->priv != NULL) { + sysfs_info = (firmware_sysfs_t *)frm_dev->priv; + } + } + if (sysfs_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to frm_dev->priv sysfs info.\n"); + return FIRMWARE_FAILED; + } + argp = (void __user *)arg; + + switch (cmd) { + case FIRMWARE_SYSFS_INIT: + /* enable upgrade access */ + ret = firmware_init_dev_loc(sysfs_info); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to init upgrade.(chain = %d)\n", + frm_dev != NULL ? frm_dev->chain : -1); + return FIRMWARE_FAILED; + } + break; + case FIRMWARE_SYSFS_FINISH: + /* disable upgrade access */ + ret = firmware_finish_dev_loc(sysfs_info); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to release upgrade.(chain = %d)\n", + frm_dev != NULL ? frm_dev->chain : -1); + return FIRMWARE_FAILED; + } + break; + case FIRMWARE_SYSFS_SPI_INFO: + /* Get SPI logic device information */ + if (copy_to_user(argp, &sysfs_info->info.spi_logic_info, sizeof(firmware_spi_logic_info_t))) { + return -EFAULT; + } + break; + case FIRMWARE_SYSFS_DEV_FILE_INFO: + /*Get logic device information */ + if (copy_to_user(argp, &sysfs_info->info.dev_file_info, sizeof(firmware_dev_file_info_t))) { + return -EFAULT; + } + break; + case FIRMWARE_SYSFS_MTD_INFO: + /*Get logic device information */ + if (copy_to_user(argp, &sysfs_info->info.mtd_info, sizeof(firmware_mtd_info_t))) { + return -EFAULT; + } + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("not find cmd: %d\r\n", cmd); + return -ENOTTY; + } /* End of switch */ + + return FIRMWARE_SUCCESS; +} + +static int firmware_sysfs_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations sysfs_dev_fops = { + .owner = THIS_MODULE, + .llseek = firmware_sysfs_llseek, + .read = firmware_sysfs_read, + .write = firmware_sysfs_write, + .unlocked_ioctl = firmware_sysfs_ioctl, + .open = firmware_sysfs_open, + .release = firmware_sysfs_release, +}; + +/* Gets the information in the device tree */ +static int of_firmware_upgrade_config_init(struct device *dev, firmware_sysfs_t *sysfs_info) +{ + int ret; + char *name; + int8_t buf[64]; + int i; + firmware_logic_dev_en_t *firmware_logic_dev_en_point; + uint32_t test_base, test_size; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_dev_loc_config_init\r\n"); + if (sysfs_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + mem_clear(sysfs_info, sizeof(firmware_sysfs_t)); + ret = 0; + ret += of_property_read_string(dev->of_node, "type", (const char **)&name); + + ret += of_property_read_u32(dev->of_node, "chain", &sysfs_info->chain); + ret += of_property_read_u32(dev->of_node, "chip_index", &sysfs_info->chip_index); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config error, ret:%d.\n", ret); + return -ENXIO; + } + strncpy(sysfs_info->type, name, sizeof(sysfs_info->type) - 1); + + ret = of_property_read_u32(dev->of_node, "test_base", &test_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config test_base, ret:%d.\n", ret); + test_base = 0; + } + + ret = of_property_read_u32(dev->of_node, "test_size", &test_size); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config test_size, ret:%d.\n", ret); + test_size = 0; + } + + if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_SPI_LOGIC) == 0) { + ret = of_property_read_string(dev->of_node, "dev_name", (const char **)&name); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config dev_name error, ret:%d.\n", ret); + return -ENXIO; + } + strncpy(sysfs_info->info.spi_logic_info.dev_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + ret = of_property_read_u32(dev->of_node, "flash_base", &sysfs_info->info.spi_logic_info.flash_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config flash_base error, ret:%d.\n", ret); + return -ENXIO; + } + + ret = of_property_read_u32(dev->of_node, "ctrl_base", &sysfs_info->info.spi_logic_info.ctrl_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config ctrl_base error, ret:%d.\n", ret); + return -ENXIO; + } + sysfs_info->info.spi_logic_info.test_base = test_base; + sysfs_info->info.spi_logic_info.test_size = test_size; + } else if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_SYSFS) == 0) { + ret = of_property_read_string(dev->of_node, "sysfs_name", (const char **)&name); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config sysfs_name error, ret:%d.\n", ret); + return -ENXIO; + } + strncpy(sysfs_info->info.dev_file_info.sysfs_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + ret = of_property_read_u32(dev->of_node, "dev_base", &sysfs_info->info.dev_file_info.dev_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("dts don't config dev_base, dev_base is 0.\n"); + sysfs_info->info.dev_file_info.dev_base = 0; + } + + ret = of_property_read_u32(dev->of_node, "per_len", &sysfs_info->info.dev_file_info.per_len); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("dts don't config per_len, per_len is 0.\n"); + sysfs_info->info.dev_file_info.per_len = 0; + } + sysfs_info->info.dev_file_info.test_base = test_base; + sysfs_info->info.dev_file_info.test_size = test_size; + } else if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_MTD) == 0) { + ret = of_property_read_string(dev->of_node, "mtd_name", (const char **)&name); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config mtd_name error, ret:%d.\n", ret); + return -ENXIO; + } + strncpy(sysfs_info->info.mtd_info.mtd_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + ret = of_property_read_u32(dev->of_node, "flash_base", &sysfs_info->info.mtd_info.flash_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config flash_base error, ret:%d.\n", ret); + return -ENXIO; + } + sysfs_info->info.mtd_info.test_base = test_base; + sysfs_info->info.mtd_info.test_size = test_size; + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config sysfs type[%s] is not support, ret:%d.\n", sysfs_info->type, ret); + return -ENXIO; + } + + sysfs_info->gpio_en_info_num = 0; + /* Enable through GPIO */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_gpio_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &sysfs_info->gpio_en_info[i].en_gpio); + if(ret != 0) { + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_level_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &sysfs_info->gpio_en_info[i].en_level); + if(ret != 0) { + break; + } + sysfs_info->gpio_en_info_num++; + } + + sysfs_info->logic_dev_en_num = 0; + /* Enable through register */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + firmware_logic_dev_en_point = &sysfs_info->logic_dev_en_info[i]; + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_dev_%d", i); + ret = 0; + ret += of_property_read_string(dev->of_node, buf, (const char **)&name); + if(ret != 0) { + /* Failure to resolve to EN_LOGIC_DEV means no logical device is enabled. No failure is returned */ + ret = 0; + break; + } + strncpy(firmware_logic_dev_en_point->dev_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_addr_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->addr); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_addr_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_mask_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->mask); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_mask_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_en_val_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->en_val); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_en_val_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_dis_val_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->dis_val); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_dis_val_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_width_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->width); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_width_%d ret =%d.\n", i, ret); + break; + } + + sysfs_info->logic_dev_en_num++; + } + + return ret; +} + +static int firmware_upgrade_config_init(struct device *dev, firmware_sysfs_t *sysfs_info) +{ + int i; + firmware_logic_dev_en_t *firmware_logic_dev_en_point; + firmware_upgrade_device_t *firmware_upgrade_device; + firmware_sysfs_device_t sysfs_upg_device; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_dev_loc_config_init\r\n"); + if (sysfs_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + if (dev->platform_data == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("platform data config error.\n"); + return -1; + } + firmware_upgrade_device = dev->platform_data; + sysfs_upg_device = firmware_upgrade_device->upg_type.sysfs; + + mem_clear(sysfs_info, sizeof(firmware_sysfs_t)); + strncpy(sysfs_info->type, firmware_upgrade_device->type, sizeof(sysfs_info->type) - 1); + sysfs_info->chain = firmware_upgrade_device->chain; + sysfs_info->chip_index = firmware_upgrade_device->chip_index; + + if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_SPI_LOGIC) == 0) { + strncpy(sysfs_info->info.spi_logic_info.dev_name, sysfs_upg_device.dev_name, FIRMWARE_DEV_NAME_LEN - 1); + sysfs_info->info.spi_logic_info.flash_base = sysfs_upg_device.flash_base; + sysfs_info->info.spi_logic_info.ctrl_base = sysfs_upg_device.ctrl_base; + sysfs_info->info.spi_logic_info.test_base = sysfs_upg_device.test_base; + sysfs_info->info.spi_logic_info.test_size = sysfs_upg_device.test_size; + } else if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_SYSFS) == 0) { + strncpy(sysfs_info->info.dev_file_info.sysfs_name, sysfs_upg_device.sysfs_name, FIRMWARE_DEV_NAME_LEN - 1); + sysfs_info->info.dev_file_info.dev_base = sysfs_upg_device.dev_base; + sysfs_info->info.dev_file_info.per_len = sysfs_upg_device.per_len; + sysfs_info->info.dev_file_info.test_base = sysfs_upg_device.test_base; + sysfs_info->info.dev_file_info.test_size = sysfs_upg_device.test_size; + } else if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_MTD) == 0) { + strncpy(sysfs_info->info.mtd_info.mtd_name, sysfs_upg_device.mtd_name, FIRMWARE_DEV_NAME_LEN - 1); + sysfs_info->info.mtd_info.flash_base = sysfs_upg_device.flash_base; + sysfs_info->info.mtd_info.test_base = sysfs_upg_device.test_base; + sysfs_info->info.mtd_info.test_size = sysfs_upg_device.test_size; + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("config sysfs type[%s] is not support.\n", sysfs_info->type); + return -ENXIO; + } + + if (firmware_upgrade_device->en_gpio_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_gpio_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_gpio_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + sysfs_info->gpio_en_info_num = firmware_upgrade_device->en_gpio_num; + /* Enable through GPIO */ + for (i = 0; i < sysfs_info->gpio_en_info_num; i++) { + sysfs_info->gpio_en_info[i].en_gpio = firmware_upgrade_device->en_gpio[i]; + sysfs_info->gpio_en_info[i].en_level = firmware_upgrade_device->en_level[i]; + } + + if (firmware_upgrade_device->en_logic_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_logic_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_logic_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + sysfs_info->logic_dev_en_num = firmware_upgrade_device->en_logic_num; + /* Enable through register */ + for (i = 0; i < sysfs_info->logic_dev_en_num; i++) { + firmware_logic_dev_en_point = &sysfs_info->logic_dev_en_info[i]; + strncpy(firmware_logic_dev_en_point->dev_name, firmware_upgrade_device->en_logic_dev[i], FIRMWARE_DEV_NAME_LEN - 1); + firmware_logic_dev_en_point->addr = firmware_upgrade_device->en_logic_addr[i]; + firmware_logic_dev_en_point->mask = firmware_upgrade_device->en_logic_mask[i]; + firmware_logic_dev_en_point->en_val = firmware_upgrade_device->en_logic_en_val[i]; + firmware_logic_dev_en_point->dis_val = firmware_upgrade_device->en_logic_dis_val[i]; + firmware_logic_dev_en_point->width = firmware_upgrade_device->en_logic_width[i]; + } + + return 0; +} + +static int firmware_sysfs_probe(struct platform_device *pdev) +{ + int ret; + firmware_sysfs_t *sysfs_info; + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_sysfs_probe\r\n"); + sysfs_info = devm_kzalloc(&pdev->dev, sizeof(firmware_sysfs_t), GFP_KERNEL); + if (sysfs_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc device tree.\n"); + return -EPERM; + } + + if (pdev->dev.of_node) { + ret = of_firmware_upgrade_config_init(&pdev->dev, sysfs_info); + } else { + ret = firmware_upgrade_config_init(&pdev->dev, sysfs_info); + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("get config init from dts error.\n"); + return -EPERM; + } + + frm_dev = devm_kzalloc(&pdev->dev, sizeof(firmware_device_t), GFP_KERNEL); + if (frm_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc firmware device.\n"); + return -EPERM; + } + + /* Based on the link number, determine the name of the device file */ + frm_dev->chain = sysfs_info->chain; + snprintf(frm_dev->name, FIRMWARE_NAME_LEN - 1, "firmware_sysfs%d", frm_dev->chain); + strncpy(sysfs_info->devname, frm_dev->name, strlen(frm_dev->name) + 1); + + INIT_LIST_HEAD(&frm_dev->list); + frm_dev->dev.minor = MISC_DYNAMIC_MINOR; + frm_dev->dev.name = frm_dev->name; + frm_dev->dev.fops = &sysfs_dev_fops; + frm_dev->priv = sysfs_info; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Register sysfs firmware chain:%d, name:%s.\n", frm_dev->chain, frm_dev->name); + + ret = firmware_device_register(frm_dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to register firmware device.\n"); + return -EPERM; + } + + platform_set_drvdata(pdev, frm_dev); + return 0; +} + +static int __exit firmware_sysfs_remove(struct platform_device *pdev) +{ + firmware_device_t *frm_dev; + + frm_dev = (firmware_device_t *)platform_get_drvdata(pdev); + firmware_device_unregister(frm_dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct of_device_id sysfs_match[] = { + { + .compatible = "firmware_sysfs", + }, + {}, +}; + +static struct platform_driver sysfs_driver = { + .driver = { + .name = "firmware_sysfs", + .owner = THIS_MODULE, + .of_match_table = sysfs_match, + }, + .probe = firmware_sysfs_probe, + .remove = firmware_sysfs_remove, +}; + +static firmware_driver_t fmw_drv_sysfs = { + .name = "firmware_sysfs", + .drv = &sysfs_driver, +}; + +int firmware_sysfs_init(void) +{ + int ret; + + INIT_LIST_HEAD(&fmw_drv_sysfs.list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("sysfs upgrade driver register \n"); + ret = firmware_driver_register(&fmw_drv_sysfs); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("sysfs upgrade driver register failed\n"); + return ret; + } + return 0; +} + +void firmware_sysfs_exit(void) +{ + firmware_driver_unregister(&fmw_drv_sysfs); + INIT_LIST_HEAD(&fmw_drv_sysfs.list); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs_upgrade.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs_upgrade.c new file mode 100644 index 000000000000..8b883006de53 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs_upgrade.c @@ -0,0 +1,258 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int firmware_file_read(const char *path, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + FIRMWARE_DRIVER_DEBUG_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + pos = (loff_t)addr; + ret = kernel_read(filp, val, size, &pos); + if (ret != size) { + FIRMWARE_DRIVER_DEBUG_ERROR("read kernel_read failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, addr, size, ret); + goto exit; + } + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int firmware_file_write(const char *path, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + FIRMWARE_DRIVER_DEBUG_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + pos = (loff_t)addr; + ret = kernel_write(filp, (void*)val, size, &pos); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("write kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, addr, size, ret); + goto exit; + } + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +/* + * firmware_file_do_work + * function: Sets logical register values + * @path:param[in] Logic device descriptor + * @addr:param[in] Logic device address + * @value:param[in] the register value needs to be set + * @mask:param[in] register mask + * @width:param[in] register bit width + * return: 0:success, <0:failed + */ +static int firmware_file_do_work(char *path, uint32_t addr, uint32_t value, uint32_t mask, + int32_t width) +{ + int ret; + uint8_t read_value[4], write_value[4]; + uint8_t tmp_read8, tmp_write8, tmp_mask8; + uint32_t tmp_read32, tmp_write32; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("path=%s, addr=0x%x, value=0x%x mask=0x%x\r\n", path, addr, value, mask); + if ((width > 4) || (width < 0)) { + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + } + ret = 0; + mem_clear(read_value, sizeof(read_value)); + mem_clear(write_value, sizeof(write_value)); + ret = firmware_file_read(path, addr, read_value, width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware sysfs read.\r\n"); + return -1; + } + + switch (width) { + case 1: + tmp_read8 = read_value[0]; + tmp_mask8 = (uint8_t)(mask) & 0xFF; + tmp_write8 = (uint8_t)value & 0xFF; + write_value[0] = (tmp_read8 & tmp_mask8) | tmp_write8; + FIRMWARE_DRIVER_DEBUG_VERBOSE("1 byte write val[0]:0x%x", write_value[0]); + break; + case 2: + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + case 4: + memcpy((uint8_t *)&tmp_read32, read_value, 4); + tmp_write32 = (tmp_read32 & mask) | value; + memcpy(write_value, (uint8_t *)&tmp_write32, 4); + FIRMWARE_DRIVER_DEBUG_VERBOSE("4 byte write val[0]:0x%x, val[1]:0x%x, val[2]:0x%x, val[3]:0x%x", + write_value[0], write_value[1], write_value[2], write_value[3]); + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("write logic dev[%s] addr[0x%x].\r\n", path, addr); + ret = firmware_file_write(path, addr, write_value, width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware_file_write %s addr 0x%x failed, ret=%d.\r\n", path, addr, ret); + return -1; + } + + return 0; +} + +/* + * firmware_upgrade_en + * function:param[in] Upgrade access enabling switch + * @flag:param[in] !0:enable 0:disable + * return: 0:success, <0:failed + */ +static int firmware_upgrade_en(firmware_sysfs_t *sysfs_info, int flag) +{ + int i; + firmware_logic_dev_en_t *firmware_logic_dev_en_info; + int ret, rv; + char *dev_name; + + ret = 0; + FIRMWARE_DRIVER_DEBUG_VERBOSE("%s en switch: gpio en num %d, logic reg en num %d.\n", + flag ? "Open" : "Close", sysfs_info->gpio_en_info_num, sysfs_info->logic_dev_en_num); + for (i = 0; i < sysfs_info->gpio_en_info_num; i++) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware sysfs [%d] gpio[%d] en_level[%d]\n", + i, sysfs_info->gpio_en_info[i].en_gpio, sysfs_info->gpio_en_info[i].en_level); + if (flag) { + ret = gpio_request(sysfs_info->gpio_en_info[i].en_gpio, "sysfs_upgrade_gpio_en"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade EN[%d] GPIO[%d] failed!\n", + i, sysfs_info->gpio_en_info[i].en_gpio); + goto free_gpio; + } + gpio_direction_output(sysfs_info->gpio_en_info[i].en_gpio, sysfs_info->gpio_en_info[i].en_level); + sysfs_info->gpio_en_info[i].flag = 1; + } else { + gpio_set_value(sysfs_info->gpio_en_info[i].en_gpio, !sysfs_info->gpio_en_info[i].en_level); + gpio_free(sysfs_info->gpio_en_info[i].en_gpio); + sysfs_info->gpio_en_info[i].flag = 0; + } + } + + for (i = 0; i < sysfs_info->logic_dev_en_num; i++) { + firmware_logic_dev_en_info = &sysfs_info->logic_dev_en_info[i]; + dev_name = firmware_logic_dev_en_info->dev_name; + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware sysfs [%d] dev_name[%s] addr[0x%x] mask[0x%x]" + " en_val[0x%x] dis_val[0x%x] width[%d]\n", + i , firmware_logic_dev_en_info->dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->mask, firmware_logic_dev_en_info->en_val, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->width); + if (flag) { + ret = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->en_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Open logic register [%d] EN failed, ret %d.\n", i, ret); + goto free_logic_dev; + } else { + firmware_logic_dev_en_info->flag = 1; + } + } else { + rv = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (rv < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Close logic register [%d] EN failed, ret %d.\n", i, rv); + ret = -1; + } + firmware_logic_dev_en_info->flag = 0; + } + } + + return ret; +free_logic_dev: + for (i = 0; i < sysfs_info->logic_dev_en_num; i++) { + firmware_logic_dev_en_info = &sysfs_info->logic_dev_en_info[i]; + dev_name = firmware_logic_dev_en_info->dev_name; + if (firmware_logic_dev_en_info->flag == 1) { + ret = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Close logic register [%d] EN failed, ret %d.\n", i, ret); + } + firmware_logic_dev_en_info->flag = 0; + } else { + break; + } + } +free_gpio: + for (i = 0; i < sysfs_info->gpio_en_info_num; i++) { + if (sysfs_info->gpio_en_info[i].flag == 1) { + gpio_set_value(sysfs_info->gpio_en_info[i].en_gpio, !sysfs_info->gpio_en_info[i].en_level); + gpio_free(sysfs_info->gpio_en_info[i].en_gpio); + sysfs_info->gpio_en_info[i].flag = 0; + } else { + break; + } + } + + return -1; +} + +/* + * firmware_init_dev_loc + * function: init logic device, enable upgrade access + * return: 0:success, <0:failed + */ +int firmware_init_dev_loc(firmware_sysfs_t *sysfs_info) +{ + int ret; + + ret = firmware_upgrade_en(sysfs_info, 1); + return ret; +} + +/* + * firmware_finish_dev_loc + * function: finish logic device, disable upgrade access + * return: 0:success, <0:failed + */ +int firmware_finish_dev_loc(firmware_sysfs_t *sysfs_info){ + int ret; + ret = firmware_upgrade_en(sysfs_info, 0); + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs.h new file mode 100644 index 000000000000..9da2303c7c00 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs.h @@ -0,0 +1,88 @@ +#ifndef __FIRMWARE_SYSFS_H__ +#define __FIRMWARE_SYSFS_H__ + +#include +#include + +#include + +/* Debug switch level */ +typedef enum { + FIRWMARE_VERBOSE, + FIRWMARE_WARN, + FIRWMARE_ERROR, + FIRWMARE_END, +} firmware_debug_level_t; + +#define FIRMWARE_DRIVER_DEBUG_VERBOSE(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_VERBOSE)) { \ + printk(KERN_INFO "[FIRMWARW_DRIVER_SYSFS][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_DRIVER_DEBUG_ERROR(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_ERROR)) { \ + printk(KERN_ERR "[FIRMWARW_DRIVER_SYSFS][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_NAME_LEN 48 + +#define FIRMWARE_FAILED (-1) +#define FIRMWARE_SUCCESS 0 + +/* ioctl publi command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_COMMON_TYPE 'C' +#define FIRMWARE_GET_CHIPNAME _IOR(FIRMWARE_COMMON_TYPE, 0, char) /* get the chip name */ +#define FIRMWARE_GET_VERSION _IOR(FIRMWARE_COMMON_TYPE, 2, int) /* get version */ + +/* firmware sysfs driver ioctl command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_SYSFS_TYPE 'S' +#define FIRMWARE_SYSFS_INIT _IOR(FIRMWARE_SYSFS_TYPE, 0, char) /* enable upgrade access */ +#define FIRMWARE_SYSFS_FINISH _IOR(FIRMWARE_SYSFS_TYPE, 1, char) /* disable upgrade access */ +#define FIRMWARE_SYSFS_SPI_INFO _IOR(FIRMWARE_SYSFS_TYPE, 2, char) /* spi flash upgrade */ +#define FIRMWARE_SYSFS_DEV_FILE_INFO _IOR(FIRMWARE_SYSFS_TYPE, 3, char) /* sysfs upgrade */ +#define FIRMWARE_SYSFS_MTD_INFO _IOR(FIRMWARE_SYSFS_TYPE, 4, char) /* sysfs mtd upgrade */ + +#define FIRMWARE_SYSFS_TYPE_SPI_LOGIC "SPI_LOGIC" +#define FIRMWARE_SYSFS_TYPE_SYSFS "SYSFS" +#define FIRMWARE_SYSFS_TYPE_MTD "MTD_DEV" + +typedef struct cmd_info_s { + uint32_t size; + void __user *data; +} cmd_info_t; + +typedef struct firmware_device_s { + struct list_head list; /* device list */ + uint32_t chain; /* chain number */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct miscdevice dev; /* device */ + void *priv; /* private data */ +} firmware_device_t; + +typedef struct firmware_driver_s { + struct list_head list; /* list */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct platform_driver *drv; /* driver */ + void *priv; /* private data */ +} firmware_driver_t; + +extern int g_firmware_driver_debug; + +/* Get device information based on minor */ +extern firmware_device_t *firmware_get_device_by_minor(int minor); +/* Registere device */ +extern int firmware_device_register(firmware_device_t *fw_dev); +/* Unregister device */ +extern void firmware_device_unregister(firmware_device_t *fw_dev); +/* Registere driver */ +extern int firmware_driver_register(firmware_driver_t *fw_drv); +/* Unregister driver */ +extern void firmware_driver_unregister(firmware_driver_t *fw_drv); +/* SYSFS upgrade initialized */ +extern int firmware_sysfs_init(void); +/* SYSFS unload function */ +extern void firmware_sysfs_exit(void); + +#endif /* end of __FIRMWARE_SYSFS_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs_upgrade.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs_upgrade.h new file mode 100644 index 000000000000..9c6b970274b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs_upgrade.h @@ -0,0 +1,72 @@ +#ifndef __FIRMWARE_SYSFS_UPGRADE_H__ +#define __FIRMWARE_SYSFS_UPGRADE_H__ + +#define FIRMWARE_DEV_NAME_LEN 64 /* the macro definition needs to same as app space define */ +#define FIRMWARE_TYPE_LEN 10 +#define FIRMWARE_EN_INFO_MAX 16 + +typedef struct firmware_spi_logic_info_s { + char dev_name[FIRMWARE_DEV_NAME_LEN]; /* Logical device name */ + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t ctrl_base; /* SPI upgrade control register base address */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_spi_logic_info_t; + +typedef struct firmware_dev_file_info_s { + char sysfs_name[FIRMWARE_DEV_NAME_LEN]; /* sysfs name */ + uint32_t dev_base; /* device upgrade base address */ + uint32_t per_len; /* The length of bytes per operation */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_dev_file_info_t; + +typedef struct firmware_mtd_info_s { + char mtd_name[FIRMWARE_DEV_NAME_LEN]; /* sysfs name */ + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_mtd_info_t; + +typedef struct firmware_gpio_jtag_en_s { + uint32_t en_gpio; /* GPIO enable pin */ + uint32_t en_level; /* GPIO enable level */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_gpio_jtag_en_t; + +typedef struct firmware_logic_dev_en_s { + char dev_name[FIRMWARE_DEV_NAME_LEN]; /* Logical device name */ + uint32_t addr; /* Enable register address */ + uint32_t mask; /* mask */ + uint32_t en_val; /* Enable value */ + uint32_t dis_val; /* Disable value*/ + uint32_t width; /* width */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_logic_dev_en_t; + +typedef struct firmware_sysfs_s { + char devname[FIRMWARE_DEV_NAME_LEN]; /* Device name */ + char type[FIRMWARE_TYPE_LEN]; /* interface type */ + uint32_t chain; /* chain num */ + uint32_t chip_index; /* chip index */ + union { + firmware_spi_logic_info_t spi_logic_info; /* SPI logic Information */ + firmware_dev_file_info_t dev_file_info; /* device file Information */ + firmware_mtd_info_t mtd_info; /* mtd device Information */ + } info; + uint32_t gpio_en_info_num; /* GPIO Enable Number */ + firmware_gpio_jtag_en_t gpio_en_info[FIRMWARE_EN_INFO_MAX]; /* GPIO Enable Information */ + uint32_t logic_dev_en_num; /* Register Enable Number */ + firmware_logic_dev_en_t logic_dev_en_info[FIRMWARE_EN_INFO_MAX]; /* Register Enable Information */ +} firmware_sysfs_t; + +typedef struct firmware_sysfs_function_s{ + int (*init_dev)(void); /* upgrade initializes the operation */ + int (*finish_dev)(void); /* upgrade completes the operation */ +}firmware_sysfs_function_t; + +extern void firmware_set_sysfs_info(firmware_sysfs_t *sysfs_info); +extern int firmware_init_dev_loc(firmware_sysfs_t *sysfs_info); +extern int firmware_finish_dev_loc(firmware_sysfs_t *sysfs_info); + +#endif /* __FIRMWARE_SYSFS_UPGRADE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/include/firmware_upgrade.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/include/firmware_upgrade.h new file mode 100644 index 000000000000..600c69646b1b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/include/firmware_upgrade.h @@ -0,0 +1,57 @@ +#ifndef __FIRMWARE_UPGRADE_H__ +#define __FIRMWARE_UPGRADE_H__ + +#include + +#define TYPE_LEN (10) +#define DEV_NAME_LEN (64) +#define ENABLE_NUM (16) + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef struct firmware_jtag_device_s { + uint32_t tdi; + uint32_t tck; + uint32_t tms; + uint32_t tdo; + uint32_t tck_delay; +} firmware_jtag_device_t; + +typedef struct firmware_sysfs_device_s { + uint32_t test_base; + uint32_t test_size; + char dev_name[DEV_NAME_LEN]; + uint32_t flash_base; + uint32_t ctrl_base; + char sysfs_name[DEV_NAME_LEN]; + uint32_t dev_base; + uint32_t per_len; + char mtd_name[DEV_NAME_LEN]; +} firmware_sysfs_device_t; + +typedef struct firmware_upgrade_device_s { + char type[TYPE_LEN]; + uint32_t chain; + uint32_t chip_index; + + uint32_t en_gpio_num; /* the number of en_gpio */ + uint32_t en_gpio[ENABLE_NUM]; + uint32_t en_level[ENABLE_NUM]; + + uint32_t en_logic_num; /* the number of en_logic */ + char en_logic_dev[ENABLE_NUM][DEV_NAME_LEN]; + uint32_t en_logic_addr[ENABLE_NUM]; + uint32_t en_logic_mask[ENABLE_NUM]; + uint32_t en_logic_en_val[ENABLE_NUM]; + uint32_t en_logic_dis_val[ENABLE_NUM]; + uint32_t en_logic_width[ENABLE_NUM]; + + int device_flag; + union { + firmware_jtag_device_t jtag; + firmware_sysfs_device_t sysfs; + } upg_type; + +} firmware_upgrade_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/Makefile new file mode 100644 index 000000000000..176d44d2abd9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/Makefile @@ -0,0 +1,33 @@ +include $(top_srcdir)/Rules.mk + +#OBJ = firmware_app.o debug.o hardware.o ispvm_ui.o ivm_core.o crc32.o +PWD = $(shell pwd) +SRC := +SRC += $(shell find $(PWD) -name '*.c') + +OBJ := $(SRC:%.c=%.o) +LIB += $(BUILD_CFALGS) $(BUILD_LDFLAGS) -lpthread -lreadline -lncurses +INCLUDE = -Iinclude +INCLUDE+= -Wall +APP = firmware_upgrade +ELF_FILE = $(APP) +MAP_FILE = $(APP).map.sym + +.PHONY: build +build:$(OBJ) + $(CC) $^ -o $(ELF_FILE) $(LINKFLAGS) $(LIB) + $(NM) $(ELF_FILE) | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' \ + | sort > $(MAP_FILE) + cp -p $(ELF_FILE) $(common_out_put_dir) + +%.o:%.c + $(CC) -c $(CFLAGS) $(INCLUDE) $< -o $@ + +.PHONY: install +install: + echo "firmware_upgrade install success." + cp -p $(ELF_FILE) $(common_out_put_dir) + +.PHONY: clean +clean: + rm -rf $(BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/crc32.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/crc32.c new file mode 100644 index 000000000000..5b60b40ad1ba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/crc32.c @@ -0,0 +1,216 @@ +/* + * This file is derived from crc32.c from the zlib-1.1.3 distribution + * by Jean-loup Gailly and Mark Adler. + */ + +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ +/* xxxx: by chihl for compile error */ +#if 1 + +#ifndef FAR +#define FAR +#endif + +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef Byte FAR Bytef; +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifndef OF /* function prototypes */ +#ifdef STDC +#define OF(args) args +#else +#define OF(args) () +#endif +#endif + +#endif + +#define local static +#define ZEXPORT /* empty */ +unsigned long crc32 (unsigned long, const unsigned char *, unsigned int); + +#define DYNAMIC_CRC_TABLE + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local uLongf crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +local void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local const uLongf crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +#endif + +#if 0 +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const uLongf * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (const uLongf *)crc_table; +} +#endif + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len) +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} + +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) + +/* No ones complement version. JFFS2 (and other things ?) + * don't use ones compliment in their CRC calculations. + */ +uLong ZEXPORT crc32_no_comp(uLong crc, const Bytef *buf, uInt len) +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + + return crc; +} + +#endif /* CFG_CMD_JFFS2 */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/debug.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/debug.c new file mode 100644 index 000000000000..dc1b1ccfc70a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/debug.c @@ -0,0 +1,60 @@ +/* + * debug.c + * firmware upgrade debug switch control + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int is_debug_on = DEBUG_IGNORE; + +/* + * firmware_upgrade_debug + * function: Debug switch + * Parses the file "/var/tmp/.firmware_upgrade_debug" and returns the corresponding debug level + * return:off--DEBUG_OFF, app debug on---DEBUG_APP_ON, kernel debug on--DEBUG_KERN_ON, + * all debug on--DEBUG_ALL_ON, other--DEBUG_IGNORE + */ +int firmware_upgrade_debug(void) +{ + int size; + FILE *fp; + char debug_info[DEBUG_INFO_LEN]; + + fp = fopen(DEBUG_FILE, "r"); + if (fp == NULL) { + return DEBUG_IGNORE; + } + + mem_clear(debug_info, DEBUG_INFO_LEN); + size = fread(debug_info, DEBUG_INFO_LEN - 1, 1, fp); + if (size < 0) { + fclose(fp); + return DEBUG_IGNORE; + } + + if (strncmp(debug_info, DEBUG_ON_INFO, 1) == 0) { + fclose(fp); + return DEBUG_APP_ON; + } + + if (strncmp(debug_info, DEBUG_ON_ALL, 1) == 0) { + fclose(fp); + return DEBUG_ALL_ON; + } + + if (strncmp(debug_info, DEBUG_OFF_INFO, 1) == 0) { + fclose(fp); + return DEBUG_OFF; + } + + fclose(fp); + return DEBUG_IGNORE; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/firmware_app.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/firmware_app.c new file mode 100644 index 000000000000..ecdc37ef350f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/firmware_app.c @@ -0,0 +1,985 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int header_offset; + +static firmware_file_name_t firmware_file_str[] = { + {"VME", FIRMWARE_VME}, + {"ISC", FIRMWARE_ISC}, + {"JBI", FIRMWARE_JBI}, + {"SPI-LOGIC-DEV", FIRMWARE_SPI_LOGIC_DEV}, + {"SYSFS", FIRMWARE_SYSFS_DEV}, + {"MTD", FIRMWARE_MTD}, +}; + +/** + * firmware_error_type + * function:set error code + * @action: param[in] The stage where the error occurs + * @info: param[in] Upgrade file information + * return value: error code + */ +int firmware_error_type(int action, name_info_t *info) +{ + if (info == NULL) { + return ERR_FW_UPGRADE; + } + + if((info->type <= FIRMWARE_UNDEF_TYPE) || (info->type > FIRMWARE_OTHER)) { + return ERR_FW_UPGRADE; + } + + if (info->type == FIRMWARE_CPLD) { + switch (action) { + case FIRMWARE_ACTION_CHECK: + return ERR_FW_CHECK_CPLD_UPGRADE; + case FIRMWARE_ACTION_MATCH: + return ERR_FW_MATCH_CPLD_UPGRADE; + case FIRMWARE_ACTION_VERCHECK: + return ERR_FW_SAMEVER_CPLD_UPGRADE; + case FIRMWARE_ACTION_UPGRADE: + return ERR_FW_DO_CPLD_UPGRADE; + case FIRMWARE_ACTION_SUPPORT: + return ERR_FW_DO_UPGRADE_NOT_SUPPORT; + default: + return ERR_FW_UPGRADE; + } + } else if (info->type == FIRMWARE_FPGA) { + switch (action) { + case FIRMWARE_ACTION_CHECK: + return ERR_FW_CHECK_FPGA_UPGRADE; + case FIRMWARE_ACTION_MATCH: + return ERR_FW_MATCH_FPGA_UPGRADE; + case FIRMWARE_ACTION_VERCHECK: + return ERR_FW_SAMEVER_FPGA_UPGRADE; + case FIRMWARE_ACTION_UPGRADE: + return ERR_FW_DO_FPGA_UPGRADE; + case FIRMWARE_ACTION_SUPPORT: + return ERR_FW_DO_UPGRADE_NOT_SUPPORT; + default: + return ERR_FW_UPGRADE; + } + } else { + switch (action) { + case FIRMWARE_ACTION_CHECK: + return ERR_FW_CHECK_UPGRADE; + case FIRMWARE_ACTION_MATCH: + return ERR_FW_MATCH_UPGRADE; + case FIRMWARE_ACTION_VERCHECK: + return ERR_FW_SAMEVER_UPGRADE; + case FIRMWARE_ACTION_UPGRADE: + return ERR_FW_DO_UPGRADE; + case FIRMWARE_ACTION_SUPPORT: + return ERR_FW_DO_UPGRADE_NOT_SUPPORT; + default: + return ERR_FW_UPGRADE; + } + } + +} + +/* + * firmware_check_file_info + * function:Check the file information to determine that the file is available for use on the device + * @info: param[in] Upgrade file information + * @main_type : param[in] main type + * @sub_type : param[in] sub type + * @slot : param[in] 0--main, sub slot starts at 1 + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_check_file_info(name_info_t *info, int main_type, int sub_type, int slot) +{ + int i; + + dbg_print(is_debug_on, "Check file info.\n"); + /* Check the mainboard type */ + for (i = 0; i < MAX_DEV_NUM; i++) { + if (main_type == info->card_type[i]) { + dbg_print(is_debug_on, "main type is 0x%x \n", main_type); + break; + } + } + if (i == MAX_DEV_NUM) { + dbg_print(is_debug_on, "Error: The main type[0x%x] is not matched \n", main_type); + return firmware_error_type(FIRMWARE_ACTION_MATCH, info); + } + + /* Check the sub board type, if firwmare upgrade sub board, then sub_type must be 0 */ + for (i = 0; i < MAX_DEV_NUM; i++) { + if (sub_type == info->sub_type[i]) { + dbg_print(is_debug_on, "sub type is 0x%x \n", sub_type); + break; + } + } + if (i == MAX_DEV_NUM) { + dbg_print(is_debug_on, "Error: The sub type[0x%x] is not matched \n", sub_type); + return firmware_error_type(FIRMWARE_ACTION_MATCH, info); + } + + /* if firwmare upgrade main board, then sub_type must be 0 and slot must be 0 + * if firwmare upgrade sub board, then sub_type must not be 0 and slot must not be 0 */ + if (((sub_type != 0) && (slot < 1)) || ((sub_type == 0) && (slot != 0))) { + dbg_print(is_debug_on, "Error: The sub type[0x%x] is not match slot %d error.\n", sub_type, slot); + return firmware_error_type(FIRMWARE_ACTION_MATCH, info); + } + + dbg_print(is_debug_on, "Success check file info.\n"); + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_get_dev_file_name + * function:Gets the name of the device file + * @info: param[in] Upgrade file information + * @len: param[in] Device file name length + * @file_name: param[out] Device file name + */ +static int firmware_get_dev_file_name(name_info_t *info, char *file_name, int len) +{ + int ret; + + ret = FIRMWARE_SUCCESS; + switch(info->file_type) { + case FIRMWARE_VME: + snprintf(file_name, len, "/dev/firmware_cpld_ispvme%d", info->chain); + break; + case FIRMWARE_ISC: + case FIRMWARE_JBI: + snprintf(file_name, len, "/dev/firmware_cpld%d", info->chain); + break; + case FIRMWARE_SPI_LOGIC_DEV: + case FIRMWARE_SYSFS_DEV: + case FIRMWARE_MTD: + snprintf(file_name, len, "/dev/firmware_sysfs%d", info->chain); + break; + default: + ret = FIRMWARE_FAILED; + break; + } + + return ret; + } + +/** + * firmware_check_chip_verison + * function: Check chip version + * @fd: param[in] Device file descriptor + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +int firmware_check_chip_verison(int fd, name_info_t *info) +{ + int ret; + cmd_info_t cmd_info; + char version[FIRMWARE_NAME_LEN + 1]; + + dbg_print(is_debug_on, "Check chip version.\n"); + mem_clear(version, FIRMWARE_NAME_LEN); + cmd_info.size = FIRMWARE_NAME_LEN; + cmd_info.data = (void *) version; + + /* Ignore version checking */ + if (strncmp("v", info->version, 1) == 0) { + dbg_print(is_debug_on, "Skip check chip version.\n"); + return FIRMWARE_SUCCESS; + } + + /* Get the program version from the device file */ + ret = ioctl(fd, FIRMWARE_GET_VERSION, &cmd_info); + if (ret < 0) { + dbg_print(is_debug_on, "Error: Failed to get version(chain %d, version %s).\n", + info->chain, info->version); + return firmware_error_type(FIRMWARE_ACTION_CHECK, NULL); + } + dbg_print(is_debug_on, "Chip verion: %s, file chip verion: %s.\n", version, info->version); + + /* The device version is the same and does not upgrade */ + if (strcmp(version, info->version) == 0) { + dbg_print(is_debug_on, "the file program version is same as the firmware version %s \n", + info->version); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + dbg_print(is_debug_on, "Check version pass.\n"); + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_get_file_size + * function: Gets the upgrade file size + * @file_name: param[in] Upgrade file name + * @size: param[out] Upgrade file size + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int firmware_get_file_size(char *file_name, uint32_t *size) +{ + int ret; + struct stat buf; + + ret = stat(file_name, &buf); + if (ret < 0) { + return FIRMWARE_FAILED; + } + + if (buf.st_size < 0 || buf.st_size - header_offset < 0) { + return FIRMWARE_FAILED; + } + /* Remove the upgrade file header information to actually upgrade the content size */ + *size = buf.st_size - header_offset; + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_get_file_info + * function: Gets the contents of the upgrade file + * @file_name: param[in] Upgrade file name + * @size: param[in] Upgrade file size + * @buf: param[out] Upgrade the file content + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int firmware_get_file_info(char *file_name, uint8_t *buf, uint32_t size) +{ + FILE *fp; + int len; + int ret; + + fp = fopen(file_name, "r"); + if (fp == NULL) { + return FIRMWARE_FAILED; + } + /* Removes the contents of the upgrade file header information */ + ret = fseek(fp, header_offset, SEEK_SET); + if (ret < 0) { + fclose(fp); + return FIRMWARE_FAILED; + } + + len = fread(buf, size, 1, fp); + if (len < 0) { + fclose(fp); + return FIRMWARE_FAILED; + } + fclose(fp); + + return FIRMWARE_SUCCESS; +} + +/* +* firmware_upgrade +* function: firmware upgrade +* @file_name: param[in] Upgrade file name +* @info: param[in] Upgrade file information +* return value : success--FIRMWARE_SUCCESS, other fail return error code +*/ +static int firmware_upgrade(char *file_name, name_info_t *info) +{ + int ret; + int fd; + uint32_t upg_size; + uint8_t *upg_buf; + char dev_file_name[FIRMWARE_NAME_LEN]; + unsigned long crc; + + dbg_print(is_debug_on, "Upgrade firmware: %s.\n", file_name); + mem_clear(dev_file_name, FIRMWARE_NAME_LEN); + ret = firmware_get_dev_file_name(info, dev_file_name, FIRMWARE_NAME_LEN - 1); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to get dev file name.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + fd = open(dev_file_name, O_RDWR); + if (fd < 0) { + dbg_print(is_debug_on, "Error: Failed to open %s.\n", dev_file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + +#if 0 + /* check chip name */ + ret = firmware_check_chip_name(fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip name: %s.\n", dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } +#endif + + /* Check chip version */ + ret = firmware_check_chip_verison(fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip version: %s.\n", dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* Gets the upgrade file size */ + ret = firmware_get_file_size(file_name, &upg_size); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to get file size: %s.\n", file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + if (upg_size == 0) { + dbg_print(is_debug_on, "Error: The upgrade file is empty \n"); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + upg_buf = (uint8_t *) malloc(upg_size + 1); + if (upg_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for upgrade file info: %s.\n", + dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* Gets the contents of the upgrade file */ + mem_clear(upg_buf, upg_size + 1); + ret = firmware_get_file_info(file_name, upg_buf, upg_size); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to read file info: %s.\n", file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* file crc32 check */ + crc = crc32(0, (const unsigned char *)upg_buf, (unsigned int)upg_size); + if (crc != info->crc32) { + dbg_print(is_debug_on, "Error: Failed to check file crc: %s.\n", file_name); + dbg_print(is_debug_on, "the crc value is : %#08x.\n", (unsigned int)crc); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + dbg_print(is_debug_on, "Start upgrading firmware, wait...\n"); + + /* Start firmware upgrade */ + switch (info->file_type) { + case FIRMWARE_VME: + dbg_print(is_debug_on, "start to ispvme upgrade: %s.\n", file_name); + ret = firmware_upgrade_ispvme(fd, file_name, info); + break; + case FIRMWARE_ISC: + case FIRMWARE_JBI: + dbg_print(is_debug_on, "start to upgrade: %s.\n", file_name); + ret = firmware_upgrade_jtag(fd, upg_buf, upg_size, info); + break; + case FIRMWARE_SPI_LOGIC_DEV: + dbg_print(is_debug_on, "start to spi logic dev upgrade: %s.\n", file_name); + ret = firmware_upgrade_spi_logic_dev(fd, upg_buf, upg_size, info); + break; + case FIRMWARE_SYSFS_DEV: + dbg_print(is_debug_on, "start to sysfs upgrade: %s.\n", file_name); + ret = firmware_upgrade_sysfs(fd, upg_buf, upg_size, info); + break; + case FIRMWARE_MTD: + dbg_print(is_debug_on, "start to mtd device upgrade: %s.\n", file_name); + ret = firmware_upgrade_mtd(fd, upg_buf, upg_size, info); + break; + default: + dbg_print(is_debug_on, "Error: file type is not support: %s.\n", file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_UPGRADE, info); + } + + dbg_print(is_debug_on, "Completed.\n"); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to upgrade: %s.\n", dev_file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_UPGRADE, info); + } + + free(upg_buf); + close(fd); + + return FIRMWARE_SUCCESS; +} + +/* +* firmware_upgrade_test +* function: firmware upgrade test +* @file_name: param[in] Upgrade file name +* @info: param[in] Upgrade file information +* return value : success--FIRMWARE_SUCCESS, other fail return error code +*/ +static int firmware_upgrade_test(char *file_name, name_info_t *info) +{ + int ret; + int fd; + uint32_t upg_size; + uint8_t *upg_buf; + char dev_file_name[FIRMWARE_NAME_LEN]; + unsigned long crc; + + dbg_print(is_debug_on, "Upgrade firmware test: %s.\n", file_name); + mem_clear(dev_file_name, FIRMWARE_NAME_LEN); + ret = firmware_get_dev_file_name(info, dev_file_name, FIRMWARE_NAME_LEN - 1); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to get dev file name.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + fd = open(dev_file_name, O_RDWR); + if (fd < 0) { + dbg_print(is_debug_on, "Error: Failed to open %s.\n", dev_file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + +#if 0 + /* check chip name */ + ret = firmware_check_chip_name(fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip name: %s.\n", dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } +#endif + + /* Check chip version */ + ret = firmware_check_chip_verison(fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip version: %s.\n", dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* Gets the upgrade file size */ + ret = firmware_get_file_size(file_name, &upg_size); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to get file size: %s.\n", file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + upg_buf = (uint8_t *) malloc(upg_size + 1); + if (upg_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for upgrade file info: %s.\n", + dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* Gets the contents of the upgrade file */ + mem_clear(upg_buf, upg_size + 1); + ret = firmware_get_file_info(file_name, upg_buf, upg_size); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to read file info: %s.\n", file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* file crc32 check */ + crc = crc32(0, (const unsigned char *)upg_buf, (unsigned int)upg_size); + if (crc != info->crc32) { + dbg_print(is_debug_on, "Error: Failed to check file crc: %s.\n", file_name); + dbg_print(is_debug_on, "the crc value is : %#08x.\n", (unsigned int)crc); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + dbg_print(is_debug_on, "Start upgrading firmware test, wait...\n"); + + /* Start firmware upgrade */ + switch (info->file_type) { + case FIRMWARE_VME: + dbg_print(is_debug_on, "start to ispvme upgrade test: %s.\n", file_name); + /* WME upgrade link testing is the same as upgrading, using vme test file. */ + ret = firmware_upgrade_ispvme(fd, file_name, info); + break; + case FIRMWARE_ISC: + case FIRMWARE_JBI: + dbg_print(is_debug_on, "start to upgrade test: %s.\n", file_name); + ret = firmware_upgrade_jtag_test(fd, upg_buf, upg_size, info); + break; + case FIRMWARE_SPI_LOGIC_DEV: + dbg_print(is_debug_on, "start to spi logic dev upgrade test: %s.\n", file_name); + ret = firmware_upgrade_spi_logic_dev_test(fd,info); + break; + case FIRMWARE_SYSFS_DEV: + dbg_print(is_debug_on, "start to sysfs upgrade test: %s.\n", file_name); + ret = firmware_upgrade_sysfs_test(fd, info); + break; + case FIRMWARE_MTD: + dbg_print(is_debug_on, "start to mtd device upgrade test: %s.\n", file_name); + ret = firmware_upgrade_mtd_test(fd, info); + break; + default: + dbg_print(is_debug_on, "Error: test file type is not support: %s.\n", file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_UPGRADE, info); + } + + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to upgrade test: %s ret=%d.\n", dev_file_name, ret); + free(upg_buf); + close(fd); + if (ret == FIRMWARE_NOT_SUPPORT) { + return firmware_error_type(FIRMWARE_ACTION_SUPPORT, info); + } else { + return firmware_error_type(FIRMWARE_ACTION_UPGRADE, info); + } + } + + free(upg_buf); + close(fd); + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_file_type_map + * function:Gets the corresponding upgrade file type from the upgrade file type list + * @value : param[in] file type name + * return value : file type, firmware_file_type_t + */ +static firmware_file_type_t firmware_upgrade_file_type_map(char *type_str) +{ + int type_num; + int i; + + type_num = (sizeof(firmware_file_str) /sizeof(firmware_file_str[0])); + for (i = 0; i < type_num; i++) { + if (!strncmp(firmware_file_str[i].firmware_file_name_str, type_str, + strlen(firmware_file_str[i].firmware_file_name_str))) { + return firmware_file_str[i].firmware_file_type; + } + } + + dbg_print(is_debug_on, "firmware file type unknown\n"); + return FIRMWARE_NONE; +} + +/* + * firmware_upgrade_parse_kv + * function:Parses the header information of the upgrade file based on the key and value + * @key: param[in] key + * @value : param[in] value + * @info : param[out] Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_parse_kv(const char *key, const char *value, name_info_t *info) +{ + int i; + if (key == NULL || value == NULL) { + dbg_print(is_debug_on, "Error: failed to get ther key or value.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } else if (strcmp(key, FILEHEADER_DEVTYPE) == 0) { + /* main board type */ + for (i = 0; i < MAX_DEV_NUM && info->card_type[i]; i++); + if (i == MAX_DEV_NUM) { + dbg_print(is_debug_on, "Error: card type is full for %s. \n", value); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + info->card_type[i] = strtoul(value, NULL, 0); + } else if (strcmp(key, FILEHEADER_SUBTYPE) == 0) { + /* sub board type */ + for (i = 0; i < MAX_DEV_NUM && info->sub_type[i]; i++); + if (i == MAX_DEV_NUM) { + dbg_print(is_debug_on, "Error: sub type is full for %s. \n", value); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + info->sub_type[i] = strtoul(value, NULL, 0); + } else if (strcmp(key, FILEHEADER_TYPE) == 0) { + /* Device type */ + if (strcmp(value, FIRMWARE_CPLD_NAME) == 0) { + info->type = FIRMWARE_CPLD; + } else if (strcmp(value, FIRMWARE_FPGA_NAME) == 0) { + info->type = FIRMWARE_FPGA; + } else { + info->type = FIRMWARE_OTHER; + } + } else if (strcmp(key, FILEHEADER_CHAIN) == 0) { + /* link num */ + info->chain = strtoul(value, NULL, 10); + } else if (strcmp(key, FILEHEADER_CHIPNAME) == 0) { + /* chip name */ + if (strlen(value) >= FIRMWARE_NAME_LEN) { + dbg_print(is_debug_on, "Error: '%s' is too long for a chipname.\n", value); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + mem_clear(info->chip_name, sizeof(info->chip_name)); + snprintf(info->chip_name, sizeof(info->chip_name) - 1, "%s", value); + } else if (strcmp(key, FILEHEADER_VERSION) == 0) { + /* version */ + if (strlen(value) >= FIRMWARE_NAME_LEN) { + dbg_print(is_debug_on, "Error: '%s' is too long for a version.\n", value); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + mem_clear(info->version, sizeof(info->version)); + snprintf(info->version, sizeof(info->version) - 1, "%s", value); + } else if (strcmp(key, FILEHEADER_FILETYPE) == 0) { + /* file type */ + info->file_type = firmware_upgrade_file_type_map((char *)value); + } else if (strcmp(key, FILEHEADER_CRC) == 0) { + /* file crc32 */ + info->crc32 = strtoul(value, NULL, 0); + } else { + dbg_print(is_debug_on, "Warning: key '%s' is unknown. Continue anyway.\n", key); + return FIRMWARE_SUCCESS; + } + dbg_print(is_debug_on, "key %s is matched.\n", key); + return FIRMWARE_SUCCESS; + } + +/* + * firmware_upgrade_parse_check + * function:Check the results of header parsing + * @file_name: Upgrade file name + * @info : Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_parse_check(char *file_name, name_info_t *info) +{ + int i; + if (info->card_type[0] == 0) { + dbg_print(is_debug_on, "Error: %s card type is missing.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if ((info->type <= FIRMWARE_UNDEF_TYPE) || (info->type > FIRMWARE_OTHER)) { + dbg_print(is_debug_on, "Error: %s type is unknown.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if (strlen(info->chip_name) == 0) { + dbg_print(is_debug_on, "Error: %s chip_name is empty.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if (strlen(info->version) == 0) { + dbg_print(is_debug_on, "Error: %s version is empty.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if ((info->file_type <= FIRMWARE_UNDEF_FILE_TYPE) || (info->file_type > FIRMWARE_NONE)) { + dbg_print(is_debug_on, "Error: %s file type is unknown.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + dbg_print(is_debug_on, "The file header parse:(%s) \n" , file_name); + dbg_print(is_debug_on, " card type: "); + for (i = 0; i < MAX_DEV_NUM && info->card_type[i]; i++){ + dbg_print(is_debug_on, "0x%x, ", info->card_type[i]); + } + dbg_print(is_debug_on, "\n" + " sub type : "); + for (i = 0; i < MAX_DEV_NUM && info->sub_type[i]; i++){ + dbg_print(is_debug_on, "0x%x, ", info->sub_type[i]); + } + dbg_print(is_debug_on, "\n" + " type : %d, \n" + " chain : %d, \n" + " chip name: %s \n" + " version : %s \n" + " file type: %d \n" + " the crc32 value: %#x \n", + info->type, info->chain, info->chip_name, info->version, info->file_type, info->crc32); + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_read_header + * function:Read the header information of the upgrade file + * @file_name: param[in] Upgrade file name + * @info : param[out] Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_read_header( char *file_name, name_info_t *info) +{ + FILE *fp; + char *charp; + char *charn; + char header_buffer[MAX_HEADER_SIZE]; + char header_key[MAX_HEADER_KV_SIZE]; + char header_var[MAX_HEADER_KV_SIZE]; + int ret; + int len; + + fp = fopen(file_name, "r"); + if (fp == NULL) { + dbg_print(is_debug_on, "Error: Failed to open file: %s. \n", file_name); + perror("fopen"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + mem_clear(header_buffer, sizeof(header_buffer)); + len = fread(header_buffer, MAX_HEADER_SIZE - 1, 1, fp); + fclose(fp); + if (len < 0) { + dbg_print(is_debug_on, "Error: Failed to read header : %s. \n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + header_buffer[MAX_HEADER_SIZE - 1] = 0; + + charp = strstr(header_buffer, "FILEHEADER(\n"); + if (charp == NULL) { + dbg_print(is_debug_on, "Error: The file format %s is wrong. \n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + charp += strlen("FILEHEADER(\n"); + + dbg_print(is_debug_on, "File parse start.\n"); + mem_clear(info, sizeof(name_info_t)); + ret = 0; + charn = charp; + mem_clear(header_key, sizeof(header_key)); + while (*charn != ')') { + charn = strpbrk(charp, "=,)\n"); + if (charn == NULL) { + dbg_print(is_debug_on, "Error: The parser can't find mark.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if (charn - charp >= MAX_HEADER_KV_SIZE) { + dbg_print(is_debug_on, "Error: The parser find a overflow mark.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + switch (*charn) { + case '=': + mem_clear(header_key, sizeof(header_key)); + memcpy(header_key, charp, charn - charp); + break; + case '\n': + case ',': + mem_clear(header_var, sizeof(header_var)); + memcpy(header_var, charp, charn - charp); + dbg_print(is_debug_on, "Parser: %s = %s .\n", header_key, header_var); + firmware_upgrade_parse_kv(header_key, header_var, info); + break; + case ')': + break; + default: + dbg_print(is_debug_on, "Error: The parser get unexpected mark '%c(0x%02X)'.\n", *charn, *charn); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + charp = (charn + 1); + } + + ret = firmware_upgrade_parse_check(file_name, info); + if (ret != FIRMWARE_SUCCESS) { + return FIRMWARE_FAILED; + } + + header_offset = charp + 1 - header_buffer; /* charp at '\n' */ + dbg_print(is_debug_on,"the header offset is %d \n", header_offset); + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_one_file + * function: upgrade file + * @file_name: Upgrade file name + * @main_type: main board type + * @sub_type: sub board type + * @slot: 0--main, sub slot starts at 1 + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_one_file(char *file_name, int main_type, int sub_type, int slot) +{ + int ret; + name_info_t info; + + if ((slot < 0) || (file_name == NULL)) { + dbg_print(is_debug_on, "Failed firmware_upgrade_one_file parameter err.\n"); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "firmware upgrade %s 0x%x 0x%x %d\n", file_name, main_type, sub_type, slot); + /* Read the header information of the upgrade file */ + ret = firmware_upgrade_read_header(file_name, &info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to get file header: %s\n", file_name); + return ret; + } + + /* Check the file information to determine that the file is available for use on the device */ + ret = firmware_check_file_info(&info, main_type, sub_type, slot); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "File is not match with the device: %s.\n", file_name); + return ret; + } + + /* The link number corresponding to the upgrade file is calculated based on the slot number. + 16 links are reserved for each slot. main boade slot is 0. */ + info.chain += slot * FIRMWARE_SLOT_MAX_NUM; + ret = firmware_upgrade(file_name, &info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to upgrade: %s.\n", file_name); + return ret; + } + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_file_test + * function: upgrade file + * @file_name: Upgrade file name + * @main_type: main board type + * @sub_type: sub board type + * @slot: 0--main, sub slot starts at 1 + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_file_test(char *file_name, int main_type, int sub_type, int slot) +{ + int ret; + name_info_t info; + + if ((slot < 0) || (file_name == NULL)) { + dbg_print(is_debug_on, "Failed firmware_upgrade_one_file parameter err.\n"); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "firmware upgrade %s 0x%x 0x%x %d\n", file_name, main_type, sub_type, slot); + /* Read the header information of the upgrade file */ + ret = firmware_upgrade_read_header(file_name, &info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to get file header: %s, ret=%d\n", file_name, ret); + return ret; + } + + /* Check the file information to determine that the file is available for use on the device */ + ret = firmware_check_file_info(&info, main_type, sub_type, slot); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "File is not match with the device: %s, ret=%d.\n", file_name, ret); + return ret; + } + + /* The link number corresponding to the upgrade file is calculated based on the slot number. + 16 links are reserved for each slot. main boade slot is 0. */ + info.chain += slot * FIRMWARE_SLOT_MAX_NUM; + ret = firmware_upgrade_test(file_name, &info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to upgrade: %s, ret=%d\n", file_name, ret); + return ret; + } + + return FIRMWARE_SUCCESS; +} + +static int firmware_upgrade_data_dump(char *argv[]) +{ + int ret; + uint32_t offset, len; + + /* dump by type */ + if (strcmp(argv[2], "spi_logic_dev") == 0) { + /* usag: firmware_upgrade dump spi_logic_dev dev_path offset size print/record_file_path */ + offset = strtoul(argv[4], NULL, 0); + len = strtoul(argv[5], NULL, 0); + /* offset needs align by 256 bytes */ + if ((offset & 0xff) || (len == 0)) { + dbg_print(is_debug_on,"only support offset align by 256 bytes.\n"); + return FIRMWARE_FAILED; + } + dbg_print(is_debug_on, "start to dump %s data. offset:0x%x, len:0x%x\n", argv[2], offset, len); + ret = firmware_upgrade_spi_logic_dev_dump(argv[3], offset, len, argv[6]); + } else { + dbg_print(is_debug_on, "Error: %s not support dump data.\n", argv[2]); + return FIRMWARE_FAILED; + } + + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to dump %s data. ret:%d\n", argv[3], ret); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +int main(int argc, char *argv[]) +{ + int ret; + int main_type, sub_type, slot; + + is_debug_on = firmware_upgrade_debug(); + + signal(SIGTERM, SIG_IGN); /* ignore kill signal */ + signal(SIGINT, SIG_IGN); /* ignore ctrl+c signal */ + signal(SIGTSTP, SIG_IGN); /* ignore ctrl+z signal */ + + if ((argc != 5) && (argc != 6) && (argc != 7)) { + printf("Use:\n"); + printf(" upgrade file : firmware_upgrade file main_type sub_type slot\n"); + printf(" upgrade test : firmware_upgrade test file main_type sub_type slot\n"); + printf(" spi_logic_dev dump : firmware_upgrade dump spi_logic_dev dev_path offset size print/record_file_path\n"); + dbg_print(is_debug_on, "Failed to upgrade the number of argv: %d.\n", argc); + return ERR_FW_UPGRADE; + } + + if (argc == 5) { + main_type = strtoul(argv[2], NULL, 16); + sub_type = strtoul(argv[3], NULL, 16); + slot = strtoul(argv[4], NULL, 10); + printf("+================================+\n"); + printf("|Begin to upgrade, please wait...|\n"); + ret = firmware_upgrade_one_file(argv[1], main_type, sub_type, slot); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to upgrade a firmware file: %s. (%d)\n", argv[1], ret); + printf("| Upgrade failed! |\n"); + printf("+================================+\n"); + return ret; + } + + printf("| Upgrade succeeded! |\n"); + printf("+================================+\n"); + dbg_print(is_debug_on, "Sucess to upgrade a firmware file: %s.\n", argv[1]); + return FIRMWARE_SUCCESS; + } else if ((argc == 6) && (strcmp(argv[1], "test") == 0)) { + main_type = strtoul(argv[3], NULL, 16); + sub_type = strtoul(argv[4], NULL, 16); + slot = strtoul(argv[5], NULL, 10); + printf("+=====================================+\n"); + printf("|Begin to upgrade test, please wait...|\n"); + ret = firmware_upgrade_file_test(argv[2], main_type, sub_type, slot); + if (ret == FIRMWARE_SUCCESS) { + printf("| Upgrade test succeeded! |\n"); + printf("+=====================================+\n"); + dbg_print(is_debug_on, "Sucess to upgrade test a firmware file: %s.\n", argv[2]); + return FIRMWARE_SUCCESS; + } else if (ret == ERR_FW_DO_UPGRADE_NOT_SUPPORT) { + dbg_print(is_debug_on, "do not support to upgrade test a firmware file: %s. (%d)\n", argv[2], ret); + printf("| Not support to upgrade test! |\n"); + printf("+=====================================+\n"); + return ret; + } else { + dbg_print(is_debug_on, "Failed to upgrade test a firmware file: %s. (%d)\n", argv[2], ret); + printf("| Upgrade test failed! |\n"); + printf("+=====================================+\n"); + return ret; + } + } else if (strcmp(argv[1], "dump") == 0) { + /* print device data */ + ret = firmware_upgrade_data_dump(argv); + if (ret == FIRMWARE_SUCCESS) { + printf("dump data succeeded.\n"); + return FIRMWARE_SUCCESS; + } else { + printf("dump data failed. ret:%d\n", ret); + return ret; + } + } + + printf("+=================+\n"); + printf("| UPGRADE FAIL! |\n"); + printf("+=================+\n"); + + return ERR_FW_UPGRADE; + } diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/hardware.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/hardware.c new file mode 100644 index 000000000000..c43c9095fda6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/hardware.c @@ -0,0 +1,263 @@ +/********************************************************************************* +* Lattice Semiconductor Corp. Copyright 2000-2008 +* +* This is the hardware.c of ispVME V12.1 for JTAG programmable devices. +* All the functions requiring customization are organized into this file for +* the convinience of porting. +*********************************************************************************/ +/********************************************************************************* +* Revision History: +* +* 09/11/07 NN Type cast mismatch variables +* 09/24/07 NN Added calibration function. +* Calibration will help to determine the system clock frequency +* and the count value for one micro-second delay of the target +* specific hardware. +* Modified the ispVMDelay function +* Removed Delay Percent support +* Moved the sclock() function from ivm_core.c to hardware.c +*********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/******************************************************************************** +* Declaration of global variables +* +*********************************************************************************/ + +unsigned char g_siIspPins = 0x00; /*Keeper of JTAG pin state*/ +unsigned short g_usInPort = 0x379; /*Address of the TDO pin*/ +unsigned short g_usOutPort = 0x378; /*Address of TDI, TMS, TCK pin*/ +unsigned short g_usCpu_Frequency = 1000; /*Enter your CPU frequency here, unit in MHz.*/ + +/********************************************************************************* +* This is the definition of the bit locations of each respective +* signal in the global variable g_siIspPins. +* +* NOTE: Users must add their own implementation here to define +* the bit location of the signal to target their hardware. +* The example below is for the Lattice download cable on +* on the parallel port. +* +*********************************************************************************/ + +#if 0 +const unsigned char g_ucPinTDI = JTAG_TDI; /* Bit address of TDI */ +const unsigned char g_ucPinTCK = JTAG_TCK; /* Bit address of TCK */ +const unsigned char g_ucPinTMS = JTAG_TMS; /* Bit address of TMS */ +const unsigned char g_ucPinENABLE = JTAG_ENABLE; /* Bit address of ENABLE */ +const unsigned char g_ucPinTRST = JTAG_TRST; /* Bit address of TRST */ +const unsigned char g_ucPinTDO = JTAG_TDO; /* Bit address of TDO*/ +#endif +int g_file_fd = -1; +/*************************************************************** +* +* Functions declared in hardware.c module. +* +***************************************************************/ +void writePort(unsigned char a_ucPins, unsigned char a_ucValue); +unsigned char readPort(); +void sclock(); +void ispVMDelay(unsigned short a_usTimeDelay); +void calibration(void); + +/******************************************************************************** +* writePort +* To apply the specified value to the pins indicated. This routine will +* be modified for specific systems. +* As an example, this code uses the IBM-PC standard Parallel port, along with the +* schematic shown in Lattice documentation, to apply the signals to the +* JTAG pins. +* +* PC Parallel port pin Signal name Port bit address +* 2 g_ucPinTDI 1 +* 3 g_ucPinTCK 2 +* 4 g_ucPinTMS 4 +* 5 g_ucPinENABLE 8 +* 6 g_ucPinTRST 16 +* 10 g_ucPinTDO 64 +* +* Parameters: +* - a_ucPins, which is actually a set of bit flags (defined above) +* that correspond to the bits of the data port. Each of the I/O port +* bits that drives an isp programming pin is assigned a flag +* (through a #define) corresponding to the signal it drives. To +* change the value of more than one pin at once, the flags are added +* together, much like file access flags are. +* +* The bit flags are only set if the pin is to be changed. Bits that +* do not have their flags set do not have their levels changed. The +* state of the port is always manintained in the static global +* variable g_siIspPins, so that each pin can be addressed individually +* without disturbing the others. +* +* - a_ucValue, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two +* values are valid. Any non-zero number sets the pin(s) high. +* +*********************************************************************************/ + +void writePort(unsigned char a_ucPins, unsigned char a_ucValue) +{ + switch (a_ucPins) { + case JTAG_TCK: + ioctl(g_file_fd, FIRMWARE_JTAG_TCK, &a_ucValue); + break; + case JTAG_TDI: + ioctl(g_file_fd, FIRMWARE_JTAG_TDI, &a_ucValue); + break; + case JTAG_TMS: + ioctl(g_file_fd, FIRMWARE_JTAG_TMS, &a_ucValue); + break; + case JTAG_ENABLE: + ioctl(g_file_fd, FIRMWARE_JTAG_EN, &a_ucValue); + break; + case JTAG_TRST: + //ioctl(g_file_fd, FIRMWARE_JTAG_TRST, &a_ucValue); + break; + default: + break; + } +} + +/********************************************************************************* +* +* readPort +* +* Returns the value of the TDO from the device. +* +**********************************************************************************/ +unsigned char readPort() +{ + unsigned char ucRet = 0; + + ioctl(g_file_fd, FIRMWARE_JTAG_TDO, &ucRet); + return (ucRet); +} + +/********************************************************************************* +* sclock +* +* Apply a pulse to TCK. +* +* This function is located here so that users can modify to slow down TCK if +* it is too fast (> 25MHZ). Users can change the IdleTime assignment from 0 to +* 1, 2... to effectively slowing down TCK by half, quarter... +* +*********************************************************************************/ +void sclock() +{ + unsigned short IdleTime = 0; //change to > 0 if need to slow down TCK + unsigned short usIdleIndex = 0; + IdleTime++; + for (usIdleIndex = 0; usIdleIndex < IdleTime; usIdleIndex++) { + writePort(JTAG_TCK, 0x01); + } + for (usIdleIndex = 0; usIdleIndex < IdleTime; usIdleIndex++) { + writePort(JTAG_TCK, 0x00); + } +} +/******************************************************************************** +* +* ispVMDelay +* +* +* Users must implement a delay to observe a_usTimeDelay, where +* bit 15 of the a_usTimeDelay defines the unit. +* 1 = milliseconds +* 0 = microseconds +* Example: +* a_usTimeDelay = 0x0001 = 1 microsecond delay. +* a_usTimeDelay = 0x8001 = 1 millisecond delay. +* +* This subroutine is called upon to provide a delay from 1 millisecond to a few +* hundreds milliseconds each time. +* It is understood that due to a_usTimeDelay is defined as unsigned short, a 16 bits +* integer, this function is restricted to produce a delay to 64000 micro-seconds +* or 32000 milli-second maximum. The VME file will never pass on to this function +* a delay time > those maximum number. If it needs more than those maximum, the VME +* file will launch the delay function several times to realize a larger delay time +* cummulatively. +* It is perfectly alright to provide a longer delay than required. It is not +* acceptable if the delay is shorter. +* +* Delay function example--using the machine clock signal of the native CPU------ +* When porting ispVME to a native CPU environment, the speed of CPU or +* the system clock that drives the CPU is usually known. +* The speed or the time it takes for the native CPU to execute one for loop +* then can be calculated as follows: +* The for loop usually is compiled into the ASSEMBLY code as shown below: +* LOOP: DEC RA; +* JNZ LOOP; +* If each line of assembly code needs 4 machine cycles to execute, +* the total number of machine cycles to execute the loop is 2 x 4 = 8. +* Usually system clock = machine clock (the internal CPU clock). +* Note: Some CPU has a clock multiplier to double the system clock for + the machine clock. +* +* Let the machine clock frequency of the CPU be F, or 1 machine cycle = 1/F. +* The time it takes to execute one for loop = (1/F ) x 8. +* Or one micro-second = F(MHz)/8; +* +* Example: The CPU internal clock is set to 100Mhz, then one micro-second = 100/8 = 12 +* +* The C code shown below can be used to create the milli-second accuracy. +* Users only need to enter the speed of the cpu. +* +**********************************************************************************/ +void ispVMDelay(unsigned short a_usTimeDelay) +{ + struct timespec ts; + + if (a_usTimeDelay & 0x8000) { + /* milliseconds */ + a_usTimeDelay &= 0x7FFF; + ts.tv_sec = (long int) (a_usTimeDelay / 1000); + ts.tv_nsec = (long int) (a_usTimeDelay % 1000) * 1000000ul; + } else { + /* microseconds */ + ts.tv_sec = 0; + ts.tv_nsec = (long int) a_usTimeDelay * 1000ul; + } + + nanosleep(&ts, NULL); +} + +/********************************************************************************* +* +* calibration +* +* It is important to confirm if the delay function is indeed providing +* the accuracy required. Also one other important parameter needed +* checking is the clock frequency. +* Calibration will help to determine the system clock frequency +* and the loop_per_micro value for one micro-second delay of the target +* specific hardware. +* +**********************************************************************************/ +void calibration(void) +{ + /*Apply 2 pulses to TCK.*/ + writePort(JTAG_TCK, 0x00); + writePort(JTAG_TCK, 0x01); + writePort(JTAG_TCK, 0x00); + writePort(JTAG_TCK, 0x01); + writePort(JTAG_TCK, 0x00); + + /*Delay for 1 millisecond. Pass on 1000 or 0x8001 both = 1ms delay.*/ + ispVMDelay(0x8001); + + /*Apply 2 pulses to TCK*/ + writePort(JTAG_TCK, 0x01); + writePort(JTAG_TCK, 0x00); + writePort(JTAG_TCK, 0x01); + writePort(JTAG_TCK, 0x00); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ispvm_ui.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ispvm_ui.c new file mode 100644 index 000000000000..69a8e53852b5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ispvm_ui.c @@ -0,0 +1,837 @@ +/************************************************************** +* +* Lattice Semiconductor Corp. Copyright 2008 +* +* ispVME Embedded allows programming of Lattice's suite of FPGA +* devices on embedded systems through the JTAG port. The software +* is distributed in source code form and is open to re - distribution +* and modification where applicable. +* +* ispVME Embedded C Source comprised with 3 modules: +* ispvm_ui.c is the module provides input and output support. +* ivm_core.c is the module interpret the VME file(s). +* hardware.c is the module access the JTAG port of the device(s). +* +* The optional module cable.c is for supporting Lattice's parallel +* port ispDOWNLOAD cable on DOS and Windows 95/98 O/S. It can be +* requested from Lattice's ispVMSupport. +* +***************************************************************/ + +/************************************************************** +* +* Revision History of ispvm_ui.c +* +* 3/6/07 ht Added functions vme_out_char(),vme_out_hex(), +* vme_out_string() to provide output resources. +* Consolidate all printf() calls into the added output +* functions. +* +* 09/11/07 NN Added Global variables initialization +* 09/24/07 NN Added a switch allowing users to do calibration. +* Calibration will help to determine the system clock frequency +* and the count value for one micro-second delay of the target +* specific hardware. +* Removed Delay Percent support +* 11/15/07 NN moved the checking of the File CRC to the end of processing +* 08/28/08 NN Added Calculate checksum support. +***************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*************************************************************** +* +* File pointer to the VME file. +* +***************************************************************/ + +FILE *g_pVMEFile = NULL; + +/*************************************************************** +* +* Functions declared in this ispvm_ui.c module +* +***************************************************************/ +unsigned char GetByte(void); +void vme_out_char(unsigned char charOut); +void vme_out_hex(unsigned char hexOut); +void vme_out_string(char *stringOut); +void ispVMMemManager(signed char cTarget, unsigned short usSize); +void ispVMFreeMem(void); +void error_handler(short a_siRetCode, char *pszMessage); +signed char ispVM(const char *a_pszFilename); + +/*************************************************************** +* +* Global variables. +* +***************************************************************/ +unsigned short g_usPreviousSize = 0; +unsigned short g_usExpectedCRC = 0; + +/*************************************************************** +* +* External variables and functions declared in ivm_core.c module. +* +***************************************************************/ +extern signed char ispVMCode(); +extern void ispVMCalculateCRC32(unsigned char a_ucData); +extern void ispVMStart(); +extern void ispVMEnd(); +extern unsigned short g_usCalculatedCRC; +extern unsigned short g_usDataType; +extern unsigned char *g_pucOutMaskData, +*g_pucInData, +*g_pucOutData, +*g_pucHIRData, +*g_pucTIRData, +*g_pucHDRData, +*g_pucTDRData, +*g_pucOutDMaskData, +*g_pucIntelBuffer; +extern unsigned char *g_pucHeapMemory; +extern unsigned short g_iHeapCounter; +extern unsigned short g_iHEAPSize; +extern unsigned short g_usIntelDataIndex; +extern unsigned short g_usIntelBufferSize; +extern LVDSPair *g_pLVDSList; +//08/28/08 NN Added Calculate checksum support. +extern unsigned long g_usChecksum; +extern unsigned int g_uiChecksumIndex; + +/* Added reinit for call ispvme more than once */ +extern void ivm_core_reinit(); +/*************************************************************** +* +* External variables and functions declared in hardware.c module. +* +***************************************************************/ +extern void calibration(void); +extern unsigned short g_usCpu_Frequency; +extern int g_file_fd; + +/*************************************************************** +* +* Supported VME versions. +* +***************************************************************/ + +const char *const g_szSupportedVersions[] = { "__VME2.0", "__VME3.0", "____12.0", "____12.1", 0 }; + +/*************************************************************** +* +* GetByte +* +* Returns a byte to the caller. The returned byte depends on the +* g_usDataType register. If the HEAP_IN bit is set, then the byte +* is returned from the HEAP. If the LHEAP_IN bit is set, then +* the byte is returned from the intelligent buffer. Otherwise, +* the byte is returned directly from the VME file. +* +***************************************************************/ + +char* strlwr(char *str) +{ + char *orig = str; +// process the string + for (; *str != '\0'; str++) + *str = tolower(*str); + return orig; +} + +unsigned char GetByte() +{ + unsigned char ucData = 0; + + if (g_usDataType & HEAP_IN) { + + /*************************************************************** + * + * Get data from repeat buffer. + * + ***************************************************************/ + + if (g_iHeapCounter > g_iHEAPSize) { + + /*************************************************************** + * + * Data over-run. + * + ***************************************************************/ + + return 0xFF; + } + + ucData = g_pucHeapMemory[g_iHeapCounter++]; + } + else if ( g_usDataType & LHEAP_IN ) { + + /*************************************************************** + * + * Get data from intel buffer. + * + ***************************************************************/ + + if (g_usIntelDataIndex >= g_usIntelBufferSize) { + + /*************************************************************** + * + * Data over-run. + * + ***************************************************************/ + + return 0xFF; + } + + ucData = g_pucIntelBuffer[g_usIntelDataIndex++]; + } + else { + + /*************************************************************** + * + * Get data from file. + * + ***************************************************************/ + + ucData = (unsigned char)fgetc(g_pVMEFile); + + if (feof(g_pVMEFile)) { + + /*************************************************************** + * + * Reached EOF. + * + ***************************************************************/ + + return 0xFF; + } + /*************************************************************** + * + * Calculate the 32-bit CRC if the expected CRC exist. + * + ***************************************************************/ + if( g_usExpectedCRC != 0) + { + ispVMCalculateCRC32(ucData); + } + } + + return (ucData); +} + +/*************************************************************** +* +* vme_out_char +* +* Send a character out to the output resource if available. +* The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_char(unsigned char charOut) +{ + dbg_print(is_debug_on, "%c", charOut); +} +/*************************************************************** +* +* vme_out_hex +* +* Send a character out as in hex format to the output resource +* if available. The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_hex(unsigned char hexOut) +{ + dbg_print(is_debug_on, "%.2X", hexOut); +} +/*************************************************************** +* +* vme_out_string +* +* Send a text string out to the output resource if available. +* The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_string(char *stringOut) +{ + dbg_print(is_debug_on,"%s",stringOut); +} +/*************************************************************** +* +* ispVMMemManager +* +* Allocate memory based on cTarget. The memory size is specified +* by usSize. +* +***************************************************************/ + +void ispVMMemManager(signed char cTarget, unsigned short usSize) +{ + switch (cTarget) { + case XTDI: + case TDI: + if (g_pucInData != NULL) { + if (g_usPreviousSize == usSize) { /*memory exist*/ + break; + } + else { + free(g_pucInData); + g_pucInData = NULL; + } + } + g_pucInData = (unsigned char *)malloc(usSize / 8 + 2); + g_usPreviousSize = usSize; + case XTDO: + case TDO: + if (g_pucOutData != NULL) { + if (g_usPreviousSize == usSize) { /*already exist*/ + break; + } + else { + free(g_pucOutData); + g_pucOutData = NULL; + } + } + g_pucOutData = (unsigned char *)malloc(usSize / 8 + 2); + g_usPreviousSize = usSize; + break; + case MASK: + if (g_pucOutMaskData != NULL) { + if (g_usPreviousSize == usSize) { /*already allocated*/ + break; + } + else { + free(g_pucOutMaskData); + g_pucOutMaskData = NULL; + } + } + g_pucOutMaskData = (unsigned char *)malloc(usSize / 8 + 2); + g_usPreviousSize = usSize; + break; + case HIR: + if (g_pucHIRData != NULL) { + free(g_pucHIRData); + g_pucHIRData = NULL; + } + g_pucHIRData = (unsigned char *)malloc(usSize / 8 + 2); + break; + case TIR: + if (g_pucTIRData != NULL) { + free(g_pucTIRData); + g_pucTIRData = NULL; + } + g_pucTIRData = (unsigned char *)malloc(usSize / 8 + 2); + break; + case HDR: + if (g_pucHDRData != NULL) { + free(g_pucHDRData); + g_pucHDRData = NULL; + } + g_pucHDRData = (unsigned char *)malloc(usSize / 8 + 2); + break; + case TDR: + if (g_pucTDRData != NULL) { + free(g_pucTDRData); + g_pucTDRData = NULL; + } + g_pucTDRData = (unsigned char *)malloc(usSize / 8 + 2); + break; + case HEAP: + if (g_pucHeapMemory != NULL) { + free(g_pucHeapMemory); + g_pucHeapMemory = NULL; + } + g_pucHeapMemory = (unsigned char *)malloc(usSize + 2); + break; + case DMASK: + if (g_pucOutDMaskData != NULL) { + if (g_usPreviousSize == usSize) { /*already allocated*/ + break; + } + else { + free(g_pucOutDMaskData); + g_pucOutDMaskData = NULL; + } + } + g_pucOutDMaskData = (unsigned char *)malloc(usSize / 8 + 2); + g_usPreviousSize = usSize; + break; + case LHEAP: + if (g_pucIntelBuffer != NULL) { + free(g_pucIntelBuffer); + g_pucIntelBuffer = NULL; + } + g_pucIntelBuffer = (unsigned char *)malloc(usSize + 2); + break; + case LVDS: + if (g_pLVDSList != NULL) { + free(g_pLVDSList); + g_pLVDSList = NULL; + } + g_pLVDSList = (LVDSPair * )calloc(usSize, sizeof(LVDSPair)); + break; + default: + return; + } +} + +/*************************************************************** +* +* ispVMFreeMem +* +* Free memory that were dynamically allocated. +* +***************************************************************/ + +void ispVMFreeMem() +{ + if (g_pucHeapMemory != NULL) { + free(g_pucHeapMemory); + g_pucHeapMemory = NULL; + } + + if (g_pucOutMaskData != NULL) { + free(g_pucOutMaskData); + g_pucOutMaskData = NULL; + } + + if (g_pucInData != NULL) { + free(g_pucInData); + g_pucInData = NULL; + } + + if (g_pucOutData != NULL) { + free(g_pucOutData); + g_pucOutData = NULL; + } + + if (g_pucHIRData != NULL) { + free(g_pucHIRData); + g_pucHIRData = NULL; + } + + if (g_pucTIRData != NULL) { + free(g_pucTIRData); + g_pucTIRData = NULL; + } + + if (g_pucHDRData != NULL) { + free(g_pucHDRData); + g_pucHDRData = NULL; + } + + if (g_pucTDRData != NULL) { + free(g_pucTDRData); + g_pucTDRData = NULL; + } + + if (g_pucOutDMaskData != NULL) { + free(g_pucOutDMaskData); + g_pucOutDMaskData = NULL; + } + + if (g_pucIntelBuffer != NULL) { + free(g_pucIntelBuffer); + g_pucIntelBuffer = NULL; + } + + if (g_pLVDSList != NULL) { + free(g_pLVDSList); + g_pLVDSList = NULL; + } +} + +/*************************************************************** +* +* error_handler +* +* Reports the error message. +* +***************************************************************/ + +void error_handler(short a_siRetCode, char *pszMessage) +{ + const char *pszErrorMessage[] = { "pass", + "verification fail", + "can't find the file", + "wrong file type", + "file error", + "option error", + "crc verification error" }; + + strcpy(pszMessage, pszErrorMessage[-a_siRetCode]); +} +/*************************************************************** +* +* ispVM +* +* The entry point of the ispVM embedded. If the version and CRC +* are verified, then the VME will be processed. +* +***************************************************************/ +signed char ispVM(const char *a_pszFilename) +{ + char szFileVersion[9] = { 0 }; + signed char cRetCode = 0; + signed char cIndex = 0; + signed char cVersionIndex = 0; + unsigned char ucReadByte = 0; + int ret; + /*************************************************************** + * + * Global variables initialization. + * + * 09/11/07 NN Added + ***************************************************************/ + g_pucHeapMemory = NULL; + g_iHeapCounter = 0; + g_iHEAPSize = 0; + g_usIntelDataIndex = 0; + g_usIntelBufferSize = 0; + g_usPreviousSize = 0; + + /*************************************************************** + * + * Open a file pointer to the VME file. + * + ***************************************************************/ + + if ((g_pVMEFile = fopen(a_pszFilename, "rb")) == NULL) { + return VME_FILE_READ_FAILURE; + } + /* Skip the contents of the file header */ + ret=fseek(g_pVMEFile, header_offset, SEEK_SET); + if (ret < 0) { + vme_out_string("Failed to skip header.\n"); + fclose(g_pVMEFile); + g_pVMEFile = NULL; + return VME_ARGUMENT_FAILURE; + } + + g_usCalculatedCRC = 0; + g_usExpectedCRC = 0; + ucReadByte = GetByte(); + switch (ucReadByte) { + case FILE_CRC: + + /*************************************************************** + * + * Read and store the expected CRC to do the comparison at the end. + * Only versions 3.0 and higher support CRC protection. + * + ***************************************************************/ + + g_usExpectedCRC = (unsigned char)fgetc(g_pVMEFile); + g_usExpectedCRC <<= 8; + g_usExpectedCRC |= fgetc(g_pVMEFile); + + /*************************************************************** + * + * Read and store the version of the VME file. + * + ***************************************************************/ + + for (cIndex = 0; cIndex < 8; cIndex++) { + szFileVersion[cIndex] = GetByte(); + } + break; + default: + + /*************************************************************** + * + * Read and store the version of the VME file. Must be version 2.0. + * + ***************************************************************/ + + szFileVersion[0] = (signed char)ucReadByte; + for (cIndex = 1; cIndex < 8; cIndex++) { + szFileVersion[cIndex] = GetByte(); + } + + break; + } + + /*************************************************************** + * + * Compare the VME file version against the supported version. + * + ***************************************************************/ + for (cVersionIndex = 0; g_szSupportedVersions[cVersionIndex] != 0; cVersionIndex++) { + for (cIndex = 0; cIndex < 8; cIndex++) { + if (szFileVersion[cIndex] != g_szSupportedVersions[cVersionIndex][cIndex]) { + cRetCode = VME_VERSION_FAILURE; + break; + } + cRetCode = 0; + } + + if (cRetCode == 0) { + + /*************************************************************** + * + * Found matching version, break. + * + ***************************************************************/ + + break; + } + } + + if (cRetCode < 0) { + + /*************************************************************** + * + * VME file version failed to match the supported versions. + * + ***************************************************************/ + + fclose(g_pVMEFile); + g_pVMEFile = NULL; + return VME_VERSION_FAILURE; + } + + /*************************************************************** + * + * Enable the JTAG port to communicate with the device. + * Set the JTAG state machine to the Test-Logic/Reset State. + * + ***************************************************************/ + ispVMStart(); + + /*************************************************************** + * + * Process the VME file. + * + ***************************************************************/ + + cRetCode = ispVMCode(); + + /*************************************************************** + * + * Set the JTAG State Machine to Test-Logic/Reset state then disable + * the communication with the JTAG port. + * + ***************************************************************/ + + ispVMEnd(); + + fclose(g_pVMEFile); + g_pVMEFile = NULL; + + ispVMFreeMem(); + + /*************************************************************** + * + * Compare the expected CRC versus the calculated CRC. + * + ***************************************************************/ + + if (cRetCode == 0 && g_usExpectedCRC != 0 && (g_usExpectedCRC != g_usCalculatedCRC)) { + printf("Expected CRC: 0x%.4X\n", g_usExpectedCRC); + printf("Calculated CRC: 0x%.4X\n", g_usCalculatedCRC); + return VME_CRC_FAILURE; + } + + return (cRetCode); +} + +/*************************************************************** +* +* ispvme_reinit +* +* Reinit ispvm_ui variables. +* +***************************************************************/ +static void ispvm_ui_reinit() +{ + g_pVMEFile = NULL; + g_usPreviousSize = 0; + g_usExpectedCRC = 0; +} + +/*************************************************************** +* +* main +* +***************************************************************/ + +int ispvme_main(int argc, char *argv[], int file_fd, name_info_t *info) +{ + unsigned short iCommandLineIndex = 0; + short siRetCode = 0; + char szExtension[5] = { 0 }; + char szCommandLineArg[300] = { 0 }; + short sicalibrate = 0; + + ispvm_ui_reinit(); + ivm_core_reinit(); + + //08/28/08 NN Added Calculate checksum support. + g_usChecksum = 0; + g_uiChecksumIndex = 0; + + if (file_fd < 0) { + dbg_print(is_debug_on, "Error:firmware upgrade ispvme dev parameters failed.\r\n"); + return -1; + } else { + g_file_fd = file_fd; + } + +#if 0 + ret = firmware_check_chip_name(g_file_fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip name: %s.\n", file_name); + close(g_file_fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + ret = firmware_check_chip_verison(g_file_fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip version: %s.\n", file_name); + close(g_file_fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } +#endif + + vme_out_string(" Lattice Semiconductor Corp.\n"); + vme_out_string("\n ispVME(tm) V"); + vme_out_string(VME_VERSION_NUMBER); + vme_out_string(" Copyright 1998-2011.\n"); + vme_out_string("\nFor daisy chain programming of all in-system programmable devices\n\n"); + + if (argc < 2) { + vme_out_string("\nUsage: vme [option] vme_file [vme_file]\n"); + vme_out_string("Example: vme vme_file1.vme vme_file2.vme\n"); + vme_out_string("option -c: do the calibration.\n"); + vme_out_string("Example: vme -c\n"); + vme_out_string("Example: vme -c vme_file1.vme vme_file2.vme\n"); + vme_out_string("\n\n"); + g_file_fd = -1; + /* Change return to determine whether the upgrade was successful */ + return -1; + } + for (iCommandLineIndex = 1; iCommandLineIndex < argc; iCommandLineIndex++) { + strncpy(szCommandLineArg, argv[iCommandLineIndex], sizeof(szCommandLineArg) - 1); + if (!strcmp(strlwr(szCommandLineArg), "-c") && (iCommandLineIndex == 1)) { + sicalibrate = 1; + } else if (!strcmp(strlwr(szCommandLineArg), "-c") && (iCommandLineIndex != 1)) { + vme_out_string("Error: calibrate option -c must be the first argument\n\n"); + g_file_fd = -1; + /* Change return to determine whether the upgrade was successful */ + return -1; + //exit(1); + } else { + strcpy(szExtension, &szCommandLineArg[strlen(szCommandLineArg) - 4]); + strlwr(szExtension); + if (strcmp(szExtension, ".vme")) { + vme_out_string("Error: VME files must end with the extension *.vme\n\n"); + g_file_fd = -1; + /* Change return to determine whether the upgrade was successful */ + return -1; + //exit(1); + } + } + } + siRetCode = 0; + + if (sicalibrate) { + calibration(); + } + for (iCommandLineIndex = 1; iCommandLineIndex < argc; iCommandLineIndex++) { /* Process all VME files sequentially */ + strcpy(szCommandLineArg, argv[iCommandLineIndex]); + if (!strcmp(strlwr(szCommandLineArg), "-c") && (iCommandLineIndex == 1)) { + + } else if (!strcmp(strlwr(szCommandLineArg), "-checksum")) { + + } else { + vme_out_string("Processing virtual machine file ("); + vme_out_string(szCommandLineArg); + vme_out_string(")......\n\n"); + siRetCode = ispVM(argv[iCommandLineIndex]); + if (siRetCode < 0) { + break; + } + } + } + + if (siRetCode < 0) { + error_handler(siRetCode, szCommandLineArg); + vme_out_string("Failed due to "); + vme_out_string(szCommandLineArg); + vme_out_string("\n\n"); + vme_out_string("+=======+\n"); + vme_out_string("| FAIL! |\n"); + vme_out_string("+=======+\n\n"); + } else { + vme_out_string("+=======+\n"); + vme_out_string("| PASS! |\n"); + vme_out_string("+=======+\n\n"); + //08/28/08 NN Added Calculate checksum support. + if (g_usChecksum != 0) { + g_usChecksum &= 0xFFFF; + printf("Data Checksum: %.4X\n\n", (unsigned int)g_usChecksum); + g_usChecksum = 0; + } + } + g_file_fd = -1; + /* Change return to determine whether the upgrade was successful */ + return siRetCode; + //exit(siRetCode); +} + +/* + * firmware_upgrade_ispvme + * function: ispvme firmware upgrade + * @file_fd: param[in] Upgrade devices fd + * @upgrade_file_name: param[in] Upgrade file name + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +int firmware_upgrade_ispvme(int file_fd, char *upgrade_file_name, name_info_t *info) +{ + char *argv[2]; + int ret, rv, i, retry; + + argv[1] = upgrade_file_name; + + /* Initialize and enable */ + rv = ioctl(file_fd, FIRMWARE_JTAG_INIT,NULL); + if (rv < 0) { + vme_out_string("Failed to init GPIO.\n"); + return VME_ARGUMENT_FAILURE; + } + + i = 0; + retry = FIRMWARE_UPGRADE_RETRY_CNT; + + ret = 0; + while(i < retry) { + ret = ispvme_main(2, argv, file_fd, info); + if (ret < 0) { + i++; + dbg_print(is_debug_on, "%d times ispvme upgrade failed. ret %d.\n", i, ret); + continue; + } else { + dbg_print(is_debug_on, "ispvme upgrade success.\n"); + break; + } + } + + /* Upgrade completed, release */ + rv = ioctl(file_fd, FIRMWARE_JTAG_FINISH, NULL); + if (rv < 0) { + vme_out_string("Failed to release GPIO.\n"); + return VME_ARGUMENT_FAILURE; + } + + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ivm_core.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ivm_core.c new file mode 100644 index 000000000000..540be481d35e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ivm_core.c @@ -0,0 +1,3097 @@ +/*************************************************************** +* +* Lattice Semiconductor Corp. Copyright 2009 +* +* ispVME Embedded allows programming of Lattice's suite of FPGA +* devices on embedded systems through the JTAG port. The software +* is distributed in source code form and is open to re - distribution +* and modification where applicable. +* +* Revision History of ivm_core.c module: +* 4/25/06 ht Change some variables from unsigned short or int +* to long int to make the code compiler independent. +* 5/24/06 ht Support using RESET (TRST) pin as a special purpose +* control pin such as triggering the loading of known +* state exit. +* 3/6/07 ht added functions to support output to terminals +* +* 09/24/07 NN Type cast mismatch variables +* Moved the sclock() function to hardware.c +* 08/28/08 NN Added Calculate checksum support. +* 4/1/09 Nguyen replaced the recursive function call codes on +* the ispVMLCOUNT function +* +***************************************************************/ + +#include +#include +#include +#include + +/*************************************************************** +* +* Global variables used to specify the flow control and data type. +* +* g_usFlowControl: flow control register. Each bit in the +* register can potentially change the +* personality of the embedded engine. +* g_usDataType: holds the data type of the current row. +* +***************************************************************/ + +unsigned short g_usFlowControl = 0x0000; +unsigned short g_usDataType = 0x0000; + +/*************************************************************** +* +* Global variables used to specify the ENDDR and ENDIR. +* +* g_ucEndDR: the state that the device goes to after SDR. +* g_ucEndIR: the state that the device goes to after SIR. +* +***************************************************************/ + +unsigned char g_ucEndDR = DRPAUSE; +unsigned char g_ucEndIR = IRPAUSE; + +/*************************************************************** +* +* Global variables used to support header/trailer. +* +* g_usHeadDR: the number of lead devices in bypass. +* g_usHeadIR: the sum of IR length of lead devices. +* g_usTailDR: the number of tail devices in bypass. +* g_usTailIR: the sum of IR length of tail devices. +* +***************************************************************/ + +unsigned short g_usHeadDR = 0; +unsigned short g_usHeadIR = 0; +unsigned short g_usTailDR = 0; +unsigned short g_usTailIR = 0; + +/*************************************************************** +* +* Global variable to store the number of bits of data or instruction +* to be shifted into or out from the device. +* +***************************************************************/ + +unsigned short g_usiDataSize = 0; + +/*************************************************************** +* +* Stores the frequency. Default to 1 MHz. +* +***************************************************************/ + +int g_iFrequency = 1000; + +/*************************************************************** +* +* Stores the maximum amount of ram needed to hold a row of data. +* +***************************************************************/ + +unsigned short g_usMaxSize = 0; + +/*************************************************************** +* +* Stores the LSH or RSH value. +* +***************************************************************/ + +unsigned short g_usShiftValue = 0; + +/*************************************************************** +* +* Stores the current repeat loop value. +* +***************************************************************/ + +unsigned short g_usRepeatLoops = 0; + +/*************************************************************** +* +* Stores the current vendor. +* +***************************************************************/ + +signed char g_cVendor = LATTICE; + +/*************************************************************** +* +* Stores the VME file CRC. +* +***************************************************************/ + +unsigned short g_usCalculatedCRC = 0; + +/*************************************************************** +* +* Stores the Device Checksum. +* +***************************************************************/ +//08/28/08 NN Added Calculate checksum support. +unsigned long g_usChecksum = 0; +unsigned int g_uiChecksumIndex = 0; + +/*************************************************************** +* +* Stores the current state of the JTAG state machine. +* +***************************************************************/ + +signed char g_cCurrentJTAGState = 0; + +/*************************************************************** +* +* Global variables used to support looping. +* +* g_pucHeapMemory: holds the entire repeat loop. +* g_iHeapCounter: points to the current byte in the repeat loop. +* g_iHEAPSize: the current size of the repeat in bytes. +* +***************************************************************/ + +unsigned char *g_pucHeapMemory = NULL; +unsigned short g_iHeapCounter = 0; +unsigned short g_iHEAPSize = 0; + +/*************************************************************** +* +* Global variables used to support intelligent programming. +* +* g_usIntelDataIndex: points to the current byte of the +* intelligent buffer. +* g_usIntelBufferSize: holds the size of the intelligent +* buffer. +* +***************************************************************/ + +unsigned short g_usIntelDataIndex = 0; +unsigned short g_usIntelBufferSize = 0; + +/**************************************************************************** +* +* Holds the maximum size of each respective buffer. These variables are used +* to write the HEX files when converting VME to HEX. +* +*****************************************************************************/ + +unsigned short g_usTDOSize = 0; +unsigned short g_usMASKSize = 0; +unsigned short g_usTDISize = 0; +unsigned short g_usDMASKSize = 0; +unsigned short g_usLCOUNTSize = 0; +unsigned short g_usHDRSize = 0; +unsigned short g_usTDRSize = 0; +unsigned short g_usHIRSize = 0; +unsigned short g_usTIRSize = 0; +unsigned short g_usHeapSize = 0; + +/*************************************************************** +* +* Global variables used to store data. +* +* g_pucOutMaskData: local RAM to hold one row of MASK data. +* g_pucInData: local RAM to hold one row of TDI data. +* g_pucOutData: local RAM to hold one row of TDO data. +* g_pucHIRData: local RAM to hold the current SIR header. +* g_pucTIRData: local RAM to hold the current SIR trailer. +* g_pucHDRData: local RAM to hold the current SDR header. +* g_pucTDRData: local RAM to hold the current SDR trailer. +* g_pucIntelBuffer: local RAM to hold the current intelligent buffer. +* g_pucOutDMaskData: local RAM to hold one row of DMASK data. +* +***************************************************************/ + +unsigned char *g_pucOutMaskData = NULL, +*g_pucInData = NULL, +*g_pucOutData = NULL, +*g_pucHIRData = NULL, +*g_pucTIRData = NULL, +*g_pucHDRData = NULL, +*g_pucTDRData = NULL, +*g_pucIntelBuffer = NULL, +*g_pucOutDMaskData = NULL; + +/*************************************************************** +* +* JTAG state machine transition table. +* +***************************************************************/ + +struct { + unsigned char CurState; /* From this state */ + unsigned char NextState; /* Step to this state */ + unsigned char Pattern; /* The tragetory of TMS */ + unsigned char Pulses; /* The number of steps */ +} g_JTAGTransistions[25] = { + { RESET, RESET, 0xFC, 6 }, /* Transitions from RESET */ + { RESET, IDLE, 0x00, 1 }, + { RESET, DRPAUSE, 0x50, 5 }, + { RESET, IRPAUSE, 0x68, 6 }, + { IDLE, RESET, 0xE0, 3 }, /* Transitions from IDLE */ + { IDLE, DRPAUSE, 0xA0, 4 }, + { IDLE, IRPAUSE, 0xD0, 5 }, + { DRPAUSE, RESET, 0xF8, 5 }, /* Transitions from DRPAUSE */ + { DRPAUSE, IDLE, 0xC0, 3 }, + { DRPAUSE, IRPAUSE, 0xF4, 7 }, + { DRPAUSE, DRPAUSE, 0xE8, 6 }, /* 06/14/06 Support POLING STATUS LOOP*/ + { IRPAUSE, RESET, 0xF8, 5 }, /* Transitions from IRPAUSE */ + { IRPAUSE, IDLE, 0xC0, 3 }, + { IRPAUSE, DRPAUSE, 0xE8, 6 }, + { DRPAUSE, SHIFTDR, 0x80, 2 }, /* Extra transitions using SHIFTDR */ + { IRPAUSE, SHIFTDR, 0xE0, 5 }, + { SHIFTDR, DRPAUSE, 0x80, 2 }, + { SHIFTDR, IDLE, 0xC0, 3 }, + { IRPAUSE, SHIFTIR, 0x80, 2 }, /* Extra transitions using SHIFTIR */ + { SHIFTIR, IRPAUSE, 0x80, 2 }, + { SHIFTIR, IDLE, 0xC0, 3 }, + { DRPAUSE, DRCAPTURE, 0xE0, 4 }, /* 11/15/05 Support DRCAPTURE*/ + { DRCAPTURE, DRPAUSE, 0x80, 2 }, + { IDLE, DRCAPTURE, 0x80, 2 }, + { IRPAUSE, DRCAPTURE, 0xE0, 4 } +}; + +/*************************************************************** +* +* List to hold all LVDS pairs. +* +***************************************************************/ + +LVDSPair *g_pLVDSList = NULL; +unsigned short g_usLVDSPairCount = 0; + +/*************************************************************** +* +* Function prototypes. +* +***************************************************************/ + +signed char ispVMCode(); +signed char ispVMDataCode(); +long int ispVMDataSize(); +void ispVMData(unsigned char *Data); +signed char ispVMShift(signed char Code); +signed char ispVMAmble(signed char Code); +signed char ispVMLoop(unsigned short a_usLoopCount); +signed char ispVMBitShift(signed char mode, unsigned short bits); +void ispVMComment(unsigned short a_usCommentSize); +void ispVMHeader(unsigned short a_usHeaderSize); +signed char ispVMLCOUNT(unsigned short a_usCountSize); +void ispVMClocks(unsigned short Clocks); +void ispVMBypass(signed char ScanType, unsigned short Bits); +void ispVMStateMachine(signed char NextState); +void ispVMStart(); +void ispVMEnd(); +signed char ispVMSend(unsigned short int); +signed char ispVMRead(unsigned short int); +signed char ispVMReadandSave(unsigned short int); +signed char ispVMProcessLVDS(unsigned short a_usLVDSCount); + +/*************************************************************** +* +* External variables and functions in ispvm_ui.c module +* +***************************************************************/ +extern void vme_out_char(unsigned char charOut); +extern void vme_out_hex(unsigned char hexOut); +extern void vme_out_string(char *stringOut); +extern unsigned char GetByte(); +extern void ispVMMemManager(signed char types, unsigned short size); + +/*************************************************************** +* +* External variables and functions in hardware.c module +* +***************************************************************/ +extern void ispVMDelay(unsigned short int a_usMicroSecondDelay); +extern unsigned char readPort(); +extern void writePort(unsigned char pins, unsigned char value); +extern void sclock(); +extern signed char g_cCurrentJTAGState; +#ifdef VME_DEBUG + +/*************************************************************** +* +* GetState +* +* Returns the state as a string based on the opcode. Only used +* for debugging purposes. +* +***************************************************************/ + +const char* GetState(unsigned char a_ucState) +{ + switch (a_ucState) { + case RESET: + return ("RESET"); + case IDLE: + return ("IDLE"); + case IRPAUSE: + return ("IRPAUSE"); + case DRPAUSE: + return ("DRPAUSE"); + case SHIFTIR: + return ("SHIFTIR"); + case SHIFTDR: + return ("SHIFTDR"); + case DRCAPTURE: /* 11/15/05 support DRCAPTURE*/ + return ("DRCAPTURE"); + default: + break; + } + + return 0; +} + +/*************************************************************** +* +* PrintData +* +* Prints the data. Only used for debugging purposes. +* +***************************************************************/ + +void PrintData(unsigned short a_iDataSize, unsigned char *a_pucData) +{ + //09/11/07 NN added local variables initialization + unsigned short usByteSize = 0; + unsigned short usBitIndex = 0; + signed short usByteIndex = 0; + unsigned char ucByte = 0; + unsigned char ucFlipByte = 0; + + if (a_iDataSize % 8) { + //09/11/07 NN Type cast mismatch variables + usByteSize = (unsigned short)(a_iDataSize / 8 + 1); + } else { + //09/11/07 NN Type cast mismatch variables + usByteSize = (unsigned short)(a_iDataSize / 8);// 4 + } + printf("("); + //09/11/07 NN Type cast mismatch variables + for (usByteIndex = (signed short)(usByteSize - 1); usByteIndex >= 0; usByteIndex--) { + ucByte = a_pucData[usByteIndex]; + ucFlipByte = 0x00; + + /*************************************************************** + * + * Flip each byte. + * + ***************************************************************/ + + for (usBitIndex = 0; usBitIndex < 8; usBitIndex++) { + ucFlipByte <<= 1; + if (ucByte & 0x1) { + ucFlipByte |= 0x1; + } + + ucByte >>= 1; + } + + /*************************************************************** + * + * Print the flipped byte. + * + ***************************************************************/ + + printf("%.02X", ucFlipByte); + if ((usByteSize - usByteIndex) % 40 == 39) { + printf("\n\t\t"); + } + if (usByteIndex < 0) + break; + } + printf(")"); +} +#endif //VME_DEBUG + +/*************************************************************** +* +* ispVMDataSize +* +* Returns a VME-encoded number, usually used to indicate the +* bit length of an SIR/SDR command. +* +***************************************************************/ + +long int ispVMDataSize() +{ + //09/11/07 NN added local variables initialization + long int iSize = 0; + signed char cCurrentByte = 0; + signed char cIndex = 0; + cIndex = 0; + + while ((cCurrentByte = GetByte()) & 0x80) { + iSize |= ((long int)(cCurrentByte & 0x7F)) << cIndex; + cIndex += 7; + } + iSize |= ((long int)(cCurrentByte & 0x7F)) << cIndex; + + return iSize; +} + +/*************************************************************** +* +* ispVMCode +* +* This is the heart of the embedded engine. All the high-level opcodes +* are extracted here. Once they have been identified, then it +* will call other functions to handle the processing. +* +***************************************************************/ + +signed char ispVMCode() +{ + //09/11/07 NN added local variables initialization + unsigned short iRepeatSize = 0; + signed char cOpcode = 0; + signed char cRetCode = 0; + unsigned char ucState = 0; + unsigned short usDelay = 0; + unsigned short usToggle = 0; + unsigned char usByte = 0; + + /*************************************************************** + * + * Check the compression flag only if this is the first time + * this function is entered. Do not check the compression flag if + * it is being called recursively from other functions within + * the embedded engine. + * + ***************************************************************/ + + if (!(g_usDataType & LHEAP_IN) && !(g_usDataType & HEAP_IN)) { + usByte = GetByte(); + if (usByte == 0xf1) { + g_usDataType |= COMPRESS; + } else if (usByte == 0xf2) { + g_usDataType &= ~COMPRESS; + } else { + return VME_INVALID_FILE; + } + } + + /*************************************************************** + * + * Begin looping through all the VME opcodes. + * + ***************************************************************/ + while ((cOpcode = GetByte()) >= 0) { + switch (cOpcode) { + case STATE: + + /*************************************************************** + * + * Step the JTAG state machine. + * + ***************************************************************/ + + ucState = GetByte(); + /*************************************************************** + * + * Step the JTAG state machine to DRCAPTURE to support Looping. + * + ***************************************************************/ + + if ((g_usDataType & LHEAP_IN) && + (ucState == DRPAUSE) && + (g_cCurrentJTAGState == ucState)) { + ispVMStateMachine(DRCAPTURE); + } + + ispVMStateMachine(ucState); + +#ifdef VME_DEBUG + if (g_usDataType & LHEAP_IN) { + printf("LDELAY %s ", GetState(ucState)); + } else { + printf("STATE %s;\n", GetState(ucState)); + } +#endif //VME_DEBUG + break; + case SIR: + case SDR: + case XSDR: + +#ifdef VME_DEBUG + switch (cOpcode) { + case SIR: + printf("SIR "); + break; + case SDR: + case XSDR: + if (g_usDataType & LHEAP_IN) { + printf("LSDR "); + } else { + printf("SDR "); + } + break; + } +#endif //VME_DEBUG + /*************************************************************** + * + * Shift in data into the device. + * + ***************************************************************/ + cRetCode = ispVMShift(cOpcode); + if (cRetCode != 0) { + return (cRetCode); + } + break; + case WAIT: + + /*************************************************************** + * + * Observe delay. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + usDelay = (unsigned short)ispVMDataSize(); + ispVMDelay(usDelay); + +#ifdef VME_DEBUG + if (usDelay & 0x8000) { + + /*************************************************************** + * + * Since MSB is set, the delay time must be decoded to + * millisecond. The SVF2VME encodes the MSB to represent + * millisecond. + * + ***************************************************************/ + + usDelay &= ~0x8000; + if (g_usDataType & LHEAP_IN) { + printf("%.2E SEC;\n", (float)usDelay / 1000); + } else { + printf("RUNTEST %.2E SEC;\n", (float)usDelay / 1000); + } + } else { + + /*************************************************************** + * + * Since MSB is not set, the delay time is given as microseconds. + * + ***************************************************************/ + + if (g_usDataType & LHEAP_IN) { + printf("%.2E SEC;\n", (float)usDelay / 1000000); + } else { + printf("RUNTEST %.2E SEC;\n", (float)usDelay / 1000000); + } + } +#endif //VME_DEBUG + break; + case TCK: + + /*************************************************************** + * + * Issue clock toggles. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + usToggle = (unsigned short)ispVMDataSize(); + ispVMClocks(usToggle); + +#ifdef VME_DEBUG + printf("RUNTEST %d TCK;\n", usToggle); +#endif //VME_DEBUG + break; + case ENDDR: + + /*************************************************************** + * + * Set the ENDDR. + * + ***************************************************************/ + + g_ucEndDR = GetByte(); + +#ifdef VME_DEBUG + printf("ENDDR %s;\n", GetState(g_ucEndDR)); +#endif //VME_DEBUG + break; + case ENDIR: + + /*************************************************************** + * + * Set the ENDIR. + * + ***************************************************************/ + + g_ucEndIR = GetByte(); + +#ifdef VME_DEBUG + printf("ENDIR %s;\n", GetState(g_ucEndIR)); +#endif //VME_DEBUG + break; + case HIR: + case TIR: + case HDR: + case TDR: + +#ifdef VME_DEBUG + switch (cOpcode) { + case HIR: + printf("HIR "); + break; + case TIR: + printf("TIR "); + break; + case HDR: + printf("HDR "); + break; + case TDR: + printf("TDR "); + break; + } +#endif //VME_DEBUG + + /*************************************************************** + * + * Set the header/trailer of the device in order to bypass + * successfully. + * + ***************************************************************/ + + cRetCode = ispVMAmble(cOpcode); + if (cRetCode != 0) { + return (cRetCode); + } + +#ifdef VME_DEBUG + printf(";\n"); +#endif //VME_DEBUG + break; + case MEM: + + /*************************************************************** + * + * The maximum RAM required to support processing one row of the + * VME file. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_usMaxSize = (unsigned short)ispVMDataSize(); + +#ifdef VME_DEBUG + printf("// MEMSIZE %d\n", g_usMaxSize); +#endif //VME_DEBUG + break; + case VENDOR: + + /*************************************************************** + * + * Set the VENDOR type. + * + ***************************************************************/ + + cOpcode = GetByte(); + switch (cOpcode) { + case LATTICE: +#ifdef VME_DEBUG + printf("// VENDOR LATTICE\n"); +#endif //VME_DEBUG + g_cVendor = LATTICE; + break; + case ALTERA: +#ifdef VME_DEBUG + printf("// VENDOR ALTERA\n"); +#endif //VME_DEBUG + g_cVendor = ALTERA; + break; + case XILINX: +#ifdef VME_DEBUG + printf("// VENDOR XILINX\n"); +#endif //VME_DEBUG + g_cVendor = XILINX; + break; + default: + break; + } + break; + case SETFLOW: + + /*************************************************************** + * + * Set the flow control. Flow control determines the personality + * of the embedded engine. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_usFlowControl |= (unsigned short)ispVMDataSize(); + break; + case RESETFLOW: + + /*************************************************************** + * + * Unset the flow control. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_usFlowControl &= (unsigned short)~(ispVMDataSize()); + break; + case HEAP: + + /*************************************************************** + * + * Allocate heap size to store loops. + * + ***************************************************************/ + + cRetCode = GetByte(); + if (cRetCode != SECUREHEAP) { + return VME_INVALID_FILE; + } + //09/11/07 NN Type cast mismatch variables + g_iHEAPSize = (unsigned short)ispVMDataSize(); + + /**************************************************************************** + * + * Store the maximum size of the HEAP buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_iHEAPSize > g_usHeapSize) { + g_usHeapSize = g_iHEAPSize; + } + + ispVMMemManager(HEAP, (unsigned short)g_iHEAPSize); + break; + case REPEAT: + + /*************************************************************** + * + * Execute loops. + * + ***************************************************************/ + + g_usRepeatLoops = 0; + + //09/11/07 NN Type cast mismatch variables + iRepeatSize = (unsigned short)ispVMDataSize(); + + cRetCode = ispVMLoop((unsigned short)iRepeatSize); + if (cRetCode != 0) { + return (cRetCode); + } + break; + case ENDLOOP: + + /*************************************************************** + * + * Exit point from processing loops. + * + ***************************************************************/ + + return (cRetCode); + case ENDVME: + + /*************************************************************** + * + * The only valid exit point that indicates end of programming. + * + ***************************************************************/ + + return (cRetCode); + case SHR: + + /*************************************************************** + * + * Right-shift address. + * + ***************************************************************/ + + g_usFlowControl |= SHIFTRIGHT; + + //09/11/07 NN Type cast mismatch variables + g_usShiftValue = (unsigned short)(g_usRepeatLoops * (unsigned short)GetByte()); + break; + case SHL: + + /*************************************************************** + * + * Left-shift address. + * + ***************************************************************/ + + g_usFlowControl |= SHIFTLEFT; + + //09/11/07 NN Type cast mismatch variables + g_usShiftValue = (unsigned short)(g_usRepeatLoops * (unsigned short)GetByte()); + break; + case FREQUENCY: + + /*************************************************************** + * + * Set the frequency. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_iFrequency = (int)(ispVMDataSize()); + //10/23/08 NN changed to check if the frequency smaller than 1000 + if (g_iFrequency >= 1000) { + g_iFrequency = g_iFrequency / 1000; + if (g_iFrequency == 1) + g_iFrequency = 1000; +#ifdef VME_DEBUG + printf("FREQUENCY %.2E HZ;\n", (float)g_iFrequency * 1000); +#endif //VME_DEBUG + } else { + if (g_iFrequency == 0) + g_iFrequency = 1000; +#ifdef VME_DEBUG + printf("FREQUENCY %.2E HZ;\n", (float)g_iFrequency); +#endif //VME_DEBUG + } + break; + case LCOUNT: + + /*************************************************************** + * + * Process LCOUNT command. + * + ***************************************************************/ + + cRetCode = ispVMLCOUNT((unsigned short)ispVMDataSize()); + if (cRetCode != 0) { + return (cRetCode); + } + break; + case VUES: + + /*************************************************************** + * + * Set the flow control to verify USERCODE. + * + ***************************************************************/ + + g_usFlowControl |= VERIFYUES; + break; + case COMMENT: + + /*************************************************************** + * + * Display comment. + * + ***************************************************************/ + + ispVMComment((unsigned short)ispVMDataSize()); + break; + case LVDS: + + /*************************************************************** + * + * Process LVDS command. + * + ***************************************************************/ + + ispVMProcessLVDS((unsigned short)ispVMDataSize()); + break; + case HEADER: + + /*************************************************************** + * + * Discard header. + * + ***************************************************************/ + + ispVMHeader((unsigned short)ispVMDataSize()); + break; + /* 03/14/06 Support Toggle ispENABLE signal*/ + case ispEN: + ucState = GetByte(); + if ((ucState == ON) || (ucState == 0x01)) + writePort(JTAG_ENABLE, 0x01); + else + writePort(JTAG_ENABLE, 0x00); + ispVMDelay(1); + break; + /* 05/24/06 support Toggle TRST pin*/ + case TRST: + ucState = GetByte(); + if (ucState == 0x01) + writePort(JTAG_TRST, 0x01); + else + writePort(JTAG_TRST, 0x00); + ispVMDelay(1); + break; + default: + + /*************************************************************** + * + * Invalid opcode encountered. + * + ***************************************************************/ + +#ifdef VME_DEBUG + printf("\nINVALID OPCODE: 0x%.2X\n", cOpcode); +#endif //VME_DEBUG + + return VME_INVALID_FILE; + } + } + + /*************************************************************** + * + * Invalid exit point. Processing the token 'ENDVME' is the only + * valid way to exit the embedded engine. + * + ***************************************************************/ + + return (VME_INVALID_FILE); +} + +/*************************************************************** +* +* ispVMDataCode +* +* Processes the TDI/TDO/MASK/DMASK etc of an SIR/SDR command. +* +***************************************************************/ + +signed char ispVMDataCode() +{ + //09/11/07 NN added local variables initialization + signed char cDataByte = 0; + signed char siDataSource = 0; /*source of data from file by default*/ + + if (g_usDataType & HEAP_IN) { + siDataSource = 1; /*the source of data from memory*/ + } + + /**************************************************************************** + * + * Clear the data type register. + * + *****************************************************************************/ + + g_usDataType &= ~(MASK_DATA + TDI_DATA + TDO_DATA + DMASK_DATA + CMASK_DATA); + + /**************************************************************************** + * + * Iterate through SIR/SDR command and look for TDI, TDO, MASK, etc. + * + *****************************************************************************/ + + while ((cDataByte = GetByte()) >= 0) { + + ispVMMemManager(cDataByte, g_usMaxSize); + switch (cDataByte) { + case TDI: + + /**************************************************************************** + * + * Store the maximum size of the TDI buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTDISize) { + g_usTDISize = g_usiDataSize; + } + /**************************************************************************** + * + * Updated data type register to indicate that TDI data is currently being + * used. Process the data in the VME file into the TDI buffer. + * + *****************************************************************************/ + + g_usDataType |= TDI_DATA; + ispVMData(g_pucInData); + break; + case XTDO: + + /**************************************************************************** + * + * Store the maximum size of the TDO buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTDOSize) { + g_usTDOSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that TDO data is currently being + * used. + * + *****************************************************************************/ + + g_usDataType |= TDO_DATA; + break; + case TDO: + + /**************************************************************************** + * + * Store the maximum size of the TDO buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTDOSize) { + g_usTDOSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that TDO data is currently being + * used. Process the data in the VME file into the TDO buffer. + * + *****************************************************************************/ + + g_usDataType |= TDO_DATA; + ispVMData(g_pucOutData); + break; + case MASK: + + /**************************************************************************** + * + * Store the maximum size of the MASK buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usMASKSize) { + g_usMASKSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that MASK data is currently being + * used. Process the data in the VME file into the MASK buffer. + * + *****************************************************************************/ + + g_usDataType |= MASK_DATA; + ispVMData(g_pucOutMaskData); + break; + case DMASK: + + /**************************************************************************** + * + * Store the maximum size of the DMASK buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usDMASKSize) { + g_usDMASKSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that DMASK data is currently being + * used. Process the data in the VME file into the DMASK buffer. + * + *****************************************************************************/ + + g_usDataType |= DMASK_DATA; + ispVMData(g_pucOutDMaskData); + break; + case CMASK: + + /**************************************************************************** + * + * Updated data type register to indicate that CMASK data is currently being + * used. Process the data in the VME file into the CMASK buffer. + * + *****************************************************************************/ + + g_usDataType |= CMASK_DATA; + ispVMData(g_pucOutMaskData); + break; + case CONTINUE: + return (0); + default: + + /**************************************************************************** + * + * Encountered invalid opcode. + * + *****************************************************************************/ + + return (VME_INVALID_FILE); + } + + switch (cDataByte) { + case TDI: + + /**************************************************************************** + * + * Left bit shift. Used when performing algorithm looping. + * + *****************************************************************************/ + + if (g_usFlowControl & SHIFTLEFT) { + ispVMBitShift(SHL, g_usShiftValue); + g_usFlowControl &= ~SHIFTLEFT; + } + + /**************************************************************************** + * + * Right bit shift. Used when performing algorithm looping. + * + *****************************************************************************/ + + if (g_usFlowControl & SHIFTRIGHT) { + ispVMBitShift(SHR, g_usShiftValue); + g_usFlowControl &= ~SHIFTRIGHT; + } + default: + break; + } + + if (siDataSource) { + g_usDataType |= HEAP_IN; /*restore data from memory*/ + } + } + + if (siDataSource) { /*fetch data from heap memory upon return*/ + g_usDataType |= HEAP_IN; + } + + if (cDataByte < 0) { + + /**************************************************************************** + * + * Encountered invalid opcode. + * + *****************************************************************************/ + + return (VME_INVALID_FILE); + } else { + return (0); + } +} + +/*************************************************************** +* +* ispVMData +* Extract one row of data operand from the current data type opcode. Perform +* the decompression if necessary. Extra RAM is not required for the +* decompression process. The decompression scheme employed in this module +* is on row by row basis. The format of the data stream: +* [compression code][compressed data stream] +* 0x00 --No compression +* 0x01 --Compress by 0x00. +* Example: +* Original stream: 0x000000000000000000000001 +* Compressed stream: 0x01000901 +* Detail: 0x01 is the code, 0x00 is the key, +* 0x09 is the count of 0x00 bytes, +* 0x01 is the uncompressed byte. +* 0x02 --Compress by 0xFF. +* Example: +* Original stream: 0xFFFFFFFFFFFFFFFFFFFFFF01 +* Compressed stream: 0x02FF0901 +* Detail: 0x02 is the code, 0xFF is the key, +* 0x09 is the count of 0xFF bytes, +* 0x01 is the uncompressed byte. +* 0x03 +* : : +* 0xFE -- Compress by nibble blocks. +* Example: +* Original stream: 0x84210842108421084210 +* Compressed stream: 0x0584210 +* Detail: 0x05 is the code, means 5 nibbles block. +* 0x84210 is the 5 nibble blocks. +* The whole row is 80 bits given by g_usiDataSize. +* The number of times the block repeat itself +* is found by g_usiDataSize/(4*0x05) which is 4. +* 0xFF -- Compress by the most frequently happen byte. +* Example: +* Original stream: 0x04020401030904040404 +* Compressed stream: 0xFF04(0,1,0x02,0,1,0x01,1,0x03,1,0x09,0,0,0) +* or: 0xFF044090181C240 +* Detail: 0xFF is the code, 0x04 is the key. +* a bit of 0 represent the key shall be put into +* the current bit position and a bit of 1 +* represent copying the next of 8 bits of data +* in. +* +***************************************************************/ + +void ispVMData(unsigned char *ByteData) +{ + //09/11/07 NN added local variables initialization + unsigned short size = 0; + unsigned short i, j, m, getData = 0; + unsigned char cDataByte = 0; + unsigned char compress = 0; + unsigned short FFcount = 0; + unsigned char compr_char = 0xFF; + unsigned short index = 0; + signed char compression = 0; + + /*convert number in bits to bytes*/ + if (g_usiDataSize % 8 > 0) { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize / 8 + 1); + } else { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize / 8); + } + + /* If there is compression, then check if compress by key of 0x00 or 0xFF + or by other keys or by nibble blocks*/ + + if (g_usDataType & COMPRESS) { + compression = 1; + if (((compress = GetByte()) == VAR) && (g_usDataType & HEAP_IN)) { + getData = 1; + g_usDataType &= ~(HEAP_IN); + compress = GetByte(); + } + + switch (compress) { + case 0x00: + /* No compression */ + compression = 0; + break; + case 0x01: + /* Compress by byte 0x00 */ + compr_char = 0x00; + break; + case 0x02: + /* Compress by byte 0xFF */ + compr_char = 0xFF; + break; + case 0xFF: + /* Huffman encoding */ + compr_char = GetByte(); + i = 8; + for (index = 0; index < size; index++) { + ByteData[index] = 0x00; + if (i > 7) { + cDataByte = GetByte(); + i = 0; + } + if ((cDataByte << i++) & 0x80) + m = 8; + else { + ByteData[index] = compr_char; + m = 0; + } + + for (j = 0; j < m; j++) { + if (i > 7) { + cDataByte = GetByte(); + i = 0; + } + ByteData[index] |= ((cDataByte << i++) & 0x80) >> j; + } + } + size = 0; + break; + default: + for (index = 0; index < size; index++) + ByteData[index] = 0x00; + for (index = 0; index < compress; index++) { + if (index % 2 == 0) + cDataByte = GetByte(); + for (i = 0; i < size * 2 / compress; i++) { + //09/11/07 NN Type cast mismatch variables + j = (unsigned short)(index + (i * (unsigned short)compress)); + /*clear the nibble to zero first*/ + if (j % 2) { + if (index % 2) + ByteData[j / 2] |= cDataByte & 0x0F; + else + ByteData[j / 2] |= cDataByte >> 4; + } else { + if (index % 2) + ByteData[j / 2] |= cDataByte << 4; + else + ByteData[j / 2] |= cDataByte & 0xF0; + } + } + } + size = 0; + break; + } + } + + FFcount = 0; + + /* Decompress by byte 0x00 or 0xFF */ + for (index = 0; index < size; index++) { + if (FFcount <= 0) { + cDataByte = GetByte(); + if ((cDataByte == VAR) && (g_usDataType & HEAP_IN) && !getData && !(g_usDataType & COMPRESS)) { + getData = 1; + g_usDataType &= ~(HEAP_IN); + cDataByte = GetByte(); + } + ByteData[index] = cDataByte; + if ((compression) && (cDataByte == compr_char)) /*decompression is on*/ + //09/11/07 NN Type cast mismatch variables + FFcount = (unsigned short)ispVMDataSize(); /*The number of 0xFF or 0x00 bytes*/ + } else { + FFcount--; /*Use up the 0xFF chain first*/ + ByteData[index] = compr_char; + } + } + + if (getData) { + g_usDataType |= HEAP_IN; + getData = 0; + } +} + +/*************************************************************** +* +* ispVMShift +* +* Processes the SDR/XSDR/SIR commands. +* +***************************************************************/ + +signed char ispVMShift(signed char a_cCode) +{ + //09/11/07 NN added local variables initialization + unsigned short iDataIndex = 0; + unsigned short iReadLoop = 0; + signed char cRetCode = 0; + + cRetCode = 0; + //09/11/07 NN Type cast mismatch variables + g_usiDataSize = (unsigned short)ispVMDataSize(); + + g_usDataType &= ~(SIR_DATA + EXPRESS + SDR_DATA); /*clear the flags first*/ + + switch (a_cCode) { + case SIR: + g_usDataType |= SIR_DATA; + /* 1/15/04 If performing cascading, then go directly to SHIFTIR. Else, + go to IRPAUSE before going to SHIFTIR */ + if (g_usFlowControl & CASCADE) { + ispVMStateMachine(SHIFTIR); + } else { + ispVMStateMachine(IRPAUSE); + ispVMStateMachine(SHIFTIR); + if (g_usHeadIR > 0) { + ispVMBypass(HIR, g_usHeadIR); + sclock(); + } + } + break; + case XSDR: + g_usDataType |= EXPRESS; /*mark simultaneous in and out*/ + case SDR: + g_usDataType |= SDR_DATA; + /* 1/15/04 If already in SHIFTDR, then do not move state or shift in header. + This would imply that the previously shifted frame was a cascaded frame. */ + if (g_cCurrentJTAGState != SHIFTDR) { + /* 1/15/04 If performing cascading, then go directly to SHIFTDR. Else, + go to DRPAUSE before going to SHIFTDR */ + if (g_usFlowControl & CASCADE) { + if (g_cCurrentJTAGState == DRPAUSE) { + ispVMStateMachine(SHIFTDR); + /* 1/15/04 If cascade flag has been set and the current state is + DRPAUSE, this implies that the first cascaded frame is about to + be shifted in. The header must be shifted prior to shifting + the first cascaded frame. */ + if (g_usHeadDR > 0) { + ispVMBypass(HDR, g_usHeadDR); + sclock(); + } + } else { + ispVMStateMachine(SHIFTDR); + } + } else { + ispVMStateMachine(DRPAUSE); + ispVMStateMachine(SHIFTDR); + if (g_usHeadDR > 0) { + ispVMBypass(HDR, g_usHeadDR); + sclock(); + } + } + } + break; + default: + return (VME_INVALID_FILE); + } + + cRetCode = ispVMDataCode(); + if (cRetCode != 0) { + return (VME_INVALID_FILE); + } + +#ifdef VME_DEBUG + if (g_usDataType & TDI_DATA) { + printf("\n\t\tTDI "); + PrintData(g_usiDataSize, g_pucInData); + } + + if (g_usDataType & TDO_DATA) { + printf("\n\t\tTDO "); + PrintData(g_usiDataSize, g_pucOutData); + } + + if (g_usDataType & MASK_DATA) { + printf("\n\t\tMASK "); + PrintData(g_usiDataSize, g_pucOutMaskData); + } + + if (g_usDataType & DMASK_DATA) { + printf("\n\t\tDMASK "); + PrintData(g_usiDataSize, g_pucOutDMaskData); + } + + printf(";\n"); +#endif //VME_DEBUG + if (g_usDataType & TDO_DATA || g_usDataType & DMASK_DATA) { + if (g_usDataType & DMASK_DATA) { + + cRetCode = ispVMReadandSave(g_usiDataSize); + + if (!cRetCode) { + if (g_usTailDR > 0) { + sclock(); + ispVMBypass(TDR, g_usTailDR); + } + ispVMStateMachine(DRPAUSE); + ispVMStateMachine(SHIFTDR); + if (g_usHeadDR > 0) { + ispVMBypass(HDR, g_usHeadDR); + sclock(); + } + for (iDataIndex = 0; iDataIndex < g_usiDataSize / 8 + 1; iDataIndex++) + g_pucInData[iDataIndex] = g_pucOutData[iDataIndex]; + g_usDataType &= ~(TDO_DATA + DMASK_DATA); + cRetCode = ispVMSend(g_usiDataSize); + } + } else { + + cRetCode = ispVMRead(g_usiDataSize); + if (cRetCode == -1 && g_cVendor == XILINX) { + for (iReadLoop = 0; iReadLoop < 30; iReadLoop++) { + cRetCode = ispVMRead(g_usiDataSize); + if (!cRetCode) { + break; + } else { + ispVMStateMachine(DRPAUSE); /*Always DRPAUSE*/ + /*Bypass other devices when appropriate*/ + ispVMBypass(TDR, g_usTailDR); + ispVMStateMachine(g_ucEndDR); + ispVMStateMachine(IDLE); + ispVMDelay(1000); + } + } + } + } + } else { /*TDI only*/ + cRetCode = ispVMSend(g_usiDataSize); + + } + + /*transfer the input data to the output buffer for the next verify*/ + if ((g_usDataType & EXPRESS) || (a_cCode == SDR)) { + if (g_pucOutData) { + for (iDataIndex = 0; iDataIndex < g_usiDataSize / 8 + 1; iDataIndex++) + g_pucOutData[iDataIndex] = g_pucInData[iDataIndex]; + } + } + + switch (a_cCode) { + case SIR: + /* 1/15/04 If not performing cascading, then shift ENDIR */ + if (!(g_usFlowControl & CASCADE)) { + if (g_usTailIR > 0) { + sclock(); + ispVMBypass(TIR, g_usTailIR); + } + ispVMStateMachine(g_ucEndIR); + } + break; + case XSDR: + case SDR: + /* 1/15/04 If not performing cascading, then shift ENDDR */ + if (!(g_usFlowControl & CASCADE)) { + if (g_usTailDR > 0) { + sclock(); + ispVMBypass(TDR, g_usTailDR); + } + ispVMStateMachine(g_ucEndDR); + } + break; + default: + break; + } + + return (cRetCode); +} + +/*************************************************************** +* +* ispVMAmble +* +* This routine is to extract Header and Trailer parameter for SIR and +* SDR operations. +* +* The Header and Trailer parameter are the pre-amble and post-amble bit +* stream need to be shifted into TDI or out of TDO of the devices. Mostly +* is for the purpose of bypassing the leading or trailing devices. ispVM +* supports only shifting data into TDI to bypass the devices. +* +* For a single device, the header and trailer parameters are all set to 0 +* as default by ispVM. If it is for multiple devices, the header and trailer +* value will change as specified by the VME file. +* +***************************************************************/ + +signed char ispVMAmble(signed char Code) +{ + signed char compress = 0; + //09/11/07 NN Type cast mismatch variables + g_usiDataSize = (unsigned short)ispVMDataSize(); + +#ifdef VME_DEBUG + printf("%d", g_usiDataSize); +#endif //VME_DEBUG + + if (g_usiDataSize) { + + /**************************************************************************** + * + * Discard the TDI byte and set the compression bit in the data type register + * to false if compression is set because TDI data after HIR/HDR/TIR/TDR is not + * compressed. + * + *****************************************************************************/ + + GetByte(); + if (g_usDataType & COMPRESS) { + g_usDataType &= ~(COMPRESS); + compress = 1; + } + } + + switch (Code) { + case HIR: + + /**************************************************************************** + * + * Store the maximum size of the HIR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usHIRSize) { + g_usHIRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the HIR value and allocate memory. + * + *****************************************************************************/ + + g_usHeadIR = g_usiDataSize; + if (g_usHeadIR) { + ispVMMemManager(HIR, g_usHeadIR); + ispVMData(g_pucHIRData); + +#ifdef VME_DEBUG + printf(" TDI "); + PrintData(g_usHeadIR, g_pucHIRData); +#endif //VME_DEBUG + } + break; + case TIR: + + /**************************************************************************** + * + * Store the maximum size of the TIR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTIRSize) { + g_usTIRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the TIR value and allocate memory. + * + *****************************************************************************/ + + g_usTailIR = g_usiDataSize; + if (g_usTailIR) { + ispVMMemManager(TIR, g_usTailIR); + ispVMData(g_pucTIRData); + +#ifdef VME_DEBUG + printf(" TDI "); + PrintData(g_usTailIR, g_pucTIRData); +#endif //VME_DEBUG + } + break; + case HDR: + + /**************************************************************************** + * + * Store the maximum size of the HDR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usHDRSize) { + g_usHDRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the HDR value and allocate memory. + * + *****************************************************************************/ + + g_usHeadDR = g_usiDataSize; + if (g_usHeadDR) { + ispVMMemManager(HDR, g_usHeadDR); + ispVMData(g_pucHDRData); + +#ifdef VME_DEBUG + printf(" TDI "); + PrintData(g_usHeadDR, g_pucHDRData); +#endif //VME_DEBUG + } + break; + case TDR: + + /**************************************************************************** + * + * Store the maximum size of the TDR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTDRSize) { + g_usTDRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the TDR value and allocate memory. + * + *****************************************************************************/ + + g_usTailDR = g_usiDataSize; + if (g_usTailDR) { + ispVMMemManager(TDR, g_usTailDR); + ispVMData(g_pucTDRData); + +#ifdef VME_DEBUG + printf(" TDI "); + PrintData(g_usTailDR, g_pucTDRData); +#endif //VME_DEBUG + } + break; + default: + break; + } + + /**************************************************************************** + * + * Re-enable compression if it was previously set. + * + *****************************************************************************/ + + if (compress) { + g_usDataType |= COMPRESS; + } + + if (g_usiDataSize) { + Code = GetByte(); + if (Code == CONTINUE) { + return 0; + } else { + + /**************************************************************************** + * + * Encountered invalid opcode. + * + *****************************************************************************/ + + return VME_INVALID_FILE; + } + } + + return 0; +} + +/*************************************************************** +* +* ispVMLoop +* +* Perform the function call upon by the REPEAT opcode. +* Memory is to be allocated to store the entire loop from REPEAT to ENDLOOP. +* After the loop is stored then execution begin. The REPEATLOOP flag is set +* on the g_usFlowControl register to indicate the repeat loop is in session +* and therefore fetch opcode from the memory instead of from the file. +* +***************************************************************/ + +signed char ispVMLoop(unsigned short a_usLoopCount) +{ + //09/11/07 NN added local variables initialization + signed char cRetCode = 0; + unsigned short iHeapIndex = 0; + unsigned short iLoopIndex = 0; + + g_usShiftValue = 0; + for (iHeapIndex = 0; iHeapIndex < g_iHEAPSize; iHeapIndex++) { + g_pucHeapMemory[iHeapIndex] = GetByte(); + } + + if (g_pucHeapMemory[iHeapIndex - 1] != ENDLOOP) { + return (VME_INVALID_FILE); + } + + g_usFlowControl |= REPEATLOOP; + g_usDataType |= HEAP_IN; + + for (iLoopIndex = 0; iLoopIndex < a_usLoopCount; iLoopIndex++) { + g_iHeapCounter = 0; + cRetCode = ispVMCode(); + g_usRepeatLoops++; + if (cRetCode < 0) { + break; + } + } + + g_usDataType &= ~(HEAP_IN); + g_usFlowControl &= ~(REPEATLOOP); + return (cRetCode); +} + +/*************************************************************** +* +* ispVMBitShift +* +* Shift the TDI stream left or right by the number of bits. The data in +* *g_pucInData is of the VME format, so the actual shifting is the reverse of +* IEEE 1532 or SVF format. +* +***************************************************************/ + +signed char ispVMBitShift(signed char mode, unsigned short bits) +{ + //09/11/07 NN added local variables initialization + unsigned short i = 0; + unsigned short size = 0; + unsigned short tmpbits = 0; + + if (g_usiDataSize % 8 > 0) { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize / 8 + 1); + } else { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize / 8); + } + + switch (mode) { + case SHR: + for (i = 0; i < size; i++) { + if (g_pucInData[i] != 0) { + tmpbits = bits; + while (tmpbits > 0) { + g_pucInData[i] <<= 1; + if (g_pucInData[i] == 0) { + i--; + g_pucInData[i] = 1; + } + tmpbits--; + } + } + } + break; + case SHL: + for (i = 0; i < size; i++) { + if (g_pucInData[i] != 0) { + tmpbits = bits; + while (tmpbits > 0) { + g_pucInData[i] >>= 1; + if (g_pucInData[i] == 0) { + i--; + g_pucInData[i] = 8; + } + tmpbits--; + } + } + } + break; + default: + return (VME_INVALID_FILE); + } + + return (0); +} + +/*************************************************************** +* +* ispVMComment +* +* Displays the SVF comments. +* +***************************************************************/ + +void ispVMComment(unsigned short a_usCommentSize) +{ + char cCurByte = 0; + for (; a_usCommentSize > 0; a_usCommentSize--) { + /**************************************************************************** + * + * Print character to the terminal. + * + *****************************************************************************/ + cCurByte = GetByte(); + vme_out_char(cCurByte); + } + cCurByte = '\n'; + vme_out_char(cCurByte); +} + +/*************************************************************** +* +* ispVMHeader +* +* Iterate the length of the header and discard it. +* +***************************************************************/ + +void ispVMHeader(unsigned short a_usHeaderSize) +{ + for (; a_usHeaderSize > 0; a_usHeaderSize--) { + GetByte(); + } +} + +/*************************************************************** +* +* ispVMCalculateCRC32 +* +* Calculate the 32-bit CRC. +* +***************************************************************/ + +void ispVMCalculateCRC32(unsigned char a_ucData) +{ + //09/11/07 NN added local variables initialization + unsigned char ucIndex = 0; + unsigned char ucFlipData = 0; + unsigned short usCRCTableEntry = 0; + unsigned int crc_table[16] = { + 0x0000, 0xCC01, 0xD801, + 0x1400, 0xF001, 0x3C00, + 0x2800, 0xE401, 0xA001, + 0x6C00, 0x7800, 0xB401, + 0x5000, 0x9C01, 0x8801, + 0x4400 + }; + + for (ucIndex = 0; ucIndex < 8; ucIndex++) { + ucFlipData <<= 1; + if (a_ucData & 0x01) { + ucFlipData |= 0x01; + } + a_ucData >>= 1; + } + + //09/11/07 NN Type cast mismatch variables + usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]); + g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF); + g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ usCRCTableEntry ^ crc_table[ucFlipData & 0xF]); + usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]); + g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF); + g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ usCRCTableEntry ^ crc_table[(ucFlipData >> 4) & 0xF]); +} + +/*************************************************************** +* +* ispVMLCOUNT +* +* Process the intelligent programming loops. +* +***************************************************************/ + +signed char ispVMLCOUNT(unsigned short a_usCountSize) +{ + unsigned short usContinue = 1; + unsigned short usIntelBufferIndex = 0; + unsigned short usCountIndex = 0; + signed char cRetCode = 0; + signed char cRepeatHeap = 0; + signed char cOpcode = 0; + unsigned char ucState = 0; + unsigned short usDelay = 0; + unsigned short usToggle = 0; + + g_usIntelBufferSize = (unsigned short)ispVMDataSize(); + + /**************************************************************************** + * + * Allocate memory for intel buffer. + * + *****************************************************************************/ + + ispVMMemManager(LHEAP, g_usIntelBufferSize); + + /**************************************************************************** + * + * Store the maximum size of the intelligent buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usIntelBufferSize > g_usLCOUNTSize) { + g_usLCOUNTSize = g_usIntelBufferSize; + } + + /**************************************************************************** + * + * Copy intel data to the buffer. + * + *****************************************************************************/ + + for (usIntelBufferIndex = 0; usIntelBufferIndex < g_usIntelBufferSize; usIntelBufferIndex++) { + g_pucIntelBuffer[usIntelBufferIndex] = GetByte(); + } + + /**************************************************************************** + * + * Set the data type register to get data from the intelligent data buffer. + * + *****************************************************************************/ + + g_usDataType |= LHEAP_IN; + + /**************************************************************************** + * + * If the HEAP_IN flag is set, temporarily unset the flag so data will be + * retrieved from the status buffer. + * + *****************************************************************************/ + + if (g_usDataType & HEAP_IN) { + g_usDataType &= ~HEAP_IN; + cRepeatHeap = 1; + } + +#ifdef VME_DEBUG + printf("LCOUNT %d;\n", a_usCountSize); +#endif //VME_DEBUG + + /**************************************************************************** + * + * Iterate through the intelligent programming command. + * + *****************************************************************************/ + + for (usCountIndex = 0; usCountIndex < a_usCountSize; usCountIndex++) { + + /**************************************************************************** + * + * Initialize the intel data index to 0 before each iteration. + * + *****************************************************************************/ + + g_usIntelDataIndex = 0; + cOpcode = 0; + ucState = 0; + usDelay = 0; + usToggle = 0; + usContinue = 1; + + /*************************************************************** + * + * Begin looping through all the VME opcodes. + * + ***************************************************************/ + /*************************************************************** + * 4/1/09 Nguyen replaced the recursive function call codes on + * the ispVMLCOUNT function + * + ***************************************************************/ + while (usContinue) { + cOpcode = GetByte(); + switch (cOpcode) { + case HIR: + case TIR: + case HDR: + case TDR: + /*************************************************************** + * + * Set the header/trailer of the device in order to bypass + * successfully. + * + ***************************************************************/ + + ispVMAmble(cOpcode); + break; + case STATE: + + /*************************************************************** + * + * Step the JTAG state machine. + * + ***************************************************************/ + + ucState = GetByte(); + /*************************************************************** + * + * Step the JTAG state machine to DRCAPTURE to support Looping. + * + ***************************************************************/ + + if ((g_usDataType & LHEAP_IN) && + (ucState == DRPAUSE) && + (g_cCurrentJTAGState == ucState)) { + ispVMStateMachine(DRCAPTURE); + } + ispVMStateMachine(ucState); +#ifdef VME_DEBUG + printf("LDELAY %s ", GetState(ucState)); +#endif //VME_DEBUG + break; + case SIR: +#ifdef VME_DEBUG + printf("SIR "); +#endif //VME_DEBUG + /*************************************************************** + * + * Shift in data into the device. + * + ***************************************************************/ + + cRetCode = ispVMShift(cOpcode); + break; + case SDR: + +#ifdef VME_DEBUG + printf("LSDR "); +#endif //VME_DEBUG + /*************************************************************** + * + * Shift in data into the device. + * + ***************************************************************/ + + cRetCode = ispVMShift(cOpcode); + break; + case WAIT: + + /*************************************************************** + * + * Observe delay. + * + ***************************************************************/ + + usDelay = (unsigned short)ispVMDataSize(); + ispVMDelay(usDelay); + +#ifdef VME_DEBUG + if (usDelay & 0x8000) { + + /*************************************************************** + * + * Since MSB is set, the delay time must be decoded to + * millisecond. The SVF2VME encodes the MSB to represent + * millisecond. + * + ***************************************************************/ + + usDelay &= ~0x8000; + printf("%.2E SEC;\n", (float)usDelay / 1000); + } else { + + /*************************************************************** + * + * Since MSB is not set, the delay time is given as microseconds. + * + ***************************************************************/ + + printf("%.2E SEC;\n", (float)usDelay / 1000000); + } +#endif //VME_DEBUG + break; + case TCK: + + /*************************************************************** + * + * Issue clock toggles. + * + ***************************************************************/ + + usToggle = (unsigned short)ispVMDataSize(); + ispVMClocks(usToggle); + +#ifdef VME_DEBUG + printf("RUNTEST %d TCK;\n", usToggle); +#endif //VME_DEBUG + break; + case ENDLOOP: + + /*************************************************************** + * + * Exit point from processing loops. + * + ***************************************************************/ + usContinue = 0; + break; + + case COMMENT: + + /*************************************************************** + * + * Display comment. + * + ***************************************************************/ + + ispVMComment((unsigned short)ispVMDataSize()); + break; + case ispEN: + ucState = GetByte(); + if ((ucState == ON) || (ucState == 0x01)) + writePort(JTAG_ENABLE, 0x01); + else + writePort(JTAG_ENABLE, 0x00); + ispVMDelay(1); + break; + case TRST: + if (GetByte() == 0x01) + writePort(JTAG_TRST, 0x01); + else + writePort(JTAG_TRST, 0x00); + ispVMDelay(1); + break; + default: + + /*************************************************************** + * + * Invalid opcode encountered. + * + ***************************************************************/ + +#ifdef VME_DEBUG + printf("\nINVALID OPCODE: 0x%.2X\n", cOpcode); +#endif //VME_DEBUG + + return VME_INVALID_FILE; + } + } + if (cRetCode >= 0) { + /**************************************************************************** + * + * Break if intelligent programming is successful. + * + *****************************************************************************/ + + break; + } + + } + /**************************************************************************** + * + * If HEAP_IN flag was temporarily disabled, re-enable it before exiting. + * + *****************************************************************************/ + + if (cRepeatHeap) { + g_usDataType |= HEAP_IN; + } + + /**************************************************************************** + * + * Set the data type register to not get data from the intelligent data buffer. + * + *****************************************************************************/ + + g_usDataType &= ~LHEAP_IN; + return cRetCode; +} + +/*************************************************************** +* +* ispVMClocks +* +* Applies the specified number of pulses to TCK. +* +***************************************************************/ + +void ispVMClocks(unsigned short Clocks) +{ + unsigned short iClockIndex = 0; + for (iClockIndex = 0; iClockIndex < Clocks; iClockIndex++) { + sclock(); + } +} + +/*************************************************************** +* +* ispVMBypass +* +* This procedure takes care of the HIR, HDR, TIR, TDR for the +* purpose of putting the other devices into Bypass mode. The +* current state is checked to find out if it is at DRPAUSE or +* IRPAUSE. If it is at DRPAUSE, perform bypass register scan. +* If it is at IRPAUSE, scan into instruction registers the bypass +* instruction. +* +***************************************************************/ + +void ispVMBypass(signed char ScanType, unsigned short Bits) +{ + //09/11/07 NN added local variables initialization + unsigned short iIndex = 0; + unsigned short iSourceIndex = 0; + unsigned char cBitState = 0; + unsigned char cCurByte = 0; + unsigned char *pcSource = NULL; + + if (Bits <= 0) { + return; + } + + switch (ScanType) { + case HIR: + pcSource = g_pucHIRData; + break; + case TIR: + pcSource = g_pucTIRData; + break; + case HDR: + pcSource = g_pucHDRData; + break; + case TDR: + pcSource = g_pucTDRData; + break; + default: + break; + } + if (pcSource) { + iSourceIndex = 0; + cBitState = 0; + for (iIndex = 0; iIndex < Bits - 1; iIndex++) { + /* Scan instruction or bypass register */ + if (iIndex % 8 == 0) { + cCurByte = pcSource[iSourceIndex++]; + } + cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00); + writePort(JTAG_TDI, cBitState); + sclock(); + } + + if (iIndex % 8 == 0) { + cCurByte = pcSource[iSourceIndex++]; + } + + cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00); + writePort(JTAG_TDI, cBitState); + } +} + +/*************************************************************** +* +* ispVMStateMachine +* +* This procedure steps all devices in the daisy chain from a given +* JTAG state to the next desirable state. If the next state is TLR, +* the JTAG state machine is brute forced into TLR by driving TMS +* high and pulse TCK 6 times. +* +***************************************************************/ + +void ispVMStateMachine(signed char cNextJTAGState) +{ + //09/11/07 NN added local variables initialization + signed char cPathIndex = 0; + signed char cStateIndex = 0; + short int found = 0; + + if ((g_cCurrentJTAGState == cNextJTAGState) && (cNextJTAGState != RESET)) { + return; + } + + for (cStateIndex = 0; cStateIndex < 25; cStateIndex++) { + if ((g_cCurrentJTAGState == g_JTAGTransistions[cStateIndex].CurState) && (cNextJTAGState == g_JTAGTransistions[cStateIndex].NextState)) { + found = 1; + break; + } + } + if (found) { + g_cCurrentJTAGState = cNextJTAGState; + for (cPathIndex = 0; cPathIndex < g_JTAGTransistions[cStateIndex].Pulses; cPathIndex++) { + if ((g_JTAGTransistions[cStateIndex].Pattern << cPathIndex) & 0x80) { + writePort(JTAG_TMS, (unsigned char)0x01); + } else { + writePort(JTAG_TMS, (unsigned char)0x00); + } + sclock(); + } + + writePort(JTAG_TDI, 0x00); + writePort(JTAG_TMS, 0x00); + } +} + +/*************************************************************** +* +* ispVMStart +* +* Enable the port to the device and set the state to RESET (TLR). +* +***************************************************************/ + +void ispVMStart() +{ +#ifdef VME_DEBUG + printf("// ISPVM EMBEDDED ADDED\n"); + printf("STATE RESET;\n"); +#endif + + ispVMStateMachine(RESET); /*step devices to RESET state*/ + +} + +/*************************************************************** +* +* ispVMEnd +* +* Set the state of devices to RESET to enable the devices and disable +* the port. +* +***************************************************************/ + +void ispVMEnd() +{ +#ifdef VME_DEBUG + printf("// ISPVM EMBEDDED ADDED\n"); + printf("STATE RESET;\n"); + printf("RUNTEST 1.00E-001 SEC;\n"); +#endif + + ispVMStateMachine(RESET); /*step devices to RESET state */ + ispVMDelay(1000); /*wake up devices*/ +} + +/*************************************************************** +* +* ispVMSend +* +* Send the TDI data stream to devices. The data stream can be +* instructions or data. +* +***************************************************************/ + +signed char ispVMSend(unsigned short a_usiDataSize) +{ + //09/11/07 NN added local variables initialization + unsigned short iIndex = 0; + unsigned short iInDataIndex = 0; + unsigned char cCurByte = 0; + unsigned char cBitState = 0; + + for (iIndex = 0; iIndex < a_usiDataSize - 1; iIndex++) { + if (iIndex % 8 == 0) { + cCurByte = g_pucInData[iInDataIndex++]; + } + cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00); + writePort(JTAG_TDI, cBitState); + sclock(); + } + + if (iIndex % 8 == 0) { + /* Take care of the last bit */ + cCurByte = g_pucInData[iInDataIndex]; + } + + cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00); + + writePort(JTAG_TDI, cBitState); + if (g_usFlowControl & CASCADE) { + /* 1/15/04 Clock in last bit for the first n-1 cascaded frames */ + sclock(); + } + + return 0; +} + +/*************************************************************** +* +* ispVMRead +* +* Read the data stream from devices and verify. +* +***************************************************************/ + +signed char ispVMRead(unsigned short a_usiDataSize) //32 +{ + //09/11/07 NN added local variables initialization + unsigned short usDataSizeIndex = 0; + unsigned short usErrorCount = 0; + unsigned short usLastBitIndex = 0; + unsigned char cDataByte = 0; + unsigned char cMaskByte = 0; + unsigned char cInDataByte = 0; + unsigned char cCurBit = 0; + unsigned char cByteIndex = 0; + unsigned short usBufferIndex = 0; + unsigned char ucDisplayByte = 0x00; + unsigned char ucDisplayFlag = 0x01; + char StrChecksum[256] = { 0 }; + unsigned char g_usCalculateChecksum = 0x00; + + //09/11/07 NN Type cast mismatch variables + usLastBitIndex = (unsigned short)(a_usiDataSize - 1); + + /**************************************************************************** + * + * If mask is not all zeros, then set the display flag to 0x00, otherwise + * it shall be set to 0x01 to indicate that data read from the device shall + * be displayed. If VME_DEBUG is defined, always display data. + * + *****************************************************************************/ + + for (usDataSizeIndex = 0; usDataSizeIndex < (a_usiDataSize + 7) / 8; usDataSizeIndex++) { + + if (g_usDataType & MASK_DATA) { + if (g_pucOutMaskData[usDataSizeIndex] != 0x00) { + ucDisplayFlag = 0x00; + break; + } + } else if (g_usDataType & CMASK_DATA) { + g_usCalculateChecksum = 0x01; + ucDisplayFlag = 0x00; + break; + } else { + ucDisplayFlag = 0x00; + break; + } + } + + /**************************************************************************** + * + * Begin shifting data in and out of the device. + * + *****************************************************************************/ + for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; usDataSizeIndex++) { + if (cByteIndex == 0) { + + /*************************************************************** + * + * Grab byte from TDO buffer. + * + ***************************************************************/ + + if (g_usDataType & TDO_DATA) { + cDataByte = g_pucOutData[usBufferIndex]; + } + + /*************************************************************** + * + * Grab byte from MASK buffer. + * + ***************************************************************/ + + if (g_usDataType & MASK_DATA) { + cMaskByte = g_pucOutMaskData[usBufferIndex]; + } else { + cMaskByte = 0xFF; + } + + /*************************************************************** + * + * Grab byte from CMASK buffer. + * + ***************************************************************/ + + if (g_usDataType & CMASK_DATA) { + cMaskByte = 0x00; + g_usCalculateChecksum = 0x01; + } + + /*************************************************************** + * + * Grab byte from TDI buffer. + * + ***************************************************************/ + + if (g_usDataType & TDI_DATA) { + cInDataByte = g_pucInData[usBufferIndex]; + } + + usBufferIndex++; + } + + cCurBit = readPort(); + + if (ucDisplayFlag) { + ucDisplayByte <<= 1; + ucDisplayByte |= cCurBit; + } + + /**************************************************************************** + * + * Check if data read from port matches with expected TDO. + * + *****************************************************************************/ + + if (g_usDataType & TDO_DATA) { + //08/28/08 NN Added Calculate checksum support. + if (g_usCalculateChecksum) { + if (cCurBit == 0x01) + g_usChecksum += (1 << (g_uiChecksumIndex % 8)); + g_uiChecksumIndex++; + } else { + if ((((cMaskByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) { + if (cCurBit != (unsigned char)(((cDataByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) { + usErrorCount++; + } + } + } + } + + /**************************************************************************** + * + * Write TDI data to the port. + * + *****************************************************************************/ + + writePort(JTAG_TDI, (unsigned char)(((cInDataByte << cByteIndex) & 0x80) ? 0x01 : 0x00)); + + if (usDataSizeIndex < usLastBitIndex) { + + /**************************************************************************** + * + * Clock data out from the data shift register. + * + *****************************************************************************/ + + sclock(); + } else if (g_usFlowControl & CASCADE) { + + /**************************************************************************** + * + * Clock in last bit for the first N - 1 cascaded frames. + * + *****************************************************************************/ + + sclock(); + } + + /*************************************************************** + * + * Increment the byte index. If it exceeds 7, then reset it back + * to zero. + * + ***************************************************************/ + + cByteIndex++; + if (cByteIndex >= 8) { + if (ucDisplayFlag) { + + /*************************************************************** + * + * Store displayed data in the TDO buffer. By reusing the TDO + * buffer to store displayed data, there is no need to allocate + * a buffer simply to hold display data. This will not cause any + * false verification errors because the true TDO byte has already + * been consumed. + * + ***************************************************************/ + + g_pucOutData[usBufferIndex - 1] = ucDisplayByte; + ucDisplayByte = 0; + } + + cByteIndex = 0; + } + //09/12/07 Nguyen changed to display the 1 bit expected data + else if (a_usiDataSize == 1) { + if (ucDisplayFlag) { + + /*************************************************************** + * + * Store displayed data in the TDO buffer. By reusing the TDO + * buffer to store displayed data, there is no need to allocate + * a buffer simply to hold display data. This will not cause any + * false verification errors because the true TDO byte has already + * been consumed. + * + ***************************************************************/ + + /**************************************************************************** + * + * Flip ucDisplayByte and store it in cDataByte. + * + *****************************************************************************/ + cDataByte = 0x00; + for (usBufferIndex = 0; usBufferIndex < 8; usBufferIndex++) { + cDataByte <<= 1; + if (ucDisplayByte & 0x01) { + cDataByte |= 0x01; + } + ucDisplayByte >>= 1; + } + g_pucOutData[0] = cDataByte; + ucDisplayByte = 0; + } + + cByteIndex = 0; + } + } + if (ucDisplayFlag) { + + /**************************************************************************** + * + * Display data read from the device. + * + *****************************************************************************/ + +#ifdef VME_DEBUG + printf("RECIEVED TDO ("); +#else + vme_out_string("Display Data: 0x"); +#endif //VME_DEBUG + + //09/11/07 NN Type cast mismatch variables + for (usDataSizeIndex = (unsigned short)((a_usiDataSize + 7) / 8); usDataSizeIndex > 0; usDataSizeIndex--) { + cMaskByte = g_pucOutData[usDataSizeIndex - 1]; + cDataByte = 0x00; + + /**************************************************************************** + * + * Flip cMaskByte and store it in cDataByte. + * + *****************************************************************************/ + + for (usBufferIndex = 0; usBufferIndex < 8; usBufferIndex++) { + cDataByte <<= 1; + if (cMaskByte & 0x01) { + cDataByte |= 0x01; + } + cMaskByte >>= 1; + } +#ifdef VME_DEBUG + printf("%.2X", cDataByte); + if ((((a_usiDataSize + 7) / 8) - usDataSizeIndex) % 40 == 39) { + printf("\n\t\t"); + } +#else + vme_out_hex(cDataByte); +#endif //VME_DEBUG + } + +#ifdef VME_DEBUG + printf(")\n\n"); +#else + vme_out_string("\n\n"); +#endif //VME_DEBUG + //09/02/08 Nguyen changed to display the data Checksum + vme_out_string("g_usChecksum:"); + sprintf(StrChecksum, "%.4X\n\n", (unsigned int)g_usChecksum); + vme_out_string(StrChecksum); + vme_out_string("\n\n"); + if (g_usChecksum != 0) { + g_usChecksum &= 0xFFFF; + sprintf(StrChecksum, "Data Checksum: %.4X\n\n", (unsigned int)g_usChecksum); + vme_out_string(StrChecksum); + g_usChecksum = 0; + } + } + + if (usErrorCount > 0) { + + if (g_usFlowControl & VERIFYUES) { + vme_out_string("USERCODE verification failed. Continue programming......\n\n"); + g_usFlowControl &= ~(VERIFYUES); + return 0; + } else { + +#ifdef VME_DEBUG + printf("TOTAL ERRORS: %d\n", usErrorCount); +#endif //VME_DEBUG + + return VME_VERIFICATION_FAILURE; + } + } else { + if (g_usFlowControl & VERIFYUES) { + vme_out_string("USERCODE verification passed. Programming aborted. \n\n"); + g_usFlowControl &= ~(VERIFYUES); + return 1; + } else { + return 0; + } + } +} + +/*************************************************************** +* +* ispVMReadandSave +* +* Support dynamic I/O. +* +***************************************************************/ + +signed char ispVMReadandSave(unsigned short int a_usiDataSize) +{ + //09/11/07 NN added local variables initialization + unsigned short int usDataSizeIndex = 0; + unsigned short int usLastBitIndex = 0; + unsigned short int usBufferIndex = 0; + unsigned short int usOutBitIndex = 0; + unsigned short int usLVDSIndex = 0; + unsigned char cDataByte = 0; + unsigned char cDMASKByte = 0; + unsigned char cInDataByte = 0; + unsigned char cCurBit = 0; + unsigned char cByteIndex = 0; + signed char cLVDSByteIndex = 0; + + //09/11/07 NN Type cast mismatch variables + usLastBitIndex = (unsigned short)(a_usiDataSize - 1); + + /*************************************************************** + * + * Iterate through the data bits. + * + ***************************************************************/ + + for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; usDataSizeIndex++) { + if (cByteIndex == 0) { + + /*************************************************************** + * + * Grab byte from DMASK buffer. + * + ***************************************************************/ + + if (g_usDataType & DMASK_DATA) { + cDMASKByte = g_pucOutDMaskData[usBufferIndex]; + } else { + cDMASKByte = 0x00; + } + + /*************************************************************** + * + * Grab byte from TDI buffer. + * + ***************************************************************/ + + if (g_usDataType & TDI_DATA) { + cInDataByte = g_pucInData[usBufferIndex]; + } + + usBufferIndex++; + } + + cCurBit = readPort(); + cDataByte = (unsigned char)(((cInDataByte << cByteIndex) & 0x80) ? 0x01 : 0x00); + + /*************************************************************** + * + * Initialize the byte to be zero. + * + ***************************************************************/ + + if (usOutBitIndex % 8 == 0) { + g_pucOutData[usOutBitIndex / 8] = 0x00; + } + + /*************************************************************** + * + * Use TDI, DMASK, and device TDO to create new TDI (actually + * stored in g_pucOutData). + * + ***************************************************************/ + + if ((((cDMASKByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) { + + if (g_pLVDSList) { + for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) { + if (g_pLVDSList[usLVDSIndex].usNegativeIndex == usDataSizeIndex) { + g_pLVDSList[usLVDSIndex].ucUpdate = 0x01; + break; + } + } + } + + /*************************************************************** + * + * DMASK bit is 1, use TDI. + * + ***************************************************************/ + + g_pucOutData[usOutBitIndex / 8] |= (unsigned char)(((cDataByte & 0x1) ? 0x01 : 0x00) << (7 - usOutBitIndex % 8)); + } else { + + /*************************************************************** + * + * DMASK bit is 0, use device TDO. + * + ***************************************************************/ + + g_pucOutData[usOutBitIndex / 8] |= (unsigned char)(((cCurBit & 0x1) ? 0x01 : 0x00) << (7 - usOutBitIndex % 8)); + } + + /*************************************************************** + * + * Shift in TDI in order to get TDO out. + * + ***************************************************************/ + + usOutBitIndex++; + writePort(JTAG_TDI, cDataByte); + if (usDataSizeIndex < usLastBitIndex) { + sclock(); + } + + /*************************************************************** + * + * Increment the byte index. If it exceeds 7, then reset it back + * to zero. + * + ***************************************************************/ + + cByteIndex++; + if (cByteIndex >= 8) { + cByteIndex = 0; + } + } + + /*************************************************************** + * + * If g_pLVDSList exists and pairs need updating, then update + * the negative-pair to receive the flipped positive-pair value. + * + ***************************************************************/ + + if (g_pLVDSList) { + for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) { + if (g_pLVDSList[usLVDSIndex].ucUpdate) { + + /*************************************************************** + * + * Read the positive value and flip it. + * + ***************************************************************/ + + cDataByte = (unsigned char)(((g_pucOutData[g_pLVDSList[usLVDSIndex].usPositiveIndex / 8] << (g_pLVDSList[usLVDSIndex].usPositiveIndex % 8)) & 0x80) ? 0x01 : 0x00); + //09/11/07 NN Type cast mismatch variables + cDataByte = (unsigned char)(!cDataByte); + + /*************************************************************** + * + * Get the byte that needs modification. + * + ***************************************************************/ + + cInDataByte = g_pucOutData[g_pLVDSList[usLVDSIndex].usNegativeIndex / 8]; + + if (cDataByte) { + + /*************************************************************** + * + * Copy over the current byte and set the negative bit to 1. + * + ***************************************************************/ + + cDataByte = 0x00; + for (cLVDSByteIndex = 7; cLVDSByteIndex >= 0; cLVDSByteIndex--) { + cDataByte <<= 1; + if (7 - (g_pLVDSList[usLVDSIndex].usNegativeIndex % 8) == cLVDSByteIndex) { + + /*************************************************************** + * + * Set negative bit to 1. + * + ***************************************************************/ + + cDataByte |= 0x01; + } else if (cInDataByte & 0x80) { + cDataByte |= 0x01; + } + + cInDataByte <<= 1; + } + + /*************************************************************** + * + * Store the modified byte. + * + ***************************************************************/ + + g_pucOutData[g_pLVDSList[usLVDSIndex].usNegativeIndex / 8] = cDataByte; + } else { + + /*************************************************************** + * + * Copy over the current byte and set the negative bit to 0. + * + ***************************************************************/ + + cDataByte = 0x00; + for (cLVDSByteIndex = 7; cLVDSByteIndex >= 0; cLVDSByteIndex--) { + cDataByte <<= 1; + if (7 - (g_pLVDSList[usLVDSIndex].usNegativeIndex % 8) == cLVDSByteIndex) { + + /*************************************************************** + * + * Set negative bit to 0. + * + ***************************************************************/ + + cDataByte |= 0x00; + } else if (cInDataByte & 0x80) { + cDataByte |= 0x01; + } + + cInDataByte <<= 1; + } + + /*************************************************************** + * + * Store the modified byte. + * + ***************************************************************/ + + g_pucOutData[g_pLVDSList[usLVDSIndex].usNegativeIndex / 8] = cDataByte; + } + + break; + } + } + } + + return (0); +} + +signed char ispVMProcessLVDS(unsigned short a_usLVDSCount) +{ + unsigned short usLVDSIndex = 0; + + /*************************************************************** + * + * Allocate memory to hold LVDS pairs. + * + ***************************************************************/ + + ispVMMemManager(LVDS, a_usLVDSCount); + g_usLVDSPairCount = a_usLVDSCount; + +#ifdef VME_DEBUG + printf("LVDS %d (", a_usLVDSCount); +#endif //VME_DEBUG + + /*************************************************************** + * + * Iterate through each given LVDS pair. + * + ***************************************************************/ + + for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) { + + /*************************************************************** + * + * Assign the positive and negative indices of the LVDS pair. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_pLVDSList[usLVDSIndex].usPositiveIndex = (unsigned short)ispVMDataSize(); + //09/11/07 NN Type cast mismatch variables + g_pLVDSList[usLVDSIndex].usNegativeIndex = (unsigned short)ispVMDataSize(); + +#ifdef VME_DEBUG + if (usLVDSIndex < g_usLVDSPairCount - 1) { + printf("%d:%d, ", g_pLVDSList[usLVDSIndex].usPositiveIndex, g_pLVDSList[usLVDSIndex].usNegativeIndex); + } else { + printf("%d:%d", g_pLVDSList[usLVDSIndex].usPositiveIndex, g_pLVDSList[usLVDSIndex].usNegativeIndex); + } +#endif //VME_DEBUG + + } + +#ifdef VME_DEBUG + printf(") -- %d;\n", a_usLVDSCount); +#endif //VME_DEBUG + + return (0); +} + +/*************************************************************** +* +* ivm_core_reinit +* +* Reinit ivm_core variables. +* +***************************************************************/ +void ivm_core_reinit() +{ + g_usFlowControl = 0x0000; + g_usDataType = 0x0000; + + g_ucEndDR = DRPAUSE; + g_ucEndIR = IRPAUSE; + + g_usHeadDR = 0; + g_usHeadIR = 0; + g_usTailDR = 0; + g_usTailIR = 0; + + g_usiDataSize = 0; + + g_iFrequency = 1000; + + g_usMaxSize = 0; + + g_usShiftValue = 0; + + g_usRepeatLoops = 0; + + g_cVendor = LATTICE; + + g_usCalculatedCRC = 0; + + g_usChecksum = 0; + g_uiChecksumIndex = 0; + + g_cCurrentJTAGState = 0; + + g_pucHeapMemory = NULL; + g_iHeapCounter = 0; + g_iHEAPSize = 0; + + g_usIntelDataIndex = 0; + g_usIntelBufferSize = 0; + + g_usTDOSize = 0; + g_usMASKSize = 0; + g_usTDISize = 0; + g_usDMASKSize = 0; + g_usLCOUNTSize = 0; + g_usHDRSize = 0; + g_usTDRSize = 0; + g_usHIRSize = 0; + g_usTIRSize = 0; + g_usHeapSize = 0; + + g_pucOutMaskData = NULL; + g_pucInData = NULL; + g_pucOutData = NULL; + g_pucHIRData = NULL; + g_pucTIRData = NULL; + g_pucHDRData = NULL; + g_pucTDRData = NULL; + g_pucIntelBuffer = NULL; + g_pucOutDMaskData = NULL; + + g_pLVDSList = NULL; + g_usLVDSPairCount = 0; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_isc/firmware_upgrade_isc.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_isc/firmware_upgrade_isc.c new file mode 100644 index 000000000000..c252dfde7c57 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_isc/firmware_upgrade_isc.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * firmware_upgrade_jtag + * function: Determine whether to upgrade ISC or JBI + * @fd: param[in] Device file descriptor + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_jtag(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + int ret; + cmd_info_t cmd_info; + + cmd_info.size = size; + cmd_info.data = buf; + ret = 0; + + if (info->type == FIRMWARE_CPLD) { + /* 0x4A,0x41,0x4D,0x01 is JBI file */ + if (buf[0] == 0x4A && buf[1] == 0x41 && buf[2] == 0x4D && buf[3] == 0x01) { + dbg_print(is_debug_on, "Use jbi file.\n"); + ret = ioctl(fd, FIRMWARE_PROGRAM_JBI, &cmd_info); + } else { + dbg_print(is_debug_on, "Use isc file.\n"); + ret = ioctl(fd, FIRMWARE_PROGRAM, &cmd_info); + } + } + + if (info->type == FIRMWARE_FPGA) { + ret = ioctl(fd, FIRMWARE_PROGRAM, &cmd_info); + } + + if (ret < 0) { + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_jtag_test + * function: Determine whether to upgrade ISC or JBI + * @fd: param[in] Device file descriptor + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_jtag_test(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + return FIRMWARE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.c new file mode 100644 index 000000000000..0a7659f0e428 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.c @@ -0,0 +1,446 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "firmware_upgrade_mtd.h" +#include "mtd-abi.h" + +static int get_mtdnum_from_name(char *name, int *mtdnum) +{ + FILE *fp; + int ret; + char buf[PATH_LEN]; + char *start; + char *end; + char *key_w = "mtd"; + + if (name == NULL || mtdnum == NULL) { + dbg_print(is_debug_on, "Input invalid error.\n"); + return -EINVAL; + } + ret = 0; + *mtdnum = -1; + fp = fopen("/proc/mtd", "r"); + if (fp == NULL) { + dbg_print(is_debug_on, "Not find mtd device.\n"); + return -FIRWMARE_MTD_PART_INFO_ERR; + } + + mem_clear(buf, sizeof(buf)); + while(fgets(buf, sizeof(buf), fp)) { + if (strstr(buf, name) != NULL) { + start = strstr(buf, key_w); + if (start == NULL) { + dbg_print(is_debug_on, "/proc/mtd don't find %s.\n", key_w); + ret = -FIRWMARE_MTD_PART_INFO_ERR; + goto exit; + } + start += strlen(key_w); + end = strchr(start, ':'); + if (end == NULL) { + dbg_print(is_debug_on, "/proc/mtd don't find %c.\n", ':'); + ret = -FIRWMARE_MTD_PART_INFO_ERR; + goto exit; + } + + *end = '\0'; + *mtdnum = atoi(start); + if (*mtdnum < 0) { + dbg_print(is_debug_on, "Not get mtd num.\n"); + ret = -FIRWMARE_MTD_PART_INFO_ERR; + goto exit; + } + } + } + + if (*mtdnum == -1) { + ret = -FIRWMARE_MTD_PART_INFO_ERR; + goto exit; + } +exit: + if (fp != NULL) { + fclose(fp); + } + + return ret; +} + +static int firmware_sysfs_get_dev_info(int fd, firmware_mtd_info_t *dev_info) +{ + int ret; + + ret = ioctl(fd, FIRMWARE_SYSFS_MTD_INFO, dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to get upg device file info.\n"); + return ret; + } + + dbg_print(is_debug_on, "mtd_name=%s flash_base=0x%x test_base=0x%x test_size=%d.\n", + dev_info->mtd_name, dev_info->flash_base, dev_info->test_base, dev_info->test_size); + return 0; +} + +/* + * MEMGETINFO + */ +static int getmeminfo(int fd, struct mtd_info_user *mtd) +{ + return ioctl(fd, MEMGETINFO, mtd); +} + +/* + * MEMERASE + */ +static int memerase(int fd, struct erase_info_user *erase) +{ + return ioctl(fd, MEMERASE, erase); +} + +static int erase_flash(int fd, uint32_t offset, uint32_t bytes) +{ + int err; + struct erase_info_user erase; + erase.start = offset; + erase.length = bytes; + err = memerase(fd, &erase); + if (err < 0) { + dbg_print(is_debug_on, "Error: memerase failed, err=%d\n", err); + return -FIRWMARE_MTD_MEMERASE; + } + dbg_print(is_debug_on, "Erased %d bytes from address 0x%.8x in flash\n", bytes, offset); + return 0; +} + +/* + * firmware_upgrade_mtd_block + * function: upgrade mtd device block + * @dev_info: param[in] Device file descriptor + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int firmware_upgrade_mtd_block(int mtd_fd, uint32_t offset, + uint8_t *buf, uint32_t size, uint32_t erasesize) +{ + int ret; + int i; + uint8_t *reread_buf; + uint32_t cmp_retry, reread_len, write_len; + + /* Read back data */ + reread_buf = (uint8_t *) malloc(size); + if (reread_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for read back data buf, size=%d.\n", size); + return FIRMWARE_FAILED; + } + + for (cmp_retry = 0; cmp_retry < FW_SYSFS_RETRY_TIME; cmp_retry++) { + for (i = 0; i < FW_SYSFS_RETRY_TIME; i++) { + if (offset != lseek(mtd_fd, offset, SEEK_SET)) { + dbg_print(is_debug_on, "Error:lseek mtd offset=%x retrytimes=%d failed.\n", offset, i); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + + dbg_print(is_debug_on, "erase mtd offset=0x%x erasesize=%d retrytimes=%d.\n", + offset, erasesize, i); + ret = erase_flash(mtd_fd, offset, erasesize); + if (ret < 0) { + dbg_print(is_debug_on, "Error:erase mtd offset=%x size=%d retrytimes=%d failed, ret=%d\n", + offset, size, i, ret); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + + dbg_print(is_debug_on, "write mtd offset=0x%x size=%d retrytimes=%d.\n", + offset, size, i); + write_len = write(mtd_fd, buf, size); + if (write_len != size) { + dbg_print(is_debug_on, "Error:write mtd offset=0x%x size=%d write_len=%d retrytimes=%d.\n", + offset, size, write_len, i); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "Error: upgrade mtd fail, offset = 0x%x, size = %d\n", offset, size); + free(reread_buf); + return FIRMWARE_FAILED; + } + + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + dbg_print(is_debug_on, "Reread mtd offset=0x%x size=%d\n", offset, size); + for (i = 0; i < FW_SYSFS_RETRY_TIME; i++) { + if (offset != lseek(mtd_fd, offset, SEEK_SET)) { + dbg_print(is_debug_on, "Error:lseek mtd offset=%x retrytimes=%d failed.\n", offset, i); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + + reread_len = read(mtd_fd, reread_buf, size); + if (reread_len != size) { + dbg_print(is_debug_on, "Error:reread mtd offset=0x%x size=%d reread_len=%d retrytimes=%d.\n", + offset, size, reread_len, i); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "Error: reread mtd fail, offset = 0x%x size = %d\n", offset, size); + free(reread_buf); + return FIRMWARE_FAILED; + } + + /* Check data */ + if (memcmp(reread_buf, buf, size) != 0) { + dbg_print(is_debug_on, "memcmp mtd fail,offset = 0x%x retrytimes = %d\n", offset, cmp_retry); + } else { + break; + } + } + if (cmp_retry >= FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "upgrade mtd fail, offset = 0x%x.\n", offset); + dbg_print(is_debug_on, "want to write buf :\n"); + for (i = 0; i < size; i++) { + dbg_print(is_debug_on, "0x%x ", buf[i]); + if (((i + 1) % 16) == 0) { + dbg_print(is_debug_on, "\n"); + } + } + dbg_print(is_debug_on, "\n"); + + dbg_print(is_debug_on, "actually reread buf :\n"); + for (i = 0; i < size; i++) { + dbg_print(is_debug_on, "0x%x ", reread_buf[i]); + if (((i + 1) % 16) == 0) { + dbg_print(is_debug_on, "\n"); + } + } + dbg_print(is_debug_on, "\n"); + + free(reread_buf); + return FIRMWARE_FAILED; + } + + free(reread_buf); + dbg_print(is_debug_on, "firmware upgrade mtd block offset[0x%.8x] success.\n", offset); + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_mtd_program + * function: upgrade mtd device + * @dev_info: param[in] Device file descriptor + * @flash_base: param[in] Upgrade the flash start address + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int firmware_upgrade_mtd_program(firmware_mtd_info_t *dev_info, + int flash_base, uint8_t *buf, uint32_t size) +{ + int ret; + int mtdnum; + char dev_mtd[PATH_LEN]; + int mtd_fd; + uint32_t offset, len, block_size; + struct mtd_info_user mtd_info; + uint8_t *data_point; + + ret = get_mtdnum_from_name(dev_info->mtd_name, &mtdnum); + if (ret < 0) { + dbg_print(is_debug_on, "Error:not find %s mtd num.\n", dev_info->mtd_name); + return FIRMWARE_FAILED; + } + + mem_clear(dev_mtd, sizeof(dev_mtd)); + snprintf(dev_mtd, sizeof(dev_mtd) - 1, "/dev/mtd%d", mtdnum); + + mtd_fd = open(dev_mtd, O_SYNC | O_RDWR); + if (mtd_fd < 0) { + dbg_print(is_debug_on, "Error:open %s failed.\n", dev_mtd); + goto err; + } + + ret = getmeminfo(mtd_fd, &mtd_info); + if (ret < 0) { + dbg_print(is_debug_on, "Error:get mtd info failed, ret=%d.\n", ret); + goto failed; + } + + offset = flash_base; + if (offset >= mtd_info.size) { + dbg_print(is_debug_on, "Error: offset[0x%.8x] over size[0x%.8x]\n", offset, size); + goto failed; + } + + len = size; + data_point = buf; + while ((offset < mtd_info.size) && (len > 0)) { + if (len > mtd_info.erasesize) { + block_size = mtd_info.erasesize; + } else { + block_size = len; + } + dbg_print(is_debug_on, "upgrade mtd[%s] block offset[0x%.8x] size[%d] relen[%d].\n", dev_mtd, offset, size, len); + ret = firmware_upgrade_mtd_block(mtd_fd, offset, data_point, block_size, mtd_info.erasesize); + if (ret < 0) { + dbg_print(is_debug_on, "Error: mt block offset[0x%.8x] size[0x%.8x] failed.\n", offset, block_size); + goto failed; + } + len -= block_size; + data_point += block_size; + offset += block_size; + usleep(FW_MTD_BLOCK_SLEEP_TIME); + } + + if (close(mtd_fd) < 0) { + dbg_print(is_debug_on, "Error:close %s failed.\n", dev_mtd); + } + dbg_print(is_debug_on, "firmware upgrade mtd device success.\n"); + return FIRMWARE_SUCCESS; + +failed: + if (close(mtd_fd) < 0) { + dbg_print(is_debug_on, "Error:close %s failed.\n", dev_mtd); + } + +err: + dbg_print(is_debug_on, "firmware upgrade mtd device fail.\n"); + return FIRMWARE_FAILED; +} + +/* + * firmware_upgrade_mtd + * function: Determine whether to upgrade ISC or JBI + * @fd: param[in] Device file descriptor + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_mtd(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + int ret; + firmware_mtd_info_t dev_info; + + if ((buf == NULL) || (info == NULL)) { + dbg_print(is_debug_on, "Input invalid error.\n"); + return FIRMWARE_FAILED; + } + + /* get sysfs information*/ + ret = firmware_sysfs_get_dev_info(fd, &dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_sysfs_get_dev_info failed, ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + /* enable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + return FIRMWARE_FAILED; + } + + ret = firmware_upgrade_mtd_program(&dev_info, dev_info.flash_base, buf, size); + if (ret < 0) { + dbg_print(is_debug_on, "Error:mtd device program failed, ret=%d.\n", ret); + goto failed; + } + + /* disable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + + return FIRMWARE_SUCCESS; + +failed: + /* disable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH,NULL); + if (ret < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + + return FIRMWARE_FAILED; +} + +/* + * firmware_upgrade_mtd_test + * function: Determine whether to upgrade ISC or JBI + * @fd: param[in] Device file descriptor + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_mtd_test(int fd, name_info_t *info) +{ + int ret, rv; + firmware_mtd_info_t dev_info; + uint8_t *data_buf; + uint8_t num; + int j; + + if (info == NULL) { + dbg_print(is_debug_on, "Input invalid error.\n"); + return FIRMWARE_FAILED; + } + + /* get sysfs information*/ + ret = firmware_sysfs_get_dev_info(fd, &dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_sysfs_get_dev_info failed, ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + if (dev_info.test_size == 0) { + dbg_print(is_debug_on, "Error: get flash size:%d, not support.\n", dev_info.test_size); + return FIRMWARE_NOT_SUPPORT; + } + + data_buf = (uint8_t *) malloc(dev_info.test_size); + if (data_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for test data buf, size=%d.\n", dev_info.test_size); + return FIRMWARE_FAILED; + } + + /* Get random data */ + for (j = 0; j < dev_info.test_size; j++) { + num = (uint8_t) rand() % 256; + data_buf[j] = num & 0xff; + } + + /* enable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + free(data_buf); + return FIRMWARE_FAILED; + } + + ret = firmware_upgrade_mtd_program(&dev_info, dev_info.test_base, data_buf, dev_info.test_size); + /* disable upgrade access */ + rv = ioctl(fd, FIRMWARE_SYSFS_FINISH, NULL); + if (rv < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + free(data_buf); + if (ret < 0) { + dbg_print(is_debug_on, "Error:mtd device program failed, ret=%d.\n", ret); + return FIRMWARE_FAILED; + } + return FIRMWARE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.h new file mode 100644 index 000000000000..06e36b3149d5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.h @@ -0,0 +1,32 @@ +#ifndef __FIRMWARE_UPGRADE_MTD_H__ +#define __FIRMWARE_UPGRADE_MTD_H__ + +#include + +#define FIRMWARE_DEV_NAME_LEN 64 /* the macro definition needs to same as FIRMWARE_DEV_NAME_LEN in firmware_sysfs_upgrade.h */ +#define PATH_LEN (256) +#define FW_MTD_BLOCK_SLEEP_TIME (10000) /* 10ms */ +#define FW_SYSFS_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define FW_SYSFS_RETRY_TIME (5) /* retry 5 times, 50ms = FW_SYSFS_RETRY_TIME *FW_SYSFS_RETRY_SLEEP_TIME; */ + +/* Debug switch level */ +typedef enum { + FIRWMARE_MTD_SUCCESS = 0, + FIRWMARE_MTD_PART_INFO_ERR, + FIRWMARE_MTD_MEMERASE, + FIRWMARE_MTD_MEMGETINFO, + FIRWMARE_END, +} firmware_debug_level_t; + +#define debug(fmt, argv...) do { \ + dbg_print(is_debug_on, ""fmt , ##argv);\ + } while(0) + +typedef struct firmware_mtd_info_s { + char mtd_name[FIRMWARE_DEV_NAME_LEN]; /* sysfs name */ + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_mtd_info_t; + +#endif /* End of __FIRMWARE_UPGRADE_MTD_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/mtd-abi.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/mtd-abi.h new file mode 100644 index 000000000000..f326d23e732e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/mtd-abi.h @@ -0,0 +1,259 @@ + +#ifndef __MTD_ABI_H__ +#define __MTD_ABI_H__ + +#include + +struct erase_info_user { + __u32 start; + __u32 length; +}; + +struct erase_info_user64 { + __u64 start; + __u64 length; +}; + +struct mtd_oob_buf { + __u32 start; + __u32 length; + unsigned char *ptr; +}; + +struct mtd_oob_buf64 { + __u64 start; + __u32 pad; + __u32 length; + __u64 usr_ptr; +}; + +/** + * MTD operation modes + * + * @MTD_OPS_PLACE_OOB: OOB data are placed at the given offset (default) + * @MTD_OPS_AUTO_OOB: OOB data are automatically placed at the free areas + * which are defined by the internal ecclayout + * @MTD_OPS_RAW: data are transferred as-is, with no error correction; + * this mode implies %MTD_OPS_PLACE_OOB + * + * These modes can be passed to ioctl(MEMWRITE) and are also used internally. + * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs. + * %MTD_FILE_MODE_RAW. + */ +enum { + MTD_OPS_PLACE_OOB = 0, + MTD_OPS_AUTO_OOB = 1, + MTD_OPS_RAW = 2, +}; + +/** + * struct mtd_write_req - data structure for requesting a write operation + * + * @start: start address + * @len: length of data buffer + * @ooblen: length of OOB buffer + * @usr_data: user-provided data buffer + * @usr_oob: user-provided OOB buffer + * @mode: MTD mode (see "MTD operation modes") + * @padding: reserved, must be set to 0 + * + * This structure supports ioctl(MEMWRITE) operations, allowing data and/or OOB + * writes in various modes. To write to OOB-only, set @usr_data == NULL, and to + * write data-only, set @usr_oob == NULL. However, setting both @usr_data and + * @usr_oob to NULL is not allowed. + */ +struct mtd_write_req { + __u64 start; + __u64 len; + __u64 ooblen; + __u64 usr_data; + __u64 usr_oob; + __u8 mode; + __u8 padding[7]; +}; + +#define MTD_ABSENT 0 +#define MTD_RAM 1 +#define MTD_ROM 2 +#define MTD_NORFLASH 3 +#define MTD_NANDFLASH 4 +#define MTD_DATAFLASH 6 +#define MTD_UBIVOLUME 7 +#define MTD_MLCNANDFLASH 8 + +#define MTD_WRITEABLE 0x400 /* Device is writeable */ +#define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */ +#define MTD_NO_ERASE 0x1000 /* No erase necessary */ +#define MTD_POWERUP_LOCK 0x2000 /* Always locked after reset */ + +/* Some common devices / combinations of capabilities */ +#define MTD_CAP_ROM 0 +#define MTD_CAP_RAM (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE) +#define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE) +#define MTD_CAP_NANDFLASH (MTD_WRITEABLE) + +/* Obsolete ECC byte placement modes (used with obsolete MEMGETOOBSEL) */ +#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended) +#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode) +#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme +#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read) +#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default + +/* OTP mode selection */ +#define MTD_OTP_OFF 0 +#define MTD_OTP_FACTORY 1 +#define MTD_OTP_USER 2 + +typedef struct mtd_info_user { + __u8 type; + __u32 flags; + __u32 size; /* Total size of the MTD */ + __u32 erasesize; + __u32 writesize; + __u32 oobsize; /* Amount of OOB data per block (e.g. 16) */ + __u64 padding; /* Old obsolete field; do not use */ +} mtd_info_user_t; + +struct region_info_user { + __u32 offset; /* At which this region starts, + * from the beginning of the MTD */ + __u32 erasesize; /* For this region */ + __u32 numblocks; /* Number of blocks in this region */ + __u32 regionindex; +}; + +struct otp_info { + __u32 start; + __u32 length; + __u32 locked; +}; + +/* + * Note, the following ioctl existed in the past and was removed: + * #define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) + * Try to avoid adding a new ioctl with the same ioctl number. + */ + +/* Get basic MTD characteristics info (better to use sysfs) */ +#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) +/* Erase segment of MTD */ +#define MEMERASE _IOW('M', 2, struct erase_info_user) +/* Write out-of-band data from MTD */ +#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) +/* Read out-of-band data from MTD */ +#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) +/* Lock a chip (for MTD that supports it) */ +#define MEMLOCK _IOW('M', 5, struct erase_info_user) +/* Unlock a chip (for MTD that supports it) */ +#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) +/* Get the number of different erase regions */ +#define MEMGETREGIONCOUNT _IOR('M', 7, int) +/* Get information about the erase region for a specific index */ +#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) +/* Get info about OOB modes (e.g., RAW, PLACE, AUTO) - legacy interface */ +#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) +/* Check if an eraseblock is bad */ +#define MEMGETBADBLOCK _IOW('M', 11, __kernel_loff_t) +/* Mark an eraseblock as bad */ +#define MEMSETBADBLOCK _IOW('M', 12, __kernel_loff_t) +/* Set OTP (One-Time Programmable) mode (factory vs. user) */ +#define OTPSELECT _IOR('M', 13, int) +/* Get number of OTP (One-Time Programmable) regions */ +#define OTPGETREGIONCOUNT _IOW('M', 14, int) +/* Get all OTP (One-Time Programmable) info about MTD */ +#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) +/* Lock a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */ +#define OTPLOCK _IOR('M', 16, struct otp_info) +/* Get ECC layout (deprecated) */ +#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout_user) +/* Get statistics about corrected/uncorrected errors */ +#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats) +/* Set MTD mode on a per-file-descriptor basis (see "MTD file modes") */ +#define MTDFILEMODE _IO('M', 19) +/* Erase segment of MTD (supports 64-bit address) */ +#define MEMERASE64 _IOW('M', 20, struct erase_info_user64) +/* Write data to OOB (64-bit version) */ +#define MEMWRITEOOB64 _IOWR('M', 21, struct mtd_oob_buf64) +/* Read data from OOB (64-bit version) */ +#define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64) +/* Check if chip is locked (for MTD that supports it) */ +#define MEMISLOCKED _IOR('M', 23, struct erase_info_user) +/* + * Most generic write interface; can write in-band and/or out-of-band in various + * modes (see "struct mtd_write_req") + */ +#define MEMWRITE _IOWR('M', 24, struct mtd_write_req) + +/* + * Obsolete legacy interface. Keep it in order not to break userspace + * interfaces + */ +struct nand_oobinfo { + __u32 useecc; + __u32 eccbytes; + __u32 oobfree[8][2]; + __u32 eccpos[32]; +}; + +struct nand_oobfree { + __u32 offset; + __u32 length; +}; + +#define MTD_MAX_OOBFREE_ENTRIES 8 +#define MTD_MAX_ECCPOS_ENTRIES 64 +/* + * OBSOLETE: ECC layout control structure. Exported to user-space via ioctl + * ECCGETLAYOUT for backwards compatbility and should not be mistaken as a + * complete set of ECC information. The ioctl truncates the larger internal + * structure to retain binary compatibility with the static declaration of the + * ioctl. Note that the "MTD_MAX_..._ENTRIES" macros represent the max size of + * the user struct, not the MAX size of the internal struct nand_ecclayout. + */ +struct nand_ecclayout_user { + __u32 eccbytes; + __u32 eccpos[MTD_MAX_ECCPOS_ENTRIES]; + __u32 oobavail; + struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; +}; + +/** + * struct mtd_ecc_stats - error correction stats + * + * @corrected: number of corrected bits + * @failed: number of uncorrectable errors + * @badblocks: number of bad blocks in this partition + * @bbtblocks: number of blocks reserved for bad block tables + */ +struct mtd_ecc_stats { + __u32 corrected; + __u32 failed; + __u32 badblocks; + __u32 bbtblocks; +}; + +/* + * MTD file modes - for read/write access to MTD + * + * @MTD_FILE_MODE_NORMAL: OTP disabled, ECC enabled + * @MTD_FILE_MODE_OTP_FACTORY: OTP enabled in factory mode + * @MTD_FILE_MODE_OTP_USER: OTP enabled in user mode + * @MTD_FILE_MODE_RAW: OTP disabled, ECC disabled + * + * These modes can be set via ioctl(MTDFILEMODE). The mode mode will be retained + * separately for each open file descriptor. + * + * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW - + * raw access to the flash, without error correction or autoplacement schemes. + * Wherever possible, the MTD_OPS_* mode will override the MTD_FILE_MODE_* mode + * (e.g., when using ioctl(MEMWRITE)), but in some cases, the MTD_FILE_MODE is + * used out of necessity (e.g., `write()', ioctl(MEMWRITEOOB64)). + */ +enum mtd_file_modes { + MTD_FILE_MODE_NORMAL = MTD_OTP_OFF, + MTD_FILE_MODE_OTP_FACTORY = MTD_OTP_FACTORY, + MTD_FILE_MODE_OTP_USER = MTD_OTP_USER, + MTD_FILE_MODE_RAW, +}; + +#endif /* __MTD_ABI_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.c new file mode 100644 index 000000000000..10a429d93bde --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.c @@ -0,0 +1,285 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "firmware_upgrade_sysfs.h" + +static int firmware_sysfs_get_dev_info(int fd, firmware_dev_file_info_t *dev_info) +{ + int ret; + + ret = ioctl(fd, FIRMWARE_SYSFS_DEV_FILE_INFO, dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to get upg flash dev info.\n"); + return ret; + } + + dbg_print(is_debug_on, "sysfs_name=%s per_len=%u.\n", dev_info->sysfs_name, dev_info->per_len); + return 0; +} + +/* sysfs upgrade program function */ +int firmware_upgrade_sysfs_program(firmware_dev_file_info_t *dev_info, uint32_t dev_base, + uint8_t *buf, uint32_t size) +{ + int ret = 0; + uint32_t offset_addr, buf_offset, len; + uint32_t write_len, cmp_retry, reread_len; + int sysfs_fd; + uint8_t *reread_buf; + int i; + + if (dev_info->per_len > 0) { + if (size % dev_info->per_len) { + dbg_print(is_debug_on, "firmware sysfs upgrade size[%u] is width[%u] mismatch, ret %d.\n", + size, dev_info->per_len, ret); + return FIRMWARE_FAILED; + } + len = dev_info->per_len; + } else { + /* Write to the maximum buffer if the length of each write is not configured */ + len = size; + } + + /* Read back data */ + reread_buf = (uint8_t *) malloc(len); + if (reread_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for read back data buf, len=%u.\n", len); + return FIRMWARE_FAILED; + } + + sysfs_fd = open(dev_info->sysfs_name, O_RDWR | O_SYNC); + if (sysfs_fd < 0) { + dbg_print(is_debug_on, "open file[%s] fail.\n", dev_info->sysfs_name); + free(reread_buf); + return FIRMWARE_FAILED; + } + + offset_addr = dev_base; + buf_offset = 0; + cmp_retry = 0; + while (buf_offset < size) { + /* Calibrate upgrade data length */ + if (buf_offset + len > size) { + len = size - buf_offset; + } + + for (i = 0; i < FW_SYSFS_RETRY_TIME; i++) { + ret = lseek(sysfs_fd, offset_addr, SEEK_SET); + if (ret < 0) { + dbg_print(is_debug_on, "lseek file[%s offset=%u] fail.\n", dev_info->sysfs_name, offset_addr); + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + write_len = write(sysfs_fd, buf + buf_offset, len); + if (write_len != len) { + dbg_print(is_debug_on, "write file[%s] fail,offset = 0x%x retrytimes = %u len = %u, write_len =%u\n", + dev_info->sysfs_name, offset_addr, i ,len, write_len); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + break; + } + + if (i == FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "write file[%s] fail, offset = 0x%x, len = %u, write_len =%u\n", + dev_info->sysfs_name, offset_addr, len, write_len); + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + + mem_clear(reread_buf, len); + ret = lseek(sysfs_fd, offset_addr, SEEK_SET); + if (ret < 0) { + dbg_print(is_debug_on, "reread lseek file[%s offset=%u] fail.\n", dev_info->sysfs_name, offset_addr); + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + + for (i = 0; i < FW_SYSFS_RETRY_TIME; i++) { + reread_len = read(sysfs_fd, reread_buf, len); + if (reread_len != len) { + dbg_print(is_debug_on, "reread file[%s] fail,offset = 0x%x retrytimes = %u reread_len = %u, len =%u\n", + dev_info->sysfs_name, offset_addr, i ,reread_len, len); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "reread file[%s] fail, offset = 0x%x, reread_len = %u, len = %u\n", + dev_info->sysfs_name, offset_addr, reread_len, len); + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + + /* Check data */ + if (memcmp(reread_buf, buf + buf_offset, len) != 0) { + if (cmp_retry < FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "memcmp file[%s] fail,offset = 0x%x retrytimes = %u\n", + dev_info->sysfs_name, offset_addr, cmp_retry); + cmp_retry++; + continue; + } + + dbg_print(is_debug_on, "upgrade file[%s] fail, offset = 0x%x.\n", dev_info->sysfs_name, offset_addr); + dbg_print(is_debug_on, "want to write buf :\n"); + for (i = 0; i < len; i++) { + dbg_print(is_debug_on, "0x%x ", buf[buf_offset + i]); + if (((i + 1) % 16) == 0) { + dbg_print(is_debug_on, "\n"); + } + } + dbg_print(is_debug_on, "\n"); + + dbg_print(is_debug_on, "actually reread buf :\n"); + for (i = 0; i < len; i++) { + dbg_print(is_debug_on, "0x%x ", reread_buf[i]); + if (((i + 1) % 16) == 0) { + dbg_print(is_debug_on, "\n"); + } + } + dbg_print(is_debug_on, "\n"); + + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + offset_addr += len; + buf_offset += len; + usleep(5000); + } + free(reread_buf); + + dbg_print(is_debug_on, "firmware upgrade sysfs success.\n"); + close(sysfs_fd); + return FIRMWARE_SUCCESS; +} + +/* sysfs upgrade function */ +int firmware_upgrade_sysfs(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + int ret = 0; + firmware_dev_file_info_t dev_info; + + if ((buf == NULL) || (info == NULL)) { + dbg_print(is_debug_on, "Input invalid error.\n"); + goto exit; + } + + /* get sysfs information*/ + ret = firmware_sysfs_get_dev_info(fd, &dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_sysfs_get_dev_info failed, ret %d.\n", ret); + goto exit; + } + + /* enable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + goto exit; + } + + ret = firmware_upgrade_sysfs_program(&dev_info, dev_info.dev_base, buf, size); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + goto fail; + } + + dbg_print(is_debug_on, "firmware upgrade sysfs success.\n"); + /* disable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH,NULL); + if (ret < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + return FIRMWARE_SUCCESS; + +fail: + /* disable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } +exit: + dbg_print(is_debug_on, "firmware upgrade sysfs fail.\n"); + return FIRMWARE_FAILED; +} + +/* sysfs upgrade test function */ +int firmware_upgrade_sysfs_test(int fd, name_info_t *info) +{ + int ret, rv; + firmware_dev_file_info_t dev_info; + uint8_t *data_buf; + uint8_t num; + int j; + + if (info == NULL) { + dbg_print(is_debug_on, "Input invalid error.\n"); + return FIRMWARE_FAILED; + } + + /* get sysfs information*/ + ret = firmware_sysfs_get_dev_info(fd, &dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_sysfs_get_dev_info failed, ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + if (dev_info.test_size == 0) { + dbg_print(is_debug_on, "Error: get sysfs test size:%d, not support.\n", dev_info.test_size); + return FIRMWARE_NOT_SUPPORT; + } + + data_buf = (uint8_t *) malloc(dev_info.test_size); + if (data_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for test data buf, size=%d.\n", dev_info.test_size); + return FIRMWARE_FAILED; + } + + /* Get random data */ + for (j = 0; j < dev_info.test_size; j++) { + num = (uint8_t) rand() % 256; + data_buf[j] = num & 0xff; + } + + /* enable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + free(data_buf); + return FIRMWARE_FAILED; + } + + ret = firmware_upgrade_sysfs_program(&dev_info, dev_info.test_base, data_buf, dev_info.test_size); + /* disable upgrade access */ + rv = ioctl(fd, FIRMWARE_SYSFS_FINISH,NULL); + if (rv < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + free(data_buf); + + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "firmware upgrade sysfs success.\n"); + return FIRMWARE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.h new file mode 100644 index 000000000000..b69080ea642e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.h @@ -0,0 +1,16 @@ +#ifndef __FIRMWARE_UPGRADE_SYSFS_H__ +#define __FIRMWARE_UPGRADE_SYSFS_H__ + +#define FIRMWARE_DEV_NAME_LEN (64) /* the macro definition needs to same as FIRMWARE_DEV_NAME_LEN in firmware_sysfs_upgrade.h */ +#define FW_SYSFS_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define FW_SYSFS_RETRY_TIME (5) /* retry 5 times, 50ms = FW_SYSFS_RETRY_TIME *FW_SYSFS_RETRY_SLEEP_TIME; */ + +typedef struct firmware_dev_file_info_s { + char sysfs_name[FIRMWARE_DEV_NAME_LEN]; /* sysfs name */ + uint32_t dev_base; /* device upgrade base address */ + uint32_t per_len; /* The length of bytes per operation */ + uint32_t test_base; /* Test device address */ + uint32_t test_size; /* Test flash size */ +} firmware_dev_file_info_t; + +#endif /* End of __FIRMWARE_UPGRADE_SYSFS_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.c new file mode 100644 index 000000000000..7db3c1b7b6ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.c @@ -0,0 +1,1181 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fw_upg_spi_logic_dev.h" + +#define be32_to_cpus(p) __be32_to_cpus(p) +#define le32_to_cpus(p) __le32_to_cpus(p) +#define cpu_to_be32s(p) __cpu_to_be32s(p) +#define cpu_to_le32s(p) __cpu_to_le32s(p) + +static void firmware_upgrade_printf_reg(uint8_t *buf, int buf_len, uint32_t offset_addr) +{ + int i, j, tmp; + + j = offset_addr % 16; + tmp = j; + offset_addr -= j; + printf("\n "); + + for (i = 0; i < 16; i++) { + printf("%2x ", i); + } + + for (i = 0; i < buf_len + j; i++) { + if ((i % 16) == 0) { + printf("\n0x%08x ", offset_addr); + offset_addr = offset_addr + 16; + } + if (tmp) { + printf(" "); + tmp--; + } else { + printf("%02x ", buf[i-j]); + } + } + + printf("\n"); + return; +} + +static int firmware_upgrade_get_spi_logic_info(int fd, firmware_spi_logic_upg_t *current_upg_priv) +{ + int ret; + firmware_spi_logic_info_t syfs_info; + + if (fd < 0) { + dbg_print(is_debug_on, "Error: get spi logic info fd %d.\n", fd); + return fd; + } + + ret = 0; + ret = ioctl(fd, FIRMWARE_SYSFS_SPI_INFO, &syfs_info); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to get upg flash dev info, ret=%d\n", ret); + return -FW_SPI_FLASH_GET_INFO_ERR; + } + + current_upg_priv->flash_base = syfs_info.flash_base; + current_upg_priv->ctrl_base = syfs_info.ctrl_base; + memcpy(current_upg_priv->dev_path, syfs_info.logic_dev_name, FIRMWARE_LOGIC_DEV_NAME_LEN - 1); + current_upg_priv->status_reg = syfs_info.ctrl_base + FPGA_UPG_STATUS_REG; + current_upg_priv->spi_ctrl_reg = syfs_info.ctrl_base + FPGA_UPG_SPI_CTRL_REG; + current_upg_priv->wr_flash_status_reg = syfs_info.ctrl_base + FPGA_UPG_WR_FLASH_STATUS_REG; + current_upg_priv->rd_flash_status_reg = syfs_info.ctrl_base + FPGA_UPG_RD_FLASH_STATUS_REG; + current_upg_priv->instruction_reg = syfs_info.ctrl_base + FPGA_UPG_INSTRUCTION_REG; + current_upg_priv->addr_reg = syfs_info.ctrl_base + FPGA_UPG_ADDR_REG; + current_upg_priv->length_reg = syfs_info.ctrl_base + FPGA_UPG_LENGTH_REG; + current_upg_priv->device_id_reg = syfs_info.ctrl_base + FPGA_UPG_DEVICE_ID_REG; + current_upg_priv->drop_reg_num_reg = syfs_info.ctrl_base + FPGA_UPG_DROP_REQ_NUM_REG; + current_upg_priv->test_base = syfs_info.test_base; + current_upg_priv->test_size = syfs_info.test_size; + + return 0; +} + +static int firmware_upgrade_spi_logic_init(int fd) +{ + int ret; + + ret = 0; + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to init spi logic, ret=%d\n", ret); + return -1; + } + + return 0; +} + +static int firmware_upgrade_spi_logic_finish(int fd) +{ + int ret; + + if (fd < 0) { + dbg_print(is_debug_on, "Error: get spi logic info fd %d.\n", fd); + return -1; + } + + ret = 0; + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to release spi logic, ret=%d\n", ret); + return -1; + } + + return 0; +} + +/** + * firmware_fpga_file_read - + * function:Provide FPGA read-register interface (address must be 4-byte aligned) + * @dev_name: Device file descriptor + * @offset: device offset + * @buf: Read Data Buffer + * @rd_len: Read Data Length + * return: 0--success; other--fail + */ +int firmware_fpga_file_read(char *dev_name, uint32_t offset, uint8_t *buf, uint32_t rd_len) +{ + int ret, fd; + + if ((dev_name == NULL) || (buf == NULL)) { + dbg_print(is_debug_on, "upg_priv or read buf is null.\n"); + return -1; + } + + if ((fd = open(dev_name, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + dbg_print(is_debug_on, "Error: Could not open file %s. Errno=%d\n", dev_name, errno); + return -1; + } + + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) { + dbg_print(is_debug_on, "read llseek failed, errno: %s\n", strerror(errno)); + close(fd); + return -1; + } + + ret = read(fd, buf, rd_len); + if (ret < 0) { + dbg_print(is_debug_on, "read failed, err: %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static int firmware_fpga_read_word(char *dev_name, uint32_t addr, uint32_t *val) +{ + int ret; + uint32_t retry; + + if (sizeof(int) < FIRMWARE_FPGA_WORD_LEN) { + dbg_print(is_debug_on, "Error:dfd_fpga_read_word buf len %ld support len %d.\n", + sizeof(int), FIRMWARE_FPGA_WORD_LEN); + return -1; + } + + retry = 0; + *val = 0; + while(retry < FIRMWARE_FPGA_UPG_RETRY_CNT) { + ret = firmware_fpga_file_read(dev_name, addr, (uint8_t *)val, FIRMWARE_FPGA_WORD_LEN); + if (ret) { + retry++; + dbg_print(is_debug_on, "firmware_fpga_file_read addr 0x%x retry %u failed ret %d.\n", + addr, retry, ret); + continue; + } else { + le32_to_cpus(val); + return 0; + } + } + + dbg_print(is_debug_on, "dfd_fpga_read_word addr 0x%x retry %u failed ret %d.\n", addr, retry, ret); + return -1; +} + +static int firmware_fpga_read_buf(char *dev_name, uint32_t addr, uint8_t *buf, uint32_t rd_len) +{ + int ret; + uint32_t retry; + + retry = 0; + while(retry < FIRMWARE_FPGA_UPG_RETRY_CNT) { + ret = firmware_fpga_file_read(dev_name, addr, buf, rd_len); + if (ret) { + retry++; + dbg_print(is_debug_on, "firmware_fpga_file_read addr 0x%x rd_len %u i %d failed ret %d.\n", + addr, rd_len, retry, ret); + continue; + } else { + return 0; + } + } + + dbg_print(is_debug_on, "firmware_fpga_file_read addr 0x%x rd_len %u retry %u failed ret %d.\n", + addr, rd_len, retry, ret); + return -1; +} + +/** + * firmware_fpga_file_write - + * function:Provide FPGA write-register interface (address must be 4-byte aligned) + * @dev_name: Device file descriptor + * @offset: device offset + * @buf: Write Data Buffer + * @wr_len: Write Data Length + * return: 0--success; other--fail + */ +int firmware_fpga_file_write(char *dev_name, uint32_t offset, uint8_t *buf, uint32_t wr_len) +{ + int ret, fd; + + if ((dev_name == NULL) || (buf == NULL)) { + dbg_print(is_debug_on, "dev_name or write buf is null.\n"); + return -1; + } + + if ((fd = open(dev_name, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + dbg_print(is_debug_on, "Error: Could not open file %s. Errno=%d\n", dev_name, errno); + return -1; + } + + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) { + dbg_print(is_debug_on, "write llseek failed, err: %s\n", strerror(errno)); + close(fd); + return -1; + } + + ret = write(fd, buf, wr_len); + if (ret < 0 ) { + dbg_print(is_debug_on, "write failed, err: %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static int firmware_fpga_write_word(char *dev_name, uint32_t addr, uint32_t val) +{ + int ret; + uint32_t retry, tmp; + + retry = 0; + tmp = val; + cpu_to_le32s(&tmp); + while(retry < FIRMWARE_FPGA_UPG_RETRY_CNT) { + ret = firmware_fpga_file_write(dev_name, addr, (uint8_t *)&tmp, FIRMWARE_FPGA_WORD_LEN); + if (ret) { + retry++; + dbg_print(is_debug_on, "firmware_fpga_file_write addr 0x%x val 0x%x retry %u failed ret %d.\n", + addr, val, retry, ret); + continue; + } else { + return 0; + } + } + + dbg_print(is_debug_on, "firmware_fpga_file_write addr 0x%x val 0x%x retry %u failed ret %d.\n", + addr, val, retry, ret); + return -1; +} + +static int firmware_fpga_write_buf(char *dev_name, uint32_t addr, uint8_t *buf, uint32_t wr_len) +{ + int ret; + uint32_t retry; + + retry = 0; + while(retry < FIRMWARE_FPGA_UPG_RETRY_CNT) { + ret = firmware_fpga_file_write(dev_name, addr, buf, wr_len); + if (ret) { + retry++; + dbg_print(is_debug_on, "firmware_fpga_file_write addr 0x%x wr_len 0x%x retry %u failed ret %d.\n", + addr, wr_len, retry, ret); + continue; + } else { + return 0; + } + } + + dbg_print(is_debug_on, "dfd_fpga_buf_write addr 0x%x wr_len 0x%x retry %u failed ret %d.\n", + addr, wr_len, retry, ret); + + return -1; +} + +/* Whether the SPI port is idle, 0--idle, 1--busy */ +static int firmware_fpga_get_status(firmware_spi_logic_upg_t *upg_priv, char *status) +{ + int ret; + uint32_t addr, val; + + addr = upg_priv->status_reg; + ret = firmware_fpga_read_word(upg_priv->dev_path, addr, &val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_get_status addr 0x%x failed ret %d.\n", addr, ret); + return -1; + } + + *status = val & FPGA_UPG_STATUS_MASK; + + return 0; +} + +/* Wait for the SPI port to become free again */ +static int firmware_fpga_wait_ready(firmware_spi_logic_upg_t *upg_priv) +{ + int timeout; + char status; + int ret; + + timeout = FIRMWARE_UPG_RETRY_TIME_CNT; + while (timeout--) { + usleep(FIRMWARE_UPG_RETRY_SLEEP_TIME); + ret = firmware_fpga_get_status(upg_priv, &status); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_get_status failed ret %d.\n", ret); + continue; + } + + /* Determine if it's idle */ + if (!status) { + return 0; + } + } + + return -1; +} + +/* Configure access */ +static int firmware_fpga_set_access(firmware_spi_logic_upg_t *upg_priv, uint32_t cmd) +{ + int ret; + uint32_t addr, val; + + addr = upg_priv->instruction_reg; + val = cmd; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", addr, val, ret); + return -1; + } + + addr = upg_priv->spi_ctrl_reg; + val = FPGA_UPG_ACCESS_ENABLE; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", addr, val, ret); + return -1; + } + + /* Wait for the SPI port on the FPGA to become free again*/ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_wait_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + return 0; +} + +/* Get SPI STATUS register */ +static int firmware_fpga_get_spi_status(firmware_spi_logic_upg_t *upg_priv, char *status) +{ + int ret; + uint32_t val, addr, cmd; + + cmd = FPGA_UPG_INSTRUTION_RDSR; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd 0x%x failed ret %d.\n", cmd, ret); + return -1; + } + + addr = upg_priv->rd_flash_status_reg; + ret = firmware_fpga_read_word(upg_priv->dev_path, addr, &val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_read_word addr 0x%x failed ret %d.\n", addr, ret); + return -1; + } + + *status = val & FPGA_UPG_SPI_STATUS_MASK; + + return 0; +} + +/* Wait for the SPI chip operation to complete */ +static int firmware_fpga_wait_spi_ready(firmware_spi_logic_upg_t *upg_priv, + uint32_t timeout, uint32_t usleep_time) +{ + char status; + int ret; + + while (timeout--) { + usleep(usleep_time); + ret = firmware_fpga_get_spi_status(upg_priv, &status); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_get_spi_status failed ret %d.\n", ret); + continue; + } + /* Determine if it's idle */ + if (!status) { + return 0; + } + } + + return -FW_SPI_FLASH_SPI_BUSY; +} + +/* Configure FPGA upgrade write enable */ +static int firmware_fpga_set_wr_enable(firmware_spi_logic_upg_t *upg_priv) +{ + int ret; + uint32_t cmd; + + cmd = FPGA_UPG_INSTRUTION_WREN; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -1; + } + + return 0; +} + +#if 0 +/* erase all flash */ +static int firmware_fpga_upg_set_erase_all(firmware_spi_logic_upg_t *upg_priv) +{ + int ret; + int cmd; + + /* Wait for the SPI port on the FPGA to become free */ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_wait_ready failed ret %d.\n", ret); + return -1; + } + + /* Configure FPGA upgrade write enable */ + ret = firmware_fpga_set_wr_enable(upg_priv); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_wr_enable failed ret %d.\n", ret); + return -1; + } + + cmd = FPGA_UPG_INSTRUTION_BE; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -1; + } + + /* Hardware requirements, delay of 1s */ + sleep(1); + + /* Wait for the SPI chip operation to complete, 1s check status once, max delay 300s */ + ret = firmware_fpga_wait_spi_ready(upg_priv, 300, (1 * 1000 * 1000)); + if (ret) { + dbg_print(is_debug_on, "dfd_fpga_wait_spi_ready failed ret %d.\n", ret); + return -1; + } + + dbg_print(is_debug_on, "Success.\n"); + return 0; +} +#endif + +/* Erase sectors (256 pages, 64K total) */ +static int firmware_fpga_erase_sector(firmware_spi_logic_upg_t *upg_priv, uint32_t spi_addr) +{ + int ret; + uint32_t val, addr, cmd; + + /* Wait for the SPI port on the FPGA to become free again */ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_fpga_wait_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + /* Enable write */ + ret = firmware_fpga_set_wr_enable(upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_fpga_set_wr_enable failed ret %d.\n", ret); + return -FW_SPI_FLASH_WR_ENABLE_ERR; + } + + /* Write erase address */ + val = spi_addr; + addr = upg_priv->addr_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", addr, val, ret); + return -FW_SPI_FLASH_ERASE_ADDR_ERR; + } + + /* Enable sector erasure */ + cmd = FPGA_UPG_INSTRUTION_SE; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -FW_SPI_FLASH_ERASE_SECTOR_ERR; + } + + /* Hardware requirements, delay of 0.25s */ + usleep(250 * 1000); + + /* Wait for the SPI chip operation to complete, 1s check status once, max delay 10s */ + ret = firmware_fpga_wait_spi_ready(upg_priv, FPGA_UPG_WAIT_SPI_RETRY_CNT, (100 * 1000)); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_wait_spi_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_SPI_BUSY; + } + + return 0; +} + +#if 0 +int firmware_fpga_erase64_sector(firmware_spi_logic_upg_t *upg_priv, int offset) +{ + int ret; + ret = -1; + + if ((offset % FIRMWARE_SPI_LOGIC_SECTOR_SIZE) == 0) { + dbg_print(is_debug_on, "erase 64k area, offset 0x%x.\n", offset); + ret = firmware_fpga_erase_sector(upg_priv, offset); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_erase_sector offset 0x%x failed ret %d.\n", offset, ret); + return ret; + } + } else { + dbg_print(is_debug_on, "Input para invalid, offset 0x%x.\n", offset); + } + + return ret; +} +#endif + +static int firmware_fpga_upg_program(firmware_spi_logic_upg_t *upg_priv, + uint32_t spi_addr, uint8_t *buf, uint32_t len) +{ + int ret; + uint32_t addr, val, cmd, wr_len; + + /* Write data to the Upgrade Content Register */ + addr = upg_priv->ctrl_base; + wr_len = len; + ret = firmware_fpga_write_buf(upg_priv->dev_path, addr, (uint8_t*)buf, wr_len); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_write_buf addr 0x%x wr_len %d failed ret %d.\n", + addr, len, ret); + return -FW_SPI_FLASH_WR_ERR; + } + + /* Write length register, FPGA is fixed 256 lengths */ + val = FFPGA_UPG_DATA_SIZE; + addr = upg_priv->length_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", + addr, val, ret); + return -FW_SPI_FLASH_WR_LENGTH_ERR; + } + + /* Write address register */ + val = spi_addr; + addr = upg_priv->addr_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", + addr, val, ret); + return -FW_SPI_FLASH_WR_ADDR_ERR; + } + + /* Start writing upgrade data to SPI */ + cmd = FPGA_UPG_INSTRUTION_PP; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -FW_SPI_FLASH_SET_ACCESS_ERR; + } + + /* min write wait 0.33ms */ + usleep(330); + + /* Wait for the SPI chip operation to complete, 100us check status once, max delay 10ms */ + ret = firmware_fpga_wait_spi_ready(upg_priv, FPGA_UPG_WAIT_SPI_RETRY_CNT, (100)); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_wait_spi_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + return 0; +} + +/** + * firmware_fpga_upg_write + * function: write interface provided to the upgrade module + * @upg_priv: Device information + * @addr: upgrade addr + * @buf: Write Data Buffer + * @len: Write Data Length + * return: 0--success; other--fail + */ +static int firmware_fpga_upg_write(firmware_spi_logic_upg_t *upg_priv, + uint32_t addr, uint8_t *buf, uint32_t len) +{ + int ret; + + /* address must be 256 bytes aligned */ + if ((upg_priv == NULL) || (buf == NULL) || (addr & 0xff) || (len > 256)) { + dbg_print(is_debug_on,"Input para invalid upg_priv %p buf %p addr 0x%x len %u.\n", + upg_priv, buf, addr, len); + return -FW_SPI_FLASH_PARAM_ERR; + } + + /* Wait for the SPI port on the FPGA to become free again*/ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_wait_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + /* Configure write enable */ + ret = firmware_fpga_set_wr_enable(upg_priv); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_set_wr_enable failed ret %d.\n", ret); + return -FW_SPI_FLASH_WR_ENABLE_ERR; + } + + /* Write upgrade data */ + ret = firmware_fpga_upg_program(upg_priv, addr, buf, len); + if (ret) { + dbg_print(is_debug_on,"dfd_fpga_upg_program addr 0x%x len %u failed ret %d.\n", addr, len, ret); + return -FW_SPI_FLASH_UPG_ERR; + } + + return 0; +} + +static int firmware_fpga_fast_read(firmware_spi_logic_upg_t *upg_priv, + uint32_t spi_addr, uint8_t *buf, uint32_t len) +{ + int ret; + uint32_t val, addr, cmd; + + /* Clear register value */ + addr = upg_priv->ctrl_base; + ret = firmware_fpga_write_buf(upg_priv->dev_path, addr, buf, len); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_buf addr 0x%x len %d failed ret %d.\n", addr, len, ret); + return -FW_SPI_FLASH_WR_ERR; + } + /* Write length register */ + val = FFPGA_UPG_DATA_SIZE; + addr = upg_priv->length_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", + addr, val, ret); + return -FW_SPI_FLASH_WR_LENGTH_ERR; + } + + /* Write address register */ + val = spi_addr; + addr = upg_priv->addr_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", + addr, val, ret); + return -FW_SPI_FLASH_WR_ADDR_ERR; + } + + /* Start reading SPI data */ + cmd = FPGA_UPG_INSTRUTION_FR; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -FW_SPI_FLASH_SET_ACCESS_ERR; + } + + /* Read the upgraded content register to the buffer, + * FPGA only supports 4 bytes of read and write */ + addr = upg_priv->ctrl_base; + ret = firmware_fpga_read_buf(upg_priv->dev_path, addr, (uint8_t*)buf, len); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_read_buf addr 0x%x len %d failed ret %d.\n", addr, len, ret); + return -FW_SPI_FLASH_RD_ERR; + } + + return 0; +} + +/** + * firmware_fpga_upg_read + * function: read interface provided to the upgrade module + * @upg_priv: Device information + * @addr: upgrade addr + * @buf: Read Data Buffer + * @len: Read Data Length + * return: 0--success; other--fail + */ +static int firmware_fpga_upg_read(firmware_spi_logic_upg_t *upg_priv, + uint32_t addr, uint8_t *buf, uint32_t len) +{ + int ret; + + /* address must be 256 bytes aligned */ + if ((upg_priv == NULL) || (buf == NULL) || (addr & 0xff) || (len > 256)) { + dbg_print(is_debug_on, "Input para invalid upg_priv %p buf %p addr 0x%x len %u.\n", + upg_priv, buf, addr, len); + return -FW_SPI_FLASH_PARAM_ERR; + } + + /* Wait for the SPI port on the FPGA to become free again */ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_wait_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + /* Configure write enable */ + ret = firmware_fpga_set_wr_enable(upg_priv); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_wr_enable failed ret %d.\n", ret); + return -FW_SPI_FLASH_WR_ENABLE_ERR; + } + + /* Read upgrade data */ + ret = firmware_fpga_fast_read(upg_priv, addr, buf, len); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_fast_read addr 0x%x len %u failed ret %d.\n", addr, len, ret); + return -FW_SPI_FLASH_RD_ERR; + } + + return 0; + +} + +static int firmware_upgreade_fpga_onetime(firmware_spi_logic_upg_t *upg_priv, + uint32_t flash_base, uint8_t *buf, uint32_t size) +{ + uint32_t offset, len, flash_addr, retry; + int ret, res; + uint8_t rbuf[FFPGA_UPG_DATA_SIZE]; + + offset = 0; + while(offset < size) { + flash_addr = flash_base + offset; + /* Erases a sector */ + if ((flash_addr % FIRMWARE_SPI_LOGIC_SECTOR_SIZE) == 0) { + ret = firmware_fpga_erase_sector(upg_priv, flash_addr); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_fpga_erase_sector flash_addr 0x%x failed ret %d.\n", + flash_addr, ret); + goto exit; + } + } + + if (size > FFPGA_UPG_DATA_SIZE) { + len = FFPGA_UPG_DATA_SIZE; + } else { + len = size; + } + + /* first, Write data */ + ret = firmware_fpga_upg_write(upg_priv, flash_addr, buf + offset, len); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_upg_write addr 0x%x len 0x%x failed ret %d.\n", + flash_addr, len, ret); + ret = -FW_SPI_FLASH_UPG_ERR; + goto exit; + } + + /* Read back the data and compare the correctness of the data */ + for (retry = 0; retry < FPGA_UPG_RETRY_TIMES; retry++) { /*retry 3 times*/ + mem_clear(rbuf, len); + ret = firmware_fpga_upg_read(upg_priv, flash_addr, rbuf, len); + res = memcmp(rbuf, buf + offset, len); + if (ret || res) { + usleep(1000); + continue; + } + break; + } + + if (ret) { + dbg_print(is_debug_on, "firmware fpga read offset 0x%x len 0x%x failed ret %d.\n", flash_addr, len, ret); + ret = -FW_SPI_FLASH_RD_ERR; + goto exit; + } + + if (res) { + dbg_print(is_debug_on, "firmware fpga rbuf wbuf not equal, len 0x%x, check failed.\n", len); + ret = -FW_SPI_FLASH_DATA_CMP_ERR; + goto exit; + } + offset += len; + } + + dbg_print(is_debug_on, "Update success.\n"); + return FIRMWARE_SUCCESS; +exit: + dbg_print(is_debug_on, "Update failed.\n"); + return FIRMWARE_FAILED; +} + +static int firmware_upgrade_do_spi_logic(firmware_spi_logic_upg_t *current_upg_priv, + unsigned char *buf, uint32_t size) +{ + int i, ret; + uint32_t retry; + + i = 0; + retry = FIRMWARE_SPI_LOGIC_UPG_RETRY_CNT; + + ret = 0; + while(i < retry) { + ret = firmware_upgreade_fpga_onetime(current_upg_priv, current_upg_priv->flash_base, buf, size); + if (ret) { + i++; + dbg_print(is_debug_on, "firmware_upgreade_fpga_onetime size 0x%x failed ret %d.\n", size, ret); + continue; + } else { + dbg_print(is_debug_on, "firmware_upgreade_fpga_onetime success.\n"); + return 0; + } + } + + return ret; +} + +/* + * firmware_upgrade_spi_logic_dev + * function: FPGA SPI FLASH Firmware upgrade handler function + * @fd: param[in] sysfs device descriptor + * @buf: param[in] Update data + * @size: param[in] Update data size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_spi_logic_dev(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + int ret; + firmware_spi_logic_upg_t current_upg_priv; + + if ((fd < 0) || (buf == NULL) || (info == NULL)) { + dbg_print(is_debug_on, "Error:firmware upgrade spi logic dev parameters failed.\n"); + return FIRMWARE_FAILED; + } + + /* Gets the current logical device information */ + mem_clear(¤t_upg_priv, sizeof(firmware_spi_logic_upg_t)); + ret = firmware_upgrade_get_spi_logic_info(fd, ¤t_upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_get_spi_logic_info failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "current_upg_priv dev_path[%s] flash_base[0x%0x] ctrl_base[0x%0x]\n", + current_upg_priv.dev_path, current_upg_priv.flash_base, + current_upg_priv.ctrl_base); + + /* Enable upgrade access */ + ret = firmware_upgrade_spi_logic_init(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_init failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + /* Upgrade logic device */ + ret = firmware_upgrade_do_spi_logic(¤t_upg_priv, buf, size); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_do_spi_logic failed ret %d.\n", ret); + goto fail; + } + + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_SUCCESS; +fail: + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_FAILED; +} + +int firmware_fpga_upgrade_test(firmware_spi_logic_upg_t *current_upg_priv) +{ + int ret, i, j, num; + uint8_t *wbuf; + uint32_t retry; + + ret = FW_SPI_FLASH_RV_OK; + wbuf = (uint8_t *) malloc(current_upg_priv->test_size); + if (wbuf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for test data buf, size=0x%x.\n", current_upg_priv->test_size); + ret = -FW_SPI_FLASH_NOT_SUPPORT_TEST; + goto exit; + } + mem_clear(wbuf, current_upg_priv->test_size); + /* Get random data */ + for (j = 0; j < current_upg_priv->test_size; j++) { + num = rand() % 256; + wbuf[j] = num & 0xff; + } + + i = 0; + retry = FIRMWARE_SPI_LOGIC_UPG_RETRY_CNT; + + ret = 0; + while(i < retry) { + ret = firmware_upgreade_fpga_onetime(current_upg_priv, current_upg_priv->test_base, wbuf, current_upg_priv->test_size); + if (ret) { + i++; + dbg_print(is_debug_on, "firmware_upgreade_fpga_onetime test size 0x%x failed ret %d.\n", + current_upg_priv->test_size, ret); + continue; + } else { + dbg_print(is_debug_on, "firmware_upgreade_fpga_onetime test success.\n"); + break; + } + } + free(wbuf); +exit: + return ret; +} + +/* + * firmware_upgrade_spi_logic_dev_test + * function: FPGA SPI FLASH Firmware upgrade test handler function + * @fd: param[in] sysfs device descriptor + * @buf: param[in] Update data + * @size: param[in] Update data size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_spi_logic_dev_test(int fd, name_info_t *info) +{ + int ret; + firmware_spi_logic_upg_t current_upg_priv; + + if ((fd < 0) || (info == NULL)) { + dbg_print(is_debug_on, "Error:firmware upgrade spi logic dev parameters failed.\n"); + return FIRMWARE_FAILED; + } + + /* Gets the current logical device information */ + mem_clear(¤t_upg_priv, sizeof(firmware_spi_logic_upg_t)); + ret = firmware_upgrade_get_spi_logic_info(fd, ¤t_upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_get_spi_logic_info failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "current_upg_priv dev_path[%s] test_base[0x%0x] test_size[0x%x]\n", + current_upg_priv.dev_path, current_upg_priv.test_base, current_upg_priv.test_size); + if (current_upg_priv.test_size <= 0) { + dbg_print(is_debug_on, "Error: don't support flast test.\n"); + return FIRMWARE_NOT_SUPPORT; + } + + /* Enable upgrade access */ + ret = firmware_upgrade_spi_logic_init(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_init failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + /* Upgrade logic device */ + ret = firmware_fpga_upgrade_test(¤t_upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_do_spi_logic failed ret %d.\n", ret); + goto fail; + } + + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_SUCCESS; +fail: + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_FAILED; +} + +static int firmware_upgreade_spi_logic_dump(firmware_spi_logic_upg_t *upg_priv, + uint32_t offset, uint8_t *buf, uint32_t size) +{ + int ret, i; + uint32_t addr, buf_page, retry, cnt, rd_len; + + buf_page = FFPGA_UPG_DATA_SIZE; /* read data by BUF SIZE each time */ + + cnt = size / FFPGA_UPG_DATA_SIZE; + if (size % FFPGA_UPG_DATA_SIZE) { + cnt++; + } + dbg_print(is_debug_on, "need read number of times:%d.\n", cnt); + + for (i = 0; i < cnt; i++) { + addr = offset + i * FFPGA_UPG_DATA_SIZE; + if (i == (cnt - 1)) { + /* last time read remain size */ + rd_len = size - buf_page * i; + } else { + /* each time read buf page size */ + rd_len = buf_page; + } + + for (retry = 0; retry < FPGA_UPG_RETRY_TIMES; retry++) { + ret = firmware_fpga_upg_read(upg_priv, addr, buf, rd_len); + if (ret < 0) { + dbg_print(is_debug_on, "addr:0x%x read %d time failed. ret %d\n", addr, retry, ret); + continue; + } + break; + } + + if (ret < 0) { + dbg_print(is_debug_on, "finally addr:0x%x read failed ret %d\n", addr, ret); + return FIRMWARE_FAILED; + } + + buf += rd_len; /* buf pointer offset rd_len */ + } + + return FIRMWARE_SUCCESS; +} + +static int firmware_fpga_dump_read(int fd, uint32_t offset, uint8_t *buf, uint32_t len) +{ + int ret; + firmware_spi_logic_upg_t current_upg_priv; + + if ((fd < 0) || (buf == NULL)) { + dbg_print(is_debug_on, "Error:firmware upgrade spi logic dev parameters failed.\n"); + return FIRMWARE_FAILED; + } + + /* Gets the current logical device information */ + mem_clear(¤t_upg_priv, sizeof(firmware_spi_logic_upg_t)); + ret = firmware_upgrade_get_spi_logic_info(fd, ¤t_upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_get_spi_logic_info failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "current_upg_priv dev_path[%s] flash_base[0x%0x] ctrl_base[0x%0x]\n", + current_upg_priv.dev_path, current_upg_priv.flash_base, + current_upg_priv.ctrl_base); + + /* Enable upgrade access */ + ret = firmware_upgrade_spi_logic_init(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_init failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + /* read logic device */ + ret = firmware_upgreade_spi_logic_dump(¤t_upg_priv, offset, buf, len); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_do_spi_logic failed ret %d.\n", ret); + goto fail; + } + + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_SUCCESS; + +fail: + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_FAILED; +} + +int firmware_upgrade_spi_logic_dev_dump(char *dev_name, uint32_t offset, + uint32_t len, char *record_file) +{ + int ret, dev_fd, file_fd; + char save_file[FIRMWARE_LOGIC_DEV_NAME_LEN]; + uint8_t *buf; + + dev_fd = open(dev_name, O_RDWR); + if (dev_fd < 0) { + dbg_print(is_debug_on, "Error: Failed to open %s, errno:%d.\n", dev_name, errno); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "open dev file %s succeeded.\n", dev_name); + + buf = (uint8_t *) malloc(len); + if (buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory read %s data.\n", dev_name); + ret = FIRMWARE_FAILED; + goto free_dev_fd; + } + + mem_clear(buf, len); + ret = firmware_fpga_dump_read(dev_fd, offset, buf, len); + if (ret < 0) { + dbg_print(is_debug_on, "addr 0x%x read 0x%x failed ret:%d\n", offset, len, ret); + goto free_data; + } + + dbg_print(is_debug_on, "dump data succeeded. offset:0x%x, len:0x%x\n", offset, len); + + if (strcmp(record_file, "print") != 0) { /* record dump data on 'record_file' */ + mem_clear(save_file, FIRMWARE_LOGIC_DEV_NAME_LEN); + strncpy(save_file, record_file, FIRMWARE_LOGIC_DEV_NAME_LEN - 1); + file_fd = open(save_file, O_RDWR|O_CREAT|O_TRUNC, S_IRWXG|S_IRWXU|S_IRWXO); + if (file_fd < 0) { + dbg_print(is_debug_on, "open file %s fail, errno:%d.\n", save_file, errno); + ret = -ENOENT; + goto free_data; + } + + dbg_print(is_debug_on, "open save file %s succeeded.\n", save_file); + + ret = write(file_fd, buf, len); + if (ret < 0) { + dbg_print(is_debug_on, "write failed (errno: %d).\n", errno); + goto free_file_fd; + } + dbg_print(is_debug_on, "write save file %s succeeded.\n", save_file); + ret = FIRMWARE_SUCCESS; + } else { /* print reg on terminal by format */ + firmware_upgrade_printf_reg((uint8_t*)buf, len, offset); + ret = FIRMWARE_SUCCESS; + goto free_data; + } + +free_file_fd: + close(file_fd); +free_data: + free(buf); +free_dev_fd: + close(dev_fd); + + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.h new file mode 100644 index 000000000000..32f820161e86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.h @@ -0,0 +1,90 @@ +#ifndef __FW_UPG_SPI_LOGIC_DEV_H__ +#define __FW_UPG_SPI_LOGIC_DEV_H__ + +#define FIRMWARE_FPGA_WORD_LEN (4) + +#define FIRMWARE_LOGIC_DEV_NAME_LEN (64) /* the macro definition needs to same as FIRMWARE_DEV_NAME_LEN in firmware_sysfs_upgrade.h */ +#define FIRMWARE_SPI_LOGIC_UPG_RETRY_CNT (10) +#define FIRMWARE_SPI_LOGIC_UPG_BUFF_SIZE (256) +#define FIRMWARE_SPI_LOGIC_SECTOR_SIZE (0x10000) /* One sector is 64Kk */ + +#define FIRMWARE_UPG_RETRY_SLEEP_TIME (10) /* 10us */ +#define FIRMWARE_UPG_RETRY_TIME_CNT (1000) +#define FPGA_UPG_WAIT_SPI_RETRY_CNT (100) +#define FPGA_UPG_WAIT_SPI_RETRY_SLEEP_TIME (1000 * 10) /* 10ms */ + +#define FIRMWARE_FPGA_UPG_RETRY_CNT (100) + +/* FPGA upgrades related instruction definitions */ +#define FPGA_UPG_INSTRUTION_SE (0xD8) +#define FPGA_UPG_INSTRUTION_RDSR (0x05) +#define FPGA_UPG_INSTRUTION_WREN (0x06) +#define FPGA_UPG_INSTRUTION_PP (0x02) +#define FPGA_UPG_INSTRUTION_FR (0x0B) +#define FPGA_UPG_INSTRUTION_BE (0xC7) +#define FPGA_UPG_STATUS_MASK (0x1) +#define FPGA_UPG_ACCESS_ENABLE (0x3) +#define FPGA_UPG_SPI_STATUS_MASK (0x1) +#define FFPGA_UPG_DATA_SIZE (256) + +#define FPGA_UPG_RETRY_TIMES (3) + +/* FPGA upgrades the offset of the associated register */ +#define FPGA_UPG_STATUS_REG (0x180) +#define FPGA_UPG_SPI_CTRL_REG (0x184) +#define FPGA_UPG_WR_FLASH_STATUS_REG (0x188) +#define FPGA_UPG_RD_FLASH_STATUS_REG (0x18C) +#define FPGA_UPG_INSTRUCTION_REG (0x190) +#define FPGA_UPG_ADDR_REG (0x194) +#define FPGA_UPG_LENGTH_REG (0x198) +#define FPGA_UPG_DEVICE_ID_REG (0x19C) +#define FPGA_UPG_DROP_REQ_NUM_REG (0x1A8) + +typedef struct firmware_spi_logic_info_s { + char logic_dev_name[FIRMWARE_LOGIC_DEV_NAME_LEN]; /* Logical device name */ + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t ctrl_base; /* SPI upgrade control register base address */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_spi_logic_info_t; + +typedef struct firmware_spi_logic_upg_s { + char dev_path[FIRMWARE_LOGIC_DEV_NAME_LEN]; + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t ctrl_base; /* SPI upgrade control register base address */ + uint32_t status_reg; + uint32_t spi_ctrl_reg; + uint32_t wr_flash_status_reg; + uint32_t rd_flash_status_reg; + uint32_t instruction_reg; + uint32_t addr_reg; + uint32_t length_reg; + uint32_t device_id_reg; + uint32_t drop_reg_num_reg; + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +}firmware_spi_logic_upg_t; + +typedef enum firmware_spi_flash_rv_s { + FW_SPI_FLASH_RV_OK = 0, + FW_SPI_FLASH_STATUS_ERR, + FW_SPI_FLASH_BUSY, + FW_SPI_FLASH_SPI_BUSY, + FW_SPI_FLASH_WR_ENABLE_ERR, + FW_SPI_FLASH_ERASE_ADDR_ERR, + FW_SPI_FLASH_ERASE_SECTOR_ERR, + FW_SPI_FLASH_WR_ERR, + FW_SPI_FLASH_RD_ERR, + FW_SPI_FLASH_PARAM_ERR, + FW_SPI_FLASH_UPG_ERR, + FW_SPI_FLASH_WR_LENGTH_ERR, + FW_SPI_FLASH_WR_ADDR_ERR, + FW_SPI_FLASH_SET_ACCESS_ERR, + FW_SPI_FLASH_DATA_CMP_ERR, + FW_SPI_FLASH_GET_INFO_ERR, + FW_SPI_FLASH_NOT_SUPPORT_TEST, +} firmware_spi_flash_rv_t; + +int fpga_test_spi_logic_flash(int argc, char *argv[]); + +#endif /* End of __FW_UPG_SPI_LOGIC_DEV_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/debug.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/debug.h new file mode 100644 index 000000000000..17dd42c3ef77 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/debug.h @@ -0,0 +1,34 @@ +/* + * + * debug.h + * firmware upgrade debug switch control + */ + +#ifndef __FIRMWARE_UPGRADE_DEBUG_H__ +#define __FIRMWARE_UPGRADE_DEBUG_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define DEBUG_INFO_LEN 20 +#define DEBUG_FILE "/tmp/.firmware_upgrade_debug" +#define DEBUG_ON_ALL "3" +#define DEBUG_ON_INFO "1" +#define DEBUG_OFF_INFO "0" + +enum debug_s { + DEBUG_OFF = 0, /* off debug */ + DEBUG_APP_ON, /* open app debug */ + DEBUG_ALL_ON, /* open all debug */ + DEBUG_IGNORE, /* ignore debug */ +}; + +#define dbg_print(debug, fmt, arg...) \ + if (debug == DEBUG_APP_ON || debug == DEBUG_ALL_ON) \ + { do{printf(fmt,##arg);} while(0); } + +/* firmware upgrade debug switch */ +extern int firmware_upgrade_debug(void); +extern int is_debug_on; + +#endif /* End of __FIRMWARE_UPGRADE_DEBUG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/firmware_app.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/firmware_app.h new file mode 100644 index 000000000000..581b2e969ec9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/firmware_app.h @@ -0,0 +1,172 @@ +#ifndef __FIRMWARE_APP_H__ +#define __FIRMWARE_APP_H__ + +#include +#include +#include +#include +#include +#include + +#define ERR_FW_CHECK_CPLD_UPGRADE (-601) /* File validation error */ +#define ERR_FW_CHECK_FPGA_UPGRADE (-602) +#define ERR_FW_MATCH_CPLD_UPGRADE (-603) /* No matching upgrade file found */ +#define ERR_FW_MATCH_FPGA_UPGRADE (-604) +#define ERR_FW_SAMEVER_CPLD_UPGRADE (-605) /* the same version */ +#define ERR_FW_SAMEVER_FPGA_UPGRADE (-606) +#define ERR_FW_DO_CPLD_UPGRADE (-607) /* upgrade fail */ +#define ERR_FW_DO_FPGA_UPGRADE (-608) +#define ERR_FW_UPGRADE (-609) /* other fail */ +#define ERR_FW_CHECK_UPGRADE (-610) /* File validation error */ +#define ERR_FW_MATCH_UPGRADE (-611) /* No matching upgrade file found */ +#define ERR_FW_SAMEVER_UPGRADE (-612) /* the same version */ +#define ERR_FW_DO_UPGRADE (-613) /* upgrade fail */ +#define ERR_FW_DO_UPGRADE_NOT_SUPPORT (-614) /* upgrade fail */ + +#define FIRMWARE_NOT_SUPPORT (-2) +#define FIRMWARE_FAILED (-1) +#define FIRMWARE_SUCCESS (0) + +#define FIRMWARE_ACTION_CHECK 0 +#define FIRMWARE_ACTION_MATCH 1 +#define FIRMWARE_ACTION_VERCHECK 2 +#define FIRMWARE_ACTION_UPGRADE 3 +#define FIRMWARE_ACTION_SUPPORT 4 + +#define FIRMWARE_UPGRADE_RETRY_CNT (10) +#define FIRMWARE_NAME_LEN (48) +#define FIRMWARE_SLOT_MAX_NUM (16) /* Maximum number of links supported by board cards */ + +/* Upgrade file headers */ +#define MAX_DEV_NUM 10 /* Maximum number of devices to which the upgrade file is applicable */ +#define INSMOD_DRIVER 1 /* insmod driver */ +#define RMMOD_DRIVER 0 /* rmmod driver */ +#define MAX_HEADER_SIZE 1000 /* Upgrade the maximum length of file header information */ +#define MAX_HEADER_KV_SIZE 64 /* Upgrade the maximum length of the file header key value */ + +/* Upgrade file header key values */ +#define FILEHEADER_DEVTYPE "DEVTYPE" +#define FILEHEADER_SUBTYPE "SUBTYPE" +#define FILEHEADER_TYPE "TYPE" +#define FILEHEADER_CHAIN "CHAIN" +#define FILEHEADER_CHIPNAME "CHIPNAME" +#define FILEHEADER_VERSION "VERSION" +#define FILEHEADER_FILETYPE "FILETYPE" +#define FILEHEADER_CRC "CRC" + +#define FIRMWARE_CPLD_NAME "cpld" +#define FIRMWARE_FPGA_NAME "fpga" + +/* ioctl publi command, the same as driver */ +#define FIRMWARE_COMMON_TYPE 'C' +#define FIRMWARE_GET_CHIPNAME _IOR(FIRMWARE_COMMON_TYPE, 0, char) /* get the chip name */ +#define FIRMWARE_GET_VERSION _IOR(FIRMWARE_COMMON_TYPE, 2, int) /* get version */ +#define FIRMWARE_SET_DEBUG_ON _IOW(FIRMWARE_COMMON_TYPE, 3, int) /* debug on */ +#define FIRMWARE_SET_DEBUG_OFF _IOW(FIRMWARE_COMMON_TYPE, 4, int) /* debug off */ + +/* firmware cpld driver ioctl command, the same as "firmware_driver\firmware_driver\include\firmware.h" */ +#define FIRMWARE_TYPE 'J' +#define FIRMWARE_PROGRAM _IOW(FIRMWARE_TYPE, 1, char) /* firmware upgrade ISC */ +#define FIRMWARE_READ_CHIP _IOR(FIRMWARE_TYPE, 5, int) /* read the contents of the chip */ +#define FIRMWARE_PROGRAM_JBI _IOW(FIRMWARE_TYPE, 6, char) /* firmware upgrade JBI */ + +/* firmware cpld ispvme driver ioctl command, the same as "firmware_driver\firmware_driver_ispvme\include\firmware_ispvme.h" */ +#define FIRMWARE_VME_TYPE 'V' +#define FIRMWARE_JTAG_TDI _IOR(FIRMWARE_VME_TYPE, 0, char) +#define FIRMWARE_JTAG_TDO _IOR(FIRMWARE_VME_TYPE, 1, char) +#define FIRMWARE_JTAG_TCK _IOR(FIRMWARE_VME_TYPE, 2, char) +#define FIRMWARE_JTAG_TMS _IOR(FIRMWARE_VME_TYPE, 3, char) +#define FIRMWARE_JTAG_EN _IOR(FIRMWARE_VME_TYPE, 4, char) +#define FIRMWARE_JTAG_INIT _IOR(FIRMWARE_VME_TYPE, 7, char) /* enable upgrade access */ +#define FIRMWARE_JTAG_FINISH _IOR(FIRMWARE_VME_TYPE, 8, char) /* disable upgrade access */ + +/* firmware sysfs driver ioctl command, the same as "firmware_driver\firmware_driver_sysfs\include\firmware_sysfs.h" */ +#define FIRMWARE_SYSFS_TYPE 'S' +#define FIRMWARE_SYSFS_INIT _IOR(FIRMWARE_SYSFS_TYPE, 0, char) /* enable upgrade access */ +#define FIRMWARE_SYSFS_FINISH _IOR(FIRMWARE_SYSFS_TYPE, 1, char) /* disable upgrade access */ +#define FIRMWARE_SYSFS_SPI_INFO _IOR(FIRMWARE_SYSFS_TYPE, 2, char) /* spi flash upgrade */ +#define FIRMWARE_SYSFS_DEV_FILE_INFO _IOR(FIRMWARE_SYSFS_TYPE, 3, char) /* sysfs upgrade */ +#define FIRMWARE_SYSFS_MTD_INFO _IOR(FIRMWARE_SYSFS_TYPE, 4, char) /* sysfs mtd upgrade */ + +/* VME file, used to distinguish the JTAG signal that needs to operate */ +#define JTAG_TDO 1 +#define JTAG_TCK 2 +#define JTAG_TDI 3 +#define JTAG_TMS 4 +#define JTAG_ENABLE 5 +#define JTAG_TRST 6 + +typedef struct name_info_s { + int card_type[MAX_DEV_NUM]; /* main board type */ + int sub_type[MAX_DEV_NUM]; /* sub board type */ + int type; /* device type */ + int chain; /* chain num */ + char chip_name[FIRMWARE_NAME_LEN]; /* chip name */ + char version[FIRMWARE_NAME_LEN]; /* version */ + int file_type; /* file type */ + unsigned int crc32; /* 4 byte CRC values */ +} name_info_t; + +typedef struct cmd_info_s { + uint32_t size; + void *data; +} cmd_info_t; + +enum firmware_type_s { + FIRMWARE_UNDEF_TYPE = 0, + FIRMWARE_CPLD, + FIRMWARE_FPGA, + FIRMWARE_SYSFS, + FIRMWARE_OTHER, +}; + +typedef enum firmware_file_type_s { + FIRMWARE_UNDEF_FILE_TYPE = 0, + FIRMWARE_VME, /* ispvme cpld, GPIO simulates JTAG */ + FIRMWARE_ISC, /* cpld, GPIO simulates JTAG */ + FIRMWARE_JBI, + FIRMWARE_SPI_LOGIC_DEV, /* FPGA SPI upgrde register upgrade flash */ + FIRMWARE_SYSFS_DEV, /* write file upgrade eeprom */ + FIRMWARE_MTD, /* upgrade mtd device */ + FIRMWARE_NONE, +} firmware_file_type_t; + +typedef struct firmware_file_name_s { + char firmware_file_name_str[MAX_HEADER_KV_SIZE]; + int firmware_file_type; +} firmware_file_name_t; + +extern int header_offset; + +/* CRC32 calculation */ +extern unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len); +/* VME file upgrade */ +extern int firmware_upgrade_ispvme(int file_fd, char *upgrade_file_name, name_info_t *info); +extern void writePort(unsigned char a_ucPins, unsigned char a_ucValue); +extern unsigned char readPort(); +extern void sclock(); +extern void ispVMStateMachine(signed char NextState); + +/* spi flash upgrade */ +extern int firmware_upgrade_spi_logic_dev(int fd, uint8_t *buf, uint32_t size, name_info_t *info); +/* spi flash upgrade test*/ +extern int firmware_upgrade_spi_logic_dev_test(int fd, name_info_t *info); +/* spi flash data print*/ +extern int firmware_upgrade_spi_logic_dev_dump(char *dev_name, uint32_t offset, uint32_t size, char *record_file); + +/* sysfs upgrade */ +extern int firmware_upgrade_sysfs(int fd, uint8_t *buf, uint32_t size, name_info_t *info); +/* sysfs upgrade test*/ +extern int firmware_upgrade_sysfs_test(int fd, name_info_t *info); + +/* isc upgrade */ +extern int firmware_upgrade_jtag(int fd, uint8_t *buf, uint32_t size, name_info_t *info); +/* isc upgrade test */ +extern int firmware_upgrade_jtag_test(int fd, uint8_t *buf, uint32_t size, name_info_t *info); + +/* mtd upgrade */ +extern int firmware_upgrade_mtd(int fd, uint8_t *buf, uint32_t size, name_info_t *info); +/* mtd upgrade test */ +extern int firmware_upgrade_mtd_test(int fd, name_info_t *info); + +#endif /* End of __FIRMWARE_APP_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/vmopcode.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/vmopcode.h new file mode 100644 index 000000000000..ae9d713ff86c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/vmopcode.h @@ -0,0 +1,192 @@ +/*************************************************************** +* +* This is the include file for Lattice Semiconductor's ispVM +* Embedded software application. +* +***************************************************************/ + +/*************************************************************** +* +* VME version. +* +* History: +* +***************************************************************/ + +#define VME_VERSION_NUMBER "12.2" + +/*************************************************************** +* +* Maximum declarations. +* +***************************************************************/ + +#define VMEHEXMAX 60000L /* The hex file is split 60K per file. */ +#define SCANMAX 64000L /* The maximum SDR/SIR burst. */ + +/*************************************************************** +* +* Supported JTAG state transitions. +* +***************************************************************/ + +#define RESET 0x00 +#define IDLE 0x01 +#define IRPAUSE 0x02 +#define DRPAUSE 0x03 +#define SHIFTIR 0x04 +#define SHIFTDR 0x05 +#define DRCAPTURE 0x06 + +/*************************************************************** +* +* Flow control register bit definitions. A set bit indicates +* that the register currently exhibits the corresponding mode. +* +***************************************************************/ + +#define INTEL_PRGM 0x0001 /* Intelligent programming is in effect. */ +#define CASCADE 0x0002 /* Currently splitting large SDR. */ +#define REPEATLOOP 0x0008 /* Currently executing a repeat loop. */ +#define SHIFTRIGHT 0x0080 /* The next data stream needs a right shift. */ +#define SHIFTLEFT 0x0100 /* The next data stream needs a left shift. */ +#define VERIFYUES 0x0200 /* Continue if fail is in effect. */ + +/*************************************************************** +* +* DataType register bit definitions. A set bit indicates +* that the register currently holds the corresponding type of data. +* +***************************************************************/ + +#define EXPRESS 0x0001 /* Simultaneous program and verify. */ +#define SIR_DATA 0x0002 /* SIR is the active SVF command. */ +#define SDR_DATA 0x0004 /* SDR is the active SVF command. */ +#define COMPRESS 0x0008 /* Data is compressed. */ +#define TDI_DATA 0x0010 /* TDI data is present. */ +#define TDO_DATA 0x0020 /* TDO data is present. */ +#define MASK_DATA 0x0040 /* MASK data is present. */ +#define HEAP_IN 0x0080 /* Data is from the heap. */ +#define LHEAP_IN 0x0200 /* Data is from intel data buffer. */ +#define VARIABLE 0x0400 /* Data is from a declared variable. */ +#define CRC_DATA 0x0800 /* CRC data is pressent. */ +#define CMASK_DATA 0x1000 /* CMASK data is pressent. */ +#define RMASK_DATA 0x2000 /* RMASK data is pressent. */ +#define READ_DATA 0x4000 /* READ data is pressent. */ +#define DMASK_DATA 0x8000 /* DMASK data is pressent. */ + +/*************************************************************** +* +* Pin opcodes. +* +***************************************************************/ + +#define signalENABLE 0x1C /* ispENABLE pin. */ +#define signalTMS 0x1D /* TMS pin. */ +#define signalTCK 0x1E /* TCK pin. */ +#define signalTDI 0x1F /* TDI pin. */ +#define signalTRST 0x20 /* TRST pin. */ + +/*************************************************************** +* +* Supported vendors. +* +***************************************************************/ + +#define VENDOR 0x56 +#define LATTICE 0x01 +#define ALTERA 0x02 +#define XILINX 0x03 + +/*************************************************************** +* +* Opcode definitions. +* +* Note: opcodes must be unique. +* +***************************************************************/ + +#define ENDDATA 0x00 /* The end of the current SDR data stream. */ +#define RUNTEST 0x01 /* The duration to stay at the stable state. */ +#define ENDDR 0x02 /* The stable state after SDR. */ +#define ENDIR 0x03 /* The stable state after SIR. */ +#define ENDSTATE 0x04 /* The stable state after RUNTEST. */ +#define TRST 0x05 /* Assert the TRST pin. */ +#define HIR 0x06 /* The sum of the IR bits of the leading devices. */ +#define TIR 0x07 /* The sum of the IR bits of the trailing devices. */ +#define HDR 0x08 /* The number of leading devices. */ +#define TDR 0x09 /* The number of trailing devices. */ +#define ispEN 0x0A /* Assert the ispEN pin. */ +#define FREQUENCY 0x0B /* The maximum clock rate to run the JTAG state machine. */ +#define STATE 0x10 /* Move to the next stable state. */ +#define SIR 0x11 /* The instruction stream follows. */ +#define SDR 0x12 /* The data stream follows. */ +#define TDI 0x13 /* The following data stream feeds into the device. */ +#define TDO 0x14 /* The following data stream is compared against the device. */ +#define MASK 0x15 /* The following data stream is used as mask. */ +#define XSDR 0x16 /* The following data stream is for simultaneous program and verify. */ +#define XTDI 0x17 /* The following data stream is for shift in only. It must be stored for the next XSDR. */ +#define XTDO 0x18 /* There is not data stream. The data stream was stored from the previous XTDI. */ +#define MEM 0x19 /* The maximum memory needed to allocate in order hold one row of data. */ +#define WAIT 0x1A /* The duration of delay to observe. */ +#define TCK 0x1B /* The number of TCK pulses. */ +#define SHR 0x23 /* Set the flow control register for right shift. */ +#define SHL 0x24 /* Set the flow control register for left shift. */ +#define HEAP 0x32 /* The memory size needed to hold one loop. */ +#define REPEAT 0x33 /* The beginning of the loop. */ +#define LEFTPAREN 0x35 /* The beginning of data following the loop. */ +#define VAR 0x55 /* Plac holder for loop data. */ +#define SEC 0x1C /* The delay time in seconds that must be observed. */ +#define SMASK 0x1D /* The mask for TDI data. */ +#define MAX 0x1E /* The absolute maximum wait time. */ +#define ON 0x1F /* Assert the targeted pin. */ +#define OFF 0x20 /* Dis-assert the targeted pin. */ +#define SETFLOW 0x30 /* Change the flow control register. */ +#define RESETFLOW 0x31 /* Clear the flow control register. */ +#define CRC 0x47 /* The following data stream is used for CRC calculation. */ +#define CMASK 0x48 /* The following data stream is used as mask for CRC calculation. */ +#define RMASK 0x49 /* The following data stream is used as mask for read and save. */ +#define READ 0x50 /* The following data stream is used for read and save. */ +#define ENDLOOP 0x59 /* The end of the repeat loop. */ +#define SECUREHEAP 0x60 /* Used to secure the HEAP opcode. */ +#define VUES 0x61 /* Support continue if fail. */ +#define DMASK 0x62 /* The following data stream is used for dynamic I/O. */ +#define COMMENT 0x63 /* Support SVF comments in the VME file. */ +#define HEADER 0x64 /* Support header in VME file. */ +#define FILE_CRC 0x65 /* Support crc-protected VME file. */ +#define LCOUNT 0x66 /* Support intelligent programming. */ +#define LDELAY 0x67 /* Support intelligent programming. */ +#define LSDR 0x68 /* Support intelligent programming. */ +#define LHEAP 0x69 /* Memory needed to hold intelligent data buffer */ +#define CONTINUE 0x70 /* Allow continuation. */ +#define LVDS 0x71 /* Support LVDS. */ +#define ENDVME 0x7F /* End of the VME file. */ +#define HIGH 0x80 /* Assert the targeted pin. */ +#define LOW 0x81 /* Dis-assert the targeted pin. */ +#define ENDFILE 0xFF /* End of file. */ + +/*************************************************************** +* +* ispVM Embedded Return Codes. +* +***************************************************************/ + +#define VME_VERIFICATION_FAILURE -1 +#define VME_FILE_READ_FAILURE -2 +#define VME_VERSION_FAILURE -3 +#define VME_INVALID_FILE -4 +#define VME_ARGUMENT_FAILURE -5 +#define VME_CRC_FAILURE -6 + +/*************************************************************** +* +* Type definitions. +* +***************************************************************/ + +/* Support LVDS */ +typedef struct { + unsigned short usPositiveIndex; + unsigned short usNegativeIndex; + unsigned char ucUpdate; +} LVDSPair; diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Makefile new file mode 100644 index 000000000000..1701b5f62114 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Makefile @@ -0,0 +1,18 @@ +top_srcdir:=$(shell pwd) +include $(top_srcdir)/Rules.mk + +firmware-y:= +firmware-y += fw_upgrade + +.PHONY: all +all: build + +.PHONY: build +build: $(firmware-y) +$(foreach dir,$(firmware-y),$(eval $(call compile_dirs,$(dir)))) + +.PHONY: rpmpkg +rpmpkg: +ifeq ("$(CONFIG_CPLD_UPGRADE_ISPVME)", "y") + #$(RPMPKG) $(install_cpld_dir) firmware-cpld-ispvme.spec git +endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Rules.mk b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Rules.mk new file mode 100644 index 000000000000..5fb5a09d34fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Rules.mk @@ -0,0 +1,42 @@ +CC ?= $(CROSS)gcc +AR ?= $(CROSS)ar +AS ?= $(CROSS)as +LD ?= $(CROSS)ld +STRIP ?= $(CROSS)strip + +install_root:=${top_srcdir}/images + +install_header_dir:=${install_root}/header +install_adir:=$(install_root)/lib +install_symbol_dir:=$(install_root)/symbol +symbol_files:=$(shell find $(EXPORT_SYMBOL) -name 'Module.symvers') +# +# symbol_files += $(shell find $(install_symbol_dir) -name 'Module.symvers') +# KBUILD_EXTRA_SYMBOLS += $(symbol_files) +# export KBUILD_EXTRA_SYMBOLS + +# top root: install_rootfs_dir +install_rootfs_dir:=$(install_root)/rootfs + +install_sodir:=$(install_rootfs_dir)/$(INSTALL_SODIR) + +install_usr_bin_dir:=$(install_rootfs_dir)/usr/bin +install_sbin_dir:=$(install_rootfs_dir)/sbin +install_etc_dir:=$(install_rootfs_dir)/etc + +export INSTALL_MOD_PATH:=$(ROOT) + +BUILD_CFLAGS:=$(CFLAGS) -I$(install_header_dir) +BUILD_LDFLAGS:=$(LDFLAGS) -L/$(install_sodir) -L/$(install_adir) + +define compile_dirs +.PHONY: $(1) +$(1): + @echo;echo "building $(1)..." + @$(MAKE) -C ${1} +endef + +compile.c = $(CC) $(BUILD_CFLAGS) -d -c -o $@ $< +%.o: %.c + $(compile.c) + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/Makefile new file mode 100644 index 000000000000..8b4bca739087 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/Makefile @@ -0,0 +1,39 @@ +include ../Rules.mk + +OBJ = fw_upgrade.o fw_upgrade_debug.o + +LIB += $(BUILD_CFALGS) $(BUILD_LDFLAGS) -lpthread +ifdef ENABLE_GCOV +ifeq ($(ENABLE_GCOV), y) +LIB += -fprofile-arcs +endif +endif # ENABLE_GCOV + +APP = fw_upgrade +BUILD_DIR = tmp +ELF_FILE = $(BUILD_DIR)/$(APP) +MAP_FILE = $(BUILD_DIR)/$(APP).map.sym +INCLUDE = -Iinclude +CFLAGS+=-Wall -W -g + +.PHONY: build +build:make-dir $(addprefix $(BUILD_DIR)/,$(OBJ)) + $(CC) -o $(ELF_FILE) $(addprefix $(BUILD_DIR)/,$(OBJ)) $(LINKFLAGS) $(LIB) + + cp -p $(ELF_FILE) $(common_out_put_dir) + +.PHONY: make-dir +make-dir: + @mkdir -p $(BUILD_DIR) + +$(BUILD_DIR)/%.o:%.c + $(CC) -c $(CFLAGS) $(INCLUDE) $< -o $@ + +.PHONY: install +install: + echo "fw_upgrade install success." + cp -p $(ELF_FILE) $(common_out_put_dir) + +.PHONY: clean +clean: + rm -rf $(BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c new file mode 100644 index 000000000000..2045608d5c3b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c @@ -0,0 +1,1632 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fw_upgrade.h" + +static flash_info_t flash_info[] = { + { + .flash_name = "M25L6433F", + .flash_size = M32, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX25L6433F, + .block_size = STEP_64, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "S25FL512S", + .flash_size = M64, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = S25FL512S, + .block_size = STEP_256, + .full_erase = 0, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "MX25l512", + .flash_size = M64, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX25l512, + .block_size = STEP_64, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "STM25P64", + .flash_size = M12, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = STM25P64, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "STM25P128", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = STM25P128, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "N25Q256", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = N25Q256, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "N25Q512", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = N25Q512, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25X16", + .flash_size = M3, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25X16, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25X64", + .flash_size = M12, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25X64, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25Q64BV", + .flash_size = M12, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25Q64BV, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25Q128BV", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25Q128BV, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25Q256FV", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25Q256FV, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "MX25L1605D", + .flash_size = M32, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX25L1605D, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "MX25L12805D", + .flash_size = M32, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX25L12805D, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "MX66L1G45G", + .flash_size = M128, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX66L1G45G, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "GD25Q256", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = GD25Q256, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, +}; + +static int debug_on; + +static void help(void) +{ + printf("------------------------------BMC Upgrade Tool--------------------------------\n"); + printf("Program Flash:\n"); + printf("\tfw_upgrade upgrade [file name] [chip select: 0 | 1 | 2] "); + printf("[erase type: full | block]\n"); + printf("\t[file name] if file is not located at /home/admin, path should be added\n"); + printf("\t[chip select] 0:master, 1:slave, 2:both\n"); + printf("\t[erase type] choose a way to erase chip, full erase would be faster\n"); + printf("Read BMC Reg:\n"); + printf("\tfw_upgrade rd [address] [length]\n"); + printf("\t[address(Hexadecimal)] register address of BMC\n"); + printf("\t[length(decimal)] length of read data, should be times of 4\n"); + + return; +} + +static int set_ioport_rw_access(void) +{ + + if ( iopl(3) < 0) { + printf("Can't get access to /dev/port \n"); + return -1; + } + + return 0; +} + +static int get_file_size(char *file_name) +{ + FILE * pFile; + int size; + + pFile = fopen(file_name,"rb"); + if (pFile == NULL) { + printf("Error opening file\n"); + return -1; + } + fseek (pFile, 0, SEEK_END); + size = ftell(pFile); + fclose (pFile); + return size; +} + +static uint8_t _read(uint16_t addr) +{ + return inb(addr); +} + +static void _write(uint16_t addr, uint8_t val) +{ + outb(val, addr); + + return; +} + +static void write_addr_port(uint8_t addr_val, uint16_t addr_port) +{ + _write(addr_port, addr_val); + + return; +} + +static void write_data_port(uint8_t val, uint16_t data_port) +{ + _write(data_port, val); + + return; +} + +static uint8_t read_data_port(uint16_t data_port) +{ + return _read(data_port); +} + +static void write_ilpc2ahb_addr(uint32_t addr) +{ + int i; + + for (i = 0; i < 4; i++) { + write_addr_port(SUPERIO_REG0 + i, LPC_ADDR_PORT); + write_data_port((addr >> (8 * (3 - i))) & MASK, LPC_DATA_PORT); + } + + return; +} + +static void write_ilpc2ahb_data(uint32_t data) +{ + int i; + + for (i = 0; i < 4; i++) { + write_addr_port(SUPERIO_REG4 + i, LPC_ADDR_PORT); + write_data_port((data >> (8 * (3 - i))) & MASK, LPC_DATA_PORT); + } + + return; +} + +static uint32_t read_ilpc2ahb_data(void) +{ + int i, tmp; + uint32_t res; + + res = 0; + for (i = 0; i < 4; i++) { + write_addr_port(SUPERIO_REG4 + i, LPC_ADDR_PORT); + tmp = read_data_port(LPC_DATA_PORT); + res |= (tmp << (8 * (3 - i))); + } + + return res; +} + +static void trigger_ilpc2ahb_read(void) +{ + write_addr_port(SUPERIO_FE, LPC_ADDR_PORT); + read_data_port(LPC_DATA_PORT); + + return; +} + +static void trigger_ilpc2ahb_write(void) +{ + write_addr_port(SUPERIO_FE, LPC_ADDR_PORT); + write_data_port(TOGGLE_WRITE, LPC_DATA_PORT); + + return; +} + +static uint32_t read_bmc_reg(uint32_t addr) +{ + uint32_t res; + + write_ilpc2ahb_addr(addr); + trigger_ilpc2ahb_read(); + res = read_ilpc2ahb_data(); + + return res; +} + +static void write_bmc_reg(uint32_t addr, uint32_t val) +{ + write_ilpc2ahb_addr(addr); + write_ilpc2ahb_data(val); + trigger_ilpc2ahb_write(); + + return; +} + +static uint32_t read_bmc_flash_data(void) +{ + uint32_t res; + + trigger_ilpc2ahb_read(); + res = read_ilpc2ahb_data(); + + return res; +} + +static void write_bmc_flash_data(uint32_t data) +{ + write_ilpc2ahb_data(data); + trigger_ilpc2ahb_write(); + + return; +} + +static void write_bmc_flash_addr(uint32_t addr) +{ + int i; + + for (i = 0; i < 4; i++) { + write_addr_port(SUPERIO_REG4 + i, LPC_ADDR_PORT); + write_data_port((addr >> (8 * i)) & MASK, LPC_DATA_PORT); + } + + trigger_ilpc2ahb_write(); + + return; +} + +static void enable_bytes(int byte) +{ + write_addr_port(SUPERIO_REG8, LPC_ADDR_PORT); + switch (byte) { + case BYTE1: + write_data_port(SUPERIO_A0 + BYTE1_VAL, LPC_DATA_PORT); + break; + case BYTE2: + write_data_port(SUPERIO_A0 + BYTE2_VAL, LPC_DATA_PORT); + break; + case BYTE4: + write_data_port(SUPERIO_A0 + BYTE4_VAL, LPC_DATA_PORT); + break; + default: + write_data_port(SUPERIO_A0 + BYTE_RESERVED, LPC_DATA_PORT); + break; + } + + return; +} + +static void pull_ce_down(flash_info_t* info) +{ + write_bmc_reg(info->ce_control_reg, USER_MODE_PULL_CE_DOWN); + + return; +} + +static void pull_ce_up(flash_info_t* info) +{ + write_bmc_reg(info->ce_control_reg, USER_MODE_PULL_CE_UP); + + return; +} + +static void send_cmd(uint32_t flash_base_addr, int cmd) +{ + write_ilpc2ahb_addr(flash_base_addr); + enable_bytes(1); + write_addr_port(SUPERIO_REG7, LPC_ADDR_PORT); + write_data_port(cmd & MASK, LPC_DATA_PORT); + trigger_ilpc2ahb_write(); + enable_bytes(4); + + return; +} + +static void send_cmd_to_flash(flash_info_t* info, int cmd) +{ + pull_ce_down(info); + send_cmd(info->flash_base_addr, cmd); + pull_ce_up(info); + + return; +} + +static void check_data_length(void) +{ + uint8_t tmp; + /* Data length check, 4 bytes */ + write_addr_port(SUPERIO_REG8, LPC_ADDR_PORT); + tmp = read_data_port(LPC_DATA_PORT); + if (tmp != SUPERIO_A2) { + write_data_port(SUPERIO_A2, LPC_DATA_PORT); + } + + return; +} + +static void enable_ilpc2ahb(void) +{ + /* Write 0xAA then write 0xA5 twice to enable super IO*/ + write_addr_port(DISABLE_LPC, LPC_ADDR_PORT); + write_addr_port(ENABLE_LPC, LPC_ADDR_PORT); + write_addr_port(ENABLE_LPC, LPC_ADDR_PORT); + + /* Enable iLPC2AHB */ + write_addr_port(SUPERIO_07, LPC_ADDR_PORT); + write_data_port(LPC_TO_AHB, LPC_DATA_PORT); + write_addr_port(SUPERIO_30, LPC_ADDR_PORT); + write_data_port(ENABLE_LPC_TO_AHB, LPC_DATA_PORT); + + /* Data length */ + check_data_length(); + + return; +} + +static void disable_ilpc2ahb(void) +{ + /* disable ilpc2ahb */ + write_addr_port(SUPERIO_30, LPC_ADDR_PORT); + write_data_port(DISABLE_LPC_TO_AHB, LPC_DATA_PORT); + /* disable super IO */ + write_addr_port(DISABLE_LPC, LPC_ADDR_PORT); + + return; +} + +/* Enable CPU */ +static void enable_cpu(void) +{ + /* unlock SCU register */ + write_bmc_reg(SCU_ADDR, UNLOCK_SCU_KEY); + /* enable ARM */ + write_bmc_reg(REBOOT_CPU_REGISTER, SET_BMC_CPU_BOOT); + /* lock SCU register */ + write_bmc_reg(SCU_ADDR, LOCK_SCU_KEY); + + return; +} + +/* diasble CPU */ +static void disable_cpu(void) +{ + uint32_t scu_hw_strap_val; + + /* unlock SCU register */ + write_bmc_reg(SCU_ADDR, UNLOCK_SCU_KEY); + /* disable ARM */ + scu_hw_strap_val = read_bmc_reg(HARDWARE_STRAP_REGISTER); + write_bmc_reg(HARDWARE_STRAP_REGISTER, scu_hw_strap_val |0x01); + /* lock SCU register */ + write_bmc_reg(SCU_ADDR, LOCK_SCU_KEY); + + return; +} + +static void enable_upgrade(void) +{ + + enable_ilpc2ahb(); + /* diasble CPU */ + disable_cpu(); + /* init CE control register */ + write_bmc_reg(CE0_CONTROL_REGISTER, 0); + write_bmc_reg(CE1_CONTROL_REGISTER, 0); + /* disable WDT2 */ + write_bmc_reg(WATCHDOG2_CONTROL, DISABLE_WATCHDOG); + + return; +} + +static void disable_upgrade(void) +{ + enable_cpu(); + dbg_print(debug_on, "DEBUG 0x%x\n", read_bmc_reg(HARDWARE_STRAP_REGISTER)); + disable_ilpc2ahb(); + + return; +} + +static void watchdog_status_debug(void) +{ + uint32_t watchdog_reg; + + /* Watchdog Control Register */ + watchdog_reg = read_bmc_reg(WATCHDOG2_CONTROL); + dbg_print(debug_on,"Watchdog Control Register: 0x%x\n", watchdog_reg); + dbg_print(debug_on,"Watchdog Enable Signal: 0x%x\n", watchdog_reg & BIT1); + dbg_print(debug_on,"Watchdog Reset SyS En: 0x%x\n", (watchdog_reg & BIT2) >> 1); + dbg_print(debug_on,"Watchdog Reset Mode: 0x%x\n", (watchdog_reg & (BIT6 | BIT7)) >> 5); + switch (watchdog_reg & (BIT6 | BIT7)) { + case SOC_SYS: + dbg_print(debug_on,"\tReset Mode En: SoC System\n"); + break; + case FULL_CHIP: + dbg_print(debug_on,"\tReset Mode En: Full Chip\n"); + break; + case ARM_CPU: + dbg_print(debug_on,"\tReset Mode En: ARM Cpu\n"); + break; + default: + break; + } + + /* Watchdog Timeout Status Register */ + watchdog_reg = read_bmc_reg(WATCHDOG2_TSR); + dbg_print(debug_on,"Watchdog Timeout Occur: 0x%x\n", watchdog_reg & BIT1); + dbg_print(debug_on,"Watchdog Boot from: CD%d\n", watchdog_reg & BIT2); + dbg_print(debug_on,"Watchdog Interrupt Occur: 0x%x\n", watchdog_reg & BIT3); + + return; +} + +/* CE Type Setting Register */ +static void ce_type_setting_debug(void) +{ + uint32_t fmc_reg; + + fmc_reg = read_bmc_reg(FMC_CE_TYPE_SETTING_REG); + if ((fmc_reg & CE0_SPI_TYPE) == SPI) { + dbg_print(debug_on,"CE0 Type Seeting: 0x%x, Type: SPI\n", fmc_reg & CE0_SPI_TYPE); + } else { + dbg_print(debug_on,"CE0 Type Seeting: 0x%x, Type: Unknown\n", fmc_reg & CE0_SPI_TYPE); + } + if (((fmc_reg & CE1_SPI_TYPE) >> BIT2) == SPI) { + dbg_print(debug_on,"CE1 Type Seeting: 0x%x, Type: SPI\n", (fmc_reg & CE1_SPI_TYPE) >> BIT2); + } else { + dbg_print(debug_on,"CE1 Type Seeting: 0x%x, Type: Unknown\n", (fmc_reg & CE1_SPI_TYPE) >> BIT2); + } + + return; +} +/* CE Control Register */ +static void ce_control_debug(void) +{ + uint32_t fmc_reg; + + fmc_reg = read_bmc_reg(CE_CONTROL_REGISTER); + dbg_print(debug_on,"CE0 Address Mode: 0x%x, Mode: %d Bytes\n", + fmc_reg & BIT1, (fmc_reg & BIT1) + 3); + dbg_print(debug_on,"CE1 Address Mode: 0x%x, Mode: %d Bytes\n", + (fmc_reg & BIT2) >> 1, ((fmc_reg & BIT2) >> 1) + 3); + + return; +} + +/* Interrupt Control & Status Register */ +static void irq_control_status_debug(void) +{ + uint32_t fmc_reg; + + fmc_reg = read_bmc_reg(INR_STATUS_CONTROL_REGISTER); + dbg_print(debug_on,"SPI Write Address Protected Interrupt EN: 0x%x\n", fmc_reg & BIT2); + dbg_print(debug_on,"SPI Command Abort Interrupt EN: 0x%x\n", fmc_reg & BIT3); + dbg_print(debug_on,"SPI Write Address Protected Status: 0x%x, Status: %s\n", + RIGHT_SHIFT_8(fmc_reg) & BIT2, (RIGHT_SHIFT_8(fmc_reg) & BIT2) == BIT2 ? "Occur" : "Normal"); + dbg_print(debug_on,"SPI Command Abort Status: 0x%x, Status: %s\n", + RIGHT_SHIFT_8(fmc_reg) & BIT3, (RIGHT_SHIFT_8(fmc_reg) & BIT3) == BIT3 ? "Occur" : "Normal"); + /*Clear Abnormal Status*/ + if ((RIGHT_SHIFT_8(fmc_reg) & BIT3) || (RIGHT_SHIFT_8(fmc_reg) & BIT2)) { + write_bmc_reg(INR_STATUS_CONTROL_REGISTER, CLEAR_INR_STATUS_CONTROL); + } + + return; +} + +/* Command Control Register */ +static void command_control_debug(void) +{ + uint32_t fmc_reg; + + fmc_reg = read_bmc_reg(COMMAND_CONTROL_REGISTER); + dbg_print(debug_on,"Data Byte Line 0: %s\n", ((fmc_reg & BIT4) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Data Byte Line 1: %s\n", ((fmc_reg & BIT3) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Data Byte Line 2: %s\n", ((fmc_reg & BIT2) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Data Byte Line 3: %s\n", ((fmc_reg & BIT1) != 0) ? "Disable" : "Enable"); + + dbg_print(debug_on,"Address Byte Line 0: %s\n", ((fmc_reg & BIT8) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Address Byte Line 1: %s\n", ((fmc_reg & BIT7) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Address Byte Line 2: %s\n", ((fmc_reg & BIT6) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Address Byte Line 3: %s\n", ((fmc_reg & BIT5) != 0) ? "Disable" : "Enable"); + + return; +} + +static void ce_control_reg_debug(void) +{ + uint32_t fmc_reg; + + /* CE0 Control Register */ + fmc_reg = read_bmc_reg(CE0_CONTROL_REGISTER); + switch (fmc_reg & (BIT1 | BIT2)){ + case NORMAL_READ: + dbg_print(debug_on,"CE0 Command Mode: Normal Read\n"); + break; + case READ_MODE: + dbg_print(debug_on,"CE0 Command Mode: Read Command\n"); + break; + case WRITE_MODE: + dbg_print(debug_on,"CE0 Command Mode: Write Command\n"); + break; + case USER_MODE: + dbg_print(debug_on,"CE0 Command Mode: User Mode\n"); + break; + default: + break; + } + switch((RIGHT_SHIFT_24(fmc_reg) & (BIT5 | BIT6 | BIT7))){ + case 0: + dbg_print(debug_on,"CE0 IO Mode: Single Mode\n"); + break; + case 2: + case 3: + dbg_print(debug_on,"CE0 IO Mode: Dual Mode\n"); + break; + default: + break; + } + + dbg_print(debug_on,"CE0 Inactive Pulse Width: %d HCLK\n", + DEFAULT_WIDTH - (RIGHT_SHIFT_24(fmc_reg) & (BIT1 | BIT2 | BIT3 | BIT4))); + dbg_print(debug_on,"CE0 Data Input Mode: %s Mode\n", (fmc_reg & BIT4) == 0 ? "Single" : "Dual"); + dbg_print(debug_on,"CE0 MSB | LSB: %s First\n", (fmc_reg & BIT6) == 0 ? "MSB" : "LSB"); + + /* CE1 Control Register */ + fmc_reg = read_bmc_reg(CE1_CONTROL_REGISTER); + switch (fmc_reg & (BIT1 | BIT2)){ + case NORMAL_READ: + dbg_print(debug_on,"CE1 Command Mode: Normal Read\n"); + break; + case READ_MODE: + dbg_print(debug_on,"CE1 Command Mode: Read Command\n"); + break; + case WRITE_MODE: + dbg_print(debug_on,"CE1 Command Mode: Write Command\n"); + break; + case USER_MODE: + dbg_print(debug_on,"CE1 Command Mode: User Mode\n"); + break; + default: + break; + } + switch((RIGHT_SHIFT_24(fmc_reg) & (BIT5 | BIT6 | BIT7))){ + case 0: + dbg_print(debug_on,"CE1 IO Mode: Single Mode\n"); + break; + case 2: + case 3: + dbg_print(debug_on,"CE1 IO Mode: Dual Mode\n"); + break; + default: + break; + } + + dbg_print(debug_on,"CE1 Inactive Pulse Width: %d HCLK\n", + DEFAULT_WIDTH - (RIGHT_SHIFT_24(fmc_reg) & (BIT1 | BIT2 | BIT3 | BIT4))); + dbg_print(debug_on,"CE1 Data Input Mode: %s Mode\n", (fmc_reg & BIT4) == 0 ? "Single" : "Dual"); + dbg_print(debug_on,"CE1 MSB | LSB: %s First\n", (fmc_reg & BIT6) == 0 ? "MSB" : "LSB"); + + return; +} + +static void fmc_debug(void) +{ + ce_type_setting_debug(); + ce_control_debug(); + irq_control_status_debug(); + command_control_debug(); + ce_control_reg_debug(); + + return; +} + +/* Enable WatchDog to reset BMC*/ +static void enable_watchdog(int cs) +{ + uint32_t enable_watch_cmd; + + enable_watch_cmd = (cs == CE0) ? ENABLE_WATCHDOG : ENABLE_WATCHDOG | BOOT_DEFAULT_MASK; + write_bmc_reg(WATCHDOG2_CLEAR_STATUS, CLEAR_WATCHDOG_STATUS); + write_bmc_reg(WATCHDOG2_RESET_FUN_MASK, WATCHDOG_GATEMASK); + write_bmc_reg(WATCHDOG2_RELOAD_VALUE, WATCHDOG_NEW_COUNT); + write_bmc_reg(WATCHDOG2_COUNTER_RST, WATCHDOG_RELOAD_COUNTER); + write_bmc_reg(WATCHDOG2_CONTROL, enable_watch_cmd); + + return; +} + +static void bmc_reboot(int cs) +{ + enable_watchdog(cs); + watchdog_status_debug(); + disable_upgrade(); + printf("Upgrade-Complete, BMC rebooting...\n"); + + return; +} + +static int get_current_bmc(void) +{ + return (read_bmc_reg(WATCHDOG2_TSR) & 0x02) >> 1; +} + +static void get_flash_base_and_ce_ctrl(int current_bmc, int cs, uint32_t *flash_base_addr, uint32_t *ce_ctrl_addr) +{ + uint32_t ce0_addr_range_reg_val, ce0_decode_addr; + uint32_t ce1_addr_range_reg_val, ce1_decode_addr; + + ce0_addr_range_reg_val = read_bmc_reg(CE0_ADDRESS_RANGE_REGISTER); + ce0_decode_addr = SEGMENT_ADDR_START(ce0_addr_range_reg_val); + ce1_addr_range_reg_val = read_bmc_reg(CE1_ADDRESS_RANGE_REGISTER); + ce1_decode_addr = SEGMENT_ADDR_START(ce1_addr_range_reg_val); + dbg_print(debug_on,"CE0 addr decode range reg value:0x%08x, decode addr:0x%08x.\n", + ce0_addr_range_reg_val, ce0_decode_addr); + dbg_print(debug_on,"CE1 addr decode range reg value:0x%08x, decode addr:0x%08x.\n", + ce1_addr_range_reg_val, ce1_decode_addr); + + if (((current_bmc == CURRENT_MASTER) && (cs ==CE0)) || ((current_bmc == CURRENT_SLAVE) && (cs ==CE1))) { + *ce_ctrl_addr = CE0_CONTROL_REGISTER; + *flash_base_addr = ce0_decode_addr; + } else { + *ce_ctrl_addr = CE1_CONTROL_REGISTER; + *flash_base_addr = ce1_decode_addr; + } + + return; +} + +static int get_flash_id(uint32_t flash_base_addr, uint32_t ce_ctrl_addr) +{ + uint32_t origin_flash_id, flash_id; + + write_bmc_reg(ce_ctrl_addr, USER_MODE_PULL_CE_DOWN); + send_cmd(flash_base_addr, READID); + origin_flash_id = read_bmc_flash_data(); + write_bmc_reg(ce_ctrl_addr, USER_MODE_PULL_CE_UP); + flash_id = origin_flash_id & 0xFFFFFF; + dbg_print(debug_on,"origin flash id:0x%x, flash id:0x%x\n", origin_flash_id, flash_id); + + return flash_id; +} + +static uint8_t get_flash_status(flash_info_t* info) +{ + uint8_t flash_status; + + pull_ce_down(info); + + send_cmd(info->flash_base_addr, READ_FLASH_STATUS); + + flash_status = read_bmc_flash_data() & MASK; + pull_ce_up(info); + + dbg_print(debug_on,"get_flash_status:0x%x\n", flash_status); + return flash_status; +} + +static int check_flash_write_enable(flash_info_t* info) +{ + uint8_t flash_status; + int i, count; + + count = FLASH_WEL_TIMEOUT / FLASH_WEL_SLEEP_TIME; + for (i = 0; i <= count; i++) { + flash_status = get_flash_status(info); + if ((flash_status & FLASH_WRITE_ENABLE_MASK) != FLASH_WRITE_ENABLE_MASK) { + usleep(FLASH_WEL_SLEEP_TIME); + } else { + dbg_print(debug_on,"Check flash WEL success, RDSR:0x%x\n", flash_status); + return 0; + } + } + printf("Check flash WEL timeout, RDSR:0x%x\n", flash_status); + return -1; +} + +static int check_flash_write_process(flash_info_t* info, int timeout, int sleep_time) +{ + int i, count; + uint8_t flash_status; + + count = timeout / sleep_time; + for (i = 0; i <= count; i++) { + flash_status = get_flash_status(info); + if ((flash_status & FLASH_WIP_MASK) != 0) { + usleep(sleep_time); + } else { + dbg_print(debug_on,"Check flash WIP success, RDSR:0x%x\n", flash_status); + return 0; + } + } + printf("Check flash WIP timeout, RDSR:0x%x.\n", flash_status); + return -1; +} + +static int flash_write_enable(flash_info_t* info) +{ + int ret; + + send_cmd_to_flash(info, WRITE_ENABLE_FLASH); + ret = check_flash_write_enable(info); + if (ret < 0) { + return -1; + } + return 0; +} + +static void send_block_erase_cmd(flash_info_t* info, uint32_t block_addr) +{ + pull_ce_down(info); + send_cmd(info->flash_base_addr, info->erase_block_command); + write_bmc_flash_addr(block_addr); /* Erase Block addr */ + pull_ce_up(info); + + return; +} + +static void send_chip_erase_cmd(flash_info_t* info) +{ + send_cmd_to_flash(info, CHIP_ERASE_FLASH); + + return; +} + +static int write_bmc_flash_page(flash_info_t* info, uint32_t page_addr, uint8_t *p, int len) +{ + int pos; + + if (len % 4) { + printf("Page size %d invalid.\n", len); + return -1; + } + + pos = 0; + pull_ce_down(info); + send_cmd(info->flash_base_addr, info->page_program); + write_bmc_flash_addr(page_addr); /* page address */ + while (len) { + write_bmc_flash_data((*(uint32_t *)(p + pos))); + pos += 4; + len -= 4; + } + pull_ce_up(info); + + return 0; +} + +static int erase_chip_full(flash_info_t* info) +{ + time_t timep; + int ret; + + if (info->full_erase == 0) { + printf("Flash not support full erase function.\n"); + return -1; + } + + ret = flash_write_enable(info); + if(ret < 0) { + printf("Chip erase, enable flash write error.\n"); + return -1; + } + + time(&timep); + printf("Full chip erasing, please wait...\n"); + dbg_print(debug_on,"Erase Start-%s\n",asctime(gmtime(&timep))); + send_chip_erase_cmd(info); + ret = check_flash_write_process(info, CHIP_ERASE_TIMEOUT, CHIP_ERASE_SLEEP_TIME); + if (ret < 0) { + printf("Chip erase timeout.\n"); + return -1; + } + time(&timep); + dbg_print(debug_on,"Erase Finish-%s\n",asctime(gmtime(&timep))); + printf("Erase Finish\n"); + printf("=========================================\n"); + return 0; +} + +static int erase_chip_block(flash_info_t* info) +{ + uint32_t block_addr, end_addr; + time_t timep; + int ret; + + printf("Block erasing...\n"); + time (&timep); + dbg_print(debug_on,"Erase-Start-%s\n", asctime(gmtime(&timep))); + end_addr = info->flash_base_addr + info->flash_size; + block_addr = info->flash_base_addr; + while (1) { + /* Enable write */ + ret = flash_write_enable(info); + if(ret < 0) { + printf("Block erase, enable flash write error, block addr:0x%x\n", block_addr); + return -1; + } + + send_block_erase_cmd(info, block_addr); + /* Erase Block(64KB) MAX time 650ms*/ + ret = check_flash_write_process(info, BLOCK_ERASE_TIMEOUT, BLOCK_ERASE_SLEEP_TIME); + if (ret < 0) { + printf("Block erase, check write status error, block addr:0x%x\n", block_addr); + return -1; + } + printf("\r0x%x", block_addr); + fflush(stdout); + if (block_addr >= end_addr) { + time(&timep); + printf("\r\nErase Finish\n"); + printf("=========================================\n"); + dbg_print(debug_on,"\nEnd-Earse-%s\n",asctime(gmtime(&timep))); + break; + } + block_addr += info->block_size; + } + return 0; +} + +static int program_chip(uint32_t file_size, uint8_t *p, flash_info_t* info) +{ + time_t timep; + uint32_t page_addr, end_addr; + int ret, page_size; + + page_addr = info->flash_base_addr; + page_size = info->page_size; + end_addr = file_size + info->flash_base_addr; + time (&timep); + printf("Programming...\n"); + dbg_print(debug_on,"Program Start-%s\n",asctime(gmtime(&timep))); + /* Debug info */ + fmc_debug(); + while (1) { + /* Write enable */ + ret = flash_write_enable(info); + if(ret < 0) { + printf("Page program, enable flash write error, page addr:0x%x\n", page_addr); + return -1; + } + ret = write_bmc_flash_page(info, page_addr, p, page_size); + if (ret < 0) { + printf("Page program, write bmc flash page error, page addr:0x%x\n", page_addr); + return -1; + } + /* page program MAX time 1.5ms */ + ret = check_flash_write_process(info, PAGE_PROGRAM_TIMEOUT, PAGE_PROGRAM_SLEEP_TIME); + if (ret < 0) { + printf("Page program, check write status error, page addr:0x%x\n", page_addr); + return -1; + } + page_addr += page_size; + p += page_size; + if ((page_addr % 0x10000) == 0) { + printf("\r0x%x", page_addr); + fflush(stdout); + } + + if (page_addr >= end_addr) { + printf("\nProgram Finish\n"); + printf("=========================================\n"); + time(&timep); + dbg_print(debug_on,"\nProgram-End-%s\n",asctime(gmtime(&timep))); + break; + } + } /* End of while (1) */ + return 0; +} + +static int check_chip(uint32_t file_size, uint8_t *p, flash_info_t* info) +{ + time_t timep; + uint32_t offset_addr, rd_val, end_addr; + int pos; + + offset_addr = info->flash_base_addr; + end_addr = file_size + info->flash_base_addr; + pos=0; + /* Checking */ + time(&timep); + printf("Checking...\n"); + dbg_print(debug_on,"Checking-Start-%s\n",asctime(gmtime(&timep))); + + pull_ce_down(info); + send_cmd(info->flash_base_addr, COMMON_FLASH_READ); + write_bmc_flash_addr(info->flash_base_addr); + while (1) { + if (offset_addr >= end_addr) { + break; + } + rd_val = read_bmc_flash_data(); + if (rd_val != (*(uint32_t *)(p + pos))) { + printf("Check Error at 0x%08x\n", offset_addr); + printf("READ:0x%08x VALUE:0x%08x\n", rd_val, (*(uint32_t *)(p + pos))); + pull_ce_up(info); + return -1; + } + if ((offset_addr % 0x10000) == 0) { + printf("\r0x%x ", offset_addr); + fflush(stdout); + } + offset_addr += 4; + pos += 4; + } + pull_ce_up(info); + printf("\r\nFlash Checked\n"); + printf("=========================================\n"); + time(&timep); + dbg_print(debug_on,"Checking-End-%s\n",asctime(gmtime(&timep))); + return 0; +} + +flash_info_t* get_flash_info(int current_bmc, int cs) +{ + int i, size; + uint32_t flash_base_addr, ce_ctrl_addr, flash_id; + + get_flash_base_and_ce_ctrl(current_bmc, cs, &flash_base_addr, &ce_ctrl_addr); + + size = (sizeof(flash_info) / sizeof((flash_info)[0])); + + flash_id = get_flash_id(flash_base_addr, ce_ctrl_addr); + for (i = 0; i < size; i++) { + if (flash_info[i].flash_id == flash_id) { + flash_info[i].flash_base_addr = flash_base_addr; + flash_info[i].ce_control_reg = ce_ctrl_addr; + flash_info[i].cs = cs; + return &flash_info[i]; + } + } + printf("Cannot get flash info, cs:%d, flash base addr:0x%x, ce control addr:0x%x, flash_id:0x%x.\n", + cs, flash_base_addr, ce_ctrl_addr, flash_id); + return NULL; +} + +static void init_flash(flash_info_t* info) +{ + send_cmd_to_flash(info, RSTEN); + send_cmd_to_flash(info, RST); + send_cmd_to_flash(info, EXIT_OTP); + send_cmd_to_flash(info, ENABLE_BYTE4); + + return; +} + +static int upgrade_bmc_core(char *file_name, int erase_type, flash_info_t* info) +{ + int file_size, fp, ret; + uint8_t *p; + + file_size = get_file_size(file_name); + if (file_size < 0) { + printf("file size %d Error\n", file_size); + return -1; + } + + fp = open(file_name, O_RDWR); + if (fp < 0) { + printf("Cannot open %s.\n", file_name); + return -1; + } + + p = mmap(NULL, file_size, PROT_READ, MAP_SHARED, fp, 0); + if (p == MAP_FAILED) { + printf("Could not mmap %s, error(%s).\n", file_name, strerror(errno)); + close(fp); + return -1; + } + + printf("* CE%d FLASH TYPE: SPI FLASH\n", info->cs); + printf("* FLASH NAME: %s\n", info->flash_name); + printf("* File Size:%d, 0x%x\n", file_size, file_size); + printf("=========================================\n"); + + /* Select erase type */ + switch (erase_type) { + case FULL_ERASE: + ret = erase_chip_full(info); + break; + case BLOCK_ERASE: + ret = erase_chip_block(info); + break; + default: + printf("Unsupport earse type:%d\n", erase_type); + goto exit; + break; + } + + if (ret < 0) { + printf("Erase Chip Error\n"); + goto exit; + } + + /* Program the flash */ + ret = program_chip(file_size, p, info); + if(ret < 0) { + printf("Program Chip Error\n"); + goto exit; + } + /* Check */ + ret = check_chip(file_size, p, info); + if(ret < 0) { + printf("Check Chip Error\n"); + goto exit; + } + + munmap(p, file_size); + close(fp); + return 0; +exit: + munmap(p, file_size); + close(fp); + return -1; +} + +static int upgrade_bmc_flash(char *filename, int current_bmc, int cs, int erase_type) +{ + int ret; + flash_info_t* info; + + info = get_flash_info(current_bmc, cs); + if(info == NULL) { + return -1; + } + + init_flash(info); + + ret = upgrade_bmc_core(filename, erase_type, info); + + return ret; +} + +static int upgrade_both_flash(char *filename, int erase_type) +{ + int ret, current_bmc; + + enable_upgrade(); + + current_bmc = get_current_bmc(); + if (current_bmc == CURRENT_MASTER) { + printf("* Current Bmc Default Boot: CE0\n"); + } else { + printf("* Current Bmc Default Boot: CE1\n"); + } + + ret = upgrade_bmc_flash(filename, current_bmc, CE0, erase_type); + if (ret < 0) { + printf("Upgrade master bmc flash failed, stop upgrade.\n"); + goto err; + } + printf("Upgrade master bmc flash success.\n"); + + ret = upgrade_bmc_flash(filename, current_bmc, CE1, erase_type); + if (ret < 0) { + printf("Upgrade slave bmc flash failed.\n"); + goto err; + } + printf("Upgrade slave bmc flash success.\n"); + + bmc_reboot(CE0); + return 0; +err: + disable_upgrade(); + return -1; +} + +static int upgrade_single_flash(char *filename, int cs, int erase_type) +{ + int ret, current_bmc; + + enable_upgrade(); + + current_bmc = get_current_bmc(); + if (current_bmc == CURRENT_MASTER) { + printf("* Current Bmc Default Boot: CE0\n"); + } else { + printf("* Current Bmc Default Boot: CE1\n"); + } + + ret = upgrade_bmc_flash(filename, current_bmc, cs, erase_type); + if (ret < 0) { + printf("Upgrade %s bmc flash failed.\n", cs == 0 ? "master":"slave"); + goto err; + } + printf("Upgrade %s bmc flash success.\n", cs == 0 ? "master":"slave"); + + bmc_reboot(cs); + return 0; +err: + disable_upgrade(); + return -1; +} + +static int upgrade_bmc(char *filename, int cs, int erase_type) +{ + int ret; + + if (access(filename, F_OK) < 0) { + printf("Can't find file\n"); + help(); + return -1; + } + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + switch(cs) { + /* Single */ + case CE0: + case CE1: + ret = upgrade_single_flash(filename, cs, erase_type); + break; + /* Both */ + case BOTHFLASH: + ret = upgrade_both_flash(filename, erase_type); + break; + default: + ret = -1; + printf("Unsupport cs:%d\n", cs); + break; + } + + return ret; +} + +static int read_single_bmc_flash(flash_info_t* info, uint32_t start_addr, int read_size, int is_print) +{ + uint32_t res, flash_start_addr, flash_end_addr; + char filename[MAX_FILENAME_LENGTH]; + int fd, ret; + + flash_start_addr = info->flash_base_addr + start_addr; + flash_end_addr = flash_start_addr + read_size; + ret = 0; + fd = 0; + if (!is_print) { + mem_clear(filename, MAX_FILENAME_LENGTH); + snprintf(filename, MAX_FILENAME_LENGTH, "/tmp/image-bmc%d", info->cs); + fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRWXG|S_IRWXU|S_IRWXO); + if (fd < 0) { + printf("open file %s fail(err:%d)!\r\n", filename, errno); + return -1; + } + } + + printf("* CE%d FLASH TYPE: SPI FLASH\n", info->cs); + printf("* FLASH NAME: %s\n", info->flash_name); + printf("* Read flash addr:0x%x, size:0x%x\n", flash_start_addr, read_size); + printf("=========================================\n"); + printf("Reading...\n"); + + pull_ce_down(info); + send_cmd(info->flash_base_addr, COMMON_FLASH_READ); + write_bmc_flash_addr(flash_start_addr); + while (1) { + if (flash_start_addr >= flash_end_addr) { + break; + } + res = read_bmc_flash_data(); + if (is_print) { + printf("addr:0x%08x, val:0x%08x\n", flash_start_addr, res); + } else { + ret = write(fd, &res, sizeof(res)); + if (ret < 0) { + printf("write failed (errno: %d).\n", errno); + ret = -1; + goto exit; + } + } + if (((flash_start_addr % 0x10000) == 0) && (!is_print)) { + printf("\r0x%x ", flash_start_addr); + fflush(stdout); + } + flash_start_addr += 4; + } + printf("\r\nRead Finish\n"); + printf("=========================================\n"); +exit: + pull_ce_up(info); + if (fd > 0) { + close(fd); + } + return ret; +} + +static int read_bmc_flash(int cs, uint32_t start_addr, int read_size, int is_print) +{ + int ret, current_bmc; + flash_info_t* info; + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + enable_upgrade(); + + current_bmc = get_current_bmc(); + if (current_bmc == CURRENT_MASTER) { + printf("* Current Bmc Default Boot: CE0\n"); + } else { + printf("* Current Bmc Default Boot: CE1\n"); + } + + info = get_flash_info(current_bmc, cs); + if(info == NULL) { + goto err; + } + + if (start_addr >= info->flash_size) { + printf("start_addr 0x%x out of range.\n", start_addr); + goto err; + } + + if ((start_addr + read_size) > info->flash_size) { + printf("read size %d exceed flash size.\n", read_size); + read_size = info->flash_size - start_addr; + } + + init_flash(info); + + ret = read_single_bmc_flash(info, start_addr, read_size, is_print); + if (ret < 0) { + printf("Read %s bmc flash failed.\n", cs == 0 ? "master" : "slave"); + goto err; + } + disable_upgrade(); + return 0; +err: + disable_upgrade(); + return -1; +} + +static int read_bmc_reg_main(int argc, char* argv[]) +{ + uint32_t start_addr, read_val; + int read_size, ret; + char *stopstring; + + if (argc != 4) { + printf("Input invalid.\n"); + help(); + return -1; + } + + start_addr = strtoul(argv[2], &stopstring, 16); + read_size = strtol(argv[3], &stopstring, 10); + + if (read_size <= 0) { + printf("read length %d invalid\n", read_size); + return -1; + } + + if (((start_addr % 4) != 0) || ((read_size % 4) != 0)) { + printf("Params invalid, start_addr:0x%08x, read_size:%d\n", start_addr, read_size); + printf("Please input address/length times of 4\n"); + return -1; + } + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + enable_ilpc2ahb(); + + printf("read bcm reg, start_addr:0x%08x, read length:%d\n", start_addr, read_size); + printf("===Addr=== | ===Cont===\n"); + while (read_size) { + read_val = read_bmc_reg(start_addr); + printf("0x%08x | 0x%08x\n", start_addr, read_val); + start_addr += 4; + read_size -= 4; + } + + disable_ilpc2ahb(); + return 0; +} + +static int write_bmc_reg_main(int argc, char* argv[]) +{ + uint32_t addr, wr_val; + int ret; + char *stopstring; + + if (argc != 4) { + printf("Input invalid.\n"); + help(); + return -1; + } + + addr = strtoul(argv[2], &stopstring, 16); + wr_val = strtoul(argv[3], &stopstring, 16); + + if (((addr & MASK_BYTE) != REGISTER_HEAD) || ((addr % 4) != 0)) { + printf("Address[0x%08x] invalid, address should be register address and times of 4.\n", addr); + return -1; + } + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + printf("write bcm reg, addr:0x%08x, val:0x%08x\n", addr, wr_val); + + enable_ilpc2ahb(); + write_bmc_reg(addr, wr_val); + disable_ilpc2ahb(); + + return 0; +} + +static int get_fmc_info_main(void) +{ + int ret; + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + enable_ilpc2ahb(); + + debug_on = 3; + fmc_debug(); + debug_on = 0; + + disable_ilpc2ahb(); + return 0; +} + +static int program_flash_main(int argc, char* argv[]) +{ + int cs, erase_way, ret; + char *stopstring; + char tmp[128]; + + if (argc != 5) { + printf("Input invalid.\n"); + help(); + return -1; + } + + cs = strtol(argv[3], &stopstring, 10); + if ((strlen(stopstring) != 0) || cs < 0 || cs > 2) { + snprintf(tmp, sizeof(tmp), "%s", argv[3]); + printf("Incorrect chip select %s\n", tmp); + help(); + return -1; + } + + if (strcmp(argv[4], "full") == 0) { + erase_way = FULL_ERASE; + } else if (strcmp(argv[4], "block") == 0) { + erase_way = BLOCK_ERASE; + } else { + snprintf(tmp, sizeof(tmp), "%s", argv[4]); + printf("Incorrect erase type %s\n", tmp); + help(); + return -1; + } + + printf("============BMC Upgrade Tool=============\n"); + ret = upgrade_bmc(argv[2], cs, erase_way); + return ret; +} + +static int read_bmc_flash_main(int argc, char* argv[]) +{ + int cs, ret, read_size, is_print; + uint32_t start_addr; + char *stopstring; + char tmp[128]; + + if (argc != 6) { + printf("Input invalid.\n"); + help(); + return -1; + } + + cs = strtol(argv[2], &stopstring, 10); + if ((strlen(stopstring) != 0) || cs < 0 || cs > 1) { + snprintf(tmp, sizeof(tmp), "%s", argv[2]); + printf("Incorrect chip select %s\n", tmp); + help(); + return -1; + } + + start_addr = strtoul(argv[3], &stopstring, 16); + read_size = strtol(argv[4], &stopstring, 10); + + if (read_size <= 0) { + printf("read length %d invalid\n", read_size); + return -1; + } + + if (((start_addr % 4) != 0) || ((read_size % 4) != 0)) { + printf("Params invalid, start_addr:0x%08x, read_size:%d\n", start_addr, read_size); + printf("Please input address/length times of 4\n"); + return -1; + } + + if (strcmp(argv[5], "print") == 0) { + is_print = 1; + } else { + is_print = 0; + } + + printf("============READ BMC FLASH=============\n"); + ret = read_bmc_flash(cs, start_addr, read_size, is_print); + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret; + + debug_on = fw_upgrade_debug(); + + if (argc < 2) { + help(); + return -1; + } + + if (argc == 2) { + if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { + help(); + return 0; + } + } + + if (strcmp(argv[1], "rd") == 0) { + ret = read_bmc_reg_main(argc, argv); + if (ret < 0) { + printf("Read Failed\n"); + } + return ret; + } + + if (strcmp(argv[1], "wr") == 0 && debug_on == 3) { + ret = write_bmc_reg_main(argc, argv); + if (ret < 0) { + printf("Write Failed\n"); + } + return ret; + } + + if (strcmp(argv[1], "info") == 0) { + ret = get_fmc_info_main(); + if (ret < 0) { + printf("Get fmc info Failed\n"); + } + return ret; + } + + if (strcmp(argv[1], "upgrade") == 0) { + ret = program_flash_main(argc, argv); + if (ret < 0) { + printf("Upgrade BMC failed.\n"); + } + return ret; + } + + if (strcmp(argv[1], "read_bmc_flash") == 0) { + ret = read_bmc_flash_main(argc, argv); + if (ret < 0) { + printf("Read BMC flash failed.\n"); + } + return ret; + } + + printf("Input invalid.\n"); + help(); + + return -1; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c new file mode 100644 index 000000000000..a7a78d011011 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "fw_upgrade_debug.h" + +int fw_upgrade_debug(void) +{ + int size; + FILE *fp; + char debug_info[DEBUG_INFO_LEN]; + + fp = fopen(DEBUG_FILE, "r"); + if (fp == NULL) { + return DEBUG_IGNORE; + } + + mem_clear(debug_info, DEBUG_INFO_LEN); + size = fread(debug_info, DEBUG_INFO_LEN - 1, 1, fp); + if (size < 0) { + fclose(fp); + return DEBUG_IGNORE; + } + + if (strncmp(debug_info, DEBUG_ON_INFO, 1) == 0) { + fclose(fp); + return DEBUG_APP_ON; + } + + if (strncmp(debug_info, DEBUG_ON_KERN, 1) == 0) { + fclose(fp); + return DEBUG_KERN_ON; + } + + if (strncmp(debug_info, DEBUG_ON_ALL, 1) == 0) { + fclose(fp); + return DEBUG_ALL_ON; + } + + if (strncmp(debug_info, DEBUG_OFF_INFO, 1) == 0) { + fclose(fp); + return DEBUG_OFF; + } + + fclose(fp); + return DEBUG_IGNORE; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h new file mode 100644 index 000000000000..bd806a94b154 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h @@ -0,0 +1,230 @@ +#ifndef _FW_UPGRADE_H_ +#define _FW_UPGRADE_H_ + +#include "fw_upgrade_debug.h" + +#define dbg_print(debug, fmt, arg...) \ + if (debug == DEBUG_APP_ON || debug == DEBUG_ALL_ON) \ + { do{printf(fmt,##arg);} while(0); } + +/* LPC Interface */ +#define LPC_ADDR_PORT (0x4E) +#define LPC_DATA_PORT (0x4F) + +/* FMC REGISTER ADDR */ +#define FMC_BASE_ADDR (0x1E620000) +#define FMC_CE_TYPE_SETTING_REG (FMC_BASE_ADDR + 0x00) +#define CE_CONTROL_REGISTER (FMC_BASE_ADDR + 0x04) +#define INR_STATUS_CONTROL_REGISTER (FMC_BASE_ADDR + 0x08) +#define COMMAND_CONTROL_REGISTER (FMC_BASE_ADDR + 0x0C) +#define CE0_CONTROL_REGISTER (FMC_BASE_ADDR + 0x10) +#define CE1_CONTROL_REGISTER (FMC_BASE_ADDR + 0x14) +#define CE0_ADDRESS_RANGE_REGISTER (FMC_BASE_ADDR + 0x30) +#define CE1_ADDRESS_RANGE_REGISTER (FMC_BASE_ADDR + 0x34) + +/* SCU REGISTER ADDR */ +#define SCU_ADDR (0x1E6E2000) +#define HARDWARE_STRAP_REGISTER (SCU_ADDR + 0x70) +#define REBOOT_CPU_REGISTER (SCU_ADDR + 0x7C) + +/* SCU KEY */ +#define UNLOCK_SCU_KEY (0x1688A8A8) +#define LOCK_SCU_KEY (0x11111111) + +/* WATCHDOG REGISTER ADDR */ +#define WATCHDOG_ADDR (0x1E785000) +#define WATCHDOG1_RELOAD_VALUE (WATCHDOG_ADDR + 0x04) +#define WATCHDOG1_COUNTER_RST (WATCHDOG_ADDR + 0x08) +#define WATCHDOG1_CONTROL (WATCHDOG_ADDR + 0x0C) +#define WATCHDOG1_TSR (WATCHDOG_ADDR + 0x10) +#define WATCHDOG1_CLEAR_STATUS (WATCHDOG_ADDR + 0x14) +#define WATCHDOG1_RESET_FUN_MASK (WATCHDOG_ADDR + 0x1C) + +#define WATCHDOG2_RELOAD_VALUE (WATCHDOG_ADDR + 0x24) +#define WATCHDOG2_COUNTER_RST (WATCHDOG_ADDR + 0x28) +#define WATCHDOG2_CONTROL (WATCHDOG_ADDR + 0x2C) +#define WATCHDOG2_TSR (WATCHDOG_ADDR + 0x30) +#define WATCHDOG2_CLEAR_STATUS (WATCHDOG_ADDR + 0x34) +#define WATCHDOG2_RESET_FUN_MASK (WATCHDOG_ADDR + 0x3C) + +/* User Mode Command */ +#define WRITE_STATUS (0x01) +#define COMMON_PAGE_PROGRAM (0x02) +#define COMMON_FLASH_READ (0x03) +#define WRITE_DISABLE_FLASH (0x04) +#define READ_FLASH_STATUS (0x05) +#define WRITE_ENABLE_FLASH (0x06) +#define PAGE_PROGRAM_FLASH (0x12) +#define SECTOR_ERASE (0x20) +#define CLEAR_FLAG (0x50) +#define SUBBLOCK_ERASE (0x52) +#define CHIP_ERASE_FLASH (0x60) +#define BLOCK_ERASE_64 (0xD8) +#define READID (0x9F) +#define ENABLE_BYTE4 (0xB7) +#define EXIT_OTP (0xC1) +#define RSTEN (0x66) +#define RST (0x99) + +#define BIT1 (0x01) +#define BIT2 (0x02) +#define BIT3 (0x04) +#define BIT4 (0x08) +#define BIT5 (0x10) +#define BIT6 (0x20) +#define BIT7 (0x40) +#define BIT8 (0x80) +#define RIGHT_SHIFT_8(reg) (reg >> 8) +#define RIGHT_SHIFT_16(reg) (reg >> 16) +#define RIGHT_SHIFT_24(reg) (reg >> 24) +#define MASK (0xFF) +#define FLASH_TYPE_MASK (BIT1 | BIT2) +#define BOOT_DEFAULT_MASK (BIT8) +#define HEAD_MASK (0x00FFFF00) +#define MASK_BYTE (0xFF000000) +#define BYTE1 (1) +#define BYTE2 (2) +#define BYTE4 (4) +#define BYTE1_VAL (0) +#define BYTE2_VAL (1) +#define BYTE4_VAL (2) +#define BYTE_RESERVED (3) + +/* SuperIO */ +#define SUPERIO_07 (0x07) +#define SUPERIO_30 (0x30) +#define SUPERIO_A0 (0xA0) +#define SUPERIO_A2 (0xA2) +#define SUPERIO_REG0 (0xF0) +#define SUPERIO_REG1 (0xF1) +#define SUPERIO_REG2 (0xF2) +#define SUPERIO_REG3 (0xF3) +#define SUPERIO_REG4 (0xF4) +#define SUPERIO_REG5 (0xF5) +#define SUPERIO_REG6 (0xF6) +#define SUPERIO_REG7 (0xF7) +#define SUPERIO_REG8 (0xF8) +#define SUPERIO_FE (0xFE) + +/* SPI Command */ +#define HIGH_CLOCK (0x00000000) +#define NORMAL_READ (0x00000000) +#define READ_MODE (0x00000001) +#define WRITE_MODE (0x00000002) +#define USER_MODE (0x00000003) +#define PULL_DOWN (0x00000000) +#define PULL_UP (0x00000004) + +#define CHIP_ERASE_TIME (60) +#define CHIP_ERASE_TIMEOUT (300 * 1000 * 1000) +#define CHIP_ERASE_SLEEP_TIME (5 * 1000 * 1000) +#define BLOCK_ERASE_TIMEOUT (10 * 1000 * 1000) +#define BLOCK_ERASE_SLEEP_TIME (100 * 1000) +#define PAGE_PROGRAM_TIMEOUT (100 * 1000) +#define PAGE_PROGRAM_SLEEP_TIME (1000) +#define FLASH_WEL_TIMEOUT (100 * 1000) +#define FLASH_WEL_SLEEP_TIME (1000) +#define FLASH_WIP_MASK (0x00000001) +#define FLASH_WRITE_ENABLE_MASK (0x00000002) + +#define DATA_LENGTH_MASK (0xA2) +#define TOGGLE_WRITE (0xCF) +#define DISABLE_LPC (0xAA) +#define ENABLE_LPC (0xA5) +#define LPC_TO_AHB (0x0D) +#define ENABLE_LPC_TO_AHB (0x01) +#define DISABLE_LPC_TO_AHB (0x00) +#define ENABLE_BMC_CPU_BOOT (0xF10BD286) +#define DISABLE_BMC_CPU_BOOT (0xF10BD287) +#define SET_BMC_CPU_BOOT (0x01) +#define CLEAR_WATCHDOG_STATUS (0x01) +#define DISABLE_WATCHDOG (0x00000030) +#define ENABLE_WATCHDOG (0x00000033) +#define WATCHDOG_GATEMASK (0x033FFFF3) +#define WATCHDOG_NEW_COUNT (0x00050000) +#define WATCHDOG_RELOAD_COUNTER (0x4755) + +#define CE0_SPI_TYPE (0x00000002) +#define CE1_SPI_TYPE (0x00000008) +#define ERROR_COMMAND (0x00000400) +#define ADDRESS_PROTECT (0x00000200) +#define CLEAR_INR_STATUS_CONTROL (ERROR_COMMAND | ADDRESS_PROTECT) +#define USER_MODE_PULL_CE_DOWN (HIGH_CLOCK | USER_MODE | PULL_DOWN) +#define USER_MODE_PULL_CE_UP (HIGH_CLOCK | USER_MODE | PULL_UP) + +#define STEP_64 (64 * 1024) +#define STEP_256 (256 * 1024) +#define BYTE_256 (256) + +#define CE0 (0) +#define CE1 (1) +#define BOTHFLASH (2) +#define SOC_SYS (0) +#define FULL_CHIP (1) +#define ARM_CPU (2) +#define FULL_ERASE (0) +#define BLOCK_ERASE (1) +#define READ_ALL (2) +#define CURRENT_SLAVE (1) +#define CURRENT_MASTER (0) +#define REGISTER_HEAD (0x1e000000) +#define DEFAULT_WIDTH (16) +#define MAX_FILENAME_LENGTH (64) +#define SEGMENT_ADDR_START(_r) ((((_r) >> 16) & 0xFF) << 23) + +typedef struct flash_info { + uint32_t flash_size; + int cs; + int flash_type; + uint32_t flash_id; + int page_size; + char flash_name[64]; + int erase_block_command; + int page_program; + int block_size; + int full_erase; + uint32_t ce_control_reg; + uint32_t flash_base_addr; +} flash_info_t; + +typedef enum flash_id { + MX25L6433F = 0x1920c2, + S25FL512S = 0x200201, + MX25l512 = 0x1a20c2, + STM25P64 = 0x172020, + STM25P128 = 0x182020, + N25Q256 = 0x19ba20, + N25Q512 = 0x20ba20, + W25X16 = 0x1530ef, + W25X64 = 0x1730ef, + W25Q64BV = 0x1740ef, + W25Q128BV = 0x1840ef, + W25Q256FV = 0x1940ef, + MX25L1605D = 0x1520C2, + MX25L12805D = 0x1820C2, + MX66L1G45G = 0x1B20C2, + SST25VF016B = 0x4125bf, + SST25VF064C = 0x4b25bf, + SST25VF040B = 0x8d25bf, + AT25DF161 = 0x02461F, + AT25DF321 = 0x01471F, + GD25Q256 = 0X1940c8, +} flash_id_t; + +typedef enum flash_type { + NOR = 0, + SPI = 2, +} flash_type_t; + +typedef enum flash_size { + M1 = 0x00080000, + M3 = 0x00200000, /* 3M */ + M6 = 0x00400000, /* 6M */ + M12 = 0x00800000, /* 12M */ + M16 = 0x01000000, /* 16M */ + M32 = 0x02000000, /* 32M */ + M64 = 0x04000000, /* 64M */ + M128 = 0x08000000, /* 128M */ +} flash_size_t; + +#endif /*_FW_UPGRADE_H_*/ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h new file mode 100644 index 000000000000..05911da62a7e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h @@ -0,0 +1,25 @@ +#ifndef __FW_UPGRADE_DEBUG_H__ +#define __FW_UPGRADE_DEBUG_H__ + +#include + +#define DEBUG_INFO_LEN 20 +#define DEBUG_FILE "/tmp/.fw_upgrade_debug" +#define DEBUG_ON_ALL "3" +#define DEBUG_ON_KERN "2" +#define DEBUG_ON_INFO "1" +#define DEBUG_OFF_INFO "0" + +#define mem_clear(data, size) memset((data), 0, (size)) + +enum debug_s { + DEBUG_OFF = 0, + DEBUG_APP_ON, + DEBUG_KERN_ON, + DEBUG_ALL_ON, + DEBUG_IGNORE, +}; + +extern int fw_upgrade_debug(void); + +#endif /* End of __FW_UPGRADE_DEBUG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/hysteresis.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/hysteresis.py new file mode 100644 index 000000000000..81fd596e7fee --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/hysteresis.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +import os +import syslog +import copy + +from plat_hal.baseutil import baseutil + +HYST_DEBUG_FILE = "/etc/.hysteresis_debug_flag" + +HYSTERROR = 1 +HYSTDEBUG = 2 + +debuglevel = 0 + + +def hyst_debug(s): + if HYSTDEBUG & debuglevel: + syslog.openlog("FANCONTROL-HYST", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def hyst_error(s): + if HYSTERROR & debuglevel: + syslog.openlog("FANCONTROL-HYST", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +class hysteresis(object): + __config = None + __hyst_config = None + + def __init__(self): + self.__config = baseutil.get_monitor_config() + self.__hyst_config = copy.deepcopy(self.__config.get("hyst", {})) + # init check + errcnt = 0 + errmsg = "" + self.debug_init() + for temp_hyst_conf in self.__hyst_config.values(): + if temp_hyst_conf["flag"] == 0: + continue + for i in range(temp_hyst_conf["temp_min"], temp_hyst_conf["temp_max"] + 1): + if i not in temp_hyst_conf["rising"]: + errcnt -= 1 + msg = "%s hyst config error, temp value %d not in rising curve;" % (temp_hyst_conf["name"], i) + hyst_error(msg) + errmsg += msg + if i not in temp_hyst_conf["descending"]: + errcnt -= 1 + msg = "%s hyst config error, temp value %d not in descending curve;" % (temp_hyst_conf["name"], i) + hyst_error(msg) + errmsg += msg + if errcnt < 0: + raise KeyError(errmsg) + + def debug_init(self): + global debuglevel + if os.path.exists(HYST_DEBUG_FILE): + debuglevel = debuglevel | HYSTDEBUG | HYSTERROR + else: + debuglevel = debuglevel & ~(HYSTDEBUG | HYSTERROR) + + def get_temp_hyst_conf(self, temp_name): + temp_hyst_conf = self.__hyst_config.get(temp_name) + return temp_hyst_conf + + def get_temp_update(self, hyst_para, current_temp): + temp = hyst_para["value"] + if temp is None: + return None + temp.append(current_temp) + del temp[0] + return temp + + def duty_to_pwm(self, duty): + pwm = int(round(float(duty) * 255 / 100)) + return pwm + + def pwm_to_duty(self, pwm): + duty = int(round(float(pwm) * 100 / 255)) + return duty + + def calc_hyst_val(self, temp_name, temp_list): + + temp_hyst_conf = self.get_temp_hyst_conf(temp_name) + hyst_min = temp_hyst_conf["hyst_min"] + hyst_max = temp_hyst_conf["hyst_max"] + temp_min = temp_hyst_conf["temp_min"] + temp_max = temp_hyst_conf["temp_max"] + rising = temp_hyst_conf["rising"] + descending = temp_hyst_conf["descending"] + last_hyst_value = temp_hyst_conf["last_hyst_value"] + current_temp = temp_list[1] + last_temp = temp_list[0] + + hyst_debug("calc_hyst_val, temp_name: %s, current_temp: %s, last_temp: %s, last_hyst_value: %s" % + (temp_name, current_temp, last_temp, last_hyst_value)) + + if current_temp < temp_min: + hyst_debug("%s current_temp %s less than temp_min %s, set min hyst value: %s" % + (temp_name, current_temp, temp_min, hyst_min)) + return hyst_min + + if current_temp > temp_max: + hyst_debug("%s current_temp %s more than temp_max %s, set max hyst value: %s" % + (temp_name, current_temp, temp_max, hyst_max)) + return hyst_max + + if last_temp is None: # first time + hyst_value = rising[current_temp] + hyst_debug("last_temp is None, it's first hysteresis, using rising hyst value: %s" % hyst_value) + return hyst_value + + if current_temp == last_temp: # temp unchanging + hyst_debug("current_temp equal last_temp, keep last hyst value: %s" % last_hyst_value) + return last_hyst_value + + if current_temp > last_temp: + calc_hyst_value = rising[current_temp] + if calc_hyst_value < last_hyst_value: + hyst_value = last_hyst_value + else: + hyst_value = calc_hyst_value + hyst_debug("temp rising, last_hyst_value: %s, calc_hyst_value: %s, set hyst value: %s" % + (last_hyst_value, calc_hyst_value, hyst_value)) + return hyst_value + + calc_hyst_value = descending[current_temp] + if calc_hyst_value > last_hyst_value: + hyst_value = last_hyst_value + else: + hyst_value = calc_hyst_value + hyst_debug("temp descending, last_hyst_value: %s, calc_hyst_value: %s, set hyst value: %s" % + (last_hyst_value, calc_hyst_value, hyst_value)) + return hyst_value + + def cacl(self, temp_name, current_temp): + self.debug_init() + try: + temp_hyst_conf = self.get_temp_hyst_conf(temp_name) + if temp_hyst_conf is None: + hyst_debug("get %s hysteresis config failed" % temp_name) + return None + + flag = temp_hyst_conf["flag"] + if flag != 1: + hyst_debug("%s hysteresis flag == 0, skip" % temp_name) + return None + + temp = self.get_temp_update(temp_hyst_conf, current_temp) + if temp is None: + hyst_debug("get %s update failed" % temp_name) + return None + + value = self.calc_hyst_val(temp_name, temp) + + temp_hyst_conf["last_hyst_value"] = value + + speed_type = temp_hyst_conf["type"] + if speed_type == "duty": + pwm = self.duty_to_pwm(value) + else: + pwm = value + + hyst_debug("temp_name: %s, current_temp: %s, set pwm 0x%x" % (temp_name, current_temp, pwm)) + return pwm + except Exception as e: + hyst_error("temp_name: %s calc hysteresis pwm error, msg: %s" % (temp_name, str(e))) + return None diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/openloop.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/openloop.py new file mode 100644 index 000000000000..6ff731fa7eb2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/openloop.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +import os +import syslog + +from plat_hal.baseutil import baseutil + +OPENLOOP_DEBUG_FILE = "/etc/.openloop_debug_flag" + +OPENLOOPERROR = 1 +OPENLOOPDEBUG = 2 + +debuglevel = 0 + + +def openloop_debug(s): + if OPENLOOPDEBUG & debuglevel: + syslog.openlog("FANCONTROL-OPENLOOP", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def openloop_error(s): + if OPENLOOPERROR & debuglevel: + syslog.openlog("FANCONTROL-OPENLOOP", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +class openloop(object): + __config = None + __openloop_config = None + + def __init__(self): + self.__config = baseutil.get_monitor_config() + self.__openloop_config = self.__config["openloop"] + + def debug_init(self): + global debuglevel + if os.path.exists(OPENLOOP_DEBUG_FILE): + debuglevel = debuglevel | OPENLOOPDEBUG | OPENLOOPERROR + else: + debuglevel = debuglevel & ~(OPENLOOPDEBUG | OPENLOOPERROR) + + def get_para(self, t): + para = self.__openloop_config.get(t) + return para + + def linear_cacl(self, temp): + self.debug_init() + openloop_para = self.get_para("linear") + if openloop_para is None: + openloop_debug("linear openloop: get para failed") + return None + + K = openloop_para["K"] + tin_min = openloop_para["tin_min"] + pwm_min = openloop_para["pwm_min"] + pwm_max = openloop_para["pwm_max"] + flag = openloop_para["flag"] + + if flag != 1: + openloop_debug("linear openloop: flag == 0") + return None + + if temp <= tin_min: + openloop_debug("linear openloop: temp = %d less than tin_min[%d]" % (temp, tin_min)) + return pwm_min + + pwm = int(pwm_min + (temp - tin_min) * K) + openloop_debug("linear openloop: cacl_pwm = 0x%x" % pwm) + + pwm = min(pwm, pwm_max) + pwm = max(pwm, pwm_min) + openloop_debug("linear openloop: temp = %d, pwm = 0x%x" % (temp, pwm)) + return pwm + + def curve_cacl(self, temp): + self.debug_init() + openloop_para = self.get_para("curve") + if openloop_para is None: + openloop_debug("curve openloop: get para failed") + return None + + a = openloop_para["a"] + b = openloop_para["b"] + c = openloop_para["c"] + tin_min = openloop_para["tin_min"] + pwm_min = openloop_para["pwm_min"] + pwm_max = openloop_para["pwm_max"] + flag = openloop_para["flag"] + + if flag != 1: + openloop_debug("curve openloop: flag == 0") + return None + + if temp <= tin_min: + openloop_debug("curve openloop: temp = %d less than tin_min[%d]" % (temp, tin_min)) + return pwm_min + + pwm = int(a * temp * temp + b * temp + c) + openloop_debug("curve openloop: cacl_pwm = 0x%x" % pwm) + + pwm = min(pwm, pwm_max) + pwm = max(pwm, pwm_min) + openloop_debug("curve openloop: temp = %d, pwm = 0x%x" % (temp, pwm)) + return pwm diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/pid.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/pid.py new file mode 100644 index 000000000000..c33c1df33b4e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/pid.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +import os +import syslog +import copy + +from plat_hal.baseutil import baseutil + +PID_DEBUG_FILE = "/etc/.pid_debug_flag" + +PIDERROR = 1 +PIDDEBUG = 2 + +debuglevel = 0 + + +def pid_debug(s): + if PIDDEBUG & debuglevel: + syslog.openlog("FANCONTROL-PID", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def pid_error(s): + if PIDERROR & debuglevel: + syslog.openlog("FANCONTROL-PID", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +class pid(object): + __config = None + __pid_config = None + + def __init__(self): + self.__config = baseutil.get_monitor_config() + self.__pid_config = copy.deepcopy(self.__config["pid"]) + + def debug_init(self): + global debuglevel + if os.path.exists(PID_DEBUG_FILE): + debuglevel = debuglevel | PIDDEBUG | PIDERROR + else: + debuglevel = debuglevel & ~(PIDDEBUG | PIDERROR) + + def get_para(self, name): + para = self.__pid_config.get(name) + return para + + def get_temp_update(self, pid_para, current_temp): + temp = pid_para["value"] + if temp is None: + return None + temp.append(current_temp) + del temp[0] + return temp + + def cacl(self, last_pwm, name, current_temp): + delta_pwm = 0 + self.debug_init() + pid_debug("last_pwm = %d" % last_pwm) + + pid_para = self.get_para(name) + if pid_para is None: + pid_debug("get %s pid para failed" % name) + return None + + temp = self.get_temp_update(pid_para, current_temp) + if temp is None: + pid_debug("get %s update failed" % name) + return None + + speed_type = pid_para["type"] + Kp = pid_para["Kp"] + Ki = pid_para["Ki"] + Kd = pid_para["Kd"] + target = pid_para["target"] + pwm_min = pid_para["pwm_min"] + pwm_max = pid_para["pwm_max"] + flag = pid_para["flag"] + + if flag != 1: + pid_debug("%s pid flag == 0" % name) + return None + + if speed_type == "duty": + current_pwm = round(last_pwm * 100 / 255) + else: + current_pwm = last_pwm + + if temp[2] is None: + tmp_pwm = current_pwm + elif ((temp[0] is None) or (temp[1] is None)): + delta_pwm = Ki * (temp[2] - target) + tmp_pwm = current_pwm + delta_pwm + else: + delta_pwm = Kp * (temp[2] - temp[1]) + Ki * (temp[2] - target) + Kd * (temp[2] - 2 * temp[1] + temp[0]) + tmp_pwm = current_pwm + delta_pwm + + pid_debug("delta_pwm = %d" % delta_pwm) + if speed_type == "duty": + pwm = round(tmp_pwm * 255 / 100) + else: + pwm = int(tmp_pwm) + + pwm = min(pwm, pwm_max) + pwm = max(pwm, pwm_min) + pid_debug("last_pwm = 0x%x, pwm = 0x%x" % (last_pwm, pwm)) + return pwm diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fantlv.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fantlv.py index 38beb068f44c..4be78e7fdc03 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fantlv.py +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fantlv.py @@ -1,19 +1,21 @@ #!/usr/bin/python3 # -*- coding: utf-8 -*- + class FantlvException(Exception): - def __init__(self, message='fantlverror', code=-100): + def __init__(self, message='fantlverror', code=-100): err = 'errcode: {0} message:{1}'.format(code, message) Exception.__init__(self, err) self.code = code self.message = message -class fan_tlv(object): + +class fan_tlv(): HEAD_INFO = "\x01\x7e\x01\xf1" - VERSION = 0x01 # E2PROM file init version is 0x01 - FLAG = 0x7E #new version E2PROM mark as 0x7E - HW_VER = 0X01 # consists of master version and revised version - TYPE = 0xf1 # hardware type define - TLV_LEN = 00 # vaild data length(16bit) + VERSION = 0x01 + FLAG = 0x7E + HW_VER = 0X01 + TYPE = 0xf1 + TLV_LEN = 00 _FAN_TLV_HDR_LEN = 6 _FAN_TLV_CRC_LEN = 2 @@ -22,8 +24,6 @@ class fan_tlv(object): _FAN_TLV_TYPE_HW_INFO = 0x05 _FAN_TLV_TYPE_DEV_TYPE = 0x06 - _fandecodetime = 0 - @property def dstatus(self): return self._dstatus @@ -44,18 +44,6 @@ def typehwinfo(self): def typedevtype(self): return self._typedevtype - @property - def fanbus(self): - return self._fanbus - - @property - def fanloc(self): - return self._fanloc - - @property - def fandecodetime(self): - return self._fandecodetime - def __init__(self): self._typename = "" self._typesn = "" @@ -63,25 +51,20 @@ def __init__(self): self._typedevtype = "" self._dstatus = 0 - def strtoarr(self, str): + def strtoarr(self, val): s = [] - if str is not None: - for index in range(len(str)): - s.append(str[index]) + if not isinstance(val, str): + return s + for index in val: + s.append(index) return s - def str_to_hex(self,rest_v): - value = 0 - for index in range(len(rest_v)): - value |= ord(rest_v[index]) << ((len(rest_v) - index - 1) * 8) - return value - - def hex_to_str(self,s): + def hex_to_str(self, s): len_t = len(s) if len_t % 2 != 0: return 0 ret = "" - for t in range(0, int(len_t / 2)): + for t in range(0, len_t / 2): ret += chr(int(s[2 * t:2 * t + 2], 16)) return ret @@ -92,7 +75,7 @@ def generate_fan_value(self): bin_buffer[2] = chr(self.HW_VER) bin_buffer[3] = chr(self.TYPE) - temp_t = "%08x" % self.typedevtype # handle devtype first + temp_t = "%08x" % self.typedevtype typedevtype_t = self.hex_to_str(temp_t) total_len = len(self.typename) + len(self.typesn) + \ len(self.typehwinfo) + len(typedevtype_t) + 8 @@ -125,10 +108,9 @@ def generate_fan_value(self): len(typedevtype_t)] = self.strtoarr(typedevtype_t) index_start = index_start + 2 + len(typedevtype_t) - crcs = fan_tlv.fancrc(''.join(bin_buffer[0:index_start])) # 2bytes checking + crcs = fan_tlv.fancrc(''.join(bin_buffer[0:index_start])) bin_buffer[index_start] = chr(crcs >> 8) bin_buffer[index_start + 1] = chr(crcs & 0x00ff) - # printvalue(bin_buffer) return bin_buffer def decode(self, e2): @@ -144,7 +126,6 @@ def decode(self, e2): tlv_index = self._FAN_TLV_HDR_LEN tlv_end = self._FAN_TLV_HDR_LEN + self.TLV_LEN - # check sum if len(e2) < self._FAN_TLV_HDR_LEN + self.TLV_LEN + 2: raise FantlvException("Fan tlv eeprom len error!", -2) sumcrc = fan_tlv.fancrc(e2[0:self._FAN_TLV_HDR_LEN + self.TLV_LEN]) @@ -152,8 +133,7 @@ def decode(self, e2): ) << 8 | ord(e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN + 1]) if sumcrc != readcrc: raise FantlvException("Fan tlv eeprom checksum error!", -1) - else: - self._dstatus = 0 + self._dstatus = 0 while (tlv_index + 2) < len(e2) and tlv_index < tlv_end: s = self.decoder( e2[tlv_index:tlv_index + 2 + ord(e2[tlv_index + 1])]) @@ -164,15 +144,16 @@ def decode(self, e2): @staticmethod def fancrc(t): - sum = 0 - for index in range(len(t)): - sum += ord(t[index]) - return sum + crc = 0 + for item in t: + crc += ord(item) + return crc def decoder(self, t): try: name = "" value = "" + _len = 0 if ord(t[0]) == self._FAN_TLV_TYPE_NAME: name = "Product Name" _len = ord(t[1]) @@ -194,10 +175,10 @@ def decoder(self, t): value = "0x" for c in t[2:2 + ord(t[1])]: value += "%02X" % (ord(c),) - self._typedevtype = int(value,16) + self._typedevtype = int(value, 16) except Exception as e: print(e) - return {"name": name, "code": ord(t[0]), "value": value,"lens": _len} + return {"name": name, "code": ord(t[0]), "value": value, "lens": _len} def __str__(self): formatstr = "VERSION : 0x%02x \n" \ @@ -207,6 +188,5 @@ def __str__(self): "typename : %s \n" \ "typesn : %s \n" \ "typehwinfo : %s \n" - return formatstr % (self.VERSION, self.FLAG, self.HW_VER, self.TYPE, self.typename, self.typesn, self.typehwinfo) - - + return formatstr % (self.VERSION, self.FLAG, self.HW_VER, self.TYPE, + self.typename, self.typesn, self.typehwinfo) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fru.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fru.py index 90a690a19edd..f95164e03601 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fru.py +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fru.py @@ -1,18 +1,14 @@ #!/usr/bin/python3 -# -*- coding: utf-8 -*- import collections -from bitarray import bitarray from datetime import datetime, timedelta -import sys +from bitarray import bitarray -__all__ = ["FruException", "FruUtil", "BaseArea", "BoardInfoArea", "ProductInfoArea", - "MultiRecordArea", "Field", "ipmifru"] __DEBUG__ = "N" class FruException(Exception): - def __init__(self, message='fruerror', code=-100): + def __init__(self, message='fruerror', code=-100): err = 'errcode: {0} message:{1}'.format(code, message) Exception.__init__(self, err) self.code = code @@ -24,7 +20,7 @@ def e_print(err): def d_print(debug_info): - if(__DEBUG__ == "Y"): + if __DEBUG__ == "Y": print(debug_info) @@ -43,7 +39,7 @@ def minToData(): starttime = datetime(1996, 1, 1, 0, 0, 0) endtime = datetime.now() seconds = (endtime - starttime).total_seconds() - mins = seconds / 60 + mins = seconds // 60 m = int(round(mins)) return m @@ -53,7 +49,7 @@ def getTimeFormat(): @staticmethod def getTypeLength(value): - if value is None: + if value is None or len(value) == 0: return 0 a = bitarray(8) a.setall(False) @@ -65,8 +61,8 @@ def getTypeLength(value): @staticmethod def checksum(b): result = 0 - for i in range(len(b)): - result += ord(b[i]) + for item in b: + result += ord(item) return (0x100 - (result & 0xff)) & 0xff @@ -89,7 +85,6 @@ def __init__(self, name="", size=0, offset=0): self._size = size self._isPresent = False self._data = b'\x00' * size - self.__dataoffset = 0 @property def childList(self): @@ -144,6 +139,9 @@ class BoardInfoArea(BaseArea): _boardTime = None _fields = None _mfg_date = None + areaversion = None + _boardversion = None + _language = None def __str__(self): formatstr = "version : %x\n" \ @@ -229,8 +227,7 @@ def decodedata(self): self.fruFileId = self.data[index + 1: index + templen + 1] index += templen + 1 d_print("decode fruFileId:%s" % self.fruFileId) - - + for i in range(1, 11): valtmp = "boardextra%d" % i if self.data[index] != chr(0xc1): @@ -242,6 +239,11 @@ def decodedata(self): else: break + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + def recalcute(self): d_print("boardInfoArea version:%x" % ord(self.boardversion)) d_print("boardInfoArea length:%d" % self.size) @@ -250,7 +252,7 @@ def recalcute(self): d_print("boardInfoArea mfg_date:%x" % self.mfg_date) self.data = chr(ord(self.boardversion)) + \ - chr(self.size / 8) + chr(self.language) + chr(self.size // 8) + chr(self.language) self.data += chr(self.mfg_date & 0xFF) self.data += chr((self.mfg_date >> 8) & 0xFF) @@ -283,9 +285,7 @@ def recalcute(self): valtmpval = getattr(self, valtmp) d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) self.data += chr(FruUtil.getTypeLength(valtmpval)) - if valtmpval is None: - pass - else: + if valtmpval is not None: self.data += valtmpval else: break @@ -293,14 +293,14 @@ def recalcute(self): self.data += chr(0xc1) if len(self.data) > (self.size - 1): - incr = (len(self.data) - self.size) / 8 + 1 + incr = (len(self.data) - self.size) // 8 + 1 self.size += incr * 8 - self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:] + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] d_print("self data:%d" % len(self.data)) d_print("self size:%d" % self.size) d_print("adjust size:%d" % (self.size - len(self.data) - 1)) - self.data = self.data.ljust((self.size - 1), self.INITVALUE) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) # checksum checksum = FruUtil.checksum(self.data) @@ -391,6 +391,7 @@ class ProductInfoArea(BaseArea): _productManufacturer = None _productAssetTag = None _FRUFileID = None + _language = None def __str__(self): formatstr = "version : %x\n" \ @@ -483,7 +484,7 @@ def decodedata(self): self.fruFileId = self.data[index + 1: index + templen + 1] index += templen + 1 d_print("decode fruFileId:%s" % self.fruFileId) - + for i in range(1, 11): valtmp = "productextra%d" % i if self.data[index] != chr(0xc1) and index < self.size - 1: @@ -567,12 +568,17 @@ def fruFileId(self): def fruFileId(self, name): self._FRUFileID = name + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + def recalcute(self): d_print("product version:%x" % ord(self.areaversion)) d_print("product length:%d" % self.size) d_print("product language:%x" % self.language) self.data = chr(ord(self.areaversion)) + \ - chr(self.size / 8) + chr(self.language) + chr(self.size // 8) + chr(self.language) typelength = FruUtil.getTypeLength(self.productManufacturer) self.data += chr(typelength) @@ -597,29 +603,26 @@ def recalcute(self): self.data += chr(FruUtil.getTypeLength(self.fruFileId)) self.data += self.fruFileId - # whether the extended field exists or not for i in range(1, 11): valtmp = "productextra%d" % i if hasattr(self, valtmp): valtmpval = getattr(self, valtmp) d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) self.data += chr(FruUtil.getTypeLength(valtmpval)) - if valtmpval is None: - pass - else: + if valtmpval is not None: self.data += valtmpval else: break self.data += chr(0xc1) if len(self.data) > (self.size - 1): - incr = (len(self.data) - self.size) / 8 + 1 + incr = (len(self.data) - self.size) // 8 + 1 self.size += incr * 8 d_print("self.data:%d" % len(self.data)) d_print("self.size:%d" % self.size) - self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:] - self.data = self.data.ljust((self.size - 1), self.INITVALUE) + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) checksum = FruUtil.checksum(self.data) d_print("board info checksum:%x" % checksum) self.data += chr(checksum) @@ -635,17 +638,13 @@ def __init__(self, fieldType="ASCII", fieldData=""): self.fieldData = fieldData self.fieldType = fieldType - @property - def data(self): - return self._data - @property def fieldType(self): - return self._fieldType + return self.fieldType @property def fieldData(self): - return self._fieldData + return self.fieldData class ipmifru(BaseArea): @@ -663,6 +662,7 @@ class ipmifru(BaseArea): _bodybin = None _version = BaseArea.COMMON_HEAD_VERSION _zeroCheckSum = None + _frusize = 256 def __str__(self): tmpstr = "" @@ -677,13 +677,13 @@ def __str__(self): def decodeBin(self, eeprom): commonHead = eeprom[0:8] d_print("decode version %x" % ord(commonHead[0])) - if self.COMMON_HEAD_VERSION != commonHead[0]: + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): raise FruException("HEAD VERSION error,not Fru format!", -10) if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): strtemp = "check header checksum error [cal:%02x data:%02x]" % ( FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) raise FruException(strtemp, -3) - if commonHead[1] != self.INITVALUE: + if ord(commonHead[1]) != ord(self.INITVALUE): d_print("Internal Use Area is present") self.internalUseArea = InternalUseArea( name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) @@ -691,7 +691,7 @@ def decodeBin(self, eeprom): self.internalUserAreaOffset = ord(commonHead[1]) self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( self.internalUserAreaOffset * 8 + self.internalUseArea.size)] - if commonHead[2] != self.INITVALUE: + if ord(commonHead[2]) != ord(self.INITVALUE): d_print("Chassis Info Area is present") self.chassisInfoArea = ChassisInfoArea( name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) @@ -699,7 +699,7 @@ def decodeBin(self, eeprom): self.chassicInfoAreaOffset = ord(commonHead[2]) self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] - if commonHead[3] != self.INITVALUE: + if ord(commonHead[3]) != ord(self.INITVALUE): self.boardInfoArea = BoardInfoArea( name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) self.boardInfoArea.isPresent = True @@ -711,12 +711,12 @@ def decodeBin(self, eeprom): self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): - print("check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ (FruUtil.checksum( - self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:]))) - sys.exit(-1) + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) self.boardInfoArea.decodedata() - if commonHead[4] != self.INITVALUE: + if ord(commonHead[4]) != ord(self.INITVALUE): d_print("Product Info Area is present") self.productInfoArea = ProductInfoArea( name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) @@ -736,7 +736,7 @@ def decodeBin(self, eeprom): FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) raise FruException(strtmp, -3) self.productInfoArea.decodedata() - if commonHead[5] != self.INITVALUE: + if ord(commonHead[5]) != ord(self.INITVALUE): self.multiRecordArea = MultiRecordArea( name="MultiRecord record Area ") d_print("MultiRecord record present") @@ -752,7 +752,6 @@ def initDefault(self): self.boardInfoAreaOffset = self.INITVALUE self.productinfoAreaOffset = self.INITVALUE self.multiRecordAreaOffset = self.INITVALUE - self.PAD = self.INITVALUE self.zeroCheckSum = self.INITVALUE self.offset = self.SUGGESTED_SIZE_COMMON_HEADER self.productInfoArea = None @@ -878,30 +877,31 @@ def recalcuteCommonHead(self): self.bindata = "" self.offset = self.SUGGESTED_SIZE_COMMON_HEADER d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) if self.internalUseArea is not None and self.internalUseArea.isPresent: - self.internalUserAreaOffset = self.offset / 8 + self.internalUserAreaOffset = self.offset // 8 self.offset += self.internalUseArea.size d_print("internalUseArea is present offset:%d" % self.offset) if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: - self.chassicInfoAreaOffset = self.offset / 8 + self.chassicInfoAreaOffset = self.offset // 8 self.offset += self.chassisInfoArea.size d_print("chassisInfoArea is present offset:%d" % self.offset) if self.boardInfoArea is not None and self.boardInfoArea.isPresent: - self.boardInfoAreaOffset = self.offset / 8 + self.boardInfoAreaOffset = self.offset // 8 self.offset += self.boardInfoArea.size d_print("boardInfoArea is present offset:%d" % self.offset) d_print("boardInfoArea is present size:%d" % self.boardInfoArea.size) if self.productInfoArea is not None and self.productInfoArea.isPresent: - self.productinfoAreaOffset = self.offset / 8 + self.productinfoAreaOffset = self.offset // 8 self.offset += self.productInfoArea.size d_print("productInfoArea is present offset:%d" % self.offset) if self.multiRecordArea is not None and self.multiRecordArea.isPresent: - self.multiRecordAreaOffset = self.offset / 8 + self.multiRecordAreaOffset = self.offset // 8 d_print("multiRecordArea is present offset:%d" % self.offset) if self.internalUserAreaOffset == self.INITVALUE: @@ -918,16 +918,17 @@ def recalcuteCommonHead(self): self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff d_print("zerochecksum:%x" % self.zeroCheckSum) - self.data = self.version + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( - self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + self.INITVALUE + chr(self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) self.bindata = self.data + self.bodybin totallen = len(self.bindata) d_print("totallen %d" % totallen) - if (totallen < 256): - self.bindata = self.bindata.ljust(256, self.INITVALUE) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) else: - raise FruException('bin data more than 256', -2) + raise FruException('bin data more than %d' % self._frusize, -2) def recalcutebin(self): self.bodybin = "" @@ -949,6 +950,12 @@ def recalcutebin(self): d_print("multiRecordArea present") self.bodybin += self.productInfoArea.data - def recalcute(self): + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size self.recalcutebin() self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/onietlv.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/onietlv.py new file mode 100644 index 000000000000..a90f8f8453c8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/onietlv.py @@ -0,0 +1,441 @@ +#!/usr/bin/python3 +import binascii + + +class OnietlvException(Exception): + def __init__(self, message='onietlverror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +class onie_tlv(object): + TLV_INFO_ID_STRING = "TlvInfo\x00" + TLV_INFO_INIA_ID = "\x00\x00\x13\x11" + TLV_INFO_VERSION = 0x01 + TLV_INFO_LENGTH = 0x00 + TLV_INFO_LENGTH_VALUE = 0xba + + TLV_CODE_PRODUCT_NAME = 0x21 + TLV_CODE_PART_NUMBER = 0x22 + TLV_CODE_SERIAL_NUMBER = 0x23 + TLV_CODE_MAC_BASE = 0x24 + TLV_CODE_MANUF_DATE = 0x25 + TLV_CODE_DEVICE_VERSION = 0x26 + TLV_CODE_LABEL_REVISION = 0x27 + TLV_CODE_PLATFORM_NAME = 0x28 + TLV_CODE_ONIE_VERSION = 0x29 + TLV_CODE_MAC_SIZE = 0x2A + TLV_CODE_MANUF_NAME = 0x2B + TLV_CODE_MANUF_COUNTRY = 0x2C + TLV_CODE_VENDOR_NAME = 0x2D + TLV_CODE_DIAG_VERSION = 0x2E + TLV_CODE_SERVICE_TAG = 0x2F + TLV_CODE_VENDOR_EXT = 0xFD + TLV_CODE_CRC_32 = 0xFE + _TLV_DISPLAY_VENDOR_EXT = 1 + TLV_CODE_WB_CARID = 0x01 + _TLV_INFO_HDR_LEN = 11 + TLV_CODE_PRODUCT_ID = 0x40 + TLV_CODE_HW_VERSION = 0x41 + TLV_CODE_MAIN_FILENAME = 0x42 + TLV_CODE_DTS_FINENAME = 0x43 + TLV_CODE_SY_SERIAL0 = 0x44 + TLV_CODE_SY_SERIAL1 = 0x45 + TLV_CODE_SY_SERIAL2 = 0x46 + TLV_CODE_SY_SERIAL3 = 0x47 + TLV_CODE_PROJECT_ID = 0x48 + TLV_CODE_SETMAC_VERSION = 0x49 + TLV_CODE_EEPROM_TYPE = 0x4A + + @property + def dstatus(self): + return self._dstatus + + @property + def cardid(self): + return self._cardid + + @property + def productname(self): + return self._productname + + @property + def partnum(self): + return self._partnum + + @property + def serialnum(self): + return self._serialnum + + @property + def macbase(self): + return self._macbase + + @property + def manufdate(self): + return self._manufdate + + @property + def deviceversion(self): + return self._deviceversion + + @property + def labelrevision(self): + return self._labelrevision + + @property + def platformname(self): + return self._platformname + + @property + def onieversion(self): + return self._onieversion + + @property + def macsize(self): + return self._macsize + + @property + def manufname(self): + return self._manufname + + @property + def manufcountry(self): + return self._manufcountry + + @property + def vendorname(self): + return self._vendorname + + @property + def diagname(self): + return self._diagname + + @property + def servicetag(self): + return self._servicetag + + @property + def vendorext(self): + return self._vendorext + + def __init__(self): + self._cardid = "" + self._productname = "" + self._partnum = "" + self._serialnum = "" + self._macbase = "" + self._manufdate = "" + self._deviceversion = "" + self._labelrevision = "" + self._platformname = "" + self._onieversion = "" + self._macsize = "" + self._manufname = "" + self._manufcountry = "" + self._vendorname = "" + self._diagname = "" + self._servicetag = "" + self._vendorext = "" + self._productid = "" + self._hwversion = "" + self._mainfilename = "" + self._dtsfilename = "" + self._syserial0 = "" + self._syserial1 = "" + self._syserial2 = "" + self._syserial3 = "" + self._projectid = "" + self._setmacversion = "" + self._eepromtype = "" + self._crc32 = "" + self._dstatus = 0 + + def oniecrc32(self, v): + data_array = bytearray() + for x in v: + data_array.append(ord(x)) + return '0x%08x' % (binascii.crc32(bytes(data_array)) & 0xffffffff) + + def getTLV_BODY(self, tlv_type, value): + x = [] + temp_t = "" + if tlv_type == self.TLV_CODE_MAC_BASE: + arr = value.split(':') + for tt in arr: + temp_t += chr(int(tt, 16)) + elif tlv_type == self.TLV_CODE_DEVICE_VERSION: + temp_t = chr(value) + elif tlv_type == self.TLV_CODE_MAC_SIZE: + temp_t = chr(value >> 8) + chr(value & 0x00ff) + else: + temp_t = value + x.append(chr(tlv_type)) + x.append(chr(len(temp_t))) + for i in temp_t: + x.append(i) + return x + + def generate_ext(self, cardid): + s = "%08x" % cardid + ret = "" + for t in range(0, 4): + ret += chr(int(s[2 * t:2 * t + 2], 16)) + ret = chr(0x01) + chr(len(ret)) + ret + return ret + + def generate_value(self, _t): + ret = [] + for i in self.TLV_INFO_ID_STRING: + ret.append(i) + ret.append(chr(self.TLV_INFO_VERSION)) + ret.append(chr(self.TLV_INFO_LENGTH)) + ret.append(chr(self.TLV_INFO_LENGTH_VALUE)) + + total_len = 0 + for key in _t: + x = self.getTLV_BODY(key, _t[key]) + ret += x + total_len += len(x) + ret[10] = chr(total_len + 6) + + ret.append(chr(0xFE)) + ret.append(chr(0x04)) + s = self.oniecrc32(''.join(ret)) + for t in range(0, 4): + ret.append(chr(int(s[2 * t + 2:2 * t + 4], 16))) + totallen = len(ret) + if totallen < 256: + for left_t in range(0, 256 - totallen): + ret.append(chr(0x00)) + return (ret, True) + + def decode_tlv(self, e): + tlv_index = 0 + tlv_end = len(e) + ret = [] + while tlv_index < tlv_end and (tlv_index + 2 + ord(e[tlv_index + 1])) <= len(e): + rt = self.decoder(e[tlv_index:tlv_index + 2 + ord(e[tlv_index + 1])]) + ret.append(rt) + if ord(e[tlv_index]) == self.TLV_CODE_CRC_32: + break + tlv_index += ord(e[tlv_index + 1]) + 2 + return ret + + def decode(self, e): + if e[0:8] != self.TLV_INFO_ID_STRING: + raise OnietlvException("ONIE tlv head info error,not onie tlv type", -1) + total_len = (ord(e[9]) << 8) | ord(e[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_len + if tlv_end > len(e): + raise OnietlvException("ONIE tlv length error", -2) + ret = [] + ret = self.decode_tlv(e[tlv_index:tlv_end]) + for item in ret: + if item['code'] == self.TLV_CODE_VENDOR_EXT: + if item["value"][0:4] == self.TLV_INFO_INIA_ID: + rt = self.decode_tlv(item["value"][4:]) + else: + rt = self.decode_tlv(item["value"][0:]) + ret.extend(rt) + return ret + + def decoder(self, t): + if ord(t[0]) == self.TLV_CODE_PRODUCT_NAME: + name = "Product Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._productname = value + elif ord(t[0]) == self.TLV_CODE_PART_NUMBER: + name = "Part Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._partnum = value + elif ord(t[0]) == self.TLV_CODE_SERIAL_NUMBER: + name = "Serial Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._serialnum = value + elif ord(t[0]) == self.TLV_CODE_MAC_BASE: + name = "Base MAC Address" + _len = ord(t[1]) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._macbase = value + elif ord(t[0]) == self.TLV_CODE_MANUF_DATE: + name = "Manufacture Date" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._manufdate = value + elif ord(t[0]) == self.TLV_CODE_DEVICE_VERSION: + name = "Device Version" + _len = ord(t[1]) + value = ord(t[2]) + self._deviceversion = value + elif ord(t[0]) == self.TLV_CODE_LABEL_REVISION: + name = "Label Revision" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._labelrevision = value + elif ord(t[0]) == self.TLV_CODE_PLATFORM_NAME: + name = "Platform Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._platformname = value + elif ord(t[0]) == self.TLV_CODE_ONIE_VERSION: + name = "ONIE Version" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._onieversion = value + elif ord(t[0]) == self.TLV_CODE_MAC_SIZE: + name = "MAC Addresses" + _len = ord(t[1]) + value = str((ord(t[2]) << 8) | ord(t[3])) + self._macsize = value + elif ord(t[0]) == self.TLV_CODE_MANUF_NAME: + name = "Manufacturer" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._manufname = value + elif ord(t[0]) == self.TLV_CODE_MANUF_COUNTRY: + name = "Manufacture Country" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._manufcountry = value + elif ord(t[0]) == self.TLV_CODE_VENDOR_NAME: + name = "Vendor Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._vendorname = value + elif ord(t[0]) == self.TLV_CODE_DIAG_VERSION: + name = "Diag Version" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._diagname = value + elif ord(t[0]) == self.TLV_CODE_SERVICE_TAG: + name = "Service Tag" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._servicetag = value + elif ord(t[0]) == self.TLV_CODE_VENDOR_EXT: + name = "Vendor Extension" + _len = ord(t[1]) + value = "" + if self._TLV_DISPLAY_VENDOR_EXT: + value = t[2:2 + ord(t[1])] + self._vendorext = value + elif ord(t[0]) == self.TLV_CODE_CRC_32 and len(t) == 6: + name = "CRC-32" + _len = ord(t[1]) + value = "0x%08X" % (((ord(t[2]) << 24) | ( + ord(t[3]) << 16) | (ord(t[4]) << 8) | ord(t[5])),) + self._crc32 = value + elif ord(t[0]) == self.TLV_CODE_WB_CARID: + name = "Card id" + _len = ord(t[1]) + value = "" + for c in t[2:2 + ord(t[1])]: + value += "%02X" % (ord(c),) + self._cardid = value + elif ord(t[0]) == self.TLV_CODE_PRODUCT_ID: + name = "Product id" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._productid = value + elif ord(t[0]) == self.TLV_CODE_HW_VERSION: + name = "Hardware Version" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._hwversion = value + elif ord(t[0]) == self.TLV_CODE_MAIN_FILENAME: + name = "Main File Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._mainfilename = value + elif ord(t[0]) == self.TLV_CODE_DTS_FINENAME: + name = "DTS File Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._dtsfilename = value + elif ord(t[0]) == self.TLV_CODE_SY_SERIAL0: + name = "SY Serial 0" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._syserial0 = value + elif ord(t[0]) == self.TLV_CODE_SY_SERIAL1: + name = "SY Serial 1" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._syserial1 = value + elif ord(t[0]) == self.TLV_CODE_SY_SERIAL2: + name = "SY Serial 2" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._syserial2 = value + elif ord(t[0]) == self.TLV_CODE_SY_SERIAL3: + name = "SY Serial 3" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._syserial3 = value + elif ord(t[0]) == self.TLV_CODE_PROJECT_ID: + name = "Project id" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._projectid = value + elif ord(t[0]) == self.TLV_CODE_SETMAC_VERSION: + name = "Setmac Version" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._setmacversion = value + elif ord(t[0]) == self.TLV_CODE_EEPROM_TYPE: + name = "EEPROM Type" + _len = ord(t[1]) + value = "" + for c in t[2:2 + ord(t[1])]: + value += "%02X" % (ord(c),) + self._eepromtype = value + else: + name = "Unknown" + _len = ord(t[1]) + value = "" + for c in t[2:2 + ord(t[1])]: + value += "0x%02X " % (ord(c),) + return {"name": name, "code": ord(t[0]), "value": value, "lens": _len} + + def __str__(self): + formatstr = "Card id : %s \n" \ + "Product Name : %s \n" \ + "Part Number : %s \n" \ + "Serial Number : %s \n" \ + "Base MAC Address : %s \n" \ + "Manufacture Date : %s \n" \ + "Device Version : %s \n" \ + "Label Revision : %s \n" \ + "Platform Name : %s \n" \ + "ONIE Version : %s \n" \ + "MAC Addresses : %s \n" \ + "Manufacturer : %s \n" \ + "Manufacture Country : %s \n" \ + "Vendor Name : %s \n" \ + "Diag Version : %s \n" \ + "Service Tag : %s \n" \ + "CRC-32 : %s \n" + return formatstr % (self._cardid, + self._productname, + self._partnum, + self._serialnum, + self._macbase, + self._manufdate, + self._deviceversion, + self._labelrevision, + self._platformname, + self._onieversion, + self._macsize, + self._manufname, + self._manufcountry, + self._vendorname, + self._diagname, + self._servicetag, + self._crc32) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/baseutil.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/baseutil.py new file mode 100644 index 000000000000..ffe271a424c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/baseutil.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python3 +####################################################### +# +# baseutil.py +# Python implementation of the Class baseutil +# +####################################################### +import importlib.machinery +import os +import syslog +import json +from plat_hal.osutil import osutil + +SYSLOG_IDENTIFIER = "HAL" + +CONFIG_DB_PATH = "/etc/sonic/config_db.json" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + +def getonieplatform(path): + if not os.path.isfile(path): + return "" + machine_vars = {} + with open(path) as machine_file: + for line in machine_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + machine_vars[tokens[0]] = tokens[1].strip() + return machine_vars.get("onie_platform") + + +def getboardid(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +def getplatform_config_db(): + if not os.path.isfile(CONFIG_DB_PATH): + return "" + val = os.popen("sonic-cfggen -j %s -v DEVICE_METADATA.localhost.platform" % CONFIG_DB_PATH).read().strip() + if len(val) <= 0: + return "" + return val + + +def getplatform_name(): + if os.path.isfile('/host/machine.conf'): + return getonieplatform('/host/machine.conf') + if os.path.isfile('/usr/share/sonic/hwsku/machine.conf'): + return getonieplatform('/usr/share/sonic/hwsku/machine.conf') + return getplatform_config_db() + + +platform = (getplatform_name()).replace("-", "_") +boardid = getboardid() +boardairflow = getboardairflow() + + +CONFIG_FILE_PATH_LIST = [ + "/usr/local/bin/", + "/usr/lib/python3/dist-packages/", + "/usr/local/lib/python3.7/dist-packages/hal-config/", + "/usr/local/lib/python3.9/dist-packages/hal-config/" +] + + +DEVICE_CONFIG_FILE_LIST = [ + platform + "_" + boardid + "_" + boardairflow + "_device.py", + platform + "_" + boardid + "_device.py", + platform + "_" + boardairflow + "_device.py", + platform + "_device.py" +] + + +MONITOR_CONFIG_FILE_LIST = [ + platform + "_" + boardid + "_" + boardairflow + "_monitor.py", + platform + "_" + boardid + "_monitor.py", + platform + "_" + boardairflow + "_monitor.py", + platform + "_monitor.py" +] + + +class baseutil: + + CONFIG_NAME = 'devices' + MONITOR_CONFIG_NAME = 'monitor' + UBOOT_ENV_URL = '/etc/device/uboot_env' + + @staticmethod + def get_config(): + real_path = None + for configfile_path in CONFIG_FILE_PATH_LIST: + for config_file in DEVICE_CONFIG_FILE_LIST: + file = configfile_path + config_file + if os.path.exists(file): + real_path = file + break + if real_path is not None: + break + + if real_path is None: + raise Exception("get hal device config error") + devices = importlib.machinery.SourceFileLoader(baseutil.CONFIG_NAME, real_path).load_module() + return devices.devices + + @staticmethod + def get_monitor_config(): + real_path = None + for configfile_path in CONFIG_FILE_PATH_LIST: + for config_file in MONITOR_CONFIG_FILE_LIST: + file = configfile_path + config_file + if os.path.exists(file): + real_path = file + break + if real_path is not None: + break + + if real_path is None: + raise Exception("get hal monitor config error") + monitor = importlib.machinery.SourceFileLoader(baseutil.MONITOR_CONFIG_NAME, real_path).load_module() + return monitor.monitor + + @staticmethod + def get_productname(): + ret, val = osutil.command("cat %s |grep productname | awk -F\"=\" '{print $2;}'" % baseutil.UBOOT_ENV_URL) + tmp = val.lower().replace('-', '_') + if ret != 0 or len(val) <= 0: + raise Exception("get productname error") + return tmp + + @staticmethod + def get_platform(): + ret, val = osutil.command("cat %s |grep conffitname | awk -F\"=\" '{print $2;}'" % baseutil.UBOOT_ENV_URL) + if ret != 0 or len(val) <= 0: + raise Exception("get platform error") + return val + + @staticmethod + def get_product_fullname(): + ret, val = osutil.command("cat %s |grep productname | awk -F\"=\" '{print $2;}'" % baseutil.UBOOT_ENV_URL) + if ret != 0 or len(val) <= 0: + raise Exception("get productname error") + return val + + @staticmethod + def logger_debug(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_DEBUG, msg) + syslog.closelog() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/chassisbase.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/chassisbase.py new file mode 100644 index 000000000000..767d6da34ba9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/chassisbase.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python3 +####################################################### +# +# chassisbase.py +# Python implementation of the Class chassisbase +# +####################################################### +from plat_hal.dcdc import dcdc +from plat_hal.onie_e2 import onie_e2 +from plat_hal.psu import psu +from plat_hal.led import led +from plat_hal.temp import temp +from plat_hal.fan import fan +from plat_hal.cpld import cpld +from plat_hal.component import component +from plat_hal.cpu import cpu +from plat_hal.baseutil import baseutil + + +class chassisbase(object): + __onie_e2_list = [] + __psu_list = [] + __led_list = [] + __temp_list = [] + __fan_list = [] + __card_list = [] + __sensor_list = [] + __dcdc_list = [] + __cpld_list = [] + __comp_list = [] + __bios_list = [] + __bmc_list = [] + __cpu = None + + def __init__(self, conftype=0, conf=None): + # type: (object, object, object) -> object + """ + init chassisbase as order + + type = 0 use default conf, maybe auto find by platform + type = 1 use given conf, conf is not None + + BITMAP + bit 16 + bit 0 PSU + bit 1 LED + bit 2 TEMP + bit 3 fan + bit 4 card + bit 5 sensor + """ + __confTemp = None + + if conftype == 0: + # user + __confTemp = baseutil.get_config() + elif conftype == 1: + __confTemp = conf + + # onie_e2 + onie_e2temp = [] + onie_e2config = __confTemp.get('onie_e2', []) + for item in onie_e2config: + onie_e2_1 = onie_e2(item) + onie_e2temp.append(onie_e2_1) + self.onie_e2_list = onie_e2temp + + # psu + psutemp = [] + psuconfig = __confTemp.get('psus', []) + for item in psuconfig: + psu1 = psu(item) + psutemp.append(psu1) + self.psu_list = psutemp + + # led + ledtemp = [] + ledconfig = __confTemp.get('leds', []) + for item in ledconfig: + led1 = led(item) + ledtemp.append(led1) + self.led_list = ledtemp + + # temp + temptemp = [] + tempconfig = __confTemp.get('temps', []) + for item in tempconfig: + temp1 = temp(item) + temptemp.append(temp1) + self.temp_list = temptemp + + # fan + fantemp = [] + fanconfig = __confTemp.get('fans', []) + for item in fanconfig: + fan1 = fan(item) + fantemp.append(fan1) + self.fan_list = fantemp + + # dcdc + dcdctemp = [] + dcdcconfig = __confTemp.get('dcdc', []) + for item in dcdcconfig: + dcdc1 = dcdc(item) + dcdctemp.append(dcdc1) + self.dcdc_list = dcdctemp + + # cpld + cpldtemp = [] + cpldconfig = __confTemp.get('cplds', []) + for item in cpldconfig: + cpld1 = cpld(item) + cpldtemp.append(cpld1) + self.cpld_list = cpldtemp + + # compoment: cpld/fpga/bios + comptemp = [] + compconfig = __confTemp.get('comp_cpld', []) + for item in compconfig: + comp1 = component(item) + comptemp.append(comp1) + self.comp_list = comptemp + + compconfig = __confTemp.get('comp_fpga', []) + for item in compconfig: + comp1 = component(item) + self.comp_list.append(comp1) + + compconfig = __confTemp.get('comp_bios', []) + for item in compconfig: + comp1 = component(item) + self.comp_list.append(comp1) + + # cpu + cpuconfig = __confTemp.get('cpu', []) + if len(cpuconfig): + self.cpu = cpu(cpuconfig[0]) + + # dcdc + @property + def dcdc_list(self): + return self.__dcdc_list + + @dcdc_list.setter + def dcdc_list(self, val): + self.__dcdc_list = val + + # sensor + @property + def sensor_list(self): + return self.__sensor_list + + @sensor_list.setter + def sensor_list(self, val): + self.__sensor_list = val + + def get_sensor_byname(self, name): + tmp = self.sensor_list + for item in tmp: + if name == item.name: + return item + return None + + # onie_e2 + @property + def onie_e2_list(self): + return self.__onie_e2_list + + @onie_e2_list.setter + def onie_e2_list(self, val): + self.__onie_e2_list = val + + def get_onie_e2_byname(self, name): + tmp = self.onie_e2_list + for item in tmp: + if name == item.name: + return item + return None + + # psu + @property + def psu_list(self): + return self.__psu_list + + @psu_list.setter + def psu_list(self, val): + self.__psu_list = val + + def get_psu_byname(self, name): + tmp = self.psu_list + for item in tmp: + if name == item.name: + return item + return None + + # fan + @property + def fan_list(self): + return self.__fan_list + + @fan_list.setter + def fan_list(self, val): + self.__fan_list = val + + def get_fan_byname(self, name): + tmp = self.fan_list + for item in tmp: + if name == item.name: + return item + return None + + # led + + @property + def led_list(self): + return self.__led_list + + @led_list.setter + def led_list(self, val): + self.__led_list = val + + def get_led_byname(self, name): + tmp = self.led_list + for item in tmp: + if name == item.name: + return item + return None + + # temp + @property + def temp_list(self): + return self.__temp_list + + @temp_list.setter + def temp_list(self, val): + self.__temp_list = val + + def get_temp_byname(self, name): + tmp = self.temp_list + for item in tmp: + if name == item.name: + return item + return None + + # cpld + @property + def cpld_list(self): + return self.__cpld_list + + @cpld_list.setter + def cpld_list(self, val): + self.__cpld_list = val + + def get_cpld_byname(self, name): + tmp = self.cpld_list + for item in tmp: + if name == item.name: + return item + return None + + @property + def comp_list(self): + return self.__comp_list + + @comp_list.setter + def comp_list(self, val): + self.__comp_list = val + + def get_comp_byname(self, name): + tmp = self.comp_list + for item in tmp: + if name == item.name: + return item + return None + + # bios + @property + def bios_list(self): + return self.__bios_list + + @bios_list.setter + def bios_list(self, val): + self.__bios_list = val + + def get_bios_byname(self, name): + tmp = self.bios_list + for item in tmp: + if name == item.name: + return item + return None + + # bmc + @property + def bmc_list(self): + return self.__bmc_list + + @bmc_list.setter + def bmc_list(self, val): + self.__bmc_list = val + + def get_bmc_byname(self, name): + tmp = self.bmc_list + for item in tmp: + if name == item.name: + return item + return None + + # cpu + @property + def cpu(self): + return self.__cpu + + @cpu.setter + def cpu(self, val): + self.__cpu = val + + def get_cpu_byname(self, name): + return self.cpu diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/component.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/component.py new file mode 100644 index 000000000000..0f2ad2167485 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/component.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +####################################################### +# +# component.py +# Python implementation of the Class fan +# +####################################################### +from plat_hal.devicebase import devicebase +from plat_hal.osutil import osutil + + +class component(devicebase): + __user_reg = None + + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.version_file = conf.get('VersionFile', None) + self.comp_id = conf.get("comp_id", None) + self.desc = conf.get("desc", None) + self.slot = conf.get("slot", None) + + def get_version(self): + version = "NA" + try: + ret, version = self.get_value(self.version_file) + if ret is False: + return version + pattern = self.version_file.get('pattern', None) + version = osutil.std_match(version, pattern) + except Exception: + return version + return version diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpld.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpld.py new file mode 100644 index 000000000000..ceb44cb4ca31 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpld.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +####################################################### +# +# fan.py +# Python implementation of the Class fan +# +####################################################### +from plat_hal.devicebase import devicebase + + +class cpld(devicebase): + __user_reg = None + + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.user_reg = conf.get('UserReg', None) + self.console_reg = conf.get('ConsoleReg', None) + self.console_reg_attrs = conf.get('ConsoleRegAttrs', None) + self.version_file = conf.get('VersionFile', None) + self.cpld_id = conf.get("cpld_id", None) + self.desc = conf.get("desc", None) + self.slot = conf.get("slot", None) + self.format = conf.get("format", "big_endian") + self.warm = conf.get("warm", None) + self.type = conf.get("type", None) + + def get_user_reg(self): + if self.user_reg is None: + return False + ret, val = self.get_value(self.user_reg) + return val + + def set_user_reg(self, value): + if self.user_reg is None: + return False + byte = value & 0xFF + ret, val = self.set_value(self.user_reg, byte) + return ret + + def set_console_owner(self, owner): + ret = False + + if self.console_reg is None: + return False + tmpattr = self.console_reg_attrs.get(owner, None) + if tmpattr is not None: + ret, val = self.set_value(self.console_reg, tmpattr) + return ret + + def get_version(self): + ret, val = self.get_value(self.version_file) + if ret is False: + val = "N/A" + return val + if self.type == "str": + return self.byteTostr(val).strip('\n') + val = val.strip('\n').split(" ") + if len(val) < 4: + val = "N/A" + return val + if self.format == "little_endian": + cpld_version = "%s%s%s%s" % (val[3], val[2], val[1], val[0]) + else: + cpld_version = "%s%s%s%s" % (val[0], val[1], val[2], val[3]) + return cpld_version diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpu.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpu.py new file mode 100644 index 000000000000..98aecdab4129 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpu.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +############################################################################### +# +# Hardware Abstraction Layer APIs -- CPU APIs. +# +############################################################################### +from plat_hal.devicebase import devicebase + + +class cpu(devicebase): + + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.cpu_reset_cnt_reg = conf.get('CpuResetCntReg', None) + + def get_cpu_reset_num(self): + """ + get cpu reset num. + @return cpu reset number, -1 for failure + """ + ret = -1 + if self.cpu_reset_cnt_reg is None: + self.logger_debug("ERR: no support get cpu reset num") + return ret + ret, reset_num = self.get_value(self.cpu_reset_cnt_reg) + if ret is False or reset_num is None: + self.logger_debug("ERR: i2c read cpu_reset_cnt_reg,result:%s" % reset_num) + else: + if isinstance(reset_num, str): + ret = int(reset_num, 16) + else: + ret = reset_num + return ret diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/dcdc.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/dcdc.py new file mode 100644 index 000000000000..ba604995043d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/dcdc.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +from plat_hal.devicebase import devicebase +from plat_hal.sensor import sensor + + +class dcdc(devicebase): + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.dcdc_id = conf.get("dcdc_id", None) + self.sensor = sensor(conf) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/devicebase.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/devicebase.py new file mode 100644 index 000000000000..e66ae0143f02 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/devicebase.py @@ -0,0 +1,355 @@ +#!/usr/bin/env python3 +####################################################### +# +# devicebase.py +# Python implementation of the Class devicebase +# +####################################################### +import subprocess +import shlex +import ast +from plat_hal.osutil import osutil +from plat_hal.baseutil import baseutil + +class CodeVisitor(ast.NodeVisitor): + + def __init__(self): + self.value = None + + def get_value(self): + return self.value + + def get_op_value(self, node): + if isinstance(node, ast.Call): # node is func call + value = self.visit_Call(node) + elif isinstance(node, ast.BinOp): # node is BinOp + value = self.visit_BinOp(node) + elif isinstance(node, ast.UnaryOp): # node is UnaryOp + value = self.visit_UnaryOp(node) + elif isinstance(node, ast.Num): # node is Num Constant + value = node.n + elif isinstance(node, ast.Str): # node is Str Constant + value = node.s + else: + raise NotImplementedError("Unsupport operand type: %s" % type(node)) + return value + + def visit_UnaryOp(self, node): + ''' + node.op: operand type, only support ast.UAdd/ast.USub + node.operand: only support ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp/ast.UnaryOp + ''' + + operand_value = self.get_op_value(node.operand) + if isinstance(node.op, ast.UAdd): + self.value = operand_value + elif isinstance(node.op, ast.USub): + self.value = 0 - operand_value + else: + raise NotImplementedError("Unsupport arithmetic methods %s" % type(node.op)) + return self.value + + def visit_BinOp(self, node): + ''' + node.left: left operand, only support ast.Call/ast.Constant(ast.Num)/ast.BinOp + node.op: operand type, only support ast.Add/ast.Sub/ast.Mult/ast.Div + node.right: right operan, only support ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp + ''' + left_value = self.get_op_value(node.left) + right_value = self.get_op_value(node.right) + + if isinstance(node.op, ast.Add): + self.value = left_value + right_value + elif isinstance(node.op, ast.Sub): + self.value = left_value - right_value + elif isinstance(node.op, ast.Mult): + self.value = left_value * right_value + elif isinstance(node.op, ast.Div): + self.value = left_value / right_value + else: + raise NotImplementedError("Unsupport arithmetic methods %s" % type(node.op)) + return self.value + + def visit_Call(self, node): + ''' + node.func.id: func name, only support 'float', 'int', 'str' + node.args: func args list,only support ast.Constant(ast.Num/ast.Str)/ast.BinOp/ast.Call + str/float only support one parameter, eg: float(XXX), str(xxx) + int support one or two parameters, eg: int(xxx) or int(xxx, 16) + xxx can be ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp + ''' + calc_tuple = ("float", "int", "str") + + if node.func.id not in calc_tuple: + raise NotImplementedError("Unsupport function call type: %s" % node.func.id) + + args_val_list = [] + for item in node.args: + ret = self.get_op_value(item) + args_val_list.append(ret) + + if node.func.id == "str": + if len(args_val_list) != 1: + raise TypeError("str() takes 1 positional argument but %s were given" % len(args_val_list)) + value = str(args_val_list[0]) + self.value = value + return value + + if node.func.id == "float": + if len(args_val_list) != 1: + raise TypeError("float() takes 1 positional argument but %s were given" % len(args_val_list)) + value = float(args_val_list[0]) + self.value = value + return value + # int + if len(args_val_list) == 1: + value = int(args_val_list[0]) + self.value = value + return value + if len(args_val_list) == 2: + value = int(args_val_list[0], args_val_list[1]) + self.value = value + return value + raise TypeError("int() takes 1 or 2 arguments (%s given)" % len(args_val_list)) + + +class devicebase(object): + _name = None + __error_ret = -99999 + + @property + def name(self): + return self._name + + @name.setter + def name(self, val): + self._name = val + + def dumpValueByI2c(self, bus, loc): + value = "" + for i in range(256): + ret, val = self.get_i2c(bus, loc, i) + value += chr(val) + return value + + def byteTostr(self, val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + def get_eeprom_info(self, conf): + eeprom = "" + if conf.get('way') == 'sysfs': + ret, eeprom = self.get_value(conf) + if ret is False: + return None + elif conf.get('way') == 'devfile': + ret, eeprom_list = self.get_value(conf) + if ret is False: + return None + for item in eeprom_list: + eeprom += chr(item) + else: + eeprom = self.dumpValueByI2c(conf.get('bus'), conf.get('addr')) + return eeprom + + def exec_os_cmd(self, cmd): + cmds = cmd.split('|') + procs = [] + for i, c in enumerate(cmds): + stdin = None if i == 0 else procs[i-1].stdout + p = subprocess.Popen(shlex.split(c), stdin=stdin, stdout=subprocess.PIPE, shell=False, stderr=subprocess.STDOUT) + procs.append(p) + for proc in procs: + proc.wait() + return procs[-1].returncode, self.byteTostr(procs[-1].communicate()[0]) + + def get_value(self, config): + ''' + get value by config way + way i2c/sysfs/lpc + ''' + way = config.get("way") + if way == 'sysfs': + return self.get_sysfs(config.get("loc"), config.get("flock_path")) + if way == "i2c": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.get_i2c(bus, addr, offset) + if way == "io": + io_addr = config.get('io_addr') + read_len = config.get('read_len', 1) + return self.get_io(io_addr, read_len) + if way == "i2cword": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.get_i2cword(bus, addr, offset) + if way == "devmem": + addr = config.get("addr") + digit = config.get("digit") + mask = config.get("mask", None) + return self.get_devmem(addr, digit, mask) + if way == "sdk": + get_type = config.get("type") + if get_type == "bcm_temp": + return self.getbcmtemp() + if get_type == "bcm_reg": + reg = config.get("reg") + return self.getbcmreg(reg) + raise Exception("cannot found sdk type deal") + if way == "devfile": + loc = config.get("loc") + offset = config.get("offset") + length = config.get("len") + ret, val_list = self.devfile_read(loc, offset, length) + if ret is True: + if length == 1: + val = val_list[0] + return True, val + return True, val_list + return False, ("devfile read failed. path:%s, offset:0x%x, read_len:%d" % (loc, offset, length)) + if way == "devfile_ascii": + loc = config.get("loc") + offset = config.get("offset") + length = config.get("len") + return self.devfile_read_ascii(loc, offset, length) + if way == 'cmd': + cmd = config.get("cmd") + ret, log = self.exec_os_cmd(cmd) + if ret: + return False, ("cmd write exec %s failed, log: %s" % (cmd, log)) + return True, log + raise Exception("cannot found way deal") + + def devfile_read(self, loc, offset, length): + return osutil.readdevfile(loc, offset, length) + + def devfile_read_ascii(self, loc, offset, length): + return osutil.readdevfile_ascii(loc, offset, length) + + def get_sysfs(self, loc, flock_path=None): + return self.getsysfs(loc, flock_path) + + def getsysfs(self, loc, flock_path=None): + ret, val = osutil.readsysfs(loc, flock_path) + return ret, val + + def get_devmem(self, addr, digit, mask): + return osutil.getdevmem(addr, digit, mask) + + def get_i2cword(self, bus, addr, offset): + return self.geti2cword(bus, addr, offset) + + def geti2cword(self, bus, addr, offset): + ret, val = osutil.geti2cword(bus, addr, offset) + return ret, val + + def get_io(self, reg_addr, read_len): + return self.getio(reg_addr, read_len) + + def getio(self, reg_addr, read_len): + ret, val = osutil.io_rd(reg_addr, read_len) + return ret, val + + def get_i2c(self, bus, addr, offset): + return self.geti2c(bus, addr, offset) + + def geti2c(self, bus, addr, offset): + ret, val = osutil.wbi2cget(bus, addr, offset) + return ret, val + + def set_value(self, config, val): + ''' + get value by config way + way i2c/sysfs/lpc + ''' + way = config.get("way") + if way == 'sysfs': + return self.set_sysfs(config.get("loc"), "0x%02x" % val) + if way == "i2c": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.set_i2c(bus, addr, offset, val) + if way == "i2cpec": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.seti2c_byte_pec(bus, addr, offset, val) + if way == 'i2cword': + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.set_i2cword(bus, addr, offset, val) + if way == "i2cwordpec": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.set_i2cwordpec(bus, addr, offset, val) + if way == "devfile": + loc = config.get("loc") + offset = config.get("offset") + return self.devfile_write(loc, offset, val) + return False, "unsupport way: %s" % way + + def set_sysfs(self, loc, value): + return self.setsysfs(loc, value) + + def setsysfs(self, loc, value): + return osutil.writesysfs(loc, value) + + def set_i2cword(self, bus, addr, offset, byte): + return self.seti2cword(bus, addr, offset, byte) + + def seti2cword(self, bus, addr, offset, byte): + return osutil.seti2cword(bus, addr, offset, byte) + + def set_i2cwordpec(self, bus, addr, offset, val): + return osutil.seti2cwordpec(bus, addr, offset, val) + + def seti2c_byte_pec(self, bus, addr, offset, val): + return osutil.seti2c_byte_pec(bus, addr, offset, val) + + def set_i2c(self, bus, addr, offset, byte): + return self.seti2c(bus, addr, offset, byte) + + def seti2c(self, bus, addr, offset, byte): + ret, val = osutil.wbi2cset(bus, addr, offset, byte) + return ret, val + + def devfile_write(self, loc, offset, val): + ret, val = osutil.writedevfile(loc, offset, val) + return ret, val + + def getbcmtemp(self): + try: + sta, ret = osutil.getmactemp() + if sta is True: + mac_aver = float(ret.get("average", self.__error_ret)) + mac_aver = mac_aver * 1000 + else: + return False, ret + except AttributeError as e: + return False, str(e) + return True, mac_aver + + def getbcmreg(self, reg): + ret, val = osutil.getsdkreg(reg) + return ret, val + + def logger_debug(self, msg): + baseutil.logger_debug(msg) + + def command(self, cmd): + ret, output = osutil.command(cmd) + return ret, output + + def get_format_value(self, format_str): + ast_obj = ast.parse(format_str, mode='eval') + visitor = CodeVisitor() + visitor.visit(ast_obj) + ret = visitor.get_value() + return ret diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/fan.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/fan.py new file mode 100644 index 000000000000..8b503bf6418f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/fan.py @@ -0,0 +1,413 @@ +#!/usr/bin/env python3 +####################################################### +# +# fan.py +# Python implementation of the Class fan +# +####################################################### +from eepromutil.fru import ipmifru +from eepromutil.fantlv import fan_tlv +from plat_hal.devicebase import devicebase +from plat_hal.rotor import rotor + + +class fan(devicebase): + __rotor_list = [] + __pn = None + __raweeprom = None + __sn = None + __hw_version = None + __e2loc = None + __rotors = None + __AirFlow = None + __SpeedMin = None + __SpeedMax = None + __PowerMax = None + __productName = None + __productSerialNumber = None + __WatchdogStatus = None + __led_attrs_config = None + __led_config = None + __WatchdogStatus_config = None + __AirFlowconifg = None + __EnableWatchdogConf = None + __Rotor_config = None + __fan_display_name = None # 'N/A' + __fan_display_name_conifg = None + + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.sn = conf.get('sn', None) + self.present = conf.get('present', None) + self.e2loc = conf.get('e2loc', None) + self.SpeedMin = conf.get('SpeedMin', None) + self.SpeedMax = conf.get('SpeedMax', None) + self.PowerMax = conf.get('PowerMax', None) + self.AirFlowconifg = conf.get("airflow", None) + self.WatchdogStatus_config = conf.get('WatchdogStatus', None) + self.EnableWatchdogConf = conf.get('EnableWatchdogConf', None) + self.led_attrs_config = conf.get('led_attrs', None) + self.led_config = conf.get('led', None) + self.Rotor_config = conf.get('Rotor', None) + self.fan_display_name_conifg = conf.get("fan_display_name", None) + rotor_tmp = [] + for value in self.Rotor_config.values(): + rotor_tmp.append(rotor(value)) + rotor_tmp.sort(key=lambda x: x.name, reverse=False) + self.rotor_list = rotor_tmp + self.rotors = len(self.rotor_list) + + @property + def EnableWatchdogConf(self): + return self.__EnableWatchdogConf + + @EnableWatchdogConf.setter + def EnableWatchdogConf(self, val): + self.__EnableWatchdogConf = val + + @property + def rotor_list(self): + return self.__rotor_list + + @rotor_list.setter + def rotor_list(self, val): + self.__rotor_list = val + + @property + def Rotor_config(self): + return self.__Rotor_config + + @Rotor_config.setter + def Rotor_config(self, val): + self.__Rotor_config = val + + @property + def productName(self): + return self.__productName + + @productName.setter + def productName(self, val): + self.__productName = val + + @property + def productSerialNumber(self): + return self.__productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, val): + self.__productSerialNumber = val + + @property + def hw_version(self): + return self.__hw_version + + @hw_version.setter + def hw_version(self, val): + self.__hw_version = val + + @property + def sn(self): + return self.__sn + + @sn.setter + def sn(self, val): + self.__sn = val + + @property + def pn(self): + return self.__pn + + @pn.setter + def pn(self, val): + self.__pn = val + + @property + def raweeprom(self): + return self.__raweeprom + + @raweeprom.setter + def raweeprom(self, val): + self.__raweeprom = val + + @property + def SpeedMax(self): + return self.__SpeedMax + + @SpeedMax.setter + def SpeedMax(self, val): + self.__SpeedMax = val + + @property + def SpeedMin(self): + return self.__SpeedMin + + @SpeedMin.setter + def SpeedMin(self, val): + self.__SpeedMin = val + + @property + def PowerMax(self): + return self.__PowerMax + + @PowerMax.setter + def PowerMax(self, val): + self.__PowerMax = val + + @property + def rotors(self): + return self.__rotors + + @property + def AirFlow(self): + return self.__AirFlow + + @AirFlow.setter + def AirFlow(self, val): + self.__AirFlow = val + + @rotors.setter + def rotors(self, val): + self.__rotors = val + + @property + def fan_display_name_conifg(self): + return self.__fan_display_name_conifg + + @fan_display_name_conifg.setter + def fan_display_name_conifg(self, val): + self.__fan_display_name_conifg = val + + @property + def fan_display_name(self): + return self.__fan_display_name + + @fan_display_name.setter + def fan_display_name(self, val): + self.__fan_display_name = val + + def getspeed(self, conf): + tmp = None + if conf is None: + return -1 + ret, val = self.get_value(conf) + if ret is True: + tmp = int(str(val), 10) + else: + val = None + if val is not None: + return int(15000000 / tmp) + return -1 + + def get_speed(self, rotor_index): + rotor_item = self.get_rotor_index(rotor_index) + if rotor_item is None: + return None + speed = rotor_item.rotor_Speed.Value + if speed is None: + return None + return int(speed) + + def set_led(self, color): + status = self.led_attrs_config.get(color, None) + if status is None: + return False + + mask = self.led_attrs_config.get('mask', 0xff) + ret, value = self.get_value(self.led_config) + if ret is False or value is None: + return False + setval = (int(value) & ~mask) | (status) + ret, val = self.set_value(self.led_config, setval) + return ret + + def get_led(self): + mask = self.led_attrs_config.get('mask', 0xff) + ret, value = self.get_value(self.led_config) + if ret is False or value is None: + return False, 'N/A' + ledval = int(value) & mask + for key, val in self.led_attrs_config.items(): + if (ledval == val) and (key != "mask"): + return True, key + return False, 'N/A' + + def set_speed(self, rotor_index, level): + if level > 255 or level < 0: + return False + rotor_item = self.get_rotor_index(rotor_index) + if rotor_item is None: + return False + ret, val = self.set_value(rotor_item.Speedconfig, int(level)) + return ret + + def get_rotor_index(self, rotor_index): + if rotor_index > len(self.rotor_list): + return None + rotor_item = self.rotor_list[rotor_index - 1] + return rotor_item + + def get_rotor_byname(self, rotor_index): + for rotor_item in self.rotor_list: + if rotor_item.name == rotor_index: + return rotor_item + return None + + def get_presence(self): + ret, val = self.get_value(self.present) + if ret is False or val is None: + return -1 + if isinstance(val, str): + value = int(val, 16) + else: + value = val + mask = self.present.get("mask") + flag = value & mask + okval = self.present.get("okval", 0) + if flag == okval: + return True + return False + + def get_speed_pwm(self, rotor_index): + rotor_item = self.get_rotor_index(rotor_index) + if rotor_item is None: + return False + if rotor_item.i2c_speed is None: + return False + val = round(rotor_item.i2c_speed * 100 / 255) + return val + + def feed_watchdog(self): + ret = False + for rotor_item in self.rotor_list: + ret, val = rotor_item.feed_watchdog() + if ret is False: + return ret + return ret + + def get_fru_info(self): + try: + if self.get_presence() is False: + raise Exception("%s: not present" % self.name) + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s: value is none" % self.name) + fru = ipmifru() + if isinstance(eeprom, bytes): + eeprom = self.byteTostr(eeprom) + fru.decodeBin(eeprom) + self.productName = fru.productInfoArea.productName.strip() # PN + self.productSerialNumber = fru.productInfoArea.productSerialNumber.strip() # SN + self.hw_version = fru.productInfoArea.productVersion.strip() # HW + except Exception: + self.productName = None + self.productSerialNumber = None + self.hw_version = None + return False + return True + + def get_tlv_info(self): + try: + if self.get_presence() is False: + raise Exception("%s: not present" % self.name) + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s: value is none" % self.name) + tlv = fan_tlv() + rets = tlv.decode(eeprom) + for item in rets: + if item["name"] == "Product Name": + self.productName = item["value"].replace("\x00", "").strip() + elif item["name"] == "serial Number": + self.productSerialNumber = item["value"].replace("\x00", "").strip() + elif item["name"] == "hardware info": + self.hw_version = item["value"].replace("\x00", "").strip() + except Exception: + self.productName = None + self.productSerialNumber = None + self.hw_version = None + return False + return True + + def decode_eeprom_info(self): + '''get fan name, hw version, sn''' + ret = self.get_tlv_info() + if ret is True: + return ret + return self.get_fru_info() + + def get_AirFlow(self): + if self.productName is None: + ret = self.decode_eeprom_info() + if ret is False: + self.AirFlow = None + return False + if self.AirFlowconifg is None: + self.AirFlow = None + return False + for i in self.AirFlowconifg: + if self.productName in self.AirFlowconifg[i]: + self.AirFlow = i + return True + self.AirFlow = None + return False + + def enable_watchdog(self, enable): + ret = False + if enable is True: + byte = self.EnableWatchdogConf.get("enable_byte", None) + ret, val = self.set_value(self.EnableWatchdogConf, byte) + elif enable is False: + byte = self.EnableWatchdogConf.get("disable_byte", None) + ret, val = self.set_value(self.EnableWatchdogConf, byte) + return ret + + def get_watchdog_status(self): + dic = {"support": None, "open": None, "work_full": None, "work_allow_set": None} + if self.WatchdogStatus_config is None: + return None + ret, val = self.get_value(self.WatchdogStatus_config) + if ret is False or val is None: + return None + support_watchdog_off = self.WatchdogStatus_config.get("support_watchdog_off", None) + is_open_off = self.WatchdogStatus_config.get("is_open_off", None) + full_running_off = self.WatchdogStatus_config.get("full_running_off", None) + running_setting_off = self.WatchdogStatus_config.get("running_setting_off", None) + if support_watchdog_off is not None: + if support_watchdog_off & val == self.WatchdogStatus_config.get("support_watchdog_mask", None): + dic["support"] = True + else: + dic["support"] = False + return dic + if is_open_off is not None: + if is_open_off & val == self.WatchdogStatus_config.get("is_open_mask", None): + dic["open"] = True + else: + dic["open"] = False + if full_running_off is not None: + if full_running_off & val == self.WatchdogStatus_config.get("full_running_mask", None): + dic["work_full"] = True + else: + dic["work_full"] = False + if running_setting_off is not None: + if running_setting_off & val == self.WatchdogStatus_config.get("running_setting_mask", None): + dic["work_allow_set"] = True + else: + dic["work_allow_set"] = False + return dic + + def get_fan_display_name(self): + if self.productName is None: + ret = self.get_fru_info() + if ret is False: + self.fan_display_name = None + return False + if self.fan_display_name_conifg is None: + self.fan_display_name = self.productName + return False + for i in self.fan_display_name_conifg: + if self.productName in self.fan_display_name_conifg[i]: + self.fan_display_name = i + return True + self.fan_display_name = self.productName + return False diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/interface.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/interface.py new file mode 100644 index 000000000000..161149eed33d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/interface.py @@ -0,0 +1,1311 @@ +#!/usr/bin/env python3 +####################################################### +# +# interface.py +# Python implementation of the Class interface +# +####################################################### +import collections +from plat_hal.chassisbase import chassisbase +from plat_hal.baseutil import baseutil +from plat_hal.osutil import osutil + + +def Singleton(cls): + _instance = {} + + def _singleton(*args, **kargs): + if cls not in _instance: + _instance[cls] = cls(*args, **kargs) + return _instance[cls] + + return _singleton + + +@Singleton +class interface(object): + __chas = None + __error_ret = None + + def __init__(self): + self.chas = chassisbase() + self.__error_ret = -99999 + self.__na_ret = 'N/A' + + @property + def na_ret(self): + return self.__na_ret + + @na_ret.setter + def na_ret(self, val): + self.__na_ret = val + + @property + def error_ret(self): + return self.__error_ret + + @error_ret.setter + def error_ret(self, val): + self.__error_ret = val + + @property + def chas(self): + return self.__chas + + @chas.setter + def chas(self, val): + self.__chas = val + + # onie_e2 + def get_onie_e2(self): + onie_e2_list = self.chas.onie_e2_list + return onie_e2_list + + def get_onie_e2_path(self, name): + onie_e2 = self.chas.get_onie_e2_byname(name) + if onie_e2 is None: + return None + return onie_e2.e2_path + + def get_device_airflow(self, name): + onie_e2 = self.chas.get_onie_e2_byname(name) + if onie_e2 is None: + return None + return onie_e2.airflow + + def get_onie_e2_obj(self, name): + onie_e2 = self.chas.get_onie_e2_byname(name) + if onie_e2 is None: + return None + onie_e2.get_onie_e2_info() + return onie_e2 + + # temp + def get_temps(self): + templist = self.chas.temp_list + return templist + + def get_temp_total_number(self): + templist = self.chas.temp_list + return len(templist) + + def check_temp_id_exist(self, temp_id): + templist = self.chas.temp_list + for temp in templist: + if temp.temp_id == temp_id: + return True + return False + + def get_temp_id_number(self): + templist = self.chas.temp_list + temp_num = 0 + for i in range(len(templist)): + temp_id = "TEMP" + str(i + 1) + ret = self.check_temp_id_exist(temp_id) + if ret is True: + temp_num = temp_num + 1 + else: + return temp_num + return temp_num + + def get_temp_location(self, temp_name): + temp = self.chas.get_temp_byname(temp_name) + return temp.get_location() + + def set_temp_location(self, temp_name, location): + temp = self.chas.get_temp_byname(temp_name) + return temp.set_location(location) + + def set_temp_name(self, temp_name, name): + temp = self.chas.get_temp_byname(temp_name) + return temp.set_name(name) + + def get_appoint_temp(self, temp_name): + temp = self.chas.get_led_byname(temp_name) + return temp.get_temp() + + def set_appoint_temp(self, temp_name, val): + temp = self.chas.get_temp_byname(temp_name) + return temp.set_temp(val) + + def get_temp_mintemp(self, temp_name): + temp = self.chas.get_temp_byname(temp_name) + return temp.get_mintemp() + + def set_temp_mintemp(self, temp_name, val): + temp = self.chas.get_temp_byname(temp_name) + return temp.set_mintemp(val) + + # led + def get_leds(self): + ledlist = self.chas.led_list + return ledlist + + def get_led_total_number(self): + ledlist = self.chas.led_list + return len(ledlist) + + def get_led_color(self, led_name): + led = self.chas.get_led_byname(led_name) + if led is None: + return -1 + return led.get_color() + + def get_led_color_by_type(self, led_type): + ledlist = self.chas.led_list + ledtmp = None + for temp in ledlist: + if temp.led_type == led_type: + ledtmp = temp + break + if ledtmp is None: + return -1 + return ledtmp.get_color() + + def set_led_color(self, led_name, color): + led = self.chas.get_led_byname(led_name) + if led is None: + return -1 + return led.set_color(color) + + # psu + def get_psu_total_number(self): + psulist = self.chas.psu_list + if psulist is None: + return -1 + return len(psulist) + + def get_psus(self): + psulist = self.chas.psu_list + return psulist + + def get_psu_presence(self, psu_name): + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + return psu.present + + def get_psu_fru_info(self, psu_name): + ''' + { + "Name": "PSU1", + "SN": "serial_number_example", # 'N/A' + "PN": "part_number_example", # 'N/A' + "AirFlow": "B2F" # 'N/A' + } + ''' + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + psu.get_fru_info() + psu.get_AirFlow() + psu.get_psu_display_name() + + dic = collections.OrderedDict() + dic["Name"] = psu.name + dic["SN"] = psu.productSerialNumber if (psu.productSerialNumber is not None) else self.na_ret + dic["PN"] = psu.productPartModelName if (psu.productPartModelName is not None) else self.na_ret + dic["DisplayName"] = psu.psu_display_name if (psu.psu_display_name is not None) else self.na_ret + dic["VENDOR"] = psu.productManufacturer if (psu.productManufacturer is not None) else self.na_ret + dic["HW"] = psu.productVersion if (psu.productVersion is not None) else self.na_ret + dic["AirFlow"] = psu.AirFlow if (psu.AirFlow is not None) else self.na_ret + return dic + + def get_psu_input_output_status(self, psu_name): + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + psu.InputsCurrent.Value # just for clear faults + if (psu.InputStatus is True) and (psu.OutputStatus is True): + return True + return False + + def get_psu_status(self, psu_name): + """ + Get status of a specific PSU + @return dict of the specific PSU's status, None for failure + Example return value(all keys are mandatory) + { + "Name": "PSU1", + "InputType": "DC", # "AC" or 'N/A' + "InputStatus": True, # H/W status bit + "OutputStatus": True # H/W status bit + "FanSpeed": { + "Value": 4000, # -99999 + "Min": 2000, # -99999 + "Max": 10000 # -99999 + }, + "Temperature": { + "Value": 40.0, # -99999.0 + "Min": -30.0, # -99999.0 + "Max": 50.0 # -99999.0 + } + } + """ + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + + dic = collections.OrderedDict() + # psu.get_Temperature() + temp_dict = collections.OrderedDict() + temp_dict['Min'] = psu.Temperature.Min + temp_dict['Max'] = psu.Temperature.Max + temp_dict['Value'] = psu.Temperature.Value + temp_dict['Unit'] = psu.Temperature.Unit + dic["Temperature"] = temp_dict + + # psu.get_FanSpeed() + fan_speed_dict = collections.OrderedDict() + fan_speed_dict['Min'] = psu.FanSpeed.Min + fan_speed_dict['Max'] = psu.FanSpeed.Max + fan_speed_dict['Tolerance'] = psu.FanSpeedTolerance + fan_speed_dict['Value'] = psu.FanSpeed.Value + fan_speed_dict['Unit'] = psu.FanSpeed.Unit + dic["FanSpeed"] = fan_speed_dict + + dic["Name"] = psu.name + dic["InputType"] = psu.InputsType + dic["InputStatus"] = psu.InputStatus + dic["OutputStatus"] = psu.OutputStatus + dic["TempStatus"] = psu.TempStatus + dic["FanStatus"] = psu.FanStatus + return dic + + def get_psu_power_status(self, psu_name): + """ + Get power status of a specific PSU + @return dict of the specific PSU's power status, None for failure + Example return value + { + "Name": "PSU1", + "Inputs": { + "Status": True, # H/W status bit + "Type": "DC", # or "AC" or "N/A" + "Voltage": { + "Value": 220, # -1 + "LowAlarm": 200, # -1 + "HighAlarm": 240, # -1 + "Unit": "V" + }, + "Current": { + "Value": 6.0, # -99999.0 + "LowAlarm": 0.2, # -99999.0 + "HighAlarm": 7.0, # -99999.0 + "Unit": "A" + }, + "Power": { + "Value": 1000, # -99999 + "LowAlarm": -1, # -99999 + "HighAlarm": 1400, # -99999 + "Unit": "W" + } + }, + "Outputs": { + "Status": True, + "Voltage": { + "Value": 220, + "LowAlarm": 200, + "HighAlarm": 240, + "Unit": "V" + }, + "Current": { + "Value": 6.0, + "LowAlarm": 0.2, + "HighAlarm": 7.0, + "Unit": "A" + }, + "Power": { + "Value": 1000, + "LowAlarm": -1, # Don't care + "HighAlarm": 1400, + "Unit": "W" + } + } + } + """ + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + + dic = collections.OrderedDict() + inputdic = collections.OrderedDict() + Outputsdic = collections.OrderedDict() + dic["Name"] = psu.name + inputdic["Status"] = psu.InputStatus + inputdic["Type"] = psu.InputsType + + # psu.get_InputsVoltage() + inputdic_voltage = collections.OrderedDict() + + inputdic_voltage["Value"] = psu.InputsVoltage.Value + inputdic_voltage["LowAlarm"] = psu.InputsVoltage.Min + inputdic_voltage["HighAlarm"] = psu.InputsVoltage.Max + inputdic_voltage["Unit"] = psu.InputsVoltage.Unit + + inputdic["Voltage"] = inputdic_voltage + inputdic_current = collections.OrderedDict() + inputdic_current["Value"] = psu.InputsCurrent.Value + inputdic_current["LowAlarm"] = psu.InputsCurrent.Min + inputdic_current["HighAlarm"] = psu.InputsCurrent.Max + inputdic_current["Unit"] = psu.InputsCurrent.Unit + inputdic["Current"] = inputdic_current + + inputdic_power = collections.OrderedDict() + inputdic_power["Value"] = psu.InputsPower.Value + inputdic_power["LowAlarm"] = psu.InputsPower.Min + inputdic_power["HighAlarm"] = psu.InputsPower.Max + inputdic_power["Unit"] = psu.InputsPower.Unit + inputdic["Power"] = inputdic_power + Outputsdic["Status"] = psu.InputStatus + + outputdic_voltage = collections.OrderedDict() + outputdic_current = collections.OrderedDict() + outputdic_power = collections.OrderedDict() + + outputdic_voltage["Value"] = psu.OutputsVoltage.Value + outputdic_voltage["LowAlarm"] = psu.OutputsVoltage.Min + outputdic_voltage["HighAlarm"] = psu.OutputsVoltage.Max + outputdic_voltage["Unit"] = psu.OutputsVoltage.Unit + + outputdic_current["Value"] = psu.OutputsCurrent.Value + outputdic_current["LowAlarm"] = psu.OutputsCurrent.Min + outputdic_current["HighAlarm"] = psu.OutputsCurrent.Max + outputdic_current["Unit"] = psu.OutputsCurrent.Unit + + outputdic_power["Value"] = psu.OutputsPower.Value + outputdic_power["LowAlarm"] = psu.OutputsPower.Min + outputdic_power["HighAlarm"] = psu.OutputsPower.Max + outputdic_power["Unit"] = psu.OutputsPower.Unit + + Outputsdic["Voltage"] = outputdic_voltage + Outputsdic["Current"] = outputdic_current + Outputsdic["Power"] = outputdic_power + + dic["Inputs"] = inputdic + dic["Outputs"] = Outputsdic + + return dic + + def set_psu_fan_speed_pwm(self, psu_name, pwm): + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + return psu.set_fan_speed_pwm(pwm) + + def get_psu_fan_speed_pwm(self, psu_name): + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + return psu.get_fan_speed_pwm() + + def get_psu_info_all(self): + """ + { + "Number": 2, + "PSU1": { + "SN": "serial_number_example", # 'N/A' + "PN": "part_number_example", # 'N/A' + "AirFlow": "intake", # 'N/A' + + "FanSpeed": { + "Value": 4000, + "Min": 2000, + "Max": 30000 + }, + "Temperature": { + "Value": 35.0, + "Min": -20.0, + "Max": 45.0 + }, + "Inputs": { + "Status": True, # H/W status bit + "Type": "DC", # or "AC" + "Voltage": { + "Value": 220, + "LowAlarm": 200, + "HighAlarm": 240, + "Unit": "V" + }, + "Current": { + "Value": 6.0, + "LowAlarm": 0.2, + "HighAlarm": 7.0, + "Unit": "A" + }, + "Power": { + "Value": 1000, + "LowAlarm": -1, + "HighAlarm": 1400, + "Unit": "W" + } + }, + "Outputs": { + "Status": True, + "Voltage": { + "Value": 220, + "LowAlarm": 200, + "HighAlarm": 240, + "Unit": "V" + }, + "Current": { + "Value": 6.0, + "LowAlarm": 0.2, + "HighAlarm": 7.0, + "Unit": "A" + }, + "Power": { + "Value": 1000, + "LowAlarm": -1, # Don't care + "HighAlarm": 1400, + "Unit": "W" + } + } + } + } + """ + + psus = self.get_psus() + psu_dict = collections.OrderedDict() + psu_dict['Number'] = len(psus) + for psu in psus: + dicttmp = self.get_psu_fru_info(psu.name) + dicttmp.update(self.get_psu_status(psu.name)) + dicttmp.update(self.get_psu_power_status(psu.name)) + if self.get_psu_presence(psu.name) is True: + dicttmp['Present'] = 'yes' + else: + dicttmp['Present'] = 'no' + psu_dict[psu.name] = dicttmp + return psu_dict + + def get_fans(self): + fanlist = self.chas.fan_list + return fanlist + + # fan + def get_fan_total_number(self): + fanlist = self.chas.fan_list + if fanlist is None: + return -1 + return len(fanlist) + + def get_fan_rotor_number(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + ret = fan.rotors + if ret is None: + return -1 + return ret + + def get_fan_speed(self, fan_name, rotor_index): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + ret = fan.get_speed(rotor_index) + if ret is None: + return -1 + return ret + + def fan_speed_set_level(self, fan_name, rotor_index, level): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + ret = fan.set_speed(rotor_index, level) + if ret is True: + return 0 + return -1 + + def get_fan_speed_pwm(self, fan_name, rotor_index): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + val = fan.get_speed_pwm(rotor_index) + if val is False: + return -1 + return val + + def set_fan_speed_pwm(self, fan_name, rotor_index, pwm): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + if isinstance(pwm, str): + rate = float(pwm.strip('%s')) + speed = round(rate * 255 / 100) + elif isinstance(pwm, int): + speed = round(pwm * 255 / 100) + elif isinstance(pwm, float): + speed = round(pwm * 255 / 100) + else: + return -1 + ret = self.fan_speed_set_level(fan.name, rotor_index, speed) + if ret == 0: + return 0 + return -1 + + def get_fan_watchdog_status(self): + fan = self.chas.fan_list[0] + dic = fan.get_watchdog_status() + if dic is None or dic["support"] is False: + return self.na_ret + if dic["open"] is False or dic["work_allow_set"] is True: + return "Normal" + if dic["work_full"] is True: + return "Abnormal" + return "Abnormal" + + def enable_fan_watchdog(self, enable=True): + fan = self.chas.fan_list[0] + ret = fan.enable_watchdog(enable) + if ret is True: + return 0 + return -1 + + def feed_fan_watchdog(self): + fan_list = self.chas.fan_list + if fan_list is None: + return -1 + for fan in fan_list: + ret = fan.feed_watchdog() + if ret is False: + return -1 + return 0 + + def set_fan_led(self, fan_name, color): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + ret = fan.set_led(color) + if ret is True: + return 0 + return -1 + + def get_fan_led(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return False, 'N/A' + return fan.get_led() + + def get_fan_presence(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + return fan.get_presence() + + def get_fan_fru_info(self, fan_name): + """ + Get specific fan's information + # Properties + "Name": "FAN1", + "SN": "serial_number_example", # 'N/A' + "PN": "part_number_exampple", # 'N/A' + "Rotors": 2, # -1 + "AirFlow": "intake", # 'N/A' + "SpeedMin": 2000, # -1 + "SpeedMax": 30000 # -1 + """ + fan = self.chas.get_fan_byname(fan_name) + fan.get_fru_info() + fan.get_AirFlow() + fan.get_fan_display_name() + + dic = collections.OrderedDict() + dic["Name"] = fan.name + dic["SN"] = fan.productSerialNumber + if dic["SN"] is None: + dic["SN"] = self.na_ret + dic["PN"] = fan.productName + if dic["PN"] is None: + dic["PN"] = self.na_ret + dic["DisplayName"] = fan.fan_display_name + if dic["DisplayName"] is None: + dic["DisplayName"] = self.na_ret + + dic["Rotors"] = fan.rotors + dic["AirFlow"] = fan.AirFlow + if dic["AirFlow"] is None: + dic["AirFlow"] = self.na_ret + dic["SpeedMin"] = fan.SpeedMin + dic["SpeedMax"] = fan.SpeedMax + return dic + + def get_fan_eeprom_info(self, fan_name): + """ + Get specific fan's information + # Properties + "Name": "M6510-FAN-F", # 'N/A' + "SN": "serial_number_example", # 'N/A' + "HW": "hw_version_exampple", # 'N/A' + """ + fan = self.chas.get_fan_byname(fan_name) + fan.decode_eeprom_info() + dic = collections.OrderedDict() + dic["NAME"] = fan.productName + if dic["NAME"] is None: + dic["NAME"] = self.na_ret + dic["SN"] = fan.productSerialNumber + if dic["SN"] is None: + dic["SN"] = self.na_ret + dic["HW"] = fan.hw_version + if dic["HW"] is None: + dic["HW"] = self.na_ret + + return dic + + def get_product_fullname(self): + return baseutil.get_product_fullname() + + def get_fan_status(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + rotorlist = fan.rotor_list + dic = collections.OrderedDict() + for rotor in rotorlist: + dic_val = collections.OrderedDict() + if rotor.rotor_Running is True: + dic_val['Running'] = 'yes' + else: + dic_val['Running'] = 'no' + if rotor.rotor_HwAlarm is True: + dic_val['HwAlarm'] = 'yes' + else: + dic_val['HwAlarm'] = 'no' + dic_val['Speed'] = int(rotor.rotor_Speed.Value) + dic[rotor.name] = dic_val + return dic + + def get_fan_rotor_status(self, fan_name, rotor_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + rotorlist = fan.rotor_list + for rotor in rotorlist: + if rotor_name == rotor.name: + if rotor.rotor_Running is True: + return True + return False + return -1 + + def get_fan_roll_status(self, fan_name, rotor_index): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + rotor = fan.get_rotor_index(rotor_index) + if rotor is None: + return -1 + if rotor.rotor_Running is True: + return True + return False + + def get_fan_info_fru(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + fan.get_fru_info() + fan.get_AirFlow() + dic = collections.OrderedDict() + dic["Name"] = fan.name + dic["SN"] = fan.productSerialNumber + if dic["SN"] is None: + dic["SN"] = self.na_ret + dic["PN"] = fan.productPartModelName + if dic["PN"] is None: + dic["PN"] = self.na_ret + flag = self.get_fan_presence(fan_name) + if flag is True: + dic["Present"] = "yes" + elif flag is False: + dic["Present"] = "no" + else: + dic["Present"] = self.na_ret + dic["Rotors"] = fan.rotors + dic["AirFlow"] = fan.AirFlow + if dic["AirFlow"] is None: + dic["AirFlow"] = self.na_ret + return dic + + # support TLV and FRU FAN E2 + def get_fan_info(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return None + fan.get_AirFlow() + dic = self.get_fan_eeprom_info(fan_name) + flag = self.get_fan_presence(fan_name) + if flag is True: + dic["Present"] = "yes" + elif flag is False: + dic["Present"] = "no" + else: + dic["Present"] = self.na_ret + dic["Rotors"] = fan.rotors + dic["AirFlow"] = fan.AirFlow + if dic["AirFlow"] is None: + dic["AirFlow"] = self.na_ret + dic["PowerMax"] = fan.PowerMax + if dic["PowerMax"] is None: + dic["PowerMax"] = self.na_ret + return dic + + def get_fan_info_rotor(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + rotorlist = fan.rotor_list + dic = collections.OrderedDict() + for rotor in rotorlist: + dic_val = collections.OrderedDict() + if rotor.rotor_Running is True: + dic_val['Running'] = 'yes' + else: + dic_val['Running'] = 'no' + if rotor.rotor_HwAlarm is True: + dic_val['HwAlarm'] = 'yes' + else: + dic_val['HwAlarm'] = 'no' + speed_value = rotor.rotor_Speed.Value + if speed_value is None: + dic_val['Speed'] = self.error_ret + else: + dic_val['Speed'] = int(speed_value) + if rotor.SpeedMin is None: + dic_val['SpeedMin'] = self.error_ret + else: + dic_val['SpeedMin'] = rotor.SpeedMin + if rotor.SpeedMax is None: + dic_val['SpeedMax'] = self.error_ret + else: + dic_val['SpeedMax'] = rotor.SpeedMax + if rotor.Tolerance is None: + dic_val['Tolerance'] = self.error_ret + else: + dic_val['Tolerance'] = rotor.Tolerance + + dic[rotor.name] = dic_val + return dic + + def get_fan_info_all(self): + fanlist = self.chas.fan_list + dic = collections.OrderedDict() + dic['Number'] = len(fanlist) + dic['WatchdogStatus'] = self.get_fan_watchdog_status() + for fan in fanlist: + dic[fan.name] = self.get_fan_info(fan.name) + dic[fan.name].update(self.get_fan_info_rotor(fan.name)) + return dic + + def temp_test(self): + templist = self.chas.temp_list + dicret = collections.OrderedDict() + + for temp in templist: + dic = collections.OrderedDict() + temp_value = temp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["LowAlarm"] = temp.Min + dic["HighAlarm"] = temp.Max + dicret[temp.name] = dic + return dicret + + # dcdc + def get_dcdc_total_number(self): + dcdclist = self.chas.dcdc_list + if dcdclist is None: + return -1 + return len(dcdclist) + + def get_dcdc_by_id(self, dcdc_id): + dcdclist = self.chas.dcdc_list + dcdctmp = None + for dcdc in dcdclist: + if dcdc.dcdc_id == dcdc_id: + dcdctmp = dcdc + dic = collections.OrderedDict() + if dcdctmp is None: + dic["Name"] = self.error_ret + dic["Min"] = self.error_ret + dic["Max"] = self.error_ret + dic["Low"] = self.error_ret + dic["High"] = self.error_ret + dic["Value"] = self.error_ret + dic["Unit"] = self.error_ret + else: + dic["Name"] = dcdctmp.name + dic["Min"] = dcdctmp.sensor.Min + dic["Max"] = dcdctmp.sensor.Max + dic["Low"] = dcdctmp.sensor.Low + dic["High"] = dcdctmp.sensor.High + tmp = dcdctmp.sensor.Value + if tmp is not None: + dic['Value'] = tmp + else: + dic['Value'] = self.error_ret + dic["Unit"] = dcdctmp.sensor.Unit + return dic + + def get_dcdc_all_info(self): + val_list = collections.OrderedDict() + dcdclist = self.chas.dcdc_list + for dcdc in dcdclist: + dicttmp = {} + sensorname = "%s" % (dcdc.name) + dicttmp['Min'] = dcdc.sensor.Min + dicttmp['Max'] = dcdc.sensor.Max + tmp = dcdc.sensor.Value + if tmp is not None: + dicttmp['Value'] = tmp + else: + dicttmp['Value'] = self.error_ret + dicttmp['Unit'] = dcdc.sensor.Unit + val_list[sensorname] = dicttmp + return val_list + + # sensors + def get_monitor_temp(self, name): + templist = self.chas.temp_list + temptmp = None + for temp in templist: + if temp.name == name: + temptmp = temp + + dic = collections.OrderedDict() + if temptmp is None: + dic["Min"] = self.error_ret + dic["Max"] = self.error_ret + dic["Value"] = self.error_ret + dic["Unit"] = self.error_ret + else: + dic["Min"] = temptmp.Min + dic["Max"] = temptmp.Max + temp_value = temptmp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temptmp.Unit + return dic + + def get_monitor_temp_by_id(self, temp_id): + templist = self.chas.temp_list + temptmp = None + for temp in templist: + if temp.temp_id == temp_id: + temptmp = temp + + dic = collections.OrderedDict() + if temptmp is None: + dic["Name"] = self.error_ret + dic["Api_name"] = self.error_ret + dic["Min"] = self.error_ret + dic["Max"] = self.error_ret + dic["Low"] = self.error_ret + dic["High"] = self.error_ret + dic["Value"] = self.error_ret + dic["Unit"] = self.error_ret + else: + dic["Name"] = temptmp.name + dic["Api_name"] = temptmp.api_name + dic["Min"] = temptmp.Min + dic["Max"] = temptmp.Max + dic["Low"] = temptmp.Low + dic["High"] = temptmp.High + temp_value = temptmp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temptmp.Unit + return dic + + def get_temp_info(self): + val_list = collections.OrderedDict() + # temp + templist = self.chas.temp_list + for temp in templist: + dic = collections.OrderedDict() + dic["Min"] = temp.Min + dic["Max"] = temp.Max + dic["Low"] = temp.Low + dic["High"] = temp.High + temp_value = temp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temp.Unit + val_list[temp.name] = dic + return val_list + + def get_sensor_info(self): + val_list = collections.OrderedDict() + # temp + templist = self.chas.temp_list + for temp in templist: + dic = collections.OrderedDict() + dic["Min"] = temp.Min + dic["Max"] = temp.Max + dic["Low"] = temp.Low + dic["High"] = temp.High + temp_value = temp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temp.Unit + val_list[temp.name] = dic + # fan + fanlist = self.chas.fan_list + for fan in fanlist: + for rotor in fan.rotor_list: + sensorname = "%s%s" % (fan.name, rotor.name) + speed = collections.OrderedDict() + speed['Min'] = rotor.rotor_Speed.Min + speed['Max'] = rotor.rotor_Speed.Max + rotor_speed_Value = rotor.rotor_Speed.Value + speed['Value'] = rotor_speed_Value if (rotor_speed_Value is not None) else self.error_ret + speed['Unit'] = rotor.rotor_Speed.Unit + val_list[sensorname] = speed + + val_list.update(self.get_dcdc_all_info()) + + # psu + psulist = self.chas.psu_list + for psu in psulist: + inputdic_voltage = collections.OrderedDict() + inputdic_current = collections.OrderedDict() + inputdic_power = collections.OrderedDict() + outputdic_voltage = collections.OrderedDict() + outputdic_current = collections.OrderedDict() + outputdic_power = collections.OrderedDict() + temperature = collections.OrderedDict() + fanspeed = collections.OrderedDict() + + psu_temp_value = psu.Temperature.Value + temperature["Value"] = psu_temp_value if (psu_temp_value is not None) else self.error_ret + temperature["Min"] = psu.Temperature.Min + temperature["Max"] = psu.Temperature.Max + temperature["Unit"] = psu.Temperature.Unit + + fanspeed["Value"] = psu.FanSpeed.Value + fanspeed["Min"] = psu.FanSpeed.Min + fanspeed["Max"] = psu.FanSpeed.Max + fanspeed["Unit"] = psu.FanSpeed.Unit + + psu_inputvoltage_value = psu.InputsVoltage.Value + inputdic_voltage["Value"] = psu_inputvoltage_value if ( + psu_inputvoltage_value is not None) else self.error_ret + inputdic_voltage["Min"] = psu.InputsVoltage.Min + inputdic_voltage["Max"] = psu.InputsVoltage.Max + inputdic_voltage["Unit"] = psu.InputsVoltage.Unit + + psu_inputcurrent_value = psu.InputsCurrent.Value + inputdic_current["Value"] = psu_inputcurrent_value if ( + psu_inputcurrent_value is not None) else self.error_ret + inputdic_current["Min"] = psu.InputsCurrent.Min + inputdic_current["Max"] = psu.InputsCurrent.Max + inputdic_current["Unit"] = psu.InputsCurrent.Unit + + psu_inputpower_value = psu.InputsPower.Value + inputdic_power["Value"] = psu_inputpower_value if (psu_inputpower_value is not None) else self.error_ret + inputdic_power["Min"] = psu.InputsPower.Min + inputdic_power["Max"] = psu.InputsPower.Max + inputdic_power["Unit"] = psu.InputsPower.Unit + + psu_outputvoltage_value = psu.OutputsVoltage.Value + outputdic_voltage["Value"] = psu_outputvoltage_value if ( + psu_outputvoltage_value is not None) else self.error_ret + outputdic_voltage["Min"] = psu.OutputsVoltage.Min + outputdic_voltage["Max"] = psu.OutputsVoltage.Max + outputdic_voltage["Unit"] = psu.OutputsVoltage.Unit + + psu_outputcurrent_value = psu.OutputsCurrent.Value + outputdic_current["Value"] = psu_outputcurrent_value if ( + psu_outputcurrent_value is not None) else self.error_ret + outputdic_current["Min"] = psu.OutputsCurrent.Min + outputdic_current["Max"] = psu.OutputsCurrent.Max + outputdic_current["Unit"] = psu.OutputsCurrent.Unit + + psu_outputpower_value = psu.OutputsPower.Value + outputdic_power["Value"] = psu_outputpower_value if ( + psu_outputpower_value is not None) else self.error_ret + outputdic_power["Min"] = psu.OutputsPower.Min + outputdic_power["Max"] = psu.OutputsPower.Max + outputdic_power["Unit"] = psu.OutputsPower.Unit + + val_list["%s%s" % (psu.name, "Vol_I")] = inputdic_voltage + val_list["%s%s" % (psu.name, "Curr_I")] = inputdic_current + val_list["%s%s" % (psu.name, "Power_I")] = inputdic_power + val_list["%s%s" % (psu.name, "Vol_O")] = outputdic_voltage + val_list["%s%s" % (psu.name, "Curr_O")] = outputdic_current + val_list["%s%s" % (psu.name, "Power_O")] = outputdic_power + val_list["%s%s" % (psu.name, "Fan")] = fanspeed + val_list["%s%s" % (psu.name, "Temp")] = temperature + + return val_list + + # cpld + def get_cpld_total_number(self): + cpldlist = self.chas.cpld_list + return len(cpldlist) + + def get_cpld_user_reg(self): + cpld = self.chas.get_cpld_byname("BASE_CPLD") + if cpld is None: + return None + return cpld.get_user_reg() + + def set_cpld_user_reg(self, value): + if isinstance(value, int) is False: + baseutil.logger_debug("value must int %s" % type(value)) + return -1 + if (int(value) < 0 or int(value) > 255): + baseutil.logger_debug("value must [0 - 255]") + return -1 + cpld = self.chas.get_cpld_byname("BASE_CPLD") + if cpld is None: + baseutil.logger_debug("name BASE_CPLD not find") + return -1 + if cpld.set_user_reg(value) is True: + return 0 + return -1 + + def set_cpld_console_owner(self, owner): + """ + Set console I/O owner + + @param owner I/O owner of the console, either "cpu" or "bmc" + + @return 0 for success, -1 for failure + """ + if owner is None: + baseutil.logger_debug("owner is None") + return -1 + owner_tuple = ("cpu", "bmc") + if owner not in owner_tuple: + baseutil.logger_debug("owner is %s, must cpu or bmc" % owner) + return -1 + cpld = self.chas.get_cpld_byname("BASE_CPLD") + if cpld is None: + baseutil.logger_debug("name BASE_CPLD not find") + return -1 + if cpld.set_console_owner(owner) is True: + return 0 + return -1 + + def get_cpld_version_by_id(self, cpld_id): + cpldlist = self.chas.cpld_list + cpldtmp = None + for cpld in cpldlist: + if cpld.cpld_id == cpld_id: + cpldtmp = cpld + + dic = collections.OrderedDict() + if cpldtmp is None: + dic["Name"] = self.na_ret + dic["Version"] = self.na_ret + dic["Desc"] = self.na_ret + dic["Slot"] = None + dic["Warm"] = None + else: + dic["Name"] = cpldtmp.name + dic["Version"] = cpldtmp.get_version() + dic["Desc"] = cpldtmp.desc + dic["Slot"] = cpldtmp.slot + dic["Warm"] = cpldtmp.warm + return dic + + def get_cpld_all_version(self): + """ + Get version of all CPLDs' that can be read from BMC + + @return dict of CPLDs' version or None for failure. + example outputs: + { + "BASE_CPLD": "0.1", # or "N/A" for read failure + "FAN_CPLD": "0.2" + } + """ + cpld_version = { + "BASE_CPLD": "N/A", + "FAN_CPLD": "N/A" + } + for cpld_name in cpld_version: + cpld = self.chas.get_cpld_byname(cpld_name) + if cpld is None: + baseutil.logger_debug("name %s not find" % cpld_name) + continue + cpld_version[cpld_name] = cpld.get_version() + return cpld_version + + # comp + def get_comp_total_number(self): + complist = self.chas.comp_list + return len(complist) + + def get_comp_list(self): + return self.chas.comp_list + + def get_comp_id(self, comp): + return comp.comp_id + + def get_comp_version_by_id(self, comp_id): + comp_list = self.chas.comp_list + comptmp = None + for comp in comp_list: + if comp.comp_id == comp_id: + comptmp = comp + break + + dic = collections.OrderedDict() + if comptmp is None: + dic["Name"] = self.na_ret + dic["Version"] = self.na_ret + dic["Desc"] = self.na_ret + dic["Slot"] = None + else: + dic["Name"] = comptmp.name + dic["Version"] = comptmp.get_version() + dic["Desc"] = comptmp.desc + dic["Slot"] = comptmp.slot + return dic + + def get_bmc_productname(self): + """ + Get product name + + @return product name string, e.g. $(device name)-F-$(VENDOR_NAME), if error return "N/A" + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name bmc(master) not find") + return self.na_ret + return bmc.get_productname() + + def call_bmc_diagcmd(self, cmdstr): + """ + Call BMC diag comman func + + @return ret: 0 sucess , -1 fail + outmsg: if success is out msg, or fail is err msg + """ + if (cmdstr is None or cmdstr == ""): + outmsg = "cmdstr is empty" + baseutil.logger_debug(outmsg) + return -1, outmsg + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + outmsg = "name bmc(master) not find" + baseutil.logger_debug(outmsg) + return -1, outmsg + baseutil.logger_debug("call cmdstr %s" % cmdstr) + return bmc.call_diagcmd(cmdstr) + + def write_bios_version(self, flash, version): + bios = self.chas.get_bios_byname("master") + if bios is None: + baseutil.logger_debug("name bios(master) not find") + return -1 + return bios.set_bios_version(flash, version) + + def get_bios_version(self): + bios = self.chas.get_bios_byname("master") + if bios is None: + baseutil.logger_debug("name bios(master) not find") + return -1 + return bios.get_bios_version() + + def get_bios_status(self): + bios = self.chas.get_bios_byname("master") + if bios is None: + baseutil.logger_debug("name bios(master) not find") + return -1 + return bios.get_bios_boot_status() + + def get_bmc_mac_rov(self): + """ + Get BMC mac rov + + @return ret: 0 sucess , -1 fail + outmsg: if success is out msg, or fail is err msg + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + msg = "name master not find" + baseutil.logger_debug(msg) + return -1, msg + return bmc.get_mac_rov() + + def get_bmc_next_boot(self): + """ + Get next booting flash of BMC + + @return 'master'/'slave' on success, "N/A" for failure + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return self.na_ret + return bmc.get_next_boot() + + def set_bmc_next_boot(self, flash): + """ + Set flash from which next BMC boot + + @param flash Booting flash of BMC, "master" or "slave" + + @return 0 on success, -1 for failure + """ + flash_status = ("master", "slave") + if flash is None or flash not in flash_status: + baseutil.logger_debug("parameter flash illegal, should be [master|slave]") + return -1 + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return -1 + return bmc.set_next_boot(flash) + + def reboot_bmc(self): + """ + Reboot running BMC + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return -1 + return bmc.reboot() + + def get_bmc_info(self): + """ + Get BMC info + + @return dict of BMC info or None for failure + "Version": "1.1.1", # "N/A" + "Flash": "master", # "N/A" + "Next": "master" # "N/A" + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return self.na_ret + return bmc.get_info() + + def get_bmc_version_all(self): + """ + @return dict of BMCs + { + "MasterVersion": "1.1.1", # "N/A" + "SlaveVersion": "1.1.1" # "N/A" + } + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return self.na_ret + return bmc.get_version_all() + + def bmc_execute_command(self, cmd_str): + ret, output = osutil.command(cmd_str) + if ret: + baseutil.logger_debug("execute %s command failed" % (cmd_str)) + return ret, output + + def get_cpu_reset_num(self): + """ + Get CPU reset num + @return CPU reset num on success, -1 for failure + """ + cpu = self.chas.get_cpu_byname("cpu") + if cpu is None: + msg = "name cpu not find" + baseutil.logger_debug(msg) + return -1 + return cpu.get_cpu_reset_num() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/led.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/led.py new file mode 100644 index 000000000000..7fb869c74d7f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/led.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +####################################################### +# +# led.py +# Python implementation of the Class led +# +####################################################### +from plat_hal.devicebase import devicebase + + +class led(devicebase): + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.led_type = conf.get('led_type', None) + self.led_attrs_config = conf.get('led_attrs', None) + self.led_config = conf.get('led', None) + + def set_color(self, color): + status = self.led_attrs_config.get(color, None) + if status is None: + return False + + mask = self.led_attrs_config.get('mask', 0xff) + + if isinstance(self.led_config, list): + for led_config_index in self.led_config: + ret, value = self.get_value(led_config_index) + if (ret is False) or (value is None): + return False + setval = (int(value) & ~mask) | (status) + ret, val = self.set_value(led_config_index, setval) + if ret is False: + return ret + else: + ret, value = self.get_value(self.led_config) + if (ret is False) or (value is None): + return False + setval = (int(value) & ~mask) | (status) + ret, val = self.set_value(self.led_config, setval) + return ret + + def get_color(self): + mask = self.led_attrs_config.get('mask', 0xff) + ret, value = self.get_value(self.led_config) + if ret is False or value is None: + return False, 'N/A' + ledval = int(value) & mask + for key, val in self.led_attrs_config.items(): + if (ledval == val) and (key != "mask"): + return True, key + return False, 'N/A' diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/onie_e2.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/onie_e2.py new file mode 100644 index 000000000000..9ac32cace263 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/onie_e2.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +####################################################### +# +# onie_e2.py +# Python implementation of the Class onie_e2 +# +####################################################### +from plat_hal.devicebase import devicebase +from eepromutil.onietlv import onie_tlv + + +class onie_e2(devicebase): + + def __init__(self, conf=None): + self._cardid = "" + self._productname = "" + self._partnum = "" + self._serialnum = "" + self._macbase = "" + self._manufdate = "" + self._deviceversion = "" + self._labelrevision = "" + self._platformname = "" + self._onieversion = "" + self._macsize = "" + self._manufname = "" + self._manufcountry = "" + self._vendorname = "" + self._diagname = "" + self._servicetag = "" + + if conf is not None: + self.name = conf.get('name', None) + self.e2loc = conf.get('e2loc', None) + self.e2_path = self.e2loc.get('loc', None) + self.airflow = conf.get('airflow', "intake") + + @property + def cardid(self): + return self._cardid + + @property + def productname(self): + return self._productname + + @property + def partnum(self): + return self._partnum + + @property + def serialnum(self): + return self._serialnum + + @property + def macbase(self): + return self._macbase + + @property + def manufdate(self): + return self._manufdate + + @property + def deviceversion(self): + return self._deviceversion + + @property + def labelrevision(self): + return self._labelrevision + + @property + def platformname(self): + return self._platformname + + @property + def onieversion(self): + return self._onieversion + + @property + def macsize(self): + return self._macsize + + @property + def manufname(self): + return self._manufname + + @property + def manufcountry(self): + return self._manufcountry + + @property + def vendorname(self): + return self._vendorname + + @property + def diagname(self): + return self._diagname + + @property + def servicetag(self): + return self._servicetag + + def get_onie_e2_info(self): + try: + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s: value is none" % self.name) + onietlv = onie_tlv() + onietlv.decode(eeprom) + self._cardid = onietlv.cardid + self._productname = onietlv.productname + self._partnum = onietlv.partnum + self._serialnum = onietlv.serialnum + self._macbase = onietlv.macbase + self._manufdate = onietlv.manufdate + self._deviceversion = onietlv.deviceversion + self._labelrevision = onietlv.labelrevision + self._platformname = onietlv.platformname + self._onieversion = onietlv.onieversion + self._macsize = onietlv.macsize + self._manufname = onietlv.manufname + self._manufcountry = onietlv.manufcountry + self._vendorname = onietlv.vendorname + self._diagname = onietlv.diagname + self._servicetag = onietlv.servicetag + except Exception: + return False + return True diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/osutil.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/osutil.py new file mode 100644 index 000000000000..684e26bb9ecd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/osutil.py @@ -0,0 +1,440 @@ +#!/usr/bin/env python3 +####################################################### +# +# osutil.py +# Python implementation of the Class osutil +# +####################################################### + +import os +import glob +import re +import time +import subprocess +import fcntl +import syslog +from functools import wraps +from wbutil.smbus import SMBus + + +PLATFORM_HAL_DEBUG_FILE = "/etc/.platform_hal_debug_flag" + + +def platform_hal_debug(s): + if os.path.exists(PLATFORM_HAL_DEBUG_FILE): + syslog.openlog("PLATFORM_HAL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def retry(maxretry=6, delay=0.01): + ''' + maxretry: max retry times + delay : interval after last retry + ''' + def decorator(f): + @wraps(f) + def wrapper(*args, **kwargs): + time_retry = maxretry + time_delay = delay + result_msg = "" + while time_retry: + try: + val, result_msg = f(*args, **kwargs) + if val is True: + return val, result_msg + time_retry -= 1 + time.sleep(time_delay) + except Exception as e: + time_retry -= 1 + result_msg = str(e) + time.sleep(time_delay) + return False, "max time retry last errmsg is {}".format(result_msg) + return wrapper + return decorator + + +pidfile = None + + +def file_rw_lock(file_path): + global pidfile + pidfile = open(file_path, "r") + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + platform_hal_debug("file_rw_lock success") + return True + except Exception: + if pidfile is not None: + pidfile.close() + pidfile = None + return False + + +def file_rw_unlock(): + try: + global pidfile + + if pidfile is not None: + fcntl.flock(pidfile, fcntl.LOCK_UN) + pidfile.close() + pidfile = None + platform_hal_debug("file_rw_unlock success") + else: + platform_hal_debug("pidfile is invalid, do nothing") + return True + except Exception as e: + platform_hal_debug("file_rw_unlock err, msg: %s" % (str(e))) + return False + + +def take_file_rw_lock(file_path): + loop = 1000 + ret = False + for i in range(0, loop): + ret = file_rw_lock(file_path) + if ret is True: + break + time.sleep(0.001) + return ret + + +class osutil(object): + """ + osutil + """ + + @staticmethod + @retry(maxretry=6) + def wbi2cget_python(bus, addr, reg): + with SMBus(bus) as y: + val, ind = y.read_byte_data(addr, reg, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2cset_python(bus, addr, reg, value): + with SMBus(bus) as y: + val, ind = y.write_byte_data(addr, reg, value, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2cgetword_python(bus, addr, reg): + with SMBus(bus) as y: + val, ind = y.read_word_data(addr, reg, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2csetword_python(bus, addr, reg, value): + with SMBus(bus) as y: + val, ind = y.write_word_data(addr, reg, value, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2csetwordpec_python(bus, addr, reg, value): + with SMBus(bus) as y: + val, ind = y.write_word_data_pec(addr, reg, value, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2cset_byte_pec_python(bus, addr, reg, value): + with SMBus(bus) as y: + val, ind = y.write_byte_data_pec(addr, reg, value, True) + return val, ind + + @staticmethod + def command(cmdstr): + retcode, output = subprocess.getstatusoutput(cmdstr) + return retcode, output + + @staticmethod + def geti2cword_i2ctool(bus, addr, offset): + command_line = "i2cget -f -y %d 0x%02x 0x%02x wp" % (bus, addr, offset) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + return True, int(ret_t, 16) + time.sleep(0.1) + return False, ret_t + + @staticmethod + def seti2cword_i2ctool(bus, addr, offset, val): + command_line = "i2cset -f -y %d 0x%02x 0x%0x 0x%04x wp" % (bus, addr, offset, val) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + return True, ret_t + time.sleep(0.1) + return False, ret_t + + @staticmethod + def wbi2cget_i2ctool(bus, devno, address): + command_line = "i2cget -f -y %d 0x%02x 0x%02x " % (bus, devno, address) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + return True, int(ret_t, 16) + time.sleep(0.1) + return False, ret_t + + @staticmethod + def wbi2cset_i2ctool(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + @staticmethod + def geti2cword(bus, addr, offset): + return osutil.wbi2cgetword_python(bus, addr, offset) + + @staticmethod + def seti2cword(bus, addr, offset, val): + return osutil.wbi2csetword_python(bus, addr, offset, val) + + @staticmethod + def seti2cwordpec(bus, addr, offset, val): + return osutil.wbi2csetwordpec_python(bus, addr, offset, val) + + @staticmethod + def seti2c_byte_pec(bus, addr, offset, val): + return osutil.wbi2cset_byte_pec_python(bus, addr, offset, val) + + @staticmethod + def wbi2cget(bus, devno, address): + return osutil.wbi2cget_python(bus, devno, address) + + @staticmethod + def wbi2cset(bus, devno, address, byte): + return osutil.wbi2cset_python(bus, devno, address, byte) + + @staticmethod + def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + @staticmethod + def io_rd(reg_addr, read_len=1): + try: + regaddr = 0 + if isinstance(reg_addr, int): + regaddr = reg_addr + else: + regaddr = int(reg_addr, 16) + devfile = "/dev/port" + fd = os.open(devfile, os.O_RDWR | os.O_CREAT) + os.lseek(fd, regaddr, os.SEEK_SET) + val = os.read(fd, read_len) + return True, "".join(["%02x" % item for item in val]) + except ValueError as e: + return False, str(e) + except Exception as e: + return False, str(e) + finally: + os.close(fd) + + @staticmethod + def readsysfs(location, flock_path=None): + flock_path_tmp = None + platform_hal_debug("readsysfs, location:%s, flock_path:%s" % (location, flock_path)) + try: + if flock_path is not None: + flock_paths = glob.glob(flock_path) + if len(flock_paths) != 0: + flock_path_tmp = flock_paths[0] + platform_hal_debug("try to get file lock, path:%s" % flock_path_tmp) + ret = take_file_rw_lock(flock_path_tmp) + if ret is False: + platform_hal_debug("take file lock timeout, path:%s" % flock_path_tmp) + return False, ("take file rw lock timeout, path:%s" % flock_path_tmp) + else: + platform_hal_debug("config error, can't find flock_path:%s" % flock_path) + + locations = glob.glob(location) + with open(locations[0], 'rb') as fd1: + retval = fd1.read() + retval = osutil.byteTostr(retval) + if flock_path_tmp is not None: + file_rw_unlock() + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + except Exception as e: + if flock_path_tmp is not None: + file_rw_unlock() + platform_hal_debug("readsysfs error, msg:%s" % str(e)) + return False, (str(e) + " location[%s]" % location) + return True, retval + + @staticmethod + def writesysfs(location, value): + try: + if not os.path.isfile(location): + print(location, 'not found !') + return False, ("location[%s] not found !" % location) + with open(location, 'w') as fd1: + fd1.write(value) + except Exception as e: + return False, (str(e) + " location[%s]" % location) + return True, ("set location[%s] %s success !" % (location, value)) + + @staticmethod + def getdevmem(addr, digit, mask): + command_line = "devmem 0x%02x %d" % (addr, digit) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + if mask is not None: + ret_t = str(int(ret_t, 16) & mask) + return True, ret_t + return False, ret_t + + @staticmethod + def readdevfile_ascii(path, offset, length): + msg = "" + ret = "" + joinstr = '' + fd = -1 + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, length) + for item in ret: + joinstr += '%02x ' % item # like sysfs, display in hex + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + return True, joinstr + + @staticmethod + def readdevfile(path, offset, length): + msg = "" + ret = "" + fd = -1 + val_list = [] + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, length) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + return True, val_list + + @staticmethod + def writedevfile(path, offset, buf): + msg = "" + fd = -1 + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + if isinstance(buf, list): + if len(buf) == 0: + msg = "buf:%s is NONE !" % buf + return False, msg + elif isinstance(buf, int): + buf = [buf] + else: + msg = "buf:%s is not list type or not int type !" % buf + return False, msg + + try: + fd = os.open(path, os.O_WRONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.write(fd, bytes(buf)) + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + + return True, ret + + @staticmethod + def wb_os_system(cmd): + status, output = subprocess.getstatusoutput(cmd) + return status, output + + @staticmethod + def getsdkreg(reg): + try: + cmd = "bcmcmd -t 1 'getr %s ' < /dev/null" % reg + ret, result = osutil.wb_os_system(cmd) + result_t = result.strip().replace("\r", "").replace("\n", "") + if ret != 0 or "Error:" in result_t: + return False, result + patt = r"%s.(.*):(.*)>drivshell" % reg + rt = re.findall(patt, result_t, re.S) + test = re.findall("=(.*)", rt[0][0])[0] + except Exception as e: + return False, 'get sdk register error, msg: %s' % str(e) + return True, test + + @staticmethod + def getmactemp(): + try: + result = {} + # need to exec twice + osutil.wb_os_system("bcmcmd -t 1 \"show temp\" < /dev/null") + ret, log = osutil.wb_os_system("bcmcmd -t 1 \"show temp\" < /dev/null") + if ret: + return False, result + logs = log.splitlines() + for line in logs: + if "average" in line: + b = re.findall(r'\d+.\d+', line) + result["average"] = b[0] + elif "maximum" in line: + b = re.findall(r'\d+.\d+', line) + result["maximum"] = b[0] + except Exception as e: + return False, str(e) + return True, result + + @staticmethod + def std_match(stdout, pattern): + if pattern is None: + return stdout.strip() + for line in stdout.splitlines(): + if re.match(pattern, line): + return line.strip() + return None diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/psu.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/psu.py new file mode 100644 index 000000000000..e7db0cdcca8b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/psu.py @@ -0,0 +1,607 @@ +#!/usr/bin/env python3 +####################################################### +# +# psu.py +# Python implementation of the Class psu +# +####################################################### +from eepromutil.fru import ipmifru +from plat_hal.devicebase import devicebase +from plat_hal.sensor import sensor + + +class psu(devicebase): + __pmbus = None + __e2loc = None + __productManufacturer = None # : ARTESYN + __productName = None # : CRPS550W + __productPartModelName = None # : CSU550AP-3-300 + __productVersion = None # : AB + __productSerialNumber = None # : M623UZ00JYABL + __AirFlow = None # 'N/A' + __AirFlowconifg = None + __psu_display_name = None # 'N/A' + __psu_display_name_conifg = None + __psu_not_present_pwm = None + __InputStatus_config = None + __OutputStatus_config = None + __FanSpeed_config = None + __Temperature_config = None + __InputStatus = None + __OutputStatus = None + __FanSpeed = None + __Temperature = None + __FanSpeedMin = None + __FanSpeedMax = None + __FanSpeedTolerance = None + __InputsVoltage_config = None + __InputsCurrent_config = None + __InputsPower_config = None + __OutputsVoltage_config = None + __OutputsCurrent_config = None + __OutputsPower_config = None + __InputsVoltage = {} + __InputsCurrent = None + __InputsPower = None + __OutputsVoltage = None + __OutputsCurrent = None + __OutputsPower = None + __InputsType_config = None + __InputsType = None + __psu_sn_config = None + __psu_hw_config = None + __psu_pn_config = None + __psu_vendor_config = None + __TempStatus_config = None + __FanStatus_config = None + __TempStatus = None + __FanStatus = None + + def __init__(self, conf=None): + self.pmbus = conf.get("pmbusloc", None) + self.e2loc = conf.get("e2loc", None) + self.__presentconfig = conf.get("present", None) + self.name = conf.get("name", None) + self.AirFlowconifg = conf.get("airflow", None) + self.psu_display_name_conifg = conf.get("psu_display_name", None) + self.psu_not_present_pwm = conf.get("psu_not_present_pwm", 100) + self.Temperature_config = conf.get("Temperature", None) + self.Temperature = sensor(self.Temperature_config) + + self.FanSpeedTolerance = conf.get('psu_fan_tolerance', 30) + self.FanSpeed_config = conf.get("FanSpeed", None) + self.FanSpeed = sensor(self.FanSpeed_config) + + self.__InputsVoltage_config = conf.get("InputsVoltage", None) + self.generate_psu_input_vol(self.__InputsVoltage_config) + self.__InputsCurrent_config = conf.get("InputsCurrent", None) + self.InputsCurrent = sensor(self.__InputsCurrent_config) + self.__InputsPower_config = conf.get("InputsPower", None) + self.InputsPower = sensor(self.__InputsPower_config) + self.__OutputsVoltage_config = conf.get("OutputsVoltage", None) + self.OutputsVoltage = sensor(self.__OutputsVoltage_config) + self.__OutputsCurrent_config = conf.get("OutputsCurrent", None) + self.OutputsCurrent = sensor(self.__OutputsCurrent_config) + self.__OutputsPower_config = conf.get("OutputsPower", None) + self.OutputsPower = sensor(self.__OutputsPower_config) + + self.__InputStatus_config = conf.get("InputsStatus", None) + self.__OutputStatus_config = conf.get("OutputsStatus", None) + self.__InputsType_config = conf.get('InputsType', None) + self.__psu_sn_config = conf.get('psu_sn', None) + self.__psu_hw_config = conf.get('psu_hw', None) + self.__psu_pn_config = conf.get('psu_pn', None) + self.__psu_vendor_config = conf.get('psu_vendor', None) + self.__TempStatus_config = conf.get("TempStatus", None) + self.__FanStatus_config = conf.get("FanStatus", None) + + def generate_psu_input_vol(self, config): + tmp = {} + for (key, item) in config.items(): + tmp.setdefault(key, sensor(item)) + self.__InputsVoltage = tmp + + def get_psu_sensor_by_name(self, psutype): + return self.__InputsVoltage.get(psutype) or self.__InputsVoltage.get('other') + + @property + def InputsVoltage(self): + psutype = self.InputsType + input_sensor = self.get_psu_sensor_by_name(psutype) + if input_sensor is None: + return None + return input_sensor + + @InputsVoltage.setter + def InputsVoltage(self, val): + self.__InputsVoltage = val + + @property + def InputsCurrent(self): + return self.__InputsCurrent + + @InputsCurrent.setter + def InputsCurrent(self, val): + self.__InputsCurrent = val + + @property + def InputsPower(self): + return self.__InputsPower + + @InputsPower.setter + def InputsPower(self, val): + self.__InputsPower = val + + @property + def OutputsVoltage(self): + return self.__OutputsVoltage + + @OutputsVoltage.setter + def OutputsVoltage(self, val): + self.__OutputsVoltage = val + + @property + def OutputsCurrent(self): + return self.__OutputsCurrent + + @OutputsCurrent.setter + def OutputsCurrent(self, val): + self.__OutputsCurrent = val + + @property + def OutputsPower(self): + return self.__OutputsPower + + @OutputsPower.setter + def OutputsPower(self, val): + self.__OutputsPower = val + + @property + def InputStatus(self): + if self.present is False: + self.__InputStatus = False + else: + ret, val = self.get_value(self.__InputStatus_config) + mask = self.__InputStatus_config.get("mask") + if ret is True: + ttt = val & mask + if ttt == 0: + self.__InputStatus = True + else: + self.__InputStatus = False + else: + self.__InputStatus = False + return self.__InputStatus + + @InputStatus.setter + def InputStatus(self, val): + self.__InputStatus = val + + @property + def TempStatus(self): + if self.__TempStatus_config is None: + return None + if self.present is False: + self.__TempStatus = False + else: + ret, val = self.get_value(self.__TempStatus_config) + mask = self.__TempStatus_config.get("mask") + if ret is True: + ttt = val & mask + if ttt == 0: + self.__TempStatus = True + else: + self.__TempStatus = False + else: + self.__TempStatus = False + return self.__TempStatus + + @TempStatus.setter + def TempStatus(self, val): + self.__TempStatus = val + + @property + def FanStatus(self): + if self.__FanStatus_config is None: + return None + if self.present is False: + self.__FanStatus = False + else: + ret, val = self.get_value(self.__FanStatus_config) + mask = self.__FanStatus_config.get("mask") + if ret is True: + ttt = val & mask + if ttt == 0: + self.__FanStatus = True + else: + self.__FanStatus = False + else: + self.__FanStatus = False + return self.__FanStatus + + @FanStatus.setter + def FanStatus(self, val): + self.__FanStatus = val + + @property + def InputsType(self): + psutypedecode = self.__InputsType_config.get('psutypedecode', None) + if self.present is False: + self.__InputsType = psutypedecode.get(0x00) + else: + ret, val = self.get_value(self.__InputsType_config) + self.__InputsType = self.__InputsType_config.get(val, None) + if self.__InputsType is not None: + return self.__InputsType + if ret is True and val in psutypedecode: + self.__InputsType = psutypedecode.get(val) + else: + self.__InputsType = psutypedecode.get(0x00) + return self.__InputsType + + @InputsType.setter + def InputsType(self, val): + self.__InputsType = val + + @property + def FanSpeedMin(self): + return self.__FanSpeedMin + + @FanSpeedMin.setter + def FanSpeedMin(self, val): + self.__FanSpeedMin = val + + @property + def FanSpeedMax(self): + return self.__FanSpeedMax + + @FanSpeedMax.setter + def FanSpeedMax(self, val): + self.__FanSpeedMax = val + + @property + def FanSpeedTolerance(self): + return self.__FanSpeedTolerance + + @FanSpeedTolerance.setter + def FanSpeedTolerance(self, val): + self.__FanSpeedTolerance = val + + @property + def OutputStatus(self): + if self.present is False: + self.__OutputStatus = False + else: + ret, val = self.get_value(self.__OutputStatus_config) + mask = self.__OutputStatus_config.get("mask") + if ret is True: + ttt = val & mask + if ttt == 0: + self.__OutputStatus = True + else: + self.__OutputStatus = False + else: + self.__OutputStatus = False + return self.__OutputStatus + + @OutputStatus.setter + def OutputStatus(self, val): + self.__OutputStatus = val + + @property + def FanSpeed(self): + return self.__FanSpeed + + @FanSpeed.setter + def FanSpeed(self, val): + self.__FanSpeed = val + + @property + def Temperature(self): + return self.__Temperature + + @Temperature.setter + def Temperature(self, val): + self.__Temperature = val + + @property + def Temperature_config(self): + return self.__Temperature_config + + @Temperature_config.setter + def Temperature_config(self, val): + self.__Temperature_config = val + + @property + def AirFlowconifg(self): + return self.__AirFlowconifg + + @AirFlowconifg.setter + def AirFlowconifg(self, val): + self.__AirFlowconifg = val + + @property + def psu_display_name_conifg(self): + return self.__psu_display_name_conifg + + @psu_display_name_conifg.setter + def psu_display_name_conifg(self, val): + self.__psu_display_name_conifg = val + + @property + def pmbus(self): + return self.__pmbus + + @pmbus.setter + def pmbus(self, val): + self.__pmbus = val + + @property + def e2loc(self): + return self.__e2loc + + @e2loc.setter + def e2loc(self, val): + self.__e2loc = val + + @property + def AirFlow(self): + return self.__AirFlow + + @AirFlow.setter + def AirFlow(self, val): + self.__AirFlow = val + + @property + def psu_display_name(self): + return self.__psu_display_name + + @psu_display_name.setter + def psu_display_name(self, val): + self.__psu_display_name = val + + @property + def psu_not_present_pwm(self): + return self.__psu_not_present_pwm + + @psu_not_present_pwm.setter + def psu_not_present_pwm(self, val): + self.__psu_not_present_pwm = val + + @property + def present(self): + ret, val = self.get_value(self.__presentconfig) + if ret is False or val is None: + return False + mask = self.__presentconfig.get("mask") + if isinstance(val, str): + value = int(val, 16) + else: + value = val + ttt = value & mask + okval = self.__presentconfig.get("okval", 0) + if ttt == okval: + return True + return False + + @property + def productManufacturer(self): + return self.__productManufacturer + + @productManufacturer.setter + def productManufacturer(self, val): + self.__productManufacturer = val + + @property + def productName(self): + return self.__productName + + @productName.setter + def productName(self, val): + self.__productName = val + + @property + def productPartModelName(self): + return self.__productPartModelName + + @productPartModelName.setter + def productPartModelName(self, val): + self.__productPartModelName = val + + @property + def productVersion(self): + return self.__productVersion + + @productVersion.setter + def productVersion(self, val): + self.__productVersion = val + + @property + def productSerialNumber(self): + return self.__productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, val): + self.__productSerialNumber = val + + @property + def psu_sn_sysfs(self): + if self.__psu_sn_config is None: + return None + ret, val = self.get_value(self.__psu_sn_config) + if ret is False or val is None: + return None + return val + + @property + def psu_hw_sysfs(self): + if self.__psu_hw_config is None: + return None + ret, val = self.get_value(self.__psu_hw_config) + if ret is False or val is None: + return None + return val + + @property + def psu_pn_sysfs(self): + if self.__psu_pn_config is None: + return None + ret, val = self.get_value(self.__psu_pn_config) + if ret is False or val is None: + return None + return val + + @property + def psu_vendor_sysfs(self): + if self.__psu_vendor_config is None: + return None + ret, val = self.get_value(self.__psu_vendor_config) + if ret is False or val is None: + return None + return val + + def __str__(self): + formatstr = \ + "name : %s \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "AirFlow : %s \n" \ + + tmpstr = formatstr % (self.name, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, self.AirFlow) + return tmpstr + + def get_fan_speed_pwm(self): + if self.present is False: + return self.psu_not_present_pwm + selfconfig = {} + selfconfig['bus'] = self.pmbus['bus'] + selfconfig['addr'] = self.pmbus['addr'] + selfconfig['way'] = 'i2cword' + selfconfig['offset'] = 0x3b + ret, val = self.get_value(selfconfig) + if ret is True: + return val + return None + + def set_fan_speed_pwm(self, pwm): + ''' + pmbus + if duty: + i2cset -f -y 0x3b 0x0064 wp + ''' + if self.present is False: + return None + if 0 <= pwm <= 100: + # enable duty first + selfconfig = {} + + selfconfig['bus'] = self.pmbus['bus'] + selfconfig['addr'] = self.pmbus['addr'] + selfconfig['way'] = 'i2cpec' + selfconfig['offset'] = 0x3a + self.set_value(selfconfig, 0x80) + + selfconfig['way'] = 'i2cwordpec' + selfconfig['offset'] = 0x3b + bytetmp = pwm + ret, val = self.set_value(selfconfig, int(bytetmp)) + if ret is True: + return True + return None + raise Exception("pwm not in range [0,100]") + + def get_fru_info_by_sysfs(self): + try: + psu_sn = self.psu_sn_sysfs + psu_hw = self.psu_hw_sysfs + psu_pn = self.psu_pn_sysfs + psu_vendor = self.psu_vendor_sysfs + if psu_sn is None or psu_hw is None or psu_pn is None or psu_vendor is None: + return False + self.productSerialNumber = psu_sn.strip().replace(chr(0), "") + self.productVersion = psu_hw.strip() + self.productPartModelName = psu_pn.strip() + self.productManufacturer = psu_vendor.strip().replace(chr(0), "") + except Exception: + self.productSerialNumber = None + self.productVersion = None + self.productPartModelName = None + self.productManufacturer = None + return False + return True + + def get_fru_info_by_decode(self): + try: + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s:value is none" % self.name) + fru = ipmifru() + if isinstance(eeprom, bytes): + eeprom = self.byteTostr(eeprom) + fru.decodeBin(eeprom) + if fru.productInfoArea is not None: + self.productManufacturer = fru.productInfoArea.productManufacturer.strip() + self.productName = fru.productInfoArea.productName.strip() + self.productPartModelName = fru.productInfoArea.productPartModelName.strip() + self.productVersion = fru.productInfoArea.productVersion.strip() + self.productSerialNumber = fru.productInfoArea.productSerialNumber.strip().replace(chr(0), "") + except Exception: + self.productManufacturer = None + self.productName = None + self.productPartModelName = None + self.productVersion = None + self.productSerialNumber = None + return False + return True + + def get_fru_info(self): + try: + if self.present is not True: + raise Exception("%s: not present" % self.name) + if self.get_fru_info_by_sysfs() is True: + return True + return self.get_fru_info_by_decode() + except Exception: + self.productManufacturer = None + self.productName = None + self.productPartModelName = None + self.productVersion = None + self.productSerialNumber = None + return False + + def get_AirFlow(self): + if self.productPartModelName is None: + ret = self.get_fru_info() + if ret is False: + self.AirFlow = None + return False + if self.AirFlowconifg is None: + self.AirFlow = None + return False + for i in self.AirFlowconifg: + if self.productPartModelName in self.AirFlowconifg[i]: + self.AirFlow = i + return True + self.AirFlow = None + return False + + def get_psu_display_name(self): + if self.productPartModelName is None: + ret = self.get_fru_info() + if ret is False: + self.psu_display_name = None + return False + if self.psu_display_name_conifg is None: + self.psu_display_name = self.productPartModelName + return False + for i in self.psu_display_name_conifg: + if self.productPartModelName in self.psu_display_name_conifg[i]: + self.psu_display_name = i + return True + self.psu_display_name = self.productPartModelName + return False diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/rotor.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/rotor.py new file mode 100644 index 000000000000..2b4e4ffd5f0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/rotor.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 +####################################################### +# +# rotor.py +# Python implementation of the Class rotor +# +####################################################### +from plat_hal.devicebase import devicebase +from plat_hal.sensor import sensor + + +class rotor(devicebase): + __rotor_Running = None + __rotor_HwAlarm_conf = None + __rotor_Speed = None + __rotor_run_conf = None + __Speedconfig = None + __i2c_speed = None + __SpeedMin = None + __SpeedMax = None + __SpeedTolerance = None + + def __init__(self, conf=None): + self.name = conf.get('name', None) + self.rotor_HwAlarm_conf = conf.get('HwAlarm', None) + self.rotor_run_conf = conf.get('Running', None) + self.SpeedMin = conf.get('SpeedMin', None) + self.SpeedMax = conf.get('SpeedMax', None) + self.Tolerance = conf.get('tolerance', 30) + self.rotor_Speed = sensor(conf.get('Speed', None)) + self.Speedconfig = conf.get('Set_speed', None) + + def getRunning(self): + ret, val = self.get_value(self.rotor_run_conf) + if ret is False or val is None: + return False + if isinstance(val, str): + value = int(val, 16) + else: + value = val + mask = self.rotor_run_conf.get("mask") + is_runing_value = self.rotor_run_conf.get("is_runing") + flag = value & mask + if flag == is_runing_value: + return True + return False + + @property + def SpeedMin(self): + return self.__SpeedMin + + @SpeedMin.setter + def SpeedMin(self, val): + self.__SpeedMin = val + + @property + def SpeedMax(self): + return self.__SpeedMax + + @SpeedMax.setter + def SpeedMax(self, val): + self.__SpeedMax = val + + @property + def Tolerance(self): + return self.__SpeedTolerance + + @Tolerance.setter + def Tolerance(self, val): + self.__SpeedTolerance = val + + @property + def i2c_speed(self): + ret, val = self.get_value(self.Speedconfig) + if ret is False: + return None + if val is not None: + self.__i2c_speed = val + return self.__i2c_speed + + def feed_watchdog(self): + ret, val = self.get_value(self.Speedconfig) + if ret is False: + return False, None + if val is not None: + ret, val = self.set_value(self.Speedconfig, val) + return ret, val + return False, None + + @i2c_speed.setter + def i2c_speed(self, val): + self.__i2c_speed = val + + @property + def Speedconfig(self): + return self.__Speedconfig + + @Speedconfig.setter + def Speedconfig(self, val): + self.__Speedconfig = val + + @property + def rotor_run_conf(self): + return self.__rotor_run_conf + + @rotor_run_conf.setter + def rotor_run_conf(self, val): + self.__rotor_run_conf = val + + @property + def rotor_Speed(self): + return self.__rotor_Speed + + @rotor_Speed.setter + def rotor_Speed(self, val): + self.__rotor_Speed = val + + @property + def rotor_HwAlarm(self): + ret, val = self.get_value(self.rotor_HwAlarm_conf) + mask = self.rotor_HwAlarm_conf.get("mask") + no_alarm_value = self.rotor_HwAlarm_conf.get("no_alarm") + if ret is False or val is None: + return False + if isinstance(val, str): + value = int(val, 16) + else: + value = val + flag = value & mask + if flag == no_alarm_value: + return False + return True + + @property + def rotor_HwAlarm_conf(self): + return self.__rotor_HwAlarm_conf + + @rotor_HwAlarm_conf.setter + def rotor_HwAlarm_conf(self, val): + self.__rotor_HwAlarm_conf = val + + @property + def rotor_Running(self): + self.__rotor_Running = self.getRunning() + return self.__rotor_Running + + @rotor_Running.setter + def rotor_Running(self, val): + self.__rotor_Running = val diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/sensor.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/sensor.py new file mode 100644 index 000000000000..2b4e05e00e43 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/sensor.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 +####################################################### +# +# sensor.py +# Python implementation of the Class sensor +# +####################################################### +import time +from plat_hal.devicebase import devicebase + + +class sensor(devicebase): + + __Value = None + __Min = None + __Max = None + __Low = None + __High = None + __ValueConfig = None + __Flag = None + __Unit = None + __format = None + __read_times = None + + __Min_config = None + __Max_config = None + __Low_config = None + __High_config = None + + @property + def Min_config(self): + return self.__Min_config + + @Min_config.setter + def Min_config(self, val): + self.__Min_config = val + + @property + def Max_config(self): + return self.__Max_config + + @Max_config.setter + def Max_config(self, val): + self.__Max_config = val + + @property + def Low_config(self): + return self.__Low_config + + @Low_config.setter + def Low_config(self, val): + self.__Low_config = val + + @property + def High_config(self): + return self.__High_config + + @High_config.setter + def High_config(self, val): + self.__High_config = val + + @property + def Unit(self): + return self.__Unit + + @Unit.setter + def Unit(self, val): + self.__Unit = val + + @property + def format(self): + return self.__format + + @format.setter + def format(self, val): + self.__format = val + + @property + def read_times(self): + return self.__read_times + + @read_times.setter + def read_times(self, val): + self.__read_times = val + + @property + def ValueConfig(self): + return self.__ValueConfig + + @ValueConfig.setter + def ValueConfig(self, val): + self.__ValueConfig = val + + @property + def Flag(self): + return self.__Flag + + @Flag.setter + def Flag(self, val): + self.__Flag = val + + def get_median(self, value_config, read_times): + val_list = [] + for i in range(0, read_times): + ret, real_value = self.get_value(value_config) + if i != (read_times - 1): + time.sleep(0.01) + if ret is False or real_value is None: + continue + val_list.append(real_value) + val_list.sort() + if val_list: + return True, val_list[int((len(val_list) - 1) / 2)] + return False, None + + @property + def Value(self): + try: + ret, val = self.get_median(self.ValueConfig, self.read_times) + if ret is False or val is None: + return None + if self.format is None: + self.__Value = int(val) + else: + self.__Value = self.get_format_value(self.format % val) + self.__Value = round(float(self.__Value), 3) + except Exception: + return None + return self.__Value + + @Value.setter + def Value(self, val): + self.__Value = val + + @property + def Min(self): + try: + if self.format is None: + self.__Min = self.Min_config + else: + self.__Min = self.get_format_value(self.format % self.Min_config) + self.__Min = round(float(self.__Min), 3) + except Exception: + return None + return self.__Min + + @Min.setter + def Min(self, val): + self.__Min = val + + @property + def Max(self): + try: + if self.format is None: + self.__Max = self.Max_config + else: + self.__Max = self.get_format_value(self.format % self.Max_config) + self.__Max = round(float(self.__Max), 3) + except Exception: + return None + return self.__Max + + @Max.setter + def Max(self, val): + self.__Max = val + + @property + def Low(self): + try: + if self.format is None: + self.__Low = self.Low_config + else: + self.__Low = self.get_format_value(self.format % self.Low_config) + except Exception: + return None + return self.__Low + + @Low.setter + def Low(self, val): + self.__Low = val + + @property + def High(self): + try: + if self.format is None: + self.__High = self.High_config + else: + self.__High = self.get_format_value(self.format % self.High_config) + except Exception: + return None + return self.__High + + @High.setter + def High(self, val): + self.__High = val + + def __init__(self, conf=None): + self.ValueConfig = conf.get("value", None) + self.Flag = conf.get("flag", None) + self.Min_config = conf.get("Min", None) + self.Max_config = conf.get("Max", None) + self.Low_config = conf.get("Low", None) + self.High_config = conf.get("High", None) + self.Unit = conf.get('Unit', None) + self.format = conf.get('format', None) + self.read_times = conf.get('read_times', 1) + + def __str__(self): + formatstr = \ + "ValueConfig: : %s \n" \ + "Min : %s \n" \ + "Max : %s \n" \ + "Unit : %s \n" \ + "format: : %s \n" + + tmpstr = formatstr % (self.ValueConfig, self.Min, + self.Max, self.Unit, + self.format) + return tmpstr diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/temp.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/temp.py new file mode 100644 index 000000000000..a202c20339c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/temp.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +####################################################### +# +# temp.py +# Python implementation of the Class temp +# +####################################################### +import os +import syslog +from plat_hal.sensor import sensor + + +PLATFORM_HAL_TEMP_DEBUG_FILE = "/etc/.platform_hal_temp_debug_flag" + + +def platform_hal_temp_debug(s): + if os.path.exists(PLATFORM_HAL_TEMP_DEBUG_FILE): + syslog.openlog("PLATFORM_HAL_TEPM", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +class temp(sensor): + def __init__(self, conf=None): + super(temp, self).__init__(conf.get('Temperature', None)) + self.name = conf.get("name", None) + self.temp_id = conf.get("temp_id", None) + self.api_name = conf.get("api_name", self.name) + self.fix_value = conf.get("fix_value", None) + self.temp_invalid = conf.get("invalid", None) + self.temp_error = conf.get("error", None) + + def temp_cali_by_fan_pwm(self, param, origin_value): + fan_pwm_conf = param.get("fan_pwm") + temp_fix_list = param.get("temp_fix_list") + + ret, val = self.get_value(fan_pwm_conf) + if ret is False or val is None: + platform_hal_temp_debug("temp calibration get fan pwm failed, msg: %s, return None" % (val)) + return None + + fan_pwm = int(val) + for item in temp_fix_list: + if item["min"] <= fan_pwm <= item["max"]: + fix_value = origin_value + item["fix"] + platform_hal_temp_debug("temp calibration by fan pwm, origin_value: %s, pwm: %s, fix_value: %s" % + (origin_value, fan_pwm, fix_value)) + return fix_value + platform_hal_temp_debug("temp calibration by fan pwm, origin_value: %s, pwm: %s, not match return None" % + (origin_value, fan_pwm)) + return None + + def fix_temp_value(self, origin_value): + try: + fix_type = self.fix_value.get("fix_type") + + if fix_type == "func": + func_name = self.fix_value.get("func_name") + func_param = self.fix_value.get("func_param") + func = getattr(self, func_name) + if func is None: + platform_hal_temp_debug("function %s, not defined" % func_name) + return None + value = func(func_param, origin_value) + return value + + if fix_type == "config": + coefficient = self.fix_value.get("coefficient", 1) + addend = self.fix_value.get("addend", 0) + value = (origin_value + addend) * coefficient + platform_hal_temp_debug("temp calibration by config, coefficient: %s, addend: %s, origin_value: %s, fix_value: %s" % + (coefficient, addend, origin_value, value)) + return value + + platform_hal_temp_debug("unsupport fix type: %s, return origin value: %s" % (fix_type, origin_value)) + return origin_value + except Exception as e: + platform_hal_temp_debug("fix_temp_value raise exception, msg: %s" % (str(e))) + return None + + def get_max_value(self, conf): + try: + ret, val = self.get_value(conf) + if ret is False or val is None: + return None + return val + except Exception: + return None + + def check_flag(self): + try: + okbit = self.Flag.get('okbit') + okval = self.Flag.get('okval') + ret, val = self.get_value(self.Flag) + if (ret is False) or (val is None): + return False + val_t = (int(val) & (1 << okbit)) >> okbit + if val_t != okval: + return False + except Exception: + return False + return True + + @property + def Value(self): + try: + if self.Flag is not None: + if self.check_flag() is False: + return None + if isinstance(self.ValueConfig, list): + max_val = None + for i in self.ValueConfig: + tmp = self.get_max_value(i) + if tmp is None: + continue + if max_val is None or max_val < tmp: + max_val = tmp + if max_val is None: + return None + if self.format is None: + self.__Value = int(max_val) + else: + self.__Value = self.get_format_value(self.format % max_val) + else: + ret, val = self.get_value(self.ValueConfig) + if ret is False or val is None: + return None + if self.format is None: + self.__Value = int(val) + else: + self.__Value = self.get_format_value(self.format % val) + except Exception: + return None + if self.fix_value is not None and self.__Value != self.temp_invalid and self.__Value != self.temp_error: + self.__Value = self.fix_temp_value(self.__Value) + return self.__Value + + @Value.setter + def Value(self, val): + self.__Value = val diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/baseutil.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/baseutil.py new file mode 100644 index 000000000000..340a1f7a733f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/baseutil.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +import os + + +def get_machine_info(): + if not os.path.isfile('/host/machine.conf'): + return None + machine_vars = {} + with open('/host/machine.conf') as machine_file: + for line in machine_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + machine_vars[tokens[0]] = tokens[1].strip() + return machine_vars + + +def get_platform_info(machine_info): + if machine_info is not None: + if 'onie_platform' in machine_info: + return machine_info['onie_platform'] + if 'aboot_platform' in machine_info: + return machine_info['aboot_platform'] + return None + + +def get_board_id(machine_info): + if machine_info is not None: + if 'onie_board_id' in machine_info: + return machine_info['onie_board_id'].lower() + return "NA" + + +def get_onie_machine(machine_info): + if machine_info is not None: + if 'onie_machine' in machine_info: + return machine_info['onie_machine'] + return None diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/smbus.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/smbus.py new file mode 100644 index 000000000000..5f1659b3bbf0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/smbus.py @@ -0,0 +1,772 @@ +#!/usr/bin/env python3 +# smbus2 - A drop-in replacement for smbus-cffi/smbus-python +# The MIT License (MIT) +# Copyright (c) 2017 Karl-Petter Lindegaard +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import os +import sys +from fcntl import ioctl +from ctypes import c_uint32, c_uint8, c_uint16, c_char, POINTER, Structure, Array, Union, create_string_buffer, string_at + + +# Commands from uapi/linux/i2c-dev.h +I2C_SLAVE = 0x0703 # Use this slave address +I2C_SLAVE_FORCE = 0x0706 # Use this slave address, even if it is already in use by a driver! +I2C_FUNCS = 0x0705 # Get the adapter functionality mask +I2C_RDWR = 0x0707 # Combined R/W transfer (one STOP only) +I2C_SMBUS = 0x0720 # SMBus transfer. Takes pointer to i2c_smbus_ioctl_data +I2C_PEC = 0x0708 + +# SMBus transfer read or write markers from uapi/linux/i2c.h +I2C_SMBUS_WRITE = 0 +I2C_SMBUS_READ = 1 + +# Size identifiers uapi/linux/i2c.h +I2C_SMBUS_QUICK = 0 +I2C_SMBUS_BYTE = 1 +I2C_SMBUS_BYTE_DATA = 2 +I2C_SMBUS_WORD_DATA = 3 +I2C_SMBUS_PROC_CALL = 4 +# This isn't supported by Pure-I2C drivers with SMBUS emulation, like those in RaspberryPi, OrangePi, etc :( +I2C_SMBUS_BLOCK_DATA = 5 +I2C_SMBUS_BLOCK_PROC_CALL = 7 # Like I2C_SMBUS_BLOCK_DATA, it isn't supported by Pure-I2C drivers either. +I2C_SMBUS_I2C_BLOCK_DATA = 8 +I2C_SMBUS_BLOCK_MAX = 32 + +# To determine what functionality is present (uapi/linux/i2c.h) +try: + from enum import IntFlag +except ImportError: + IntFlag = int + + +class I2cFunc(IntFlag): + """ + These flags identify the operations supported by an I2C/SMBus device. + + You can test these flags on your `smbus.funcs` + + On newer python versions, I2cFunc is an IntFlag enum, but it + falls back to class with a bunch of int constants on older releases. + """ + I2C = 0x00000001 + ADDR_10BIT = 0x00000002 + PROTOCOL_MANGLING = 0x00000004 # I2C_M_IGNORE_NAK etc. + SMBUS_PEC = 0x00000008 + NOSTART = 0x00000010 # I2C_M_NOSTART + SLAVE = 0x00000020 + SMBUS_BLOCK_PROC_CALL = 0x00008000 # SMBus 2.0 + SMBUS_QUICK = 0x00010000 + SMBUS_READ_BYTE = 0x00020000 + SMBUS_WRITE_BYTE = 0x00040000 + SMBUS_READ_BYTE_DATA = 0x00080000 + SMBUS_WRITE_BYTE_DATA = 0x00100000 + SMBUS_READ_WORD_DATA = 0x00200000 + SMBUS_WRITE_WORD_DATA = 0x00400000 + SMBUS_PROC_CALL = 0x00800000 + SMBUS_READ_BLOCK_DATA = 0x01000000 + SMBUS_WRITE_BLOCK_DATA = 0x02000000 + SMBUS_READ_I2C_BLOCK = 0x04000000 # I2C-like block xfer + SMBUS_WRITE_I2C_BLOCK = 0x08000000 # w/ 1-byte reg. addr. + SMBUS_HOST_NOTIFY = 0x10000000 + + SMBUS_BYTE = 0x00060000 + SMBUS_BYTE_DATA = 0x00180000 + SMBUS_WORD_DATA = 0x00600000 + SMBUS_BLOCK_DATA = 0x03000000 + SMBUS_I2C_BLOCK = 0x0c000000 + SMBUS_EMUL = 0x0eff0008 + + +# i2c_msg flags from uapi/linux/i2c.h +I2C_M_RD = 0x0001 + +# Pointer definitions +LP_c_uint8 = POINTER(c_uint8) +LP_c_uint16 = POINTER(c_uint16) +LP_c_uint32 = POINTER(c_uint32) + + +############################################################# +# Type definitions as in i2c.h + + +class i2c_smbus_data(Array): + """ + Adaptation of the i2c_smbus_data union in ``i2c.h``. + + Data for SMBus messages. + """ + _length_ = I2C_SMBUS_BLOCK_MAX + 2 + _type_ = c_uint8 + + +class union_i2c_smbus_data(Union): + _fields_ = [ + ("byte", c_uint8), + ("word", c_uint16), + ("block", i2c_smbus_data) + ] + + +union_pointer_type = POINTER(union_i2c_smbus_data) + + +class i2c_smbus_ioctl_data(Structure): + """ + As defined in ``i2c-dev.h``. + """ + _fields_ = [ + ('read_write', c_uint8), + ('command', c_uint8), + ('size', c_uint32), + ('data', union_pointer_type)] + __slots__ = [name for name, type in _fields_] + + @staticmethod + def create(read_write=I2C_SMBUS_READ, command=0, size=I2C_SMBUS_BYTE_DATA): + u = union_i2c_smbus_data() + return i2c_smbus_ioctl_data( + read_write=read_write, command=command, size=size, + data=union_pointer_type(u)) + + +############################################################# +# Type definitions for i2c_rdwr combined transactions + + +class i2c_msg(Structure): + """ + As defined in ``i2c.h``. + """ + _fields_ = [ + ('addr', c_uint16), + ('flags', c_uint16), + ('len', c_uint16), + ('buf', POINTER(c_char))] + + def __iter__(self): + """ Iterator / Generator + + :return: iterates over :py:attr:`buf` + :rtype: :py:class:`generator` which returns int values + """ + idx = 0 + while idx < self.len: + yield ord(self.buf[idx]) + idx += 1 + + def __len__(self): + return self.len + + def __bytes__(self): + return string_at(self.buf, self.len) + + def __repr__(self): + return 'i2c_msg(%d,%d,%r)' % (self.addr, self.flags, self.__bytes__()) + + def __str__(self): + s = self.__bytes__() + if sys.version_info.major >= 3: + s = ''.join(map(chr, s)) + return s + + @staticmethod + def read(address, length): + """ + Prepares an i2c read transaction. + + :param address: Slave address. + :type: address: int + :param length: Number of bytes to read. + :type: length: int + :return: New :py:class:`i2c_msg` instance for read operation. + :rtype: :py:class:`i2c_msg` + """ + arr = create_string_buffer(length) + return i2c_msg( + addr=address, flags=I2C_M_RD, len=length, + buf=arr) + + @staticmethod + def write(address, buf): + """ + Prepares an i2c write transaction. + + :param address: Slave address. + :type address: int + :param buf: Bytes to write. Either list of values or str. + :type buf: list + :return: New :py:class:`i2c_msg` instance for write operation. + :rtype: :py:class:`i2c_msg` + """ + if sys.version_info.major >= 3: + if isinstance(buf, str): + buf = bytes(map(ord, buf)) + else: + buf = bytes(buf) + else: + if not isinstance(buf, str): + buf = ''.join([chr(x) for x in buf]) + arr = create_string_buffer(buf, len(buf)) + return i2c_msg( + addr=address, flags=0, len=len(arr), + buf=arr) + + +class i2c_rdwr_ioctl_data(Structure): + """ + As defined in ``i2c-dev.h``. + """ + _fields_ = [ + ('msgs', POINTER(i2c_msg)), + ('nmsgs', c_uint32) + ] + __slots__ = [name for name, type in _fields_] + + @staticmethod + def create(*i2c_msg_instances): + """ + Factory method for creating a i2c_rdwr_ioctl_data struct that can + be called with ``ioctl(fd, I2C_RDWR, data)``. + + :param i2c_msg_instances: Up to 42 i2c_msg instances + :rtype: i2c_rdwr_ioctl_data + """ + n_msg = len(i2c_msg_instances) + msg_array = (i2c_msg * n_msg)(*i2c_msg_instances) + return i2c_rdwr_ioctl_data( + msgs=msg_array, + nmsgs=n_msg + ) + + +############################################################# + + +class SMBus(object): + + def __init__(self, bus=None, force=False): + """ + Initialize and (optionally) open an i2c bus connection. + + :param bus: i2c bus number (e.g. 0 or 1) + or an absolute file path (e.g. `/dev/i2c-42`). + If not given, a subsequent call to ``open()`` is required. + :type bus: int or str + :param force: force using the slave address even when driver is + already using it. + :type force: boolean + """ + self.fd = None + self.funcs = I2cFunc(0) + if bus is not None: + self.open(bus) + self.address = None + self.force = force + self._force_last = None + + def __enter__(self): + """Enter handler.""" + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + """Exit handler.""" + self.close() + + def open(self, bus): + """ + Open a given i2c bus. + + :param bus: i2c bus number (e.g. 0 or 1) + or an absolute file path (e.g. '/dev/i2c-42'). + :type bus: int or str + :raise TypeError: if type(bus) is not in (int, str) + """ + if isinstance(bus, int): + filepath = "/dev/i2c-{}".format(bus) + elif isinstance(bus, str): + filepath = bus + else: + raise TypeError("Unexpected type(bus)={}".format(type(bus))) + + self.fd = os.open(filepath, os.O_RDWR) + self.funcs = self._get_funcs() + + def close(self): + """ + Close the i2c connection. + """ + if self.fd: + os.close(self.fd) + self.fd = None + + def _set_address(self, address, force=None): + """ + Set i2c slave address to use for subsequent calls. + + :param address: + :type address: int + :param force: + :type force: Boolean + """ + force = force if force is not None else self.force + if self.address != address or self._force_last != force: + if force is True: + ioctl(self.fd, I2C_SLAVE_FORCE, address) + else: + ioctl(self.fd, I2C_SLAVE, address) + self.address = address + self._force_last = force + + def _get_funcs(self): + """ + Returns a 32-bit value stating supported I2C functions. + + :rtype: int + """ + f = c_uint32() + ioctl(self.fd, I2C_FUNCS, f) + return f.value + + def write_quick(self, i2c_addr, force=None): + """ + Perform quick transaction. Throws IOError if unsuccessful. + :param i2c_addr: i2c address + :type i2c_addr: int + :param force: + :type force: Boolean + """ + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=0, size=I2C_SMBUS_QUICK) + ioctl(self.fd, I2C_SMBUS, msg) + + def read_byte(self, i2c_addr, force=None): + """ + Read a single byte from a device. + + :rtype: int + :param i2c_addr: i2c address + :type i2c_addr: int + :param force: + :type force: Boolean + :return: Read byte value + """ + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_READ, command=0, size=I2C_SMBUS_BYTE + ) + ioctl(self.fd, I2C_SMBUS, msg) + return msg.data.contents.byte + + def write_byte(self, i2c_addr, value, force=None): + """ + Write a single byte to a device. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param value: value to write + :type value: int + :param force: + :type force: Boolean + """ + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=value, size=I2C_SMBUS_BYTE + ) + ioctl(self.fd, I2C_SMBUS, msg) + + def read_byte_data(self, i2c_addr, register, force=None): + """ + Read a single byte from a designated register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to read + :type register: int + :param force: + :type force: Boolean + :return: Read byte value + :rtype: int + """ + val_t = -1 + returnmsg = "" + try: + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_BYTE_DATA + ) + val_t = ioctl(self.fd, I2C_SMBUS, msg) + except Exception as e: + self.close() + returnmsg = str(e) + if val_t < 0: + return False, returnmsg + return True, msg.data.contents.byte + + def write_byte_data(self, i2c_addr, register, value, force=None): + """ + Write a byte to a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to write to + :type register: int + :param value: Byte value to transmit + :type value: int + :param force: + :type force: Boolean + :rtype: None + """ + val_t = -1 + returnmsg = "" + try: + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BYTE_DATA + ) + msg.data.contents.byte = value + val_t = ioctl(self.fd, I2C_SMBUS, msg) + except Exception as e: + returnmsg = str(e) + self.close() + if val_t < 0: + return False, returnmsg or "" + return True, "" + + def write_byte_data_pec(self, i2c_addr, register, value, force=None): + """ + Write a byte to a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to write to + :type register: int + :param value: Byte value to transmit + :type value: int + :param force: + :type force: Boolean + :rtype: None + """ + val_t = -1 + returnmsg = "" + try: + val_t = ioctl(self.fd, I2C_PEC, 1) + if val_t < 0: + raise Exception("set pec mod error") + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BYTE_DATA + ) + msg.data.contents.byte = value + val_t = ioctl(self.fd, I2C_SMBUS, msg) + except Exception as e: + returnmsg = str(e) + self.close() + if val_t < 0: + return False, returnmsg or "" + return True, "" + + def read_word_data(self, i2c_addr, register, force=None): + """ + Read a single word (2 bytes) from a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to read + :type register: int + :param force: + :type force: Boolean + :return: 2-byte word + :rtype: int + """ + val_t = -1 + returnmsg = "" + try: + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_WORD_DATA + ) + val_t = ioctl(self.fd, I2C_SMBUS, msg) + except Exception as e: + returnmsg = str(e) + self.close() + if val_t < 0: + return False, returnmsg or "" + return True, msg.data.contents.word + + def write_word_data_pec(self, i2c_addr, register, value, force=None): + """ + Write a byte to a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to write to + :type register: int + :param value: Word value to transmit + :type value: int + :param force: + :type force: Boolean + :rtype: None + """ + val_t = -1 + returnmsg = "" + try: + val_t = ioctl(self.fd, I2C_PEC, 1) + if val_t < 0: + raise Exception("set pec mod error") + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_WORD_DATA + ) + msg.data.contents.word = value + val_t = ioctl(self.fd, I2C_SMBUS, msg) + except Exception as e: + returnmsg = str(e) + self.close() + if val_t < 0: + return False, returnmsg or "" + return True, "" + + def write_word_data(self, i2c_addr, register, value, force=None): + """ + Write a byte to a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to write to + :type register: int + :param value: Word value to transmit + :type value: int + :param force: + :type force: Boolean + :rtype: None + """ + val_t = -1 + returnmsg = "" + try: + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_WORD_DATA + ) + msg.data.contents.word = value + val_t = ioctl(self.fd, I2C_SMBUS, msg) + except Exception as e: + returnmsg = str(e) + self.close() + if val_t < 0: + return False, returnmsg or "" + return True, "" + + def process_call(self, i2c_addr, register, value, force=None): + """ + Executes a SMBus Process Call, sending a 16-bit value and receiving a 16-bit response + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to read/write to + :type register: int + :param value: Word value to transmit + :type value: int + :param force: + :type force: Boolean + :rtype: int + """ + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_PROC_CALL + ) + msg.data.contents.word = value + ioctl(self.fd, I2C_SMBUS, msg) + return msg.data.contents.word + + def read_block_data(self, i2c_addr, register, force=None): + """ + Read a block of up to 32-bytes from a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Start register + :type register: int + :param force: + :type force: Boolean + :return: List of bytes + :rtype: list + """ + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_BLOCK_DATA + ) + ioctl(self.fd, I2C_SMBUS, msg) + length = msg.data.contents.block[0] + return msg.data.contents.block[1:length + 1] + + def write_block_data(self, i2c_addr, register, data, force=None): + """ + Write a block of byte data to a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Start register + :type register: int + :param data: List of bytes + :type data: list + :param force: + :type force: Boolean + :rtype: None + """ + length = len(data) + if length > I2C_SMBUS_BLOCK_MAX: + raise ValueError("Data length cannot exceed %d bytes" % I2C_SMBUS_BLOCK_MAX) + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BLOCK_DATA + ) + msg.data.contents.block[0] = length + msg.data.contents.block[1:length + 1] = data + ioctl(self.fd, I2C_SMBUS, msg) + + def block_process_call(self, i2c_addr, register, data, force=None): + """ + Executes a SMBus Block Process Call, sending a variable-size data + block and receiving another variable-size response + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to read/write to + :type register: int + :param data: List of bytes + :type data: list + :param force: + :type force: Boolean + :return: List of bytes + :rtype: list + """ + length = len(data) + if length > I2C_SMBUS_BLOCK_MAX: + raise ValueError("Data length cannot exceed %d bytes" % I2C_SMBUS_BLOCK_MAX) + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BLOCK_PROC_CALL + ) + msg.data.contents.block[0] = length + msg.data.contents.block[1:length + 1] = data + ioctl(self.fd, I2C_SMBUS, msg) + length = msg.data.contents.block[0] + return msg.data.contents.block[1:length + 1] + + def read_i2c_block_data(self, i2c_addr, register, length, force=None): + """ + Read a block of byte data from a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Start register + :type register: int + :param length: Desired block length + :type length: int + :param force: + :type force: Boolean + :return: List of bytes + :rtype: list + """ + if length > I2C_SMBUS_BLOCK_MAX: + raise ValueError("Desired block length over %d bytes" % I2C_SMBUS_BLOCK_MAX) + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_I2C_BLOCK_DATA + ) + msg.data.contents.byte = length + ioctl(self.fd, I2C_SMBUS, msg) + return msg.data.contents.block[1:length + 1] + + def write_i2c_block_data(self, i2c_addr, register, data, force=None): + """ + Write a block of byte data to a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Start register + :type register: int + :param data: List of bytes + :type data: list + :param force: + :type force: Boolean + :rtype: None + """ + length = len(data) + if length > I2C_SMBUS_BLOCK_MAX: + raise ValueError("Data length cannot exceed %d bytes" % I2C_SMBUS_BLOCK_MAX) + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_I2C_BLOCK_DATA + ) + msg.data.contents.block[0] = length + msg.data.contents.block[1:length + 1] = data + ioctl(self.fd, I2C_SMBUS, msg) + + def i2c_rdwr(self, *i2c_msgs): + """ + Combine a series of i2c read and write operations in a single + transaction (with repeated start bits but no stop bits in between). + + This method takes i2c_msg instances as input, which must be created + first with :py:meth:`i2c_msg.read` or :py:meth:`i2c_msg.write`. + + :param i2c_msgs: One or more i2c_msg class instances. + :type i2c_msgs: i2c_msg + :rtype: None + """ + ioctl_data = i2c_rdwr_ioctl_data.create(*i2c_msgs) + ioctl(self.fd, I2C_RDWR, ioctl_data) + + +class SMBusWrapper: + """ + Wrapper class around the SMBus. + Deprecated as of version 0.3.0. Please replace with :py:class:`SMBus`. + + Enables the user to wrap access to the :py:class:`SMBus` class in a + "with" statement. If auto_cleanup is True (default), the + :py:class:`SMBus` handle will be automatically closed + upon exit of the ``with`` block. + """ + + def __init__(self, bus_number=0, auto_cleanup=True, force=False): + """ + :param auto_cleanup: Close bus when leaving scope. + :type auto_cleanup: Boolean + :param force: Force using the slave address even when driver is already using it. + :type force: Boolean + """ + self.bus_number = bus_number + self.auto_cleanup = auto_cleanup + self.force = force + self.bus = None + + def __enter__(self): + self.bus = SMBus(bus=self.bus_number, force=self.force) + return self.bus + + def __exit__(self, exc_type, exc_val, exc_tb): + if self.auto_cleanup: + self.bus.close() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modprobe_conf/kernel_drivers_blacklist.conf b/platform/broadcom/sonic-platform-modules-ragile/common/modprobe_conf/kernel_drivers_blacklist.conf new file mode 100644 index 000000000000..5e861802d915 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modprobe_conf/kernel_drivers_blacklist.conf @@ -0,0 +1,5 @@ +blacklist wb_fpga_pcie +blacklist wb_i2c_i801 +blacklist wb_spi_gpio +blacklist intel_spi +blacklist intel_spi_platform diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile old mode 100755 new mode 100644 index f7204c8684d9..8727f1f508f1 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile @@ -1,15 +1,55 @@ -obj-m := rg-gpio-xeon.o -obj-m += rg_fan.o -obj-m += rg_psu.o -obj-m += ragile_platform.o -obj-m += i2c-mux-pca9641.o -obj-m += i2c-mux-pca954x.o -obj-m += csu550.o -ragile_common-objs := ragile_common_module.o -obj-m += ragile_common.o -obj-m += fpga_pcie_i2c.o -obj-m += fpga_i2c_ocores.o -obj-m += lpc_dbg.o -obj-m += lpc_cpld_i2c_ocores.o -obj-m += rg-i2c-algo-bit.o -obj-m += rg-i2c-gpio.o +PWD = $(shell pwd) +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +KVERSION ?= $(shell uname -r) +KERNEL_SRC ?= /lib/modules/$(KVERSION) + +module_out_put_dir := $(PWD)/build +export module_out_put_dir + +KERNEL_MODULES_SRC = $(PWD)/linux-5.10 + +PLAT_SYSFS_DIR = $(PWD)/plat_sysfs +INTEL_SPI = $(PWD)/intel_spi + +export PLAT_SYSFS_DIR + +platform_common-objs := platform_common_module.o dfd_tlveeprom.o +obj-m += platform_common.o +obj-m += wb_mac_bsc.o +obj-m += wb_fpga_pcie.o +obj-m += wb_pcie_dev.o +obj-m += wb_fpga_i2c_bus_drv.o +obj-m += wb_fpga_pca954x_drv.o +obj-m += wb_lpc_drv.o +obj-m += wb_i2c_dev.o +obj-m += wb_platform_i2c_dev.o +obj-m += wb_io_dev.o +obj-m += wb_eeprom_93xx46.o +obj-m += wb_spi_93xx46.o +obj-m += wb_gpio_d1500.o +obj-m += wb_gpio_device.o +obj-m += wb_i2c_ocores.o +obj-m += wb_spi_ocores.o +obj-m += wb_spi_dev.o +obj-m += wb_wdt.o +obj-m += wb_optoe.o +obj-m += wb_spi_gpio.o +obj-m += wb_spi_gpio_device.o +obj-m += wb_spi_nor_device.o +obj-m += wb_xdpe132g5c.o +obj-m += wb_uio_irq.o + +all : + $(MAKE) -C $(KERNEL_MODULES_SRC) + $(MAKE) -C $(PLAT_SYSFS_DIR) + $(MAKE) -C $(INTEL_SPI) + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) + +clean : + rm -rf $(module_out_put_dir) + rm -f ${PWD}/*.o ${PWD}/*.ko ${PWD}/*.mod.c ${PWD}/.*.cmd ${PWD}/.*.o.d ${PWD}/*.mod + rm -f ${PWD}/Module.markers ${PWD}/Module.symvers ${PWD}/modules.order + rm -rf ${PWD}/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.c new file mode 100644 index 000000000000..0d6f38ecc551 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.c @@ -0,0 +1,516 @@ +/* + * Copyright (C) 2003-2014 FreeIPMI Core Team + * + * 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 . + * + */ +/*****************************************************************************\ + * Copyright (C) 2007-2014 Lawrence Livermore National Security, LLC. + * Copyright (C) 2007 The Regents of the University of California. + * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). + * Written by Albert Chu + * UCRL-CODE-232183 + * + * This file is part of Ipmi-fru, a tool used for retrieving + * motherboard field replaceable unit (FRU) information. For details, + * see http://www.llnl.gov/linux/. + * + * Ipmi-fru 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. + * + * Ipmi-fru 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 Ipmi-fru. If not, see . +\*****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "platform_common.h" +#include "dfd_tlveeprom.h" + +/* using in is_valid_tlvinfo_header */ +static u_int32_t eeprom_size; + +/* + * List of TLV codes and names. + */ +static const struct tlv_code_desc tlv_code_list[] = { + { TLV_CODE_PRODUCT_NAME , "Product Name"}, + { TLV_CODE_PART_NUMBER , "Part Number"}, + { TLV_CODE_SERIAL_NUMBER , "Serial Number"}, + { TLV_CODE_MAC_BASE , "Base MAC Address"}, + { TLV_CODE_MANUF_DATE , "Manufacture Date"}, + { TLV_CODE_DEVICE_VERSION , "Device Version"}, + { TLV_CODE_LABEL_REVISION , "Label Revision"}, + { TLV_CODE_PLATFORM_NAME , "Platform Name"}, + { TLV_CODE_ONIE_VERSION , "ONIE Version"}, + { TLV_CODE_MAC_SIZE , "MAC Addresses"}, + { TLV_CODE_MANUF_NAME , "Manufacturer"}, + { TLV_CODE_MANUF_COUNTRY , "Country Code"}, + { TLV_CODE_VENDOR_NAME , "Vendor Name"}, + { TLV_CODE_DIAG_VERSION , "Diag Version"}, + { TLV_CODE_SERVICE_TAG , "Service Tag"}, + { TLV_CODE_VENDOR_EXT , "Vendor Extension"}, + { TLV_CODE_CRC_32 , "CRC-32"}, +}; + +#if 0 +#define OPENBMC_VPD_KEY_INVAIL_VAL 0 + +static const tlv_code_map_t tlv_code_map[] = { + { TLV_CODE_PRODUCT_NAME , OPENBMC_VPD_KEY_PRODUCT_NAME}, + { TLV_CODE_PART_NUMBER , OPENBMC_VPD_KEY_PRODUCT_PART_MODEL_NUM}, + { TLV_CODE_SERIAL_NUMBER , OPENBMC_VPD_KEY_PRODUCT_SERIAL_NUM}, + { TLV_CODE_MAC_BASE , OPENBMC_VPD_KEY_INVAIL_VAL}, + { TLV_CODE_MANUF_DATE , OPENBMC_VPD_KEY_BOARD_MFG_DATE}, + { TLV_CODE_DEVICE_VERSION , OPENBMC_VPD_KEY_PRODUCT_VER}, + { TLV_CODE_LABEL_REVISION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM7}, + { TLV_CODE_PLATFORM_NAME , OPENBMC_VPD_KEY_PRODUCT_CUSTOM1}, + { TLV_CODE_ONIE_VERSION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM2}, + { TLV_CODE_MAC_SIZE , OPENBMC_VPD_KEY_INVAIL_VAL}, + { TLV_CODE_MANUF_NAME , OPENBMC_VPD_KEY_PRODUCT_MFR}, + { TLV_CODE_MANUF_COUNTRY , OPENBMC_VPD_KEY_PRODUCT_CUSTOM3}, + { TLV_CODE_VENDOR_NAME , OPENBMC_VPD_KEY_PRODUCT_CUSTOM4}, + { TLV_CODE_DIAG_VERSION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM8}, + { TLV_CODE_SERVICE_TAG , OPENBMC_VPD_KEY_PRODUCT_CUSTOM5}, + { TLV_CODE_VENDOR_EXT , OPENBMC_VPD_KEY_PRODUCT_CUSTOM6}, + { TLV_CODE_CRC_32 , OPENBMC_VPD_KEY_INVAIL_VAL}, +}; +#endif + +#define TLV_CODE_NUM (sizeof(tlv_code_list) / sizeof(tlv_code_list[0])) + +#if 0 +#define TLV_CODE_MAP_NUM (sizeof(tlv_code_map) / sizeof(tlv_code_map[0])) +#endif + +const unsigned long crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +static unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len) +{ + unsigned i; + if (len < 1) + return 0xffffffff; + + for (i = 0; i != len; ++i) + { + crc = crc_table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8); + } + + crc = crc ^ 0xffffffff; + + return crc; +} + +/* + * is_valid_tlv + * + * Perform basic sanity checks on a TLV field. The TLV is pointed to + * by the parameter provided. + * 1. The type code is not reserved (0x00 or 0xFF) + */ +static inline bool is_valid_tlv(tlvinfo_tlv_t *tlv) +{ + return ((tlv->type != 0x00) && (tlv->type != 0xFF)); +} + +/* + * is_valid_tlvinfo_header + * + * Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM + * data pointed to by the parameter: + * 1. First 8 bytes contain null-terminated ASCII string "TlvInfo" + * 2. Version byte is 1 + * 3. Total length bytes contain value which is less than or equal + * to the allowed maximum (2048-11) + * + */ +static inline bool is_valid_tlvinfo_header(tlvinfo_header_t *hdr) +{ + int max_size = eeprom_size; + return((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) && + (hdr->version == TLV_INFO_VERSION) && + (be16_to_cpu(hdr->totallen) <= max_size) ); +} + +/* + * decode_tlv_value + * + * Decode a single TLV value into a string. + + * The validity of EEPROM contents and the TLV field have been verified + * prior to calling this function. + */ +static void decode_tlv_value(tlvinfo_tlv_t *tlv, tlv_decode_value_t *decode_value) +{ + int i; + char *value; + u_int32_t length; + + value = (char *)decode_value->value; + + switch (tlv->type) { + case TLV_CODE_PRODUCT_NAME: + case TLV_CODE_PART_NUMBER: + case TLV_CODE_SERIAL_NUMBER: + case TLV_CODE_MANUF_DATE: + case TLV_CODE_LABEL_REVISION: + case TLV_CODE_PLATFORM_NAME: + case TLV_CODE_ONIE_VERSION: + case TLV_CODE_MANUF_NAME: + case TLV_CODE_MANUF_COUNTRY: + case TLV_CODE_VENDOR_NAME: + case TLV_CODE_DIAG_VERSION: + case TLV_CODE_SERVICE_TAG: + case TLV_CODE_VENDOR_EXT: + memcpy(value, tlv->value, tlv->length); + value[tlv->length] = 0; + length = tlv->length; + break; + case TLV_CODE_MAC_BASE: + length = sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X", + tlv->value[0], tlv->value[1], tlv->value[2], + tlv->value[3], tlv->value[4], tlv->value[5]); + break; + case TLV_CODE_DEVICE_VERSION: + length = sprintf(value, "%u", tlv->value[0]); + break; + case TLV_CODE_MAC_SIZE: + length = sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]); + break; + #if 0 + case TLV_CODE_VENDOR_EXT: + value[0] = 0; + length = 0; + for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) { + length += sprintf(value, "%s 0x%02X", value, tlv->value[i]); + } + break; + #endif + case TLV_CODE_CRC_32: + length = sprintf(value, "0x%02X%02X%02X%02X", tlv->value[0], + tlv->value[1], tlv->value[2], tlv->value[3]); + break; + default: + value[0] = 0; + length = 0; + for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) { + length += sprintf(value, "%s 0x%02X", value, tlv->value[i]); + } + break; + } + + decode_value->length = length; +} + +/* + * is_checksum_valid + * + * Validate the checksum in the provided TlvInfo EEPROM data. First, + * verify that the TlvInfo header is valid, then make sure the last + * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data + * and compare it to the value stored in the EEPROM CRC-32 TLV. + */ +static bool is_checksum_valid(u_int8_t *eeprom) +{ + tlvinfo_header_t *eeprom_hdr; + tlvinfo_tlv_t *eeprom_crc; + unsigned int calc_crc; + unsigned int stored_crc; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + + // Is the eeprom header valid? + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + return false; + } + + // Is the last TLV a CRC? + eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) + + be16_to_cpu(eeprom_hdr->totallen) - (sizeof(tlvinfo_tlv_t) + 4)]; + if ((eeprom_crc->type != TLV_CODE_CRC_32) || (eeprom_crc->length != 4)) { + return false; + } + + // Calculate the checksum + calc_crc = crc32(0xffffffffL, (const unsigned char *)eeprom, sizeof(tlvinfo_header_t) + + be16_to_cpu(eeprom_hdr->totallen) - 4); + stored_crc = ((eeprom_crc->value[0] << 24) | (eeprom_crc->value[1] << 16) | + (eeprom_crc->value[2] << 8) | eeprom_crc->value[3]); + + return (calc_crc == stored_crc); +} + +/* + * tlvinfo_find_tlv + * + * This function finds the TLV with the supplied code in the EERPOM. + * An offset from the beginning of the EEPROM is returned in the + * eeprom_index parameter if the TLV is found. + */ +static bool tlvinfo_find_tlv(u_int8_t *eeprom, u_int8_t tcode, int *eeprom_index) +{ + tlvinfo_header_t *eeprom_hdr; + tlvinfo_tlv_t *eeprom_tlv; + int eeprom_end; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + + // Search through the TLVs, looking for the first one which matches the + // supplied type code. + *eeprom_index = sizeof(tlvinfo_header_t); + eeprom_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen); + while (*eeprom_index < eeprom_end) { + eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[*eeprom_index]; + if (!is_valid_tlv(eeprom_tlv)) { + return false; + } + + if (eeprom_tlv->type == tcode) { + return true; + } + + *eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length; + } + + return false; +} + +/* + * tlvinfo_decode_tlv + * + * This function finds the TLV with the supplied code in the EERPOM + * and decodes the value into the buffer provided. + */ +static bool tlvinfo_decode_tlv(u_int8_t *eeprom, u_int8_t tcode, tlv_decode_value_t *decode_value) +{ + int eeprom_index; + tlvinfo_tlv_t *eeprom_tlv; + + // Find the TLV and then decode it + if (tlvinfo_find_tlv(eeprom, tcode, &eeprom_index)) { + eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index]; + decode_tlv_value(eeprom_tlv, decode_value); + return true; + } + + return false; +} + +/* + * parse_tlv_eeprom + * + * parse the EEPROM into memory, if it hasn't already been read. + */ +int parse_tlv_eeprom(u_int8_t *eeprom, u_int32_t size) +{ + unsigned int i; + bool ret; + tlvinfo_header_t *eeprom_hdr; + //tlv_info_vec_t tlv_info; + tlv_decode_value_t decode_value; + int j; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + eeprom_size = size; /* eeprom real size */ + + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + DBG_ERROR("Failed to check tlv header.\n"); + return -1; + } + + if (!is_checksum_valid(eeprom)) { + DBG_ERROR("Failed to check tlv crc.\n"); + return -1; + } + + for (i = 0; i < TLV_CODE_NUM; i++) { + mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t)); + ret = tlvinfo_decode_tlv(eeprom, tlv_code_list[i].m_code, &decode_value); + if (!ret) { + DBG_ERROR("No found type: %s\n", tlv_code_list[i].m_name); + continue; + } + + DBG_DEBUG("i: %d,Found type: %s tlv[%d]:%s\n", i, tlv_code_list[i].m_name, tlv_code_list[i].m_code, + decode_value.value); + for (j = 0; j < decode_value.length; j++) { + if ((j % 16) == 0) { + DBG_DEBUG("\n"); + } + DBG_DEBUG("%02x ", decode_value.value[j]); + } + DBG_DEBUG("\n\n"); + } + return 0; +} +static int dfd_parse_tlv_eeprom(u_int8_t *eeprom, u_int32_t size, u_int8_t main_type, tlv_decode_value_t *decode_value) +{ + bool ret; + tlvinfo_header_t *eeprom_hdr; + //tlv_info_vec_t tlv_info; + int j; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + eeprom_size = size; /* eeprom real size */ + + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + DBG_ERROR("Failed to check tlv header.\n"); + return -1; + } + + if (!is_checksum_valid(eeprom)) { + DBG_ERROR("Failed to check tlv crc.\n"); + return -1; + } + + ret = tlvinfo_decode_tlv(eeprom, main_type, decode_value); + if (!ret) { + DBG_ERROR("No found type: %d\n", main_type); + return -1; + } + + DBG_DEBUG("Found type: %d, value: %s\n", main_type,decode_value->value); + for (j = 0; j < decode_value->length; j++) { + if ((j % 16) == 0) { + DBG_DEBUG("\n"); + } + DBG_DEBUG("%02x ", decode_value->value[j]); + } + DBG_DEBUG("\n\n"); + + return 0; +} + +static int tlvinfo_find_wb_ext_tlv(tlv_decode_value_t *ext_tlv_value, u_int8_t ext_type, + u_int8_t *buf, u_int8_t *buf_len) +{ + tlvinfo_tlv_t *eeprom_tlv; + int eeprom_end, eeprom_index; + + // Search through the TLVs, looking for the first one which matches the + // supplied type code. + DBG_DEBUG("ext_tlv_value->length: %d.\n", ext_tlv_value->length); + for (eeprom_index = 0; eeprom_index < ext_tlv_value->length; eeprom_index++) { + if ((eeprom_index % 16) == 0) { + DBG_DEBUG("\n"); + } + DBG_DEBUG("%02x ", ext_tlv_value->value[eeprom_index]); + } + + DBG_DEBUG("\n"); + + eeprom_index = 0; + eeprom_end = ext_tlv_value->length; + while (eeprom_index < eeprom_end) { + eeprom_tlv = (tlvinfo_tlv_t *) &(ext_tlv_value->value[eeprom_index]); + if (!is_valid_tlv(eeprom_tlv)) { + DBG_ERROR("tlv is not valid, eeprom_tlv->type 0x%x.\n", eeprom_tlv->type); + return -1; + } + + DBG_DEBUG("eeprom_tlv->length %d.\n", eeprom_tlv->length); + if (eeprom_tlv->type == ext_type) { + if (*buf_len >= eeprom_tlv->length) { + memcpy(buf, eeprom_tlv->value, eeprom_tlv->length); + DBG_DEBUG("eeprom_tlv->length %d.\n", eeprom_tlv->length); + *buf_len = eeprom_tlv->length; + return 0; + } + DBG_ERROR("buf_len %d small than info_len %d.\n", *buf_len, eeprom_tlv->length); + return -1; + } + + eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length; + } + + DBG_ERROR("ext_type %d: tlv is not found.\n", ext_type); + return -1; +} + +int dfd_tlvinfo_get_e2prom_info(u_int8_t *eeprom, u_int32_t size, dfd_tlv_type_t *tlv_type, u_int8_t* buf, u_int8_t *buf_len) +{ + tlv_decode_value_t decode_value; + int ret; + + if (eeprom == NULL || tlv_type == NULL || buf == NULL) { + DBG_ERROR("Input para invalid.\n"); + return -1; + } + + mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t)); + ret = dfd_parse_tlv_eeprom(eeprom, size, tlv_type->main_type, &decode_value); + if (ret) { + DBG_ERROR("dfd_parse_tlv_eeprom failed ret %d.\n", ret); + return ret; + } + + if (tlv_type->main_type != TLV_CODE_VENDOR_EXT) { + if (*buf_len >= decode_value.length) { + memcpy(buf, decode_value.value, decode_value.length); + *buf_len = decode_value.length; + return 0; + } + DBG_ERROR("buf_len %d small than info_len %d.\n", *buf_len, decode_value.length); + return -1; + } + DBG_DEBUG("info_len %d.\n", decode_value.length); + + return tlvinfo_find_wb_ext_tlv(&decode_value, tlv_type->ext_type, buf, buf_len); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.h new file mode 100644 index 000000000000..6eaac5848223 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.h @@ -0,0 +1,121 @@ +#ifndef DFD_OPENBMC_TLVEEPROM_H +#define DFD_OPENBMC_TLVEEPROM_H + +#ifndef u_int8_t +#define u_int8_t unsigned char +#endif + +#ifndef u_int16_t +#define u_int16_t unsigned short +#endif + +#ifndef u_int32_t +#define u_int32_t unsigned int +#endif + +#ifndef be16_to_cpu +#define be16_to_cpu(x) ntohs(x) +#endif + +#ifndef cpu_to_be16 +#define cpu_to_be16(x) htons(x) +#endif + +/** + * The TLV Types. + * + * Keep these in sync with tlv_code_list in cmd_sys_eeprom.c + */ +#define TLV_CODE_PRODUCT_NAME 0x21 +#define TLV_CODE_PART_NUMBER 0x22 +#define TLV_CODE_SERIAL_NUMBER 0x23 +#define TLV_CODE_MAC_BASE 0x24 +#define TLV_CODE_MANUF_DATE 0x25 +#define TLV_CODE_DEVICE_VERSION 0x26 +#define TLV_CODE_LABEL_REVISION 0x27 +#define TLV_CODE_PLATFORM_NAME 0x28 +#define TLV_CODE_ONIE_VERSION 0x29 +#define TLV_CODE_MAC_SIZE 0x2A +#define TLV_CODE_MANUF_NAME 0x2B +#define TLV_CODE_MANUF_COUNTRY 0x2C +#define TLV_CODE_VENDOR_NAME 0x2D +#define TLV_CODE_DIAG_VERSION 0x2E +#define TLV_CODE_SERVICE_TAG 0x2F +#define TLV_CODE_VENDOR_EXT 0xFD +#define TLV_CODE_CRC_32 0xFE + +#define TLV_CODE_NAME_LEN 64 +/* + * Struct for displaying the TLV codes and names. + */ +struct tlv_code_desc { + u_int8_t m_code; + char m_name[TLV_CODE_NAME_LEN]; +}; + +typedef struct dfd_tlv_type_s { + u_int8_t main_type; + u_int8_t ext_type; +} dfd_tlv_type_t; + +// Header Field Constants +#define TLV_INFO_ID_STRING "TlvInfo" +#define TLV_INFO_VERSION 0x01 +/*#define TLV_TOTAL_LEN_MAX (XXXXXXXX - sizeof(tlvinfo_header_t))*/ + +struct __attribute__ ((__packed__)) tlvinfo_header_s { + char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */ + u_int8_t version; /* 0x08 Structure version */ + u_int16_t totallen; /* 0x09 - 0x0A Length of all data which follows */ +}; +typedef struct tlvinfo_header_s tlvinfo_header_t; + +/* + * TlvInfo TLV: Layout of a TLV field + */ +struct __attribute__ ((__packed__)) tlvinfo_tlv_s { + u_int8_t type; + u_int8_t length; + u_int8_t value[0]; +}; +typedef struct tlvinfo_tlv_s tlvinfo_tlv_t; + +#define TLV_VALUE_MAX_LEN 255 +/* + * The max decode value is currently for the 'raw' type or the 'vendor + * extension' type, both of which have the same decode format. The + * max decode string size is computed as follows: + * + * strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1 + * + */ +#define TLV_DECODE_VALUE_MAX_LEN ((5 * TLV_VALUE_MAX_LEN) + 1) + +typedef struct tlv_decode_value_s { + u_int8_t value[TLV_DECODE_VALUE_MAX_LEN]; + u_int32_t length; +} tlv_decode_value_t; + +typedef enum dfd_tlvinfo_ext_tlv_type_e { + DFD_TLVINFO_EXT_TLV_TYPE_DEV_TYPE = 1, +} dfd_tlvinfo_ext_tlv_type_t; + +#if 0 +#define TLV_TIME_LEN 64 + +int ipmi_tlv_validate_fru_area(const uint8_t fruid, const char *fru_file_name, + sd_bus *bus_type, const bool bmc_fru); + +extern const char *get_vpd_key_names(int key_id); +extern std::string getService(sdbusplus::bus::bus& bus, + const std::string& intf, + const std::string& path); +extern std::string getFRUValue(const std::string& section, + const std::string& key, + const std::string& delimiter, + IPMIFruInfo& fruData); +#endif + +int dfd_tlvinfo_get_e2prom_info(u_int8_t *eeprom, u_int32_t size, dfd_tlv_type_t *tlv_type, u_int8_t* buf, u_int8_t *buf_len); + +#endif /* endif DFD_OPENBMC_TLVEEPROM_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c.h new file mode 100644 index 000000000000..649a8452debe --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c.h @@ -0,0 +1,133 @@ +#ifndef _FPGA_I2C_H +#define _FPGA_I2C_H + +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#if 0 + +#define FPGA_I2C_EXT_9548_ADDR (0x00) +#define FPGA_I2C_EXT_9548_CHAN (0x04) +#define FPGA_I2C_DEV_SLAVE_ADDR (0x08) +#define FPGA_I2C_DEV_REG_ADDR (0x0C) +#define FPGA_I2C_DEV_RDWR_LEN (0x10) +#define FPGA_I2C_CTRL_REG (0x14) +#define FPGA_I2C_STATUS_REG (0x18) +#define FPGA_I2C_SCALE_REG (0x1C) +#define FPGA_I2C_FILTER_REG (0x20) +#define FPGA_I2C_STRETCH_REG (0x24) +#define FPGA_I2C_EXT_9548_EXITS_FLAG (0x28) +#define FPGA_I2C_INTERNAL_9548_CHAN (0x2C) +#define FPGA_I2C_RDWR_DATA_BUF (0x80) +#endif +#define FPGA_I2C_RDWR_MAX_LEN_DEFAULT (128) +#define I2C_REG_MAX_WIDTH (16) + +#define DEV_NAME_MAX_LEN (64) + +#define FPGA_I2C_MAX_TIMES (10) +#define FPGA_I2C_XFER_TIME_OUT (100000) +#define FPGA_I2C_SLEEP_TIME (40) + +typedef struct fpga_i2c_reg_s { + uint32_t i2c_scale; + uint32_t i2c_filter; + uint32_t i2c_stretch; + uint32_t i2c_ext_9548_exits_flag; + uint32_t i2c_ext_9548_addr; + uint32_t i2c_ext_9548_chan; + uint32_t i2c_in_9548_chan; + uint32_t i2c_slave; + uint32_t i2c_reg; + uint32_t i2c_reg_len; + uint32_t i2c_data_len; + uint32_t i2c_ctrl; + uint32_t i2c_status; + uint32_t i2c_err_vec; + uint32_t i2c_data_buf; + uint32_t i2c_data_buf_len; +} fpga_i2c_reg_t; + +typedef struct fpga_i2c_reset_cfg_s { + uint32_t i2c_adap_reset_flag; + uint32_t reset_addr; + uint32_t reset_on; + uint32_t reset_off; + uint32_t reset_delay_b; + uint32_t reset_delay; + uint32_t reset_delay_a; +} fpga_i2c_reset_cfg_t; + +typedef struct fpga_i2c_reg_addr_s { + uint8_t reg_addr_len; + uint8_t read_reg_addr[I2C_REG_MAX_WIDTH]; +} fpga_i2c_reg_addr_t; + +typedef struct fpga_i2c_dev_s { + fpga_i2c_reg_t reg; + fpga_i2c_reset_cfg_t reset_cfg; + fpga_i2c_reg_addr_t i2c_addr_desc; + const char *dev_name; + uint32_t i2c_scale_value; + uint32_t i2c_filter_value; + uint32_t i2c_stretch_value; + uint32_t i2c_timeout; + uint32_t i2c_func_mode; + wait_queue_head_t queue; + struct i2c_adapter adap; + int adap_nr; + struct device *dev; + bool i2c_params_check; +} fpga_i2c_dev_t; + +typedef struct fpga_i2c_bus_device_s { + int i2c_timeout; + int i2c_scale; + int i2c_filter; + int i2c_stretch; + int i2c_ext_9548_exits_flag; + int i2c_ext_9548_addr; + int i2c_ext_9548_chan; + int i2c_in_9548_chan; + int i2c_slave; + int i2c_reg; + int i2c_reg_len; + int i2c_data_len; + int i2c_ctrl; + int i2c_status; + int i2c_err_vec; + int i2c_data_buf; + int i2c_data_buf_len; + char dev_name[DEV_NAME_MAX_LEN]; + int adap_nr; + int i2c_scale_value; + int i2c_filter_value; + int i2c_stretch_value; + int i2c_func_mode; + int i2c_adap_reset_flag; + int i2c_reset_addr; + int i2c_reset_on; + int i2c_reset_off; + int i2c_rst_delay_b; /* delay time before reset(us) */ + int i2c_rst_delay; /* reset time(us) */ + int i2c_rst_delay_a; /* delay time after reset(us) */ + int device_flag; + bool i2c_params_check; + int i2c_data_buf_len_reg; + int i2c_offset_reg; +} fpga_i2c_bus_device_t; + +typedef struct fpga_pca954x_device_s { + struct i2c_client *client; + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t fpga_9548_flag; + uint32_t fpga_9548_reset_flag; + uint32_t pca9548_base_nr; +} fpga_pca954x_device_t; + +#endif /* _FPGA_I2C_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/Makefile new file mode 100644 index 000000000000..269e95019cba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/Makefile @@ -0,0 +1,21 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +#ifdef ENABLE_GCOV +#ifeq ($(ENABLE_GCOV), y) +#EXTRA_CFLAGS+= -fprofile-arcs -ftest-coverage -lgcov +#endif +#endif # ENABLE_GCOV + +obj-m := intel_spi.o +obj-m += intel_spi_platform.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/include/intel_spi.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/include/intel_spi.h new file mode 100644 index 000000000000..d0a570b1f3b0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/include/intel_spi.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Intel PCH/PCU SPI flash driver. + * + * Copyright (C) 2016, Intel Corporation + * Author: Mika Westerberg + */ + +#ifndef INTEL_SPI_H +#define INTEL_SPI_H + +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +struct intel_spi; +struct resource; + +struct intel_spi *intel_spi_probe(struct device *dev, + struct resource *mem, const struct intel_spi_boardinfo *info); +int intel_spi_remove(struct intel_spi *ispi); + +#endif /* INTEL_SPI_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi.c new file mode 100644 index 000000000000..98de90f0c0b2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi.c @@ -0,0 +1,969 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Intel PCH/PCU SPI flash driver. + * + * Copyright (C) 2016, Intel Corporation + * Author: Mika Westerberg + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "intel_spi.h" + +/* Offsets are from @ispi->base */ +#define BFPREG 0x00 + +#define HSFSTS_CTL 0x04 +#define HSFSTS_CTL_FSMIE BIT(31) +#define HSFSTS_CTL_FDBC_SHIFT 24 +#define HSFSTS_CTL_FDBC_MASK (0x3f << HSFSTS_CTL_FDBC_SHIFT) + +#define HSFSTS_CTL_FCYCLE_SHIFT 17 +#define HSFSTS_CTL_FCYCLE_MASK (0x0f << HSFSTS_CTL_FCYCLE_SHIFT) +/* HW sequencer opcodes */ +#define HSFSTS_CTL_FCYCLE_READ (0x00 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_WRITE (0x02 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_ERASE (0x03 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_ERASE_64K (0x04 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_RDID (0x06 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_WRSR (0x07 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_RDSR (0x08 << HSFSTS_CTL_FCYCLE_SHIFT) + +#define HSFSTS_CTL_FGO BIT(16) +#define HSFSTS_CTL_FLOCKDN BIT(15) +#define HSFSTS_CTL_FDV BIT(14) +#define HSFSTS_CTL_SCIP BIT(5) +#define HSFSTS_CTL_AEL BIT(2) +#define HSFSTS_CTL_FCERR BIT(1) +#define HSFSTS_CTL_FDONE BIT(0) + +#define FADDR 0x08 +#define DLOCK 0x0c +#define FDATA(n) (0x10 + ((n) * 4)) + +#define FRACC 0x50 + +#define FREG(n) (0x54 + ((n) * 4)) +#define FREG_BASE_MASK 0x3fff +#define FREG_LIMIT_SHIFT 16 +#define FREG_LIMIT_MASK (0x03fff << FREG_LIMIT_SHIFT) + +/* Offset is from @ispi->pregs */ +#define PR(n) ((n) * 4) +#define PR_WPE BIT(31) +#define PR_LIMIT_SHIFT 16 +#define PR_LIMIT_MASK (0x3fff << PR_LIMIT_SHIFT) +#define PR_RPE BIT(15) +#define PR_BASE_MASK 0x3fff + +/* Offsets are from @ispi->sregs */ +#define SSFSTS_CTL 0x00 +#define SSFSTS_CTL_FSMIE BIT(23) +#define SSFSTS_CTL_DS BIT(22) +#define SSFSTS_CTL_DBC_SHIFT 16 +#define SSFSTS_CTL_SPOP BIT(11) +#define SSFSTS_CTL_ACS BIT(10) +#define SSFSTS_CTL_SCGO BIT(9) +#define SSFSTS_CTL_COP_SHIFT 12 +#define SSFSTS_CTL_FRS BIT(7) +#define SSFSTS_CTL_DOFRS BIT(6) +#define SSFSTS_CTL_AEL BIT(4) +#define SSFSTS_CTL_FCERR BIT(3) +#define SSFSTS_CTL_FDONE BIT(2) +#define SSFSTS_CTL_SCIP BIT(0) + +#define PREOP_OPTYPE 0x04 +#define OPMENU0 0x08 +#define OPMENU1 0x0c + +#define OPTYPE_READ_NO_ADDR 0 +#define OPTYPE_WRITE_NO_ADDR 1 +#define OPTYPE_READ_WITH_ADDR 2 +#define OPTYPE_WRITE_WITH_ADDR 3 + +/* CPU specifics */ +#define BYT_PR 0x74 +#define BYT_SSFSTS_CTL 0x90 +#define BYT_BCR 0xfc +#define BYT_BCR_WPD BIT(0) +#define BYT_FREG_NUM 5 +#define BYT_PR_NUM 5 + +#define LPT_PR 0x74 +#define LPT_SSFSTS_CTL 0x90 +#define LPT_FREG_NUM 5 +#define LPT_PR_NUM 5 + +#define BXT_PR 0x84 +#define BXT_SSFSTS_CTL 0xa0 +#define BXT_FREG_NUM 12 +#define BXT_PR_NUM 6 + +#define CNL_PR 0x84 +#define CNL_FREG_NUM 6 +#define CNL_PR_NUM 5 + +#define LVSCC 0xc4 +#define UVSCC 0xc8 +#define ERASE_OPCODE_SHIFT 8 +#define ERASE_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) +#define ERASE_64K_OPCODE_SHIFT 16 +#define ERASE_64K_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) + +#define INTEL_SPI_TIMEOUT 5000 /* ms */ +#define INTEL_SPI_FIFO_SZ 64 + +/** + * struct intel_spi - Driver private data + * @dev: Device pointer + * @info: Pointer to board specific info + * @nor: SPI NOR layer structure + * @base: Beginning of MMIO space + * @pregs: Start of protection registers + * @sregs: Start of software sequencer registers + * @nregions: Maximum number of regions + * @pr_num: Maximum number of protected range registers + * @writeable: Is the chip writeable + * @locked: Is SPI setting locked + * @swseq_reg: Use SW sequencer in register reads/writes + * @swseq_erase: Use SW sequencer in erase operation + * @erase_64k: 64k erase supported + * @atomic_preopcode: Holds preopcode when atomic sequence is requested + * @opcodes: Opcodes which are supported. This are programmed by BIOS + * before it locks down the controller. + */ +struct intel_spi { + struct device *dev; + const struct intel_spi_boardinfo *info; + struct spi_nor nor; + void __iomem *base; + void __iomem *pregs; + void __iomem *sregs; + size_t nregions; + size_t pr_num; + bool writeable; + bool locked; + bool swseq_reg; + bool swseq_erase; + bool erase_64k; + u8 atomic_preopcode; + u8 opcodes[8]; +}; + +static bool writeable; +module_param(writeable, bool, 0); +MODULE_PARM_DESC(writeable, "Enable write access to SPI flash chip (default=0)"); + +static void intel_spi_dump_regs(struct intel_spi *ispi) +{ + u32 value; + int i; + + dev_dbg(ispi->dev, "BFPREG=0x%08x\n", readl(ispi->base + BFPREG)); + + value = readl(ispi->base + HSFSTS_CTL); + dev_dbg(ispi->dev, "HSFSTS_CTL=0x%08x\n", value); + if (value & HSFSTS_CTL_FLOCKDN) + dev_dbg(ispi->dev, "-> Locked\n"); + + dev_dbg(ispi->dev, "FADDR=0x%08x\n", readl(ispi->base + FADDR)); + dev_dbg(ispi->dev, "DLOCK=0x%08x\n", readl(ispi->base + DLOCK)); + + for (i = 0; i < 16; i++) + dev_dbg(ispi->dev, "FDATA(%d)=0x%08x\n", + i, readl(ispi->base + FDATA(i))); + + dev_dbg(ispi->dev, "FRACC=0x%08x\n", readl(ispi->base + FRACC)); + + for (i = 0; i < ispi->nregions; i++) + dev_dbg(ispi->dev, "FREG(%d)=0x%08x\n", i, + readl(ispi->base + FREG(i))); + for (i = 0; i < ispi->pr_num; i++) + dev_dbg(ispi->dev, "PR(%d)=0x%08x\n", i, + readl(ispi->pregs + PR(i))); + + if (ispi->sregs) { + value = readl(ispi->sregs + SSFSTS_CTL); + dev_dbg(ispi->dev, "SSFSTS_CTL=0x%08x\n", value); + dev_dbg(ispi->dev, "PREOP_OPTYPE=0x%08x\n", + readl(ispi->sregs + PREOP_OPTYPE)); + dev_dbg(ispi->dev, "OPMENU0=0x%08x\n", + readl(ispi->sregs + OPMENU0)); + dev_dbg(ispi->dev, "OPMENU1=0x%08x\n", + readl(ispi->sregs + OPMENU1)); + } + + if (ispi->info->type == INTEL_SPI_BYT) + dev_dbg(ispi->dev, "BCR=0x%08x\n", readl(ispi->base + BYT_BCR)); + + dev_dbg(ispi->dev, "LVSCC=0x%08x\n", readl(ispi->base + LVSCC)); + dev_dbg(ispi->dev, "UVSCC=0x%08x\n", readl(ispi->base + UVSCC)); + + dev_dbg(ispi->dev, "Protected regions:\n"); + for (i = 0; i < ispi->pr_num; i++) { + u32 base, limit; + + value = readl(ispi->pregs + PR(i)); + if (!(value & (PR_WPE | PR_RPE))) + continue; + + limit = (value & PR_LIMIT_MASK) >> PR_LIMIT_SHIFT; + base = value & PR_BASE_MASK; + + dev_dbg(ispi->dev, " %02d base: 0x%08x limit: 0x%08x [%c%c]\n", + i, base << 12, (limit << 12) | 0xfff, + value & PR_WPE ? 'W' : '.', + value & PR_RPE ? 'R' : '.'); + } + + dev_dbg(ispi->dev, "Flash regions:\n"); + for (i = 0; i < ispi->nregions; i++) { + u32 region, base, limit; + + region = readl(ispi->base + FREG(i)); + base = region & FREG_BASE_MASK; + limit = (region & FREG_LIMIT_MASK) >> FREG_LIMIT_SHIFT; + + if (base >= limit || (i > 0 && limit == 0)) + dev_dbg(ispi->dev, " %02d disabled\n", i); + else + dev_dbg(ispi->dev, " %02d base: 0x%08x limit: 0x%08x\n", + i, base << 12, (limit << 12) | 0xfff); + } + + dev_dbg(ispi->dev, "Using %cW sequencer for register access\n", + ispi->swseq_reg ? 'S' : 'H'); + dev_dbg(ispi->dev, "Using %cW sequencer for erase operation\n", + ispi->swseq_erase ? 'S' : 'H'); +} + +/* Reads max INTEL_SPI_FIFO_SZ bytes from the device fifo */ +static int intel_spi_read_block(struct intel_spi *ispi, void *buf, size_t size) +{ + size_t bytes; + int i = 0; + + if (size > INTEL_SPI_FIFO_SZ) + return -EINVAL; + + while (size > 0) { + bytes = min_t(size_t, size, 4); + memcpy_fromio(buf, ispi->base + FDATA(i), bytes); + size -= bytes; + buf += bytes; + i++; + } + + return 0; +} + +/* Writes max INTEL_SPI_FIFO_SZ bytes to the device fifo */ +static int intel_spi_write_block(struct intel_spi *ispi, const void *buf, + size_t size) +{ + size_t bytes; + int i = 0; + + if (size > INTEL_SPI_FIFO_SZ) + return -EINVAL; + + while (size > 0) { + bytes = min_t(size_t, size, 4); + memcpy_toio(ispi->base + FDATA(i), buf, bytes); + size -= bytes; + buf += bytes; + i++; + } + + return 0; +} + +static int intel_spi_wait_hw_busy(struct intel_spi *ispi) +{ + u32 val; + + return readl_poll_timeout(ispi->base + HSFSTS_CTL, val, + !(val & HSFSTS_CTL_SCIP), 0, + INTEL_SPI_TIMEOUT * 1000); +} + +static int intel_spi_wait_sw_busy(struct intel_spi *ispi) +{ + u32 val; + + return readl_poll_timeout(ispi->sregs + SSFSTS_CTL, val, + !(val & SSFSTS_CTL_SCIP), 0, + INTEL_SPI_TIMEOUT * 1000); +} + +static int intel_spi_init(struct intel_spi *ispi) +{ + u32 opmenu0, opmenu1, lvscc, uvscc, val; + int i; + + switch (ispi->info->type) { + case INTEL_SPI_BYT: + ispi->sregs = ispi->base + BYT_SSFSTS_CTL; + ispi->pregs = ispi->base + BYT_PR; + ispi->nregions = BYT_FREG_NUM; + ispi->pr_num = BYT_PR_NUM; + ispi->swseq_reg = true; + + if (writeable) { + /* Disable write protection */ + val = readl(ispi->base + BYT_BCR); + if (!(val & BYT_BCR_WPD)) { + val |= BYT_BCR_WPD; + writel(val, ispi->base + BYT_BCR); + val = readl(ispi->base + BYT_BCR); + } + + ispi->writeable = !!(val & BYT_BCR_WPD); + } + + break; + + case INTEL_SPI_LPT: + ispi->sregs = ispi->base + LPT_SSFSTS_CTL; + ispi->pregs = ispi->base + LPT_PR; + ispi->nregions = LPT_FREG_NUM; + ispi->pr_num = LPT_PR_NUM; + ispi->swseq_reg = true; + break; + + case INTEL_SPI_BXT: + ispi->sregs = ispi->base + BXT_SSFSTS_CTL; + ispi->pregs = ispi->base + BXT_PR; + ispi->nregions = BXT_FREG_NUM; + ispi->pr_num = BXT_PR_NUM; + ispi->erase_64k = true; + break; + + case INTEL_SPI_CNL: + ispi->sregs = NULL; + ispi->pregs = ispi->base + CNL_PR; + ispi->nregions = CNL_FREG_NUM; + ispi->pr_num = CNL_PR_NUM; + break; + + default: + return -EINVAL; + } + + /* Disable #SMI generation from HW sequencer */ + val = readl(ispi->base + HSFSTS_CTL); + val &= ~HSFSTS_CTL_FSMIE; + writel(val, ispi->base + HSFSTS_CTL); + + /* + * Determine whether erase operation should use HW or SW sequencer. + * + * The HW sequencer has a predefined list of opcodes, with only the + * erase opcode being programmable in LVSCC and UVSCC registers. + * If these registers don't contain a valid erase opcode, erase + * cannot be done using HW sequencer. + */ + lvscc = readl(ispi->base + LVSCC); + uvscc = readl(ispi->base + UVSCC); + if (!(lvscc & ERASE_OPCODE_MASK) || !(uvscc & ERASE_OPCODE_MASK)) + ispi->swseq_erase = true; + /* SPI controller on Intel BXT supports 64K erase opcode */ + if (ispi->info->type == INTEL_SPI_BXT && !ispi->swseq_erase) + if (!(lvscc & ERASE_64K_OPCODE_MASK) || + !(uvscc & ERASE_64K_OPCODE_MASK)) + ispi->erase_64k = false; + + if (ispi->sregs == NULL && (ispi->swseq_reg || ispi->swseq_erase)) { + dev_err(ispi->dev, "software sequencer not supported, but required\n"); + return -EINVAL; + } + + /* + * Some controllers can only do basic operations using hardware + * sequencer. All other operations are supposed to be carried out + * using software sequencer. + */ + if (ispi->swseq_reg) { + /* Disable #SMI generation from SW sequencer */ + val = readl(ispi->sregs + SSFSTS_CTL); + val &= ~SSFSTS_CTL_FSMIE; + writel(val, ispi->sregs + SSFSTS_CTL); + } + + /* Check controller's lock status */ + val = readl(ispi->base + HSFSTS_CTL); + ispi->locked = !!(val & HSFSTS_CTL_FLOCKDN); + + if (ispi->locked && ispi->sregs) { + /* + * BIOS programs allowed opcodes and then locks down the + * register. So read back what opcodes it decided to support. + * That's the set we are going to support as well. + */ + opmenu0 = readl(ispi->sregs + OPMENU0); + opmenu1 = readl(ispi->sregs + OPMENU1); + + if (opmenu0 && opmenu1) { + for (i = 0; i < ARRAY_SIZE(ispi->opcodes) / 2; i++) { + ispi->opcodes[i] = opmenu0 >> i * 8; + ispi->opcodes[i + 4] = opmenu1 >> i * 8; + } + } + } + + intel_spi_dump_regs(ispi); + + return 0; +} + +static int intel_spi_opcode_index(struct intel_spi *ispi, u8 opcode, int optype) +{ + int i; + int preop; + + if (ispi->locked) { + for (i = 0; i < ARRAY_SIZE(ispi->opcodes); i++) + if (ispi->opcodes[i] == opcode) + return i; + + return -EINVAL; + } + + /* The lock is off, so just use index 0 */ + writel(opcode, ispi->sregs + OPMENU0); + preop = readw(ispi->sregs + PREOP_OPTYPE); + writel(optype << 16 | preop, ispi->sregs + PREOP_OPTYPE); + + return 0; +} + +static int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len) +{ + u32 val, status; + int ret; + + val = readl(ispi->base + HSFSTS_CTL); + val &= ~(HSFSTS_CTL_FCYCLE_MASK | HSFSTS_CTL_FDBC_MASK); + + switch (opcode) { + case SPINOR_OP_RDID: + val |= HSFSTS_CTL_FCYCLE_RDID; + break; + case SPINOR_OP_WRSR: + val |= HSFSTS_CTL_FCYCLE_WRSR; + break; + case SPINOR_OP_RDSR: + val |= HSFSTS_CTL_FCYCLE_RDSR; + break; + default: + return -EINVAL; + } + + if (len > INTEL_SPI_FIFO_SZ) + return -EINVAL; + + val |= (len - 1) << HSFSTS_CTL_FDBC_SHIFT; + val |= HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; + val |= HSFSTS_CTL_FGO; + writel(val, ispi->base + HSFSTS_CTL); + + ret = intel_spi_wait_hw_busy(ispi); + if (ret) + return ret; + + status = readl(ispi->base + HSFSTS_CTL); + if (status & HSFSTS_CTL_FCERR) + return -EIO; + else if (status & HSFSTS_CTL_AEL) + return -EACCES; + + return 0; +} + +static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len, + int optype) +{ + u32 val = 0, status; + u8 atomic_preopcode; + int ret; + + ret = intel_spi_opcode_index(ispi, opcode, optype); + if (ret < 0) + return ret; + + if (len > INTEL_SPI_FIFO_SZ) + return -EINVAL; + + /* + * Always clear it after each SW sequencer operation regardless + * of whether it is successful or not. + */ + atomic_preopcode = ispi->atomic_preopcode; + ispi->atomic_preopcode = 0; + + /* Only mark 'Data Cycle' bit when there is data to be transferred */ + if (len > 0) + val = ((len - 1) << SSFSTS_CTL_DBC_SHIFT) | SSFSTS_CTL_DS; + val |= ret << SSFSTS_CTL_COP_SHIFT; + val |= SSFSTS_CTL_FCERR | SSFSTS_CTL_FDONE; + val |= SSFSTS_CTL_SCGO; + if (atomic_preopcode) { + u16 preop; + + switch (optype) { + case OPTYPE_WRITE_NO_ADDR: + case OPTYPE_WRITE_WITH_ADDR: + /* Pick matching preopcode for the atomic sequence */ + preop = readw(ispi->sregs + PREOP_OPTYPE); + if ((preop & 0xff) == atomic_preopcode) + ; /* Do nothing */ + else if ((preop >> 8) == atomic_preopcode) + val |= SSFSTS_CTL_SPOP; + else + return -EINVAL; + + /* Enable atomic sequence */ + val |= SSFSTS_CTL_ACS; + break; + + default: + return -EINVAL; + } + + } + writel(val, ispi->sregs + SSFSTS_CTL); + + ret = intel_spi_wait_sw_busy(ispi); + if (ret) + return ret; + + status = readl(ispi->sregs + SSFSTS_CTL); + if (status & SSFSTS_CTL_FCERR) + return -EIO; + else if (status & SSFSTS_CTL_AEL) + return -EACCES; + + return 0; +} + +static int intel_spi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, + size_t len) +{ + struct intel_spi *ispi = nor->priv; + int ret; + + /* Address of the first chip */ + writel(0, ispi->base + FADDR); + + if (ispi->swseq_reg) + ret = intel_spi_sw_cycle(ispi, opcode, len, + OPTYPE_READ_NO_ADDR); + else + ret = intel_spi_hw_cycle(ispi, opcode, len); + + if (ret) + return ret; + + return intel_spi_read_block(ispi, buf, len); +} + +static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, + size_t len) +{ + struct intel_spi *ispi = nor->priv; + int ret; + + /* + * This is handled with atomic operation and preop code in Intel + * controller so we only verify that it is available. If the + * controller is not locked, program the opcode to the PREOP + * register for later use. + * + * When hardware sequencer is used there is no need to program + * any opcodes (it handles them automatically as part of a command). + */ + if (opcode == SPINOR_OP_WREN) { + u16 preop; + + if (!ispi->swseq_reg) + return 0; + + preop = readw(ispi->sregs + PREOP_OPTYPE); + if ((preop & 0xff) != opcode && (preop >> 8) != opcode) { + if (ispi->locked) + return -EINVAL; + writel(opcode, ispi->sregs + PREOP_OPTYPE); + } + + /* + * This enables atomic sequence on next SW sycle. Will + * be cleared after next operation. + */ + ispi->atomic_preopcode = opcode; + return 0; + } + + /* + * We hope that HW sequencer will do the right thing automatically and + * with the SW sequencer we cannot use preopcode anyway, so just ignore + * the Write Disable operation and pretend it was completed + * successfully. + */ + if (opcode == SPINOR_OP_WRDI) + return 0; + + writel(0, ispi->base + FADDR); + + /* Write the value beforehand */ + ret = intel_spi_write_block(ispi, buf, len); + if (ret) + return ret; + + if (ispi->swseq_reg) + return intel_spi_sw_cycle(ispi, opcode, len, + OPTYPE_WRITE_NO_ADDR); + return intel_spi_hw_cycle(ispi, opcode, len); +} + +static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len, + u_char *read_buf) +{ + struct intel_spi *ispi = nor->priv; + size_t block_size, retlen = 0; + u32 val, status; + ssize_t ret; + + /* + * Atomic sequence is not expected with HW sequencer reads. Make + * sure it is cleared regardless. + */ + if (WARN_ON_ONCE(ispi->atomic_preopcode)) + ispi->atomic_preopcode = 0; + + switch (nor->read_opcode) { + case SPINOR_OP_READ: + case SPINOR_OP_READ_FAST: + case SPINOR_OP_READ_4B: + case SPINOR_OP_READ_FAST_4B: + break; + default: + return -EINVAL; + } + + while (len > 0) { + block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); + + /* Read cannot cross 4K boundary */ + block_size = min_t(loff_t, from + block_size, + round_up(from + 1, SZ_4K)) - from; + + writel(from, ispi->base + FADDR); + + val = readl(ispi->base + HSFSTS_CTL); + val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK); + val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; + val |= (block_size - 1) << HSFSTS_CTL_FDBC_SHIFT; + val |= HSFSTS_CTL_FCYCLE_READ; + val |= HSFSTS_CTL_FGO; + writel(val, ispi->base + HSFSTS_CTL); + + ret = intel_spi_wait_hw_busy(ispi); + if (ret) + return ret; + + status = readl(ispi->base + HSFSTS_CTL); + if (status & HSFSTS_CTL_FCERR) + ret = -EIO; + else if (status & HSFSTS_CTL_AEL) + ret = -EACCES; + + if (ret < 0) { + dev_err(ispi->dev, "read error: %llx: %#x\n", from, + status); + return ret; + } + + ret = intel_spi_read_block(ispi, read_buf, block_size); + if (ret) + return ret; + + len -= block_size; + from += block_size; + retlen += block_size; + read_buf += block_size; + } + + return retlen; +} + +static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len, + const u_char *write_buf) +{ + struct intel_spi *ispi = nor->priv; + size_t block_size, retlen = 0; + u32 val, status; + ssize_t ret; + + /* Not needed with HW sequencer write, make sure it is cleared */ + ispi->atomic_preopcode = 0; + + while (len > 0) { + block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); + + /* Write cannot cross 4K boundary */ + block_size = min_t(loff_t, to + block_size, + round_up(to + 1, SZ_4K)) - to; + + writel(to, ispi->base + FADDR); + + val = readl(ispi->base + HSFSTS_CTL); + val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK); + val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; + val |= (block_size - 1) << HSFSTS_CTL_FDBC_SHIFT; + val |= HSFSTS_CTL_FCYCLE_WRITE; + + ret = intel_spi_write_block(ispi, write_buf, block_size); + if (ret) { + dev_err(ispi->dev, "failed to write block\n"); + return ret; + } + + /* Start the write now */ + val |= HSFSTS_CTL_FGO; + writel(val, ispi->base + HSFSTS_CTL); + + ret = intel_spi_wait_hw_busy(ispi); + if (ret) { + dev_err(ispi->dev, "timeout\n"); + return ret; + } + + status = readl(ispi->base + HSFSTS_CTL); + if (status & HSFSTS_CTL_FCERR) + ret = -EIO; + else if (status & HSFSTS_CTL_AEL) + ret = -EACCES; + + if (ret < 0) { + dev_err(ispi->dev, "write error: %llx: %#x\n", to, + status); + return ret; + } + + len -= block_size; + to += block_size; + retlen += block_size; + write_buf += block_size; + } + + return retlen; +} + +static int intel_spi_erase(struct spi_nor *nor, loff_t offs) +{ + size_t erase_size, len = nor->mtd.erasesize; + struct intel_spi *ispi = nor->priv; + u32 val, status, cmd; + int ret; + + /* If the hardware can do 64k erase use that when possible */ + if (len >= SZ_64K && ispi->erase_64k) { + cmd = HSFSTS_CTL_FCYCLE_ERASE_64K; + erase_size = SZ_64K; + } else { + cmd = HSFSTS_CTL_FCYCLE_ERASE; + erase_size = SZ_4K; + } + + if (ispi->swseq_erase) { + while (len > 0) { + writel(offs, ispi->base + FADDR); + + ret = intel_spi_sw_cycle(ispi, nor->erase_opcode, + 0, OPTYPE_WRITE_WITH_ADDR); + if (ret) + return ret; + + offs += erase_size; + len -= erase_size; + } + + return 0; + } + + /* Not needed with HW sequencer erase, make sure it is cleared */ + ispi->atomic_preopcode = 0; + + while (len > 0) { + writel(offs, ispi->base + FADDR); + + val = readl(ispi->base + HSFSTS_CTL); + val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK); + val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; + val |= cmd; + val |= HSFSTS_CTL_FGO; + writel(val, ispi->base + HSFSTS_CTL); + + ret = intel_spi_wait_hw_busy(ispi); + if (ret) + return ret; + + status = readl(ispi->base + HSFSTS_CTL); + if (status & HSFSTS_CTL_FCERR) + return -EIO; + else if (status & HSFSTS_CTL_AEL) + return -EACCES; + + offs += erase_size; + len -= erase_size; + } + + return 0; +} + +static bool intel_spi_is_protected(const struct intel_spi *ispi, + unsigned int base, unsigned int limit) +{ + int i; + + for (i = 0; i < ispi->pr_num; i++) { + u32 pr_base, pr_limit, pr_value; + + pr_value = readl(ispi->pregs + PR(i)); + if (!(pr_value & (PR_WPE | PR_RPE))) + continue; + + pr_limit = (pr_value & PR_LIMIT_MASK) >> PR_LIMIT_SHIFT; + pr_base = pr_value & PR_BASE_MASK; + + if (pr_base >= base && pr_limit <= limit) + return true; + } + + return false; +} + +/* + * There will be a single partition holding all enabled flash regions. We + * call this "BIOS". + */ +static void intel_spi_fill_partition(struct intel_spi *ispi, + struct mtd_partition *part) +{ + u64 end; + int i; + + mem_clear(part, sizeof(*part)); + + /* Start from the mandatory descriptor region */ + part->size = 4096; + part->name = "BIOS"; + + /* + * Now try to find where this partition ends based on the flash + * region registers. + */ + for (i = 1; i < ispi->nregions; i++) { + u32 region, base, limit; + + region = readl(ispi->base + FREG(i)); + base = region & FREG_BASE_MASK; + limit = (region & FREG_LIMIT_MASK) >> FREG_LIMIT_SHIFT; + + if (base >= limit || limit == 0) + continue; + + /* + * If any of the regions have protection bits set, make the + * whole partition read-only to be on the safe side. + */ + if (intel_spi_is_protected(ispi, base, limit)) + ispi->writeable = false; + + end = (limit << 12) + 4096; + if (end > part->size) + part->size = end; + } +} + +static const struct spi_nor_controller_ops intel_spi_controller_ops = { + .read_reg = intel_spi_read_reg, + .write_reg = intel_spi_write_reg, + .read = intel_spi_read, + .write = intel_spi_write, + .erase = intel_spi_erase, +}; + +struct intel_spi *intel_spi_probe(struct device *dev, + struct resource *mem, const struct intel_spi_boardinfo *info) +{ + const struct spi_nor_hwcaps hwcaps = { + .mask = SNOR_HWCAPS_READ | + SNOR_HWCAPS_READ_FAST | + SNOR_HWCAPS_PP, + }; + struct mtd_partition part; + struct intel_spi *ispi; + int ret; + + if (!info || !mem) + return ERR_PTR(-EINVAL); + + ispi = devm_kzalloc(dev, sizeof(*ispi), GFP_KERNEL); + if (!ispi) + return ERR_PTR(-ENOMEM); + + ispi->base = devm_ioremap_resource(dev, mem); + if (IS_ERR(ispi->base)) + return ERR_CAST(ispi->base); + + ispi->dev = dev; + ispi->info = info; + ispi->writeable = info->writeable; + + ret = intel_spi_init(ispi); + if (ret) + return ERR_PTR(ret); + + ispi->nor.dev = ispi->dev; + ispi->nor.priv = ispi; + ispi->nor.controller_ops = &intel_spi_controller_ops; + + ret = spi_nor_scan(&ispi->nor, NULL, &hwcaps); + if (ret) { + dev_info(dev, "failed to locate the chip\n"); + return ERR_PTR(ret); + } + + intel_spi_fill_partition(ispi, &part); + + /* Prevent writes if not explicitly enabled */ + if (!ispi->writeable || !writeable) + ispi->nor.mtd.flags &= ~MTD_WRITEABLE; + + ret = mtd_device_register(&ispi->nor.mtd, &part, 1); + if (ret) + return ERR_PTR(ret); + + return ispi; +} +EXPORT_SYMBOL_GPL(intel_spi_probe); + +int intel_spi_remove(struct intel_spi *ispi) +{ + return mtd_device_unregister(&ispi->nor.mtd); +} +EXPORT_SYMBOL_GPL(intel_spi_remove); + +MODULE_DESCRIPTION("Intel PCH/PCU SPI flash core driver"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi_platform.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi_platform.c new file mode 100644 index 000000000000..b9f294860ce4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi_platform.c @@ -0,0 +1,167 @@ +/* + * Intel PCH/PCU SPI flash platform driver. + * + * Copyright (C) 2016, Intel Corporation + * Author: Mika Westerberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include "intel_spi.h" + +#define PCI_VENDOR_ID_D1527_LPC (0x8c54) + +#define BIOS_CNTL (0xdc) +#define BIOS_CNTL_SRC_SHIFT 2 +#define BIOS_CNTL_WN BIT(0) +#define BIOS_CNTL_BLE BIT(1) +#define BIOS_CNTL_SMM_BMP BIT(5) + +#define RCBABASE 0xf0 + +int intel_spi_platform_debug = 0; +module_param(intel_spi_platform_debug, int, S_IRUGO | S_IWUSR); +int intel_spi_platform_error = 0; +module_param(intel_spi_platform_error, int, S_IRUGO | S_IWUSR); + +static bool writeable; +module_param(writeable, bool, 0); +MODULE_PARM_DESC(writeable, "Enable write access to BIOS (default=0)"); + +#define INTEL_SPI_PLATFORM_VERBOSE(fmt, args...) do { \ + if (intel_spi_platform_debug) { \ + printk(KERN_INFO "[INTEL_SPI_PLATFORM][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ + } while (0) + +#define INTEL_SPI_PLATFORM_ERROR(fmt, args...) do { \ + if (intel_spi_platform_error) { \ + printk(KERN_ERR "[INTEL_SPI_PLATFORM][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ + } while (0) + +static void intel_spi_enable_bios_write(struct pci_dev *pci_dev, struct intel_spi_boardinfo *info) +{ + u8 bios_cntl, value, want, new; + + if (writeable) { + pci_read_config_byte(pci_dev, BIOS_CNTL, &bios_cntl); + want = bios_cntl; + value = (bios_cntl >> BIOS_CNTL_SRC_SHIFT) & 0x3 ; + if (value == 0x3) { + INTEL_SPI_PLATFORM_VERBOSE("invalid prefetching/caching settings, "); + } else { + INTEL_SPI_PLATFORM_VERBOSE("prefetching %sabled, caching %sabled, ", + (value & 0x2) ? "en" : "dis", + (value & 0x1) ? "dis" : "en"); + } + + /* writeable regardless */ + want &= ~BIOS_CNTL_SMM_BMP; + /* write enable */ + want |= BIOS_CNTL_WN; + /* BIOS lock disabled */ + want &= ~BIOS_CNTL_BLE; + INTEL_SPI_PLATFORM_VERBOSE("bios cntl is:0x%x, want is:0x%x\n", bios_cntl, want); + pci_write_config_byte(pci_dev, BIOS_CNTL, want); + pci_read_config_byte(pci_dev, BIOS_CNTL, &new); + INTEL_SPI_PLATFORM_VERBOSE("\nBIOS_CNTL = 0x%02x: ", new); + INTEL_SPI_PLATFORM_VERBOSE("BIOS Lock Enable: %sabled, ", (new & BIOS_CNTL_BLE) ? "en" : "dis"); + INTEL_SPI_PLATFORM_VERBOSE("BIOS Write Enable: %sabled\n", (new & BIOS_CNTL_WN) ? "en" : "dis"); + + if (new & BIOS_CNTL_SMM_BMP) { + INTEL_SPI_PLATFORM_VERBOSE("BIOS region SMM protection is enabled!\n"); + } + + if (new != want) { + INTEL_SPI_PLATFORM_VERBOSE("Warning: Setting Bios Control at 0x%x from 0x%02x to 0x%02x failed.\n" + "New value is 0x%02x.\n", BIOS_CNTL, value, want, new); + } else { + info->writeable = !!(new & BIOS_CNTL_WN); + } + INTEL_SPI_PLATFORM_VERBOSE("Bios Control is 0x%x\n", new); + } else { + INTEL_SPI_PLATFORM_VERBOSE("Bios don't write\n"); + } + + return ; +} + +static int intel_spi_platform_probe(struct platform_device *pdev) +{ + struct intel_spi_boardinfo *info; + struct intel_spi *ispi; + struct resource *mem; + struct pci_dev *pci_dev = NULL; + u32 rcba; + + info = dev_get_platdata(&pdev->dev); + if (!info) + return -EINVAL; + + pci_dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC, pci_dev); + if (!pci_dev) { + INTEL_SPI_PLATFORM_ERROR("pci_get_device(0x8086, 0x8c54) failed!\n"); + return -1; + } + + switch (info->type) { + case INTEL_SPI_LPT: + pci_read_config_dword(pci_dev, RCBABASE, &rcba); + if (rcba & 1) { + intel_spi_enable_bios_write(pci_dev, info); + } + break; + default: + INTEL_SPI_PLATFORM_ERROR("info type[%d] not need set writeable.\n",info->type); + break; + } + INTEL_SPI_PLATFORM_VERBOSE("intel spi boardinfo writeable is %sabled\n", + info->writeable ? "en" : "dis"); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ispi = intel_spi_probe(&pdev->dev, mem, info); + if (IS_ERR(ispi)) + return PTR_ERR(ispi); + + platform_set_drvdata(pdev, ispi); + return 0; +} + +static int intel_spi_platform_remove(struct platform_device *pdev) +{ + struct intel_spi *ispi = platform_get_drvdata(pdev); + + return intel_spi_remove(ispi); +} + +static struct of_device_id intel_spi_match[] = { + { + .compatible = "spi-c224", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, intel_spi_match); + +static struct platform_driver intel_spi_platform_driver = { + .probe = intel_spi_platform_probe, + .remove = intel_spi_platform_remove, + .driver = { + .name = "intel-spi", + .of_match_table = intel_spi_match, + }, +}; + +module_platform_driver(intel_spi_platform_driver); + +MODULE_DESCRIPTION("Intel PCH/PCU SPI flash platform driver"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:intel-spi"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/Makefile new file mode 100644 index 000000000000..4226f2734275 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/Makefile @@ -0,0 +1,34 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +#ifdef ENABLE_GCOV +#ifeq ($(ENABLE_GCOV), y) +#EXTRA_CFLAGS+= -fprofile-arcs -ftest-coverage -lgcov +#endif +#endif # ENABLE_GCOV + +obj-m := wb_lm75.o +obj-m += wb_tmp401.o +obj-m += wb_i2c_mux_pca9641.o +obj-m += wb_i2c_mux_pca954x.o +obj-m += wb_i2c_i801.o +obj-m += wb_i2c_algo_bit.o +obj-m += wb_i2c_gpio.o +obj-m += wb_i2c_gpio_device.o +obj-m += wb_at24.o +obj-m += wb_pmbus_core.o +obj-m += wb_csu550.o +obj-m += wb_ina3221.o +obj-m += wb_isl68137.o +obj-m += wb_tps53622.o +obj-m += wb_ucd9000.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/*.mod + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_at24.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_at24.c new file mode 100644 index 000000000000..1075e6ef18de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_at24.c @@ -0,0 +1,861 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Address pointer is 16 bit. */ +#define AT24_FLAG_ADDR16 BIT(7) +/* sysfs-entry will be read-only. */ +#define AT24_FLAG_READONLY BIT(6) +/* sysfs-entry will be world-readable. */ +#define AT24_FLAG_IRUGO BIT(5) +/* Take always 8 addresses (24c00). */ +#define AT24_FLAG_TAKE8ADDR BIT(4) +/* Factory-programmed serial number. */ +#define AT24_FLAG_SERIAL BIT(3) +/* Factory-programmed mac address. */ +#define AT24_FLAG_MAC BIT(2) +/* Does not auto-rollover reads to the next slave address. */ +#define AT24_FLAG_NO_RDROL BIT(1) + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_client { + struct i2c_client *client; + struct regmap *regmap; +}; + +struct at24_data { + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + + unsigned int write_max; + unsigned int num_addresses; + unsigned int offset_adj; + + u32 byte_len; + u16 page_size; + u8 flags; + + struct nvmem_device *nvmem; + struct regulator *vcc_reg; + void (*read_post)(unsigned int off, char *buf, size_t count); + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct at24_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 at24_io_limit = 128; +module_param_named(io_limit, at24_io_limit, uint, 0); +MODULE_PARM_DESC(at24_io_limit, "Maximum bytes per I/O (default 128)"); + +/* + * Specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned int at24_write_timeout = 25; +module_param_named(write_timeout, at24_write_timeout, uint, 0); +MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)"); + +struct at24_chip_data { + u32 byte_len; + u8 flags; + void (*read_post)(unsigned int off, char *buf, size_t count); +}; + +#define AT24_CHIP_DATA(_name, _len, _flags) \ + static const struct at24_chip_data _name = { \ + .byte_len = _len, .flags = _flags, \ + } + +#define AT24_CHIP_DATA_CB(_name, _len, _flags, _read_post) \ + static const struct at24_chip_data _name = { \ + .byte_len = _len, .flags = _flags, \ + .read_post = _read_post, \ + } + +static void at24_read_post_vaio(unsigned int off, char *buf, size_t count) +{ + int i; + + if (capable(CAP_SYS_ADMIN)) + return; + + /* + * Hide VAIO private settings to regular users: + * - BIOS passwords: bytes 0x00 to 0x0f + * - UUID: bytes 0x10 to 0x1f + * - Serial number: 0xc0 to 0xdf + */ + for (i = 0; i < count; i++) { + if ((off + i <= 0x1f) || + (off + i >= 0xc0 && off + i <= 0xdf)) + buf[i] = 0; + } +} + +/* needs 8 addresses as A0-A2 are ignored */ +AT24_CHIP_DATA(at24_data_24c00, 128 / 8, AT24_FLAG_TAKE8ADDR); +/* old variants can't be handled with this generic entry! */ +AT24_CHIP_DATA(at24_data_24c01, 1024 / 8, 0); +AT24_CHIP_DATA(at24_data_24cs01, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c02, 2048 / 8, AT24_FLAG_IRUGO); +AT24_CHIP_DATA(at24_data_24cs02, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24mac402, 48 / 8, + AT24_FLAG_MAC | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24mac602, 64 / 8, + AT24_FLAG_MAC | AT24_FLAG_READONLY); +/* spd is a 24c02 in memory DIMMs */ +AT24_CHIP_DATA(at24_data_spd, 2048 / 8, + AT24_FLAG_READONLY | AT24_FLAG_IRUGO); +/* 24c02_vaio is a 24c02 on some Sony laptops */ +AT24_CHIP_DATA_CB(at24_data_24c02_vaio, 2048 / 8, + AT24_FLAG_READONLY | AT24_FLAG_IRUGO, + at24_read_post_vaio); +AT24_CHIP_DATA(at24_data_24c04, 4096 / 8, 0); +AT24_CHIP_DATA(at24_data_24cs04, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +/* 24rf08 quirk is handled at i2c-core */ +AT24_CHIP_DATA(at24_data_24c08, 8192 / 8, 0); +AT24_CHIP_DATA(at24_data_24cs08, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c16, 16384 / 8, 0); +AT24_CHIP_DATA(at24_data_24cs16, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c32, 32768 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24cs32, 16, + AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c64, 65536 / 8, AT24_FLAG_ADDR16 | AT24_FLAG_IRUGO); +AT24_CHIP_DATA(at24_data_24cs64, 16, + AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c128, 131072 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24c256, 262144 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24c512, 524288 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24c1024, 1048576 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24c2048, 2097152 / 8, AT24_FLAG_ADDR16); +/* identical to 24c08 ? */ +AT24_CHIP_DATA(at24_data_INT3499, 8192 / 8, 0); + +static const struct i2c_device_id at24_ids[] = { + { "wb_24c00", (kernel_ulong_t)&at24_data_24c00 }, + { "wb_24c01", (kernel_ulong_t)&at24_data_24c01 }, + { "wb_24cs01", (kernel_ulong_t)&at24_data_24cs01 }, + { "wb_24c02", (kernel_ulong_t)&at24_data_24c02 }, + { "wb_24cs02", (kernel_ulong_t)&at24_data_24cs02 }, + { "wb_24mac402", (kernel_ulong_t)&at24_data_24mac402 }, + { "wb_24mac602", (kernel_ulong_t)&at24_data_24mac602 }, + { "wb_spd", (kernel_ulong_t)&at24_data_spd }, + { "wb_24c02-vaio", (kernel_ulong_t)&at24_data_24c02_vaio }, + { "wb_24c04", (kernel_ulong_t)&at24_data_24c04 }, + { "wb_24cs04", (kernel_ulong_t)&at24_data_24cs04 }, + { "wb_24c08", (kernel_ulong_t)&at24_data_24c08 }, + { "wb_24cs08", (kernel_ulong_t)&at24_data_24cs08 }, + { "wb_24c16", (kernel_ulong_t)&at24_data_24c16 }, + { "wb_24cs16", (kernel_ulong_t)&at24_data_24cs16 }, + { "wb_24c32", (kernel_ulong_t)&at24_data_24c32 }, + { "wb_24cs32", (kernel_ulong_t)&at24_data_24cs32 }, + { "wb_24c64", (kernel_ulong_t)&at24_data_24c64 }, + { "wb_24cs64", (kernel_ulong_t)&at24_data_24cs64 }, + { "wb_24c128", (kernel_ulong_t)&at24_data_24c128 }, + { "wb_24c256", (kernel_ulong_t)&at24_data_24c256 }, + { "wb_24c512", (kernel_ulong_t)&at24_data_24c512 }, + { "wb_24c1024", (kernel_ulong_t)&at24_data_24c1024 }, + { "wb_24c2048", (kernel_ulong_t)&at24_data_24c2048 }, + { "wb_at24", 0 }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ids); + +static const struct of_device_id at24_of_match[] = { + { .compatible = "atmel,24c00", .data = &at24_data_24c00 }, + { .compatible = "atmel,24c01", .data = &at24_data_24c01 }, + { .compatible = "atmel,24cs01", .data = &at24_data_24cs01 }, + { .compatible = "atmel,24c02", .data = &at24_data_24c02 }, + { .compatible = "atmel,24cs02", .data = &at24_data_24cs02 }, + { .compatible = "atmel,24mac402", .data = &at24_data_24mac402 }, + { .compatible = "atmel,24mac602", .data = &at24_data_24mac602 }, + { .compatible = "atmel,spd", .data = &at24_data_spd }, + { .compatible = "atmel,24c04", .data = &at24_data_24c04 }, + { .compatible = "atmel,24cs04", .data = &at24_data_24cs04 }, + { .compatible = "atmel,24c08", .data = &at24_data_24c08 }, + { .compatible = "atmel,24cs08", .data = &at24_data_24cs08 }, + { .compatible = "atmel,24c16", .data = &at24_data_24c16 }, + { .compatible = "atmel,24cs16", .data = &at24_data_24cs16 }, + { .compatible = "atmel,24c32", .data = &at24_data_24c32 }, + { .compatible = "atmel,24cs32", .data = &at24_data_24cs32 }, + { .compatible = "atmel,24c64", .data = &at24_data_24c64 }, + { .compatible = "atmel,24cs64", .data = &at24_data_24cs64 }, + { .compatible = "atmel,24c128", .data = &at24_data_24c128 }, + { .compatible = "atmel,24c256", .data = &at24_data_24c256 }, + { .compatible = "atmel,24c512", .data = &at24_data_24c512 }, + { .compatible = "atmel,24c1024", .data = &at24_data_24c1024 }, + { .compatible = "atmel,24c2048", .data = &at24_data_24c2048 }, + { /* END OF LIST */ }, +}; +MODULE_DEVICE_TABLE(of, at24_of_match); + +static const struct acpi_device_id __maybe_unused at24_acpi_ids[] = { + { "INT3499", (kernel_ulong_t)&at24_data_INT3499 }, + { "TPF0001", (kernel_ulong_t)&at24_data_24c1024 }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(acpi, at24_acpi_ids); + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + * + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + */ +static struct at24_client *at24_translate_offset(struct at24_data *at24, + unsigned int *offset) +{ + unsigned int i; + + if (at24->flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return &at24->client[i]; +} + +static struct device *at24_base_client_dev(struct at24_data *at24) +{ + return &at24->client[0].client->dev; +} + +static size_t at24_adjust_read_count(struct at24_data *at24, + unsigned int offset, size_t count) +{ + unsigned int bits; + size_t remainder; + + /* + * In case of multi-address chips that don't rollover reads to + * the next slave address: truncate the count to the slave boundary, + * so that the read never straddles slaves. + */ + if (at24->flags & AT24_FLAG_NO_RDROL) { + bits = (at24->flags & AT24_FLAG_ADDR16) ? 16 : 8; + remainder = BIT(bits) - offset; + if (count > remainder) + count = remainder; + } + + if (count > at24_io_limit) + count = at24_io_limit; + + return count; +} + +static ssize_t at24_regmap_read(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct at24_client *at24_client; + struct i2c_client *client; + struct regmap *regmap; + int ret; + + at24_client = at24_translate_offset(at24, &offset); + regmap = at24_client->regmap; + client = at24_client->client; + count = at24_adjust_read_count(at24, offset, count); + + /* adjust offset for mac and serial read ops */ + offset += at24->offset_adj; + + timeout = jiffies + msecs_to_jiffies(at24_write_timeout); + do { + /* + * The timestamp shall be taken before the actual operation + * to avoid a premature timeout in case of high CPU load. + */ + read_time = jiffies; + + ret = regmap_bulk_read(regmap, offset, buf, count); + dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", + count, offset, ret, jiffies); + if (!ret) + return count; + + usleep_range(1000, 1500); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. These routines + * write at most one page. + */ + +static size_t at24_adjust_write_count(struct at24_data *at24, + unsigned int offset, size_t count) +{ + unsigned int next_page; + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->page_size); + if (offset + count > next_page) + count = next_page - offset; + + return count; +} + +static ssize_t at24_regmap_write(struct at24_data *at24, const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct at24_client *at24_client; + struct i2c_client *client; + struct regmap *regmap; + int ret; + + at24_client = at24_translate_offset(at24, &offset); + regmap = at24_client->regmap; + client = at24_client->client; + count = at24_adjust_write_count(at24, offset, count); + timeout = jiffies + msecs_to_jiffies(at24_write_timeout); + + do { + /* + * The timestamp shall be taken before the actual operation + * to avoid a premature timeout in case of high CPU load. + */ + write_time = jiffies; + + ret = regmap_bulk_write(regmap, offset, buf, count); + dev_dbg(&client->dev, "write %zu@%d --> %d (%ld)\n", + count, offset, ret, jiffies); + if (!ret) + return count; + + usleep_range(1000, 1500); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + +static int at24_read(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24; + struct device *dev; + char *buf = val; + int i, ret; + + at24 = priv; + dev = at24_base_client_dev(at24); + + if (unlikely(!count)) + return count; + + if (off + count > at24->byte_len) + return -EINVAL; + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + return ret; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + for (i = 0; count; i += ret, count -= ret) { + ret = at24_regmap_read(at24, buf + i, off + i, count); + if (ret < 0) { + mutex_unlock(&at24->lock); + pm_runtime_put(dev); + return ret; + } + } + + mutex_unlock(&at24->lock); + + pm_runtime_put(dev); + + if (unlikely(at24->read_post)) + at24->read_post(off, buf, i); + + return 0; +} + +static int at24_write(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24; + struct device *dev; + char *buf = val; + int ret; + + at24 = priv; + dev = at24_base_client_dev(at24); + + if (unlikely(!count)) + return -EINVAL; + + if (off + count > at24->byte_len) + return -EINVAL; + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + return ret; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + ret = at24_regmap_write(at24, buf, off, count); + if (ret < 0) { + mutex_unlock(&at24->lock); + pm_runtime_put(dev); + return ret; + } + buf += ret; + off += ret; + count -= ret; + } + + mutex_unlock(&at24->lock); + + pm_runtime_put(dev); + + return 0; +} + +static const struct at24_chip_data *at24_get_chip_data(struct device *dev) +{ + struct device_node *of_node = dev->of_node; + const struct at24_chip_data *cdata; + const struct i2c_device_id *id; + + id = i2c_match_id(at24_ids, to_i2c_client(dev)); + + /* + * The I2C core allows OF nodes compatibles to match against the + * I2C device ID table as a fallback, so check not only if an OF + * node is present but also if it matches an OF device ID entry. + */ + if (of_node && of_match_device(at24_of_match, dev)) + cdata = of_device_get_match_data(dev); + else if (id) + cdata = (void *)id->driver_data; + else + cdata = acpi_device_get_match_data(dev); + + if (!cdata) + return ERR_PTR(-ENODEV); + + return cdata; +} + +static int at24_make_dummy_client(struct at24_data *at24, unsigned int index, + struct regmap_config *regmap_config) +{ + struct i2c_client *base_client, *dummy_client; + struct regmap *regmap; + struct device *dev; + + base_client = at24->client[0].client; + dev = &base_client->dev; + + dummy_client = devm_i2c_new_dummy_device(dev, base_client->adapter, + base_client->addr + index); + if (IS_ERR(dummy_client)) + return PTR_ERR(dummy_client); + + regmap = devm_regmap_init_i2c(dummy_client, regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + at24->client[index].client = dummy_client; + at24->client[index].regmap = regmap; + + return 0; +} + +static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len) +{ + if (flags & AT24_FLAG_MAC) { + /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */ + return 0xa0 - byte_len; + } else if (flags & AT24_FLAG_SERIAL && flags & AT24_FLAG_ADDR16) { + /* + * For 16 bit address pointers, the word address must contain + * a '10' sequence in bits 11 and 10 regardless of the + * intended position of the address pointer. + */ + return 0x0800; + } else if (flags & AT24_FLAG_SERIAL) { + /* + * Otherwise the word address must begin with a '10' sequence, + * regardless of the intended address. + */ + return 0x0080; + } else { + return 0; + } +} + +static int at24_probe(struct i2c_client *client) +{ + struct regmap_config regmap_config = { }; + struct nvmem_config nvmem_config = { }; + u32 byte_len, page_size, flags, addrw; + const struct at24_chip_data *cdata; + struct device *dev = &client->dev; + bool i2c_fn_i2c, i2c_fn_block; + unsigned int i, num_addresses; + struct at24_data *at24; + struct regmap *regmap; + bool writable; + u8 test_byte; + int err; + + i2c_fn_i2c = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); + i2c_fn_block = i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK); + + cdata = at24_get_chip_data(dev); + if (IS_ERR(cdata)) + return PTR_ERR(cdata); + + err = device_property_read_u32(dev, "pagesize", &page_size); + if (err) + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via device tree + * or properties is recommended anyhow. + */ + page_size = 1; + + flags = cdata->flags; + if (device_property_present(dev, "read-only")) + flags |= AT24_FLAG_READONLY; + if (device_property_present(dev, "no-read-rollover")) + flags |= AT24_FLAG_NO_RDROL; + + err = device_property_read_u32(dev, "address-width", &addrw); + if (!err) { + switch (addrw) { + case 8: + if (flags & AT24_FLAG_ADDR16) + dev_warn(dev, + "Override address width to be 8, while default is 16\n"); + flags &= ~AT24_FLAG_ADDR16; + break; + case 16: + flags |= AT24_FLAG_ADDR16; + break; + default: + dev_warn(dev, "Bad \"address-width\" property: %u\n", + addrw); + } + } + + err = device_property_read_u32(dev, "size", &byte_len); + if (err) + byte_len = cdata->byte_len; + + if (!i2c_fn_i2c && !i2c_fn_block) + page_size = 1; + + if (!page_size) { + dev_err(dev, "page_size must not be 0!\n"); + return -EINVAL; + } + + if (!is_power_of_2(page_size)) + dev_warn(dev, "page_size looks suspicious (no power of 2)!\n"); + + err = device_property_read_u32(dev, "num-addresses", &num_addresses); + if (err) { + if (flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(byte_len, + (flags & AT24_FLAG_ADDR16) ? 65536 : 256); + } + + if ((flags & AT24_FLAG_SERIAL) && (flags & AT24_FLAG_MAC)) { + dev_err(dev, + "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC."); + return -EINVAL; + } + + regmap_config.val_bits = 8; + regmap_config.reg_bits = (flags & AT24_FLAG_ADDR16) ? 16 : 8; + regmap_config.disable_locking = true; + + regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + at24 = devm_kzalloc(dev, struct_size(at24, client, num_addresses), + GFP_KERNEL); + if (!at24) + return -ENOMEM; + + mutex_init(&at24->lock); + at24->byte_len = byte_len; + at24->page_size = page_size; + at24->flags = flags; + at24->read_post = cdata->read_post; + at24->num_addresses = num_addresses; + at24->offset_adj = at24_get_offset_adj(flags, byte_len); + at24->client[0].client = client; + at24->client[0].regmap = regmap; + + at24->vcc_reg = devm_regulator_get(dev, "vcc"); + if (IS_ERR(at24->vcc_reg)) + return PTR_ERR(at24->vcc_reg); + + writable = !(flags & AT24_FLAG_READONLY); + if (writable) { + at24->write_max = min_t(unsigned int, + page_size, at24_io_limit); + if (!i2c_fn_i2c && at24->write_max > I2C_SMBUS_BLOCK_MAX) + at24->write_max = I2C_SMBUS_BLOCK_MAX; + } + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + err = at24_make_dummy_client(at24, i, ®map_config); + if (err) + return err; + } + + /* + * If the 'label' property is not present for the AT24 EEPROM, + * then nvmem_config.id is initialised to NVMEM_DEVID_AUTO, + * and this will append the 'devid' to the name of the NVMEM + * device. This is purely legacy and the AT24 driver has always + * defaulted to this. However, if the 'label' property is + * present then this means that the name is specified by the + * firmware and this name should be used verbatim and so it is + * not necessary to append the 'devid'. + */ + if (device_property_present(dev, "label")) { + nvmem_config.id = NVMEM_DEVID_NONE; + err = device_property_read_string(dev, "label", + &nvmem_config.name); + if (err) + return err; + } else { + nvmem_config.id = NVMEM_DEVID_AUTO; + nvmem_config.name = dev_name(dev); + } + + nvmem_config.type = NVMEM_TYPE_EEPROM; + nvmem_config.dev = dev; + nvmem_config.read_only = !writable; + nvmem_config.root_only = !(flags & AT24_FLAG_IRUGO); + nvmem_config.owner = THIS_MODULE; + nvmem_config.compat = true; + nvmem_config.base_dev = dev; + nvmem_config.reg_read = at24_read; + nvmem_config.reg_write = at24_write; + nvmem_config.priv = at24; + nvmem_config.stride = 1; + nvmem_config.word_size = 1; + nvmem_config.size = byte_len; + + i2c_set_clientdata(client, at24); + + err = regulator_enable(at24->vcc_reg); + if (err) { + dev_err(dev, "Failed to enable vcc regulator\n"); + return err; + } + + /* enable runtime pm */ + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + at24->nvmem = devm_nvmem_register(dev, &nvmem_config); + if (IS_ERR(at24->nvmem)) { + pm_runtime_disable(dev); + if (!pm_runtime_status_suspended(dev)) + regulator_disable(at24->vcc_reg); + return PTR_ERR(at24->nvmem); + } + + /* + * Perform a one-byte test read to verify that the + * chip is functional. + */ + err = at24_read(at24, 0, &test_byte, 1); + if (err) { + pm_runtime_disable(dev); + if (!pm_runtime_status_suspended(dev)) + regulator_disable(at24->vcc_reg); + return -ENODEV; + } + + pm_runtime_idle(dev); + + if (writable) + dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n", + byte_len, client->name, at24->write_max); + else + dev_info(dev, "%u byte %s EEPROM, read-only\n", + byte_len, client->name); + + return 0; +} + +static int at24_remove(struct i2c_client *client) +{ + struct at24_data *at24 = i2c_get_clientdata(client); + + pm_runtime_disable(&client->dev); + if (!pm_runtime_status_suspended(&client->dev)) + regulator_disable(at24->vcc_reg); + pm_runtime_set_suspended(&client->dev); + + return 0; +} + +static int __maybe_unused at24_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct at24_data *at24 = i2c_get_clientdata(client); + + return regulator_disable(at24->vcc_reg); +} + +static int __maybe_unused at24_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct at24_data *at24 = i2c_get_clientdata(client); + + return regulator_enable(at24->vcc_reg); +} + +static const struct dev_pm_ops at24_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(at24_suspend, at24_resume, NULL) +}; + +static struct i2c_driver at24_driver = { + .driver = { + .name = "wb_at24", + .pm = &at24_pm_ops, + .of_match_table = at24_of_match, + .acpi_match_table = ACPI_PTR(at24_acpi_ids), + }, + .probe_new = at24_probe, + .remove = at24_remove, + .id_table = at24_ids, +}; + +static int __init at24_init(void) +{ + if (!at24_io_limit) { + pr_err("at24: at24_io_limit must not be 0!\n"); + return -EINVAL; + } + + at24_io_limit = rounddown_pow_of_two(at24_io_limit); + return i2c_add_driver(&at24_driver); +} +module_init(at24_init); + +static void __exit at24_exit(void) +{ + i2c_del_driver(&at24_driver); +} +module_exit(at24_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_csu550.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_csu550.c new file mode 100644 index 000000000000..574d344c7966 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_csu550.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Hardware monitoring driver for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_pmbus.h" + +struct pmbus_device_info { + int pages; + u32 flags; +}; + +static const struct i2c_device_id pmbus_id[]; + +/* + * Find sensor groups and status registers on each page. + */ +static void pmbus_find_sensor_groups(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int page; + + /* Sensors detected on page 0 only */ + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_VIN)) + info->func[0] |= PMBUS_HAVE_VIN; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_VCAP)) + info->func[0] |= PMBUS_HAVE_VCAP; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_IIN)) + info->func[0] |= PMBUS_HAVE_IIN; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_PIN)) + info->func[0] |= PMBUS_HAVE_PIN; + if (info->func[0] + && wb_pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT)) + info->func[0] |= PMBUS_HAVE_STATUS_INPUT; + if (wb_pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) && + wb_pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) { + info->func[0] |= PMBUS_HAVE_FAN12; + if (wb_pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN12; + } + if (wb_pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) && + wb_pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) { + info->func[0] |= PMBUS_HAVE_FAN34; + if (wb_pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN34; + } + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) + info->func[0] |= PMBUS_HAVE_TEMP; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2)) + info->func[0] |= PMBUS_HAVE_TEMP2; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3)) + info->func[0] |= PMBUS_HAVE_TEMP3; + if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_TEMP3) + && wb_pmbus_check_byte_register(client, 0, + PMBUS_STATUS_TEMPERATURE)) + info->func[0] |= PMBUS_HAVE_STATUS_TEMP; + + /* Sensors detected on all pages */ + for (page = 0; page < info->pages; page++) { + if (wb_pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) { + info->func[page] |= PMBUS_HAVE_VOUT; + if (wb_pmbus_check_byte_register(client, page, + PMBUS_STATUS_VOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_VOUT; + } + if (wb_pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) { + info->func[page] |= PMBUS_HAVE_IOUT; + if (wb_pmbus_check_byte_register(client, 0, + PMBUS_STATUS_IOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_IOUT; + } + if (wb_pmbus_check_word_register(client, page, PMBUS_READ_POUT)) + info->func[page] |= PMBUS_HAVE_POUT; + } +} + +/* + * Identify chip parameters. + */ +static int pmbus_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int ret = 0; + + if (!info->pages) { + /* + * Check if the PAGE command is supported. If it is, + * keep setting the page number until it fails or until the + * maximum number of pages has been reached. Assume that + * this is the number of pages supported by the chip. + */ + if (wb_pmbus_check_byte_register(client, 0, PMBUS_PAGE)) { + int page; + + for (page = 1; page < PMBUS_PAGES; page++) { + if (wb_pmbus_set_page(client, page, 0xff) < 0) + break; + } + wb_pmbus_set_page(client, 0, 0xff); + info->pages = page; + } else { + info->pages = 1; + } + + wb_pmbus_clear_faults(client); + } + + if (wb_pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) { + int vout_mode, i; + + vout_mode = wb_pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); + if (vout_mode >= 0 && vout_mode != 0xff) { + switch (vout_mode >> 5) { + case 0: + break; + case 1: + info->format[PSC_VOLTAGE_OUT] = vid; + for (i = 0; i < info->pages; i++) + info->vrm_version[i] = vr11; + break; + case 2: + info->format[PSC_VOLTAGE_OUT] = direct; + break; + default: + ret = -ENODEV; + goto abort; + } + } + } + + /* + * We should check if the COEFFICIENTS register is supported. + * If it is, and the chip is configured for direct mode, we can read + * the coefficients from the chip, one set per group of sensor + * registers. + * + * To do this, we will need access to a chip which actually supports the + * COEFFICIENTS command, since the command is too complex to implement + * without testing it. Until then, abort if a chip configured for direct + * mode was detected. + */ + if (info->format[PSC_VOLTAGE_OUT] == direct) { + ret = -ENODEV; + goto abort; + } + + /* Try to find sensor groups */ + pmbus_find_sensor_groups(client, info); +abort: + return ret; +} + +static int pmbus_probe(struct i2c_client *client) +{ + struct pmbus_driver_info *info; + struct pmbus_platform_data *pdata = NULL; + struct device *dev = &client->dev; + struct pmbus_device_info *device_info; + + info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + device_info = (struct pmbus_device_info *)i2c_match_id(pmbus_id, client)->driver_data; + if (device_info->flags & PMBUS_SKIP_STATUS_CHECK) { + pdata = devm_kzalloc(dev, sizeof(struct pmbus_platform_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdata->flags = PMBUS_SKIP_STATUS_CHECK; + } + + info->pages = device_info->pages; + info->identify = pmbus_identify; + dev->platform_data = pdata; + + return wb_pmbus_do_probe(client, info); +} + +static const struct pmbus_device_info pmbus_info_one = { + .pages = 1, + .flags = 0 +}; + +static const struct pmbus_device_info pmbus_info_zero = { + .pages = 0, + .flags = 0 +}; + +static const struct pmbus_device_info pmbus_info_one_skip = { + .pages = 1, + .flags = PMBUS_SKIP_STATUS_CHECK +}; + +static const struct pmbus_device_info pmbus_info_zero_skip = { + .pages = 0, + .flags = PMBUS_SKIP_STATUS_CHECK +}; +/* + * Use driver_data to set the number of pages supported by the chip. + */ +static const struct i2c_device_id pmbus_id[] = { + {"wb_csu550", (kernel_ulong_t)&pmbus_info_zero_skip}, + {"wb_csu800", (kernel_ulong_t)&pmbus_info_one_skip}, + {"wb_fsp1200", (kernel_ulong_t)&pmbus_info_one_skip}, + {"wb_dps550", (kernel_ulong_t)&pmbus_info_one_skip}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pmbus_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver pmbus_driver = { + .driver = { + .name = "wb_pmbus", + }, + .probe_new = pmbus_probe, + .remove = wb_pmbus_do_remove, + .id_table = pmbus_id, +}; + +module_i2c_driver(pmbus_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Generic PMBus driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_algo_bit.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_algo_bit.c new file mode 100644 index 000000000000..c98ac7a1c5b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_algo_bit.c @@ -0,0 +1,725 @@ +/* ------------------------------------------------------------------------- + * i2c-algo-bit.c i2c driver algorithms for bit-shift adapters + * ------------------------------------------------------------------------- + * Copyright (C) 1995-2000 Simon G. Vogl + + 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. + * ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include + +static int g_i2c_algo_bit_debug = 0; +static int g_i2c_algo_bit_error = 0; + +module_param(g_i2c_algo_bit_debug, int, S_IRUGO | S_IWUSR); +module_param(g_i2c_algo_bit_error, int, S_IRUGO | S_IWUSR); + +#define I2C_ALGO_BIT_DEBUG(fmt, args...) do { \ + if (g_i2c_algo_bit_debug) { \ + printk(KERN_INFO "[I2C_ALGO_BIT][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define I2C_ALGO_BIT_ERROR(fmt, args...) do { \ + if (g_i2c_algo_bit_error) { \ + printk(KERN_ERR "[I2C_ALGO_BIT][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* ----- global defines ----------------------------------------------- */ + +#ifdef DEBUG +#define bit_dbg(level, dev, format, args...) \ + do { \ + if (i2c_debug >= level) \ + dev_dbg(dev, format, ##args); \ + } while (0) +#else +#define bit_dbg(level, dev, format, args...) \ + do {} while (0) +#endif /* DEBUG */ + +/* ----- global variables --------------------------------------------- */ + +static int bit_test; /* see if the line-setting functions work */ +module_param(bit_test, int, S_IRUGO); +MODULE_PARM_DESC(bit_test, "lines testing - 0 off; 1 report; 2 fail if stuck"); + +#ifdef DEBUG +static int i2c_debug = 1; +module_param(i2c_debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(i2c_debug, + "debug level - 0 off; 1 normal; 2 verbose; 3 very verbose"); +#endif + +/* --- setting states on the bus with the right timing: --------------- */ + +#define setsda(adap, val) adap->setsda(adap->data, val) +#define setscl(adap, val) adap->setscl(adap->data, val) +#define getsda(adap) adap->getsda(adap->data) +#define getscl(adap) adap->getscl(adap->data) + +static inline void sdalo(struct i2c_algo_bit_data *adap) +{ + setsda(adap, 0); + udelay((adap->udelay + 1) / 2); +} + +static inline void sdahi(struct i2c_algo_bit_data *adap) +{ + setsda(adap, 1); + udelay((adap->udelay + 1) / 2); +} + +static inline void scllo(struct i2c_algo_bit_data *adap) +{ + setscl(adap, 0); + udelay(adap->udelay / 2); +} + +/* + * Raise scl line, and do checking for delays. This is necessary for slower + * devices. + */ +static int sclhi(struct i2c_algo_bit_data *adap) +{ + unsigned long start; + + setscl(adap, 1); + + /* Not all adapters have scl sense line... */ + if (!adap->getscl) + goto done; + + start = jiffies; + while (!getscl(adap)) { + /* This hw knows how to read the clock line, so we wait + * until it actually gets high. This is safer as some + * chips may hold it low ("clock stretching") while they + * are processing data internally. + */ + if (time_after(jiffies, start + adap->timeout)) { + /* Test one last time, as we may have been preempted + * between last check and timeout test. + */ + if (getscl(adap)) + break; + return -ETIMEDOUT; + } + cpu_relax(); + } +#ifdef DEBUG + if (jiffies != start && i2c_debug >= 3) + pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go " + "high\n", jiffies - start); +#endif + +done: + udelay(adap->udelay); + return 0; +} + +/* --- other auxiliary functions -------------------------------------- */ +static void i2c_start(struct i2c_algo_bit_data *adap) +{ + /* assert: scl, sda are high */ + setsda(adap, 0); + udelay(adap->udelay); + scllo(adap); +} + +static void i2c_repstart(struct i2c_algo_bit_data *adap) +{ + /* assert: scl is low */ + sdahi(adap); + sclhi(adap); + setsda(adap, 0); + udelay(adap->udelay); + scllo(adap); +} + +static void i2c_stop(struct i2c_algo_bit_data *adap) +{ + /* assert: scl is low */ + sdalo(adap); + sclhi(adap); + setsda(adap, 1); + udelay(adap->udelay); +} + +/* send a byte without start cond., look for arbitration, + check ackn. from slave */ +/* returns: + * 1 if the device acknowledged + * 0 if the device did not ack + * -ETIMEDOUT if an error occurred (while raising the scl line) + */ +static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) +{ + int i; + int sb; + int ack; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: scl is low */ + for (i = 7; i >= 0; i--) { + sb = (c >> i) & 1; + setsda(adap, sb); + udelay((adap->udelay + 1) / 2); + if (sclhi(adap) < 0) { /* timed out */ + bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " + "timeout at bit #%d\n", (int)c, i); + return -ETIMEDOUT; + } + /* FIXME do arbitration here: + * if (sb && !getsda(adap)) -> ouch! Get out of here. + * + * Report a unique code, so higher level code can retry + * the whole (combined) message and *NOT* issue STOP. + */ + scllo(adap); + } + sdahi(adap); + if (sclhi(adap) < 0) { /* timeout */ + bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " + "timeout at ack\n", (int)c); + return -ETIMEDOUT; + } + + /* read ack: SDA should be pulled down by slave, or it may + * NAK (usually to report problems with the data we wrote). + */ + ack = !getsda(adap); /* ack: sda is pulled low -> success */ + bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, + ack ? "A" : "NA"); + + scllo(adap); + return ack; + /* assert: scl is low (sda undef) */ +} + +static int i2c_inb(struct i2c_adapter *i2c_adap) +{ + /* read byte via i2c port, without start/stop sequence */ + /* acknowledge is sent in i2c_read. */ + int i; + unsigned char indata = 0; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: scl is low */ + sdahi(adap); + for (i = 0; i < 8; i++) { + if (sclhi(adap) < 0) { /* timeout */ + bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit " + "#%d\n", 7 - i); + return -ETIMEDOUT; + } + indata *= 2; + if (getsda(adap)) + indata |= 0x01; + setscl(adap, 0); + udelay(i == 7 ? adap->udelay / 2 : adap->udelay); + } + /* assert: scl is low */ + return indata; +} + +/* + * Sanity check for the adapter hardware - check the reaction of + * the bus lines only if it seems to be idle. + */ +static int test_bus(struct i2c_adapter *i2c_adap) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + const char *name = i2c_adap->name; + int scl, sda, ret; + + if (adap->pre_xfer) { + ret = adap->pre_xfer(i2c_adap); + if (ret < 0) + return -ENODEV; + } + + if (adap->getscl == NULL) + pr_info("%s: Testing SDA only, SCL is not readable\n", name); + + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (!scl || !sda) { + printk(KERN_WARNING + "%s: bus seems to be busy (scl=%d, sda=%d)\n", + name, scl, sda); + goto bailout; + } + + sdalo(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (sda) { + printk(KERN_WARNING "%s: SDA stuck high!\n", name); + goto bailout; + } + if (!scl) { + printk(KERN_WARNING "%s: SCL unexpected low " + "while pulling SDA low!\n", name); + goto bailout; + } + + sdahi(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (!sda) { + printk(KERN_WARNING "%s: SDA stuck low!\n", name); + goto bailout; + } + if (!scl) { + printk(KERN_WARNING "%s: SCL unexpected low " + "while pulling SDA high!\n", name); + goto bailout; + } + + scllo(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 0 : getscl(adap); + if (scl) { + printk(KERN_WARNING "%s: SCL stuck high!\n", name); + goto bailout; + } + if (!sda) { + printk(KERN_WARNING "%s: SDA unexpected low " + "while pulling SCL low!\n", name); + goto bailout; + } + + sclhi(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (!scl) { + printk(KERN_WARNING "%s: SCL stuck low!\n", name); + goto bailout; + } + if (!sda) { + printk(KERN_WARNING "%s: SDA unexpected low " + "while pulling SCL high!\n", name); + goto bailout; + } + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); + + pr_info("%s: Test OK\n", name); + return 0; +bailout: + sdahi(adap); + sclhi(adap); + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); + + return -ENODEV; +} + +/* ----- Utility functions + */ + +/* try_address tries to contact a chip for a number of + * times before it gives up. + * return values: + * 1 chip answered + * 0 chip did not answer + * -x transmission error + */ +static int try_address(struct i2c_adapter *i2c_adap, + unsigned char addr, int retries) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int i, ret = 0; + + for (i = 0; i <= retries; i++) { + ret = i2c_outb(i2c_adap, addr); + if (ret == 1 || i == retries) + break; + bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); + i2c_stop(adap); + udelay(adap->udelay); + yield(); + bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); + i2c_start(adap); + } + if (i && ret) + bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at " + "0x%02x: %s\n", i + 1, + addr & 1 ? "read from" : "write to", addr >> 1, + ret == 1 ? "success" : "failed, timeout?"); + return ret; +} + +static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + const unsigned char *temp = msg->buf; + int count = msg->len; + unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + int retval; + int wrcount = 0; + + while (count > 0) { + retval = i2c_outb(i2c_adap, *temp); + + /* OK/ACK; or ignored NAK */ + if ((retval > 0) || (nak_ok && (retval == 0))) { + count--; + temp++; + wrcount++; + + /* A slave NAKing the master means the slave didn't like + * something about the data it saw. For example, maybe + * the SMBus PEC was wrong. + */ + } else if (retval == 0) { + dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n"); + return -EIO; + + /* Timeout; or (someday) lost arbitration + * + * FIXME Lost ARB implies retrying the transaction from + * the first message, after the "winning" master issues + * its STOP. As a rule, upper layer code has no reason + * to know or care about this ... it is *NOT* an error. + */ + } else { + dev_err(&i2c_adap->dev, "sendbytes: error %d\n", + retval); + return retval; + } + } + return wrcount; +} + +static int acknak(struct i2c_adapter *i2c_adap, int is_ack) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: sda is high */ + if (is_ack) /* send ack */ + setsda(adap, 0); + udelay((adap->udelay + 1) / 2); + if (sclhi(adap) < 0) { /* timeout */ + dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n"); + return -ETIMEDOUT; + } + scllo(adap); + return 0; +} + +static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int inval; + int rdcount = 0; /* counts bytes read */ + unsigned char *temp = msg->buf; + int count = msg->len; + const unsigned flags = msg->flags; + + while (count > 0) { + inval = i2c_inb(i2c_adap); + if (inval >= 0) { + *temp = inval; + rdcount++; + } else { /* read timed out */ + break; + } + + temp++; + count--; + + /* Some SMBus transactions require that we receive the + transaction length as the first read byte. */ + if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) { + if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { + if (!(flags & I2C_M_NO_RD_ACK)) + acknak(i2c_adap, 0); + dev_err(&i2c_adap->dev, "readbytes: invalid " + "block length (%d)\n", inval); + return -EPROTO; + } + /* The original count value accounts for the extra + bytes, that is, either 1 for a regular transaction, + or 2 for a PEC transaction. */ + count += inval; + msg->len += inval; + } + + bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n", + inval, + (flags & I2C_M_NO_RD_ACK) + ? "(no ack/nak)" + : (count ? "A" : "NA")); + + if (!(flags & I2C_M_NO_RD_ACK)) { + inval = acknak(i2c_adap, count); + if (inval < 0) + return inval; + } + } + return rdcount; +} + +/* doAddress initiates the transfer by generating the start condition (in + * try_address) and transmits the address in the necessary format to handle + * reads, writes as well as 10bit-addresses. + * returns: + * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set + * -x an error occurred (like: -ENXIO if the device did not answer, or + * -ETIMEDOUT, for example if the lines are stuck...) + */ +static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + unsigned char addr; + int ret, retries; + + retries = nak_ok ? 0 : i2c_adap->retries; + + if (flags & I2C_M_TEN) { + /* a ten bit address */ + addr = 0xf0 | ((msg->addr >> 7) & 0x06); + bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); + /* try extended address code...*/ + ret = try_address(i2c_adap, addr, retries); + if ((ret != 1) && !nak_ok) { + dev_err(&i2c_adap->dev, + "died at extended address code\n"); + return -ENXIO; + } + /* the remaining 8 bit address */ + ret = i2c_outb(i2c_adap, msg->addr & 0xff); + if ((ret != 1) && !nak_ok) { + /* the chip did not ack / xmission error occurred */ + dev_err(&i2c_adap->dev, "died at 2nd address code\n"); + return -ENXIO; + } + if (flags & I2C_M_RD) { + bit_dbg(3, &i2c_adap->dev, "emitting repeated " + "start condition\n"); + i2c_repstart(adap); + /* okay, now switch into reading mode */ + addr |= 0x01; + ret = try_address(i2c_adap, addr, retries); + if ((ret != 1) && !nak_ok) { + dev_err(&i2c_adap->dev, + "died at repeated address code\n"); + return -EIO; + } + } + } else { /* normal 7bit address */ + addr = msg->addr << 1; + if (flags & I2C_M_RD) + addr |= 1; + if (flags & I2C_M_REV_DIR_ADDR) + addr ^= 1; + ret = try_address(i2c_adap, addr, retries); + if ((ret != 1) && !nak_ok) + return -ENXIO; + } + + return 0; +} + +static void bit_i2c_unblock(struct i2c_adapter *i2c_adap) +{ + int i; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + for (i = 0; i < 9; i++) { + setscl(adap, 0); + udelay(5); + setscl(adap, 1); + udelay(5); + } + setscl(adap, 0); + setsda(adap, 0); + udelay(5); + setscl(adap, 1); + udelay(5); + setsda(adap, 1); +} + +static int check_bit_i2c_unblock(struct i2c_adapter *i2c_adap) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int sda, scl; + + sda = getsda(adap); + scl = getscl(adap); + if ((sda == 0) && scl) { + I2C_ALGO_BIT_ERROR("SCL is high and SDA is low, send 9 clock to device.\n"); + bit_i2c_unblock(i2c_adap); + } + + sda = getsda(adap); + scl = getscl(adap); + if (sda && scl) { + I2C_ALGO_BIT_DEBUG("SCL and SDA are both high, i2c level check ok.\n"); + return 0; + } + dev_warn(&i2c_adap->dev, "Check i2c level failed, SCL %s, SDA %s.\n", scl ? "high" : "low", sda ? "high" : "low"); + return -EIO; +} + +static int bit_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], int num) +{ + struct i2c_msg *pmsg; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int i, ret; + unsigned short nak_ok; + + if (adap->pre_xfer) { + ret = adap->pre_xfer(i2c_adap); + if (ret < 0) + return ret; + } + + if (check_bit_i2c_unblock(i2c_adap) < 0) { + I2C_ALGO_BIT_ERROR("check i2c is block.\n"); + return -EIO; + } + + bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); + i2c_start(adap); + for (i = 0; i < num; i++) { + pmsg = &msgs[i]; + nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; + if (!(pmsg->flags & I2C_M_NOSTART)) { + if (i) { + bit_dbg(3, &i2c_adap->dev, "emitting " + "repeated start condition\n"); + i2c_repstart(adap); + } + ret = bit_doAddress(i2c_adap, pmsg); + if ((ret != 0) && !nak_ok) { + bit_dbg(1, &i2c_adap->dev, "NAK from " + "device addr 0x%02x msg #%d\n", + msgs[i].addr, i); + goto bailout; + } + } + if (pmsg->flags & I2C_M_RD) { + /* read bytes into buffer*/ + ret = readbytes(i2c_adap, pmsg); + if (ret >= 1) + bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n", + ret, ret == 1 ? "" : "s"); + if (ret < pmsg->len) { + if (ret >= 0) + ret = -EIO; + goto bailout; + } + } else { + /* write bytes from buffer */ + ret = sendbytes(i2c_adap, pmsg); + if (ret >= 1) + bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n", + ret, ret == 1 ? "" : "s"); + if (ret < pmsg->len) { + if (ret >= 0) + ret = -EIO; + goto bailout; + } + } + } + ret = i; + +bailout: + bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); + i2c_stop(adap); + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); + return ret; +} + +static u32 bit_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_SMBUS_READ_BLOCK_DATA | + I2C_FUNC_SMBUS_BLOCK_PROC_CALL | + I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; +} + +/* -----exported algorithm data: ------------------------------------- */ + +const struct i2c_algorithm wb_i2c_bit_algo = { + .master_xfer = bit_xfer, + .functionality = bit_func, +}; +EXPORT_SYMBOL(wb_i2c_bit_algo); + +static const struct i2c_adapter_quirks i2c_bit_quirk_no_clk_stretch = { + .flags = I2C_AQ_NO_CLK_STRETCH, +}; + +/* + * registering functions to load algorithms at runtime + */ +static int __i2c_bit_add_bus(struct i2c_adapter *adap, + int (*add_adapter)(struct i2c_adapter *)) +{ + struct i2c_algo_bit_data *bit_adap = adap->algo_data; + int ret; + + if (bit_test) { + ret = test_bus(adap); + if (bit_test >= 2 && ret < 0) + return -ENODEV; + } + + /* register new adapter to i2c module... */ + adap->algo = &wb_i2c_bit_algo; + adap->retries = 3; + if (bit_adap->getscl == NULL) + adap->quirks = &i2c_bit_quirk_no_clk_stretch; + + ret = add_adapter(adap); + if (ret < 0) + return ret; + + /* Complain if SCL can't be read */ + if (bit_adap->getscl == NULL) { + dev_warn(&adap->dev, "Not I2C compliant: can't read SCL\n"); + dev_warn(&adap->dev, "Bus may be unreliable\n"); + } + return 0; +} + +int wb_i2c_bit_add_bus(struct i2c_adapter *adap) +{ + return __i2c_bit_add_bus(adap, i2c_add_adapter); +} +EXPORT_SYMBOL(wb_i2c_bit_add_bus); + +int wb_i2c_bit_add_numbered_bus(struct i2c_adapter *adap) +{ + return __i2c_bit_add_bus(adap, i2c_add_numbered_adapter); +} +EXPORT_SYMBOL(wb_i2c_bit_add_numbered_bus); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio.c new file mode 100644 index 000000000000..0362e905fddb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio.c @@ -0,0 +1,431 @@ +/* + * Bitbanging I2C bus driver using the GPIO API + * + * Copyright (C) 2007 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int wb_i2c_bit_add_numbered_bus(struct i2c_adapter *adap); + +struct i2c_gpio_private_data { + struct gpio_desc *sda; + struct gpio_desc *scl; + struct i2c_adapter adap; + struct i2c_algo_bit_data bit_data; + struct i2c_gpio_platform_data pdata; +#ifdef CONFIG_I2C_GPIO_FAULT_INJECTOR + struct dentry *debug_dir; +#endif +}; + +/* + * Toggle SDA by changing the output value of the pin. This is only + * valid for pins configured as open drain (i.e. setting the value + * high effectively turns off the output driver.) + */ +static void i2c_gpio_setsda_val(void *data, int state) +{ + struct i2c_gpio_private_data *priv = data; + + gpiod_set_value_cansleep(priv->sda, state); +} + +/* + * Toggle SCL by changing the output value of the pin. This is used + * for pins that are configured as open drain and for output-only + * pins. The latter case will break the i2c protocol, but it will + * often work in practice. + */ +static void i2c_gpio_setscl_val(void *data, int state) +{ + struct i2c_gpio_private_data *priv = data; + + gpiod_set_value_cansleep(priv->scl, state); +} + +static int i2c_gpio_getsda(void *data) +{ + struct i2c_gpio_private_data *priv = data; + + return gpiod_get_value_cansleep(priv->sda); +} + +static int i2c_gpio_getscl(void *data) +{ + struct i2c_gpio_private_data *priv = data; + + return gpiod_get_value_cansleep(priv->scl); +} + +#ifdef CONFIG_I2C_GPIO_FAULT_INJECTOR +static struct dentry *i2c_gpio_debug_dir; + +#define setsda(bd, val) ((bd)->setsda((bd)->data, val)) +#define setscl(bd, val) ((bd)->setscl((bd)->data, val)) +#define getsda(bd) ((bd)->getsda((bd)->data)) +#define getscl(bd) ((bd)->getscl((bd)->data)) + +#define WIRE_ATTRIBUTE(wire) \ +static int fops_##wire##_get(void *data, u64 *val) \ +{ \ + struct i2c_gpio_private_data *priv = data; \ + \ + i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ + *val = get##wire(&priv->bit_data); \ + i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ + return 0; \ +} \ +static int fops_##wire##_set(void *data, u64 val) \ +{ \ + struct i2c_gpio_private_data *priv = data; \ + \ + i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ + set##wire(&priv->bit_data, val); \ + i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ + return 0; \ +} \ +DEFINE_DEBUGFS_ATTRIBUTE(fops_##wire, fops_##wire##_get, fops_##wire##_set, "%llu\n") + +WIRE_ATTRIBUTE(scl); +WIRE_ATTRIBUTE(sda); + +static void i2c_gpio_incomplete_transfer(struct i2c_gpio_private_data *priv, + u32 pattern, u8 pattern_size) +{ + struct i2c_algo_bit_data *bit_data = &priv->bit_data; + int i; + + i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); + + /* START condition */ + setsda(bit_data, 0); + udelay(bit_data->udelay); + + /* Send pattern, request ACK, don't send STOP */ + for (i = pattern_size - 1; i >= 0; i--) { + setscl(bit_data, 0); + udelay(bit_data->udelay / 2); + setsda(bit_data, (pattern >> i) & 1); + udelay((bit_data->udelay + 1) / 2); + setscl(bit_data, 1); + udelay(bit_data->udelay); + } + + i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); +} + +static int fops_incomplete_addr_phase_set(void *data, u64 addr) +{ + struct i2c_gpio_private_data *priv = data; + u32 pattern; + + if (addr > 0x7f) + return -EINVAL; + + /* ADDR (7 bit) + RD (1 bit) + Client ACK, keep SDA hi (1 bit) */ + pattern = (addr << 2) | 3; + + i2c_gpio_incomplete_transfer(priv, pattern, 9); + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(fops_incomplete_addr_phase, NULL, fops_incomplete_addr_phase_set, "%llu\n"); + +static int fops_incomplete_write_byte_set(void *data, u64 addr) +{ + struct i2c_gpio_private_data *priv = data; + u32 pattern; + + if (addr > 0x7f) + return -EINVAL; + + /* ADDR (7 bit) + WR (1 bit) + Client ACK (1 bit) */ + pattern = (addr << 2) | 1; + /* 0x00 (8 bit) + Client ACK, keep SDA hi (1 bit) */ + pattern = (pattern << 9) | 1; + + i2c_gpio_incomplete_transfer(priv, pattern, 18); + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(fops_incomplete_write_byte, NULL, fops_incomplete_write_byte_set, "%llu\n"); + +static void i2c_gpio_fault_injector_init(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv = platform_get_drvdata(pdev); + + /* + * If there will be a debugfs-dir per i2c adapter somewhen, put the + * 'fault-injector' dir there. Until then, we have a global dir with + * all adapters as subdirs. + */ + if (!i2c_gpio_debug_dir) { + i2c_gpio_debug_dir = debugfs_create_dir("i2c-fault-injector", NULL); + if (!i2c_gpio_debug_dir) + return; + } + + priv->debug_dir = debugfs_create_dir(pdev->name, i2c_gpio_debug_dir); + if (!priv->debug_dir) + return; + + debugfs_create_file_unsafe("scl", 0600, priv->debug_dir, priv, &fops_scl); + debugfs_create_file_unsafe("sda", 0600, priv->debug_dir, priv, &fops_sda); + debugfs_create_file_unsafe("incomplete_address_phase", 0200, priv->debug_dir, + priv, &fops_incomplete_addr_phase); + debugfs_create_file_unsafe("incomplete_write_byte", 0200, priv->debug_dir, + priv, &fops_incomplete_write_byte); +} + +static void i2c_gpio_fault_injector_exit(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv = platform_get_drvdata(pdev); + + debugfs_remove_recursive(priv->debug_dir); +} +#else +static inline void i2c_gpio_fault_injector_init(struct platform_device *pdev) {} +static inline void i2c_gpio_fault_injector_exit(struct platform_device *pdev) {} +#endif /* CONFIG_I2C_GPIO_FAULT_INJECTOR*/ + +static void of_i2c_gpio_get_props(struct device_node *np, + struct i2c_gpio_platform_data *pdata) +{ + u32 reg; + + of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay); + + if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", ®)) + pdata->timeout = msecs_to_jiffies(reg); + + pdata->sda_is_open_drain = + of_property_read_bool(np, "i2c-gpio,sda-open-drain"); + pdata->scl_is_open_drain = + of_property_read_bool(np, "i2c-gpio,scl-open-drain"); + pdata->scl_is_output_only = + of_property_read_bool(np, "i2c-gpio,scl-output-only"); +} + +static struct gpio_desc *i2c_gpio_get_desc(struct device *dev, + const char *con_id, + unsigned int index, + enum gpiod_flags gflags) +{ + struct gpio_desc *retdesc; + int ret; + + retdesc = devm_gpiod_get(dev, con_id, gflags); + if (!IS_ERR(retdesc)) { + dev_dbg(dev, "got GPIO from name %s\n", con_id); + return retdesc; + } + + retdesc = devm_gpiod_get_index(dev, NULL, index, gflags); + if (!IS_ERR(retdesc)) { + dev_dbg(dev, "got GPIO from index %u\n", index); + return retdesc; + } + + ret = PTR_ERR(retdesc); + + /* FIXME: hack in the old code, is this really necessary? */ + if (ret == -EINVAL) + retdesc = ERR_PTR(-EPROBE_DEFER); + + /* This happens if the GPIO driver is not yet probed, let's defer */ + if (ret == -ENOENT) + retdesc = ERR_PTR(-EPROBE_DEFER); + + if (PTR_ERR(retdesc) != -EPROBE_DEFER) + dev_err(dev, "error trying to get descriptor: %d\n", ret); + + return retdesc; +} + +static int i2c_gpio_probe(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv; + struct i2c_gpio_platform_data *pdata; + struct i2c_algo_bit_data *bit_data; + struct i2c_adapter *adap; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + enum gpiod_flags gflags; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + adap = &priv->adap; + bit_data = &priv->bit_data; + pdata = &priv->pdata; + + if (np) { + of_i2c_gpio_get_props(np, pdata); + } else { + /* + * If all platform data settings are zero it is OK + * to not provide any platform data from the board. + */ + if (dev_get_platdata(dev)) + memcpy(pdata, dev_get_platdata(dev), sizeof(*pdata)); + } + + /* + * First get the GPIO pins; if it fails, we'll defer the probe. + * If the SDA line is marked from platform data or device tree as + * "open drain" it means something outside of our control is making + * this line being handled as open drain, and we should just handle + * it as any other output. Else we enforce open drain as this is + * required for an I2C bus. + */ + if (pdata->sda_is_open_drain) + gflags = GPIOD_OUT_HIGH; + else + gflags = GPIOD_OUT_HIGH_OPEN_DRAIN; + priv->sda = i2c_gpio_get_desc(dev, "sda", 0, gflags); + if (IS_ERR(priv->sda)) + return PTR_ERR(priv->sda); + + /* + * If the SCL line is marked from platform data or device tree as + * "open drain" it means something outside of our control is making + * this line being handled as open drain, and we should just handle + * it as any other output. Else we enforce open drain as this is + * required for an I2C bus. + */ + if (pdata->scl_is_open_drain) + gflags = GPIOD_OUT_HIGH; + else + gflags = GPIOD_OUT_HIGH_OPEN_DRAIN; + priv->scl = i2c_gpio_get_desc(dev, "scl", 1, gflags); + if (IS_ERR(priv->scl)) + return PTR_ERR(priv->scl); + + if (gpiod_cansleep(priv->sda) || gpiod_cansleep(priv->scl)) + dev_warn(dev, "Slow GPIO pins might wreak havoc into I2C/SMBus bus timing"); + + bit_data->setsda = i2c_gpio_setsda_val; + bit_data->setscl = i2c_gpio_setscl_val; + + if (!pdata->scl_is_output_only) + bit_data->getscl = i2c_gpio_getscl; + bit_data->getsda = i2c_gpio_getsda; + + if (pdata->udelay) + bit_data->udelay = pdata->udelay; + else if (pdata->scl_is_output_only) + bit_data->udelay = 50; /* 10 kHz */ + else + bit_data->udelay = 5; /* 100 kHz */ + + if (pdata->timeout) + bit_data->timeout = pdata->timeout; + else + bit_data->timeout = HZ / 10; /* 100 ms */ + + bit_data->data = priv; + + adap->owner = THIS_MODULE; + if (np) + strlcpy(adap->name, dev_name(dev), sizeof(adap->name)); + else + snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id); + + adap->algo_data = bit_data; + adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + adap->dev.parent = dev; + adap->dev.of_node = np; + + adap->nr = pdev->id; + ret = wb_i2c_bit_add_numbered_bus(adap); + if (ret) + return ret; + + platform_set_drvdata(pdev, priv); + + /* + * FIXME: using global GPIO numbers is not helpful. If/when we + * get accessors to get the actual name of the GPIO line, + * from the descriptor, then provide that instead. + */ + dev_info(dev, "using lines %u (SDA) and %u (SCL%s)\n", + desc_to_gpio(priv->sda), desc_to_gpio(priv->scl), + pdata->scl_is_output_only + ? ", no clock stretching" : ""); + + i2c_gpio_fault_injector_init(pdev); + + return 0; +} + +static int i2c_gpio_remove(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv; + struct i2c_adapter *adap; + + i2c_gpio_fault_injector_exit(pdev); + + priv = platform_get_drvdata(pdev); + adap = &priv->adap; + + i2c_del_adapter(adap); + + return 0; +} + +#if defined(CONFIG_OF) +static const struct of_device_id i2c_gpio_dt_ids[] = { + { .compatible = "wb-i2c-gpio", }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids); +#endif + +static struct platform_driver i2c_gpio_driver = { + .driver = { + .name = "wb-i2c-gpio", + .of_match_table = of_match_ptr(i2c_gpio_dt_ids), + }, + .probe = i2c_gpio_probe, + .remove = i2c_gpio_remove, +}; + +static int __init i2c_gpio_init(void) +{ + int ret; + + ret = platform_driver_register(&i2c_gpio_driver); + if (ret) + printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); + + return ret; +} +subsys_initcall(i2c_gpio_init); + +static void __exit i2c_gpio_exit(void) +{ + platform_driver_unregister(&i2c_gpio_driver); +} +module_exit(i2c_gpio_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:i2c-gpio"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio_device.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio_device.c new file mode 100644 index 000000000000..5cf949d70ef8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio_device.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int gpio_sda = 17; +module_param(gpio_sda, int, S_IRUGO | S_IWUSR); + +static int gpio_scl = 1; +module_param(gpio_scl, int, S_IRUGO | S_IWUSR); + +static int gpio_udelay = 2; +module_param(gpio_udelay, int, S_IRUGO | S_IWUSR); + +static int g_wb_i2c_gpio_device_debug = 0; +static int g_wb_i2c_gpio_device_error = 0; + +module_param(g_wb_i2c_gpio_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_gpio_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_GPIO_DEVICE_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_gpio_device_debug) { \ + printk(KERN_INFO "[WB_I2C_GPIO_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_GPIO_DEVICE_ERROR(fmt, args...) do { \ + if (g_wb_i2c_gpio_device_error) { \ + printk(KERN_ERR "[WB_I2C_GPIO_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/****************** i2c adapter with gpio ***********************/ +static struct i2c_gpio_platform_data i2c_pdata = { + .udelay = 2, + .scl_is_output_only = 0, + .sda_is_open_drain = 0, + .scl_is_open_drain = 0, +}; + +static void i2c_gpio_release(struct device *dev) +{ + return; +} + +static struct platform_device wb_i2c_gpio_device = { + .name = "wb-i2c-gpio", + .id = -1, + .num_resources = 0, + .resource = NULL, + .dev = { + .platform_data = &i2c_pdata, + .release = i2c_gpio_release, + }, +}; + +/* + * i2c + */ +static struct gpiod_lookup_table wb_i2c_gpio_table = { + .dev_id = "wb-i2c-gpio", + .table = { + GPIO_LOOKUP_IDX("wb_gpio_d1500", 17, NULL, 0, + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), + GPIO_LOOKUP_IDX("wb_gpio_d1500", 1, NULL, 1, + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), + }, +}; + +static int __init wb_i2c_gpio_device_init(void) +{ + int err; + + WB_I2C_GPIO_DEVICE_VERBOSE("wb_i2c_gpio_device_init enter!\n"); + wb_i2c_gpio_table.table[0].chip_hwnum = gpio_sda; + wb_i2c_gpio_table.table[1].chip_hwnum = gpio_scl; + i2c_pdata.udelay = gpio_udelay; + gpiod_add_lookup_table(&wb_i2c_gpio_table); + + err = platform_device_register(&wb_i2c_gpio_device); + if (err < 0) { + printk(KERN_ERR "register i2c gpio device fail(%d). \n", err); + gpiod_remove_lookup_table(&wb_i2c_gpio_table); + return -1; + } + return 0; +} + +static void __exit wb_i2c_gpio_device_exit(void) +{ + WB_I2C_GPIO_DEVICE_VERBOSE("wb_i2c_gpio_device_exit enter!\n"); + platform_device_unregister(&wb_i2c_gpio_device); + gpiod_remove_lookup_table(&wb_i2c_gpio_table); +} + +module_init(wb_i2c_gpio_device_init); +module_exit(wb_i2c_gpio_device_exit); +MODULE_DESCRIPTION("I2C GPIO Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_i801.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_i801.c new file mode 100644 index 000000000000..a733c115487e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_i801.c @@ -0,0 +1,2114 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + Copyright (c) 1998 - 2002 Frodo Looijaard , + Philip Edelbrock , and Mark D. Studebaker + + Copyright (C) 2007 - 2014 Jean Delvare + Copyright (C) 2010 Intel Corporation, + David Woodhouse + +*/ + +/* + * Supports the following Intel I/O Controller Hubs (ICH): + * + * I/O Block I2C + * region SMBus Block proc. block + * Chip name PCI ID size PEC buffer call read + * --------------------------------------------------------------------------- + * 82801AA (ICH) 0x2413 16 no no no no + * 82801AB (ICH0) 0x2423 16 no no no no + * 82801BA (ICH2) 0x2443 16 no no no no + * 82801CA (ICH3) 0x2483 32 soft no no no + * 82801DB (ICH4) 0x24c3 32 hard yes no no + * 82801E (ICH5) 0x24d3 32 hard yes yes yes + * 6300ESB 0x25a4 32 hard yes yes yes + * 82801F (ICH6) 0x266a 32 hard yes yes yes + * 6310ESB/6320ESB 0x269b 32 hard yes yes yes + * 82801G (ICH7) 0x27da 32 hard yes yes yes + * 82801H (ICH8) 0x283e 32 hard yes yes yes + * 82801I (ICH9) 0x2930 32 hard yes yes yes + * EP80579 (Tolapai) 0x5032 32 hard yes yes yes + * ICH10 0x3a30 32 hard yes yes yes + * ICH10 0x3a60 32 hard yes yes yes + * 5/3400 Series (PCH) 0x3b30 32 hard yes yes yes + * 6 Series (PCH) 0x1c22 32 hard yes yes yes + * Patsburg (PCH) 0x1d22 32 hard yes yes yes + * Patsburg (PCH) IDF 0x1d70 32 hard yes yes yes + * Patsburg (PCH) IDF 0x1d71 32 hard yes yes yes + * Patsburg (PCH) IDF 0x1d72 32 hard yes yes yes + * DH89xxCC (PCH) 0x2330 32 hard yes yes yes + * Panther Point (PCH) 0x1e22 32 hard yes yes yes + * Lynx Point (PCH) 0x8c22 32 hard yes yes yes + * Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes + * Avoton (SOC) 0x1f3c 32 hard yes yes yes + * Wellsburg (PCH) 0x8d22 32 hard yes yes yes + * Wellsburg (PCH) MS 0x8d7d 32 hard yes yes yes + * Wellsburg (PCH) MS 0x8d7e 32 hard yes yes yes + * Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes + * Coleto Creek (PCH) 0x23b0 32 hard yes yes yes + * Wildcat Point (PCH) 0x8ca2 32 hard yes yes yes + * Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes + * BayTrail (SOC) 0x0f12 32 hard yes yes yes + * Braswell (SOC) 0x2292 32 hard yes yes yes + * Sunrise Point-H (PCH) 0xa123 32 hard yes yes yes + * Sunrise Point-LP (PCH) 0x9d23 32 hard yes yes yes + * DNV (SOC) 0x19df 32 hard yes yes yes + * Emmitsburg (PCH) 0x1bc9 32 hard yes yes yes + * Broxton (SOC) 0x5ad4 32 hard yes yes yes + * Lewisburg (PCH) 0xa1a3 32 hard yes yes yes + * Lewisburg Supersku (PCH) 0xa223 32 hard yes yes yes + * Kaby Lake PCH-H (PCH) 0xa2a3 32 hard yes yes yes + * Gemini Lake (SOC) 0x31d4 32 hard yes yes yes + * Cannon Lake-H (PCH) 0xa323 32 hard yes yes yes + * Cannon Lake-LP (PCH) 0x9da3 32 hard yes yes yes + * Cedar Fork (PCH) 0x18df 32 hard yes yes yes + * Ice Lake-LP (PCH) 0x34a3 32 hard yes yes yes + * Comet Lake (PCH) 0x02a3 32 hard yes yes yes + * Comet Lake-H (PCH) 0x06a3 32 hard yes yes yes + * Elkhart Lake (PCH) 0x4b23 32 hard yes yes yes + * Tiger Lake-LP (PCH) 0xa0a3 32 hard yes yes yes + * Tiger Lake-H (PCH) 0x43a3 32 hard yes yes yes + * Jasper Lake (SOC) 0x4da3 32 hard yes yes yes + * Comet Lake-V (PCH) 0xa3a3 32 hard yes yes yes + * Alder Lake-S (PCH) 0x7aa3 32 hard yes yes yes + * + * Features supported by this driver: + * Software PEC no + * Hardware PEC yes + * Block buffer yes + * Block process call transaction yes + * I2C block read transaction yes (doesn't use the block buffer) + * Slave mode no + * SMBus Host Notify yes + * Interrupt processing yes + * + * See the file Documentation/i2c/busses/i2c-i801.rst for details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI +#include +#include +#endif + +#define mem_clear(data, size) memset((data), 0, (size)) + +/* I801 SMBus address offsets */ +#define SMBHSTSTS(p) (0 + (p)->smba) +#define SMBHSTCNT(p) (2 + (p)->smba) +#define SMBHSTCMD(p) (3 + (p)->smba) +#define SMBHSTADD(p) (4 + (p)->smba) +#define SMBHSTDAT0(p) (5 + (p)->smba) +#define SMBHSTDAT1(p) (6 + (p)->smba) +#define SMBBLKDAT(p) (7 + (p)->smba) +#define SMBPEC(p) (8 + (p)->smba) /* ICH3 and later */ +#define SMBAUXSTS(p) (12 + (p)->smba) /* ICH4 and later */ +#define SMBAUXCTL(p) (13 + (p)->smba) /* ICH4 and later */ +#define SMBSLVSTS(p) (16 + (p)->smba) /* ICH3 and later */ +#define SMBSLVCMD(p) (17 + (p)->smba) /* ICH3 and later */ +#define SMBNTFDADD(p) (20 + (p)->smba) /* ICH3 and later */ +#define SMBPINCTL(p) (15 + (p)->smba) /* SMBus Pin Control Register */ + +/* PCI Address Constants */ +#define SMBBAR 4 +#define SMBPCICTL 0x004 +#define SMBPCISTS 0x006 +#define SMBHSTCFG 0x040 +#define TCOBASE 0x050 +#define TCOCTL 0x054 + +#define SBREG_BAR 0x10 +#define SBREG_SMBCTRL 0xc6000c +#define SBREG_SMBCTRL_DNV 0xcf000c + +/* Host status bits for SMBPCISTS */ +#define SMBPCISTS_INTS BIT(3) + +/* Control bits for SMBPCICTL */ +#define SMBPCICTL_INTDIS BIT(10) + +/* Host configuration bits for SMBHSTCFG */ +#define SMBHSTCFG_HST_EN BIT(0) +#define SMBHSTCFG_SMB_SMI_EN BIT(1) +#define SMBHSTCFG_I2C_EN BIT(2) +#define SMBHSTCFG_SSRESET BIT(3) +#define SSRESET_SLEEP_TIME 1 /* 1us */ +#define SSRESET_RETRY_TIME (1000 / SSRESET_SLEEP_TIME) + +/* Pin status for SMBPINCTL */ +#define SMBPINCTL_CLK_STS 1 /* bit0 SMBCLK_CUR_STS*/ +#define SMBPINCTL_SDA_STS 2 /* bit1 SMBDATA_CUR_STS*/ +#define SMBPINCTL_CLK_CTL 4 /* bit2 SMBCLK_CTL */ + +#define SMBHSTCFG_SPD_WD BIT(4) + +/* TCO configuration bits for TCOCTL */ +#define TCOCTL_EN BIT(8) + +/* Auxiliary status register bits, ICH4+ only */ +#define SMBAUXSTS_CRCE BIT(0) +#define SMBAUXSTS_STCO BIT(1) + +/* Auxiliary control register bits, ICH4+ only */ +#define SMBAUXCTL_CRC BIT(0) +#define SMBAUXCTL_E32B BIT(1) + +/* Other settings */ +#define MAX_RETRIES 400 + +/* I801 command constants */ +#define I801_QUICK 0x00 +#define I801_BYTE 0x04 +#define I801_BYTE_DATA 0x08 +#define I801_WORD_DATA 0x0C +#define I801_PROC_CALL 0x10 /* unimplemented */ +#define I801_BLOCK_DATA 0x14 +#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */ +#define I801_BLOCK_PROC_CALL 0x1C + +/* I801 Host Control register bits */ +#define SMBHSTCNT_INTREN BIT(0) +#define SMBHSTCNT_KILL BIT(1) +#define SMBHSTCNT_LAST_BYTE BIT(5) +#define SMBHSTCNT_START BIT(6) +#define SMBHSTCNT_PEC_EN BIT(7) /* ICH3 and later */ + +/* I801 Hosts Status register bits */ +#define SMBHSTSTS_BYTE_DONE BIT(7) +#define SMBHSTSTS_INUSE_STS BIT(6) +#define SMBHSTSTS_SMBALERT_STS BIT(5) +#define SMBHSTSTS_FAILED BIT(4) +#define SMBHSTSTS_BUS_ERR BIT(3) +#define SMBHSTSTS_DEV_ERR BIT(2) +#define SMBHSTSTS_INTR BIT(1) +#define SMBHSTSTS_HOST_BUSY BIT(0) + +/* Host Notify Status register bits */ +#define SMBSLVSTS_HST_NTFY_STS BIT(0) + +/* Host Notify Command register bits */ +#define SMBSLVCMD_HST_NTFY_INTREN BIT(0) + +#define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \ + SMBHSTSTS_DEV_ERR) + +#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \ + STATUS_ERROR_FLAGS) + +/* Older devices have their ID defined in */ +#define PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS 0x02a3 +#define PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS 0x06a3 +#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 +#define PCI_DEVICE_ID_INTEL_CDF_SMBUS 0x18df +#define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df +#define PCI_DEVICE_ID_INTEL_EBG_SMBUS 0x1bc9 +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 +/* Patsburg also has three 'Integrated Device Function' SMBus controllers */ +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70 +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22 +#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c +#define PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS 0x2292 +#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 +#define PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS 0x23b0 +#define PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS 0x31d4 +#define PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS 0x34a3 +#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 +#define PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS 0x43a3 +#define PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS 0x4b23 +#define PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS 0x4da3 +#define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4 +#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 +#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS 0x8d22 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0 0x8d7d +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1 0x8d7e +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 +#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS 0x9ca2 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS 0x9d23 +#define PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS 0x9da3 +#define PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS 0xa0a3 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS 0xa123 +#define PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS 0xa1a3 +#define PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS 0xa223 +#define PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS 0xa2a3 +#define PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS 0xa323 +#define PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS 0xa3a3 + +struct i801_mux_config { + char *gpio_chip; + unsigned values[3]; + int n_values; + unsigned classes[3]; + unsigned gpios[2]; /* Relative to gpio_chip->base */ + int n_gpios; +}; + +struct i801_priv { + struct i2c_adapter adapter; + unsigned long smba; + unsigned char original_hstcfg; + unsigned char original_slvcmd; + struct pci_dev *pci_dev; + unsigned int features; + + /* isr processing */ + wait_queue_head_t waitq; + u8 status; + + /* Command state used by isr for byte-by-byte block transactions */ + u8 cmd; + bool is_read; + int count; + int len; + u8 *data; + +#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI + const struct i801_mux_config *mux_drvdata; + struct platform_device *mux_pdev; + struct gpiod_lookup_table *lookup; +#endif + struct platform_device *tco_pdev; + + /* + * If set to true the host controller registers are reserved for + * ACPI AML use. Protected by acpi_lock. + */ + bool acpi_reserved; + struct mutex acpi_lock; +}; + +#define FEATURE_SMBUS_PEC BIT(0) +#define FEATURE_BLOCK_BUFFER BIT(1) +#define FEATURE_BLOCK_PROC BIT(2) +#define FEATURE_I2C_BLOCK_READ BIT(3) +#define FEATURE_IRQ BIT(4) +#define FEATURE_HOST_NOTIFY BIT(5) +/* Not really a feature, but it's convenient to handle it as such */ +#define FEATURE_IDF BIT(15) +#define FEATURE_TCO_SPT BIT(16) +#define FEATURE_TCO_CNL BIT(17) + +static const char *i801_feature_names[] = { + "SMBus PEC", + "Block buffer", + "Block process call", + "I2C block read", + "Interrupt", + "SMBus Host Notify", +}; + +static unsigned int disable_features; +module_param(disable_features, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n" + "\t\t 0x01 disable SMBus PEC\n" + "\t\t 0x02 disable the block buffer\n" + "\t\t 0x08 disable the I2C block read functionality\n" + "\t\t 0x10 don't use interrupts\n" + "\t\t 0x20 disable SMBus Host Notify "); + +static void i801_setscl(struct i801_priv *priv, unsigned int level) +{ + int pin_status; + pin_status = inb_p(SMBPINCTL(priv)); + if (level == 0) { + pin_status &= (~SMBPINCTL_CLK_CTL); + } + else { + pin_status |= SMBPINCTL_CLK_CTL; + } + outb_p(pin_status, SMBPINCTL(priv)); + return; +} + +static void i801_i2c_unblock(struct i801_priv *priv) +{ + int i; + for (i = 0; i < 10; i++) { + i801_setscl(priv, 0); + udelay(5); + i801_setscl(priv, 1); + udelay(5); + } + return; +} + +static int i801_check_i2c_unblock(struct i801_priv *priv) +{ + int pin_status; + + pin_status = inb_p(SMBPINCTL(priv)); + if ( (!(pin_status & SMBPINCTL_SDA_STS) ) && (pin_status & SMBPINCTL_CLK_STS) ) { + dev_dbg(&priv->pci_dev->dev, "SDA is low, send 9 clock to device!\n"); + i801_i2c_unblock(priv); + } + return 0; +} + +static void i801_do_reset(struct i801_priv *priv) +{ + unsigned char tmp; + unsigned int retry_count = 0; + + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &tmp); + tmp |= SMBHSTCFG_SSRESET; + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, tmp); + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &tmp); + + while( ((tmp & SMBHSTCFG_SSRESET) != 0) && (retry_count < SSRESET_RETRY_TIME)) { + usleep_range(SSRESET_SLEEP_TIME, SSRESET_SLEEP_TIME + 1); + retry_count++; + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &tmp); + } + + return ; +} + +static int i801_check_i2c_scl(struct i801_priv *priv) +{ + int pin_status; + + pin_status = inb_p(SMBPINCTL(priv)); + if ( (pin_status & SMBPINCTL_SDA_STS) && (pin_status & SMBPINCTL_CLK_STS) ) { + return 0; + } + + dev_dbg(&priv->pci_dev->dev, "SDA or SCL is low, begin to reset SMBus adapter, pin_status: 0x%x\n",pin_status); + i801_do_reset(priv); + pin_status = inb_p(SMBPINCTL(priv)); + if ( (pin_status & SMBPINCTL_SDA_STS) && (pin_status & SMBPINCTL_CLK_STS) ) { + return 0; + } + dev_warn(&priv->pci_dev->dev, "SDA or SCL is low.pin_status:0x%x\n",pin_status); + return -1; +} + +/* Make sure the SMBus host is ready to start transmitting. + Return 0 if it is, -EBUSY if it is not. */ +static int i801_check_pre(struct i801_priv *priv) +{ + int status; + + i801_check_i2c_unblock(priv); + + if (i801_check_i2c_scl(priv)) { + return -EIO; + } + + status = inb_p(SMBHSTSTS(priv)); + if (status & SMBHSTSTS_HOST_BUSY) { + dev_dbg(&priv->pci_dev->dev, "SMBus is busy, begin to reset SMBus adapter!\n"); + + i801_do_reset(priv); + + status = inb_p(SMBHSTSTS(priv)); + if (status & SMBHSTSTS_HOST_BUSY) { + dev_err(&priv->pci_dev->dev, "SMBus is busy, can't use it!\n"); + return -EBUSY; + } + } + + status &= STATUS_FLAGS; + if (status) { + dev_dbg(&priv->pci_dev->dev, "Clearing status flags (%02x)\n", + status); + outb_p(status, SMBHSTSTS(priv)); + status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS; + if (status) { + dev_err(&priv->pci_dev->dev, + "Failed clearing status flags (%02x)\n", + status); + return -EBUSY; + } + } + + /* + * Clear CRC status if needed. + * During normal operation, i801_check_post() takes care + * of it after every operation. We do it here only in case + * the hardware was already in this state when the driver + * started. + */ + if (priv->features & FEATURE_SMBUS_PEC) { + status = inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE; + if (status) { + dev_dbg(&priv->pci_dev->dev, + "Clearing aux status flags (%02x)\n", status); + outb_p(status, SMBAUXSTS(priv)); + status = inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE; + if (status) { + dev_err(&priv->pci_dev->dev, + "Failed clearing aux status flags (%02x)\n", + status); + return -EBUSY; + } + } + } + + return 0; +} + +/* + * Convert the status register to an error code, and clear it. + * Note that status only contains the bits we want to clear, not the + * actual register value. + */ +static int i801_check_post(struct i801_priv *priv, int status) +{ + int result = 0; + + /* + * If the SMBus is still busy, we give up + * Note: This timeout condition only happens when using polling + * transactions. For interrupt operation, NAK/timeout is indicated by + * DEV_ERR. + */ + if (unlikely(status < 0)) { + dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); + /* try to stop the current command */ + dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n"); + outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv)); + usleep_range(1000, 2000); + outb_p(0, SMBHSTCNT(priv)); + + /* Check if it worked */ + status = inb_p(SMBHSTSTS(priv)); + if ((status & SMBHSTSTS_HOST_BUSY) || + !(status & SMBHSTSTS_FAILED)) + dev_err(&priv->pci_dev->dev, + "Failed terminating the transaction\n"); + outb_p(STATUS_FLAGS, SMBHSTSTS(priv)); + return -ETIMEDOUT; + } + + if (status & SMBHSTSTS_FAILED) { + result = -EIO; + dev_err(&priv->pci_dev->dev, "Transaction failed\n"); + } + if (status & SMBHSTSTS_DEV_ERR) { + /* + * This may be a PEC error, check and clear it. + * + * AUXSTS is handled differently from HSTSTS. + * For HSTSTS, i801_isr() or i801_wait_intr() + * has already cleared the error bits in hardware, + * and we are passed a copy of the original value + * in "status". + * For AUXSTS, the hardware register is left + * for us to handle here. + * This is asymmetric, slightly iffy, but safe, + * since all this code is serialized and the CRCE + * bit is harmless as long as it's cleared before + * the next operation. + */ + if ((priv->features & FEATURE_SMBUS_PEC) && + (inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE)) { + outb_p(SMBAUXSTS_CRCE, SMBAUXSTS(priv)); + result = -EBADMSG; + dev_dbg(&priv->pci_dev->dev, "PEC error\n"); + } else { + result = -ENXIO; + dev_dbg(&priv->pci_dev->dev, "No response\n"); + } + } + if (status & SMBHSTSTS_BUS_ERR) { + result = -EAGAIN; + dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n"); + } + + /* Clear status flags except BYTE_DONE, to be cleared by caller */ + outb_p(status, SMBHSTSTS(priv)); + + return result; +} + +/* Wait for BUSY being cleared and either INTR or an error flag being set */ +static int i801_wait_intr(struct i801_priv *priv) +{ + int timeout = 0; + int status; + + /* We will always wait for a fraction of a second! */ + do { + usleep_range(250, 500); + status = inb_p(SMBHSTSTS(priv)); + } while (((status & SMBHSTSTS_HOST_BUSY) || + !(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) && + (timeout++ < MAX_RETRIES)); + + if (timeout > MAX_RETRIES) { + dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n"); + return -ETIMEDOUT; + } + return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR); +} + +/* Wait for either BYTE_DONE or an error flag being set */ +static int i801_wait_byte_done(struct i801_priv *priv) +{ + int timeout = 0; + int status; + + /* We will always wait for a fraction of a second! */ + do { + usleep_range(250, 500); + status = inb_p(SMBHSTSTS(priv)); + } while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) && + (timeout++ < MAX_RETRIES)); + + if (timeout > MAX_RETRIES) { + dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n"); + return -ETIMEDOUT; + } + return status & STATUS_ERROR_FLAGS; +} + +static int i801_transaction(struct i801_priv *priv, int xact) +{ + int status; + int result; + const struct i2c_adapter *adap = &priv->adapter; + + result = i801_check_pre(priv); + if (result < 0) + return result; + + if (priv->features & FEATURE_IRQ) { + outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START, + SMBHSTCNT(priv)); + result = wait_event_timeout(priv->waitq, + (status = priv->status), + adap->timeout); + if (!result) { + status = -ETIMEDOUT; + dev_warn(&priv->pci_dev->dev, + "Timeout waiting for interrupt!\n"); + } + priv->status = 0; + return i801_check_post(priv, status); + } + + /* the current contents of SMBHSTCNT can be overwritten, since PEC, + * SMBSCMD are passed in xact */ + outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv)); + + status = i801_wait_intr(priv); + return i801_check_post(priv, status); +} + +static int i801_block_transaction_by_block(struct i801_priv *priv, + union i2c_smbus_data *data, + char read_write, int command, + int hwpec) +{ + int i, len; + int status; + int xact = hwpec ? SMBHSTCNT_PEC_EN : 0; + + switch (command) { + case I2C_SMBUS_BLOCK_PROC_CALL: + xact |= I801_BLOCK_PROC_CALL; + break; + case I2C_SMBUS_BLOCK_DATA: + xact |= I801_BLOCK_DATA; + break; + default: + return -EOPNOTSUPP; + } + + inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */ + + /* Use 32-byte buffer to process this transaction */ + if (read_write == I2C_SMBUS_WRITE) { + len = data->block[0]; + outb_p(len, SMBHSTDAT0(priv)); + for (i = 0; i < len; i++) + outb_p(data->block[i+1], SMBBLKDAT(priv)); + } + + status = i801_transaction(priv, xact); + if (status) + return status; + + if (read_write == I2C_SMBUS_READ || + command == I2C_SMBUS_BLOCK_PROC_CALL) { + len = inb_p(SMBHSTDAT0(priv)); + if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) + return -EPROTO; + + data->block[0] = len; + for (i = 0; i < len; i++) + data->block[i + 1] = inb_p(SMBBLKDAT(priv)); + } + return 0; +} + +static void i801_isr_byte_done(struct i801_priv *priv) +{ + if (priv->is_read) { + /* For SMBus block reads, length is received with first byte */ + if (((priv->cmd & 0x1c) == I801_BLOCK_DATA) && + (priv->count == 0)) { + priv->len = inb_p(SMBHSTDAT0(priv)); + if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX) { + dev_err(&priv->pci_dev->dev, + "Illegal SMBus block read size %d\n", + priv->len); + /* FIXME: Recover */ + priv->len = I2C_SMBUS_BLOCK_MAX; + } else { + dev_dbg(&priv->pci_dev->dev, + "SMBus block read size is %d\n", + priv->len); + } + priv->data[-1] = priv->len; + } + + /* Read next byte */ + if (priv->count < priv->len) + priv->data[priv->count++] = inb(SMBBLKDAT(priv)); + else + dev_dbg(&priv->pci_dev->dev, + "Discarding extra byte on block read\n"); + + /* Set LAST_BYTE for last byte of read transaction */ + if (priv->count == priv->len - 1) + outb_p(priv->cmd | SMBHSTCNT_LAST_BYTE, + SMBHSTCNT(priv)); + } else if (priv->count < priv->len - 1) { + /* Write next byte, except for IRQ after last byte */ + outb_p(priv->data[++priv->count], SMBBLKDAT(priv)); + } + + /* Clear BYTE_DONE to continue with next byte */ + outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv)); +} + +static irqreturn_t i801_host_notify_isr(struct i801_priv *priv) +{ + unsigned short addr; + + addr = inb_p(SMBNTFDADD(priv)) >> 1; + + /* + * With the tested platforms, reading SMBNTFDDAT (22 + (p)->smba) + * always returns 0. Our current implementation doesn't provide + * data, so we just ignore it. + */ + i2c_handle_smbus_host_notify(&priv->adapter, addr); + + /* clear Host Notify bit and return */ + outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv)); + return IRQ_HANDLED; +} + +/* + * There are three kinds of interrupts: + * + * 1) i801 signals transaction completion with one of these interrupts: + * INTR - Success + * DEV_ERR - Invalid command, NAK or communication timeout + * BUS_ERR - SMI# transaction collision + * FAILED - transaction was canceled due to a KILL request + * When any of these occur, update ->status and wake up the waitq. + * ->status must be cleared before kicking off the next transaction. + * + * 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt + * occurs for each byte of a byte-by-byte to prepare the next byte. + * + * 3) Host Notify interrupts + */ +static irqreturn_t i801_isr(int irq, void *dev_id) +{ + struct i801_priv *priv = dev_id; + u16 pcists; + u8 status; + + /* Confirm this is our interrupt */ + pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); + if (!(pcists & SMBPCISTS_INTS)) + return IRQ_NONE; + + if (priv->features & FEATURE_HOST_NOTIFY) { + status = inb_p(SMBSLVSTS(priv)); + if (status & SMBSLVSTS_HST_NTFY_STS) + return i801_host_notify_isr(priv); + } + + status = inb_p(SMBHSTSTS(priv)); + if (status & SMBHSTSTS_BYTE_DONE) + i801_isr_byte_done(priv); + + /* + * Clear irq sources and report transaction result. + * ->status must be cleared before the next transaction is started. + */ + status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; + if (status) { + outb_p(status, SMBHSTSTS(priv)); + priv->status = status; + wake_up(&priv->waitq); + } + + return IRQ_HANDLED; +} + +/* + * For "byte-by-byte" block transactions: + * I2C write uses cmd=I801_BLOCK_DATA, I2C_EN=1 + * I2C read uses cmd=I801_I2C_BLOCK_DATA + */ +static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, + union i2c_smbus_data *data, + char read_write, int command, + int hwpec) +{ + int i, len; + int smbcmd; + int status; + int result; + const struct i2c_adapter *adap = &priv->adapter; + + if (command == I2C_SMBUS_BLOCK_PROC_CALL) + return -EOPNOTSUPP; + + result = i801_check_pre(priv); + if (result < 0) + return result; + + len = data->block[0]; + + if (read_write == I2C_SMBUS_WRITE) { + outb_p(len, SMBHSTDAT0(priv)); + outb_p(data->block[1], SMBBLKDAT(priv)); + } + + if (command == I2C_SMBUS_I2C_BLOCK_DATA && + read_write == I2C_SMBUS_READ) + smbcmd = I801_I2C_BLOCK_DATA; + else + smbcmd = I801_BLOCK_DATA; + + if (priv->features & FEATURE_IRQ) { + priv->is_read = (read_write == I2C_SMBUS_READ); + if (len == 1 && priv->is_read) + smbcmd |= SMBHSTCNT_LAST_BYTE; + priv->cmd = smbcmd | SMBHSTCNT_INTREN; + priv->len = len; + priv->count = 0; + priv->data = &data->block[1]; + + outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv)); + result = wait_event_timeout(priv->waitq, + (status = priv->status), + adap->timeout); + if (!result) { + status = -ETIMEDOUT; + dev_warn(&priv->pci_dev->dev, + "Timeout waiting for interrupt!\n"); + } + priv->status = 0; + return i801_check_post(priv, status); + } + + for (i = 1; i <= len; i++) { + if (i == len && read_write == I2C_SMBUS_READ) + smbcmd |= SMBHSTCNT_LAST_BYTE; + outb_p(smbcmd, SMBHSTCNT(priv)); + + if (i == 1) + outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START, + SMBHSTCNT(priv)); + + status = i801_wait_byte_done(priv); + if (status) + goto exit; + + if (i == 1 && read_write == I2C_SMBUS_READ + && command != I2C_SMBUS_I2C_BLOCK_DATA) { + len = inb_p(SMBHSTDAT0(priv)); + if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) { + dev_err(&priv->pci_dev->dev, + "Illegal SMBus block read size %d\n", + len); + /* Recover */ + while (inb_p(SMBHSTSTS(priv)) & + SMBHSTSTS_HOST_BUSY) + outb_p(SMBHSTSTS_BYTE_DONE, + SMBHSTSTS(priv)); + outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv)); + return -EPROTO; + } + data->block[0] = len; + } + + /* Retrieve/store value in SMBBLKDAT */ + if (read_write == I2C_SMBUS_READ) + data->block[i] = inb_p(SMBBLKDAT(priv)); + if (read_write == I2C_SMBUS_WRITE && i+1 <= len) + outb_p(data->block[i+1], SMBBLKDAT(priv)); + + /* signals SMBBLKDAT ready */ + outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv)); + } + + status = i801_wait_intr(priv); +exit: + return i801_check_post(priv, status); +} + +static int i801_set_block_buffer_mode(struct i801_priv *priv) +{ + outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv)); + if ((inb_p(SMBAUXCTL(priv)) & SMBAUXCTL_E32B) == 0) + return -EIO; + return 0; +} + +/* Block transaction function */ +static int i801_block_transaction(struct i801_priv *priv, + union i2c_smbus_data *data, char read_write, + int command, int hwpec) +{ + int result = 0; + unsigned char hostc; + + if (command == I2C_SMBUS_I2C_BLOCK_DATA) { + if (read_write == I2C_SMBUS_WRITE) { + /* set I2C_EN bit in configuration register */ + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc); + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, + hostc | SMBHSTCFG_I2C_EN); + } else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) { + dev_err(&priv->pci_dev->dev, + "I2C block read is unsupported!\n"); + return -EOPNOTSUPP; + } + } + + if (read_write == I2C_SMBUS_WRITE + || command == I2C_SMBUS_I2C_BLOCK_DATA) { + if (data->block[0] < 1) + data->block[0] = 1; + if (data->block[0] > I2C_SMBUS_BLOCK_MAX) + data->block[0] = I2C_SMBUS_BLOCK_MAX; + } else { + data->block[0] = 32; /* max for SMBus block reads */ + } + + /* Experience has shown that the block buffer can only be used for + SMBus (not I2C) block transactions, even though the datasheet + doesn't mention this limitation. */ + if ((priv->features & FEATURE_BLOCK_BUFFER) + && command != I2C_SMBUS_I2C_BLOCK_DATA + && i801_set_block_buffer_mode(priv) == 0) + result = i801_block_transaction_by_block(priv, data, + read_write, + command, hwpec); + else + result = i801_block_transaction_byte_by_byte(priv, data, + read_write, + command, hwpec); + + if (command == I2C_SMBUS_I2C_BLOCK_DATA + && read_write == I2C_SMBUS_WRITE) { + /* restore saved configuration register value */ + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc); + } + return result; +} + +/* Return negative errno on error. */ +static s32 i801_access(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, u8 command, + int size, union i2c_smbus_data *data) +{ + int hwpec; + int block = 0; + int ret = 0, xact = 0; + struct i801_priv *priv = i2c_get_adapdata(adap); + + mutex_lock(&priv->acpi_lock); + if (priv->acpi_reserved) { + mutex_unlock(&priv->acpi_lock); + return -EBUSY; + } + + pm_runtime_get_sync(&priv->pci_dev->dev); + + hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC) + && size != I2C_SMBUS_QUICK + && size != I2C_SMBUS_I2C_BLOCK_DATA; + + switch (size) { + case I2C_SMBUS_QUICK: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + xact = I801_QUICK; + break; + case I2C_SMBUS_BYTE: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + if (read_write == I2C_SMBUS_WRITE) + outb_p(command, SMBHSTCMD(priv)); + xact = I801_BYTE; + break; + case I2C_SMBUS_BYTE_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + outb_p(command, SMBHSTCMD(priv)); + if (read_write == I2C_SMBUS_WRITE) + outb_p(data->byte, SMBHSTDAT0(priv)); + xact = I801_BYTE_DATA; + break; + case I2C_SMBUS_WORD_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + outb_p(command, SMBHSTCMD(priv)); + if (read_write == I2C_SMBUS_WRITE) { + outb_p(data->word & 0xff, SMBHSTDAT0(priv)); + outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv)); + } + xact = I801_WORD_DATA; + break; + case I2C_SMBUS_BLOCK_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + outb_p(command, SMBHSTCMD(priv)); + block = 1; + break; + case I2C_SMBUS_I2C_BLOCK_DATA: + /* + * NB: page 240 of ICH5 datasheet shows that the R/#W + * bit should be cleared here, even when reading. + * However if SPD Write Disable is set (Lynx Point and later), + * the read will fail if we don't set the R/#W bit. + */ + outb_p(((addr & 0x7f) << 1) | + ((priv->original_hstcfg & SMBHSTCFG_SPD_WD) ? + (read_write & 0x01) : 0), + SMBHSTADD(priv)); + if (read_write == I2C_SMBUS_READ) { + /* NB: page 240 of ICH5 datasheet also shows + * that DATA1 is the cmd field when reading */ + outb_p(command, SMBHSTDAT1(priv)); + } else + outb_p(command, SMBHSTCMD(priv)); + block = 1; + break; + case I2C_SMBUS_BLOCK_PROC_CALL: + /* + * Bit 0 of the slave address register always indicate a write + * command. + */ + outb_p((addr & 0x7f) << 1, SMBHSTADD(priv)); + outb_p(command, SMBHSTCMD(priv)); + block = 1; + break; + default: + dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n", + size); + ret = -EOPNOTSUPP; + goto out; + } + + if (hwpec) /* enable/disable hardware PEC */ + outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv)); + else + outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC), + SMBAUXCTL(priv)); + + if (block) + ret = i801_block_transaction(priv, data, read_write, size, + hwpec); + else + ret = i801_transaction(priv, xact); + + /* Some BIOSes don't like it when PEC is enabled at reboot or resume + time, so we forcibly disable it after every transaction. Turn off + E32B for the same reason. */ + if (hwpec || block) + outb_p(inb_p(SMBAUXCTL(priv)) & + ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); + + if (block) + goto out; + if (ret) + goto out; + if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK)) + goto out; + + switch (xact & 0x7f) { + case I801_BYTE: /* Result put in SMBHSTDAT0 */ + case I801_BYTE_DATA: + data->byte = inb_p(SMBHSTDAT0(priv)); + break; + case I801_WORD_DATA: + data->word = inb_p(SMBHSTDAT0(priv)) + + (inb_p(SMBHSTDAT1(priv)) << 8); + break; + } + +out: + pm_runtime_mark_last_busy(&priv->pci_dev->dev); + pm_runtime_put_autosuspend(&priv->pci_dev->dev); + mutex_unlock(&priv->acpi_lock); + return ret; +} + +static u32 i801_func(struct i2c_adapter *adapter) +{ + struct i801_priv *priv = i2c_get_adapdata(adapter); + + 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_WRITE_I2C_BLOCK | + ((priv->features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) | + ((priv->features & FEATURE_BLOCK_PROC) ? + I2C_FUNC_SMBUS_BLOCK_PROC_CALL : 0) | + ((priv->features & FEATURE_I2C_BLOCK_READ) ? + I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0) | + ((priv->features & FEATURE_HOST_NOTIFY) ? + I2C_FUNC_SMBUS_HOST_NOTIFY : 0); +} + +static void i801_enable_host_notify(struct i2c_adapter *adapter) +{ + struct i801_priv *priv = i2c_get_adapdata(adapter); + + if (!(priv->features & FEATURE_HOST_NOTIFY)) + return; + + if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd)) + outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd, + SMBSLVCMD(priv)); + + /* clear Host Notify bit to allow a new notification */ + outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv)); +} + +static void i801_disable_host_notify(struct i801_priv *priv) +{ + if (!(priv->features & FEATURE_HOST_NOTIFY)) + return; + + outb_p(priv->original_slvcmd, SMBSLVCMD(priv)); +} + +static const struct i2c_algorithm smbus_algorithm = { + .smbus_xfer = i801_access, + .functionality = i801_func, +}; + +static const struct pci_device_id i801_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EP80579_1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CDF_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EBG_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROXTON_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS) }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, i801_ids); + +#if defined CONFIG_X86 && defined CONFIG_DMI +static unsigned char apanel_addr; + +/* Scan the system ROM for the signature "FJKEYINF" */ +static __init const void __iomem *bios_signature(const void __iomem *bios) +{ + ssize_t offset; + const unsigned char signature[] = "FJKEYINF"; + + for (offset = 0; offset < 0x10000; offset += 0x10) { + if (check_signature(bios + offset, signature, + sizeof(signature)-1)) + return bios + offset; + } + return NULL; +} + +static void __init input_apanel_init(void) +{ + void __iomem *bios; + const void __iomem *p; + + bios = ioremap(0xF0000, 0x10000); /* Can't fail */ + p = bios_signature(bios); + if (p) { + /* just use the first address */ + apanel_addr = readb(p + 8 + 3) >> 1; + } + iounmap(bios); +} + +struct dmi_onboard_device_info { + const char *name; + u8 type; + unsigned short i2c_addr; + const char *i2c_type; +}; + +static const struct dmi_onboard_device_info dmi_devices[] = { + { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" }, + { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" }, + { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" }, +}; + +static void dmi_check_onboard_device(u8 type, const char *name, + struct i2c_adapter *adap) +{ + int i; + struct i2c_board_info info; + + for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) { + /* & ~0x80, ignore enabled/disabled bit */ + if ((type & ~0x80) != dmi_devices[i].type) + continue; + if (strcasecmp(name, dmi_devices[i].name)) + continue; + + mem_clear(&info, sizeof(struct i2c_board_info)); + info.addr = dmi_devices[i].i2c_addr; + strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE); + i2c_new_client_device(adap, &info); + break; + } +} + +/* We use our own function to check for onboard devices instead of + dmi_find_device() as some buggy BIOS's have the devices we are interested + in marked as disabled */ +static void dmi_check_onboard_devices(const struct dmi_header *dm, void *adap) +{ + int i, count; + + if (dm->type != 10) + return; + + count = (dm->length - sizeof(struct dmi_header)) / 2; + for (i = 0; i < count; i++) { + const u8 *d = (char *)(dm + 1) + (i * 2); + const char *name = ((char *) dm) + dm->length; + u8 type = d[0]; + u8 s = d[1]; + + if (!s) + continue; + s--; + while (s > 0 && name[0]) { + name += strlen(name) + 1; + s--; + } + if (name[0] == 0) /* Bogus string reference */ + continue; + + dmi_check_onboard_device(type, name, adap); + } +} + +/* NOTE: Keep this list in sync with drivers/platform/x86/dell-smo8800.c */ +static const char *const acpi_smo8800_ids[] = { + "SMO8800", + "SMO8801", + "SMO8810", + "SMO8811", + "SMO8820", + "SMO8821", + "SMO8830", + "SMO8831", +}; + +static acpi_status check_acpi_smo88xx_device(acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + struct acpi_device_info *info; + acpi_status status; + char *hid; + int i; + + status = acpi_get_object_info(obj_handle, &info); + if (ACPI_FAILURE(status)) + return AE_OK; + + if (!(info->valid & ACPI_VALID_HID)) + goto smo88xx_not_found; + + hid = info->hardware_id.string; + if (!hid) + goto smo88xx_not_found; + + i = match_string(acpi_smo8800_ids, ARRAY_SIZE(acpi_smo8800_ids), hid); + if (i < 0) + goto smo88xx_not_found; + + kfree(info); + + *((bool *)return_value) = true; + return AE_CTRL_TERMINATE; + +smo88xx_not_found: + kfree(info); + return AE_OK; +} + +static bool is_dell_system_with_lis3lv02d(void) +{ + bool found; + const char *vendor; + + vendor = dmi_get_system_info(DMI_SYS_VENDOR); + if (!vendor || strcmp(vendor, "Dell Inc.")) + return false; + + /* + * Check that ACPI device SMO88xx is present and is functioning. + * Function acpi_get_devices() already filters all ACPI devices + * which are not present or are not functioning. + * ACPI device SMO88xx represents our ST microelectronics lis3lv02d + * accelerometer but unfortunately ACPI does not provide any other + * information (like I2C address). + */ + found = false; + acpi_get_devices(NULL, check_acpi_smo88xx_device, NULL, + (void **)&found); + + return found; +} + +/* + * Accelerometer's I2C address is not specified in DMI nor ACPI, + * so it is needed to define mapping table based on DMI product names. + */ +static const struct { + const char *dmi_product_name; + unsigned short i2c_addr; +} dell_lis3lv02d_devices[] = { + /* + * Dell platform team told us that these Latitude devices have + * ST microelectronics accelerometer at I2C address 0x29. + */ + { "Latitude E5250", 0x29 }, + { "Latitude E5450", 0x29 }, + { "Latitude E5550", 0x29 }, + { "Latitude E6440", 0x29 }, + { "Latitude E6440 ATG", 0x29 }, + { "Latitude E6540", 0x29 }, + /* + * Additional individual entries were added after verification. + */ + { "Latitude 5480", 0x29 }, + { "Vostro V131", 0x1d }, +}; + +static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv) +{ + struct i2c_board_info info; + const char *dmi_product_name; + int i; + + dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME); + for (i = 0; i < ARRAY_SIZE(dell_lis3lv02d_devices); ++i) { + if (strcmp(dmi_product_name, + dell_lis3lv02d_devices[i].dmi_product_name) == 0) + break; + } + + if (i == ARRAY_SIZE(dell_lis3lv02d_devices)) { + dev_warn(&priv->pci_dev->dev, + "Accelerometer lis3lv02d is present on SMBus but its" + " address is unknown, skipping registration\n"); + return; + } + + mem_clear(&info, sizeof(struct i2c_board_info)); + info.addr = dell_lis3lv02d_devices[i].i2c_addr; + strlcpy(info.type, "lis3lv02d", I2C_NAME_SIZE); + i2c_new_client_device(&priv->adapter, &info); +} + +/* Register optional slaves */ +static void i801_probe_optional_slaves(struct i801_priv *priv) +{ + /* Only register slaves on main SMBus channel */ + if (priv->features & FEATURE_IDF) + return; + + if (apanel_addr) { + struct i2c_board_info info; + + mem_clear(&info, sizeof(struct i2c_board_info)); + info.addr = apanel_addr; + strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE); + i2c_new_client_device(&priv->adapter, &info); + } + + if (dmi_name_in_vendors("FUJITSU")) + dmi_walk(dmi_check_onboard_devices, &priv->adapter); + + if (is_dell_system_with_lis3lv02d()) + register_dell_lis3lv02d_i2c_device(priv); + + /* Instantiate SPD EEPROMs unless the SMBus is multiplexed */ +#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) + if (!priv->mux_drvdata) +#endif + i2c_register_spd(&priv->adapter); +} +#else +static void __init input_apanel_init(void) {} +static void i801_probe_optional_slaves(struct i801_priv *priv) {} +#endif /* CONFIG_X86 && CONFIG_DMI */ + +#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI +static struct i801_mux_config i801_mux_config_asus_z8_d12 = { + .gpio_chip = "gpio_ich", + .values = { 0x02, 0x03 }, + .n_values = 2, + .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD }, + .gpios = { 52, 53 }, + .n_gpios = 2, +}; + +static struct i801_mux_config i801_mux_config_asus_z8_d18 = { + .gpio_chip = "gpio_ich", + .values = { 0x02, 0x03, 0x01 }, + .n_values = 3, + .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD }, + .gpios = { 52, 53 }, + .n_gpios = 2, +}; + +static const struct dmi_system_id mux_dmi_table[] = { + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"), + }, + .driver_data = &i801_mux_config_asus_z8_d18, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"), + }, + .driver_data = &i801_mux_config_asus_z8_d18, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { } +}; + +/* Setup multiplexing if needed */ +static int i801_add_mux(struct i801_priv *priv) +{ + struct device *dev = &priv->adapter.dev; + const struct i801_mux_config *mux_config; + struct i2c_mux_gpio_platform_data gpio_data; + struct gpiod_lookup_table *lookup; + int err, i; + + if (!priv->mux_drvdata) + return 0; + mux_config = priv->mux_drvdata; + + /* Prepare the platform data */ + mem_clear(&gpio_data, sizeof(struct i2c_mux_gpio_platform_data)); + gpio_data.parent = priv->adapter.nr; + gpio_data.values = mux_config->values; + gpio_data.n_values = mux_config->n_values; + gpio_data.classes = mux_config->classes; + gpio_data.idle = I2C_MUX_GPIO_NO_IDLE; + + /* Register GPIO descriptor lookup table */ + lookup = devm_kzalloc(dev, + struct_size(lookup, table, mux_config->n_gpios + 1), + GFP_KERNEL); + if (!lookup) + return -ENOMEM; + lookup->dev_id = "i2c-mux-gpio"; + for (i = 0; i < mux_config->n_gpios; i++) { + lookup->table[i] = (struct gpiod_lookup) + GPIO_LOOKUP(mux_config->gpio_chip, + mux_config->gpios[i], "mux", 0); + } + gpiod_add_lookup_table(lookup); + priv->lookup = lookup; + + /* + * Register the mux device, we use PLATFORM_DEVID_NONE here + * because since we are referring to the GPIO chip by name we are + * anyways in deep trouble if there is more than one of these + * devices, and there should likely only be one platform controller + * hub. + */ + priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio", + PLATFORM_DEVID_NONE, &gpio_data, + sizeof(struct i2c_mux_gpio_platform_data)); + if (IS_ERR(priv->mux_pdev)) { + err = PTR_ERR(priv->mux_pdev); + gpiod_remove_lookup_table(lookup); + priv->mux_pdev = NULL; + dev_err(dev, "Failed to register i2c-mux-gpio device\n"); + return err; + } + + return 0; +} + +static void i801_del_mux(struct i801_priv *priv) +{ + if (priv->mux_pdev) + platform_device_unregister(priv->mux_pdev); + if (priv->lookup) + gpiod_remove_lookup_table(priv->lookup); +} + +static unsigned int i801_get_adapter_class(struct i801_priv *priv) +{ + const struct dmi_system_id *id; + const struct i801_mux_config *mux_config; + unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + int i; + + id = dmi_first_match(mux_dmi_table); + if (id) { + /* Remove branch classes from trunk */ + mux_config = id->driver_data; + for (i = 0; i < mux_config->n_values; i++) + class &= ~mux_config->classes[i]; + + /* Remember for later */ + priv->mux_drvdata = mux_config; + } + + return class; +} +#else +static inline int i801_add_mux(struct i801_priv *priv) { return 0; } +static inline void i801_del_mux(struct i801_priv *priv) { } + +static inline unsigned int i801_get_adapter_class(struct i801_priv *priv) +{ + return I2C_CLASS_HWMON | I2C_CLASS_SPD; +} +#endif + +static const struct itco_wdt_platform_data spt_tco_platform_data = { + .name = "Intel PCH", + .version = 4, +}; + +static DEFINE_SPINLOCK(p2sb_spinlock); + +static struct platform_device * +i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, + struct resource *tco_res) +{ + struct resource *res; + unsigned int devfn; + u64 base64_addr; + u32 base_addr; + u8 hidden; + + /* + * We must access the NO_REBOOT bit over the Primary to Sideband + * bridge (P2SB). The BIOS prevents the P2SB device from being + * enumerated by the PCI subsystem, so we need to unhide/hide it + * to lookup the P2SB BAR. + */ + spin_lock(&p2sb_spinlock); + + devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 1); + + /* Unhide the P2SB device, if it is hidden */ + pci_bus_read_config_byte(pci_dev->bus, devfn, 0xe1, &hidden); + if (hidden) + pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, 0x0); + + pci_bus_read_config_dword(pci_dev->bus, devfn, SBREG_BAR, &base_addr); + base64_addr = base_addr & 0xfffffff0; + + pci_bus_read_config_dword(pci_dev->bus, devfn, SBREG_BAR + 0x4, &base_addr); + base64_addr |= (u64)base_addr << 32; + + /* Hide the P2SB device, if it was hidden before */ + if (hidden) + pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden); + spin_unlock(&p2sb_spinlock); + + res = &tco_res[1]; + if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS) + res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV; + else + res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL; + + res->end = res->start + 3; + res->flags = IORESOURCE_MEM; + + return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, + tco_res, 2, &spt_tco_platform_data, + sizeof(spt_tco_platform_data)); +} + +static const struct itco_wdt_platform_data cnl_tco_platform_data = { + .name = "Intel PCH", + .version = 6, +}; + +static struct platform_device * +i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev, + struct resource *tco_res) +{ + return platform_device_register_resndata(&pci_dev->dev, + "iTCO_wdt", -1, tco_res, 1, &cnl_tco_platform_data, + sizeof(cnl_tco_platform_data)); +} + +static void i801_add_tco(struct i801_priv *priv) +{ + struct pci_dev *pci_dev = priv->pci_dev; + struct resource tco_res[2], *res; + u32 tco_base, tco_ctl; + + /* If we have ACPI based watchdog use that instead */ + if (acpi_has_watchdog()) + return; + + if (!(priv->features & (FEATURE_TCO_SPT | FEATURE_TCO_CNL))) + return; + + pci_read_config_dword(pci_dev, TCOBASE, &tco_base); + pci_read_config_dword(pci_dev, TCOCTL, &tco_ctl); + if (!(tco_ctl & TCOCTL_EN)) + return; + + mem_clear(tco_res, sizeof(tco_res)); + /* + * Always populate the main iTCO IO resource here. The second entry + * for NO_REBOOT MMIO is filled by the SPT specific function. + */ + res = &tco_res[0]; + res->start = tco_base & ~1; + res->end = res->start + 32 - 1; + res->flags = IORESOURCE_IO; + + if (priv->features & FEATURE_TCO_CNL) + priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res); + else + priv->tco_pdev = i801_add_tco_spt(priv, pci_dev, tco_res); + + if (IS_ERR(priv->tco_pdev)) + dev_warn(&pci_dev->dev, "failed to create iTCO device\n"); +} + +#ifdef CONFIG_ACPI +static bool i801_acpi_is_smbus_ioport(const struct i801_priv *priv, + acpi_physical_address address) +{ + return address >= priv->smba && + address <= pci_resource_end(priv->pci_dev, SMBBAR); +} + +static acpi_status +i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits, + u64 *value, void *handler_context, void *region_context) +{ + struct i801_priv *priv = handler_context; + struct pci_dev *pdev = priv->pci_dev; + acpi_status status; + + /* + * Once BIOS AML code touches the OpRegion we warn and inhibit any + * further access from the driver itself. This device is now owned + * by the system firmware. + */ + mutex_lock(&priv->acpi_lock); + + if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) { + priv->acpi_reserved = true; + + dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n"); + dev_warn(&pdev->dev, "Driver SMBus register access inhibited\n"); + + /* + * BIOS is accessing the host controller so prevent it from + * suspending automatically from now on. + */ + pm_runtime_get_sync(&pdev->dev); + } + + if ((function & ACPI_IO_MASK) == ACPI_READ) + status = acpi_os_read_port(address, (u32 *)value, bits); + else + status = acpi_os_write_port(address, (u32)*value, bits); + + mutex_unlock(&priv->acpi_lock); + + return status; +} + +static int i801_acpi_probe(struct i801_priv *priv) +{ + struct acpi_device *adev; + acpi_status status; + + adev = ACPI_COMPANION(&priv->pci_dev->dev); + if (adev) { + status = acpi_install_address_space_handler(adev->handle, + ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler, + NULL, priv); + if (ACPI_SUCCESS(status)) + return 0; + } + + return acpi_check_resource_conflict(&priv->pci_dev->resource[SMBBAR]); +} + +static void i801_acpi_remove(struct i801_priv *priv) +{ + struct acpi_device *adev; + + adev = ACPI_COMPANION(&priv->pci_dev->dev); + if (!adev) + return; + + acpi_remove_address_space_handler(adev->handle, + ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler); + + mutex_lock(&priv->acpi_lock); + if (priv->acpi_reserved) + pm_runtime_put(&priv->pci_dev->dev); + mutex_unlock(&priv->acpi_lock); +} +#else +static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; } +static inline void i801_acpi_remove(struct i801_priv *priv) { } +#endif + +static unsigned char i801_setup_hstcfg(struct i801_priv *priv) +{ + unsigned char hstcfg = priv->original_hstcfg; + + hstcfg &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ + hstcfg |= SMBHSTCFG_HST_EN; + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hstcfg); + return hstcfg; +} + +static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + unsigned char temp; + int err, i; + struct i801_priv *priv; + + priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + i2c_set_adapdata(&priv->adapter, priv); + priv->adapter.owner = THIS_MODULE; + priv->adapter.class = i801_get_adapter_class(priv); + priv->adapter.algo = &smbus_algorithm; + priv->adapter.dev.parent = &dev->dev; + ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&dev->dev)); + priv->adapter.retries = 3; + mutex_init(&priv->acpi_lock); + + priv->pci_dev = dev; + switch (dev->device) { + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS: + case PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS: + case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS: + case PCI_DEVICE_ID_INTEL_DNV_SMBUS: + case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS: + case PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS: + priv->features |= FEATURE_BLOCK_PROC; + priv->features |= FEATURE_I2C_BLOCK_READ; + priv->features |= FEATURE_IRQ; + priv->features |= FEATURE_SMBUS_PEC; + priv->features |= FEATURE_BLOCK_BUFFER; + priv->features |= FEATURE_TCO_SPT; + priv->features |= FEATURE_HOST_NOTIFY; + break; + + case PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS: + case PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS: + case PCI_DEVICE_ID_INTEL_CDF_SMBUS: + case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS: + case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS: + case PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS: + case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS: + case PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS: + case PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS: + case PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS: + case PCI_DEVICE_ID_INTEL_EBG_SMBUS: + case PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS: + priv->features |= FEATURE_BLOCK_PROC; + priv->features |= FEATURE_I2C_BLOCK_READ; + priv->features |= FEATURE_IRQ; + priv->features |= FEATURE_SMBUS_PEC; + priv->features |= FEATURE_BLOCK_BUFFER; + priv->features |= FEATURE_TCO_CNL; + priv->features |= FEATURE_HOST_NOTIFY; + break; + + case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0: + case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1: + case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2: + priv->features |= FEATURE_IDF; + fallthrough; + default: + priv->features |= FEATURE_BLOCK_PROC; + priv->features |= FEATURE_I2C_BLOCK_READ; + priv->features |= FEATURE_IRQ; + fallthrough; + case PCI_DEVICE_ID_INTEL_82801DB_3: + priv->features |= FEATURE_SMBUS_PEC; + priv->features |= FEATURE_BLOCK_BUFFER; + fallthrough; + case PCI_DEVICE_ID_INTEL_82801CA_3: + priv->features |= FEATURE_HOST_NOTIFY; + fallthrough; + case PCI_DEVICE_ID_INTEL_82801BA_2: + case PCI_DEVICE_ID_INTEL_82801AB_3: + case PCI_DEVICE_ID_INTEL_82801AA_3: + break; + } + + /* Disable features on user request */ + for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) { + if (priv->features & disable_features & (1 << i)) + dev_notice(&dev->dev, "%s disabled by user\n", + i801_feature_names[i]); + } + priv->features &= ~disable_features; + + err = pcim_enable_device(dev); + if (err) { + dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", + err); + return err; + } + pcim_pin_device(dev); + + /* Determine the address of the SMBus area */ + priv->smba = pci_resource_start(dev, SMBBAR); + if (!priv->smba) { + dev_err(&dev->dev, + "SMBus base address uninitialized, upgrade BIOS\n"); + return -ENODEV; + } + + if (i801_acpi_probe(priv)) + return -ENODEV; + + err = pcim_iomap_regions(dev, 1 << SMBBAR, + dev_driver_string(&dev->dev)); + if (err) { + dev_err(&dev->dev, + "Failed to request SMBus region 0x%lx-0x%Lx\n", + priv->smba, + (unsigned long long)pci_resource_end(dev, SMBBAR)); + i801_acpi_remove(priv); + return err; + } + + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &priv->original_hstcfg); + temp = i801_setup_hstcfg(priv); + if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN)) + dev_info(&dev->dev, "Enabling SMBus device\n"); + + if (temp & SMBHSTCFG_SMB_SMI_EN) { + dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); + /* Disable SMBus interrupt feature if SMBus using SMI# */ + priv->features &= ~FEATURE_IRQ; + } + if (temp & SMBHSTCFG_SPD_WD) + dev_info(&dev->dev, "SPD Write Disable is set\n"); + + /* Clear special mode bits */ + if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER)) + outb_p(inb_p(SMBAUXCTL(priv)) & + ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); + + /* Remember original Host Notify setting */ + if (priv->features & FEATURE_HOST_NOTIFY) + priv->original_slvcmd = inb_p(SMBSLVCMD(priv)); + + /* Default timeout in interrupt mode: 200 ms */ + priv->adapter.timeout = HZ / 5; + + if (dev->irq == IRQ_NOTCONNECTED) + priv->features &= ~FEATURE_IRQ; + + if (priv->features & FEATURE_IRQ) { + u16 pcictl, pcists; + + /* Complain if an interrupt is already pending */ + pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); + if (pcists & SMBPCISTS_INTS) + dev_warn(&dev->dev, "An interrupt is pending!\n"); + + /* Check if interrupts have been disabled */ + pci_read_config_word(priv->pci_dev, SMBPCICTL, &pcictl); + if (pcictl & SMBPCICTL_INTDIS) { + dev_info(&dev->dev, "Interrupts are disabled\n"); + priv->features &= ~FEATURE_IRQ; + } + } + + if (priv->features & FEATURE_IRQ) { + init_waitqueue_head(&priv->waitq); + + err = devm_request_irq(&dev->dev, dev->irq, i801_isr, + IRQF_SHARED, + dev_driver_string(&dev->dev), priv); + if (err) { + dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", + dev->irq, err); + priv->features &= ~FEATURE_IRQ; + } + } + dev_info(&dev->dev, "SMBus using %s\n", + priv->features & FEATURE_IRQ ? "PCI interrupt" : "polling"); + + i801_add_tco(priv); + + snprintf(priv->adapter.name, sizeof(priv->adapter.name), + "SMBus I801 adapter at %04lx", priv->smba); + err = i2c_add_adapter(&priv->adapter); + if (err) { + i801_acpi_remove(priv); + return err; + } + + i801_enable_host_notify(&priv->adapter); + + i801_probe_optional_slaves(priv); + /* We ignore errors - multiplexing is optional */ + i801_add_mux(priv); + + pci_set_drvdata(dev, priv); + + dev_pm_set_driver_flags(&dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE); + pm_runtime_set_autosuspend_delay(&dev->dev, 1000); + pm_runtime_use_autosuspend(&dev->dev); + pm_runtime_put_autosuspend(&dev->dev); + pm_runtime_allow(&dev->dev); + dev_info(&dev->dev, "wb-i2c-i801 probe ok.\n"); + + return 0; +} + +static void i801_remove(struct pci_dev *dev) +{ + struct i801_priv *priv = pci_get_drvdata(dev); + + pm_runtime_forbid(&dev->dev); + pm_runtime_get_noresume(&dev->dev); + + i801_disable_host_notify(priv); + i801_del_mux(priv); + i2c_del_adapter(&priv->adapter); + i801_acpi_remove(priv); + pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); + + platform_device_unregister(priv->tco_pdev); + + /* + * do not call pci_disable_device(dev) since it can cause hard hangs on + * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) + */ +} + +static void i801_shutdown(struct pci_dev *dev) +{ + struct i801_priv *priv = pci_get_drvdata(dev); + + /* Restore config registers to avoid hard hang on some systems */ + i801_disable_host_notify(priv); + pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); +} + +#ifdef CONFIG_PM_SLEEP +static int i801_suspend(struct device *dev) +{ + struct i801_priv *priv = dev_get_drvdata(dev); + + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, priv->original_hstcfg); + return 0; +} + +static int i801_resume(struct device *dev) +{ + struct i801_priv *priv = dev_get_drvdata(dev); + + i801_setup_hstcfg(priv); + i801_enable_host_notify(&priv->adapter); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(i801_pm_ops, i801_suspend, i801_resume); + +static struct pci_driver i801_driver = { + .name = "wb_i801_smbus", + .id_table = i801_ids, + .probe = i801_probe, + .remove = i801_remove, + .shutdown = i801_shutdown, + .driver = { + .pm = &i801_pm_ops, + }, +}; + +static int __init i2c_i801_init(void) +{ + if (dmi_name_in_vendors("FUJITSU")) + input_apanel_init(); + return pci_register_driver(&i801_driver); +} + +static void __exit i2c_i801_exit(void) +{ + pci_unregister_driver(&i801_driver); +} + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("I801 SMBus driver"); +MODULE_LICENSE("GPL"); + +module_init(i2c_i801_init); +module_exit(i2c_i801_exit); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.c new file mode 100644 index 000000000000..0859cf16539e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.c @@ -0,0 +1,1343 @@ +/* + * I2C multiplexer + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This module supports the PCA954x series of I2C multiplexer/switch chips + * made by Philips Semiconductors. + * This includes the: + * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547 + * and PCA9548. + * + * 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 . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_i2c_mux_pca954x.h" + +#define PCA954X_MAX_NCHANS 8 +#define PCA954X_IRQ_OFFSET 4 + +#define I2C_RETRY_TIMES 5 +#define I2C_RETRY_WAIT_TIMES 10 /*delay 10ms*/ + +typedef struct pca9548_cfg_info_s { + uint32_t pca9548_base_nr; + uint32_t pca9548_reset_type; + uint32_t rst_delay_b; /* delay time before reset(us) */ + uint32_t rst_delay; /* reset time(us) */ + uint32_t rst_delay_a; /* delay time after reset(us) */ + union { + i2c_attr_t i2c_attr; + gpio_attr_t gpio_attr; + io_attr_t io_attr; + file_attr_t file_attr; + } attr; + bool select_chan_check; + bool close_chan_force_reset; +} pca9548_cfg_info_t; + +int g_pca954x_debug = 0; +int g_pca954x_error = 0; + +module_param(g_pca954x_debug, int, S_IRUGO | S_IWUSR); +module_param(g_pca954x_error, int, S_IRUGO | S_IWUSR); + +#define PCA954X_DEBUG(fmt, args...) do { \ + if (g_pca954x_debug) { \ + printk(KERN_INFO "[PCA95x][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PCA954X_ERROR(fmt, args...) do { \ + if (g_pca954x_error) { \ + printk(KERN_ERR "[PCA95x][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +extern int pca9641_setmuxflag(int nr, int flag); +enum pca_type { + pca_9540, + pca_9542, + pca_9543, + pca_9544, + pca_9545, + pca_9546, + pca_9547, + pca_9548, +}; + +struct chip_desc { + u8 nchans; + u8 enable; /* used for muxes only */ + u8 has_irq; + enum muxtype { + pca954x_ismux = 0, + pca954x_isswi + } muxtype; +}; + +struct pca954x { + const struct chip_desc *chip; + u8 last_chan; /* last register value */ + u8 deselect; + struct i2c_client *client; + struct irq_domain *irq; + unsigned int irq_mask; + raw_spinlock_t lock; + pca9548_cfg_info_t pca9548_cfg_info; /* pca9548 reset cfg */ +}; + +/* Provide specs for the PCA954x types we know about */ +static const struct chip_desc chips[] = { + [pca_9540] = { + .nchans = 2, + .enable = 0x4, + .muxtype = pca954x_ismux, + }, + [pca_9542] = { + .nchans = 2, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + }, + [pca_9543] = { + .nchans = 2, + .has_irq = 1, + .muxtype = pca954x_isswi, + }, + [pca_9544] = { + .nchans = 4, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + }, + [pca_9545] = { + .nchans = 4, + .has_irq = 1, + .muxtype = pca954x_isswi, + }, + [pca_9546] = { + .nchans = 4, + .muxtype = pca954x_isswi, + }, + [pca_9547] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + }, + [pca_9548] = { + .nchans = 8, + .muxtype = pca954x_isswi, + }, +}; + +static const struct i2c_device_id pca954x_id[] = { + { "wb_pca9540", pca_9540 }, + { "wb_pca9542", pca_9542 }, + { "wb_pca9543", pca_9543 }, + { "wb_pca9544", pca_9544 }, + { "wb_pca9545", pca_9545 }, + { "wb_pca9546", pca_9546 }, + { "wb_pca9547", pca_9547 }, + { "wb_pca9548", pca_9548 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pca954x_id); + +#ifdef CONFIG_OF +static const struct of_device_id pca954x_of_match[] = { + { .compatible = "nxp,wb_pca9540", .data = &chips[pca_9540] }, + { .compatible = "nxp,wb_pca9542", .data = &chips[pca_9542] }, + { .compatible = "nxp,wb_pca9543", .data = &chips[pca_9543] }, + { .compatible = "nxp,wb_pca9544", .data = &chips[pca_9544] }, + { .compatible = "nxp,wb_pca9545", .data = &chips[pca_9545] }, + { .compatible = "nxp,wb_pca9546", .data = &chips[pca_9546] }, + { .compatible = "nxp,wb_pca9547", .data = &chips[pca_9547] }, + { .compatible = "nxp,wb_pca9548", .data = &chips[pca_9548] }, + {} +}; +MODULE_DEVICE_TABLE(of, pca954x_of_match); +#endif + +/* 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) +{ + int ret = -ENODEV; + + if (adap->algo->master_xfer) { + struct i2c_msg msg; + char buf[1]; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = 1; + buf[0] = val; + msg.buf = buf; + ret = __i2c_transfer(adap, &msg, 1); + + if (ret >= 0 && ret != 1) + ret = -EREMOTEIO; + } else { + union i2c_smbus_data data; + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_WRITE, + val, I2C_SMBUS_BYTE, &data); + } + return ret; +} + + static int pca954x_reg_read(struct i2c_adapter *adap, + struct i2c_client *client, u8 *val) + { + int ret = -ENODEV; + u8 tmp_val; + + if (adap->algo->master_xfer) { + struct i2c_msg msg; + + msg.addr = client->addr; + msg.flags = I2C_M_RD; + msg.len = 1; + msg.buf = &tmp_val; + ret = __i2c_transfer(adap, &msg, 1); + + if (ret >= 0 && ret != 1) + ret = -EREMOTEIO; + } else { + union i2c_smbus_data data; + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_READ, + 0, I2C_SMBUS_BYTE, &data); + + if (!ret) { + tmp_val = data.byte; + } + } + + *val = tmp_val; + return ret; + } + +static int pca954x_setmuxflag(struct i2c_client *client, int flag) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + + pca9641_setmuxflag(adap->nr, flag); + return 0; +} + +static int pca9548_gpio_init(gpio_attr_t *gpio_attr) +{ + int err; + + if (gpio_attr->gpio_init) { + PCA954X_DEBUG("gpio%d already init, do nothing.\n", gpio_attr->gpio); + return 0; + } + + PCA954X_DEBUG("gpio%d init.\n", gpio_attr->gpio); + err = gpio_request(gpio_attr->gpio, "pca9548_reset"); + if (err) { + goto error; + } + err = gpio_direction_output(gpio_attr->gpio, gpio_attr->reset_off); + if (err) { + gpio_free(gpio_attr->gpio); + goto error; + } + gpio_attr->gpio_init = 1; + return 0; +error: + PCA954X_ERROR("pca9548_gpio_init failed, ret:%d.\n", err); + return err; +} + +static void pca9548_gpio_free(gpio_attr_t *gpio_attr) +{ + if (gpio_attr->gpio_init == 1) { + PCA954X_DEBUG("gpio%d release.\n", gpio_attr->gpio); + gpio_free(gpio_attr->gpio); + gpio_attr->gpio_init = 0; + } +} + +static int pca954x_reset_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + PCA954X_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + PCA954X_ERROR("kernel_read failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int pca954x_reset_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + PCA954X_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + PCA954X_ERROR("kernel_write failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int pca954x_reset_i2c_read(uint32_t bus, uint32_t addr, uint32_t offset_addr, + unsigned char *buf, uint32_t size) +{ + struct file *fp; + struct i2c_client client; + char i2c_path[32]; + int i ,j ; + int rv; + + rv = 0; + mem_clear(i2c_path, sizeof(i2c_path)); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + PCA954X_ERROR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = addr; + for (j = 0 ;j < size ;j++) { + for (i = 0; i < I2C_RETRY_TIMES; i++) { + rv = i2c_smbus_read_byte_data(&client, (offset_addr + j)); + if (rv < 0) { + PCA954X_ERROR("i2c read failed, try again.\n"); + msleep(I2C_RETRY_WAIT_TIMES); + if (i >= (I2C_RETRY_TIMES - 1)) { + goto out; + } + continue; + } + *(buf + j) = (unsigned char)rv; + break; + } + } +out: + filp_close(fp, NULL); + return rv; +} + +static int pca954x_reset_i2c_write(uint32_t bus, uint32_t dev_addr, uint32_t offset_addr, + uint8_t write_buf) +{ + struct file *fp; + struct i2c_client client; + char i2c_path[32]; + int i; + int rv; + + rv = 0; + mem_clear(i2c_path, sizeof(i2c_path)); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + PCA954X_ERROR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = dev_addr; + for (i = 0; i < I2C_RETRY_TIMES; i++) { + rv = i2c_smbus_write_byte_data(&client, offset_addr, write_buf); + if (rv < 0) { + PCA954X_ERROR("i2c write failed, try again.\n"); + msleep(I2C_RETRY_WAIT_TIMES); + if (i >= (I2C_RETRY_TIMES - 1)) { + goto out; + } + continue; + } + break; + } +out: + filp_close(fp, NULL); + return rv; +} + +static void pca954x_close_chan_finally(struct i2c_mux_core * muxc) +{ + struct pca954x *data; + struct i2c_adapter *adapter; + struct i2c_client *client; + int adapter_timeout; + + data = i2c_mux_priv(muxc); + client = data->client; + adapter = muxc->parent; + /* get bus info */ + while (i2c_parent_is_i2c_adapter(adapter)) { + adapter = to_i2c_adapter(adapter->dev.parent); + } + adapter_timeout = adapter->timeout; + adapter->timeout = msecs_to_jiffies(50); + pca954x_reg_write(muxc->parent, client, data->last_chan); + adapter->timeout = adapter_timeout; + + return; +} + +static int pca954x_do_file_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout, err; + struct pca954x *data; + struct i2c_client *client; + pca9548_cfg_info_t *reset_cfg; + file_attr_t *file_attr; + u8 val; + + data = i2c_mux_priv(muxc); + client = data->client; + reset_cfg = &data->pca9548_cfg_info; + file_attr = &reset_cfg->attr.file_attr; + ret = -1; + + PCA954X_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA954X_DEBUG("dev_name:%s, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + file_attr->dev_name, file_attr->offset, file_attr->mask, + file_attr->reset_on, file_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + err = pca954x_reset_file_read(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= ~(file_attr->mask); + val |= file_attr->reset_on; + err = pca954x_reset_file_write(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(file_attr->mask); + val |= file_attr->reset_off; + err = pca954x_reset_file_write(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + err = pca954x_reset_file_read(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= (file_attr->mask); + if (val == file_attr->reset_off) { + ret = 0; + pca954x_close_chan_finally(muxc); + PCA954X_DEBUG("pca954x_do_file_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + if (ret < 0) { + PCA954X_ERROR("pca954x_do_file_reset timeout.\n"); + } +out: + if (err < 0) { + PCA954X_ERROR("pca954x_do_file_reset file rd/wr failed, ret:%d.\n", err); + } + + return ret; +} + +static int pca954x_do_io_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout; + struct pca954x *data; + struct i2c_client *client; + pca9548_cfg_info_t *reset_cfg; + io_attr_t *io_attr; + u8 val; + + data = i2c_mux_priv(muxc); + client = data->client; + reset_cfg = &data->pca9548_cfg_info; + io_attr = &reset_cfg->attr.io_attr; + + PCA954X_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA954X_DEBUG("io_addr:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + io_attr->io_addr, io_attr->mask, io_attr->reset_on, io_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + val = inb(io_attr->io_addr); + val &= ~(io_attr->mask); + val |= io_attr->reset_on; + outb(val, io_attr->io_addr); + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(io_attr->mask); + val |= io_attr->reset_off; + outb(val, io_attr->io_addr); + + ret = -1; + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + val = inb(io_attr->io_addr); + val &= (io_attr->mask); + if (val == io_attr->reset_off) { + ret = 0; + pca954x_close_chan_finally(muxc); + PCA954X_DEBUG("pca954x_do_io_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + + if (ret < 0) { + PCA954X_ERROR("pca954x_do_io_reset timeout.\n"); + } + + return ret; +} + +static int pca954x_do_gpio_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout; + struct pca954x *data; + struct i2c_client *client; + pca9548_cfg_info_t *reset_cfg; + gpio_attr_t *gpio_attr; + u8 val; + + data = i2c_mux_priv(muxc); + client = data->client; + reset_cfg = &data->pca9548_cfg_info; + gpio_attr = &reset_cfg->attr.gpio_attr; + + ret = pca9548_gpio_init(gpio_attr); + if (ret) { + return -1; + } + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + /* reset on */ + __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_on); + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + /* reset off */ + __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_off); + ret = -1; + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + val = __gpio_get_value(gpio_attr->gpio); + if (val == gpio_attr->reset_off) { + ret = 0; + pca954x_close_chan_finally(muxc); + PCA954X_DEBUG("pca954x_do_gpio_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + /* 1MS schedule*/ + schedule(); + } + timeout--; + } + + if (ret < 0) { + PCA954X_ERROR("pca954x_do_gpio_reset timeout.\n"); + } + + pca9548_gpio_free(gpio_attr); + return ret; +} + +static int pca954x_do_i2c_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout, err; + struct pca954x *data; + struct i2c_client *client; + pca9548_cfg_info_t *reset_cfg; + i2c_attr_t *i2c_attr; + u8 val; + + data = i2c_mux_priv(muxc); + client = data->client; + reset_cfg = &data->pca9548_cfg_info; + i2c_attr = &reset_cfg->attr.i2c_attr; + ret = -1; + + PCA954X_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA954X_DEBUG("bus:0x%x, addr:0x%x, reg:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + i2c_attr->i2c_bus, i2c_attr->i2c_addr, i2c_attr->reg_offset, + i2c_attr->mask, i2c_attr->reset_on, i2c_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + err = pca954x_reset_i2c_read(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= ~(i2c_attr->mask); + val |= i2c_attr->reset_on; + err = pca954x_reset_i2c_write(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, val); + if (err < 0) { + goto out; + } + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(i2c_attr->mask); + val |= i2c_attr->reset_off; + err = pca954x_reset_i2c_write(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, val); + if (err < 0) { + goto out; + } + + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + err = pca954x_reset_i2c_read(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= (i2c_attr->mask); + if (val == i2c_attr->reset_off) { + ret = 0; + pca954x_close_chan_finally(muxc); + PCA954X_DEBUG("pca954x_do_i2c_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + if (ret < 0) { + PCA954X_ERROR("pca954x_do_i2c_reset timeout.\n"); + } +out: + if (err < 0) { + PCA954X_ERROR("pca954x_do_i2c_reset i2c op failed, ret:%d.\n", err); + } + return ret; +} + +static int pca954x_do_reset(struct i2c_mux_core *muxc) +{ + int ret; + struct pca954x *data; + + data = i2c_mux_priv(muxc); + if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_NONE) { + ret = -1; + PCA954X_DEBUG("Don't need to reset.\n"); + } else if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_I2C) { + ret = pca954x_do_i2c_reset(muxc); + } else if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_GPIO) { + ret = pca954x_do_gpio_reset(muxc); + } else if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_IO) { + ret = pca954x_do_io_reset(muxc); + } else if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_FILE) { + ret = pca954x_do_file_reset(muxc); + } else { + ret = -1; + PCA954X_ERROR("Unsupport reset type:0x%x.\n", + data->pca9548_cfg_info.pca9548_reset_type); + } + + if (ret < 0) { + PCA954X_ERROR("pca9548_reset_ctrl failed, reset type:%u, ret:%d.\n", + data->pca9548_cfg_info.pca9548_reset_type, ret); + } + return ret; +} + +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; + const struct chip_desc *chip = data->chip; + u8 regval; + int ret = 0; + u8 read_val = 0; + int rv; + + /* we make switches look like muxes, not sure how to be smarter */ + if (chip->muxtype == pca954x_ismux) + regval = chan | chip->enable; + else + regval = 1 << chan; + + /* Only select the channel if its different from the last channel */ + if (data->last_chan != regval) { + pca954x_setmuxflag(client, 0); + ret = pca954x_reg_write(muxc->parent, client, regval); + data->last_chan = ret < 0 ? 0 : regval; + } + + if (data->pca9548_cfg_info.select_chan_check) { /* check chan */ + ret = pca954x_reg_read(muxc->parent, client, &read_val); + /* read failed or chan not open, reset pca9548 */ + if ((ret < 0) || (read_val != data->last_chan)) { + dev_warn(&client->dev, "pca954x open channle %u failed, do reset.\n", chan); + PCA954X_DEBUG("ret = %d, read_val = %d, last_chan = %d.\n", ret, read_val, data->last_chan); + rv = pca954x_do_reset(muxc); + if (rv >= 0) { + PCA954X_DEBUG("pca954x_do_reset success, rv = %d.\n", rv); + } else { + PCA954X_DEBUG("pca954x_do_reset failed, rv = %d.\n", rv); + } + if (ret >= 0) { + ret = -EIO; /* chan not match, return IO error */ + } + } + } + + 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; + int ret, rv; + + /* Deselect active channel */ + data->last_chan = 0; + if (data->pca9548_cfg_info.close_chan_force_reset) { + ret = pca954x_do_reset(muxc); + } else { + ret = pca954x_reg_write(muxc->parent, client, data->last_chan); + if (ret < 0 ) { + + dev_warn(&client->dev, "pca954x close channel %u failed, do reset.\n", chan); + rv = pca954x_do_reset(muxc); + if (rv == 0) { + ret = 0; + } + } + } + + pca954x_setmuxflag(client, 1); + (void)pca954x_reg_write(muxc->parent, client, data->last_chan); + + return ret; + +} + +static irqreturn_t pca954x_irq_handler(int irq, void *dev_id) +{ + struct pca954x *data = dev_id; + unsigned int child_irq; + int ret, i, handled = 0; + + ret = i2c_smbus_read_byte(data->client); + if (ret < 0) + return IRQ_NONE; + + for (i = 0; i < data->chip->nchans; i++) { + if (ret & BIT(PCA954X_IRQ_OFFSET + i)) { + child_irq = irq_linear_revmap(data->irq, i); + handle_nested_irq(child_irq); + handled++; + } + } + return handled ? IRQ_HANDLED : IRQ_NONE; +} + +static void pca954x_irq_mask(struct irq_data *idata) +{ + struct pca954x *data = irq_data_get_irq_chip_data(idata); + unsigned int pos = idata->hwirq; + unsigned long flags; + + raw_spin_lock_irqsave(&data->lock, flags); + + data->irq_mask &= ~BIT(pos); + if (!data->irq_mask) + disable_irq(data->client->irq); + + raw_spin_unlock_irqrestore(&data->lock, flags); +} + +static void pca954x_irq_unmask(struct irq_data *idata) +{ + struct pca954x *data = irq_data_get_irq_chip_data(idata); + unsigned int pos = idata->hwirq; + unsigned long flags; + + raw_spin_lock_irqsave(&data->lock, flags); + + if (!data->irq_mask) + enable_irq(data->client->irq); + data->irq_mask |= BIT(pos); + + raw_spin_unlock_irqrestore(&data->lock, flags); +} + +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_mask = pca954x_irq_mask, + .irq_unmask = pca954x_irq_unmask, + .irq_set_type = pca954x_irq_set_type, +}; + +static int of_pca954x_irq_setup(struct i2c_mux_core *muxc) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int c, err, 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); + irq_set_chip_data(irq, data); + irq_set_chip_and_handler(irq, &pca954x_irq_chip, + handle_simple_irq); + } + + err = devm_request_threaded_irq(&client->dev, data->client->irq, NULL, + pca954x_irq_handler, + IRQF_ONESHOT | IRQF_SHARED, + "pca954x", data); + if (err) + goto err_req_irq; + + disable_irq(data->client->irq); + + return 0; +err_req_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); + + return err; +} + +static int pca954x_irq_setup(struct i2c_mux_core *muxc) +{ + return 0; +} + +static int of_pca954x_reset_data_init(struct pca954x *data) +{ + int err; + struct device *dev = &data->client->dev; + pca9548_cfg_info_t *reset_cfg; + + reset_cfg = &data->pca9548_cfg_info; + if (dev == NULL || dev->of_node == NULL) { + PCA954X_DEBUG("dev or dev->of_node is NUll, no reset.\n"); + reset_cfg->pca9548_reset_type = PCA9548_RESET_NONE; + return 0; + } + + reset_cfg->select_chan_check = of_property_read_bool(dev->of_node, "select_chan_check"); + reset_cfg->close_chan_force_reset = of_property_read_bool(dev->of_node, "close_chan_force_reset"); + PCA954X_DEBUG("select_chan_check:%d, close_chan_force_reset:%d.\n", reset_cfg->select_chan_check, + reset_cfg->close_chan_force_reset); + + if (of_property_read_u32(dev->of_node, "pca9548_reset_type", &reset_cfg->pca9548_reset_type)) { + + PCA954X_DEBUG("pca9548_reset_type not found, no reset.\n"); + reset_cfg->pca9548_reset_type = PCA9548_RESET_NONE; + return 0; + } + err = of_property_read_u32(dev->of_node, "rst_delay_b", &reset_cfg->rst_delay_b); + err |= of_property_read_u32(dev->of_node, "rst_delay", &reset_cfg->rst_delay); + err |= of_property_read_u32(dev->of_node, "rst_delay_a", &reset_cfg->rst_delay_a); + + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("reset_type:0x%x, rst_delay_b:0x%x, rst_delay:0x%x, rst_delay_a:0x%x.\n", + reset_cfg->pca9548_reset_type, reset_cfg->rst_delay_b, + reset_cfg->rst_delay, reset_cfg->rst_delay_a); + + if (reset_cfg->pca9548_reset_type == PCA9548_RESET_I2C) { + + PCA954X_DEBUG("reset by i2c.\n"); + err = of_property_read_u32(dev->of_node, "i2c_bus", &reset_cfg->attr.i2c_attr.i2c_bus); + err |=of_property_read_u32(dev->of_node, "i2c_addr", &reset_cfg->attr.i2c_attr.i2c_addr); + err |=of_property_read_u32(dev->of_node, "reg_offset", &reset_cfg->attr.i2c_attr.reg_offset); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.i2c_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.i2c_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.i2c_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("bus:%u, addr:0x%x, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + reset_cfg->attr.i2c_attr.i2c_bus, reset_cfg->attr.i2c_attr.i2c_addr, + reset_cfg->attr.i2c_attr.reg_offset, reset_cfg->attr.i2c_attr.mask, + reset_cfg->attr.i2c_attr.reset_on, reset_cfg->attr.i2c_attr.reset_off); + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_GPIO) { + + PCA954X_DEBUG("reset by gpio.\n"); + err = of_property_read_u32(dev->of_node, "gpio", &reset_cfg->attr.gpio_attr.gpio); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.gpio_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.gpio_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("gpio number:%u, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.gpio_attr.gpio, reset_cfg->attr.gpio_attr.reset_on, + reset_cfg->attr.gpio_attr.reset_off); + reset_cfg->attr.gpio_attr.gpio_init = 0; + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_IO) { + + PCA954X_DEBUG("reset by io.\n"); + err = of_property_read_u32(dev->of_node, "io_addr", &reset_cfg->attr.io_attr.io_addr); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.io_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.io_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.io_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("io_addr:0x%x, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.io_attr.io_addr, reset_cfg->attr.io_attr.mask, + reset_cfg->attr.io_attr.reset_on, reset_cfg->attr.io_attr.reset_off); + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_FILE) { + + PCA954X_DEBUG("reset by file.\n"); + err = of_property_read_string(dev->of_node, "dev_name", &reset_cfg->attr.file_attr.dev_name); + err |=of_property_read_u32(dev->of_node, "offset", &reset_cfg->attr.file_attr.offset); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.file_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.file_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.file_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("dev_name:%s, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.file_attr.dev_name, reset_cfg->attr.file_attr.mask, + reset_cfg->attr.file_attr.reset_on, reset_cfg->attr.file_attr.reset_off); + } else { + PCA954X_ERROR("Unsupport reset type:%d.\n", reset_cfg->pca9548_reset_type); + goto dts_config_err; + } + return 0; +dts_config_err: + PCA954X_ERROR("dts config error, ret:%d.\n", err); + return -EINVAL; +} + +static int pca954x_reset_data_init(struct pca954x *data) +{ + pca9548_cfg_info_t *reset_cfg; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device; + + if (data->client->dev.platform_data == NULL) { + PCA954X_DEBUG("pca954x has no reset platform data config.\n"); + return 0; + } + reset_cfg = &data->pca9548_cfg_info; + i2c_mux_pca954x_device = data->client->dev.platform_data; + reset_cfg->select_chan_check = i2c_mux_pca954x_device->select_chan_check; + reset_cfg->close_chan_force_reset = i2c_mux_pca954x_device->close_chan_force_reset; + PCA954X_DEBUG("select_chan_check:%d, close_chan_force_reset:%d.\n", reset_cfg->select_chan_check, + reset_cfg->close_chan_force_reset); + + reset_cfg->pca9548_reset_type = i2c_mux_pca954x_device->pca9548_reset_type; + if (reset_cfg->pca9548_reset_type == PCA9548_RESET_NONE) { + PCA954X_DEBUG("pca9548_reset_type not found, no reset.\n"); + return 0; + } + + reset_cfg->rst_delay_b = i2c_mux_pca954x_device->rst_delay_b; + reset_cfg->rst_delay = i2c_mux_pca954x_device->rst_delay; + reset_cfg->rst_delay_a = i2c_mux_pca954x_device->rst_delay_a; + PCA954X_DEBUG("reset_type:0x%x, rst_delay_b:0x%x, rst_delay:0x%x, rst_delay_a:0x%x.\n", + reset_cfg->pca9548_reset_type, reset_cfg->rst_delay_b, + reset_cfg->rst_delay, reset_cfg->rst_delay_a); + + if (reset_cfg->pca9548_reset_type == PCA9548_RESET_I2C) { + + PCA954X_DEBUG("reset by i2c.\n"); + reset_cfg->attr.i2c_attr.i2c_bus = i2c_mux_pca954x_device->attr.i2c_attr.i2c_bus; + reset_cfg->attr.i2c_attr.i2c_addr = i2c_mux_pca954x_device->attr.i2c_attr.i2c_addr; + reset_cfg->attr.i2c_attr.reg_offset = i2c_mux_pca954x_device->attr.i2c_attr.reg_offset; + reset_cfg->attr.i2c_attr.mask = i2c_mux_pca954x_device->attr.i2c_attr.mask; + reset_cfg->attr.i2c_attr.reset_on = i2c_mux_pca954x_device->attr.i2c_attr.reset_on; + reset_cfg->attr.i2c_attr.reset_off = i2c_mux_pca954x_device->attr.i2c_attr.reset_off; + PCA954X_DEBUG("bus:%u, addr:0x%x, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + reset_cfg->attr.i2c_attr.i2c_bus, reset_cfg->attr.i2c_attr.i2c_addr, + reset_cfg->attr.i2c_attr.reg_offset, reset_cfg->attr.i2c_attr.mask, + reset_cfg->attr.i2c_attr.reset_on, reset_cfg->attr.i2c_attr.reset_off); + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_GPIO) { + + PCA954X_DEBUG("reset by gpio.\n"); + reset_cfg->attr.gpio_attr.gpio = i2c_mux_pca954x_device->attr.gpio_attr.gpio; + reset_cfg->attr.gpio_attr.reset_on = i2c_mux_pca954x_device->attr.gpio_attr.reset_on; + reset_cfg->attr.gpio_attr.reset_off = i2c_mux_pca954x_device->attr.gpio_attr.reset_off; + PCA954X_DEBUG("gpio number:%u, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.gpio_attr.gpio, reset_cfg->attr.gpio_attr.reset_on, + reset_cfg->attr.gpio_attr.reset_off); + reset_cfg->attr.gpio_attr.gpio_init = 0; + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_IO) { + + PCA954X_DEBUG("reset by io.\n"); + reset_cfg->attr.io_attr.io_addr = i2c_mux_pca954x_device->attr.io_attr.io_addr; + reset_cfg->attr.io_attr.mask = i2c_mux_pca954x_device->attr.io_attr.mask; + reset_cfg->attr.io_attr.reset_on = i2c_mux_pca954x_device->attr.io_attr.reset_on; + reset_cfg->attr.io_attr.reset_off = i2c_mux_pca954x_device->attr.io_attr.reset_off; + PCA954X_DEBUG("io_addr:0x%x, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.io_attr.io_addr, reset_cfg->attr.io_attr.mask, + reset_cfg->attr.io_attr.reset_on, reset_cfg->attr.io_attr.reset_off); + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_FILE) { + + reset_cfg->attr.file_attr.dev_name = i2c_mux_pca954x_device->attr.file_attr.dev_name; + reset_cfg->attr.file_attr.offset = i2c_mux_pca954x_device->attr.file_attr.offset; + reset_cfg->attr.file_attr.mask = i2c_mux_pca954x_device->attr.file_attr.mask; + reset_cfg->attr.file_attr.reset_on = i2c_mux_pca954x_device->attr.file_attr.reset_on; + reset_cfg->attr.file_attr.reset_off = i2c_mux_pca954x_device->attr.file_attr.reset_off; + PCA954X_DEBUG("dev_name:%s, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.file_attr.dev_name, reset_cfg->attr.file_attr.mask, + reset_cfg->attr.file_attr.reset_on, reset_cfg->attr.file_attr.reset_off); + } else { + PCA954X_ERROR("Unsupport reset type:%d.\n", reset_cfg->pca9548_reset_type); + return -EINVAL; + } + return 0; +} + +/* + * I2C init/probing/exit functions + */ +static int pca954x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + struct device_node *of_node = client->dev.of_node; + bool idle_disconnect_dt; + struct gpio_desc *gpio; + int num, force, class; + struct i2c_mux_core *muxc; + struct pca954x *data; + const struct of_device_id *match; + unsigned int probe_disable; + int ret, dynamic_nr; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device; + + PCA954X_DEBUG("pca954x_probe, parent bus: %d, 9548 addr:0x%x.\n", adap->nr, client->addr); + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + + muxc = i2c_mux_alloc(adap, &client->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; + + /* Get the mux out of reset if a reset GPIO is specified. */ + gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + + /* check device connection status */ + + if (client->dev.of_node == NULL) { + if (client->dev.platform_data == NULL) { + probe_disable = 1; + PCA954X_DEBUG("has no platform data config, set probe_disable = 1.\n"); + } else { + i2c_mux_pca954x_device = client->dev.platform_data; + probe_disable = i2c_mux_pca954x_device->probe_disable; + } + } else { + probe_disable = of_property_read_bool(of_node, "probe_disable"); + } + + /* Write the mux register at addr to verify + * that the mux is in fact present. This also + * initializes the mux to disconnected state. + */ + if (!probe_disable && (i2c_smbus_write_byte(client, 0) < 0)) { + dev_warn(&client->dev, "probe failed\n"); + return -ENODEV; + } + + match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev); + if (match) + data->chip = of_device_get_match_data(&client->dev); + else + data->chip = &chips[id->driver_data]; + + data->last_chan = 0; /* force the first selection */ + + if (client->dev.of_node == NULL) { + idle_disconnect_dt = false; + } else { + idle_disconnect_dt = of_node && + of_property_read_bool(of_node, "i2c-mux-idle-disconnect"); + } + + if (client->dev.of_node) { + ret= of_pca954x_reset_data_init(data); + } else { + ret= pca954x_reset_data_init(data); + } + if (ret < 0) { + dev_err(&client->dev, "pca954x reset config err, ret:%d.\n", ret); + return ret; + } + + if (client->dev.of_node) { + ret = of_pca954x_irq_setup(muxc); + } else { + ret = pca954x_irq_setup(muxc); + } + if (ret) { + goto fail_del_adapters; + } + + if (client->dev.of_node == NULL) { + if (client->dev.platform_data == NULL) { + dynamic_nr = 1; + PCA954X_DEBUG("platform data is NULL, use dynamic adap number.\n"); + } else { + i2c_mux_pca954x_device = client->dev.platform_data; + data->pca9548_cfg_info.pca9548_base_nr = i2c_mux_pca954x_device->pca9548_base_nr; + if (data->pca9548_cfg_info.pca9548_base_nr == 0) { + dynamic_nr = 1; + PCA954X_DEBUG("pca9548_base_nr = 0, use dynamic adap number.\n"); + } else { + dynamic_nr = 0; + PCA954X_DEBUG("pca9548_base_nr:%u.\n", data->pca9548_cfg_info.pca9548_base_nr); + } + } + } else { + if (of_property_read_u32(of_node, "pca9548_base_nr", &data->pca9548_cfg_info.pca9548_base_nr)) { + + dynamic_nr = 1; + PCA954X_DEBUG("pca9548_base_nr not found, use dynamic adap number"); + } else { + dynamic_nr = 0; + PCA954X_DEBUG("pca9548_base_nr:%u.\n", data->pca9548_cfg_info.pca9548_base_nr); + } + } + + /* Now create an adapter for each channel */ + for (num = 0; num < data->chip->nchans; num++) { + bool idle_disconnect_pd = false; + if (dynamic_nr == 1) { + force = 0; /* dynamic adap number */ + } else { + force = data->pca9548_cfg_info.pca9548_base_nr + num; + } + + class = 0; /* no class by default */ + data->deselect |= (idle_disconnect_pd || + idle_disconnect_dt) << num; + + ret = i2c_mux_add_adapter(muxc, force, num, class); + if (ret) + goto fail_del_adapters; + } + + dev_info(&client->dev, + "registered %d multiplexed busses for I2C %s %s\n", + num, data->chip->muxtype == pca954x_ismux + ? "mux" : "switch", client->name); + + return 0; + +fail_del_adapters: + i2c_mux_del_adapters(muxc); + return ret; +} + +static int pca954x_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + 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); + 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); + + data->last_chan = 0; + return i2c_smbus_write_byte(client, 0); +} +#endif + +static SIMPLE_DEV_PM_OPS(pca954x_pm, NULL, pca954x_resume); + +static struct i2c_driver pca954x_driver = { + .driver = { + .name = "wb_pca954x", + .pm = &pca954x_pm, + .of_match_table = of_match_ptr(pca954x_of_match), + }, + .probe = pca954x_probe, + .remove = pca954x_remove, + .id_table = pca954x_id, +}; + +module_i2c_driver(pca954x_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PCA954x I2C mux/switch driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.h new file mode 100644 index 000000000000..9cbe162782c5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.h @@ -0,0 +1,67 @@ +#ifndef __WB_I2C_MUX_PCA954X_H__ +#define __WB_I2C_MUX_PCA954X_H__ + +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef enum pca9548_reset_type_s { + PCA9548_RESET_NONE = 0, + PCA9548_RESET_I2C = 1, + PCA9548_RESET_GPIO = 2, + PCA9548_RESET_IO = 3, + PCA9548_RESET_FILE = 4, +} pca9548_reset_type_t; + +typedef struct i2c_attr_s { + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t reg_offset; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} i2c_attr_t; + +typedef struct io_attr_s { + uint32_t io_addr; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} io_attr_t; + +typedef struct file_attr_s { + const char *dev_name; + uint32_t offset; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} file_attr_t; + +typedef struct gpio_attr_s { + int gpio_init; + uint32_t gpio; + uint32_t reset_on; + uint32_t reset_off; +} gpio_attr_t; + +typedef struct i2c_mux_pca954x_device_s { + struct i2c_client *client; + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t pca9548_base_nr; + uint32_t pca9548_reset_type; + uint32_t rst_delay_b; /* delay time before reset(us) */ + uint32_t rst_delay; /* reset time(us) */ + uint32_t rst_delay_a; /* delay time after reset(us) */ + bool probe_disable; + bool select_chan_check; + bool close_chan_force_reset; + union { + i2c_attr_t i2c_attr; + gpio_attr_t gpio_attr; + io_attr_t io_attr; + file_attr_t file_attr; + } attr; +} i2c_mux_pca954x_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.c new file mode 100644 index 000000000000..9945f6fcad25 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.c @@ -0,0 +1,1375 @@ +/* + * I2C multiplexer driver for PCA9541 bus master selector + * + * Copyright (c) 2010 Ericsson AB. + * + * Author: Guenter Roeck + * + * Derived from: + * pca954x.c + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_i2c_mux_pca9641.h" + +/* + * The PCA9541 is a bus master selector. It supports two I2C masters connected + * to a single slave bus. + * + * Before each bus transaction, a master has to acquire bus ownership. After the + * transaction is complete, bus ownership has to be released. This fits well + * into the I2C multiplexer framework, which provides select and release + * functions for this purpose. For this reason, this driver is modeled as + * single-channel I2C bus multiplexer. + * + * This driver assumes that the two bus masters are controlled by two different + * hosts. If a single host controls both masters, platform code has to ensure + * that only one of the masters is instantiated at any given time. + */ + +#define PCA9541_CONTROL 0x01 +#define PCA9541_ISTAT 0x02 + +#define PCA9541_CTL_MYBUS (1 << 0) +#define PCA9541_CTL_NMYBUS (1 << 1) +#define PCA9541_CTL_BUSON (1 << 2) +#define PCA9541_CTL_NBUSON (1 << 3) +#define PCA9541_CTL_BUSINIT (1 << 4) +#define PCA9541_CTL_TESTON (1 << 6) +#define PCA9541_CTL_NTESTON (1 << 7) +#define PCA9541_ISTAT_INTIN (1 << 0) +#define PCA9541_ISTAT_BUSINIT (1 << 1) +#define PCA9541_ISTAT_BUSOK (1 << 2) +#define PCA9541_ISTAT_BUSLOST (1 << 3) +#define PCA9541_ISTAT_MYTEST (1 << 6) +#define PCA9541_ISTAT_NMYTEST (1 << 7) +#define PCA9641_ID 0x00 +#define PCA9641_ID_MAGIC 0x38 +#define PCA9641_CONTROL 0x01 +#define PCA9641_STATUS 0x02 +#define PCA9641_TIME 0x03 +#define PCA9641_CTL_LOCK_REQ BIT(0) +#define PCA9641_CTL_LOCK_GRANT BIT(1) +#define PCA9641_CTL_BUS_CONNECT BIT(2) +#define PCA9641_CTL_BUS_INIT BIT(3) +#define PCA9641_CTL_SMBUS_SWRST BIT(4) +#define PCA9641_CTL_IDLE_TIMER_DIS BIT(5) +#define PCA9641_CTL_SMBUS_DIS BIT(6) +#define PCA9641_CTL_PRIORITY BIT(7) +#define PCA9641_STS_OTHER_LOCK BIT(0) +#define PCA9641_STS_BUS_INIT_FAIL BIT(1) +#define PCA9641_STS_BUS_HUNG BIT(2) +#define PCA9641_STS_MBOX_EMPTY BIT(3) +#define PCA9641_STS_MBOX_FULL BIT(4) +#define PCA9641_STS_TEST_INT BIT(5) +#define PCA9641_STS_SCL_IO BIT(6) +#define PCA9641_STS_SDA_IO BIT(7) +#define PCA9641_RES_TIME 0x03 +#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) +#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) +#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) +#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) +#define BUSOFF(x, y) (!((x) & PCA9641_CTL_LOCK_GRANT) && \ + !((y) & PCA9641_STS_OTHER_LOCK)) +#define other_lock(x) ((x) & PCA9641_STS_OTHER_LOCK) +#define lock_grant(x) ((x) & PCA9641_CTL_LOCK_GRANT) + +#define PCA9641_RETRY_TIME (8) +#define PCA9641_RESET_DELAY (150) + +typedef struct i2c_muxs_struct_flag +{ + int nr; + char name[48]; + struct mutex update_lock; + int flag; +}i2c_mux_flag; + +i2c_mux_flag pca_flag = { + .flag = -1, +}; + +int pca9641_setmuxflag(int nr, int flag) +{ + if (pca_flag.nr == nr) { + pca_flag.flag = flag; + } + return 0; +} +EXPORT_SYMBOL(pca9641_setmuxflag); + +static int g_debug_info = 0; +static int g_debug_err = 0; + +module_param(g_debug_info, int, S_IRUGO | S_IWUSR); +module_param(g_debug_err, int, S_IRUGO | S_IWUSR); + +#define PCA_DEBUG(fmt, args...) do { \ + if (g_debug_info) { \ + printk(KERN_INFO "[pca9641][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PCA_DEBUG_ERR(fmt, args...) do { \ + if (g_debug_err) { \ + printk(KERN_ERR "[pca9641][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* arbitration timeouts, in jiffies */ +#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */ +#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */ + +/* arbitration retry delays, in us */ +#define SELECT_DELAY_SHORT 50 +#define SELECT_DELAY_LONG 1000 +#define I2C_RETRY_TIMES (5) +#define I2C_RETRY_WAIT_TIMES (10) /*delay 10ms*/ + +typedef struct pca9641_cfg_info_s { + uint32_t pca9641_reset_type; + uint32_t rst_delay_b; /* delay time before reset(us) */ + uint32_t rst_delay; /* reset time(us) */ + uint32_t rst_delay_a; /* delay time after reset(us) */ + union { + i2c_attr_t i2c_attr; + gpio_attr_t gpio_attr; + io_attr_t io_attr; + file_attr_t file_attr; + } attr; +} pca9641_cfg_info_t; + +struct pca9541 { + struct i2c_client *client; + unsigned long select_timeout; + unsigned long arb_timeout; + uint32_t pca9641_nr; + pca9641_cfg_info_t pca9641_cfg_info; /* pca9641 reset cfg */ +}; + +static const struct i2c_device_id pca9541_id[] = { + {"wb_pca9541", 0}, + {"wb_pca9641", 1}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pca9541_id); + +#ifdef CONFIG_OF +static const struct of_device_id pca9541_of_match[] = { + { .compatible = "nxp,wb_pca9541" }, + { .compatible = "nxp,wb_pca9641" }, + {} +}; +MODULE_DEVICE_TABLE(of, pca9541_of_match); +#endif + +static int pca9641_gpio_init(gpio_attr_t *gpio_attr) +{ + int err; + + if (gpio_attr->gpio_init) { + PCA_DEBUG("gpio%d already init, do nothing.\n", gpio_attr->gpio); + return 0; + } + + PCA_DEBUG("gpio%d init.\n", gpio_attr->gpio); + err = gpio_request(gpio_attr->gpio, "pca9641_reset"); + if (err) { + goto error; + } + err = gpio_direction_output(gpio_attr->gpio, gpio_attr->reset_off); + if (err) { + gpio_free(gpio_attr->gpio); + goto error; + } + gpio_attr->gpio_init = 1; + return 0; +error: + PCA_DEBUG_ERR("pca9641_gpio_init failed, ret:%d.\n", err); + return err; +} + +static void pca9641_gpio_free(gpio_attr_t *gpio_attr) +{ + if (gpio_attr->gpio_init == 1) { + PCA_DEBUG("gpio%d release.\n", gpio_attr->gpio); + gpio_free(gpio_attr->gpio); + gpio_attr->gpio_init = 0; + } + return; +} + +static int pca9641_reset_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + PCA_DEBUG_ERR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + PCA_DEBUG_ERR("kernel_read failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int pca9641_reset_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + PCA_DEBUG_ERR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + PCA_DEBUG_ERR("kernel_write failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int pca9641_reset_i2c_read(uint32_t bus, uint32_t addr, uint32_t offset_addr, + unsigned char *buf, uint32_t size) +{ + struct file *fp; + struct i2c_client client; + char i2c_path[32]; + int i, j; + int rv; + + rv = 0; + mem_clear(i2c_path, sizeof(i2c_path)); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + PCA_DEBUG_ERR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = addr; + for (j = 0; j < size; j++) { + for (i = 0; i < I2C_RETRY_TIMES; i++) { + rv = i2c_smbus_read_byte_data(&client, (offset_addr + j)); + if (rv < 0) { + PCA_DEBUG_ERR("i2c read failed, try again.\n"); + msleep(I2C_RETRY_WAIT_TIMES); + if (i >= (I2C_RETRY_TIMES - 1)) { + goto out; + } + continue; + } + *(buf + j) = (unsigned char)rv; + break; + } + } +out: + filp_close(fp, NULL); + return rv; +} + +static int pca9641_reset_i2c_write(uint32_t bus, uint32_t dev_addr, uint32_t offset_addr, + uint8_t write_buf) +{ + struct file *fp; + struct i2c_client client; + char i2c_path[32]; + int i; + int rv; + + rv = 0; + mem_clear(i2c_path, sizeof(i2c_path)); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + PCA_DEBUG_ERR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = dev_addr; + for (i = 0; i < I2C_RETRY_TIMES; i++) { + rv = i2c_smbus_write_byte_data(&client, offset_addr, write_buf); + if (rv < 0) { + PCA_DEBUG_ERR("i2c write failed, try again.\n"); + msleep(I2C_RETRY_WAIT_TIMES); + if (i >= (I2C_RETRY_TIMES - 1)) { + goto out; + } + continue; + } + break; + } +out: + filp_close(fp, NULL); + return rv; +} + +static int pca9641_do_file_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout, err; + struct pca9541 *data; + pca9641_cfg_info_t *reset_cfg; + file_attr_t *file_attr; + u8 val; + + data = i2c_mux_priv(muxc); + reset_cfg = &data->pca9641_cfg_info; + file_attr = &reset_cfg->attr.file_attr; + ret = -1; + + PCA_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA_DEBUG("dev_name:%s, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + file_attr->dev_name, file_attr->offset, file_attr->mask, + file_attr->reset_on, file_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + err = pca9641_reset_file_read(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + val &= ~(file_attr->mask); + val |= file_attr->reset_on; + err = pca9641_reset_file_write(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(file_attr->mask); + val |= file_attr->reset_off; + err = pca9641_reset_file_write(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + err = pca9641_reset_file_read(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= (file_attr->mask); + if (val == file_attr->reset_off) { + ret = 0; + PCA_DEBUG("pca9641_do_file_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_do_file_reset timeout.\n"); + } +out: + if (err < 0) { + PCA_DEBUG_ERR("pca9641_do_file_reset file rd/wr failed, ret:%d.\n", err); + } + + return ret; +} + +static int pca9641_do_io_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout; + struct pca9541 *data; + pca9641_cfg_info_t *reset_cfg; + io_attr_t *io_attr; + u8 val; + + data = i2c_mux_priv(muxc); + reset_cfg = &data->pca9641_cfg_info; + io_attr = &reset_cfg->attr.io_attr; + + PCA_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA_DEBUG("io_addr:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + io_attr->io_addr, io_attr->mask, io_attr->reset_on, io_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + val = inb(io_attr->io_addr); + val &= ~(io_attr->mask); + val |= io_attr->reset_on; + outb(val, io_attr->io_addr); + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(io_attr->mask); + val |= io_attr->reset_off; + outb(val, io_attr->io_addr); + + ret = -1; + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + val = inb(io_attr->io_addr); + val &= (io_attr->mask); + if (val == io_attr->reset_off) { + ret = 0; + PCA_DEBUG("pca9641_do_io_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_do_io_reset timeout.\n"); + } + + return ret; +} + +static int pca9641_do_gpio_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout; + struct pca9541 *data; + pca9641_cfg_info_t *reset_cfg; + gpio_attr_t *gpio_attr; + u8 val; + + data = i2c_mux_priv(muxc); + reset_cfg = &data->pca9641_cfg_info; + gpio_attr = &reset_cfg->attr.gpio_attr; + + ret = pca9641_gpio_init(gpio_attr); + if (ret) { + return -1; + } + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_on); + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_off); + ret = -1; + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + val = __gpio_get_value(gpio_attr->gpio); + if (val == gpio_attr->reset_off) { + ret = 0; + PCA_DEBUG("pca9641_do_gpio_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + /* 1MS schedule*/ + schedule(); + } + timeout--; + } + + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_do_gpio_reset timeout.\n"); + } + + pca9641_gpio_free(gpio_attr); + return ret; +} + +static int pca9641_do_i2c_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout, err; + struct pca9541 *data; + pca9641_cfg_info_t *reset_cfg; + i2c_attr_t *i2c_attr; + u8 val; + + data = i2c_mux_priv(muxc); + reset_cfg = &data->pca9641_cfg_info; + i2c_attr = &reset_cfg->attr.i2c_attr; + ret = -1; + + PCA_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA_DEBUG("bus:0x%x, addr:0x%x, reg:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + i2c_attr->i2c_bus, i2c_attr->i2c_addr, i2c_attr->reg_offset, + i2c_attr->mask, i2c_attr->reset_on, i2c_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + err = pca9641_reset_i2c_read(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + val &= ~(i2c_attr->mask); + val |= i2c_attr->reset_on; + err = pca9641_reset_i2c_write(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, val); + if (err < 0) { + goto out; + } + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(i2c_attr->mask); + val |= i2c_attr->reset_off; + err = pca9641_reset_i2c_write(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, val); + if (err < 0) { + goto out; + } + + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + err = pca9641_reset_i2c_read(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= (i2c_attr->mask); + if (val == i2c_attr->reset_off) { + ret = 0; + PCA_DEBUG("pca9641_do_i2c_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_do_i2c_reset timeout.\n"); + } +out: + if (err < 0) { + PCA_DEBUG_ERR("pca9641_do_i2c_reset i2c op failed, ret:%d.\n", err); + } + return ret; +} + +static int pca9641_do_reset(struct i2c_mux_core *muxc) +{ + int ret; + struct pca9541 *data; + + data = i2c_mux_priv(muxc); + if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_NONE) { + ret = -1; + PCA_DEBUG("Don't need to reset.\n"); + } else if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_I2C) { + ret = pca9641_do_i2c_reset(muxc); + } else if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_GPIO) { + ret = pca9641_do_gpio_reset(muxc); + } else if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_IO) { + ret = pca9641_do_io_reset(muxc); + } else if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_FILE) { + ret = pca9641_do_file_reset(muxc); + } else { + ret = -1; + PCA_DEBUG_ERR("Unsupport reset type:0x%x.\n", + data->pca9641_cfg_info.pca9641_reset_type); + } + + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_reset_ctrl failed, reset type:%u, ret:%d.\n", + data->pca9641_cfg_info.pca9641_reset_type, ret); + } else { + udelay(PCA9641_RESET_DELAY); + } + return ret; +} + +/* + * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock the adapter a second time. + */ +static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val) +{ + struct i2c_adapter *adap = client->adapter; + int ret; + + if (adap->algo->master_xfer) { + struct i2c_msg msg; + char buf[2]; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = 2; + buf[0] = command; + buf[1] = val; + msg.buf = buf; + ret = __i2c_transfer(adap, &msg, 1); + } else { + union i2c_smbus_data data; + + data.byte = val; + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_WRITE, + command, + I2C_SMBUS_BYTE_DATA, &data); + } + + return ret; +} + +/* + * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock adapter a second time. + */ +static int pca9541_reg_read(struct i2c_client *client, u8 command) +{ + struct i2c_adapter *adap = client->adapter; + int ret; + u8 val; + + if (adap->algo->master_xfer) { + struct i2c_msg msg[2] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &command + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = &val + } + }; + ret = __i2c_transfer(adap, msg, 2); + if (ret == 2) + ret = val; + else if (ret >= 0) + ret = -EIO; + } else { + union i2c_smbus_data data; + + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_READ, + command, + I2C_SMBUS_BYTE_DATA, &data); + if (!ret) + ret = data.byte; + } + return ret; +} + +/* + * Arbitration management functions + */ + +/* Release bus. Also reset NTESTON and BUSINIT if it was set. */ +static void pca9541_release_bus(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg >= 0 && !busoff(reg) && mybus(reg)) + pca9541_reg_write(client, PCA9541_CONTROL, + (reg & PCA9541_CTL_NBUSON) >> 1); +} + +/* + * Arbitration is defined as a two-step process. A bus master can only activate + * the slave bus if it owns it; otherwise it has to request ownership first. + * This multi-step process ensures that access contention is resolved + * gracefully. + * + * Bus Ownership Other master Action + * state requested access + * ---------------------------------------------------- + * off - yes wait for arbitration timeout or + * for other master to drop request + * off no no take ownership + * off yes no turn on bus + * on yes - done + * on no - wait for arbitration timeout or + * for other master to release bus + * + * The main contention point occurs if the slave bus is off and both masters + * request ownership at the same time. In this case, one master will turn on + * the slave bus, believing that it owns it. The other master will request + * bus ownership. Result is that the bus is turned on, and master which did + * _not_ own the slave bus before ends up owning it. + */ + +/* Control commands per PCA9541 datasheet */ +static const u8 pca9541_control[16] = { + 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1 +}; + +/* + * Channel arbitration + * + * Return values: + * <0: error + * 0 : bus not acquired + * 1 : bus acquired + */ +static int pca9541_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg < 0) + return reg; + + if (busoff(reg)) { + int istat; + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + istat = pca9541_reg_read(client, PCA9541_ISTAT); + if (!(istat & PCA9541_ISTAT_NMYTEST) + || time_is_before_eq_jiffies(data->arb_timeout)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_NTESTON); + data->select_timeout = SELECT_DELAY_SHORT; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (mybus(reg)) { + /* + * Bus is on, and we own it. We are done with acquisition. + * Reset NTESTON and BUSINIT, then return success. + */ + if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg & ~(PCA9541_CTL_NTESTON + | PCA9541_CTL_BUSINIT)); + return 1; + } else { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + data->select_timeout = SELECT_DELAY_LONG; + if (time_is_before_eq_jiffies(data->arb_timeout)) { + /* Time is up, take the bus and reset it. */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_BUSINIT + | PCA9541_CTL_NTESTON); + } else { + /* Request bus ownership if needed */ + if (!(reg & PCA9541_CTL_NTESTON)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg | PCA9541_CTL_NTESTON); + } + } + return 0; +} + +static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + + do { + ret = pca9541_arbitrate(client); + if (ret) + return ret < 0 ? ret : 0; + + if (data->select_timeout == SELECT_DELAY_SHORT) + udelay(data->select_timeout); + else + msleep(data->select_timeout / 1000); + } while (time_is_after_eq_jiffies(timeout)); + + dev_warn(&client->dev, "pca9541 select channel timeout.\n"); + return -ETIMEDOUT; +} + +static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + pca9541_release_bus(client); + return 0; +} + +/* +* Arbitration management functions +*/ +static void pca9641_release_bus(struct i2c_client *client) +{ + pca9541_reg_write(client, PCA9641_CONTROL, 0x80); //master 0x80 +} + +/* +* Channel arbitration +* +* Return values: +* <0: error +* 0 : bus not acquired +* 1 : bus acquired +*/ +static int pca9641_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg_ctl, reg_sts; + + reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); + if (reg_ctl < 0) { + PCA_DEBUG_ERR("pca9641 read control register failed, ret:%d.\n", reg_ctl); + return reg_ctl; + } + + reg_sts = pca9541_reg_read(client, PCA9641_STATUS); + if (reg_sts < 0) { + PCA_DEBUG_ERR("pca9641 read status register failed, ret:%d.\n", reg_sts); + return reg_sts; + } + + if (BUSOFF(reg_ctl, reg_sts)) { + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + reg_ctl |= PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); + if (reg_ctl < 0) { + PCA_DEBUG_ERR("Bus is off, but read control register failed, ret:%d.\n", reg_ctl); + return reg_ctl; + } + + if (lock_grant(reg_ctl)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + PCA_DEBUG("Bus is off, get pca9641 arbitration success.\n"); + reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + return 1; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + PCA_DEBUG("Bus is off, but get pca9641 arbitration failed.\n"); + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (lock_grant(reg_ctl)) { + /* + * Bus is on, and we own it. We are done with acquisition. + */ + PCA_DEBUG("Bus is on, get pca9641 arbitration success.\n"); + reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + return 1; + } else if (other_lock(reg_sts)) { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + PCA_DEBUG("Other master owns the bus, try to request it.\n"); + data->select_timeout = SELECT_DELAY_LONG; + reg_ctl |= PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + } + return 0; +} + +int pca9641_select_chan_single(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + int result; + unsigned long msleep_time; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + for (result = 0 ; result < PCA9641_RETRY_TIME ; result ++) { + do { + ret = pca9641_arbitrate(client); + if (ret) { + return ret < 0 ? -EIO : 0; + } + msleep_time = data->select_timeout / 1000; + if (msleep_time < 1) { + msleep(1); + } else { + msleep(msleep_time); + } + } while (time_is_after_eq_jiffies(timeout)); + timeout = jiffies + ARB2_TIMEOUT; + } + dev_warn(&client->dev, "pca9641 select channel timeout.\n"); + return -ETIMEDOUT; +} + +static int pca9641_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + int ret, rv; + + ret = pca9641_select_chan_single(muxc, chan); + if (ret < 0) { + PCA_DEBUG_ERR("pca9641 select channel failed, ret:%d, try to reset pca9641.\n", ret); + rv = pca9641_do_reset(muxc); + + if (rv < 0) { + PCA_DEBUG_ERR("pca9641 reset failed, rv:%d.\n", rv); + return ret; + } + + ret = pca9641_select_chan_single(muxc, chan); + if (ret < 0) { + PCA_DEBUG_ERR("after pca9641 reset, select channel still failed, ret:%d.\n", ret); + } + } + return ret; +} + +static int pca9641_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + if (pca_flag.flag) { + pca9641_release_bus(client); + } + return 0; +} + +static int pca9641_detect_id(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9641_ID); + if (reg == PCA9641_ID_MAGIC) + return 1; + else + return 0; +} + +static int pca9641_recordflag(struct i2c_adapter *adap) { + if (pca_flag.flag != -1) { + pr_err(" %s %d has init already!!!", __func__, __LINE__); + return -1 ; + } + pca_flag.nr = adap->nr; + PCA_DEBUG(" adap->nr:%d\n", adap->nr); + snprintf(pca_flag.name, sizeof(pca_flag.name),adap->name); + return 0; +} + +static int of_pca9641_reset_data_init(struct pca9541 *data) +{ + int err; + struct device *dev = &data->client->dev; + pca9641_cfg_info_t *reset_cfg; + + reset_cfg = &data->pca9641_cfg_info; + if (dev == NULL || dev->of_node == NULL) { + PCA_DEBUG("dev or dev->of_node is NUll, no reset.\n"); + reset_cfg->pca9641_reset_type = PCA9641_RESET_NONE; + return 0; + } + + if (of_property_read_u32(dev->of_node, "pca9641_reset_type", &reset_cfg->pca9641_reset_type)) { + + PCA_DEBUG("pca9641_reset_type not found, no reset.\n"); + reset_cfg->pca9641_reset_type = PCA9641_RESET_NONE; + return 0; + } + err = of_property_read_u32(dev->of_node, "rst_delay_b", &reset_cfg->rst_delay_b); + err |= of_property_read_u32(dev->of_node, "rst_delay", &reset_cfg->rst_delay); + err |= of_property_read_u32(dev->of_node, "rst_delay_a", &reset_cfg->rst_delay_a); + + if (err) { + goto dts_config_err; + } + PCA_DEBUG("reset_type:0x%x, rst_delay_b:0x%x, rst_delay:0x%x, rst_delay_a:0x%x.\n", + reset_cfg->pca9641_reset_type, reset_cfg->rst_delay_b, + reset_cfg->rst_delay, reset_cfg->rst_delay_a); + + if (reset_cfg->pca9641_reset_type == PCA9641_RESET_I2C) { + + PCA_DEBUG("reset by i2c.\n"); + err = of_property_read_u32(dev->of_node, "i2c_bus", &reset_cfg->attr.i2c_attr.i2c_bus); + err |=of_property_read_u32(dev->of_node, "i2c_addr", &reset_cfg->attr.i2c_attr.i2c_addr); + err |=of_property_read_u32(dev->of_node, "reg_offset", &reset_cfg->attr.i2c_attr.reg_offset); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.i2c_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.i2c_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.i2c_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA_DEBUG("bus:%u, addr:0x%x, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + reset_cfg->attr.i2c_attr.i2c_bus, reset_cfg->attr.i2c_attr.i2c_addr, + reset_cfg->attr.i2c_attr.reg_offset, reset_cfg->attr.i2c_attr.mask, + reset_cfg->attr.i2c_attr.reset_on, reset_cfg->attr.i2c_attr.reset_off); + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_GPIO) { + + PCA_DEBUG("reset by gpio.\n"); + err = of_property_read_u32(dev->of_node, "gpio", &reset_cfg->attr.gpio_attr.gpio); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.gpio_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.gpio_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA_DEBUG("gpio number:%u, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.gpio_attr.gpio, reset_cfg->attr.gpio_attr.reset_on, + reset_cfg->attr.gpio_attr.reset_off); + reset_cfg->attr.gpio_attr.gpio_init = 0; + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_IO) { + + PCA_DEBUG("reset by io.\n"); + err = of_property_read_u32(dev->of_node, "io_addr", &reset_cfg->attr.io_attr.io_addr); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.io_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.io_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.io_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA_DEBUG("io_addr:0x%x, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.io_attr.io_addr, reset_cfg->attr.io_attr.mask, + reset_cfg->attr.io_attr.reset_on, reset_cfg->attr.io_attr.reset_off); + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_FILE) { + + PCA_DEBUG("reset by file.\n"); + err = of_property_read_string(dev->of_node, "dev_name", &reset_cfg->attr.file_attr.dev_name); + err |=of_property_read_u32(dev->of_node, "offset", &reset_cfg->attr.file_attr.offset); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.file_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.file_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.file_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA_DEBUG("dev_name:%s, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.file_attr.dev_name, reset_cfg->attr.file_attr.mask, + reset_cfg->attr.file_attr.reset_on, reset_cfg->attr.file_attr.reset_off); + } else { + PCA_DEBUG_ERR("Unsupport reset type:%d.\n", reset_cfg->pca9641_reset_type); + goto dts_config_err; + } + return 0; +dts_config_err: + PCA_DEBUG_ERR("dts config error, ret:%d.\n", err); + return -EINVAL; +} + +static int pca9641_reset_data_init(struct pca9541 *data) +{ + pca9641_cfg_info_t *reset_cfg; + i2c_mux_pca9641_device_t *i2c_mux_pca9641_device; + + if (data->client->dev.platform_data == NULL) { + PCA_DEBUG("pca9641 has no reset platform data config.\n"); + return 0; + } + reset_cfg = &data->pca9641_cfg_info; + i2c_mux_pca9641_device = data->client->dev.platform_data; + reset_cfg->pca9641_reset_type = i2c_mux_pca9641_device->pca9641_reset_type; + if (reset_cfg->pca9641_reset_type == PCA9641_RESET_NONE) { + PCA_DEBUG("pca9641 has no reset function.\n"); + return 0; + } + + reset_cfg->rst_delay_b = i2c_mux_pca9641_device->rst_delay_b; + reset_cfg->rst_delay = i2c_mux_pca9641_device->rst_delay; + reset_cfg->rst_delay_a = i2c_mux_pca9641_device->rst_delay_a; + PCA_DEBUG("reset_type:0x%x, rst_delay_b:0x%x, rst_delay:0x%x, rst_delay_a:0x%x.\n", + reset_cfg->pca9641_reset_type, reset_cfg->rst_delay_b, + reset_cfg->rst_delay, reset_cfg->rst_delay_a); + + if (reset_cfg->pca9641_reset_type == PCA9641_RESET_I2C) { + + PCA_DEBUG("reset by i2c.\n"); + reset_cfg->attr.i2c_attr.i2c_bus = i2c_mux_pca9641_device->attr.i2c_attr.i2c_bus; + reset_cfg->attr.i2c_attr.i2c_addr = i2c_mux_pca9641_device->attr.i2c_attr.i2c_addr; + reset_cfg->attr.i2c_attr.reg_offset = i2c_mux_pca9641_device->attr.i2c_attr.reg_offset; + reset_cfg->attr.i2c_attr.mask = i2c_mux_pca9641_device->attr.i2c_attr.mask; + reset_cfg->attr.i2c_attr.reset_on = i2c_mux_pca9641_device->attr.i2c_attr.reset_on; + reset_cfg->attr.i2c_attr.reset_off = i2c_mux_pca9641_device->attr.i2c_attr.reset_off; + PCA_DEBUG("bus:%u, addr:0x%x, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + reset_cfg->attr.i2c_attr.i2c_bus, reset_cfg->attr.i2c_attr.i2c_addr, + reset_cfg->attr.i2c_attr.reg_offset, reset_cfg->attr.i2c_attr.mask, + reset_cfg->attr.i2c_attr.reset_on, reset_cfg->attr.i2c_attr.reset_off); + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_GPIO) { + + PCA_DEBUG("reset by gpio.\n"); + reset_cfg->attr.gpio_attr.gpio = i2c_mux_pca9641_device->attr.gpio_attr.gpio; + reset_cfg->attr.gpio_attr.reset_on = i2c_mux_pca9641_device->attr.gpio_attr.reset_on; + reset_cfg->attr.gpio_attr.reset_off = i2c_mux_pca9641_device->attr.gpio_attr.reset_off; + PCA_DEBUG("gpio number:%u, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.gpio_attr.gpio, reset_cfg->attr.gpio_attr.reset_on, + reset_cfg->attr.gpio_attr.reset_off); + reset_cfg->attr.gpio_attr.gpio_init = 0; + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_IO) { + + PCA_DEBUG("reset by io.\n"); + reset_cfg->attr.io_attr.io_addr = i2c_mux_pca9641_device->attr.io_attr.io_addr; + reset_cfg->attr.io_attr.mask = i2c_mux_pca9641_device->attr.io_attr.mask; + reset_cfg->attr.io_attr.reset_on = i2c_mux_pca9641_device->attr.io_attr.reset_on; + reset_cfg->attr.io_attr.reset_off = i2c_mux_pca9641_device->attr.io_attr.reset_off; + PCA_DEBUG("io_addr:0x%x, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.io_attr.io_addr, reset_cfg->attr.io_attr.mask, + reset_cfg->attr.io_attr.reset_on, reset_cfg->attr.io_attr.reset_off); + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_FILE) { + + PCA_DEBUG("reset by file.\n"); + reset_cfg->attr.file_attr.dev_name = i2c_mux_pca9641_device->attr.file_attr.dev_name; + reset_cfg->attr.file_attr.offset = i2c_mux_pca9641_device->attr.file_attr.offset; + reset_cfg->attr.file_attr.mask = i2c_mux_pca9641_device->attr.file_attr.mask; + reset_cfg->attr.file_attr.reset_on = i2c_mux_pca9641_device->attr.file_attr.reset_on; + reset_cfg->attr.file_attr.reset_off = i2c_mux_pca9641_device->attr.file_attr.reset_off; + PCA_DEBUG("dev_name:%s, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.file_attr.dev_name, reset_cfg->attr.file_attr.mask, + reset_cfg->attr.file_attr.reset_on, reset_cfg->attr.file_attr.reset_off); + } else { + PCA_DEBUG_ERR("Unsupport reset type:%d.\n", reset_cfg->pca9641_reset_type); + return -EINVAL; + } + return 0; +} + +/* + * I2C init/probing/exit functions + */ +static int pca9541_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = client->adapter; + struct i2c_mux_core *muxc; + struct pca9541 *data; + int force; + int ret = -ENODEV; + int detect_id; + i2c_mux_pca9641_device_t *i2c_mux_pca9641_device; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + detect_id = pca9641_detect_id(client); + + /* + * I2C accesses are unprotected here. + * We have to lock the adapter before releasing the bus. + */ + if (detect_id == 0) { + i2c_lock_bus(adap, I2C_LOCK_ROOT_ADAPTER); + pca9541_release_bus(client); + i2c_unlock_bus(adap, I2C_LOCK_ROOT_ADAPTER); + } else { + i2c_lock_bus(adap, I2C_LOCK_ROOT_ADAPTER); + pca9641_release_bus(client); + i2c_unlock_bus(adap, I2C_LOCK_ROOT_ADAPTER); + } + + if (detect_id == 0) { /* pca9541 */ + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), + I2C_MUX_ARBITRATOR, + pca9541_select_chan, pca9541_release_chan); + if (!muxc) + return -ENOMEM; + + data = i2c_mux_priv(muxc); + data->client = client; + + i2c_set_clientdata(client, muxc); + /* Create mux adapter */ + if (of_property_read_u32(client->dev.of_node, "pca9641_nr", &data->pca9641_nr)) { + + force = 0; + PCA_DEBUG("pca9641_nr not found, use dynamic adap number.\n"); + } else { + force = data->pca9641_nr; + PCA_DEBUG("pca9641_nr: %d.\n", force); + } + + ret = i2c_mux_add_adapter(muxc, force, 0, 0); + if (ret) + return ret; + } else { + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), I2C_MUX_ARBITRATOR, + pca9641_select_chan, pca9641_release_chan); + if (!muxc) { + dev_err(&client->dev, "i2c_mux_alloc failed, out of memory.\n"); + return -ENOMEM; + } + + data = i2c_mux_priv(muxc); + data->client = client; + + i2c_set_clientdata(client, muxc); + + if (client->dev.of_node) { + ret= of_pca9641_reset_data_init(data); + } else { + ret= pca9641_reset_data_init(data); + } + if (ret < 0) { + dev_err(&client->dev, "pca9641 reset config err, ret:%d.\n", ret); + return ret; + } + + if (client->dev.of_node == NULL) { + if (client->dev.platform_data == NULL) { + force = 0; + PCA_DEBUG("platform data is NULL, use dynamic adap number.\n"); + } else { + i2c_mux_pca9641_device = client->dev.platform_data; + data->pca9641_nr = i2c_mux_pca9641_device->pca9641_nr; + if (data->pca9641_nr == 0) { + force = 0; + PCA_DEBUG("pca9641_nr = 0, use dynamic adap number.\n"); + } else { + force = data->pca9641_nr; + PCA_DEBUG("pca9641_nr: %d.\n", force); + } + } + } else { + /* Create mux adapter */ + if (of_property_read_u32(client->dev.of_node, "pca9641_nr", &data->pca9641_nr)) { + + force = 0; + PCA_DEBUG("pca9641_nr not found, use dynamic adap number.\n"); + } else { + force = data->pca9641_nr; + PCA_DEBUG("pca9641_nr: %d.\n", force); + } + } + + ret = i2c_mux_add_adapter(muxc, force, 0, 0); + if (ret) { + dev_err(&client->dev, "Failed to register master selector.\n"); + return ret; + } + } + pca9641_recordflag(muxc->adapter[0]); + + dev_info(&client->dev, "registered master selector for I2C %s\n", client->name); + + return 0; +} + +static int pca9541_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + i2c_mux_del_adapters(muxc); + return 0; +} + +static struct i2c_driver pca9641_driver = { + .driver = { + .name = "wb_pca9641", + .of_match_table = of_match_ptr(pca9541_of_match), + }, + .probe = pca9541_probe, + .remove = pca9541_remove, + .id_table = pca9541_id, +}; + +module_i2c_driver(pca9641_driver); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PCA9541 I2C master selector driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.h new file mode 100644 index 000000000000..b87f7585567b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.h @@ -0,0 +1,64 @@ +#ifndef __WB_I2C_MUX_PCA9641_H__ +#define __WB_I2C_MUX_PCA9641_H__ + +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef enum pca9641_reset_type_s { + PCA9641_RESET_NONE = 0, + PCA9641_RESET_I2C = 1, + PCA9641_RESET_GPIO = 2, + PCA9641_RESET_IO = 3, + PCA9641_RESET_FILE = 4, +} pca9641_reset_type_t; + +typedef struct i2c_attr_s { + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t reg_offset; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} i2c_attr_t; + +typedef struct io_attr_s { + uint32_t io_addr; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} io_attr_t; + +typedef struct file_attr_s { + const char *dev_name; + uint32_t offset; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} file_attr_t; + +typedef struct gpio_attr_s { + int gpio_init; + uint32_t gpio; + uint32_t reset_on; + uint32_t reset_off; +} gpio_attr_t; + +typedef struct i2c_mux_pca9641_device_s { + struct i2c_client *client; + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t pca9641_nr; + uint32_t pca9641_reset_type; + uint32_t rst_delay_b; /* delay time before reset(us) */ + uint32_t rst_delay; /* reset time(us) */ + uint32_t rst_delay_a; /* delay time after reset(us) */ + union { + i2c_attr_t i2c_attr; + gpio_attr_t gpio_attr; + io_attr_t io_attr; + file_attr_t file_attr; + } attr; +} i2c_mux_pca9641_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ina3221.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ina3221.c new file mode 100644 index 000000000000..fba2c4e3a68e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ina3221.c @@ -0,0 +1,1031 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * INA3221 Triple Current/Voltage Monitor + * + * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/ + * Andrew F. Davis + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define INA3221_DRIVER_NAME "wb_ina3221" + +#define INA3221_CONFIG 0x00 +#define INA3221_SHUNT1 0x01 +#define INA3221_BUS1 0x02 +#define INA3221_SHUNT2 0x03 +#define INA3221_BUS2 0x04 +#define INA3221_SHUNT3 0x05 +#define INA3221_BUS3 0x06 +#define INA3221_CRIT1 0x07 +#define INA3221_WARN1 0x08 +#define INA3221_CRIT2 0x09 +#define INA3221_WARN2 0x0a +#define INA3221_CRIT3 0x0b +#define INA3221_WARN3 0x0c +#define INA3221_SHUNT_SUM 0x0d +#define INA3221_CRIT_SUM 0x0e +#define INA3221_MASK_ENABLE 0x0f + +#define INA3221_CONFIG_MODE_MASK GENMASK(2, 0) +#define INA3221_CONFIG_MODE_POWERDOWN 0 +#define INA3221_CONFIG_MODE_SHUNT BIT(0) +#define INA3221_CONFIG_MODE_BUS BIT(1) +#define INA3221_CONFIG_MODE_CONTINUOUS BIT(2) +#define INA3221_CONFIG_VSH_CT_SHIFT 3 +#define INA3221_CONFIG_VSH_CT_MASK GENMASK(5, 3) +#define INA3221_CONFIG_VSH_CT(x) (((x) & GENMASK(5, 3)) >> 3) +#define INA3221_CONFIG_VBUS_CT_SHIFT 6 +#define INA3221_CONFIG_VBUS_CT_MASK GENMASK(8, 6) +#define INA3221_CONFIG_VBUS_CT(x) (((x) & GENMASK(8, 6)) >> 6) +#define INA3221_CONFIG_AVG_SHIFT 9 +#define INA3221_CONFIG_AVG_MASK GENMASK(11, 9) +#define INA3221_CONFIG_AVG(x) (((x) & GENMASK(11, 9)) >> 9) +#define INA3221_CONFIG_CHs_EN_MASK GENMASK(14, 12) +#define INA3221_CONFIG_CHx_EN(x) BIT(14 - (x)) + +#define INA3221_MASK_ENABLE_SCC_MASK GENMASK(14, 12) + +#define INA3221_CONFIG_DEFAULT 0x7127 +#define INA3221_RSHUNT_DEFAULT 10000 + +enum ina3221_fields { + /* Configuration */ + F_RST, + + /* Status Flags */ + F_CVRF, + + /* Warning Flags */ + F_WF3, F_WF2, F_WF1, + + /* Alert Flags: SF is the summation-alert flag */ + F_SF, F_CF3, F_CF2, F_CF1, + + /* sentinel */ + F_MAX_FIELDS +}; + +static const struct reg_field ina3221_reg_fields[] = { + [F_RST] = REG_FIELD(INA3221_CONFIG, 15, 15), + + [F_CVRF] = REG_FIELD(INA3221_MASK_ENABLE, 0, 0), + [F_WF3] = REG_FIELD(INA3221_MASK_ENABLE, 3, 3), + [F_WF2] = REG_FIELD(INA3221_MASK_ENABLE, 4, 4), + [F_WF1] = REG_FIELD(INA3221_MASK_ENABLE, 5, 5), + [F_SF] = REG_FIELD(INA3221_MASK_ENABLE, 6, 6), + [F_CF3] = REG_FIELD(INA3221_MASK_ENABLE, 7, 7), + [F_CF2] = REG_FIELD(INA3221_MASK_ENABLE, 8, 8), + [F_CF1] = REG_FIELD(INA3221_MASK_ENABLE, 9, 9), +}; + +enum ina3221_channels { + INA3221_CHANNEL1, + INA3221_CHANNEL2, + INA3221_CHANNEL3, + INA3221_NUM_CHANNELS +}; + +/** + * struct ina3221_input - channel input source specific information + * @label: label of channel input source + * @shunt_resistor: shunt resistor value of channel input source + * @disconnected: connection status of channel input source + */ +struct ina3221_input { + const char *label; + int shunt_resistor; + bool disconnected; +}; + +/** + * struct ina3221_data - device specific information + * @pm_dev: Device pointer for pm runtime + * @regmap: Register map of the device + * @fields: Register fields of the device + * @inputs: Array of channel input source specific structures + * @lock: mutex lock to serialize sysfs attribute accesses + * @reg_config: Register value of INA3221_CONFIG + * @summation_shunt_resistor: equivalent shunt resistor value for summation + * @single_shot: running in single-shot operating mode + */ +struct ina3221_data { + struct device *pm_dev; + struct regmap *regmap; + struct regmap_field *fields[F_MAX_FIELDS]; + struct ina3221_input inputs[INA3221_NUM_CHANNELS]; + struct mutex lock; + u32 reg_config; + int summation_shunt_resistor; + + bool single_shot; +}; + +static inline bool ina3221_is_enabled(struct ina3221_data *ina, int channel) +{ + /* Summation channel checks shunt resistor values */ + if (channel > INA3221_CHANNEL3) + return ina->summation_shunt_resistor != 0; + + return pm_runtime_active(ina->pm_dev) && + (ina->reg_config & INA3221_CONFIG_CHx_EN(channel)); +} + +/** + * Helper function to return the resistor value for current summation. + * + * There is a condition to calculate current summation -- all the shunt + * resistor values should be the same, so as to simply fit the formula: + * current summation = shunt voltage summation / shunt resistor + * + * Returns the equivalent shunt resistor value on success or 0 on failure + */ +static inline int ina3221_summation_shunt_resistor(struct ina3221_data *ina) +{ + struct ina3221_input *input = ina->inputs; + int i, shunt_resistor = 0; + + for (i = 0; i < INA3221_NUM_CHANNELS; i++) { + if (input[i].disconnected || !input[i].shunt_resistor) + continue; + if (!shunt_resistor) { + /* Found the reference shunt resistor value */ + shunt_resistor = input[i].shunt_resistor; + } else { + /* No summation if resistor values are different */ + if (shunt_resistor != input[i].shunt_resistor) + return 0; + } + } + + return shunt_resistor; +} + +/* Lookup table for Bus and Shunt conversion times in usec */ +static const u16 ina3221_conv_time[] = { + 140, 204, 332, 588, 1100, 2116, 4156, 8244, +}; + +/* Lookup table for number of samples using in averaging mode */ +static const int ina3221_avg_samples[] = { + 1, 4, 16, 64, 128, 256, 512, 1024, +}; + +/* Converting update_interval in msec to conversion time in usec */ +static inline u32 ina3221_interval_ms_to_conv_time(u16 config, int interval) +{ + u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK); + u32 samples_idx = INA3221_CONFIG_AVG(config); + u32 samples = ina3221_avg_samples[samples_idx]; + + /* Bisect the result to Bus and Shunt conversion times */ + return DIV_ROUND_CLOSEST(interval * 1000 / 2, channels * samples); +} + +/* Converting CONFIG register value to update_interval in usec */ +static inline u32 ina3221_reg_to_interval_us(u16 config) +{ + u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK); + u32 vbus_ct_idx = INA3221_CONFIG_VBUS_CT(config); + u32 vsh_ct_idx = INA3221_CONFIG_VSH_CT(config); + u32 samples_idx = INA3221_CONFIG_AVG(config); + u32 samples = ina3221_avg_samples[samples_idx]; + u32 vbus_ct = ina3221_conv_time[vbus_ct_idx]; + u32 vsh_ct = ina3221_conv_time[vsh_ct_idx]; + + /* Calculate total conversion time */ + return channels * (vbus_ct + vsh_ct) * samples; +} + +static inline int ina3221_wait_for_data(struct ina3221_data *ina) +{ + u32 wait, cvrf; + + wait = ina3221_reg_to_interval_us(ina->reg_config); + + /* Polling the CVRF bit to make sure read data is ready */ + return regmap_field_read_poll_timeout(ina->fields[F_CVRF], + cvrf, cvrf, wait, wait * 2); +} + +static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg, + int *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(ina->regmap, reg, ®val); + if (ret) + return ret; + + /* + * Shunt Voltage Sum register has 14-bit value with 1-bit shift + * Other Shunt Voltage registers have 12 bits with 3-bit shift + */ + if (reg == INA3221_SHUNT_SUM) + *val = sign_extend32(regval >> 1, 14); + else + *val = sign_extend32(regval >> 3, 12); + + return 0; +} + +static const u8 ina3221_in_reg[] = { + INA3221_BUS1, + INA3221_BUS2, + INA3221_BUS3, + INA3221_SHUNT1, + INA3221_SHUNT2, + INA3221_SHUNT3, + INA3221_SHUNT_SUM, +}; + +static int ina3221_read_chip(struct device *dev, u32 attr, long *val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int regval; + + switch (attr) { + case hwmon_chip_samples: + regval = INA3221_CONFIG_AVG(ina->reg_config); + *val = ina3221_avg_samples[regval]; + return 0; + case hwmon_chip_update_interval: + /* Return in msec */ + *val = ina3221_reg_to_interval_us(ina->reg_config); + *val = DIV_ROUND_CLOSEST(*val, 1000); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int ina3221_read_in(struct device *dev, u32 attr, int channel, long *val) +{ + const bool is_shunt = channel > INA3221_CHANNEL3; + struct ina3221_data *ina = dev_get_drvdata(dev); + u8 reg = ina3221_in_reg[channel]; + int regval, ret; + + /* + * Translate shunt channel index to sensor channel index except + * the 7th channel (6 since being 0-aligned) is for summation. + */ + if (channel != 6) + channel %= INA3221_NUM_CHANNELS; + + switch (attr) { + case hwmon_in_input: + if (!ina3221_is_enabled(ina, channel)) + return -ENODATA; + + /* Write CONFIG register to trigger a single-shot measurement */ + if (ina->single_shot) + regmap_write(ina->regmap, INA3221_CONFIG, + ina->reg_config); + + ret = ina3221_wait_for_data(ina); + if (ret) + return ret; + + ret = ina3221_read_value(ina, reg, ®val); + if (ret) + return ret; + + /* + * Scale of shunt voltage (uV): LSB is 40uV + * Scale of bus voltage (mV): LSB is 8mV + */ + *val = regval * (is_shunt ? 40 : 8); + return 0; + case hwmon_in_enable: + *val = ina3221_is_enabled(ina, channel); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static const u8 ina3221_curr_reg[][INA3221_NUM_CHANNELS + 1] = { + [hwmon_curr_input] = { INA3221_SHUNT1, INA3221_SHUNT2, + INA3221_SHUNT3, INA3221_SHUNT_SUM }, + [hwmon_curr_max] = { INA3221_WARN1, INA3221_WARN2, INA3221_WARN3, 0 }, + [hwmon_curr_crit] = { INA3221_CRIT1, INA3221_CRIT2, + INA3221_CRIT3, INA3221_CRIT_SUM }, + [hwmon_curr_max_alarm] = { F_WF1, F_WF2, F_WF3, 0 }, + [hwmon_curr_crit_alarm] = { F_CF1, F_CF2, F_CF3, F_SF }, +}; + +static int ina3221_read_curr(struct device *dev, u32 attr, + int channel, long *val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + struct ina3221_input *input = ina->inputs; + u8 reg = ina3221_curr_reg[attr][channel]; + int resistance_uo, voltage_nv; + int regval, ret; + + if (channel > INA3221_CHANNEL3) + resistance_uo = ina->summation_shunt_resistor; + else + resistance_uo = input[channel].shunt_resistor; + + switch (attr) { + case hwmon_curr_input: + if (!ina3221_is_enabled(ina, channel)) + return -ENODATA; + + /* Write CONFIG register to trigger a single-shot measurement */ + if (ina->single_shot) + regmap_write(ina->regmap, INA3221_CONFIG, + ina->reg_config); + + ret = ina3221_wait_for_data(ina); + if (ret) + return ret; + + fallthrough; + case hwmon_curr_crit: + case hwmon_curr_max: + if (!resistance_uo) + return -ENODATA; + + ret = ina3221_read_value(ina, reg, ®val); + if (ret) + return ret; + + /* Scale of shunt voltage: LSB is 40uV (40000nV) */ + voltage_nv = regval * 40000; + /* Return current in mA */ + *val = DIV_ROUND_CLOSEST(voltage_nv, resistance_uo); + return 0; + case hwmon_curr_crit_alarm: + case hwmon_curr_max_alarm: + /* No actual register read if channel is disabled */ + if (!ina3221_is_enabled(ina, channel)) { + /* Return 0 for alert flags */ + *val = 0; + return 0; + } + ret = regmap_field_read(ina->fields[reg], ®val); + if (ret) + return ret; + *val = regval; + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int ina3221_write_chip(struct device *dev, u32 attr, long val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret, idx; + u32 tmp; + + switch (attr) { + case hwmon_chip_samples: + idx = find_closest(val, ina3221_avg_samples, + ARRAY_SIZE(ina3221_avg_samples)); + + tmp = (ina->reg_config & ~INA3221_CONFIG_AVG_MASK) | + (idx << INA3221_CONFIG_AVG_SHIFT); + ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp); + if (ret) + return ret; + + /* Update reg_config accordingly */ + ina->reg_config = tmp; + return 0; + case hwmon_chip_update_interval: + tmp = ina3221_interval_ms_to_conv_time(ina->reg_config, val); + idx = find_closest(tmp, ina3221_conv_time, + ARRAY_SIZE(ina3221_conv_time)); + + /* Update Bus and Shunt voltage conversion times */ + tmp = INA3221_CONFIG_VBUS_CT_MASK | INA3221_CONFIG_VSH_CT_MASK; + tmp = (ina->reg_config & ~tmp) | + (idx << INA3221_CONFIG_VBUS_CT_SHIFT) | + (idx << INA3221_CONFIG_VSH_CT_SHIFT); + ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp); + if (ret) + return ret; + + /* Update reg_config accordingly */ + ina->reg_config = tmp; + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int ina3221_write_curr(struct device *dev, u32 attr, + int channel, long val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + struct ina3221_input *input = ina->inputs; + u8 reg = ina3221_curr_reg[attr][channel]; + int resistance_uo, current_ma, voltage_uv; + int regval; + + if (channel > INA3221_CHANNEL3) + resistance_uo = ina->summation_shunt_resistor; + else + resistance_uo = input[channel].shunt_resistor; + + if (!resistance_uo) + return -EOPNOTSUPP; + + /* clamp current */ + current_ma = clamp_val(val, + INT_MIN / resistance_uo, + INT_MAX / resistance_uo); + + voltage_uv = DIV_ROUND_CLOSEST(current_ma * resistance_uo, 1000); + + /* clamp voltage */ + voltage_uv = clamp_val(voltage_uv, -163800, 163800); + + /* + * Formula to convert voltage_uv to register value: + * regval = (voltage_uv / scale) << shift + * Note: + * The scale is 40uV for all shunt voltage registers + * Shunt Voltage Sum register left-shifts 1 bit + * All other Shunt Voltage registers shift 3 bits + * Results: + * SHUNT_SUM: (1 / 40uV) << 1 = 1 / 20uV + * SHUNT[1-3]: (1 / 40uV) << 3 = 1 / 5uV + */ + if (reg == INA3221_SHUNT_SUM) + regval = DIV_ROUND_CLOSEST(voltage_uv, 20) & 0xfffe; + else + regval = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8; + + return regmap_write(ina->regmap, reg, regval); +} + +static int ina3221_write_enable(struct device *dev, int channel, bool enable) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + u16 config, mask = INA3221_CONFIG_CHx_EN(channel); + u16 config_old = ina->reg_config & mask; + u32 tmp; + int ret; + + config = enable ? mask : 0; + + /* Bypass if enable status is not being changed */ + if (config_old == config) + return 0; + + /* For enabling routine, increase refcount and resume() at first */ + if (enable) { + ret = pm_runtime_resume_and_get(ina->pm_dev); + if (ret < 0) { + dev_err(dev, "Failed to get PM runtime\n"); + return ret; + } + } + + /* Enable or disable the channel */ + tmp = (ina->reg_config & ~mask) | (config & mask); + ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp); + if (ret) + goto fail; + + /* Cache the latest config register value */ + ina->reg_config = tmp; + + /* For disabling routine, decrease refcount or suspend() at last */ + if (!enable) + pm_runtime_put_sync(ina->pm_dev); + + return 0; + +fail: + if (enable) { + dev_err(dev, "Failed to enable channel %d: error %d\n", + channel, ret); + pm_runtime_put_sync(ina->pm_dev); + } + + return ret; +} + +static int ina3221_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + mutex_lock(&ina->lock); + + switch (type) { + case hwmon_chip: + ret = ina3221_read_chip(dev, attr, val); + break; + case hwmon_in: + /* 0-align channel ID */ + ret = ina3221_read_in(dev, attr, channel - 1, val); + break; + case hwmon_curr: + ret = ina3221_read_curr(dev, attr, channel, val); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + mutex_unlock(&ina->lock); + + return ret; +} + +static int ina3221_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + mutex_lock(&ina->lock); + + switch (type) { + case hwmon_chip: + ret = ina3221_write_chip(dev, attr, val); + break; + case hwmon_in: + /* 0-align channel ID */ + ret = ina3221_write_enable(dev, channel - 1, val); + break; + case hwmon_curr: + ret = ina3221_write_curr(dev, attr, channel, val); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + mutex_unlock(&ina->lock); + + return ret; +} + +static int ina3221_read_string(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, const char **str) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int index = channel - 1; + + if (channel == 7) + *str = "sum of shunt voltages"; + else + *str = ina->inputs[index].label; + + return 0; +} + +static umode_t ina3221_is_visible(const void *drvdata, + enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct ina3221_data *ina = drvdata; + const struct ina3221_input *input = NULL; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_samples: + case hwmon_chip_update_interval: + return 0644; + default: + return 0; + } + case hwmon_in: + /* Ignore in0_ */ + if (channel == 0) + return 0; + + switch (attr) { + case hwmon_in_label: + if (channel - 1 <= INA3221_CHANNEL3) + input = &ina->inputs[channel - 1]; + else if (channel == 7) + return 0444; + /* Hide label node if label is not provided */ + return (input && input->label) ? 0444 : 0; + case hwmon_in_input: + return 0444; + case hwmon_in_enable: + return 0644; + default: + return 0; + } + case hwmon_curr: + switch (attr) { + case hwmon_curr_input: + case hwmon_curr_crit_alarm: + case hwmon_curr_max_alarm: + return 0444; + case hwmon_curr_crit: + case hwmon_curr_max: + return 0644; + default: + return 0; + } + default: + return 0; + } +} + +#define INA3221_HWMON_CURR_CONFIG (HWMON_C_INPUT | \ + HWMON_C_CRIT | HWMON_C_CRIT_ALARM | \ + HWMON_C_MAX | HWMON_C_MAX_ALARM) + +static const struct hwmon_channel_info *ina3221_info[] = { + HWMON_CHANNEL_INFO(chip, + HWMON_C_SAMPLES, + HWMON_C_UPDATE_INTERVAL), + HWMON_CHANNEL_INFO(in, + /* 0: dummy, skipped in is_visible */ + HWMON_I_INPUT, + /* 1-3: input voltage Channels */ + HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL, + HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL, + HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL, + /* 4-6: shunt voltage Channels */ + HWMON_I_INPUT, + HWMON_I_INPUT, + HWMON_I_INPUT, + /* 7: summation of shunt voltage channels */ + HWMON_I_INPUT | HWMON_I_LABEL), + HWMON_CHANNEL_INFO(curr, + /* 1-3: current channels*/ + INA3221_HWMON_CURR_CONFIG, + INA3221_HWMON_CURR_CONFIG, + INA3221_HWMON_CURR_CONFIG, + /* 4: summation of current channels */ + HWMON_C_INPUT | HWMON_C_CRIT | HWMON_C_CRIT_ALARM), + NULL +}; + +static const struct hwmon_ops ina3221_hwmon_ops = { + .is_visible = ina3221_is_visible, + .read_string = ina3221_read_string, + .read = ina3221_read, + .write = ina3221_write, +}; + +static const struct hwmon_chip_info ina3221_chip_info = { + .ops = &ina3221_hwmon_ops, + .info = ina3221_info, +}; + +/* Extra attribute groups */ +static ssize_t ina3221_shunt_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int channel = sd_attr->index; + struct ina3221_input *input = &ina->inputs[channel]; + + return snprintf(buf, PAGE_SIZE, "%d\n", input->shunt_resistor); +} + +static ssize_t ina3221_shunt_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int channel = sd_attr->index; + struct ina3221_input *input = &ina->inputs[channel]; + int val; + int ret; + + ret = kstrtoint(buf, 0, &val); + if (ret) + return ret; + + val = clamp_val(val, 1, INT_MAX); + + input->shunt_resistor = val; + + /* Update summation_shunt_resistor for summation channel */ + ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina); + + return count; +} + +/* shunt resistance */ +static SENSOR_DEVICE_ATTR_RW(shunt1_resistor, ina3221_shunt, INA3221_CHANNEL1); +static SENSOR_DEVICE_ATTR_RW(shunt2_resistor, ina3221_shunt, INA3221_CHANNEL2); +static SENSOR_DEVICE_ATTR_RW(shunt3_resistor, ina3221_shunt, INA3221_CHANNEL3); + +static struct attribute *ina3221_attrs[] = { + &sensor_dev_attr_shunt1_resistor.dev_attr.attr, + &sensor_dev_attr_shunt2_resistor.dev_attr.attr, + &sensor_dev_attr_shunt3_resistor.dev_attr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(ina3221); + +static const struct regmap_range ina3221_yes_ranges[] = { + regmap_reg_range(INA3221_CONFIG, INA3221_BUS3), + regmap_reg_range(INA3221_SHUNT_SUM, INA3221_SHUNT_SUM), + regmap_reg_range(INA3221_MASK_ENABLE, INA3221_MASK_ENABLE), +}; + +static const struct regmap_access_table ina3221_volatile_table = { + .yes_ranges = ina3221_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(ina3221_yes_ranges), +}; + +static const struct regmap_config ina3221_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + + .cache_type = REGCACHE_RBTREE, + .volatile_table = &ina3221_volatile_table, +}; + +static int ina3221_probe_child_from_dt(struct device *dev, + struct device_node *child, + struct ina3221_data *ina) +{ + struct ina3221_input *input; + u32 val; + int ret; + + ret = of_property_read_u32(child, "reg", &val); + if (ret) { + dev_err(dev, "missing reg property of %pOFn\n", child); + return ret; + } else if (val > INA3221_CHANNEL3) { + dev_err(dev, "invalid reg %d of %pOFn\n", val, child); + return ret; + } + + input = &ina->inputs[val]; + + /* Log the disconnected channel input */ + if (!of_device_is_available(child)) { + input->disconnected = true; + return 0; + } + + /* Save the connected input label if available */ + of_property_read_string(child, "label", &input->label); + + /* Overwrite default shunt resistor value optionally */ + if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", &val)) { + if (val < 1 || val > INT_MAX) { + dev_err(dev, "invalid shunt resistor value %u of %pOFn\n", + val, child); + return -EINVAL; + } + input->shunt_resistor = val; + } + + return 0; +} + +static int ina3221_probe_from_dt(struct device *dev, struct ina3221_data *ina) +{ + const struct device_node *np = dev->of_node; + struct device_node *child; + int ret; + + /* Compatible with non-DT platforms */ + if (!np) + return 0; + + ina->single_shot = of_property_read_bool(np, "ti,single-shot"); + + for_each_child_of_node(np, child) { + ret = ina3221_probe_child_from_dt(dev, child, ina); + if (ret) { + of_node_put(child); + return ret; + } + } + + return 0; +} + +static int ina3221_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct ina3221_data *ina; + struct device *hwmon_dev; + int i, ret; + + ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL); + if (!ina) + return -ENOMEM; + + ina->regmap = devm_regmap_init_i2c(client, &ina3221_regmap_config); + if (IS_ERR(ina->regmap)) { + dev_err(dev, "Unable to allocate register map\n"); + return PTR_ERR(ina->regmap); + } + + for (i = 0; i < F_MAX_FIELDS; i++) { + ina->fields[i] = devm_regmap_field_alloc(dev, + ina->regmap, + ina3221_reg_fields[i]); + if (IS_ERR(ina->fields[i])) { + dev_err(dev, "Unable to allocate regmap fields\n"); + return PTR_ERR(ina->fields[i]); + } + } + + for (i = 0; i < INA3221_NUM_CHANNELS; i++) + ina->inputs[i].shunt_resistor = INA3221_RSHUNT_DEFAULT; + + ret = ina3221_probe_from_dt(dev, ina); + if (ret) { + dev_err(dev, "Unable to probe from device tree\n"); + return ret; + } + + /* The driver will be reset, so use reset value */ + ina->reg_config = INA3221_CONFIG_DEFAULT; + + /* Clear continuous bit to use single-shot mode */ + if (ina->single_shot) + ina->reg_config &= ~INA3221_CONFIG_MODE_CONTINUOUS; + + /* Disable channels if their inputs are disconnected */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) { + if (ina->inputs[i].disconnected) + ina->reg_config &= ~INA3221_CONFIG_CHx_EN(i); + } + + /* Initialize summation_shunt_resistor for summation channel control */ + ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina); + + ina->pm_dev = dev; + mutex_init(&ina->lock); + dev_set_drvdata(dev, ina); + + /* Enable PM runtime -- status is suspended by default */ + pm_runtime_enable(ina->pm_dev); + + /* Initialize (resume) the device */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) { + if (ina->inputs[i].disconnected) + continue; + /* Match the refcount with number of enabled channels */ + ret = pm_runtime_get_sync(ina->pm_dev); + if (ret < 0) + goto fail; + } + + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, ina, + &ina3221_chip_info, + ina3221_groups); + if (IS_ERR(hwmon_dev)) { + dev_err(dev, "Unable to register hwmon device\n"); + ret = PTR_ERR(hwmon_dev); + goto fail; + } + + return 0; + +fail: + pm_runtime_disable(ina->pm_dev); + pm_runtime_set_suspended(ina->pm_dev); + /* pm_runtime_put_noidle() will decrease the PM refcount until 0 */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) + pm_runtime_put_noidle(ina->pm_dev); + mutex_destroy(&ina->lock); + + return ret; +} + +static int ina3221_remove(struct i2c_client *client) +{ + struct ina3221_data *ina = dev_get_drvdata(&client->dev); + int i; + + pm_runtime_disable(ina->pm_dev); + pm_runtime_set_suspended(ina->pm_dev); + + /* pm_runtime_put_noidle() will decrease the PM refcount until 0 */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) + pm_runtime_put_noidle(ina->pm_dev); + + mutex_destroy(&ina->lock); + + return 0; +} + +static int __maybe_unused ina3221_suspend(struct device *dev) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + /* Save config register value and enable cache-only */ + ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); + if (ret) + return ret; + + /* Set to power-down mode for power saving */ + ret = regmap_update_bits(ina->regmap, INA3221_CONFIG, + INA3221_CONFIG_MODE_MASK, + INA3221_CONFIG_MODE_POWERDOWN); + if (ret) + return ret; + + regcache_cache_only(ina->regmap, true); + regcache_mark_dirty(ina->regmap); + + return 0; +} + +static int __maybe_unused ina3221_resume(struct device *dev) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + regcache_cache_only(ina->regmap, false); + + /* Software reset the chip */ + ret = regmap_field_write(ina->fields[F_RST], true); + if (ret) { + dev_err(dev, "Unable to reset device\n"); + return ret; + } + + /* Restore cached register values to hardware */ + ret = regcache_sync(ina->regmap); + if (ret) + return ret; + + /* Restore config register value to hardware */ + ret = regmap_write(ina->regmap, INA3221_CONFIG, ina->reg_config); + if (ret) + return ret; + + /* Initialize summation channel control */ + if (ina->summation_shunt_resistor) { + /* + * Take all three channels into summation by default + * Shunt measurements of disconnected channels should + * be 0, so it does not matter for summation. + */ + ret = regmap_update_bits(ina->regmap, INA3221_MASK_ENABLE, + INA3221_MASK_ENABLE_SCC_MASK, + INA3221_MASK_ENABLE_SCC_MASK); + if (ret) { + dev_err(dev, "Unable to control summation channel\n"); + return ret; + } + } + + return 0; +} + +static const struct dev_pm_ops ina3221_pm = { + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(ina3221_suspend, ina3221_resume, NULL) +}; + +static const struct of_device_id ina3221_of_match_table[] = { + { .compatible = "ti,wb_ina3221", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ina3221_of_match_table); + +static const struct i2c_device_id ina3221_ids[] = { + { "wb_ina3221", 0 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(i2c, ina3221_ids); + +static struct i2c_driver ina3221_i2c_driver = { + .probe_new = ina3221_probe, + .remove = ina3221_remove, + .driver = { + .name = INA3221_DRIVER_NAME, + .of_match_table = ina3221_of_match_table, + .pm = &ina3221_pm, + }, + .id_table = ina3221_ids, +}; +module_i2c_driver(ina3221_i2c_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Texas Instruments INA3221 HWMon Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_isl68137.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_isl68137.c new file mode 100644 index 000000000000..2797a831bd66 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_isl68137.c @@ -0,0 +1,572 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Hardware monitoring driver for Renesas Digital Multiphase Voltage Regulators + * + * Copyright (c) 2017 Google Inc + * Copyright (c) 2020 Renesas Electronics America + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_pmbus.h" + +#define ISL68137_VOUT_AVS (0x30) +#define RAA_DMPVR2_READ_VMON (0xc8) +#define WRITE_PROTECT_CLOSE (0x00) +#define WRITE_PROTECT_OPEN (0x40) + +static int g_wb_isl68137_debug = 0; +static int g_wb_isl68137_error = 0; + +module_param(g_wb_isl68137_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_isl68137_error, int, S_IRUGO | S_IWUSR); + +#define WB_ISL68137_VERBOSE(fmt, args...) do { \ + if (g_wb_isl68137_debug) { \ + printk(KERN_INFO "[WB_ISL68137][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_ISL68137_ERROR(fmt, args...) do { \ + if (g_wb_isl68137_error) { \ + printk(KERN_ERR "[WB_ISL68137][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +enum chips { + isl68137, + isl68220, + isl68221, + isl68222, + isl68223, + isl68224, + isl68225, + isl68226, + isl68227, + isl68229, + isl68233, + isl68239, + isl69222, + isl69223, + isl69224, + isl69225, + isl69227, + isl69228, + isl69234, + isl69236, + isl69239, + isl69242, + isl69243, + isl69247, + isl69248, + isl69254, + isl69255, + isl69256, + isl69259, + isl69260, + isl69268, + isl69269, + isl69298, + raa228000, + raa228004, + raa228006, + raa228228, + raa229001, + raa229004, +}; + +enum variants { + raa_dmpvr1_2rail, + raa_dmpvr2_1rail, + raa_dmpvr2_2rail, + raa_dmpvr2_2rail_nontc, + raa_dmpvr2_3rail, + raa_dmpvr2_hv, +}; + +static const struct i2c_device_id raa_dmpvr_id[]; + +static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client, + int page, + char *buf) +{ + int val = wb_pmbus_read_byte_data(client, page, PMBUS_OPERATION); + + return sprintf(buf, "%d\n", + (val & ISL68137_VOUT_AVS) == ISL68137_VOUT_AVS ? 1 : 0); +} + +static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client, + int page, + const char *buf, size_t count) +{ + int rc, op_val; + bool result; + + rc = kstrtobool(buf, &result); + if (rc) + return rc; + + op_val = result ? ISL68137_VOUT_AVS : 0; + + /* + * Writes to VOUT setpoint over AVSBus will persist after the VRM is + * switched to PMBus control. Switching back to AVSBus control + * restores this persisted setpoint rather than re-initializing to + * PMBus VOUT_COMMAND. Writing VOUT_COMMAND first over PMBus before + * enabling AVS control is the workaround. + */ + if (op_val == ISL68137_VOUT_AVS) { + rc = wb_pmbus_read_word_data(client, page, 0xff, + PMBUS_VOUT_COMMAND); + if (rc < 0) + return rc; + + rc = wb_pmbus_write_word_data(client, page, PMBUS_VOUT_COMMAND, + rc); + if (rc < 0) + return rc; + } + + rc = wb_pmbus_update_byte_data(client, page, PMBUS_OPERATION, + ISL68137_VOUT_AVS, op_val); + + return (rc < 0) ? rc : count; +} + +static ssize_t isl68137_avs_enable_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + + return isl68137_avs_enable_show_page(client, attr->index, buf); +} + +static ssize_t isl68137_avs_enable_store(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + + return isl68137_avs_enable_store_page(client, attr->index, buf, count); +} + +static ssize_t isl68137_avs_vout_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + int ret, vout_cmd, vout; + + mutex_lock(&data->update_lock); + vout_cmd = wb_pmbus_read_word_data(client, attr->index, 0xff, PMBUS_VOUT_COMMAND); + if (vout_cmd < 0) { + WB_ISL68137_ERROR("%d-%04x: read page%d vout command reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, attr->index, PMBUS_VOUT_COMMAND, ret); + mutex_unlock(&data->update_lock); + return vout_cmd; + } + vout = vout_cmd * 1000; + WB_ISL68137_VERBOSE("%d-%04x: page%d, vout: %d, vout_cmd: 0x%x\n", client->adapter->nr, + client->addr, attr->index, vout, vout_cmd); + mutex_unlock(&data->update_lock); + return snprintf(buf, PAGE_SIZE, "%d\n", vout); +} + +static ssize_t isl68137_avs_vout_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + int vout, vout_max, vout_min; + int ret, vout_cmd, vout_cmd_set; + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + ret = kstrtoint(buf, 0, &vout); + if (ret) { + WB_ISL68137_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + + vout_max = data->vout_max[attr->index]; + vout_min = data->vout_min[attr->index]; + if ((vout > vout_max) || (vout < vout_min)) { + WB_ISL68137_ERROR("%d-%04x: vout value: %d, out of range [%d, %d] \n", client->adapter->nr, + client->addr, vout, vout_min, vout_max); + return -EINVAL; + } + + /* calc VOUT_COMMAND set value */ + vout_cmd_set = vout / 1000; + if (vout_cmd_set > 0xffff) { + WB_ISL68137_ERROR("%d-%04x: invalid value, vout %d, vout_cmd_set: 0x%x\n", + client->adapter->nr, client->addr, vout, vout_cmd_set); + return -EINVAL; + } + + mutex_lock(&data->update_lock); + + /* close write protect */ + ret = wb_pmbus_write_byte_data(client, attr->index, PMBUS_WRITE_PROTECT, WRITE_PROTECT_CLOSE); + if (ret < 0) { + WB_ISL68137_ERROR("%d-%04x: close page%d write protect failed, ret: %d\n", client->adapter->nr, + client->addr, attr->index, ret); + mutex_unlock(&data->update_lock); + return ret; + } + + /* set VOUT_COMMAND */ + ret = wb_pmbus_write_word_data(client, attr->index, PMBUS_VOUT_COMMAND, vout_cmd_set); + if (ret < 0) { + WB_ISL68137_ERROR("%d-%04x: set page%d vout cmd reg: 0x%x, value: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, attr->index, PMBUS_VOUT_COMMAND, vout_cmd_set, ret); + goto error; + } + + /* read back VOUT_COMMAND */ + vout_cmd = wb_pmbus_read_word_data(client, attr->index, 0xff, PMBUS_VOUT_COMMAND); + if (vout_cmd < 0) { + ret = vout_cmd; + WB_ISL68137_ERROR("%d-%04x: read page%d vout command reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, attr->index, PMBUS_VOUT_COMMAND, ret); + goto error; + } + + /* compare vout_cmd and vout_cmd_set */ + if (vout_cmd != vout_cmd_set) { + ret = -EIO; + WB_ISL68137_ERROR("%d-%04x: vout cmd value check error, vout cmd read: 0x%x, vout cmd set: 0x%x\n", + client->adapter->nr, client->addr, vout_cmd, vout_cmd_set); + goto error; + } + + /* open write protect */ + wb_pmbus_write_byte_data(client, attr->index, PMBUS_WRITE_PROTECT, WRITE_PROTECT_OPEN); + mutex_unlock(&data->update_lock); + WB_ISL68137_VERBOSE("%d-%04x: set page%d vout cmd success, vout %d, vout_cmd_set: 0x%x\n", + client->adapter->nr, client->addr, attr->index, vout, vout_cmd_set); + return count; +error: + wb_pmbus_write_byte_data(client, attr->index, PMBUS_WRITE_PROTECT, WRITE_PROTECT_OPEN); + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t isl68137_avs_vout_max_store(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + int ret, vout_threshold; + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + ret = kstrtoint(buf, 0, &vout_threshold); + if (ret) { + WB_ISL68137_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + + WB_ISL68137_VERBOSE("%d-%04x: vout%d max threshold: %d", client->adapter->nr, client->addr, + attr->index, vout_threshold); + + data->vout_max[attr->index] = vout_threshold; + return count; +} + +static ssize_t isl68137_avs_vout_max_show(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + return snprintf(buf, PAGE_SIZE, "%d\n", data->vout_max[attr->index]); +} + +static ssize_t isl68137_avs_vout_min_store(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + int ret, vout_threshold; + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + ret = kstrtoint(buf, 0, &vout_threshold); + if (ret) { + WB_ISL68137_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + + WB_ISL68137_VERBOSE("%d-%04x: vout%d min threshold: %d", client->adapter->nr, client->addr, + attr->index, vout_threshold); + + data->vout_min[attr->index] = vout_threshold; + return count; +} + +static ssize_t isl68137_avs_vout_min_show(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + return snprintf(buf, PAGE_SIZE, "%d\n", data->vout_min[attr->index]); +} + +static SENSOR_DEVICE_ATTR_RW(avs0_enable, isl68137_avs_enable, 0); +static SENSOR_DEVICE_ATTR_RW(avs1_enable, isl68137_avs_enable, 1); + +static SENSOR_DEVICE_ATTR_RW(avs0_vout, isl68137_avs_vout, 0); +static SENSOR_DEVICE_ATTR_RW(avs1_vout, isl68137_avs_vout, 1); +static SENSOR_DEVICE_ATTR_RW(avs0_vout_max, isl68137_avs_vout_max, 0); +static SENSOR_DEVICE_ATTR_RW(avs0_vout_min, isl68137_avs_vout_min, 0); +static SENSOR_DEVICE_ATTR_RW(avs1_vout_max, isl68137_avs_vout_max, 1); +static SENSOR_DEVICE_ATTR_RW(avs1_vout_min, isl68137_avs_vout_min, 1); + +static struct attribute *enable_attrs[] = { + &sensor_dev_attr_avs0_enable.dev_attr.attr, + &sensor_dev_attr_avs1_enable.dev_attr.attr, + NULL, +}; + +static struct attribute *avs_ctrl_attrs[] = { + &sensor_dev_attr_avs0_vout.dev_attr.attr, + &sensor_dev_attr_avs1_vout.dev_attr.attr, + &sensor_dev_attr_avs0_vout_max.dev_attr.attr, + &sensor_dev_attr_avs0_vout_min.dev_attr.attr, + &sensor_dev_attr_avs1_vout_max.dev_attr.attr, + &sensor_dev_attr_avs1_vout_min.dev_attr.attr, + NULL, +}; + +static const struct attribute_group enable_group = { + .attrs = enable_attrs, +}; + +static const struct attribute_group avs_ctrl_group = { + .attrs = avs_ctrl_attrs, +}; + +static const struct attribute_group *isl68137_attribute_groups[] = { + &enable_group, + &avs_ctrl_group, + NULL, +}; + +static int raa_dmpvr2_read_word_data(struct i2c_client *client, int page, + int phase, int reg) +{ + int ret; + + switch (reg) { + case PMBUS_VIRT_READ_VMON: + ret = wb_pmbus_read_word_data(client, page, phase, + RAA_DMPVR2_READ_VMON); + break; + default: + ret = -ENODATA; + break; + } + + return ret; +} + +static struct pmbus_driver_info raa_dmpvr_info = { + .pages = 3, + .format[PSC_VOLTAGE_IN] = direct, + .format[PSC_VOLTAGE_OUT] = direct, + .format[PSC_CURRENT_IN] = direct, + .format[PSC_CURRENT_OUT] = direct, + .format[PSC_POWER] = direct, + .format[PSC_TEMPERATURE] = direct, + .m[PSC_VOLTAGE_IN] = 1, + .b[PSC_VOLTAGE_IN] = 0, + .R[PSC_VOLTAGE_IN] = 2, + .m[PSC_VOLTAGE_OUT] = 1, + .b[PSC_VOLTAGE_OUT] = 0, + .R[PSC_VOLTAGE_OUT] = 3, + .m[PSC_CURRENT_IN] = 1, + .b[PSC_CURRENT_IN] = 0, + .R[PSC_CURRENT_IN] = 2, + .m[PSC_CURRENT_OUT] = 1, + .b[PSC_CURRENT_OUT] = 0, + .R[PSC_CURRENT_OUT] = 1, + .m[PSC_POWER] = 1, + .b[PSC_POWER] = 0, + .R[PSC_POWER] = 0, + .m[PSC_TEMPERATURE] = 1, + .b[PSC_TEMPERATURE] = 0, + .R[PSC_TEMPERATURE] = 0, + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN + | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT + | PMBUS_HAVE_VMON, + .func[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT + | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT + | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, + .func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT + | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT + | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, +}; + +static int isl68137_probe(struct i2c_client *client) +{ + struct pmbus_driver_info *info; + + info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + memcpy(info, &raa_dmpvr_info, sizeof(*info)); + + switch (i2c_match_id(raa_dmpvr_id, client)->driver_data) { + case raa_dmpvr1_2rail: + info->pages = 2; + info->R[PSC_VOLTAGE_IN] = 3; + info->func[0] &= ~PMBUS_HAVE_VMON; + info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT + | PMBUS_HAVE_POUT; + info->groups = isl68137_attribute_groups; + break; + case raa_dmpvr2_1rail: + info->pages = 1; + info->read_word_data = raa_dmpvr2_read_word_data; + break; + case raa_dmpvr2_2rail_nontc: + info->func[0] &= ~PMBUS_HAVE_TEMP3; + info->func[1] &= ~PMBUS_HAVE_TEMP3; + fallthrough; + case raa_dmpvr2_2rail: + info->pages = 2; + info->read_word_data = raa_dmpvr2_read_word_data; + break; + case raa_dmpvr2_3rail: + info->read_word_data = raa_dmpvr2_read_word_data; + break; + case raa_dmpvr2_hv: + info->pages = 1; + info->R[PSC_VOLTAGE_IN] = 1; + info->m[PSC_VOLTAGE_OUT] = 2; + info->R[PSC_VOLTAGE_OUT] = 2; + info->m[PSC_CURRENT_IN] = 2; + info->m[PSC_POWER] = 2; + info->R[PSC_POWER] = -1; + info->read_word_data = raa_dmpvr2_read_word_data; + break; + default: + return -ENODEV; + } + + return wb_pmbus_do_probe(client, info); +} + +static const struct i2c_device_id raa_dmpvr_id[] = { + {"wb_isl68127", raa_dmpvr1_2rail}, + {"wb_isl68137", raa_dmpvr1_2rail}, + {"wb_isl68220", raa_dmpvr2_2rail}, + {"wb_isl68221", raa_dmpvr2_3rail}, + {"wb_isl68222", raa_dmpvr2_2rail}, + {"wb_isl68223", raa_dmpvr2_2rail}, + {"wb_isl68224", raa_dmpvr2_3rail}, + {"wb_isl68225", raa_dmpvr2_2rail}, + {"wb_isl68226", raa_dmpvr2_3rail}, + {"wb_isl68227", raa_dmpvr2_1rail}, + {"wb_isl68229", raa_dmpvr2_3rail}, + {"wb_isl68233", raa_dmpvr2_2rail}, + {"wb_isl68239", raa_dmpvr2_3rail}, + + {"wb_isl69222", raa_dmpvr2_2rail}, + {"wb_isl69223", raa_dmpvr2_3rail}, + {"wb_isl69224", raa_dmpvr2_2rail}, + {"wb_isl69225", raa_dmpvr2_2rail}, + {"wb_isl69227", raa_dmpvr2_3rail}, + {"wb_isl69228", raa_dmpvr2_3rail}, + {"wb_isl69234", raa_dmpvr2_2rail}, + {"wb_isl69236", raa_dmpvr2_2rail}, + {"wb_isl69239", raa_dmpvr2_3rail}, + {"wb_isl69242", raa_dmpvr2_2rail}, + {"wb_isl69243", raa_dmpvr2_1rail}, + {"wb_isl69247", raa_dmpvr2_2rail}, + {"wb_isl69248", raa_dmpvr2_2rail}, + {"wb_isl69254", raa_dmpvr2_2rail}, + {"wb_isl69255", raa_dmpvr2_2rail}, + {"wb_isl69256", raa_dmpvr2_2rail}, + {"wb_isl69259", raa_dmpvr2_2rail}, + {"wb_isl69260", raa_dmpvr2_2rail}, + {"wb_isl69268", raa_dmpvr2_2rail}, + {"wb_isl69269", raa_dmpvr2_3rail}, + {"wb_isl69298", raa_dmpvr2_2rail}, + + {"wb_raa228000", raa_dmpvr2_hv}, + {"wb_raa228004", raa_dmpvr2_hv}, + {"wb_raa228006", raa_dmpvr2_hv}, + {"wb_raa228228", raa_dmpvr2_2rail_nontc}, + {"wb_raa229001", raa_dmpvr2_2rail}, + {"wb_raa229004", raa_dmpvr2_2rail}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, raa_dmpvr_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver isl68137_driver = { + .driver = { + .name = "wb_isl68137", + }, + .probe_new = isl68137_probe, + .remove = wb_pmbus_do_remove, + .id_table = raa_dmpvr_id, +}; + +module_i2c_driver(isl68137_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PMBus driver for Renesas digital multiphase voltage regulators"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.c new file mode 100644 index 000000000000..b8291c553688 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.c @@ -0,0 +1,987 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * lm75.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998, 1999 Frodo Looijaard + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_lm75.h" + +/* + * This driver handles the LM75 and compatible digital temperature sensors. + */ + +enum lm75_type { /* keep sorted in alphabetical order */ + adt75, + ds1775, + ds75, + ds7505, + g751, + lm75, + lm75a, + lm75b, + max6625, + max6626, + max31725, + mcp980x, + pct2075, + stds75, + stlm75, + tcn75, + tmp100, + tmp101, + tmp105, + tmp112, + tmp175, + tmp275, + tmp75, + tmp75b, + tmp75c, +}; + +/** + * struct lm75_params - lm75 configuration parameters. + * @set_mask: Bits to set in configuration register when configuring + * the chip. + * @clr_mask: Bits to clear in configuration register when configuring + * the chip. + * @default_resolution: Default number of bits to represent the temperature + * value. + * @resolution_limits: Limit register resolution. Optional. Should be set if + * the resolution of limit registers does not match the + * resolution of the temperature register. + * @resolutions: List of resolutions associated with sample times. + * Optional. Should be set if num_sample_times is larger + * than 1, and if the resolution changes with sample times. + * If set, number of entries must match num_sample_times. + * @default_sample_time:Sample time to be set by default. + * @num_sample_times: Number of possible sample times to be set. Optional. + * Should be set if the number of sample times is larger + * than one. + * @sample_times: All the possible sample times to be set. Mandatory if + * num_sample_times is larger than 1. If set, number of + * entries must match num_sample_times. + */ + +struct lm75_params { + u8 set_mask; + u8 clr_mask; + u8 default_resolution; + u8 resolution_limits; + const u8 *resolutions; + unsigned int default_sample_time; + u8 num_sample_times; + const unsigned int *sample_times; +}; +#if 0 +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; +#endif +/* The LM75 registers */ +#define LM75_REG_TEMP 0x00 +#define LM75_REG_CONF 0x01 +#define LM75_REG_HYST 0x02 +#define LM75_REG_MAX 0x03 +#define PCT2075_REG_IDLE 0x04 +#define LM75_TEMP_INVALID_RETRY_TIMES (3) + +/* Each client has this additional data */ +struct lm75_data { + struct i2c_client *client; + struct regmap *regmap; + struct regulator *vs; + u8 orig_conf; + u8 current_conf; + u8 resolution; /* In bits, 9 to 16 */ + unsigned int sample_time; /* In ms */ + enum lm75_type kind; + const struct lm75_params *params; +}; + +/*-----------------------------------------------------------------------*/ + +static const u8 lm75_sample_set_masks[] = { 0 << 5, 1 << 5, 2 << 5, 3 << 5 }; + +#define LM75_SAMPLE_CLEAR_MASK (3 << 5) + +/* The structure below stores the configuration values of the supported devices. + * In case of being supported multiple configurations, the default one must + * always be the first element of the array + */ +static const struct lm75_params device_params[] = { + [adt75] = { + .clr_mask = 1 << 5, /* not one-shot mode */ + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [ds1775] = { + .clr_mask = 3 << 5, + .set_mask = 2 << 5, /* 11-bit mode */ + .default_resolution = 11, + .default_sample_time = 500, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 125, 250, 500, 1000 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [ds75] = { + .clr_mask = 3 << 5, + .set_mask = 2 << 5, /* 11-bit mode */ + .default_resolution = 11, + .default_sample_time = 600, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 150, 300, 600, 1200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [stds75] = { + .clr_mask = 3 << 5, + .set_mask = 2 << 5, /* 11-bit mode */ + .default_resolution = 11, + .default_sample_time = 600, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 150, 300, 600, 1200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [stlm75] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 6, + }, + [ds7505] = { + .set_mask = 3 << 5, /* 12-bit mode*/ + .default_resolution = 12, + .default_sample_time = 200, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 25, 50, 100, 200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [g751] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [lm75] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [lm75a] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [lm75b] = { + .default_resolution = 11, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [max6625] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 7, + }, + [max6626] = { + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 7, + .resolution_limits = 9, + }, + [max31725] = { + .default_resolution = 16, + .default_sample_time = MSEC_PER_SEC / 20, + }, + [tcn75] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 18, + }, + [pct2075] = { + .default_resolution = 11, + .default_sample_time = MSEC_PER_SEC / 10, + .num_sample_times = 31, + .sample_times = (unsigned int []){ 100, 200, 300, 400, 500, 600, + 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, + 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, + 2800, 2900, 3000, 3100 }, + }, + [mcp980x] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode */ + .default_resolution = 12, + .resolution_limits = 9, + .default_sample_time = 240, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 30, 60, 120, 240 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp100] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode */ + .default_resolution = 12, + .default_sample_time = 320, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 40, 80, 160, 320 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp101] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode */ + .default_resolution = 12, + .default_sample_time = 320, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 40, 80, 160, 320 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp105] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp112] = { + .set_mask = 3 << 5, /* 8 samples / second */ + .clr_mask = 1 << 7, /* no one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 125, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 125, 250, 1000, 4000 }, + }, + [tmp175] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp275] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp75] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp75b] = { /* not one-shot mode, Conversion rate 37Hz */ + .clr_mask = 1 << 7 | 3 << 5, + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 37, + .sample_times = (unsigned int []){ MSEC_PER_SEC / 37, + MSEC_PER_SEC / 18, + MSEC_PER_SEC / 9, MSEC_PER_SEC / 4 }, + .num_sample_times = 4, + }, + [tmp75c] = { + .clr_mask = 1 << 5, /*not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 12, + } +}; + +/* input temp threshold check */ +typedef struct lm75_temp_threshold_s { + int chip_type; + int temp_max; + int temp_min; +} lm75_temp_threshold_t; + +static lm75_temp_threshold_t g_lm75_temp_threshold_info[] = { + { + .chip_type = lm75, + .temp_max = 125000, + .temp_min = -55000, + }, +}; + +/*-----------------------------------------------------------------------*/ +static int lm75_input_temp_check(struct lm75_data *data, int input_val) +{ + int i, size; + + size = ARRAY_SIZE(g_lm75_temp_threshold_info); + + for (i = 0; i < size; i++) { + if (g_lm75_temp_threshold_info[i].chip_type == data->kind) { + if ((input_val > g_lm75_temp_threshold_info[i].temp_max) + || (input_val < g_lm75_temp_threshold_info[i].temp_min)) { + dev_dbg(&data->client->dev, "input temp: %d not in range[%d, %d]\n", + input_val, g_lm75_temp_threshold_info[i].temp_min, + g_lm75_temp_threshold_info[i].temp_max); + return -EINVAL; + } + dev_dbg(&data->client->dev, "input temp: %d in range[%d, %d]", input_val, + g_lm75_temp_threshold_info[i].temp_min, g_lm75_temp_threshold_info[i].temp_max); + return 0; + } + } + return 0; +} + +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +static int lm75_write_config(struct lm75_data *data, u8 set_mask, + u8 clr_mask) +{ + u8 value; + + clr_mask |= LM75_SHUTDOWN; + value = data->current_conf & ~clr_mask; + value |= set_mask; + + if (data->current_conf != value) { + s32 err; + + err = i2c_smbus_write_byte_data(data->client, LM75_REG_CONF, + value); + if (err) + return err; + data->current_conf = value; + } + return 0; +} + +static int lm75_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, + long *val) +{ + struct lm75_data *data = dev_get_drvdata(dev); + unsigned int regval; + int err, reg, i, ret; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_update_interval: + *val = data->sample_time; + break; + default: + return -EINVAL; + } + break; + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + reg = LM75_REG_TEMP; + break; + case hwmon_temp_max: + reg = LM75_REG_MAX; + break; + case hwmon_temp_max_hyst: + reg = LM75_REG_HYST; + break; + default: + return -EINVAL; + } + for (i = 0; i < LM75_TEMP_INVALID_RETRY_TIMES; i++) { + err = regmap_read(data->regmap, reg, ®val); + if (err < 0) { + return err; + } + *val = lm75_reg_to_mc(regval, data->resolution); + if (attr != LM75_REG_TEMP) { + return 0; + } + /* do input_temp_check */ + ret = lm75_input_temp_check(data, *val); + if (ret == 0) { /* input temp check ok */ + return 0; + } + if ((i + 1) < LM75_TEMP_INVALID_RETRY_TIMES) { + msleep(data->sample_time); + } + } + dev_info(&data->client->dev, "temp_input value: %ld invalid\n", *val); + return -EINVAL; + default: + return -EINVAL; + } + return 0; +} + +static int lm75_write_temp(struct device *dev, u32 attr, long temp) +{ + struct lm75_data *data = dev_get_drvdata(dev); + u8 resolution; + int reg; + + switch (attr) { + case hwmon_temp_max: + reg = LM75_REG_MAX; + break; + case hwmon_temp_max_hyst: + reg = LM75_REG_HYST; + break; + default: + return -EINVAL; + } + + /* + * Resolution of limit registers is assumed to be the same as the + * temperature input register resolution unless given explicitly. + */ + if (data->params->resolution_limits) + resolution = data->params->resolution_limits; + else + resolution = data->resolution; + + temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + temp = DIV_ROUND_CLOSEST(temp << (resolution - 8), + 1000) << (16 - resolution); + + return regmap_write(data->regmap, reg, (u16)temp); +} + +static int lm75_update_interval(struct device *dev, long val) +{ + struct lm75_data *data = dev_get_drvdata(dev); + unsigned int reg; + u8 index; + s32 err; + + index = find_closest(val, data->params->sample_times, + (int)data->params->num_sample_times); + + switch (data->kind) { + default: + err = lm75_write_config(data, lm75_sample_set_masks[index], + LM75_SAMPLE_CLEAR_MASK); + if (err) + return err; + + data->sample_time = data->params->sample_times[index]; + if (data->params->resolutions) + data->resolution = data->params->resolutions[index]; + break; + case tmp112: + err = regmap_read(data->regmap, LM75_REG_CONF, ®); + if (err < 0) + return err; + reg &= ~0x00c0; + reg |= (3 - index) << 6; + err = regmap_write(data->regmap, LM75_REG_CONF, reg); + if (err < 0) + return err; + data->sample_time = data->params->sample_times[index]; + break; + case pct2075: + err = i2c_smbus_write_byte_data(data->client, PCT2075_REG_IDLE, + index + 1); + if (err) + return err; + data->sample_time = data->params->sample_times[index]; + break; + } + return 0; +} + +static int lm75_write_chip(struct device *dev, u32 attr, long val) +{ + switch (attr) { + case hwmon_chip_update_interval: + return lm75_update_interval(dev, val); + default: + return -EINVAL; + } + return 0; +} + +static int lm75_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + switch (type) { + case hwmon_chip: + return lm75_write_chip(dev, attr, val); + case hwmon_temp: + return lm75_write_temp(dev, attr, val); + default: + return -EINVAL; + } + return 0; +} + +static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct lm75_data *config_data = data; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_update_interval: + if (config_data->params->num_sample_times > 1) + return 0644; + return 0444; + } + break; + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + return 0444; + case hwmon_temp_max: + case hwmon_temp_max_hyst: + return 0644; + } + break; + default: + break; + } + return 0; +} + +static const struct hwmon_channel_info *lm75_info[] = { + HWMON_CHANNEL_INFO(chip, + HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL), + HWMON_CHANNEL_INFO(temp, + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), + NULL +}; + +static const struct hwmon_ops lm75_hwmon_ops = { + .is_visible = lm75_is_visible, + .read = lm75_read, + .write = lm75_write, +}; + +static const struct hwmon_chip_info lm75_chip_info = { + .ops = &lm75_hwmon_ops, + .info = lm75_info, +}; + +static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg) +{ + return reg != LM75_REG_TEMP; +} + +static bool lm75_is_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg == LM75_REG_TEMP || reg == LM75_REG_CONF; +} + +static const struct regmap_config lm75_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .max_register = PCT2075_REG_IDLE, + .writeable_reg = lm75_is_writeable_reg, + .volatile_reg = lm75_is_volatile_reg, + .val_format_endian = REGMAP_ENDIAN_BIG, + .cache_type = REGCACHE_RBTREE, + .use_single_read = true, + .use_single_write = true, +}; + +static void lm75_disable_regulator(void *data) +{ + struct lm75_data *lm75 = data; + + regulator_disable(lm75->vs); +} + +static void lm75_remove(void *data) +{ + struct lm75_data *lm75 = data; + struct i2c_client *client = lm75->client; + + i2c_smbus_write_byte_data(client, LM75_REG_CONF, lm75->orig_conf); +} + +static const struct i2c_device_id lm75_ids[]; + +static int lm75_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct lm75_data *data; + int status, err; + enum lm75_type kind; + + if (client->dev.of_node) + kind = (enum lm75_type)of_device_get_match_data(&client->dev); + else + kind = i2c_match_id(lm75_ids, client)->driver_data; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return -EIO; + + data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + data->kind = kind; + + data->vs = devm_regulator_get(dev, "vs"); + if (IS_ERR(data->vs)) + return PTR_ERR(data->vs); + + data->regmap = devm_regmap_init_i2c(client, &lm75_regmap_config); + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + + /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. + * Then tweak to be more precise when appropriate. + */ + + data->params = &device_params[data->kind]; + + /* Save default sample time and resolution*/ + data->sample_time = data->params->default_sample_time; + data->resolution = data->params->default_resolution; + + /* Enable the power */ + err = regulator_enable(data->vs); + if (err) { + dev_err(dev, "failed to enable regulator: %d\n", err); + return err; + } + + err = devm_add_action_or_reset(dev, lm75_disable_regulator, data); + if (err) + return err; + + /* Cache original configuration */ + status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(dev, "Can't read config? %d\n", status); + return status; + } + data->orig_conf = status; + data->current_conf = status; + + err = lm75_write_config(data, data->params->set_mask, + data->params->clr_mask); + if (err) + return err; + + err = devm_add_action_or_reset(dev, lm75_remove, data); + if (err) + return err; + + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, + data, &lm75_chip_info, + NULL); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name); + + return 0; +} + +static const struct i2c_device_id lm75_ids[] = { + { "wb_adt75", adt75, }, + { "wb_ds1775", ds1775, }, + { "wb_ds75", ds75, }, + { "wb_ds7505", ds7505, }, + { "wb_g751", g751, }, + { "wb_lm75", lm75, }, + { "wb_lm75a", lm75a, }, + { "wb_lm75b", lm75b, }, + { "wb_max6625", max6625, }, + { "wb_max6626", max6626, }, + { "wb_max31725", max31725, }, + { "wb_max31726", max31725, }, + { "wb_mcp980x", mcp980x, }, + { "wb_pct2075", pct2075, }, + { "wb_stds75", stds75, }, + { "wb_stlm75", stlm75, }, + { "wb_tcn75", tcn75, }, + { "wb_tmp100", tmp100, }, + { "wb_tmp101", tmp101, }, + { "wb_tmp105", tmp105, }, + { "wb_tmp112", tmp112, }, + { "wb_tmp175", tmp175, }, + { "wb_tmp275", tmp275, }, + { "wb_tmp75", tmp75, }, + { "wb_tmp75b", tmp75b, }, + { "wb_tmp75c", tmp75c, }, + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, lm75_ids); + +static const struct of_device_id __maybe_unused lm75_of_match[] = { + { + .compatible = "adi,adt75", + .data = (void *)adt75 + }, + { + .compatible = "dallas,ds1775", + .data = (void *)ds1775 + }, + { + .compatible = "dallas,ds75", + .data = (void *)ds75 + }, + { + .compatible = "dallas,ds7505", + .data = (void *)ds7505 + }, + { + .compatible = "gmt,g751", + .data = (void *)g751 + }, + { + .compatible = "national,lm75", + .data = (void *)lm75 + }, + { + .compatible = "national,lm75a", + .data = (void *)lm75a + }, + { + .compatible = "national,lm75b", + .data = (void *)lm75b + }, + { + .compatible = "maxim,max6625", + .data = (void *)max6625 + }, + { + .compatible = "maxim,max6626", + .data = (void *)max6626 + }, + { + .compatible = "maxim,max31725", + .data = (void *)max31725 + }, + { + .compatible = "maxim,max31726", + .data = (void *)max31725 + }, + { + .compatible = "maxim,mcp980x", + .data = (void *)mcp980x + }, + { + .compatible = "nxp,pct2075", + .data = (void *)pct2075 + }, + { + .compatible = "st,stds75", + .data = (void *)stds75 + }, + { + .compatible = "st,stlm75", + .data = (void *)stlm75 + }, + { + .compatible = "microchip,tcn75", + .data = (void *)tcn75 + }, + { + .compatible = "ti,tmp100", + .data = (void *)tmp100 + }, + { + .compatible = "ti,tmp101", + .data = (void *)tmp101 + }, + { + .compatible = "ti,tmp105", + .data = (void *)tmp105 + }, + { + .compatible = "ti,tmp112", + .data = (void *)tmp112 + }, + { + .compatible = "ti,tmp175", + .data = (void *)tmp175 + }, + { + .compatible = "ti,tmp275", + .data = (void *)tmp275 + }, + { + .compatible = "ti,tmp75", + .data = (void *)tmp75 + }, + { + .compatible = "ti,tmp75b", + .data = (void *)tmp75b + }, + { + .compatible = "ti,tmp75c", + .data = (void *)tmp75c + }, + { }, +}; +MODULE_DEVICE_TABLE(of, lm75_of_match); + +#define LM75A_ID 0xA1 +#if 0 +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm75_detect(struct i2c_client *new_client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int i; + int conf, hyst, os; + bool is_lm75a = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + /* + * Now, we do the remaining detection. There is no identification- + * dedicated register so we have to rely on several tricks: + * unused bits, registers cycling over 8-address boundaries, + * addresses 0x04-0x07 returning the last read value. + * The cycling+unused addresses combination is not tested, + * since it would significantly slow the detection down and would + * hardly add any value. + * + * The National Semiconductor LM75A is different than earlier + * LM75s. It has an ID byte of 0xaX (where X is the chip + * revision, with 1 being the only revision in existence) in + * register 7, and unused registers return 0xff rather than the + * last read value. + * + * Note that this function only detects the original National + * Semiconductor LM75 and the LM75A. Clones from other vendors + * aren't detected, on purpose, because they are typically never + * found on PC hardware. They are found on embedded designs where + * they can be instantiated explicitly so detection is not needed. + * The absence of identification registers on all these clones + * would make their exhaustive detection very difficult and weak, + * and odds are that the driver would bind to unsupported devices. + */ + + /* Unused bits */ + conf = i2c_smbus_read_byte_data(new_client, 1); + if (conf & 0xe0) + return -ENODEV; + + /* First check for LM75A */ + if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { + /* + * LM75A returns 0xff on unused registers so + * just to be sure we check for that too. + */ + if (i2c_smbus_read_byte_data(new_client, 4) != 0xff + || i2c_smbus_read_byte_data(new_client, 5) != 0xff + || i2c_smbus_read_byte_data(new_client, 6) != 0xff) + return -ENODEV; + is_lm75a = 1; + hyst = i2c_smbus_read_byte_data(new_client, 2); + os = i2c_smbus_read_byte_data(new_client, 3); + } else { /* Traditional style LM75 detection */ + /* Unused addresses */ + hyst = i2c_smbus_read_byte_data(new_client, 2); + if (i2c_smbus_read_byte_data(new_client, 4) != hyst + || i2c_smbus_read_byte_data(new_client, 5) != hyst + || i2c_smbus_read_byte_data(new_client, 6) != hyst + || i2c_smbus_read_byte_data(new_client, 7) != hyst) + return -ENODEV; + os = i2c_smbus_read_byte_data(new_client, 3); + if (i2c_smbus_read_byte_data(new_client, 4) != os + || i2c_smbus_read_byte_data(new_client, 5) != os + || i2c_smbus_read_byte_data(new_client, 6) != os + || i2c_smbus_read_byte_data(new_client, 7) != os) + return -ENODEV; + } + /* + * It is very unlikely that this is a LM75 if both + * hysteresis and temperature limit registers are 0. + */ + if (hyst == 0 && os == 0) + return -ENODEV; + + /* Addresses cycling */ + for (i = 8; i <= 248; i += 40) { + if (i2c_smbus_read_byte_data(new_client, i + 1) != conf + || i2c_smbus_read_byte_data(new_client, i + 2) != hyst + || i2c_smbus_read_byte_data(new_client, i + 3) != os) + return -ENODEV; + if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) + != LM75A_ID) + return -ENODEV; + } + + strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); + + return 0; +} +#endif + +#ifdef CONFIG_PM +static int lm75_suspend(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + + status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status | LM75_SHUTDOWN; + i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); + return 0; +} + +static int lm75_resume(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + + status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status & ~LM75_SHUTDOWN; + i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); + return 0; +} + +static const struct dev_pm_ops lm75_dev_pm_ops = { + .suspend = lm75_suspend, + .resume = lm75_resume, +}; +#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) +#else +#define LM75_DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + +static struct i2c_driver lm75_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "wb_lm75", + .of_match_table = of_match_ptr(lm75_of_match), + .pm = LM75_DEV_PM_OPS, + }, + .probe_new = lm75_probe, + .id_table = lm75_ids, + /* .detect = lm75_detect, */ + /* .address_list = normal_i2c, */ +}; + +module_i2c_driver(lm75_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("LM75 driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.h new file mode 100644 index 000000000000..a398171162a8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * lm75.h - Part of lm_sensors, Linux kernel modules for hardware monitoring + * Copyright (c) 2003 Mark M. Hoffman + */ + +/* + * This file contains common code for encoding/decoding LM75 type + * temperature readings, which are emulated by many of the chips + * we support. As the user is unlikely to load more than one driver + * which contains this code, we don't worry about the wasted space. + */ + +#include + +/* straight from the datasheet */ +#define LM75_TEMP_MIN (-55000) +#define LM75_TEMP_MAX 125000 +#define LM75_SHUTDOWN 0x01 + +/* + * TEMP: 0.001C/bit (-55C to +125C) + * REG: (0.5C/bit, two's complement) << 7 + */ +static inline u16 LM75_TEMP_TO_REG(long temp) +{ + int ntemp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + + ntemp += (ntemp < 0 ? -250 : 250); + return (u16)((ntemp / 500) << 7); +} + +static inline int LM75_TEMP_FROM_REG(u16 reg) +{ + /* + * use integer division instead of equivalent right shift to + * guarantee arithmetic shift and preserve the sign + */ + return ((s16)reg / 128) * 500; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus.h new file mode 100644 index 000000000000..9fb2c9017ae6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus.h @@ -0,0 +1,535 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * wb_pmbus.h - Common defines and structures for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + */ + +#ifndef WB_PMBUS_H +#define WB_PMBUS_H + +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +/* + * Registers + */ +enum pmbus_regs { + PMBUS_PAGE = 0x00, + PMBUS_OPERATION = 0x01, + PMBUS_ON_OFF_CONFIG = 0x02, + PMBUS_CLEAR_FAULTS = 0x03, + PMBUS_PHASE = 0x04, + + PMBUS_WRITE_PROTECT = 0x10, + + PMBUS_CAPABILITY = 0x19, + PMBUS_QUERY = 0x1A, + + PMBUS_VOUT_MODE = 0x20, + PMBUS_VOUT_COMMAND = 0x21, + PMBUS_VOUT_TRIM = 0x22, + PMBUS_VOUT_CAL_OFFSET = 0x23, + PMBUS_VOUT_MAX = 0x24, + PMBUS_VOUT_MARGIN_HIGH = 0x25, + PMBUS_VOUT_MARGIN_LOW = 0x26, + PMBUS_VOUT_TRANSITION_RATE = 0x27, + PMBUS_VOUT_DROOP = 0x28, + PMBUS_VOUT_SCALE_LOOP = 0x29, + PMBUS_VOUT_SCALE_MONITOR = 0x2A, + + PMBUS_COEFFICIENTS = 0x30, + PMBUS_POUT_MAX = 0x31, + + PMBUS_FAN_CONFIG_12 = 0x3A, + PMBUS_FAN_COMMAND_1 = 0x3B, + PMBUS_FAN_COMMAND_2 = 0x3C, + PMBUS_FAN_CONFIG_34 = 0x3D, + PMBUS_FAN_COMMAND_3 = 0x3E, + PMBUS_FAN_COMMAND_4 = 0x3F, + + PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, + PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, + PMBUS_VOUT_OV_WARN_LIMIT = 0x42, + PMBUS_VOUT_UV_WARN_LIMIT = 0x43, + PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, + PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, + PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, + PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, + PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, + PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, + PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, + PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, + PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, + + PMBUS_OT_FAULT_LIMIT = 0x4F, + PMBUS_OT_FAULT_RESPONSE = 0x50, + PMBUS_OT_WARN_LIMIT = 0x51, + PMBUS_UT_WARN_LIMIT = 0x52, + PMBUS_UT_FAULT_LIMIT = 0x53, + PMBUS_UT_FAULT_RESPONSE = 0x54, + PMBUS_VIN_OV_FAULT_LIMIT = 0x55, + PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, + PMBUS_VIN_OV_WARN_LIMIT = 0x57, + PMBUS_VIN_UV_WARN_LIMIT = 0x58, + PMBUS_VIN_UV_FAULT_LIMIT = 0x59, + + PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, + PMBUS_IIN_OC_WARN_LIMIT = 0x5D, + + PMBUS_POUT_OP_FAULT_LIMIT = 0x68, + PMBUS_POUT_OP_WARN_LIMIT = 0x6A, + PMBUS_PIN_OP_WARN_LIMIT = 0x6B, + + PMBUS_STATUS_BYTE = 0x78, + PMBUS_STATUS_WORD = 0x79, + PMBUS_STATUS_VOUT = 0x7A, + PMBUS_STATUS_IOUT = 0x7B, + PMBUS_STATUS_INPUT = 0x7C, + PMBUS_STATUS_TEMPERATURE = 0x7D, + PMBUS_STATUS_CML = 0x7E, + PMBUS_STATUS_OTHER = 0x7F, + PMBUS_STATUS_MFR_SPECIFIC = 0x80, + PMBUS_STATUS_FAN_12 = 0x81, + PMBUS_STATUS_FAN_34 = 0x82, + + PMBUS_READ_VIN = 0x88, + PMBUS_READ_IIN = 0x89, + PMBUS_READ_VCAP = 0x8A, + PMBUS_READ_VOUT = 0x8B, + PMBUS_READ_IOUT = 0x8C, + PMBUS_READ_TEMPERATURE_1 = 0x8D, + PMBUS_READ_TEMPERATURE_2 = 0x8E, + PMBUS_READ_TEMPERATURE_3 = 0x8F, + PMBUS_READ_FAN_SPEED_1 = 0x90, + PMBUS_READ_FAN_SPEED_2 = 0x91, + PMBUS_READ_FAN_SPEED_3 = 0x92, + PMBUS_READ_FAN_SPEED_4 = 0x93, + PMBUS_READ_DUTY_CYCLE = 0x94, + PMBUS_READ_FREQUENCY = 0x95, + PMBUS_READ_POUT = 0x96, + PMBUS_READ_PIN = 0x97, + + PMBUS_REVISION = 0x98, + PMBUS_MFR_ID = 0x99, + PMBUS_MFR_MODEL = 0x9A, + PMBUS_MFR_REVISION = 0x9B, + PMBUS_MFR_LOCATION = 0x9C, + PMBUS_MFR_DATE = 0x9D, + PMBUS_MFR_SERIAL = 0x9E, + + PMBUS_MFR_VIN_MIN = 0xA0, + PMBUS_MFR_VIN_MAX = 0xA1, + PMBUS_MFR_IIN_MAX = 0xA2, + PMBUS_MFR_PIN_MAX = 0xA3, + PMBUS_MFR_VOUT_MIN = 0xA4, + PMBUS_MFR_VOUT_MAX = 0xA5, + PMBUS_MFR_IOUT_MAX = 0xA6, + PMBUS_MFR_POUT_MAX = 0xA7, + + PMBUS_IC_DEVICE_ID = 0xAD, + PMBUS_IC_DEVICE_REV = 0xAE, + + PMBUS_MFR_MAX_TEMP_1 = 0xC0, + PMBUS_MFR_MAX_TEMP_2 = 0xC1, + PMBUS_MFR_MAX_TEMP_3 = 0xC2, + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ + PMBUS_VIRT_BASE = 0x100, + PMBUS_VIRT_READ_TEMP_AVG, + PMBUS_VIRT_READ_TEMP_MIN, + PMBUS_VIRT_READ_TEMP_MAX, + PMBUS_VIRT_RESET_TEMP_HISTORY, + PMBUS_VIRT_READ_VIN_AVG, + PMBUS_VIRT_READ_VIN_MIN, + PMBUS_VIRT_READ_VIN_MAX, + PMBUS_VIRT_RESET_VIN_HISTORY, + PMBUS_VIRT_READ_IIN_AVG, + PMBUS_VIRT_READ_IIN_MIN, + PMBUS_VIRT_READ_IIN_MAX, + PMBUS_VIRT_RESET_IIN_HISTORY, + PMBUS_VIRT_READ_PIN_AVG, + PMBUS_VIRT_READ_PIN_MIN, + PMBUS_VIRT_READ_PIN_MAX, + PMBUS_VIRT_RESET_PIN_HISTORY, + PMBUS_VIRT_READ_POUT_AVG, + PMBUS_VIRT_READ_POUT_MIN, + PMBUS_VIRT_READ_POUT_MAX, + PMBUS_VIRT_RESET_POUT_HISTORY, + PMBUS_VIRT_READ_VOUT_AVG, + PMBUS_VIRT_READ_VOUT_MIN, + PMBUS_VIRT_READ_VOUT_MAX, + PMBUS_VIRT_RESET_VOUT_HISTORY, + PMBUS_VIRT_READ_IOUT_AVG, + PMBUS_VIRT_READ_IOUT_MIN, + PMBUS_VIRT_READ_IOUT_MAX, + PMBUS_VIRT_RESET_IOUT_HISTORY, + PMBUS_VIRT_READ_TEMP2_AVG, + PMBUS_VIRT_READ_TEMP2_MIN, + PMBUS_VIRT_READ_TEMP2_MAX, + PMBUS_VIRT_RESET_TEMP2_HISTORY, + + PMBUS_VIRT_READ_VMON, + PMBUS_VIRT_VMON_UV_WARN_LIMIT, + PMBUS_VIRT_VMON_OV_WARN_LIMIT, + PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + PMBUS_VIRT_STATUS_VMON, + + /* + * RPM and PWM Fan control + * + * Drivers wanting to expose PWM control must define the behaviour of + * PMBUS_VIRT_PWM_[1-4] and PMBUS_VIRT_PWM_ENABLE_[1-4] in the + * {read,write}_word_data callback. + * + * pmbus core provides a default implementation for + * PMBUS_VIRT_FAN_TARGET_[1-4]. + * + * TARGET, PWM and PWM_ENABLE members must be defined sequentially; + * pmbus core uses the difference between the provided register and + * it's _1 counterpart to calculate the FAN/PWM ID. + */ + PMBUS_VIRT_FAN_TARGET_1, + PMBUS_VIRT_FAN_TARGET_2, + PMBUS_VIRT_FAN_TARGET_3, + PMBUS_VIRT_FAN_TARGET_4, + PMBUS_VIRT_PWM_1, + PMBUS_VIRT_PWM_2, + PMBUS_VIRT_PWM_3, + PMBUS_VIRT_PWM_4, + PMBUS_VIRT_PWM_ENABLE_1, + PMBUS_VIRT_PWM_ENABLE_2, + PMBUS_VIRT_PWM_ENABLE_3, + PMBUS_VIRT_PWM_ENABLE_4, + + /* Samples for average + * + * Drivers wanting to expose functionality for changing the number of + * samples used for average values should implement support in + * {read,write}_word_data callback for either PMBUS_VIRT_SAMPLES if it + * applies to all types of measurements, or any number of specific + * PMBUS_VIRT_*_SAMPLES registers to allow for individual control. + */ + PMBUS_VIRT_SAMPLES, + PMBUS_VIRT_IN_SAMPLES, + PMBUS_VIRT_CURR_SAMPLES, + PMBUS_VIRT_POWER_SAMPLES, + PMBUS_VIRT_TEMP_SAMPLES, +}; + +/* + * OPERATION + */ +#define PB_OPERATION_CONTROL_ON BIT(7) + +/* + * WRITE_PROTECT + */ +#define PB_WP_ALL BIT(7) /* all but WRITE_PROTECT */ +#define PB_WP_OP BIT(6) /* all but WP, OPERATION, PAGE */ +#define PB_WP_VOUT BIT(5) /* all but WP, OPERATION, PAGE, VOUT, ON_OFF */ + +#define PB_WP_ANY (PB_WP_ALL | PB_WP_OP | PB_WP_VOUT) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT BIT(4) +#define PB_CAPABILITY_ERROR_CHECK BIT(7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1)) +#define PB_FAN_2_RPM BIT(2) +#define PB_FAN_2_INSTALLED BIT(3) +#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5)) +#define PB_FAN_1_RPM BIT(6) +#define PB_FAN_1_INSTALLED BIT(7) + +enum pmbus_fan_mode { percent = 0, rpm }; + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE BIT(0) +#define PB_STATUS_CML BIT(1) +#define PB_STATUS_TEMPERATURE BIT(2) +#define PB_STATUS_VIN_UV BIT(3) +#define PB_STATUS_IOUT_OC BIT(4) +#define PB_STATUS_VOUT_OV BIT(5) +#define PB_STATUS_OFF BIT(6) +#define PB_STATUS_BUSY BIT(7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN BIT(8) +#define PB_STATUS_OTHER BIT(9) +#define PB_STATUS_FANS BIT(10) +#define PB_STATUS_POWER_GOOD_N BIT(11) +#define PB_STATUS_WORD_MFR BIT(12) +#define PB_STATUS_INPUT BIT(13) +#define PB_STATUS_IOUT_POUT BIT(14) +#define PB_STATUS_VOUT BIT(15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING BIT(0) +#define PB_POUT_OP_FAULT BIT(1) +#define PB_POWER_LIMITING BIT(2) +#define PB_CURRENT_SHARE_FAULT BIT(3) +#define PB_IOUT_UC_FAULT BIT(4) +#define PB_IOUT_OC_WARNING BIT(5) +#define PB_IOUT_OC_LV_FAULT BIT(6) +#define PB_IOUT_OC_FAULT BIT(7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT BIT(4) +#define PB_VOLTAGE_UV_WARNING BIT(5) +#define PB_VOLTAGE_OV_WARNING BIT(6) +#define PB_VOLTAGE_OV_FAULT BIT(7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING BIT(0) +#define PB_IIN_OC_WARNING BIT(1) +#define PB_IIN_OC_FAULT BIT(2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT BIT(4) +#define PB_TEMP_UT_WARNING BIT(5) +#define PB_TEMP_OT_WARNING BIT(6) +#define PB_TEMP_OT_FAULT BIT(7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING BIT(0) +#define PB_FAN_AIRFLOW_FAULT BIT(1) +#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2) +#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3) +#define PB_FAN_FAN2_WARNING BIT(4) +#define PB_FAN_FAN1_WARNING BIT(5) +#define PB_FAN_FAN2_FAULT BIT(6) +#define PB_FAN_FAN1_FAULT BIT(7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) +#define PB_CML_FAULT_OTHER_COMM BIT(1) +#define PB_CML_FAULT_PROCESSOR BIT(3) +#define PB_CML_FAULT_MEMORY BIT(4) +#define PB_CML_FAULT_PACKET_ERROR BIT(5) +#define PB_CML_FAULT_INVALID_DATA BIT(6) +#define PB_CML_FAULT_INVALID_COMMAND BIT(7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_PWM, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ +#define PMBUS_PHASES 8 /* Maximum number of phases per page */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN BIT(0) +#define PMBUS_HAVE_VCAP BIT(1) +#define PMBUS_HAVE_VOUT BIT(2) +#define PMBUS_HAVE_IIN BIT(3) +#define PMBUS_HAVE_IOUT BIT(4) +#define PMBUS_HAVE_PIN BIT(5) +#define PMBUS_HAVE_POUT BIT(6) +#define PMBUS_HAVE_FAN12 BIT(7) +#define PMBUS_HAVE_FAN34 BIT(8) +#define PMBUS_HAVE_TEMP BIT(9) +#define PMBUS_HAVE_TEMP2 BIT(10) +#define PMBUS_HAVE_TEMP3 BIT(11) +#define PMBUS_HAVE_STATUS_VOUT BIT(12) +#define PMBUS_HAVE_STATUS_IOUT BIT(13) +#define PMBUS_HAVE_STATUS_INPUT BIT(14) +#define PMBUS_HAVE_STATUS_TEMP BIT(15) +#define PMBUS_HAVE_STATUS_FAN12 BIT(16) +#define PMBUS_HAVE_STATUS_FAN34 BIT(17) +#define PMBUS_HAVE_VMON BIT(18) +#define PMBUS_HAVE_STATUS_VMON BIT(19) +#define PMBUS_HAVE_PWM12 BIT(20) +#define PMBUS_HAVE_PWM34 BIT(21) +#define PMBUS_HAVE_SAMPLES BIT(22) + +#define PMBUS_PHASE_VIRTUAL BIT(30) /* Phases on this page are virtual */ +#define PMBUS_PAGE_VIRTUAL BIT(31) /* Page is virtual */ + +enum pmbus_data_format { linear = 0, direct, vid }; +enum vrm_version { vr11 = 0, vr12, vr13, imvp9, amd625mv }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + u8 phases[PMBUS_PAGES]; /* Number of phases per page */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + enum vrm_version vrm_version[PMBUS_PAGES]; /* vrm version per page */ + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + u32 pfunc[PMBUS_PHASES];/* Functionality, per phase */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int phase, + int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); + + /* Regulator functionality, if supported by this chip driver. */ + int num_regulators; + const struct regulator_desc *reg_desc; + + /* custom attributes */ + const struct attribute_group **groups; +}; + +/* Regulator ops */ + +extern const struct regulator_ops wb_pmbus_regulator_ops; + +/* Macro for filling in array of struct regulator_desc */ +#define PMBUS_REGULATOR(_name, _id) \ + [_id] = { \ + .name = (_name # _id), \ + .id = (_id), \ + .of_match = of_match_ptr(_name # _id), \ + .regulators_node = of_match_ptr("regulators"), \ + .ops = &wb_pmbus_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +struct pmbus_data { + struct device *dev; + struct device *hwmon_dev; + + u32 flags; /* from platform data */ + + int exponent[PMBUS_PAGES]; /* linear mode: exponent for output voltages */ + + const struct pmbus_driver_info *info; + + int max_attributes; + int num_attributes; + struct attribute_group group; + const struct attribute_group **groups; + struct dentry *debugfs; /* debugfs device directory */ + + struct pmbus_sensor *sensors; + + struct mutex update_lock; + + bool has_status_word; /* device uses STATUS_WORD register */ + int (*read_status)(struct i2c_client *client, int page); + + s16 currpage; /* current page, -1 for unknown/unset */ + s16 currphase; /* current phase, 0xff for all, -1 for unknown/unset */ + int vout_max[PMBUS_PAGES]; /* pmbus maximum output voltage */ + int vout_min[PMBUS_PAGES]; /* pmbus minimum output voltage */ +}; + +/* Function declarations */ +void wb_pmbus_clear_cache(struct i2c_client *client); +int wb_pmbus_set_page(struct i2c_client *client, int page, int phase); +int wb_pmbus_read_word_data(struct i2c_client *client, int page, int phase, + u8 reg); +int wb_pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, + u16 word); +int wb_pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int wb_pmbus_write_byte(struct i2c_client *client, int page, u8 value); +int wb_pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, + u8 value); +int wb_pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, + u8 mask, u8 value); +void wb_pmbus_clear_faults(struct i2c_client *client); +bool wb_pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool wb_pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int wb_pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info); +int wb_pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *wb_pmbus_get_driver_info(struct i2c_client + *client); +int wb_pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode); +int wb_pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode); +int wb_pmbus_update_fan(struct i2c_client *client, int page, int id, + u8 config, u8 mask, u16 command); +struct dentry *wb_pmbus_get_debugfs_dir(struct i2c_client *client); + +#endif /* WB_PMBUS_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus_core.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus_core.c new file mode 100644 index 000000000000..bba6ca39cd3c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus_core.c @@ -0,0 +1,2780 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Hardware monitoring driver for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_pmbus.h" + +/* + * Number of additional attribute pointers to allocate + * with each call to krealloc + */ +#define PMBUS_ATTR_ALLOC_SIZE (32) +#define PMBUS_NAME_SIZE (24) +#define PMBUS_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define PMBUS_RETRY_TIME (3) + +struct pmbus_sensor { + struct pmbus_sensor *next; + char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ + struct device_attribute attribute; + u8 page; /* page number */ + u8 phase; /* phase number, 0xff for all phases */ + u16 reg; /* register */ + enum pmbus_sensor_classes class; /* sensor class */ + bool update; /* runtime sensor update needed */ + bool convert; /* Whether or not to apply linear/vid/direct */ + int data; /* Sensor data. + Negative if there was a read error */ +}; +#define to_pmbus_sensor(_attr) \ + container_of(_attr, struct pmbus_sensor, attribute) + +struct pmbus_boolean { + char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ + struct sensor_device_attribute attribute; + struct pmbus_sensor *s1; + struct pmbus_sensor *s2; +}; +#define to_pmbus_boolean(_attr) \ + container_of(_attr, struct pmbus_boolean, attribute) + +struct pmbus_label { + char name[PMBUS_NAME_SIZE]; /* sysfs label name */ + struct device_attribute attribute; + char label[PMBUS_NAME_SIZE]; /* label */ +}; +#define to_pmbus_label(_attr) \ + container_of(_attr, struct pmbus_label, attribute) + +/* Macros for converting between sensor index and register/page/status mask */ + +#define PB_STATUS_MASK 0xffff +#define PB_REG_SHIFT 16 +#define PB_REG_MASK 0x3ff +#define PB_PAGE_SHIFT 26 +#define PB_PAGE_MASK 0x3f + +#define pb_reg_to_index(page, reg, mask) (((page) << PB_PAGE_SHIFT) | \ + ((reg) << PB_REG_SHIFT) | (mask)) + +#define pb_index_to_page(index) (((index) >> PB_PAGE_SHIFT) & PB_PAGE_MASK) +#define pb_index_to_reg(index) (((index) >> PB_REG_SHIFT) & PB_REG_MASK) +#define pb_index_to_mask(index) ((index) & PB_STATUS_MASK) + +struct pmbus_debugfs_entry { + struct i2c_client *client; + u8 page; + u8 reg; +}; + +static const int pmbus_fan_rpm_mask[] = { + PB_FAN_1_RPM, + PB_FAN_2_RPM, + PB_FAN_1_RPM, + PB_FAN_2_RPM, +}; + +static const int pmbus_fan_config_registers[] = { + PMBUS_FAN_CONFIG_12, + PMBUS_FAN_CONFIG_12, + PMBUS_FAN_CONFIG_34, + PMBUS_FAN_CONFIG_34 +}; + +static const int pmbus_fan_command_registers[] = { + PMBUS_FAN_COMMAND_1, + PMBUS_FAN_COMMAND_2, + PMBUS_FAN_COMMAND_3, + PMBUS_FAN_COMMAND_4, +}; + +void wb_pmbus_clear_cache(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor *sensor; + + for (sensor = data->sensors; sensor; sensor = sensor->next) + sensor->data = -ENODATA; +} +EXPORT_SYMBOL_GPL(wb_pmbus_clear_cache); + +static int wb_pmbus_set_page_tmp(struct i2c_client *client, int page, int phase) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int rv; + + if (page < 0) + return 0; + + if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL) && + data->info->pages > 1 && page != data->currpage) { + rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); + if (rv < 0) + return rv; + + rv = i2c_smbus_read_byte_data(client, PMBUS_PAGE); + if (rv < 0) + return rv; + + if (rv != page) + return -EIO; + } + data->currpage = page; + + if (data->info->phases[page] && data->currphase != phase && + !(data->info->func[page] & PMBUS_PHASE_VIRTUAL)) { + rv = i2c_smbus_write_byte_data(client, PMBUS_PHASE, + phase); + if (rv) + return rv; + } + data->currphase = phase; + + return 0; +} + +int wb_pmbus_set_page(struct i2c_client *client, int page, int phase) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_set_page_tmp(client, page, phase); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_set_page failed, page=%d, phase=%d, rv=%d\n", + page, phase, rv); + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_set_page); + +static int wb_pmbus_write_byte_tmp(struct i2c_client *client, int page, u8 value) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, 0xff); + if (rv < 0) + return rv; + + return i2c_smbus_write_byte(client, value); +} + +int wb_pmbus_write_byte(struct i2c_client *client, int page, u8 value) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_write_byte_tmp(client, page, value); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_write_byte failed, page=%d, value=0x%x, rv: %d\n", + page, value, rv); + return rv; +} + +EXPORT_SYMBOL_GPL(wb_pmbus_write_byte); + +/* + * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->write_byte) { + status = info->write_byte(client, page, value); + if (status != -ENODATA) + return status; + } + return wb_pmbus_write_byte(client, page, value); +} + +static int wb_pmbus_write_word_data_tmp(struct i2c_client *client, int page, u8 reg, + u16 word) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, 0xff); + if (rv < 0) + return rv; + + return i2c_smbus_write_word_data(client, reg, word); +} + +int wb_pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, + u16 word) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_write_word_data_tmp(client, page, reg, word); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_write_word_data failed, page: %d, reg: 0x%x, value: 0x%x, rv: %d\n", + page, reg, word, rv); + return rv; + +} +EXPORT_SYMBOL_GPL(wb_pmbus_write_word_data); + +static int pmbus_write_virt_reg(struct i2c_client *client, int page, int reg, + u16 word) +{ + int bit; + int id; + int rv; + + switch (reg) { + case PMBUS_VIRT_FAN_TARGET_1 ... PMBUS_VIRT_FAN_TARGET_4: + id = reg - PMBUS_VIRT_FAN_TARGET_1; + bit = pmbus_fan_rpm_mask[id]; + rv = wb_pmbus_update_fan(client, page, id, bit, bit, word); + break; + default: + rv = -ENXIO; + break; + } + + return rv; +} + +/* + * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, + u16 word) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->write_word_data) { + status = info->write_word_data(client, page, reg, word); + if (status != -ENODATA) + return status; + } + + if (reg >= PMBUS_VIRT_BASE) + return pmbus_write_virt_reg(client, page, reg, word); + + return wb_pmbus_write_word_data(client, page, reg, word); +} + +int wb_pmbus_update_fan(struct i2c_client *client, int page, int id, + u8 config, u8 mask, u16 command) +{ + int from; + int rv; + u8 to; + + from = wb_pmbus_read_byte_data(client, page, + pmbus_fan_config_registers[id]); + if (from < 0) + return from; + + to = (from & ~mask) | (config & mask); + if (to != from) { + rv = wb_pmbus_write_byte_data(client, page, + pmbus_fan_config_registers[id], to); + if (rv < 0) + return rv; + } + + return _pmbus_write_word_data(client, page, + pmbus_fan_command_registers[id], command); +} +EXPORT_SYMBOL_GPL(wb_pmbus_update_fan); + +static int wb_pmbus_read_word_data_tmp(struct i2c_client *client, int page, int phase, u8 reg) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, phase); + if (rv < 0) + return rv; + + return i2c_smbus_read_word_data(client, reg); +} + +int wb_pmbus_read_word_data(struct i2c_client *client, int page, int phase, u8 reg) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_read_word_data_tmp(client, page, phase, reg); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_read_word_data failed, page: %d, phase: %d, reg: 0x%x, rv: %d\n", + page, phase, reg, rv); + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_read_word_data); + +static int pmbus_read_virt_reg(struct i2c_client *client, int page, int reg) +{ + int rv; + int id; + + switch (reg) { + case PMBUS_VIRT_FAN_TARGET_1 ... PMBUS_VIRT_FAN_TARGET_4: + id = reg - PMBUS_VIRT_FAN_TARGET_1; + rv = wb_pmbus_get_fan_rate_device(client, page, id, rpm); + break; + default: + rv = -ENXIO; + break; + } + + return rv; +} + +/* + * _pmbus_read_word_data() is similar to wb_pmbus_read_word_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_read_word_data(struct i2c_client *client, int page, + int phase, int reg) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->read_word_data) { + status = info->read_word_data(client, page, phase, reg); + if (status != -ENODATA) + return status; + } + + if (reg >= PMBUS_VIRT_BASE) + return pmbus_read_virt_reg(client, page, reg); + + return wb_pmbus_read_word_data(client, page, phase, reg); +} + +/* Same as above, but without phase parameter, for use in check functions */ +static int __pmbus_read_word_data(struct i2c_client *client, int page, int reg) +{ + return _pmbus_read_word_data(client, page, 0xff, reg); +} + +static int wb_pmbus_read_byte_data_tmp(struct i2c_client *client, int page, u8 reg) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, 0xff); + if (rv < 0) + return rv; + + return i2c_smbus_read_byte_data(client, reg); +} + +int wb_pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_read_byte_data_tmp(client, page, reg); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_read_byte_data failed, page: %d, reg: 0x%x, rv: %d\n", + page, reg, rv); + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_read_byte_data); + +static int wb_pmbus_write_byte_data_tmp(struct i2c_client *client, int page, u8 reg, u8 value) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, 0xff); + if (rv < 0) + return rv; + + return i2c_smbus_write_byte_data(client, reg, value); +} + +int wb_pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, u8 value) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_write_byte_data_tmp(client, page, reg, value); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_write_byte_data failed, page: %d, reg: 0x%x, value: 0x%x, rv: %d\n", + page, reg, value, rv); + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_write_byte_data); + +int wb_pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, + u8 mask, u8 value) +{ + unsigned int tmp; + int rv; + + rv = wb_pmbus_read_byte_data(client, page, reg); + if (rv < 0) + return rv; + + tmp = (rv & ~mask) | (value & mask); + + if (tmp != rv) + rv = wb_pmbus_write_byte_data(client, page, reg, tmp); + + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_update_byte_data); + +/* + * _pmbus_read_byte_data() is similar to wb_pmbus_read_byte_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->read_byte_data) { + status = info->read_byte_data(client, page, reg); + if (status != -ENODATA) + return status; + } + return wb_pmbus_read_byte_data(client, page, reg); +} + +static struct pmbus_sensor *pmbus_find_sensor(struct pmbus_data *data, int page, + int reg) +{ + struct pmbus_sensor *sensor; + + for (sensor = data->sensors; sensor; sensor = sensor->next) { + if (sensor->page == page && sensor->reg == reg) + return sensor; + } + + return ERR_PTR(-EINVAL); +} + +static int pmbus_get_fan_rate(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode, + bool from_cache) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + bool want_rpm, have_rpm; + struct pmbus_sensor *s; + int config; + int reg; + + want_rpm = (mode == rpm); + + if (from_cache) { + reg = want_rpm ? PMBUS_VIRT_FAN_TARGET_1 : PMBUS_VIRT_PWM_1; + s = pmbus_find_sensor(data, page, reg + id); + if (IS_ERR(s)) + return PTR_ERR(s); + + return s->data; + } + + config = wb_pmbus_read_byte_data(client, page, + pmbus_fan_config_registers[id]); + if (config < 0) + return config; + + have_rpm = !!(config & pmbus_fan_rpm_mask[id]); + if (want_rpm == have_rpm) + return wb_pmbus_read_word_data(client, page, 0xff, + pmbus_fan_command_registers[id]); + + /* Can't sensibly map between RPM and PWM, just return zero */ + return 0; +} + +int wb_pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode) +{ + return pmbus_get_fan_rate(client, page, id, mode, false); +} +EXPORT_SYMBOL_GPL(wb_pmbus_get_fan_rate_device); + +int wb_pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode) +{ + return pmbus_get_fan_rate(client, page, id, mode, true); +} +EXPORT_SYMBOL_GPL(wb_pmbus_get_fan_rate_cached); + +static void pmbus_clear_fault_page(struct i2c_client *client, int page) +{ + _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); +} + +void wb_pmbus_clear_faults(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int i; + + for (i = 0; i < data->info->pages; i++) + pmbus_clear_fault_page(client, i); +} +EXPORT_SYMBOL_GPL(wb_pmbus_clear_faults); + +static int pmbus_check_status_cml(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int status, status2; + + status = data->read_status(client, -1); + if (status < 0 || (status & PB_STATUS_CML)) { + status2 = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); + if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND)) + return -EIO; + } + return 0; +} + +static bool pmbus_check_register(struct i2c_client *client, + int (*func)(struct i2c_client *client, + int page, int reg), + int page, int reg) +{ + int rv; + struct pmbus_data *data = i2c_get_clientdata(client); + + rv = func(client, page, reg); + if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) + rv = pmbus_check_status_cml(client); + pmbus_clear_fault_page(client, -1); + return rv >= 0; +} + +static bool pmbus_check_status_register(struct i2c_client *client, int page) +{ + int status; + struct pmbus_data *data = i2c_get_clientdata(client); + + status = data->read_status(client, page); + if (status >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK) && + (status & PB_STATUS_CML)) { + status = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); + if (status < 0 || (status & PB_CML_FAULT_INVALID_COMMAND)) + status = -EIO; + } + + pmbus_clear_fault_page(client, -1); + return status >= 0; +} + +bool wb_pmbus_check_byte_register(struct i2c_client *client, int page, int reg) +{ + return pmbus_check_register(client, _pmbus_read_byte_data, page, reg); +} +EXPORT_SYMBOL_GPL(wb_pmbus_check_byte_register); + +bool wb_pmbus_check_word_register(struct i2c_client *client, int page, int reg) +{ + return pmbus_check_register(client, __pmbus_read_word_data, page, reg); +} +EXPORT_SYMBOL_GPL(wb_pmbus_check_word_register); + +const struct pmbus_driver_info *wb_pmbus_get_driver_info(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + + return data->info; +} +EXPORT_SYMBOL_GPL(wb_pmbus_get_driver_info); + +static int pmbus_read_status_byte(struct i2c_client *client, int page) +{ + return _pmbus_read_byte_data(client, page, PMBUS_STATUS_BYTE); +} + +static int pmbus_read_status_word(struct i2c_client *client, int page) +{ + return _pmbus_read_word_data(client, page, 0xff, PMBUS_STATUS_WORD); +} + +static int pmbus_get_status(struct i2c_client *client, int page, int reg) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int status; + + switch (reg) { + case PMBUS_STATUS_WORD: + status = data->read_status(client, page); + if ((status < 0) || (data->has_status_word && (status == 0xffff)) + || (!data->has_status_word && (status == 0xff))) { + if (data->has_status_word) { + data->read_status = pmbus_read_status_byte; + } else { + data->read_status = pmbus_read_status_word; + } + data->has_status_word = !data->has_status_word; + status = data->read_status(client, page); + } + break; + default: + status = _pmbus_read_byte_data(client, page, reg); + break; + } + if (status < 0) + wb_pmbus_clear_faults(client); + return status; +} + +static void pmbus_update_sensor_data(struct i2c_client *client, struct pmbus_sensor *sensor) +{ + if (sensor->data < 0 || sensor->update) + sensor->data = _pmbus_read_word_data(client, sensor->page, + sensor->phase, sensor->reg); +} + +/* + * Convert linear sensor values to milli- or micro-units + * depending on sensor type. + */ +static s64 pmbus_reg2data_linear(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + s16 exponent; + s32 mantissa; + s64 val; + + if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ + exponent = data->exponent[sensor->page]; + mantissa = (u16) sensor->data; + } else { /* LINEAR11 */ + exponent = ((s16)sensor->data) >> 11; + mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5; + } + + val = mantissa; + + /* scale result to milli-units for all sensors except fans */ + if (sensor->class != PSC_FAN) + val = val * 1000LL; + + /* scale result to micro-units for power sensors */ + if (sensor->class == PSC_POWER) + val = val * 1000LL; + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val; +} + +/* + * Convert direct sensor values to milli- or micro-units + * depending on sensor type. + */ +static s64 pmbus_reg2data_direct(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + s64 b, val = (s16)sensor->data; + s32 m, R; + + m = data->info->m[sensor->class]; + b = data->info->b[sensor->class]; + R = data->info->R[sensor->class]; + + if (m == 0) + return 0; + + /* X = 1/m * (Y * 10^-R - b) */ + R = -R; + /* scale result to milli-units for everything but fans */ + if (!(sensor->class == PSC_FAN || sensor->class == PSC_PWM)) { + R += 3; + b *= 1000; + } + + /* scale result to micro-units for power sensors */ + if (sensor->class == PSC_POWER) { + R += 3; + b *= 1000; + } + + while (R > 0) { + val *= 10; + R--; + } + while (R < 0) { + val = div_s64(val + 5LL, 10L); /* round closest */ + R++; + } + + val = div_s64(val - b, m); + return val; +} + +/* + * Convert VID sensor values to milli- or micro-units + * depending on sensor type. + */ +static s64 pmbus_reg2data_vid(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + long val = sensor->data; + long rv = 0; + + switch (data->info->vrm_version[sensor->page]) { + case vr11: + if (val >= 0x02 && val <= 0xb2) + rv = DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100); + break; + case vr12: + if (val >= 0x01) + rv = 250 + (val - 1) * 5; + break; + case vr13: + if (val >= 0x01) + rv = 500 + (val - 1) * 10; + break; + case imvp9: + if (val >= 0x01) + rv = 200 + (val - 1) * 10; + break; + case amd625mv: + if (val >= 0x0 && val <= 0xd8) + rv = DIV_ROUND_CLOSEST(155000 - val * 625, 100); + break; + } + return rv; +} + +static s64 pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) +{ + s64 val; + + if (!sensor->convert) + return sensor->data; + + switch (data->info->format[sensor->class]) { + case direct: + val = pmbus_reg2data_direct(data, sensor); + break; + case vid: + val = pmbus_reg2data_vid(data, sensor); + break; + case linear: + default: + val = pmbus_reg2data_linear(data, sensor); + break; + } + return val; +} + +#define MAX_MANTISSA (1023 * 1000) +#define MIN_MANTISSA (511 * 1000) + +static u16 pmbus_data2reg_linear(struct pmbus_data *data, + struct pmbus_sensor *sensor, s64 val) +{ + s16 exponent = 0, mantissa; + bool negative = false; + + /* simple case */ + if (val == 0) + return 0; + + if (sensor->class == PSC_VOLTAGE_OUT) { + /* LINEAR16 does not support negative voltages */ + if (val < 0) + return 0; + + /* + * For a static exponents, we don't have a choice + * but to adjust the value to it. + */ + if (data->exponent[sensor->page] < 0) + val <<= -data->exponent[sensor->page]; + else + val >>= data->exponent[sensor->page]; + val = DIV_ROUND_CLOSEST_ULL(val, 1000); + return clamp_val(val, 0, 0xffff); + } + + if (val < 0) { + negative = true; + val = -val; + } + + /* Power is in uW. Convert to mW before converting. */ + if (sensor->class == PSC_POWER) + val = DIV_ROUND_CLOSEST_ULL(val, 1000); + + /* + * For simplicity, convert fan data to milli-units + * before calculating the exponent. + */ + if (sensor->class == PSC_FAN) + val = val * 1000LL; + + /* Reduce large mantissa until it fits into 10 bit */ + while (val >= MAX_MANTISSA && exponent < 15) { + exponent++; + val >>= 1; + } + /* Increase small mantissa to improve precision */ + while (val < MIN_MANTISSA && exponent > -15) { + exponent--; + val <<= 1; + } + + /* Convert mantissa from milli-units to units */ + mantissa = clamp_val(DIV_ROUND_CLOSEST_ULL(val, 1000), 0, 0x3ff); + + /* restore sign */ + if (negative) + mantissa = -mantissa; + + /* Convert to 5 bit exponent, 11 bit mantissa */ + return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800); +} + +static u16 pmbus_data2reg_direct(struct pmbus_data *data, + struct pmbus_sensor *sensor, s64 val) +{ + s64 b; + s32 m, R; + + m = data->info->m[sensor->class]; + b = data->info->b[sensor->class]; + R = data->info->R[sensor->class]; + + /* Power is in uW. Adjust R and b. */ + if (sensor->class == PSC_POWER) { + R -= 3; + b *= 1000; + } + + /* Calculate Y = (m * X + b) * 10^R */ + if (!(sensor->class == PSC_FAN || sensor->class == PSC_PWM)) { + R -= 3; /* Adjust R and b for data in milli-units */ + b *= 1000; + } + val = val * m + b; + + while (R > 0) { + val *= 10; + R--; + } + while (R < 0) { + val = div_s64(val + 5LL, 10L); /* round closest */ + R++; + } + + return (u16)clamp_val(val, S16_MIN, S16_MAX); +} + +static u16 pmbus_data2reg_vid(struct pmbus_data *data, + struct pmbus_sensor *sensor, s64 val) +{ + val = clamp_val(val, 500, 1600); + + return 2 + DIV_ROUND_CLOSEST_ULL((1600LL - val) * 100LL, 625); +} + +static u16 pmbus_data2reg(struct pmbus_data *data, + struct pmbus_sensor *sensor, s64 val) +{ + u16 regval; + + if (!sensor->convert) + return val; + + switch (data->info->format[sensor->class]) { + case direct: + regval = pmbus_data2reg_direct(data, sensor, val); + break; + case vid: + regval = pmbus_data2reg_vid(data, sensor, val); + break; + case linear: + default: + regval = pmbus_data2reg_linear(data, sensor, val); + break; + } + return regval; +} + +/* + * Return boolean calculated from converted data. + * defines a status register index and mask. + * The mask is in the lower 8 bits, the register index is in bits 8..23. + * + * The associated pmbus_boolean structure contains optional pointers to two + * sensor attributes. If specified, those attributes are compared against each + * other to determine if a limit has been exceeded. + * + * If the sensor attribute pointers are NULL, the function returns true if + * (status[reg] & mask) is true. + * + * If sensor attribute pointers are provided, a comparison against a specified + * limit has to be performed to determine the boolean result. + * In this case, the function returns true if v1 >= v2 (where v1 and v2 are + * sensor values referenced by sensor attribute pointers s1 and s2). + * + * To determine if an object exceeds upper limits, specify = . + * To determine if an object exceeds lower limits, specify = . + * + * If a negative value is stored in any of the referenced registers, this value + * reflects an error code which will be returned. + */ +static int pmbus_get_boolean(struct i2c_client *client, struct pmbus_boolean *b, + int index) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor *s1 = b->s1; + struct pmbus_sensor *s2 = b->s2; + u16 mask = pb_index_to_mask(index); + u8 page = pb_index_to_page(index); + u16 reg = pb_index_to_reg(index); + int ret, status; + u16 regval; + + mutex_lock(&data->update_lock); + status = pmbus_get_status(client, page, reg); + if (status < 0) { + ret = status; + goto unlock; + } + + if (s1) + pmbus_update_sensor_data(client, s1); + if (s2) + pmbus_update_sensor_data(client, s2); + + regval = status & mask; + if (s1 && s2) { + s64 v1, v2; + + if (s1->data < 0) { + ret = s1->data; + goto unlock; + } + if (s2->data < 0) { + ret = s2->data; + goto unlock; + } + + v1 = pmbus_reg2data(data, s1); + v2 = pmbus_reg2data(data, s2); + ret = !!(regval && v1 >= v2); + } else { + ret = !!regval; + } +unlock: + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t pmbus_show_boolean(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct pmbus_boolean *boolean = to_pmbus_boolean(attr); + struct i2c_client *client = to_i2c_client(dev->parent); + int val; + + val = pmbus_get_boolean(client, boolean, attr->index); + if (val < 0) + return val; + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t pmbus_show_sensor(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + ssize_t ret; + + mutex_lock(&data->update_lock); + pmbus_update_sensor_data(client, sensor); + if (sensor->data < 0) + ret = sensor->data; + else + ret = snprintf(buf, PAGE_SIZE, "%lld\n", pmbus_reg2data(data, sensor)); + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t pmbus_set_sensor(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); + ssize_t rv = count; + s64 val; + int ret; + u16 regval; + + if (kstrtos64(buf, 10, &val) < 0) + return -EINVAL; + + mutex_lock(&data->update_lock); + regval = pmbus_data2reg(data, sensor, val); + ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); + if (ret < 0) + rv = ret; + else + sensor->data = regval; + mutex_unlock(&data->update_lock); + return rv; +} + +static ssize_t pmbus_show_label(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct pmbus_label *label = to_pmbus_label(da); + + return snprintf(buf, PAGE_SIZE, "%s\n", label->label); +} + +static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr) +{ + if (data->num_attributes >= data->max_attributes - 1) { + int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE; + void *new_attrs = devm_krealloc(data->dev, data->group.attrs, + new_max_attrs * sizeof(void *), + GFP_KERNEL); + if (!new_attrs) + return -ENOMEM; + data->group.attrs = new_attrs; + data->max_attributes = new_max_attrs; + } + + data->group.attrs[data->num_attributes++] = attr; + data->group.attrs[data->num_attributes] = NULL; + return 0; +} + +static void pmbus_dev_attr_init(struct device_attribute *dev_attr, + const char *name, + umode_t mode, + ssize_t (*show)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*store)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count)) +{ + sysfs_attr_init(&dev_attr->attr); + dev_attr->attr.name = name; + dev_attr->attr.mode = mode; + dev_attr->show = show; + dev_attr->store = store; +} + +static void pmbus_attr_init(struct sensor_device_attribute *a, + const char *name, + umode_t mode, + ssize_t (*show)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*store)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count), + int idx) +{ + pmbus_dev_attr_init(&a->dev_attr, name, mode, show, store); + a->index = idx; +} + +static int pmbus_add_boolean(struct pmbus_data *data, + const char *name, const char *type, int seq, + struct pmbus_sensor *s1, + struct pmbus_sensor *s2, + u8 page, u16 reg, u16 mask) +{ + struct pmbus_boolean *boolean; + struct sensor_device_attribute *a; + + if (WARN((s1 && !s2) || (!s1 && s2), "Bad s1/s2 parameters\n")) + return -EINVAL; + + boolean = devm_kzalloc(data->dev, sizeof(*boolean), GFP_KERNEL); + if (!boolean) + return -ENOMEM; + + a = &boolean->attribute; + + snprintf(boolean->name, sizeof(boolean->name), "%s%d_%s", + name, seq, type); + boolean->s1 = s1; + boolean->s2 = s2; + pmbus_attr_init(a, boolean->name, 0444, pmbus_show_boolean, NULL, + pb_reg_to_index(page, reg, mask)); + + return pmbus_add_attribute(data, &a->dev_attr.attr); +} + +static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, + const char *name, const char *type, + int seq, int page, int phase, + int reg, + enum pmbus_sensor_classes class, + bool update, bool readonly, + bool convert) +{ + struct pmbus_sensor *sensor; + struct device_attribute *a; + + sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) + return NULL; + a = &sensor->attribute; + + if (type) + snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", + name, seq, type); + else + snprintf(sensor->name, sizeof(sensor->name), "%s%d", + name, seq); + + if (data->flags & PMBUS_WRITE_PROTECTED) + readonly = true; + + sensor->page = page; + sensor->phase = phase; + sensor->reg = reg; + sensor->class = class; + sensor->update = update; + sensor->convert = convert; + sensor->data = -ENODATA; + pmbus_dev_attr_init(a, sensor->name, + readonly ? 0444 : 0644, + pmbus_show_sensor, pmbus_set_sensor); + + if (pmbus_add_attribute(data, &a->attr)) + return NULL; + + sensor->next = data->sensors; + data->sensors = sensor; + + return sensor; +} + +static int pmbus_add_label(struct pmbus_data *data, + const char *name, int seq, + const char *lstring, int index, int phase) +{ + struct pmbus_label *label; + struct device_attribute *a; + + label = devm_kzalloc(data->dev, sizeof(*label), GFP_KERNEL); + if (!label) + return -ENOMEM; + + a = &label->attribute; + + snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq); + if (!index) { + if (phase == 0xff) + strncpy(label->label, lstring, + sizeof(label->label) - 1); + else + snprintf(label->label, sizeof(label->label), "%s.%d", + lstring, phase); + } else { + if (phase == 0xff) + snprintf(label->label, sizeof(label->label), "%s%d", + lstring, index); + else + snprintf(label->label, sizeof(label->label), "%s%d.%d", + lstring, index, phase); + } + + pmbus_dev_attr_init(a, label->name, 0444, pmbus_show_label, NULL); + return pmbus_add_attribute(data, &a->attr); +} + +/* + * Search for attributes. Allocate sensors, booleans, and labels as needed. + */ + +/* + * The pmbus_limit_attr structure describes a single limit attribute + * and its associated alarm attribute. + */ +struct pmbus_limit_attr { + u16 reg; /* Limit register */ + u16 sbit; /* Alarm attribute status bit */ + bool update; /* True if register needs updates */ + bool low; /* True if low limit; for limits with compare + functions only */ + const char *attr; /* Attribute name */ + const char *alarm; /* Alarm attribute name */ +}; + +/* + * The pmbus_sensor_attr structure describes one sensor attribute. This + * description includes a reference to the associated limit attributes. + */ +struct pmbus_sensor_attr { + u16 reg; /* sensor register */ + u16 gbit; /* generic status bit */ + u8 nlimit; /* # of limit registers */ + enum pmbus_sensor_classes class;/* sensor class */ + const char *label; /* sensor label */ + bool paged; /* true if paged sensor */ + bool update; /* true if update needed */ + bool compare; /* true if compare function needed */ + u32 func; /* sensor mask */ + u32 sfunc; /* sensor status mask */ + int sreg; /* status register */ + const struct pmbus_limit_attr *limit;/* limit registers */ +}; + +/* + * Add a set of limit attributes and, if supported, the associated + * alarm attributes. + * returns 0 if no alarm register found, 1 if an alarm register was found, + * < 0 on errors. + */ +static int pmbus_add_limit_attrs(struct i2c_client *client, + struct pmbus_data *data, + const struct pmbus_driver_info *info, + const char *name, int index, int page, + struct pmbus_sensor *base, + const struct pmbus_sensor_attr *attr) +{ + const struct pmbus_limit_attr *l = attr->limit; + int nlimit = attr->nlimit; + int have_alarm = 0; + int i, ret; + struct pmbus_sensor *curr; + + for (i = 0; i < nlimit; i++) { + if (wb_pmbus_check_word_register(client, page, l->reg)) { + curr = pmbus_add_sensor(data, name, l->attr, index, + page, 0xff, l->reg, attr->class, + attr->update || l->update, + false, true); + if (!curr) + return -ENOMEM; + if (l->sbit && (info->func[page] & attr->sfunc)) { + ret = pmbus_add_boolean(data, name, + l->alarm, index, + attr->compare ? l->low ? curr : base + : NULL, + attr->compare ? l->low ? base : curr + : NULL, + page, attr->sreg, l->sbit); + if (ret) + return ret; + have_alarm = 1; + } + } + l++; + } + return have_alarm; +} + +static int pmbus_add_sensor_attrs_one(struct i2c_client *client, + struct pmbus_data *data, + const struct pmbus_driver_info *info, + const char *name, + int index, int page, int phase, + const struct pmbus_sensor_attr *attr, + bool paged) +{ + struct pmbus_sensor *base; + bool upper = !!(attr->gbit & 0xff00); /* need to check STATUS_WORD */ + int ret; + + if (attr->label) { + ret = pmbus_add_label(data, name, index, attr->label, + paged ? page + 1 : 0, phase); + if (ret) + return ret; + } + base = pmbus_add_sensor(data, name, "input", index, page, phase, + attr->reg, attr->class, true, true, true); + if (!base) + return -ENOMEM; + /* No limit and alarm attributes for phase specific sensors */ + if (attr->sfunc && phase == 0xff) { + ret = pmbus_add_limit_attrs(client, data, info, name, + index, page, base, attr); + if (ret < 0) + return ret; + /* + * Add generic alarm attribute only if there are no individual + * alarm attributes, if there is a global alarm bit, and if + * the generic status register (word or byte, depending on + * which global bit is set) for this page is accessible. + */ + if (!ret && attr->gbit && + (!upper || (upper && data->has_status_word)) && + pmbus_check_status_register(client, page)) { + ret = pmbus_add_boolean(data, name, "alarm", index, + NULL, NULL, + page, PMBUS_STATUS_WORD, + attr->gbit); + if (ret) + return ret; + } + } + return 0; +} + +static bool pmbus_sensor_is_paged(const struct pmbus_driver_info *info, + const struct pmbus_sensor_attr *attr) +{ + int p; + + if (attr->paged) + return true; + + /* + * Some attributes may be present on more than one page despite + * not being marked with the paged attribute. If that is the case, + * then treat the sensor as being paged and add the page suffix to the + * attribute name. + * We don't just add the paged attribute to all such attributes, in + * order to maintain the un-suffixed labels in the case where the + * attribute is only on page 0. + */ + for (p = 1; p < info->pages; p++) { + if (info->func[p] & attr->func) + return true; + } + return false; +} + +static int pmbus_add_sensor_attrs(struct i2c_client *client, + struct pmbus_data *data, + const char *name, + const struct pmbus_sensor_attr *attrs, + int nattrs) +{ + const struct pmbus_driver_info *info = data->info; + int index, i; + int ret; + + index = 1; + for (i = 0; i < nattrs; i++) { + int page, pages; + bool paged = pmbus_sensor_is_paged(info, attrs); + + pages = paged ? info->pages : 1; + for (page = 0; page < pages; page++) { + if (!(info->func[page] & attrs->func)) + continue; + ret = pmbus_add_sensor_attrs_one(client, data, info, + name, index, page, + 0xff, attrs, paged); + if (ret) + return ret; + index++; + if (info->phases[page]) { + int phase; + + for (phase = 0; phase < info->phases[page]; + phase++) { + if (!(info->pfunc[phase] & attrs->func)) + continue; + ret = pmbus_add_sensor_attrs_one(client, + data, info, name, index, page, + phase, attrs, paged); + if (ret) + return ret; + index++; + } + } + } + attrs++; + } + return 0; +} + +static const struct pmbus_limit_attr vin_limit_attrs[] = { + { + .reg = PMBUS_VIN_UV_WARN_LIMIT, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_VOLTAGE_UV_WARNING, + }, { + .reg = PMBUS_VIN_UV_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_VOLTAGE_UV_FAULT, + }, { + .reg = PMBUS_VIN_OV_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_VOLTAGE_OV_WARNING, + }, { + .reg = PMBUS_VIN_OV_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_VOLTAGE_OV_FAULT, + }, { + .reg = PMBUS_VIRT_READ_VIN_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_VIN_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_VIN_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_VIN_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_VIN_MIN, + .attr = "rated_min", + }, { + .reg = PMBUS_MFR_VIN_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr vmon_limit_attrs[] = { + { + .reg = PMBUS_VIRT_VMON_UV_WARN_LIMIT, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_VOLTAGE_UV_WARNING, + }, { + .reg = PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_VOLTAGE_UV_FAULT, + }, { + .reg = PMBUS_VIRT_VMON_OV_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_VOLTAGE_OV_WARNING, + }, { + .reg = PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_VOLTAGE_OV_FAULT, + } +}; + +static const struct pmbus_limit_attr vout_limit_attrs[] = { + { + .reg = PMBUS_VOUT_UV_WARN_LIMIT, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_VOLTAGE_UV_WARNING, + }, { + .reg = PMBUS_VOUT_UV_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_VOLTAGE_UV_FAULT, + }, { + .reg = PMBUS_VOUT_OV_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_VOLTAGE_OV_WARNING, + }, { + .reg = PMBUS_VOUT_OV_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_VOLTAGE_OV_FAULT, + }, { + .reg = PMBUS_VIRT_READ_VOUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_VOUT_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_VOUT_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_VOUT_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_VOUT_MIN, + .attr = "rated_min", + }, { + .reg = PMBUS_MFR_VOUT_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_sensor_attr voltage_attributes[] = { + { + .reg = PMBUS_READ_VIN, + .class = PSC_VOLTAGE_IN, + .label = "vin", + .func = PMBUS_HAVE_VIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sreg = PMBUS_STATUS_INPUT, + .gbit = PB_STATUS_VIN_UV, + .limit = vin_limit_attrs, + .nlimit = ARRAY_SIZE(vin_limit_attrs), + }, { + .reg = PMBUS_VIRT_READ_VMON, + .class = PSC_VOLTAGE_IN, + .label = "vmon", + .func = PMBUS_HAVE_VMON, + .sfunc = PMBUS_HAVE_STATUS_VMON, + .sreg = PMBUS_VIRT_STATUS_VMON, + .limit = vmon_limit_attrs, + .nlimit = ARRAY_SIZE(vmon_limit_attrs), + }, { + .reg = PMBUS_READ_VCAP, + .class = PSC_VOLTAGE_IN, + .label = "vcap", + .func = PMBUS_HAVE_VCAP, + }, { + .reg = PMBUS_READ_VOUT, + .class = PSC_VOLTAGE_OUT, + .label = "vout", + .paged = true, + .func = PMBUS_HAVE_VOUT, + .sfunc = PMBUS_HAVE_STATUS_VOUT, + .sreg = PMBUS_STATUS_VOUT, + .gbit = PB_STATUS_VOUT_OV, + .limit = vout_limit_attrs, + .nlimit = ARRAY_SIZE(vout_limit_attrs), + } +}; + +/* Current attributes */ + +static const struct pmbus_limit_attr iin_limit_attrs[] = { + { + .reg = PMBUS_IIN_OC_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_IIN_OC_WARNING, + }, { + .reg = PMBUS_IIN_OC_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_IIN_OC_FAULT, + }, { + .reg = PMBUS_VIRT_READ_IIN_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_IIN_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_IIN_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_IIN_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_IIN_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr iout_limit_attrs[] = { + { + .reg = PMBUS_IOUT_OC_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_IOUT_OC_WARNING, + }, { + .reg = PMBUS_IOUT_UC_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_IOUT_UC_FAULT, + }, { + .reg = PMBUS_IOUT_OC_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_IOUT_OC_FAULT, + }, { + .reg = PMBUS_VIRT_READ_IOUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_IOUT_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_IOUT_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_IOUT_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_IOUT_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_sensor_attr current_attributes[] = { + { + .reg = PMBUS_READ_IIN, + .class = PSC_CURRENT_IN, + .label = "iin", + .func = PMBUS_HAVE_IIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sreg = PMBUS_STATUS_INPUT, + .gbit = PB_STATUS_INPUT, + .limit = iin_limit_attrs, + .nlimit = ARRAY_SIZE(iin_limit_attrs), + }, { + .reg = PMBUS_READ_IOUT, + .class = PSC_CURRENT_OUT, + .label = "iout", + .paged = true, + .func = PMBUS_HAVE_IOUT, + .sfunc = PMBUS_HAVE_STATUS_IOUT, + .sreg = PMBUS_STATUS_IOUT, + .gbit = PB_STATUS_IOUT_OC, + .limit = iout_limit_attrs, + .nlimit = ARRAY_SIZE(iout_limit_attrs), + } +}; + +/* Power attributes */ + +static const struct pmbus_limit_attr pin_limit_attrs[] = { + { + .reg = PMBUS_PIN_OP_WARN_LIMIT, + .attr = "max", + .alarm = "alarm", + .sbit = PB_PIN_OP_WARNING, + }, { + .reg = PMBUS_VIRT_READ_PIN_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_PIN_MIN, + .update = true, + .attr = "input_lowest", + }, { + .reg = PMBUS_VIRT_READ_PIN_MAX, + .update = true, + .attr = "input_highest", + }, { + .reg = PMBUS_VIRT_RESET_PIN_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_PIN_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr pout_limit_attrs[] = { + { + .reg = PMBUS_POUT_MAX, + .attr = "cap", + .alarm = "cap_alarm", + .sbit = PB_POWER_LIMITING, + }, { + .reg = PMBUS_POUT_OP_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_POUT_OP_WARNING, + }, { + .reg = PMBUS_POUT_OP_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_POUT_OP_FAULT, + }, { + .reg = PMBUS_VIRT_READ_POUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_POUT_MIN, + .update = true, + .attr = "input_lowest", + }, { + .reg = PMBUS_VIRT_READ_POUT_MAX, + .update = true, + .attr = "input_highest", + }, { + .reg = PMBUS_VIRT_RESET_POUT_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_POUT_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_sensor_attr power_attributes[] = { + { + .reg = PMBUS_READ_PIN, + .class = PSC_POWER, + .label = "pin", + .func = PMBUS_HAVE_PIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sreg = PMBUS_STATUS_INPUT, + .gbit = PB_STATUS_INPUT, + .limit = pin_limit_attrs, + .nlimit = ARRAY_SIZE(pin_limit_attrs), + }, { + .reg = PMBUS_READ_POUT, + .class = PSC_POWER, + .label = "pout", + .paged = true, + .func = PMBUS_HAVE_POUT, + .sfunc = PMBUS_HAVE_STATUS_IOUT, + .sreg = PMBUS_STATUS_IOUT, + .limit = pout_limit_attrs, + .nlimit = ARRAY_SIZE(pout_limit_attrs), + } +}; + +/* Temperature atributes */ + +static const struct pmbus_limit_attr temp_limit_attrs[] = { + { + .reg = PMBUS_UT_WARN_LIMIT, + .low = true, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_TEMP_UT_WARNING, + }, { + .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_TEMP_UT_FAULT, + }, { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + }, { + .reg = PMBUS_OT_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_TEMP_OT_FAULT, + }, { + .reg = PMBUS_VIRT_READ_TEMP_MIN, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_TEMP_AVG, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_TEMP_MAX, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_TEMP_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_MAX_TEMP_1, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr temp_limit_attrs2[] = { + { + .reg = PMBUS_UT_WARN_LIMIT, + .low = true, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_TEMP_UT_WARNING, + }, { + .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_TEMP_UT_FAULT, + }, { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + }, { + .reg = PMBUS_OT_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_TEMP_OT_FAULT, + }, { + .reg = PMBUS_VIRT_READ_TEMP2_MIN, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_TEMP2_AVG, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_TEMP2_MAX, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_TEMP2_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_MAX_TEMP_2, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr temp_limit_attrs3[] = { + { + .reg = PMBUS_UT_WARN_LIMIT, + .low = true, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_TEMP_UT_WARNING, + }, { + .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_TEMP_UT_FAULT, + }, { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + }, { + .reg = PMBUS_OT_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_TEMP_OT_FAULT, + }, { + .reg = PMBUS_MFR_MAX_TEMP_3, + .attr = "rated_max", + }, +}; + +static const struct pmbus_sensor_attr temp_attributes[] = { + { + .reg = PMBUS_READ_TEMPERATURE_1, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sreg = PMBUS_STATUS_TEMPERATURE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs, + .nlimit = ARRAY_SIZE(temp_limit_attrs), + }, { + .reg = PMBUS_READ_TEMPERATURE_2, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP2, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sreg = PMBUS_STATUS_TEMPERATURE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs2, + .nlimit = ARRAY_SIZE(temp_limit_attrs2), + }, { + .reg = PMBUS_READ_TEMPERATURE_3, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP3, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sreg = PMBUS_STATUS_TEMPERATURE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs3, + .nlimit = ARRAY_SIZE(temp_limit_attrs3), + } +}; + +static const int pmbus_fan_registers[] = { + PMBUS_READ_FAN_SPEED_1, + PMBUS_READ_FAN_SPEED_2, + PMBUS_READ_FAN_SPEED_3, + PMBUS_READ_FAN_SPEED_4 +}; + +static const int pmbus_fan_status_registers[] = { + PMBUS_STATUS_FAN_12, + PMBUS_STATUS_FAN_12, + PMBUS_STATUS_FAN_34, + PMBUS_STATUS_FAN_34 +}; + +static const u32 pmbus_fan_flags[] = { + PMBUS_HAVE_FAN12, + PMBUS_HAVE_FAN12, + PMBUS_HAVE_FAN34, + PMBUS_HAVE_FAN34 +}; + +static const u32 pmbus_fan_status_flags[] = { + PMBUS_HAVE_STATUS_FAN12, + PMBUS_HAVE_STATUS_FAN12, + PMBUS_HAVE_STATUS_FAN34, + PMBUS_HAVE_STATUS_FAN34 +}; + +/* Fans */ + +/* Precondition: FAN_CONFIG_x_y and FAN_COMMAND_x must exist for the fan ID */ +static int pmbus_add_fan_ctrl(struct i2c_client *client, + struct pmbus_data *data, int index, int page, int id, + u8 config) +{ + struct pmbus_sensor *sensor; + + sensor = pmbus_add_sensor(data, "fan", "target", index, page, + 0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN, + false, false, true); + + if (!sensor) + return -ENOMEM; + + if (!((data->info->func[page] & PMBUS_HAVE_PWM12) || + (data->info->func[page] & PMBUS_HAVE_PWM34))) + return 0; + + sensor = pmbus_add_sensor(data, "pwm", NULL, index, page, + 0xff, PMBUS_VIRT_PWM_1 + id, PSC_PWM, + false, false, true); + + if (!sensor) + return -ENOMEM; + + sensor = pmbus_add_sensor(data, "pwm", "enable", index, page, + 0xff, PMBUS_VIRT_PWM_ENABLE_1 + id, PSC_PWM, + true, false, false); + + if (!sensor) + return -ENOMEM; + + return 0; +} + +static int pmbus_add_fan_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + const struct pmbus_driver_info *info = data->info; + int index = 1; + int page; + int ret; + + for (page = 0; page < info->pages; page++) { + int f; + + for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) { + int regval; + + if (!(info->func[page] & pmbus_fan_flags[f])) + break; + + if (!wb_pmbus_check_word_register(client, page, + pmbus_fan_registers[f])) + break; + + /* + * Skip fan if not installed. + * Each fan configuration register covers multiple fans, + * so we have to do some magic. + */ + regval = _pmbus_read_byte_data(client, page, + pmbus_fan_config_registers[f]); + if (regval < 0 || + (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) + continue; + + if (pmbus_add_sensor(data, "fan", "input", index, + page, 0xff, pmbus_fan_registers[f], + PSC_FAN, true, true, true) == NULL) + return -ENOMEM; + + /* Fan control */ + if (wb_pmbus_check_word_register(client, page, + pmbus_fan_command_registers[f])) { + ret = pmbus_add_fan_ctrl(client, data, index, + page, f, regval); + if (ret < 0) + return ret; + } + + /* + * Each fan status register covers multiple fans, + * so we have to do some magic. + */ + if ((info->func[page] & pmbus_fan_status_flags[f]) && + wb_pmbus_check_byte_register(client, + page, pmbus_fan_status_registers[f])) { + int reg; + + if (f > 1) /* fan 3, 4 */ + reg = PMBUS_STATUS_FAN_34; + else + reg = PMBUS_STATUS_FAN_12; + ret = pmbus_add_boolean(data, "fan", + "alarm", index, NULL, NULL, page, reg, + PB_FAN_FAN1_WARNING >> (f & 1)); + if (ret) + return ret; + ret = pmbus_add_boolean(data, "fan", + "fault", index, NULL, NULL, page, reg, + PB_FAN_FAN1_FAULT >> (f & 1)); + if (ret) + return ret; + } + index++; + } + } + return 0; +} + +struct pmbus_samples_attr { + int reg; + char *name; +}; + +struct pmbus_samples_reg { + int page; + struct pmbus_samples_attr *attr; + struct device_attribute dev_attr; +}; + +static struct pmbus_samples_attr pmbus_samples_registers[] = { + { + .reg = PMBUS_VIRT_SAMPLES, + .name = "samples", + }, { + .reg = PMBUS_VIRT_IN_SAMPLES, + .name = "in_samples", + }, { + .reg = PMBUS_VIRT_CURR_SAMPLES, + .name = "curr_samples", + }, { + .reg = PMBUS_VIRT_POWER_SAMPLES, + .name = "power_samples", + }, { + .reg = PMBUS_VIRT_TEMP_SAMPLES, + .name = "temp_samples", + } +}; + +#define to_samples_reg(x) container_of(x, struct pmbus_samples_reg, dev_attr) + +static ssize_t pmbus_show_samples(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int val; + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_samples_reg *reg = to_samples_reg(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + val = _pmbus_read_word_data(client, reg->page, 0xff, reg->attr->reg); + mutex_unlock(&data->update_lock); + if (val < 0) + return val; + + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t pmbus_set_samples(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + int ret; + long val; + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_samples_reg *reg = to_samples_reg(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + + if (kstrtol(buf, 0, &val) < 0) + return -EINVAL; + + mutex_lock(&data->update_lock); + ret = _pmbus_write_word_data(client, reg->page, reg->attr->reg, val); + mutex_unlock(&data->update_lock); + + return ret ? : count; +} + +static int pmbus_add_samples_attr(struct pmbus_data *data, int page, + struct pmbus_samples_attr *attr) +{ + struct pmbus_samples_reg *reg; + + reg = devm_kzalloc(data->dev, sizeof(*reg), GFP_KERNEL); + if (!reg) + return -ENOMEM; + + reg->attr = attr; + reg->page = page; + + pmbus_dev_attr_init(®->dev_attr, attr->name, 0644, + pmbus_show_samples, pmbus_set_samples); + + return pmbus_add_attribute(data, ®->dev_attr.attr); +} + +static int pmbus_add_samples_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + const struct pmbus_driver_info *info = data->info; + int s; + + if (!(info->func[0] & PMBUS_HAVE_SAMPLES)) + return 0; + + for (s = 0; s < ARRAY_SIZE(pmbus_samples_registers); s++) { + struct pmbus_samples_attr *attr; + int ret; + + attr = &pmbus_samples_registers[s]; + if (!wb_pmbus_check_word_register(client, 0, attr->reg)) + continue; + + ret = pmbus_add_samples_attr(data, 0, attr); + if (ret) + return ret; + } + + return 0; +} + +static int pmbus_find_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + int ret; + + /* Voltage sensors */ + ret = pmbus_add_sensor_attrs(client, data, "in", voltage_attributes, + ARRAY_SIZE(voltage_attributes)); + if (ret) + return ret; + + /* Current sensors */ + ret = pmbus_add_sensor_attrs(client, data, "curr", current_attributes, + ARRAY_SIZE(current_attributes)); + if (ret) + return ret; + + /* Power sensors */ + ret = pmbus_add_sensor_attrs(client, data, "power", power_attributes, + ARRAY_SIZE(power_attributes)); + if (ret) + return ret; + + /* Temperature sensors */ + ret = pmbus_add_sensor_attrs(client, data, "temp", temp_attributes, + ARRAY_SIZE(temp_attributes)); + if (ret) + return ret; + + /* Fans */ + ret = pmbus_add_fan_attributes(client, data); + if (ret) + return ret; + + ret = pmbus_add_samples_attributes(client, data); + return ret; +} + +/* + * Identify chip parameters. + * This function is called for all chips. + */ +static int pmbus_identify_common(struct i2c_client *client, + struct pmbus_data *data, int page) +{ + int vout_mode = -1; + + if (wb_pmbus_check_byte_register(client, page, PMBUS_VOUT_MODE)) + vout_mode = _pmbus_read_byte_data(client, page, + PMBUS_VOUT_MODE); + if (vout_mode >= 0 && vout_mode != 0xff) { + /* + * Not all chips support the VOUT_MODE command, + * so a failure to read it is not an error. + */ + switch (vout_mode >> 5) { + case 0: /* linear mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != linear) + return -ENODEV; + + data->exponent[page] = ((s8)(vout_mode << 3)) >> 3; + break; + case 1: /* VID mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != vid) + return -ENODEV; + break; + case 2: /* direct mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != direct) + return -ENODEV; + break; + default: + return -ENODEV; + } + } + + pmbus_clear_fault_page(client, page); + return 0; +} + +static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, + struct pmbus_driver_info *info) +{ + struct device *dev = &client->dev; + int page, ret, i; + + /* + * Some PMBus chips don't support PMBUS_STATUS_WORD, so try + * to use PMBUS_STATUS_BYTE instead if that is the case. + * Bail out if both registers are not supported. + */ + for(i = 0; i < PMBUS_RETRY_TIME; i++) { + data->read_status = pmbus_read_status_word; + ret = i2c_smbus_read_word_data(client, PMBUS_STATUS_WORD); + if (ret < 0 || ret == 0xffff) { + data->read_status = pmbus_read_status_byte; + ret = i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE); + if (ret < 0 || ret == 0xff) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + continue; + } + } else { + data->has_status_word = true; + } + break; + } + + if(i == PMBUS_RETRY_TIME) { + dev_err(dev, "PMBus status register not found\n"); + return -ENODEV; + } + + /* Enable PEC if the controller supports it */ + for(i = 0; i < PMBUS_RETRY_TIME; i++) { + ret = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); + if (ret >= 0) { + break; + } + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + + if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK)) + client->flags |= I2C_CLIENT_PEC; + + /* + * Check if the chip is write protected. If it is, we can not clear + * faults, and we should not try it. Also, in that case, writes into + * limit registers need to be disabled. + */ + for(i = 0; i < PMBUS_RETRY_TIME; i++) { + ret = i2c_smbus_read_byte_data(client, PMBUS_WRITE_PROTECT); + if (ret >= 0) { + break; + } + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + + if (ret > 0 && (ret & PB_WP_ANY)) + data->flags |= PMBUS_WRITE_PROTECTED | PMBUS_SKIP_STATUS_CHECK; + + if (data->info->pages) + wb_pmbus_clear_faults(client); + else + pmbus_clear_fault_page(client, -1); + + if (info->identify) { + ret = (*info->identify)(client, info); + if (ret < 0) { + dev_err(dev, "Chip identification failed\n"); + return ret; + } + } + + if (info->pages <= 0 || info->pages > PMBUS_PAGES) { + dev_err(dev, "Bad number of PMBus pages: %d\n", info->pages); + return -ENODEV; + } + + for (page = 0; page < info->pages; page++) { + ret = pmbus_identify_common(client, data, page); + if (ret < 0) { + dev_err(dev, "Failed to identify chip capabilities\n"); + return ret; + } + } + return 0; +} + +#if IS_ENABLED(CONFIG_REGULATOR) +static int pmbus_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct device *dev = rdev_get_dev(rdev); + struct i2c_client *client = to_i2c_client(dev->parent); + u8 page = rdev_get_id(rdev); + int ret; + + ret = wb_pmbus_read_byte_data(client, page, PMBUS_OPERATION); + if (ret < 0) + return ret; + + return !!(ret & PB_OPERATION_CONTROL_ON); +} + +static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable) +{ + struct device *dev = rdev_get_dev(rdev); + struct i2c_client *client = to_i2c_client(dev->parent); + u8 page = rdev_get_id(rdev); + + return wb_pmbus_update_byte_data(client, page, PMBUS_OPERATION, + PB_OPERATION_CONTROL_ON, + enable ? PB_OPERATION_CONTROL_ON : 0); +} + +static int pmbus_regulator_enable(struct regulator_dev *rdev) +{ + return _pmbus_regulator_on_off(rdev, 1); +} + +static int pmbus_regulator_disable(struct regulator_dev *rdev) +{ + return _pmbus_regulator_on_off(rdev, 0); +} + +const struct regulator_ops wb_pmbus_regulator_ops = { + .enable = pmbus_regulator_enable, + .disable = pmbus_regulator_disable, + .is_enabled = pmbus_regulator_is_enabled, +}; +EXPORT_SYMBOL_GPL(wb_pmbus_regulator_ops); + +static int pmbus_regulator_register(struct pmbus_data *data) +{ + struct device *dev = data->dev; + const struct pmbus_driver_info *info = data->info; + const struct pmbus_platform_data *pdata = dev_get_platdata(dev); + struct regulator_dev *rdev; + int i; + + for (i = 0; i < info->num_regulators; i++) { + struct regulator_config config = { }; + + config.dev = dev; + config.driver_data = data; + + if (pdata && pdata->reg_init_data) + config.init_data = &pdata->reg_init_data[i]; + + rdev = devm_regulator_register(dev, &info->reg_desc[i], + &config); + if (IS_ERR(rdev)) { + dev_err(dev, "Failed to register %s regulator\n", + info->reg_desc[i].name); + return PTR_ERR(rdev); + } + } + + return 0; +} +#else +static int pmbus_regulator_register(struct pmbus_data *data) +{ + return 0; +} +#endif + +static struct dentry *pmbus_debugfs_dir; /* pmbus debugfs directory */ + +#if IS_ENABLED(CONFIG_DEBUG_FS) +static int pmbus_debugfs_get(void *data, u64 *val) +{ + int rc; + struct pmbus_debugfs_entry *entry = data; + + rc = _pmbus_read_byte_data(entry->client, entry->page, entry->reg); + if (rc < 0) + return rc; + + *val = rc; + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops, pmbus_debugfs_get, NULL, + "0x%02llx\n"); + +static int pmbus_debugfs_get_status(void *data, u64 *val) +{ + int rc; + struct pmbus_debugfs_entry *entry = data; + struct pmbus_data *pdata = i2c_get_clientdata(entry->client); + + rc = pdata->read_status(entry->client, entry->page); + if (rc < 0) + return rc; + + *val = rc; + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_status, pmbus_debugfs_get_status, + NULL, "0x%04llx\n"); + +static int pmbus_debugfs_get_pec(void *data, u64 *val) +{ + struct i2c_client *client = data; + + *val = !!(client->flags & I2C_CLIENT_PEC); + + return 0; +} + +static int pmbus_debugfs_set_pec(void *data, u64 val) +{ + int rc; + struct i2c_client *client = data; + + if (!val) { + client->flags &= ~I2C_CLIENT_PEC; + return 0; + } + + if (val != 1) + return -EINVAL; + + rc = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); + if (rc < 0) + return rc; + + if (!(rc & PB_CAPABILITY_ERROR_CHECK)) + return -EOPNOTSUPP; + + client->flags |= I2C_CLIENT_PEC; + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_pec, pmbus_debugfs_get_pec, + pmbus_debugfs_set_pec, "%llu\n"); + +static int pmbus_init_debugfs(struct i2c_client *client, + struct pmbus_data *data) +{ + int i, idx = 0; + char name[PMBUS_NAME_SIZE]; + struct pmbus_debugfs_entry *entries; + + if (!pmbus_debugfs_dir) + return -ENODEV; + + /* + * Create the debugfs directory for this device. Use the hwmon device + * name to avoid conflicts (hwmon numbers are globally unique). + */ + data->debugfs = debugfs_create_dir(dev_name(data->hwmon_dev), + pmbus_debugfs_dir); + if (IS_ERR_OR_NULL(data->debugfs)) { + data->debugfs = NULL; + return -ENODEV; + } + + /* Allocate the max possible entries we need. */ + entries = devm_kcalloc(data->dev, + data->info->pages * 10, sizeof(*entries), + GFP_KERNEL); + if (!entries) + return -ENOMEM; + + debugfs_create_file("pec", 0664, data->debugfs, client, + &pmbus_debugfs_ops_pec); + + for (i = 0; i < data->info->pages; ++i) { + /* Check accessibility of status register if it's not page 0 */ + if (!i || pmbus_check_status_register(client, i)) { + /* No need to set reg as we have special read op. */ + entries[idx].client = client; + entries[idx].page = i; + scnprintf(name, PMBUS_NAME_SIZE, "status%d", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops_status); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_VOUT) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_VOUT; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_vout", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_IOUT) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_IOUT; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_iout", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_INPUT) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_INPUT; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_input", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_TEMP) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_TEMPERATURE; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_temp", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (wb_pmbus_check_byte_register(client, i, PMBUS_STATUS_CML)) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_CML; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_cml", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (wb_pmbus_check_byte_register(client, i, PMBUS_STATUS_OTHER)) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_OTHER; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_other", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (wb_pmbus_check_byte_register(client, i, + PMBUS_STATUS_MFR_SPECIFIC)) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_MFR_SPECIFIC; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_mfr", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_FAN12) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_FAN_12; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_fan12", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_FAN34) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_FAN_34; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_fan34", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + } + + return 0; +} +#else +static int pmbus_init_debugfs(struct i2c_client *client, + struct pmbus_data *data) +{ + return 0; +} +#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ + +int wb_pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info) +{ + struct device *dev = &client->dev; + const struct pmbus_platform_data *pdata = dev_get_platdata(dev); + struct pmbus_data *data; + size_t groups_num = 0; + int ret; + + if (!info) + return -ENODEV; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE + | I2C_FUNC_SMBUS_BYTE_DATA + | I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + if (info->groups) + while (info->groups[groups_num]) + groups_num++; + + data->groups = devm_kcalloc(dev, groups_num + 2, sizeof(void *), + GFP_KERNEL); + if (!data->groups) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->dev = dev; + + if (pdata) + data->flags = pdata->flags; + data->info = info; + data->currpage = -1; + data->currphase = -1; + + ret = pmbus_init_common(client, data, info); + if (ret < 0) + return ret; + + ret = pmbus_find_attributes(client, data); + if (ret) + return ret; + + /* + * If there are no attributes, something is wrong. + * Bail out instead of trying to register nothing. + */ + if (!data->num_attributes) { + dev_err(dev, "No attributes found\n"); + return -ENODEV; + } + + data->groups[0] = &data->group; + memcpy(data->groups + 1, info->groups, sizeof(void *) * groups_num); + data->hwmon_dev = devm_hwmon_device_register_with_groups(dev, + client->name, data, data->groups); + if (IS_ERR(data->hwmon_dev)) { + dev_err(dev, "Failed to register hwmon device\n"); + return PTR_ERR(data->hwmon_dev); + } + + ret = pmbus_regulator_register(data); + if (ret) + return ret; + + ret = pmbus_init_debugfs(client, data); + if (ret) + dev_warn(dev, "Failed to register debugfs\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(wb_pmbus_do_probe); + +int wb_pmbus_do_remove(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + + debugfs_remove_recursive(data->debugfs); + + return 0; +} +EXPORT_SYMBOL_GPL(wb_pmbus_do_remove); + +struct dentry *wb_pmbus_get_debugfs_dir(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + + return data->debugfs; +} +EXPORT_SYMBOL_GPL(wb_pmbus_get_debugfs_dir); + +static int __init pmbus_core_init(void) +{ + pmbus_debugfs_dir = debugfs_create_dir("pmbus", NULL); + if (IS_ERR(pmbus_debugfs_dir)) + pmbus_debugfs_dir = NULL; + + return 0; +} + +static void __exit pmbus_core_exit(void) +{ + debugfs_remove_recursive(pmbus_debugfs_dir); +} + +module_init(pmbus_core_init); +module_exit(pmbus_core_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PMBus core driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tmp401.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tmp401.c new file mode 100644 index 000000000000..4118510b1006 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tmp401.c @@ -0,0 +1,798 @@ +/* tmp401.c + * + * Copyright (C) 2007,2008 Hans de Goede + * Preliminary tmp411 support by: + * Gabriel Konat, Sander Leget, Wouter Willems + * Copyright (C) 2009 Andre Prendel + * + * Cleanup and support for TMP431 and TMP432 by Guenter Roeck + * Copyright (c) 2013 Guenter Roeck + * + * 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. + */ + +/* + * Driver for the Texas Instruments TMP401 SMBUS temperature sensor IC. + * + * Note this IC is in some aspect similar to the LM90, but it has quite a + * few differences too, for example the local temp has a higher resolution + * and thus has 16 bits registers for its value and limit instead of 8 bits. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +/* static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, + 0x4e, 0x4f, I2C_CLIENT_END }; */ + +enum chips { tmp401, tmp411, tmp431, tmp432, tmp435, tmp461 }; + +/* + * The TMP401 registers, note some registers have different addresses for + * reading and writing + */ +#define TMP401_STATUS 0x02 +#define TMP401_CONFIG_READ 0x03 +#define TMP401_CONFIG_WRITE 0x09 +#define TMP401_CONVERSION_RATE_READ 0x04 +#define TMP401_CONVERSION_RATE_WRITE 0x0A +#define TMP401_TEMP_CRIT_HYST 0x21 +#define TMP401_MANUFACTURER_ID_REG 0xFE +#define TMP401_DEVICE_ID_REG 0xFF + +static const u8 TMP401_TEMP_MSB_READ[7][2] = { + { 0x00, 0x01 }, /* temp */ + { 0x06, 0x08 }, /* low limit */ + { 0x05, 0x07 }, /* high limit */ + { 0x20, 0x19 }, /* therm (crit) limit */ + { 0x30, 0x34 }, /* lowest */ + { 0x32, 0x36 }, /* highest */ + { 0, 0x11 }, /* offset */ +}; + +static const u8 TMP401_TEMP_MSB_WRITE[7][2] = { + { 0, 0 }, /* temp (unused) */ + { 0x0C, 0x0E }, /* low limit */ + { 0x0B, 0x0D }, /* high limit */ + { 0x20, 0x19 }, /* therm (crit) limit */ + { 0x30, 0x34 }, /* lowest */ + { 0x32, 0x36 }, /* highest */ + { 0, 0x11 }, /* offset */ +}; + +static const u8 TMP401_TEMP_LSB[7][2] = { + { 0x15, 0x10 }, /* temp */ + { 0x17, 0x14 }, /* low limit */ + { 0x16, 0x13 }, /* high limit */ + { 0, 0 }, /* therm (crit) limit (unused) */ + { 0x31, 0x35 }, /* lowest */ + { 0x33, 0x37 }, /* highest */ + { 0, 0x12 }, /* offset */ +}; + +static const u8 TMP432_TEMP_MSB_READ[4][3] = { + { 0x00, 0x01, 0x23 }, /* temp */ + { 0x06, 0x08, 0x16 }, /* low limit */ + { 0x05, 0x07, 0x15 }, /* high limit */ + { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ +}; + +static const u8 TMP432_TEMP_MSB_WRITE[4][3] = { + { 0, 0, 0 }, /* temp - unused */ + { 0x0C, 0x0E, 0x16 }, /* low limit */ + { 0x0B, 0x0D, 0x15 }, /* high limit */ + { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ +}; + +static const u8 TMP432_TEMP_LSB[3][3] = { + { 0x29, 0x10, 0x24 }, /* temp */ + { 0x3E, 0x14, 0x18 }, /* low limit */ + { 0x3D, 0x13, 0x17 }, /* high limit */ +}; + +/* [0] = fault, [1] = low, [2] = high, [3] = therm/crit */ +static const u8 TMP432_STATUS_REG[] = { + 0x1b, 0x36, 0x35, 0x37 }; + +/* Flags */ +#define TMP401_CONFIG_RANGE BIT(2) +#define TMP401_CONFIG_SHUTDOWN BIT(6) +#define TMP401_STATUS_LOCAL_CRIT BIT(0) +#define TMP401_STATUS_REMOTE_CRIT BIT(1) +#define TMP401_STATUS_REMOTE_OPEN BIT(2) +#define TMP401_STATUS_REMOTE_LOW BIT(3) +#define TMP401_STATUS_REMOTE_HIGH BIT(4) +#define TMP401_STATUS_LOCAL_LOW BIT(5) +#define TMP401_STATUS_LOCAL_HIGH BIT(6) + +/* On TMP432, each status has its own register */ +#define TMP432_STATUS_LOCAL BIT(0) +#define TMP432_STATUS_REMOTE1 BIT(1) +#define TMP432_STATUS_REMOTE2 BIT(2) + +/* Manufacturer / Device ID's */ +#define TMP401_MANUFACTURER_ID 0x55 +#define TMP401_DEVICE_ID 0x11 +#define TMP411A_DEVICE_ID 0x12 +#define TMP411B_DEVICE_ID 0x13 +#define TMP411C_DEVICE_ID 0x10 +#define TMP431_DEVICE_ID 0x31 +#define TMP432_DEVICE_ID 0x32 +#define TMP435_DEVICE_ID 0x35 + +/* + * Driver data (common to all clients) + */ + +static const struct i2c_device_id tmp401_id[] = { + { "wb_tmp401", tmp401 }, + { "wb_tmp411", tmp411 }, + { "wb_tmp431", tmp431 }, + { "wb_tmp432", tmp432 }, + { "wb_tmp435", tmp435 }, + { "wb_tmp461", tmp461 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tmp401_id); + +/* + * Client data (each client gets its own) + */ + +struct tmp401_data { + struct i2c_client *client; + const struct attribute_group *groups[3]; + struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + enum chips kind; + + unsigned int update_interval; /* in milliseconds */ + + /* register values */ + u8 status[4]; + u8 config; + u16 temp[7][3]; + u8 temp_crit_hyst; +}; + +/* + * Sysfs attr show / store functions + */ + +static int tmp401_register_to_temp(u16 reg, u8 config) +{ + int temp = reg; + + if (config & TMP401_CONFIG_RANGE) + temp -= 64 * 256; + + return DIV_ROUND_CLOSEST(temp * 125, 32); +} + +static u16 tmp401_temp_to_register(long temp, u8 config, int zbits) +{ + if (config & TMP401_CONFIG_RANGE) { + temp = clamp_val(temp, -64000, 191000); + temp += 64000; + } else + temp = clamp_val(temp, 0, 127000); + + return DIV_ROUND_CLOSEST(temp * (1 << (8 - zbits)), 1000) << zbits; +} + +static int tmp401_update_device_reg16(struct i2c_client *client, + struct tmp401_data *data) +{ + int i, j, val; + int num_regs = data->kind == tmp411 ? 6 : 4; + int num_sensors = data->kind == tmp432 ? 3 : 2; + + for (i = 0; i < num_sensors; i++) { /* local / r1 / r2 */ + for (j = 0; j < num_regs; j++) { /* temp / low / ... */ + u8 regaddr; + /* + * High byte must be read first immediately followed + * by the low byte + */ + regaddr = data->kind == tmp432 ? + TMP432_TEMP_MSB_READ[j][i] : + TMP401_TEMP_MSB_READ[j][i]; + val = i2c_smbus_read_byte_data(client, regaddr); + if (val < 0) + return val; + data->temp[j][i] = val << 8; + if (j == 3) /* crit is msb only */ + continue; + regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[j][i] + : TMP401_TEMP_LSB[j][i]; + val = i2c_smbus_read_byte_data(client, regaddr); + if (val < 0) + return val; + data->temp[j][i] |= val; + } + } + return 0; +} + +static struct tmp401_data *tmp401_update_device(struct device *dev) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + struct tmp401_data *ret = data; + int i, val; + unsigned long next_update; + + mutex_lock(&data->update_lock); + + next_update = data->last_updated + + msecs_to_jiffies(data->update_interval); + if (time_after(jiffies, next_update) || !data->valid) { + if (data->kind != tmp432) { + /* + * The driver uses the TMP432 status format internally. + * Convert status to TMP432 format for other chips. + */ + val = i2c_smbus_read_byte_data(client, TMP401_STATUS); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->status[0] = + (val & TMP401_STATUS_REMOTE_OPEN) >> 1; + data->status[1] = + ((val & TMP401_STATUS_REMOTE_LOW) >> 2) | + ((val & TMP401_STATUS_LOCAL_LOW) >> 5); + data->status[2] = + ((val & TMP401_STATUS_REMOTE_HIGH) >> 3) | + ((val & TMP401_STATUS_LOCAL_HIGH) >> 6); + data->status[3] = val & (TMP401_STATUS_LOCAL_CRIT + | TMP401_STATUS_REMOTE_CRIT); + } else { + for (i = 0; i < ARRAY_SIZE(data->status); i++) { + val = i2c_smbus_read_byte_data(client, + TMP432_STATUS_REG[i]); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->status[i] = val; + } + } + + val = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->config = val; + val = tmp401_update_device_reg16(client, data); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + val = i2c_smbus_read_byte_data(client, TMP401_TEMP_CRIT_HYST); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->temp_crit_hyst = val; + + data->last_updated = jiffies; + data->valid = 1; + } + +abort: + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t show_temp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int nr = to_sensor_dev_attr_2(devattr)->nr; + int index = to_sensor_dev_attr_2(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%d\n", + tmp401_register_to_temp(data->temp[nr][index], data->config)); +} + +static ssize_t show_temp_crit_hyst(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int temp, index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + mutex_lock(&data->update_lock); + temp = tmp401_register_to_temp(data->temp[3][index], data->config); + temp -= data->temp_crit_hyst * 1000; + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t show_status(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int nr = to_sensor_dev_attr_2(devattr)->nr; + int mask = to_sensor_dev_attr_2(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%d\n", !!(data->status[nr] & mask)); +} + +static ssize_t store_temp(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + int nr = to_sensor_dev_attr_2(devattr)->nr; + int index = to_sensor_dev_attr_2(devattr)->index; + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + long val; + u16 reg; + u8 regaddr; + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + reg = tmp401_temp_to_register(val, data->config, nr == 3 ? 8 : 4); + + mutex_lock(&data->update_lock); + + regaddr = data->kind == tmp432 ? TMP432_TEMP_MSB_WRITE[nr][index] + : TMP401_TEMP_MSB_WRITE[nr][index]; + i2c_smbus_write_byte_data(client, regaddr, reg >> 8); + if (nr != 3) { + regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[nr][index] + : TMP401_TEMP_LSB[nr][index]; + i2c_smbus_write_byte_data(client, regaddr, reg & 0xFF); + } + data->temp[nr][index] = reg; + + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + int temp, index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + long val; + u8 reg; + + if (IS_ERR(data)) + return PTR_ERR(data); + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + if (data->config & TMP401_CONFIG_RANGE) + val = clamp_val(val, -64000, 191000); + else + val = clamp_val(val, 0, 127000); + + mutex_lock(&data->update_lock); + temp = tmp401_register_to_temp(data->temp[3][index], data->config); + val = clamp_val(val, temp - 255000, temp); + reg = ((temp - val) + 500) / 1000; + + i2c_smbus_write_byte_data(data->client, TMP401_TEMP_CRIT_HYST, + reg); + + data->temp_crit_hyst = reg; + + mutex_unlock(&data->update_lock); + + return count; +} + +/* + * Resets the historical measurements of minimum and maximum temperatures. + * This is done by writing any value to any of the minimum/maximum registers + * (0x30-0x37). + */ +static ssize_t reset_temp_history(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + long val; + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + if (val != 1) { + dev_err(dev, + "temp_reset_history value %ld not supported. Use 1 to reset the history!\n", + val); + return -EINVAL; + } + mutex_lock(&data->update_lock); + i2c_smbus_write_byte_data(client, TMP401_TEMP_MSB_WRITE[5][0], val); + data->valid = 0; + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_update_interval(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", data->update_interval); +} + +static ssize_t set_update_interval(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + unsigned long val; + int err, rate; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + /* + * For valid rates, interval can be calculated as + * interval = (1 << (7 - rate)) * 125; + * Rounded rate is therefore + * rate = 7 - __fls(interval * 4 / (125 * 3)); + * Use clamp_val() to avoid overflows, and to ensure valid input + * for __fls. + */ + val = clamp_val(val, 125, 16000); + rate = 7 - __fls(val * 4 / (125 * 3)); + mutex_lock(&data->update_lock); + i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, rate); + data->update_interval = (1 << (7 - rate)) * 125; + mutex_unlock(&data->update_lock); + + return count; +} + +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); +static SENSOR_DEVICE_ATTR_2(temp1_min, S_IWUSR | S_IRUGO, show_temp, + store_temp, 1, 0); +static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp, + store_temp, 2, 0); +static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IWUSR | S_IRUGO, show_temp, + store_temp, 3, 0); +static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, + show_temp_crit_hyst, store_temp_crit_hyst, 0); +static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_status, NULL, + 1, TMP432_STATUS_LOCAL); +static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_status, NULL, + 2, TMP432_STATUS_LOCAL); +static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_status, NULL, + 3, TMP432_STATUS_LOCAL); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1); +static SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp, + store_temp, 1, 1); +static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp, + store_temp, 2, 1); +static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IWUSR | S_IRUGO, show_temp, + store_temp, 3, 1); +static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, + NULL, 1); +static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_status, NULL, + 0, TMP432_STATUS_REMOTE1); +static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_status, NULL, + 1, TMP432_STATUS_REMOTE1); +static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_status, NULL, + 2, TMP432_STATUS_REMOTE1); +static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_status, NULL, + 3, TMP432_STATUS_REMOTE1); + +static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, + set_update_interval); + +static struct attribute *tmp401_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + + &dev_attr_update_interval.attr, + + NULL +}; + +static const struct attribute_group tmp401_group = { + .attrs = tmp401_attributes, +}; + +/* + * Additional features of the TMP411 chip. + * The TMP411 stores the minimum and maximum + * temperature measured since power-on, chip-reset, or + * minimum and maximum register reset for both the local + * and remote channels. + */ +static SENSOR_DEVICE_ATTR_2(temp1_lowest, S_IRUGO, show_temp, NULL, 4, 0); +static SENSOR_DEVICE_ATTR_2(temp1_highest, S_IRUGO, show_temp, NULL, 5, 0); +static SENSOR_DEVICE_ATTR_2(temp2_lowest, S_IRUGO, show_temp, NULL, 4, 1); +static SENSOR_DEVICE_ATTR_2(temp2_highest, S_IRUGO, show_temp, NULL, 5, 1); +static SENSOR_DEVICE_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, + 0); + +static struct attribute *tmp411_attributes[] = { + &sensor_dev_attr_temp1_highest.dev_attr.attr, + &sensor_dev_attr_temp1_lowest.dev_attr.attr, + &sensor_dev_attr_temp2_highest.dev_attr.attr, + &sensor_dev_attr_temp2_lowest.dev_attr.attr, + &sensor_dev_attr_temp_reset_history.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp411_group = { + .attrs = tmp411_attributes, +}; + +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2); +static SENSOR_DEVICE_ATTR_2(temp3_min, S_IWUSR | S_IRUGO, show_temp, + store_temp, 1, 2); +static SENSOR_DEVICE_ATTR_2(temp3_max, S_IWUSR | S_IRUGO, show_temp, + store_temp, 2, 2); +static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IWUSR | S_IRUGO, show_temp, + store_temp, 3, 2); +static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, + NULL, 2); +static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_status, NULL, + 0, TMP432_STATUS_REMOTE2); +static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_status, NULL, + 1, TMP432_STATUS_REMOTE2); +static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_status, NULL, + 2, TMP432_STATUS_REMOTE2); +static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_status, NULL, + 3, TMP432_STATUS_REMOTE2); + +static struct attribute *tmp432_attributes[] = { + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + + NULL +}; + +static const struct attribute_group tmp432_group = { + .attrs = tmp432_attributes, +}; + +/* + * Additional features of the TMP461 chip. + * The TMP461 temperature offset for the remote channel. + */ +static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IWUSR | S_IRUGO, show_temp, + store_temp, 6, 1); + +static struct attribute *tmp461_attributes[] = { + &sensor_dev_attr_temp2_offset.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp461_group = { + .attrs = tmp461_attributes, +}; + +/* + * Begin non sysfs callback code (aka Real code) + */ + +static int tmp401_init_client(struct tmp401_data *data, + struct i2c_client *client) +{ + int config, config_orig, status = 0; + + /* Set the conversion rate to 2 Hz */ + i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); + data->update_interval = 500; + + /* Start conversions (disable shutdown if necessary) */ + config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); + if (config < 0) + return config; + + config_orig = config; + config &= ~TMP401_CONFIG_SHUTDOWN; + + if (config != config_orig) + status = i2c_smbus_write_byte_data(client, + TMP401_CONFIG_WRITE, + config); + + return status; +} + +#if 0 +static int tmp401_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + enum chips kind; + struct i2c_adapter *adapter = client->adapter; + u8 reg; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + /* Detect and identify the chip */ + reg = i2c_smbus_read_byte_data(client, TMP401_MANUFACTURER_ID_REG); + if (reg != TMP401_MANUFACTURER_ID) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG); + + switch (reg) { + case TMP401_DEVICE_ID: + if (client->addr != 0x4c) + return -ENODEV; + kind = tmp401; + break; + case TMP411A_DEVICE_ID: + if (client->addr != 0x4c) + return -ENODEV; + kind = tmp411; + break; + case TMP411B_DEVICE_ID: + if (client->addr != 0x4d) + return -ENODEV; + kind = tmp411; + break; + case TMP411C_DEVICE_ID: + if (client->addr != 0x4e) + return -ENODEV; + kind = tmp411; + break; + case TMP431_DEVICE_ID: + if (client->addr != 0x4c && client->addr != 0x4d) + return -ENODEV; + kind = tmp431; + break; + case TMP432_DEVICE_ID: + if (client->addr != 0x4c && client->addr != 0x4d) + return -ENODEV; + kind = tmp432; + break; + case TMP435_DEVICE_ID: + kind = tmp435; + break; + default: + return -ENODEV; + } + + reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); + if (reg & 0x1b) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, TMP401_CONVERSION_RATE_READ); + /* Datasheet says: 0x1-0x6 */ + if (reg > 15) + return -ENODEV; + + strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE); + + return 0; +} +#endif + +static int tmp401_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + static const char * const names[] = { + "TMP401", "TMP411", "TMP431", "TMP432", "TMP435", "TMP461" + }; + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct tmp401_data *data; + int groups = 0, status; + + data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + mutex_init(&data->update_lock); + data->kind = id->driver_data; + + /* Initialize the TMP401 chip */ + status = tmp401_init_client(data, client); + if (status < 0) + return status; + + /* Register sysfs hooks */ + data->groups[groups++] = &tmp401_group; + + /* Register additional tmp411 sysfs hooks */ + if (data->kind == tmp411) + data->groups[groups++] = &tmp411_group; + + /* Register additional tmp432 sysfs hooks */ + if (data->kind == tmp432) + data->groups[groups++] = &tmp432_group; + + if (data->kind == tmp461) + data->groups[groups++] = &tmp461_group; + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + dev_info(dev, "Detected TI %s chip\n", names[data->kind]); + + return 0; +} + +static struct i2c_driver tmp401_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "wb_tmp401", + }, + .probe = tmp401_probe, + .id_table = tmp401_id, + /* .detect = tmp401_detect, */ + /* .address_list = normal_i2c, */ +}; + +module_i2c_driver(tmp401_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tps53622.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tps53622.c new file mode 100644 index 000000000000..b68196d9f57c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tps53622.c @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Hardware monitoring driver for Texas Instruments TPS53679 + * + * Copyright (c) 2017 Mellanox Technologies. All rights reserved. + * Copyright (c) 2017 Vadim Pasternak + */ + +#include +#include +#include +#include +#include +#include +#include +#include "wb_pmbus.h" + +enum chips { + tps53647, tps53667, tps53679, tps53681, tps53688, tps53622 +}; + +#define TPS53647_PAGE_NUM 1 + +#define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */ +#define TPS53679_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */ +#define TPS53679_PROT_VR13_10MV 0x04 /* VR13.0 mode, 10-mV DAC */ +#define TPS53679_PROT_IMVP8_5MV 0x05 /* IMVP8 mode, 5-mV DAC */ +#define TPS53679_PROT_VR13_5MV 0x07 /* VR13.0 mode, 5-mV DAC */ +#define TPS53679_PAGE_NUM 2 + +#define TPS53681_DEVICE_ID 0x81 + +#define TPS53681_PMBUS_REVISION 0x33 + +#define TPS53681_MFR_SPECIFIC_20 0xe4 /* Number of phases, per page */ + +static const struct i2c_device_id tps53679_id[]; + +static int tps53679_identify_mode(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + u8 vout_params; + int i, ret; + + for (i = 0; i < info->pages; i++) { + /* Read the register with VOUT scaling value.*/ + ret = wb_pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); + if (ret < 0) + return ret; + + vout_params = ret & GENMASK(4, 0); + + switch (vout_params) { + case TPS53679_PROT_VR13_10MV: + case TPS53679_PROT_VR12_5_10MV: + info->vrm_version[i] = vr13; + break; + case TPS53679_PROT_VR13_5MV: + case TPS53679_PROT_VR12_5MV: + case TPS53679_PROT_IMVP8_5MV: + info->vrm_version[i] = vr12; + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int tps53679_identify_phases(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int ret; + + /* On TPS53681, only channel A provides per-phase output current */ + ret = wb_pmbus_read_byte_data(client, 0, TPS53681_MFR_SPECIFIC_20); + if (ret < 0) + return ret; + info->phases[0] = (ret & 0x07) + 1; + + return 0; +} + +static int tps53679_identify_chip(struct i2c_client *client, + u8 revision, u16 id) +{ + u8 buf[I2C_SMBUS_BLOCK_MAX]; + int ret; + + ret = wb_pmbus_read_byte_data(client, 0, PMBUS_REVISION); + if (ret < 0) + return ret; + if (ret != revision) { + dev_err(&client->dev, "Unexpected PMBus revision 0x%x\n", ret); + return -ENODEV; + } + + ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf); + if (ret < 0) + return ret; + if (ret != 1 || buf[0] != id) { + dev_err(&client->dev, "Unexpected device ID 0x%x\n", buf[0]); + return -ENODEV; + } + return 0; +} + +/* + * Common identification function for chips with multi-phase support. + * Since those chips have special configuration registers, we want to have + * some level of reassurance that we are really talking with the chip + * being probed. Check PMBus revision and chip ID. + */ +static int tps53679_identify_multiphase(struct i2c_client *client, + struct pmbus_driver_info *info, + int pmbus_rev, int device_id) +{ + int ret; + + ret = tps53679_identify_chip(client, pmbus_rev, device_id); + if (ret < 0) + return ret; + + ret = tps53679_identify_mode(client, info); + if (ret < 0) + return ret; + + return tps53679_identify_phases(client, info); +} + +static int tps53679_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + return tps53679_identify_mode(client, info); +} + +static int tps53681_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + return tps53679_identify_multiphase(client, info, + TPS53681_PMBUS_REVISION, + TPS53681_DEVICE_ID); +} + +static int tps53681_read_word_data(struct i2c_client *client, int page, + int phase, int reg) +{ + /* + * For reading the total output current (READ_IOUT) for all phases, + * the chip datasheet is a bit vague. It says "PHASE must be set to + * FFh to access all phases simultaneously. PHASE may also be set to + * 80h readack (!) the total phase current". + * Experiments show that the command does _not_ report the total + * current for all phases if the phase is set to 0xff. Instead, it + * appears to report the current of one of the phases. Override phase + * parameter with 0x80 when reading the total output current on page 0. + */ + if (reg == PMBUS_READ_IOUT && page == 0 && phase == 0xff) + return wb_pmbus_read_word_data(client, page, 0x80, reg); + return -ENODATA; +} + +static struct pmbus_driver_info tps53679_info = { + .format[PSC_VOLTAGE_IN] = linear, + .format[PSC_VOLTAGE_OUT] = vid, + .format[PSC_TEMPERATURE] = linear, + .format[PSC_CURRENT_OUT] = linear, + .format[PSC_POWER] = linear, + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | + PMBUS_HAVE_STATUS_INPUT | + PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | + PMBUS_HAVE_POUT, + .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | + PMBUS_HAVE_POUT, + .pfunc[0] = PMBUS_HAVE_IOUT, + .pfunc[1] = PMBUS_HAVE_IOUT, + .pfunc[2] = PMBUS_HAVE_IOUT, + .pfunc[3] = PMBUS_HAVE_IOUT, + .pfunc[4] = PMBUS_HAVE_IOUT, + .pfunc[5] = PMBUS_HAVE_IOUT, +}; + +static int tps53679_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct pmbus_driver_info *info; + enum chips chip_id; + + if (dev->of_node) + chip_id = (enum chips)of_device_get_match_data(dev); + else + chip_id = i2c_match_id(tps53679_id, client)->driver_data; + + info = devm_kmemdup(dev, &tps53679_info, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + switch (chip_id) { + case tps53647: + case tps53667: + info->pages = TPS53647_PAGE_NUM; + info->identify = tps53679_identify; + break; + case tps53679: + case tps53688: + case tps53622: + info->pages = TPS53679_PAGE_NUM; + info->identify = tps53679_identify; + break; + case tps53681: + info->pages = TPS53679_PAGE_NUM; + info->phases[0] = 6; + info->identify = tps53681_identify; + info->read_word_data = tps53681_read_word_data; + break; + default: + return -ENODEV; + } + + return wb_pmbus_do_probe(client, info); +} + +static const struct i2c_device_id tps53679_id[] = { + {"wb_tps53647", tps53647}, + {"wb_tps53667", tps53667}, + {"wb_tps53679", tps53679}, + {"wb_tps53681", tps53681}, + {"wb_tps53688", tps53688}, + {"wb_tps53622", tps53622}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, tps53679_id); + +static const struct of_device_id __maybe_unused tps53679_of_match[] = { + {.compatible = "ti,wb_tps53647", .data = (void *)tps53647}, + {.compatible = "ti,wb_tps53667", .data = (void *)tps53667}, + {.compatible = "ti,wb_tps53679", .data = (void *)tps53679}, + {.compatible = "ti,wb_tps53681", .data = (void *)tps53681}, + {.compatible = "ti,wb_tps53688", .data = (void *)tps53688}, + {.compatible = "ti,wb_tps53622", .data = (void *)tps53622}, + {} +}; +MODULE_DEVICE_TABLE(of, tps53679_of_match); + +static struct i2c_driver tps53679_driver = { + .driver = { + .name = "wb_tps53622", + .of_match_table = of_match_ptr(tps53679_of_match), + }, + .probe_new = tps53679_probe, + .remove = wb_pmbus_do_remove, + .id_table = tps53679_id, +}; + +module_i2c_driver(tps53679_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PMBus driver for Texas Instruments TPS53679"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ucd9000.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ucd9000.c new file mode 100644 index 000000000000..9b967f141a86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ucd9000.c @@ -0,0 +1,675 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Hardware monitoring driver for UCD90xxx Sequencer and System Health + * Controller series + * + * Copyright (C) 2011 Ericsson AB. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_pmbus.h" + +enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd90320, ucd9090, + ucd90910 }; + +#define UCD9000_MONITOR_CONFIG 0xd5 +#define UCD9000_NUM_PAGES 0xd6 +#define UCD9000_FAN_CONFIG_INDEX 0xe7 +#define UCD9000_FAN_CONFIG 0xe8 +#define UCD9000_MFR_STATUS 0xf3 +#define UCD9000_GPIO_SELECT 0xfa +#define UCD9000_GPIO_CONFIG 0xfb +#define UCD9000_DEVICE_ID 0xfd + +/* GPIO CONFIG bits */ +#define UCD9000_GPIO_CONFIG_ENABLE BIT(0) +#define UCD9000_GPIO_CONFIG_OUT_ENABLE BIT(1) +#define UCD9000_GPIO_CONFIG_OUT_VALUE BIT(2) +#define UCD9000_GPIO_CONFIG_STATUS BIT(3) +#define UCD9000_GPIO_INPUT 0 +#define UCD9000_GPIO_OUTPUT 1 + +#define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07) +#define UCD9000_MON_PAGE(x) ((x) & 0x1f) + +#define UCD9000_MON_VOLTAGE 1 +#define UCD9000_MON_TEMPERATURE 2 +#define UCD9000_MON_CURRENT 3 +#define UCD9000_MON_VOLTAGE_HW 4 + +#define UCD9000_NUM_FAN 4 + +#define UCD9000_GPIO_NAME_LEN 16 +#define UCD9090_NUM_GPIOS 23 +#define UCD901XX_NUM_GPIOS 26 +#define UCD90320_NUM_GPIOS 84 +#define UCD90910_NUM_GPIOS 26 + +#define UCD9000_DEBUGFS_NAME_LEN 24 +#define UCD9000_GPI_COUNT 8 +#define UCD90320_GPI_COUNT 32 + +#define UCD9000_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define UCD9000_RETRY_TIME (3) +#define WB_DEV_NAME_MAX_LEN (64) + +static int g_wb_ucd9000_debug = 0; +static int g_wb_ucd9000_error = 0; + +module_param(g_wb_ucd9000_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_ucd9000_error, int, S_IRUGO | S_IWUSR); + +#define WB_UDC9000_VERBOSE(fmt, args...) do { \ + if (g_wb_ucd9000_debug) { \ + printk(KERN_INFO "[WB_UCD9000][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_UDC9000_ERROR(fmt, args...) do { \ + if (g_wb_ucd9000_error) { \ + printk(KERN_ERR "[WB_UCD9000][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct ucd9000_data { + u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX]; + struct pmbus_driver_info info; +#ifdef CONFIG_GPIOLIB + struct gpio_chip gpio; +#endif + struct dentry *debugfs; +}; +#define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info) + +struct ucd9000_debugfs_entry { + struct i2c_client *client; + u8 index; +}; + +static int wb_i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values) +{ + int rv, i; + + for(i = 0; i < UCD9000_RETRY_TIME; i++) { + rv = i2c_smbus_read_block_data(client, command, values); + if(rv >= 0){ + return rv; + } + usleep_range(UCD9000_RETRY_SLEEP_TIME, UCD9000_RETRY_SLEEP_TIME + 1); + } + WB_UDC9000_ERROR("read_block_data failed. nr:%d, addr:0x%x, reg:0x%x, rv:%d.", + client->adapter->nr, client->addr, command, rv); + return rv; +} + +static int ucd9000_get_fan_config(struct i2c_client *client, int fan) +{ + int fan_config = 0; + struct ucd9000_data *data + = to_ucd9000_data(wb_pmbus_get_driver_info(client)); + + if (data->fan_data[fan][3] & 1) + fan_config |= PB_FAN_2_INSTALLED; /* Use lower bit position */ + + /* Pulses/revolution */ + fan_config |= (data->fan_data[fan][3] & 0x06) >> 1; + + return fan_config; +} + +static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg) +{ + int ret = 0; + int fan_config; + + switch (reg) { + case PMBUS_FAN_CONFIG_12: + if (page > 0) + return -ENXIO; + + ret = ucd9000_get_fan_config(client, 0); + if (ret < 0) + return ret; + fan_config = ret << 4; + ret = ucd9000_get_fan_config(client, 1); + if (ret < 0) + return ret; + fan_config |= ret; + ret = fan_config; + break; + case PMBUS_FAN_CONFIG_34: + if (page > 0) + return -ENXIO; + + ret = ucd9000_get_fan_config(client, 2); + if (ret < 0) + return ret; + fan_config = ret << 4; + ret = ucd9000_get_fan_config(client, 3); + if (ret < 0) + return ret; + fan_config |= ret; + ret = fan_config; + break; + default: + ret = -ENODATA; + break; + } + return ret; +} + +static const struct i2c_device_id ucd9000_id[] = { + {"wb_ucd9000", ucd9000}, + {"wb_ucd90120", ucd90120}, + {"wb_ucd90124", ucd90124}, + {"wb_ucd90160", ucd90160}, + {"wb_ucd90320", ucd90320}, + {"wb_ucd9090", ucd9090}, + {"wb_ucd90910", ucd90910}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ucd9000_id); + +static const struct of_device_id __maybe_unused ucd9000_of_match[] = { + { + .compatible = "ti,wb_ucd9000", + .data = (void *)ucd9000 + }, + { + .compatible = "ti,wb_ucd90120", + .data = (void *)ucd90120 + }, + { + .compatible = "ti,wb_ucd90124", + .data = (void *)ucd90124 + }, + { + .compatible = "ti,wb_ucd90160", + .data = (void *)ucd90160 + }, + { + .compatible = "ti,wb_ucd90320", + .data = (void *)ucd90320 + }, + { + .compatible = "ti,wb_ucd9090", + .data = (void *)ucd9090 + }, + { + .compatible = "ti,wb_ucd90910", + .data = (void *)ucd90910 + }, + { }, +}; +MODULE_DEVICE_TABLE(of, ucd9000_of_match); + +#ifdef CONFIG_GPIOLIB +static int ucd9000_gpio_read_config(struct i2c_client *client, + unsigned int offset) +{ + int ret; + + /* No page set required */ + ret = i2c_smbus_write_byte_data(client, UCD9000_GPIO_SELECT, offset); + if (ret < 0) + return ret; + + return i2c_smbus_read_byte_data(client, UCD9000_GPIO_CONFIG); +} + +static int ucd9000_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct i2c_client *client = gpiochip_get_data(gc); + int ret; + + ret = ucd9000_gpio_read_config(client, offset); + if (ret < 0) + return ret; + + return !!(ret & UCD9000_GPIO_CONFIG_STATUS); +} + +static void ucd9000_gpio_set(struct gpio_chip *gc, unsigned int offset, + int value) +{ + struct i2c_client *client = gpiochip_get_data(gc); + int ret; + + ret = ucd9000_gpio_read_config(client, offset); + if (ret < 0) { + dev_dbg(&client->dev, "failed to read GPIO %d config: %d\n", + offset, ret); + return; + } + + if (value) { + if (ret & UCD9000_GPIO_CONFIG_STATUS) + return; + + ret |= UCD9000_GPIO_CONFIG_STATUS; + } else { + if (!(ret & UCD9000_GPIO_CONFIG_STATUS)) + return; + + ret &= ~UCD9000_GPIO_CONFIG_STATUS; + } + + ret |= UCD9000_GPIO_CONFIG_ENABLE; + + /* Page set not required */ + ret = i2c_smbus_write_byte_data(client, UCD9000_GPIO_CONFIG, ret); + if (ret < 0) { + dev_dbg(&client->dev, "Failed to write GPIO %d config: %d\n", + offset, ret); + return; + } + + ret &= ~UCD9000_GPIO_CONFIG_ENABLE; + + ret = i2c_smbus_write_byte_data(client, UCD9000_GPIO_CONFIG, ret); + if (ret < 0) + dev_dbg(&client->dev, "Failed to write GPIO %d config: %d\n", + offset, ret); +} + +static int ucd9000_gpio_get_direction(struct gpio_chip *gc, + unsigned int offset) +{ + struct i2c_client *client = gpiochip_get_data(gc); + int ret; + + ret = ucd9000_gpio_read_config(client, offset); + if (ret < 0) + return ret; + + return !(ret & UCD9000_GPIO_CONFIG_OUT_ENABLE); +} + +static int ucd9000_gpio_set_direction(struct gpio_chip *gc, + unsigned int offset, bool direction_out, + int requested_out) +{ + struct i2c_client *client = gpiochip_get_data(gc); + int ret, config, out_val; + + ret = ucd9000_gpio_read_config(client, offset); + if (ret < 0) + return ret; + + if (direction_out) { + out_val = requested_out ? UCD9000_GPIO_CONFIG_OUT_VALUE : 0; + + if (ret & UCD9000_GPIO_CONFIG_OUT_ENABLE) { + if ((ret & UCD9000_GPIO_CONFIG_OUT_VALUE) == out_val) + return 0; + } else { + ret |= UCD9000_GPIO_CONFIG_OUT_ENABLE; + } + + if (out_val) + ret |= UCD9000_GPIO_CONFIG_OUT_VALUE; + else + ret &= ~UCD9000_GPIO_CONFIG_OUT_VALUE; + + } else { + if (!(ret & UCD9000_GPIO_CONFIG_OUT_ENABLE)) + return 0; + + ret &= ~UCD9000_GPIO_CONFIG_OUT_ENABLE; + } + + ret |= UCD9000_GPIO_CONFIG_ENABLE; + config = ret; + + /* Page set not required */ + ret = i2c_smbus_write_byte_data(client, UCD9000_GPIO_CONFIG, config); + if (ret < 0) + return ret; + + config &= ~UCD9000_GPIO_CONFIG_ENABLE; + + return i2c_smbus_write_byte_data(client, UCD9000_GPIO_CONFIG, config); +} + +static int ucd9000_gpio_direction_input(struct gpio_chip *gc, + unsigned int offset) +{ + return ucd9000_gpio_set_direction(gc, offset, UCD9000_GPIO_INPUT, 0); +} + +static int ucd9000_gpio_direction_output(struct gpio_chip *gc, + unsigned int offset, int val) +{ + return ucd9000_gpio_set_direction(gc, offset, UCD9000_GPIO_OUTPUT, + val); +} + +static void ucd9000_probe_gpio(struct i2c_client *client, + const struct i2c_device_id *mid, + struct ucd9000_data *data) +{ + int rc; + + switch (mid->driver_data) { + case ucd9090: + data->gpio.ngpio = UCD9090_NUM_GPIOS; + break; + case ucd90120: + case ucd90124: + case ucd90160: + data->gpio.ngpio = UCD901XX_NUM_GPIOS; + break; + case ucd90320: + data->gpio.ngpio = UCD90320_NUM_GPIOS; + break; + case ucd90910: + data->gpio.ngpio = UCD90910_NUM_GPIOS; + break; + default: + return; /* GPIO support is optional. */ + } + + /* + * Pinmux support has not been added to the new gpio_chip. + * This support should be added when possible given the mux + * behavior of these IO devices. + */ + data->gpio.label = client->name; + data->gpio.get_direction = ucd9000_gpio_get_direction; + data->gpio.direction_input = ucd9000_gpio_direction_input; + data->gpio.direction_output = ucd9000_gpio_direction_output; + data->gpio.get = ucd9000_gpio_get; + data->gpio.set = ucd9000_gpio_set; + data->gpio.can_sleep = true; + data->gpio.base = -1; + data->gpio.parent = &client->dev; + + rc = devm_gpiochip_add_data(&client->dev, &data->gpio, client); + if (rc) + dev_warn(&client->dev, "Could not add gpiochip: %d\n", rc); +} +#else +static void ucd9000_probe_gpio(struct i2c_client *client, + const struct i2c_device_id *mid, + struct ucd9000_data *data) +{ +} +#endif /* CONFIG_GPIOLIB */ + +#ifdef CONFIG_DEBUG_FS +static int ucd9000_get_mfr_status(struct i2c_client *client, u8 *buffer) +{ + int ret = wb_pmbus_set_page(client, 0, 0xff); + + if (ret < 0) + return ret; + + return wb_i2c_smbus_read_block_data(client, UCD9000_MFR_STATUS, buffer); +} + +static int ucd9000_debugfs_show_mfr_status_bit(void *data, u64 *val) +{ + struct ucd9000_debugfs_entry *entry = data; + struct i2c_client *client = entry->client; + u8 buffer[I2C_SMBUS_BLOCK_MAX]; + int ret, i; + + ret = ucd9000_get_mfr_status(client, buffer); + if (ret < 0) + return ret; + + /* + * GPI fault bits are in sets of 8, two bytes from end of response. + */ + i = ret - 3 - entry->index / 8; + if (i >= 0) + *val = !!(buffer[i] & BIT(entry->index % 8)); + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(ucd9000_debugfs_mfr_status_bit, + ucd9000_debugfs_show_mfr_status_bit, NULL, "%1lld\n"); + +static ssize_t ucd9000_debugfs_read_mfr_status(struct file *file, + char __user *buf, size_t count, + loff_t *ppos) +{ + struct i2c_client *client = file->private_data; + u8 buffer[I2C_SMBUS_BLOCK_MAX]; + char str[(I2C_SMBUS_BLOCK_MAX * 2) + 2]; + char *res; + int rc; + + rc = ucd9000_get_mfr_status(client, buffer); + if (rc < 0) + return rc; + + res = bin2hex(str, buffer, min(rc, I2C_SMBUS_BLOCK_MAX)); + *res++ = '\n'; + *res = 0; + + return simple_read_from_buffer(buf, count, ppos, str, res - str); +} + +static const struct file_operations ucd9000_debugfs_show_mfr_status_fops = { + .llseek = noop_llseek, + .read = ucd9000_debugfs_read_mfr_status, + .open = simple_open, +}; + +static int ucd9000_init_debugfs(struct i2c_client *client, + const struct i2c_device_id *mid, + struct ucd9000_data *data) +{ + struct dentry *debugfs; + struct ucd9000_debugfs_entry *entries; + int i, gpi_count; + char name[UCD9000_DEBUGFS_NAME_LEN]; + + debugfs = wb_pmbus_get_debugfs_dir(client); + if (!debugfs) + return -ENOENT; + + data->debugfs = debugfs_create_dir(client->name, debugfs); + if (!data->debugfs) + return -ENOENT; + + /* + * Of the chips this driver supports, only the UCD9090, UCD90160, + * UCD90320, and UCD90910 report GPI faults in their MFR_STATUS + * register, so only create the GPI fault debugfs attributes for those + * chips. + */ + if (mid->driver_data == ucd9090 || mid->driver_data == ucd90160 || + mid->driver_data == ucd90320 || mid->driver_data == ucd90910) { + gpi_count = mid->driver_data == ucd90320 ? UCD90320_GPI_COUNT + : UCD9000_GPI_COUNT; + entries = devm_kcalloc(&client->dev, + gpi_count, sizeof(*entries), + GFP_KERNEL); + if (!entries) + return -ENOMEM; + + for (i = 0; i < gpi_count; i++) { + entries[i].client = client; + entries[i].index = i; + scnprintf(name, UCD9000_DEBUGFS_NAME_LEN, + "gpi%d_alarm", i + 1); + debugfs_create_file(name, 0444, data->debugfs, + &entries[i], + &ucd9000_debugfs_mfr_status_bit); + } + } + + scnprintf(name, UCD9000_DEBUGFS_NAME_LEN, "mfr_status"); + debugfs_create_file(name, 0444, data->debugfs, client, + &ucd9000_debugfs_show_mfr_status_fops); + + return 0; +} +#else +static int ucd9000_init_debugfs(struct i2c_client *client, + const struct i2c_device_id *mid, + struct ucd9000_data *data) +{ + return 0; +} +#endif /* CONFIG_DEBUG_FS */ + +static int ucd9000_probe(struct i2c_client *client) +{ + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; + char wb_device_name[WB_DEV_NAME_MAX_LEN]; + struct ucd9000_data *data; + struct pmbus_driver_info *info; + const struct i2c_device_id *mid; + enum chips chip; + int i, ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA)) + return -ENODEV; + + ret = wb_i2c_smbus_read_block_data(client, UCD9000_DEVICE_ID, + block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read device ID\n"); + return ret; + } + block_buffer[ret] = '\0'; + dev_info(&client->dev, "Device ID %s\n", block_buffer); + + mem_clear(wb_device_name, sizeof(wb_device_name)); + snprintf(wb_device_name, sizeof(wb_device_name), "wb_%s", block_buffer); + + for (mid = ucd9000_id; mid->name[0]; mid++) { + if (!strncasecmp(mid->name, wb_device_name, strlen(mid->name))) + break; + } + if (!mid->name[0]) { + dev_err(&client->dev, "Unsupported device\n"); + return -ENODEV; + } + + if (client->dev.of_node) + chip = (enum chips)of_device_get_match_data(&client->dev); + else + chip = mid->driver_data; + + if (chip != ucd9000 && strcmp(client->name, mid->name) != 0) + dev_notice(&client->dev, + "Device mismatch: Configured %s, detected %s\n", + client->name, mid->name); + + data = devm_kzalloc(&client->dev, sizeof(struct ucd9000_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + info = &data->info; + + ret = i2c_smbus_read_byte_data(client, UCD9000_NUM_PAGES); + if (ret < 0) { + dev_err(&client->dev, + "Failed to read number of active pages\n"); + return ret; + } + info->pages = ret; + if (!info->pages) { + dev_err(&client->dev, "No pages configured\n"); + return -ENODEV; + } + + /* The internal temperature sensor is always active */ + info->func[0] = PMBUS_HAVE_TEMP; + + /* Everything else is configurable */ + ret = wb_i2c_smbus_read_block_data(client, UCD9000_MONITOR_CONFIG, + block_buffer); + if (ret <= 0) { + dev_err(&client->dev, "Failed to read configuration data\n"); + return -ENODEV; + } + for (i = 0; i < ret; i++) { + int page = UCD9000_MON_PAGE(block_buffer[i]); + + if (page >= info->pages) + continue; + + switch (UCD9000_MON_TYPE(block_buffer[i])) { + case UCD9000_MON_VOLTAGE: + case UCD9000_MON_VOLTAGE_HW: + info->func[page] |= PMBUS_HAVE_VOUT + | PMBUS_HAVE_STATUS_VOUT; + break; + case UCD9000_MON_TEMPERATURE: + info->func[page] |= PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_STATUS_TEMP; + break; + case UCD9000_MON_CURRENT: + info->func[page] |= PMBUS_HAVE_IOUT + | PMBUS_HAVE_STATUS_IOUT; + break; + default: + break; + } + } + + /* Fan configuration */ + if (mid->driver_data == ucd90124) { + for (i = 0; i < UCD9000_NUM_FAN; i++) { + i2c_smbus_write_byte_data(client, + UCD9000_FAN_CONFIG_INDEX, i); + ret = wb_i2c_smbus_read_block_data(client, + UCD9000_FAN_CONFIG, + data->fan_data[i]); + if (ret < 0) + return ret; + } + i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0); + + info->read_byte_data = ucd9000_read_byte_data; + info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 + | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34; + } + + ucd9000_probe_gpio(client, mid, data); + + ret = wb_pmbus_do_probe(client, info); + if (ret) + return ret; + + ret = ucd9000_init_debugfs(client, mid, data); + if (ret) + dev_warn(&client->dev, "Failed to register debugfs: %d\n", + ret); + + return 0; +} + +/* This is the driver that will be inserted */ +static struct i2c_driver ucd9000_driver = { + .driver = { + .name = "wb_ucd9000", + .of_match_table = of_match_ptr(ucd9000_of_match), + }, + .probe_new = ucd9000_probe, + .remove = wb_pmbus_do_remove, + .id_table = ucd9000_id, +}; + +module_i2c_driver(ucd9000_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/Makefile new file mode 100644 index 000000000000..369b64605dd3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/Makefile @@ -0,0 +1,20 @@ +pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST)) +pes_parent_dir:=$(shell dirname $(pes_parent_dir)) + +SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "build") print $$9}') +INC = -I./inc + +all : CHECK $(SUBDIRS) +CHECK : + @echo $(pes_parent_dir) + +$(SUBDIRS):ECHO + #@echo $@ + make -C $@ + +ECHO: + @echo $(SUBDIRS) + +.PHONY : clean +clean : + -rm -rf $(SYSFS_OUT_PUT) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/Makefile new file mode 100644 index 000000000000..e516b70b3d92 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/Makefile @@ -0,0 +1,25 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +SUBDIR_CFG = cfg +plat_dfd-objs := dfd_module.o dfd_fan_driver.o \ +dfd_slot_driver.o \ +dfd_sensors_driver.o \ +dfd_psu_driver.o \ +dfd_sff_driver.o \ +$(SUBDIR_CFG)/dfd_cfg.o \ +$(SUBDIR_CFG)/dfd_cfg_adapter.o \ +$(SUBDIR_CFG)/dfd_cfg_file.o \ +$(SUBDIR_CFG)/dfd_cfg_info.o \ +$(SUBDIR_CFG)/dfd_cfg_listnode.o \ + +obj-m := plat_dfd.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/$(SUBDIR_CFG)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/$(SUBDIR_CFG)/.*.cmd $(PWD)/*.mod + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c new file mode 100644 index 000000000000..b0c9e9f6e723 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c @@ -0,0 +1,812 @@ +#include +#include +#include +#include +#include +#include + +#include "../include/dfd_module.h" +#include "../include/dfd_cfg_file.h" +#include "../include/dfd_cfg_listnode.h" +#include "../include/dfd_cfg_info.h" +#include "../include/dfd_cfg_adapter.h" +#include "../include/dfd_cfg.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) _name, +static char *dfd_cfg_item_name[] = { + DFD_CFG_ITEM_ALL +}; + +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) {_index_min, _index_max}, +static index_range_t dfd_cfg_item_index_range[] = { + DFD_CFG_ITEM_ALL +}; + +static lnode_root_t dfd_ko_cfg_list_root; + +static void dfd_ko_cfg_del_space_lf_cr(char *str) +{ + int i, j; + int len; + + len = strlen(str); + for (i = 0; i < len; i++) { + if (str[i] == '\r' || str[i] == '\n' || str[i] == ' ') { + for (j = i; j < len - 1; j++) { + str[j] = str[j + 1]; + } + str[j] = '\0'; + len--; + i--; + } + } +} + +static int dfd_ko_cfg_get_value_from_char(char *value_str, int32_t *value, int line_num) +{ + int value_tmp = 0; + + if (strlen(value_str) == 0) { + DBG_DEBUG(DBG_WARN, "line%d: value str is empty\n", line_num); + *value = DFD_CFG_EMPTY_VALUE; + return 0; + } + + if ((strlen(value_str) > 2) && (value_str[0] == '0') + && (value_str[1] == 'x' || value_str[1] == 'X')) { + value_tmp = (int32_t)simple_strtol(value_str, NULL, 16); + } else { + value_tmp = (int32_t)simple_strtol(value_str, NULL, 10); + } + + *value = value_tmp; + return 0; +} + +static int dfd_ko_cfg_analyse_index(char *index_str, int *index1, int *index2, int line_num) +{ + int rv; + char *index1_begin_char, *index2_begin_char; + + if (index_str[0] != '_') { + DBG_DEBUG(DBG_ERROR, "line%d: no '-' between name and index1\n", line_num); + return -1; + } + + index1_begin_char = index_str; + rv = dfd_ko_cfg_get_value_from_char(++index1_begin_char, index1, line_num); + if (rv < 0) { + return -1; + } + + if (index2 == NULL) { + return 0; + } + + index2_begin_char = strchr(index1_begin_char, '_'); + if (index2_begin_char == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: no '-' between index1 and index2\n", line_num); + return -1; + } else { + rv = dfd_ko_cfg_get_value_from_char(++index2_begin_char, index2, line_num); + if (rv < 0) { + return -1; + } + } + + return 0; +} + +static int dfd_ko_cfg_check_array_index(index_range_t *index_range, int *index1, int *index2, + int line_num) +{ + + if ((*index1 < 0) || (*index1 > index_range->index1_max)) { + DBG_DEBUG(DBG_ERROR, "line%d: index1[%d] invalid, max=%d\n", line_num, *index1, + index_range->index1_max); + return -1; + } + + if (index2 == NULL) { + return 0; + } + + if ((*index2 < 0) || (*index2 > index_range->index2_max)) { + DBG_DEBUG(DBG_ERROR, "line%d: index2[%d] invalid, max=%d\n", line_num, *index2, + index_range->index2_max); + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_get_index(char *index_str, index_range_t *index_range, int *index1, + int *index2, int line_num) +{ + int rv; + + if (index_range->index2_max == INDEX_NOT_EXIST) { + index2 = NULL; + } + + rv = dfd_ko_cfg_analyse_index(index_str, index1, index2, line_num); + if (rv < 0) { + return -1; + } + + rv = dfd_ko_cfg_check_array_index(index_range, index1, index2, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_add_int_item(int key, int value, int line_num) +{ + int rv; + int *int_cfg; + + int_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (int_cfg == NULL) { + + int_cfg = (int *)kmalloc(sizeof(int), GFP_KERNEL); + if (int_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc int fail\n", line_num); + return -1; + } + + *int_cfg = value; + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, int_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add int item[%d] success, key=0x%08x\n", line_num, value, key); + } else { + kfree(int_cfg); + int_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add int item[%d] fail, key=0x%08x rv=%d \n", line_num, value, key, rv); + return -1; + } + } else { + + DBG_DEBUG(DBG_WARN, "line%d: replace int item[%d->%d], key=0x%08x\n", line_num, *int_cfg, value, key); + *int_cfg = value; + } + + return 0; +} + +static int dfd_ko_cfg_analyse_int_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, char *arg_value, + char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int value, key; + char *arg_name_tmp; + + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num); + if (rv < 0) { + return -1; + } + + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_int_item(key, value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_add_str_item(int key, char *str, int line_num) +{ + int rv; + char *str_cfg; + + str_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (str_cfg == NULL) { + + str_cfg = (char *)kmalloc(DFD_CFG_STR_MAX_LEN, GFP_KERNEL); + if (str_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc str[%lu] fail\n", line_num, strlen(str)); + return -1; + } + mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); + strncpy(str_cfg, str, DFD_CFG_STR_MAX_LEN - 1); + + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, str_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add string item[%s] success, key=0x%08x\n", line_num, str_cfg, key); + } else { + kfree(str_cfg); + str_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add string item[%s] fail, key=0x%08x rv=%d \n", line_num, str_cfg, key, rv); + return -1; + } + } else { + DBG_DEBUG(DBG_WARN, "line%d: replace string item[%s->%s], key=0x%08x\n", line_num, str_cfg, str, key); + mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); + strncpy(str_cfg, str, DFD_CFG_STR_MAX_LEN - 1); + } + + return 0; +} + +static int dfd_ko_cfg_analyse_str_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, char *arg_value, + char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int btree_key; + char *arg_name_tmp; + + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + if (strlen(arg_value) >= DFD_CFG_STR_MAX_LEN) { + DBG_DEBUG(DBG_ERROR, "line%d: string item[%s] is too long \n", line_num, arg_value); + return -1; + } + + btree_key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_str_item(btree_key, arg_value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_get_i2c_dev_member(char *member_str, dfd_i2c_dev_mem_t *member, int line_num) +{ + dfd_i2c_dev_mem_t mem_index; + + for (mem_index = DFD_I2C_DEV_MEM_BUS; mem_index < DFD_I2C_DEV_MEM_END; mem_index++) { + if (memcmp(member_str, g_dfd_i2c_dev_mem_str[mem_index], + strlen(g_dfd_i2c_dev_mem_str[mem_index])) == 0) { + *member = mem_index; + return 0; + } + } + + DBG_DEBUG(DBG_ERROR, "line%d: i2c dev member[%s] invalid\n", line_num, member_str); + return -1; +} + +static void dfd_ko_cfg_set_i2c_dev_mem_value(dfd_i2c_dev_t *i2c_dev, dfd_i2c_dev_mem_t member, + int value) +{ + switch (member) { + case DFD_I2C_DEV_MEM_BUS: + i2c_dev->bus = value; + break; + case DFD_I2C_DEV_MEM_ADDR: + i2c_dev->addr = value; + break; + default: + break; + } +} + +static int dfd_ko_cfg_add_i2c_dev_item(int key, dfd_i2c_dev_mem_t member, int value, int line_num) +{ + int rv; + dfd_i2c_dev_t *i2c_dev_cfg; + + i2c_dev_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (i2c_dev_cfg == NULL) { + + i2c_dev_cfg = (dfd_i2c_dev_t *)kmalloc(sizeof(dfd_i2c_dev_t), GFP_KERNEL); + if (i2c_dev_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc i2c_dev fail\n", line_num); + return -1; + } + mem_clear(i2c_dev_cfg, sizeof(dfd_i2c_dev_t)); + + dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value); + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, i2c_dev_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add i2c_dev item[%s=%d] success, key=0x%08x\n", line_num, + g_dfd_i2c_dev_mem_str[member], value, key); + } else { + kfree(i2c_dev_cfg); + i2c_dev_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add i2c_dev item[%s=%d] fail, key=0x%08x rv=%d\n", line_num, + g_dfd_i2c_dev_mem_str[member], value, key, rv); + return -1; + } + } else { + + DBG_DEBUG(DBG_VERBOSE, "line%d: replace i2c_dev item[%s=%d], key=0x%08x\n", line_num, + g_dfd_i2c_dev_mem_str[member], value, key); + dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value); + } + + return 0; +} + +static int dfd_ko_cfg_analyse_i2c_dev_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int value, key; + char *arg_name_tmp; + dfd_i2c_dev_mem_t member; + + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_i2c_dev_member(arg_name_tmp, &member, line_num); + if (rv < 0) { + return -1; + } + + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp += strlen(g_dfd_i2c_dev_mem_str[member]); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num); + if (rv < 0) { + return -1; + } + + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_i2c_dev_item(key, member, value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_get_enum_value_by_str(char *enum_val_str[], int enum_val_end, char *buf) +{ + int i; + int enum_val; + + enum_val = DFD_CFG_INVALID_VALUE; + for (i = 0; i < enum_val_end; i++) { + if (memcmp(buf, enum_val_str[i], strlen(enum_val_str[i])) == 0) { + enum_val = i; + break; + } + } + + return enum_val; +} + +static int dfd_ko_cfg_get_info_ctrl_member(char *member_str, info_ctrl_mem_t *member, int line_num) +{ + info_ctrl_mem_t mem_index; + + for (mem_index = INFO_CTRL_MEM_MODE; mem_index < INFO_CTRL_MEM_END; mem_index++) { + if (memcmp(member_str, g_info_ctrl_mem_str[mem_index], + strlen(g_info_ctrl_mem_str[mem_index])) == 0) { + *member = mem_index; + return 0; + } + } + + DBG_DEBUG(DBG_ERROR, "line%d: info ctrl member[%s] invalid\n", line_num, member_str); + return -1; +} + +static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl_mem_t member, + char *buf_val, int line_num) +{ + switch (member) { + case INFO_CTRL_MEM_MODE: + info_ctrl->mode = dfd_ko_cfg_get_enum_value_by_str(g_info_ctrl_mode_str, INFO_CTRL_MODE_END, buf_val);; + break; + case INFO_CTRL_MEM_INT_CONS: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_cons), line_num); + break; + case INFO_CTRL_MEM_SRC: + info_ctrl->src = dfd_ko_cfg_get_enum_value_by_str(g_info_src_str, INFO_SRC_END, buf_val); + break; + case INFO_CTRL_MEM_FRMT: + info_ctrl->frmt = dfd_ko_cfg_get_enum_value_by_str(g_info_frmt_str, INFO_FRMT_END, buf_val); + break; + case INFO_CTRL_MEM_POLA: + info_ctrl->pola = dfd_ko_cfg_get_enum_value_by_str(g_info_pola_str, INFO_POLA_END, buf_val); + break; + case INFO_CTRL_MEM_FPATH: + mem_clear(info_ctrl->fpath, sizeof(info_ctrl->fpath)); + strncpy(info_ctrl->fpath, buf_val, sizeof(info_ctrl->fpath) - 1); + break; + case INFO_CTRL_MEM_ADDR: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->addr), line_num); + break; + case INFO_CTRL_MEM_LEN: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->len), line_num); + break; + case INFO_CTRL_MEM_BIT_OFFSET: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->bit_offset), line_num); + break; + case INFO_CTRL_MEM_STR_CONS: + mem_clear(info_ctrl->str_cons, sizeof(info_ctrl->str_cons)); + strncpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons) - 1); + break; + case INFO_CTRL_MEM_INT_EXTRA1: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra1), line_num); + break; + case INFO_CTRL_MEM_INT_EXTRA2: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra2), line_num); + break; + default: + break; + } +} + +static int dfd_ko_cfg_add_info_ctrl_item(int key, info_ctrl_mem_t member, char *buf_val, + int line_num) +{ + int rv; + info_ctrl_t *info_ctrl_cfg; + + info_ctrl_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (info_ctrl_cfg == NULL) { + + info_ctrl_cfg = (info_ctrl_t *)kmalloc(sizeof(info_ctrl_t), GFP_KERNEL); + if (info_ctrl_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc info_ctrl fail\n", line_num); + return -1; + } + mem_clear(info_ctrl_cfg, sizeof(info_ctrl_t)); + + dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num); + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, info_ctrl_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add info_ctrl item[%s=%s] success, key=0x%08x\n", line_num, + g_info_ctrl_mem_str[member], buf_val, key); + } else { + kfree(info_ctrl_cfg); + info_ctrl_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add info_ctrl item[%s=%s] fail, key=0x%08x rv=%d\n", line_num, + g_info_ctrl_mem_str[member], buf_val, key, rv); + return -1; + } + } else { + + DBG_DEBUG(DBG_VERBOSE, "line%d: replace info_ctrl item[%s=%s], key=0x%08x\n", line_num, + g_info_ctrl_mem_str[member], buf_val, key); + dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num); + } + + return 0; +} + +static int dfd_ko_cfg_analyse_info_ctrl_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int key; + char *arg_name_tmp; + info_ctrl_mem_t member; + + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_info_ctrl_member(arg_name_tmp, &member, line_num); + if (rv < 0) { + return -1; + } + + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp += strlen(g_info_ctrl_mem_str[member]); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_info_ctrl_item(key, member, arg_value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_analyse_config(char *arg_name, char*arg_value, int line_num) +{ + int i, rv = 0; + int cfg_item_num; + + cfg_item_num = sizeof(dfd_cfg_item_name) / sizeof(dfd_cfg_item_name[0]); + for (i = 0; i < cfg_item_num; i++) { + if (memcmp(arg_name, dfd_cfg_item_name[i], strlen(dfd_cfg_item_name[i])) == 0){ + if (DFD_CFG_ITEM_IS_INT(i)) { + rv = dfd_ko_cfg_analyse_int_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_STRING(i)) { + rv = dfd_ko_cfg_analyse_str_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_I2C_DEV(i)) { + rv = dfd_ko_cfg_analyse_i2c_dev_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_INFO_CTRL(i)) { + rv = dfd_ko_cfg_analyse_info_ctrl_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else { + rv = -1; + } + break; + } + } + + return rv; +} + +static int dfd_ko_cfg_cut_config_line(char *config_line, char *arg_name, char *arg_value) +{ + int i, j = 0, k = 0; + int len, name_value_flag = 0; + + len = strlen(config_line); + for (i = 0; i < len; i++) { + if (config_line[i] == '=') { + name_value_flag = 1; + continue; + } + + if (name_value_flag == 0) { + arg_name[j++] = config_line[i]; + } else { + arg_value[k++] = config_line[i]; + } + } + + if (name_value_flag == 0) { + return -1; + } else { + return 0; + } +} + +static int dfd_ko_cfg_analyse_config_line(char *config_line, int line_num) +{ + int rv; + char arg_name[DFD_CFG_NAME_MAX_LEN] = {0}; + char arg_value[DFD_CFG_VALUE_MAX_LEN] = {0}; + + dfd_ko_cfg_del_space_lf_cr(config_line); + + if (strlen(config_line) == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: space line\n", line_num); + return 0; + } + + if (config_line[0] == '#') { + DBG_DEBUG(DBG_VERBOSE, "line%d: comment line[%s]\n", line_num, config_line); + return 0; + } + + rv = dfd_ko_cfg_cut_config_line(config_line, arg_name, arg_value); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: [%s]no '=' between name and value\n", line_num, config_line); + return -1; + } + + DBG_DEBUG(DBG_VERBOSE, "line%d: config_line[%s] name[%s] value[%s]\n", line_num, config_line, arg_name, arg_value); + return dfd_ko_cfg_analyse_config(arg_name, arg_value, line_num); +} + +static int dfd_ko_cfg_analyse_config_file(char *fpath) +{ + int rv; + int line_num = 1; + kfile_ctrl_t kfile_ctrl; + char config_line[DFD_CFG_CMDLINE_MAX_LEN] = {0}; + + rv = kfile_open(fpath, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", fpath, rv); + return -1; + } + + while(kfile_gets(config_line, sizeof(config_line), &kfile_ctrl) > 0){ + rv = dfd_ko_cfg_analyse_config_line(config_line, line_num++); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "!!!!file[%s] config line[%d %s] analyse fail\n", fpath, line_num - 1, + config_line); + break; + } + + (void)mem_clear(config_line, sizeof(config_line)); + + } + kfile_close(&kfile_ctrl); + + return rv; +} + +void *dfd_ko_cfg_get_item(int key) +{ + return lnode_find_node(&dfd_ko_cfg_list_root, key); +} + +static void dfd_ko_cfg_print_item(int key, const void *cfg) +{ + int item_id; + dfd_i2c_dev_t *i2c_dev; + info_ctrl_t *info_ctrl; + + if (cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return; + } + printk(KERN_INFO "**************************\n"); + printk(KERN_INFO "key=0x%08x\n", key); + + item_id = DFD_CFG_ITEM_ID(key); + if (DFD_CFG_ITEM_IS_INT(item_id)) { + printk(KERN_INFO "int=%d\n", *((int *)cfg)); + } else if (DFD_CFG_ITEM_IS_I2C_DEV(item_id)) { + i2c_dev = (dfd_i2c_dev_t *)cfg; + printk(KERN_INFO ".bus=0x%02x\n", i2c_dev->bus); + printk(KERN_INFO ".addr=0x%02x\n", i2c_dev->addr); + } else if (DFD_CFG_ITEM_IS_INFO_CTRL(item_id)) { + info_ctrl = (info_ctrl_t *)cfg; + printk(KERN_INFO ".mode=%s\n", g_info_ctrl_mode_str[info_ctrl->mode]); + printk(KERN_INFO ".int_cons=%d\n", info_ctrl->int_cons); + printk(KERN_INFO ".src=%s\n", g_info_src_str[info_ctrl->src]); + printk(KERN_INFO ".frmt=%s\n", g_info_frmt_str[info_ctrl->frmt]); + printk(KERN_INFO ".pola=%s\n", g_info_pola_str[info_ctrl->pola]); + printk(KERN_INFO ".fpath=%s\n", info_ctrl->fpath); + printk(KERN_INFO ".addr=0x%02x\n", info_ctrl->addr); + printk(KERN_INFO ".len=%d\n", info_ctrl->len); + printk(KERN_INFO ".bit_offset=%d\n", info_ctrl->bit_offset); + } else { + printk(KERN_INFO "item[%d] error!\n", item_id); + } +} + +void dfd_ko_cfg_show_item(int key) +{ + void *cfg; + + cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (cfg == 0) { + printk(KERN_INFO "item[0x%08x] not exist\n", key); + return; + } + + dfd_ko_cfg_print_item(key, cfg); +} + +static int dfd_get_my_dev_type_by_file(void) +{ + struct file *fp; + loff_t pos; + int card_type; + char buf[DFD_PID_BUF_LEN]; + int ret; + + fp= filp_open(DFD_PUB_CARDTYPE_FILE, O_RDONLY, 0); + if (IS_ERR(fp)) { + DBG_DEBUG(DBG_VERBOSE, "open file fail!\n"); + return -1; + } + mem_clear(buf, DFD_PID_BUF_LEN); + pos = 0; + ret = kernel_read(fp, buf, DFD_PRODUCT_ID_LENGTH + 1, &pos); + if (ret < 0) { + DBG_DEBUG(DBG_VERBOSE, "kernel_read failed, path=%s, addr=0, size=%d, ret=%d\n", + DFD_PUB_CARDTYPE_FILE, DFD_PRODUCT_ID_LENGTH + 1, ret); + filp_close(fp, NULL); + return -1; + } + + card_type = simple_strtoul(buf, NULL, 10); + DBG_DEBUG(DBG_VERBOSE, "card_type 0x%x.\n", card_type); + + filp_close(fp, NULL); + return card_type; +} + +static int drv_get_my_dev_type(void) +{ + static int type = -1; + + if (type > 0) { + return type; + } + type = dfd_get_my_dev_type_by_file(); + DBG_DEBUG(DBG_VERBOSE, "ko board type %d\n", type); + return type; +} + +static int dfd_ko_cfg_init(void) +{ + int rv; + int card_type; + char file_name[32] = {0}; + char fpath[128] = {0}; + kfile_ctrl_t kfile_ctrl; + + rv = lnode_init_root(&dfd_ko_cfg_list_root); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "init list root fail, rv=%d\n", rv); + return -1; + } + + card_type = drv_get_my_dev_type(); + if (card_type > 0) { + snprintf(fpath, sizeof(fpath), "%s0x%x", DFD_KO_CFG_FILE_DIR, card_type); + rv = kfile_open(fpath, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_VERBOSE, "open config file[%s] fail, rv=%d, maybe not exist\n", + fpath, rv); + + rv = kfile_open(DFD_KO_CFG_FILE_NAME, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", DFD_KO_CFG_FILE_NAME, + rv); + return -1; + } + DBG_DEBUG(DBG_ERROR, "get config file from: %s, success.\n", DFD_KO_CFG_FILE_NAME); + } else { + DBG_DEBUG(DBG_VERBOSE, "get config file from: %s, success.\n", fpath); + } + } else { + DBG_DEBUG(DBG_VERBOSE, "get board id failed, try to get config file from: %s\n", + DFD_KO_CFG_FILE_NAME); + + rv = kfile_open(DFD_KO_CFG_FILE_NAME, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", DFD_KO_CFG_FILE_NAME, rv); + return -1; + } + DBG_DEBUG(DBG_ERROR, "get config file from: %s, success.\n", DFD_KO_CFG_FILE_NAME); + } + + while (kfile_gets(file_name, sizeof(file_name), &kfile_ctrl) > 0) { + + dfd_ko_cfg_del_space_lf_cr(file_name); + mem_clear(fpath, sizeof(fpath)); + snprintf(fpath, sizeof(fpath), "%s%s.cfg", DFD_KO_CFG_FILE_DIR, file_name); + DBG_DEBUG(DBG_VERBOSE, ">>>>start parsing config file[%s]\n", fpath); + + rv = dfd_ko_cfg_analyse_config_file(fpath); + if (rv < 0) { + break; + } + } + kfile_close(&kfile_ctrl); + + return 0; +} + +int32_t dfd_dev_cfg_init(void) +{ + return dfd_ko_cfg_init(); +} + +void dfd_dev_cfg_exit(void) +{ + lnode_free_list(&dfd_ko_cfg_list_root); + return; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c new file mode 100644 index 000000000000..1d5ca7072f8f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c @@ -0,0 +1,351 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "../include/dfd_module.h" +#include "../include/dfd_cfg_file.h" +#include "../include/dfd_cfg.h" +#include "../include/dfd_cfg_adapter.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +char *g_dfd_i2c_dev_mem_str[DFD_I2C_DEV_MEM_END] = { + ".bus", + ".addr", +}; + +static dfd_i2c_dev_t* dfd_ko_get_cpld_i2c_dev(int sub_slot, int cpld_id) +{ + int key; + dfd_i2c_dev_t *i2c_dev; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_I2C_DEV, sub_slot, cpld_id); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld[%d] i2c dev config fail, key=0x%08x\n", cpld_id, key); + return NULL; + } + + return i2c_dev; +} + +static int32_t dfd_ko_i2c_smbus_transfer(int read_write, int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int rv; + struct i2c_adapter *i2c_adap; + union i2c_smbus_data data; + + i2c_adap = i2c_get_adapter(bus); + if (i2c_adap == NULL) { + DBG_DEBUG(DBG_ERROR, "get i2c bus[%d] adapter fail\n", bus); + return -DFD_RV_DEV_FAIL; + } + + if (read_write == I2C_SMBUS_WRITE) { + data.byte = *buf; + } else { + data.byte = 0; + } + rv = i2c_smbus_xfer(i2c_adap, addr, 0, read_write, offset, I2C_SMBUS_BYTE_DATA, &data); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer fail, rv=%d\n", + bus, addr, offset, size, read_write, rv); + rv = -DFD_RV_DEV_FAIL; + } else { + DBG_DEBUG(DBG_VERBOSE, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer success\n", + bus, addr, offset, size, read_write); + rv = DFD_RV_OK; + } + + if (read_write == I2C_SMBUS_READ) { + if (rv == DFD_RV_OK) { + *buf = data.byte; + } else { + *buf = 0; + } + } + + i2c_put_adapter(i2c_adap); + return rv; +} + +static int32_t dfd_ko_i2c_read_data(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_READ, bus, addr, offset, buf, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d]cpld read[offset=0x%x] fail, rv %d\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d]cpld read[offset=0x%x] success, value=0x%x\n", + i, addr, *buf); + break; + } + } + return rv; +} + +static int32_t dfd_ko_i2c_write_data(int bus, int addr, int offset, uint8_t data, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_WRITE, bus, addr, offset, &data, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d]cpld write[offset=0x%x] fail, rv=%d\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d]cpld write[offset=0x%x, data=%d] success\n", i, addr, data); + break; + } + } + + return rv; +} + +static int32_t dfd_ko_cpld_i2c_read(int32_t addr, uint8_t *buf) +{ + int rv; + int sub_slot, cpld_id, cpld_addr; + dfd_i2c_dev_t *i2c_dev; + + if (buf == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INDEX_INVALID; + } + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + cpld_addr = DFD_KO_CPLD_GET_INDEX(addr); + + i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id); + if (i2c_dev == NULL) { + return -DFD_RV_DEV_NOTSUPPORT; + } + rv = dfd_ko_i2c_read_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, buf, sizeof(uint8_t)); + + return rv; +} + +static int32_t dfd_ko_cpld_i2c_write(int32_t addr, uint8_t data) +{ + int rv; + int sub_slot, cpld_id, cpld_addr; + dfd_i2c_dev_t *i2c_dev; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + cpld_addr = DFD_KO_CPLD_GET_INDEX(addr); + + i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id); + if (i2c_dev == NULL) { + return -DFD_RV_DEV_NOTSUPPORT; + } + + rv = dfd_ko_i2c_write_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, data, sizeof(uint8_t)); + + return rv; +} + +static int32_t dfd_ko_cpld_io_read(int32_t addr, uint8_t *buf) +{ + int cpld_id, sub_slot, offset; + int key; + int *tmp; + uint16_t io_port; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + offset = DFD_KO_CPLD_GET_INDEX(addr); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id); + tmp = dfd_ko_cfg_get_item(key); + if (tmp == NULL) { + DBG_DEBUG(DBG_ERROR,"get cpld io base config fail, key=0x%08x\n", key); + return -1; + } + + io_port = (u16)(*tmp) + offset; + *buf = inb(io_port); + DBG_DEBUG(DBG_VERBOSE, "read cpld io port addr 0x%x, data 0x%x\n", io_port, *buf); + + return DFD_RV_OK; + +} + +static int32_t dfd_ko_cpld_io_write(int32_t addr, uint8_t data) +{ + int cpld_id, sub_slot, offset; + int key; + int *tmp; + uint16_t io_port; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + offset = DFD_KO_CPLD_GET_INDEX(addr); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id); + tmp = dfd_ko_cfg_get_item(key); + if (tmp == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld io base config fail, key=0x%08x\n", key); + return -1; + } + + io_port = (u16)(*tmp) + offset; + DBG_DEBUG(DBG_VERBOSE, "write cpld io port addr 0x%x, data 0x%x\n", io_port, data); + outb(data, (u16)io_port); + + return DFD_RV_OK; +} + +static int dfd_cfg_get_cpld_mode(int sub_slot, int cpld_id, int *mode) +{ + int key; + char *name; + + if (mode == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_TYPE_ERR; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_MODE, sub_slot, cpld_id); + name = dfd_ko_cfg_get_item(key); + if (name == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld[%d] mode info ctrl fail, key=0x%08x\n", cpld_id, key); + return -DFD_RV_NODE_FAIL; + } + + DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode_name %s.\n", cpld_id, name); + if (!strncmp(name, DFD_KO_CPLD_MODE_I2C_STRING, strlen(DFD_KO_CPLD_MODE_I2C_STRING))) { + *mode = DFD_CPLD_MODE_I2C; + } else if (!strncmp(name, DFD_KO_CPLD_MODE_LPC_STRING, strlen(DFD_KO_CPLD_MODE_LPC_STRING))) { + *mode = DFD_CPLD_MODE_LPC; + } else { + + *mode = DFD_CPLD_MODE_I2C; + } + + DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode %d.\n", cpld_id, *mode); + return 0; +} + +int32_t dfd_ko_cpld_read(int32_t addr, uint8_t *buf) +{ + int ret; + int sub_slot, cpld_id; + int cpld_mode; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + + ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode); + if (ret) { + DBG_DEBUG(DBG_WARN, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default i2c mode.\n", sub_slot, cpld_id); + cpld_mode = DFD_CPLD_MODE_I2C; + } + + if (cpld_mode == DFD_CPLD_MODE_I2C) { + ret = dfd_ko_cpld_i2c_read(addr, buf); + } else if (cpld_mode == DFD_CPLD_MODE_LPC) { + ret = dfd_ko_cpld_io_read(addr, buf); + } else { + DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, *buf, ret); + return ret; +} + +int32_t dfd_ko_cpld_write(int32_t addr, uint8_t val) +{ + int ret; + int sub_slot, cpld_id, cpld_mode; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + + ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode); + if (ret) { + DBG_DEBUG(DBG_ERROR, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default local_bus mode.\n", sub_slot, cpld_id); + cpld_mode = DFD_CPLD_MODE_I2C; + } + + if (cpld_mode == DFD_CPLD_MODE_I2C) { + ret = dfd_ko_cpld_i2c_write(addr, val); + } else if (cpld_mode == DFD_CPLD_MODE_LPC) { + ret = dfd_ko_cpld_io_write(addr, val); + } else { + DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, val, ret); + return ret; +} + +int32_t dfd_ko_i2c_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + + for (i = 0; i < size; i++) { + rv = dfd_ko_i2c_read_data(bus, addr, offset, &buf[i], sizeof(uint8_t)); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_read[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n", + bus, addr, offset, rv); + return rv; + } + offset++; + } + + return size; +} + +int32_t dfd_ko_i2c_write(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + + for (i = 0; i < size; i++) { + rv = dfd_ko_i2c_write_data(bus, addr, offset, buf[i], sizeof(uint8_t)); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_write[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n", + bus, addr, offset, rv); + return rv; + } + offset++; + } + + return size; + +} + +int32_t dfd_ko_read_file(char *fpath, int32_t addr, uint8_t *val, int32_t read_bytes) +{ + int32_t ret; + struct file *filp; + loff_t pos; + + if ((fpath == NULL) || (val == NULL) || (addr < 0) || (read_bytes < 0)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, addr=%d read_bytes=%d\n", addr, read_bytes); + return -DFD_RV_INDEX_INVALID; + } + + filp = filp_open(fpath, O_RDONLY, 0); + if (IS_ERR(filp)){ + DBG_DEBUG(DBG_ERROR, "open file[%s] fail\n", fpath); + return -DFD_RV_DEV_FAIL; + } + + pos = addr; + ret = kernel_read(filp, val, read_bytes, &pos); + if (ret < 0) { + DBG_DEBUG(DBG_ERROR, "kernel_read failed, path=%s, addr=%d, size=%d, ret=%d\n", fpath, addr, read_bytes, ret); + ret = -DFD_RV_DEV_FAIL; + } + + filp_close(filp, NULL); + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c new file mode 100644 index 000000000000..8d77759ba7e0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../include/dfd_cfg_file.h" +#include "../include/dfd_module.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +struct getdents_callback { + struct dir_context ctx; + const char *obj_name; + char *match_name; + int dir_len; + int found; +}; + +int kfile_open(char *fname, kfile_ctrl_t *kfile_ctrl) +{ + int ret; + struct file *filp; + loff_t pos; + + if ((fname == NULL) || (kfile_ctrl == NULL)) { + return KFILE_RV_INPUT_ERR; + } + + filp = filp_open(fname, O_RDONLY, 0); + if (IS_ERR(filp)){ + return KFILE_RV_OPEN_FAIL; + } + + kfile_ctrl->size = filp->f_inode->i_size; + + kfile_ctrl->buf = kmalloc(kfile_ctrl->size, GFP_KERNEL); + if (kfile_ctrl->buf == NULL) { + ret = KFILE_RV_MALLOC_FAIL; + goto close_fp; + } + mem_clear(kfile_ctrl->buf, kfile_ctrl->size); + + pos = 0; + ret = kernel_read(filp, kfile_ctrl->buf, kfile_ctrl->size, &pos); + if (ret < 0) { + ret = KFILE_RV_RD_FAIL; + goto free_buf; + } + + kfile_ctrl->pos = 0; + + ret = KFILE_RV_OK; + goto close_fp; + +free_buf: + kfree(kfile_ctrl->buf); + kfile_ctrl->buf = NULL; + +close_fp: + filp_close(filp, NULL); + return ret; +} + +void kfile_close(kfile_ctrl_t *kfile_ctrl) +{ + if (kfile_ctrl == NULL) { + return; + } + + kfile_ctrl->size = 0; + kfile_ctrl->pos = 0; + if (kfile_ctrl->buf) { + kfree(kfile_ctrl->buf); + kfile_ctrl->buf = NULL; + } +} + +int kfile_gets(char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl) +{ + int i; + int has_cr = 0; + + if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL) + || (kfile_ctrl->size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + mem_clear(buf, buf_size); + for (i = 0; i < buf_size; i++) { + + if (kfile_ctrl->pos >= kfile_ctrl->size) { + break; + } + + if (has_cr) { + break; + } + + if (IS_CR(kfile_ctrl->buf[kfile_ctrl->pos])) { + has_cr = 1; + } + + buf[i] = kfile_ctrl->buf[kfile_ctrl->pos]; + kfile_ctrl->pos++; + } + + return i; +} + +int kfile_read(int32_t addr, char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl) +{ + int i; + + if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL) + || (kfile_ctrl->size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + if ((addr < 0) || (addr >= kfile_ctrl->size)) { + return KFILE_RV_ADDR_ERR; + } + + mem_clear(buf, buf_size); + + kfile_ctrl->pos = addr; + for (i = 0; i < buf_size; i++) { + + if (kfile_ctrl->pos >= kfile_ctrl->size) { + break; + } + + buf[i] = kfile_ctrl->buf[kfile_ctrl->pos]; + kfile_ctrl->pos++; + } + + return i; +} + +static int kfile_filldir_one(struct dir_context *ctx, const char * name, int len, + loff_t pos, u64 ino, unsigned int d_type) +{ + struct getdents_callback *buf ; + int result; + buf = container_of(ctx, struct getdents_callback, ctx); + result = 0; + if (strncmp(buf->obj_name, name, strlen(buf->obj_name)) == 0) { + if (buf->dir_len < len) { + DBG_DEBUG(DBG_ERROR, "match ok. dir name:%s, but buf_len %d small than dir len %d.\n", + name, buf->dir_len, len); + buf->found = 0; + return -1; + } + mem_clear(buf->match_name, buf->dir_len); + memcpy(buf->match_name, name, len); + buf->found = 1; + result = -1; + } + return result; +} + +int kfile_iterate_dir(const char *dir_path, const char *obj_name, char *match_name, int len) +{ + int ret; + struct file *dir; + struct getdents_callback buffer = { + .ctx.actor = kfile_filldir_one, + }; + + if(!dir_path || !obj_name || !match_name) { + DBG_DEBUG(DBG_ERROR, "params error. \n"); + return KFILE_RV_INPUT_ERR; + } + buffer.obj_name = obj_name; + buffer.match_name = match_name; + buffer.dir_len = len; + buffer.found = 0; + + dir = filp_open(dir_path, O_RDONLY, 0); + if (IS_ERR(dir)) { + DBG_DEBUG(DBG_ERROR, "filp_open error, dir path:%s\n", dir_path); + return KFILE_RV_OPEN_FAIL; + } + ret = iterate_dir(dir, &buffer.ctx); + if (buffer.found) { + DBG_DEBUG(DBG_VERBOSE, "match ok, dir name:%s\n", match_name); + filp_close(dir, NULL); + return DFD_RV_OK; + } + filp_close(dir, NULL); + return -DFD_RV_NODE_FAIL; +} + +#if 0 + +int kfile_write(char *fpath, int32_t addr, char *buf, int buf_size) +{ + int ret = KFILE_RV_OK; + struct file *filp; + mm_segment_t old_fs; + int wlen; + + if ((fpath == NULL) || (buf == NULL) || (buf_size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + if (addr < 0) { + return KFILE_RV_ADDR_ERR; + } + + filp = filp_open(fpath, O_RDWR, 0); + if (IS_ERR(filp)){ + return KFILE_RV_OPEN_FAIL; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + filp->f_op->llseek(filp,0,0); + filp->f_pos = addr; + + wlen = filp->f_op->write(filp, buf, buf_size, &(filp->f_pos)); + if (wlen < 0) { + ret = KFILE_RV_WR_FAIL; + } + + filp->f_op->llseek(filp,0,0); + set_fs(old_fs); + filp_close(filp, NULL); + + return ret; +} +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c new file mode 100644 index 000000000000..5dae1539a116 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c @@ -0,0 +1,587 @@ +#include +#include +#include + +#include "../include/dfd_module.h" +#include "../include/dfd_cfg_adapter.h" +#include "../include/dfd_cfg.h" +#include "../include/dfd_cfg_info.h" +#include "../include/dfd_cfg_file.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +#define DFD_HWMON_NAME "hwmon" +#define DFD_GET_CPLD_VOLATGE_CODE_VALUE(value) ((value >> 4)& 0xfff) +#define DFD_GET_CPLD_VOLATGE_REAL_VALUE(code_val, k) ((code_val * 16 * 33 * k) / ((65536 - 5000) * 10)) + +char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END] = { + ".mode", + ".int_cons", + ".src", + ".frmt", + ".pola", + ".fpath", + ".addr", + ".len", + ".bit_offset", + ".str_cons", + ".int_extra1", + ".int_extra2", +}; + +char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END] = { + "none", + "config", + "constant", + "tlv", + "str_constant", +}; + +char *g_info_src_str[INFO_SRC_END] = { + "none", + "cpld", + "fpga", + "other_i2c", + "file", +}; + +char *g_info_frmt_str[INFO_FRMT_END] = { + "none", + "bit", + "byte", + "num_bytes", + "num_str", + "num_buf", + "buf", +}; + +char *g_info_pola_str[INFO_POLA_END] = { + "none", + "positive", + "negative", +}; + +static int dfd_read_info_from_cpld(int32_t addr, int read_bytes, uint8_t *val) +{ + int i, rv; + + for (i = 0; i < read_bytes; i++) { + rv = dfd_ko_cpld_read(addr, &(val[i])); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "read info[addr=0x%x read_bytes=%d] from cpld fail, reading_byte=%d rv=%d\n", + addr, read_bytes, i, rv); + return rv; + } + addr++; + } + + return read_bytes; +} + +static int dfd_write_info_to_cpld(int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask) +{ + int rv; + uint8_t val_tmp; + + if (bit_mask != 0xff) { + rv = dfd_ko_cpld_read(addr, &val_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "read original info[addr=0x%x] from cpld fail, rv=%d\n", addr, rv); + return -1; + } + + val_tmp = (val_tmp & (~bit_mask)) | (val[0] & bit_mask); + } else { + val_tmp = val[0]; + } + + rv = dfd_ko_cpld_write(addr, val_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "write info[addr=0x%x val=0x%x] to cpld fail, rv=%d\n", addr, val_tmp, rv); + return -1; + } + + return 0; +} + +static int dfd_read_info(info_src_t src, char *fpath, int32_t addr, int read_bytes, uint8_t *val) +{ + int rv = 0; + + switch (src) { + case INFO_SRC_CPLD: + rv = dfd_read_info_from_cpld(addr, read_bytes, val); + break; + case INFO_SRC_FPGA: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support read info from fpga\n"); + break; + case INFO_SRC_OTHER_I2C: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support read info from other i2c\n"); + break; + case INFO_SRC_FILE: + rv = dfd_ko_read_file(fpath, addr, val, read_bytes); + break; + default: + rv = -1; + DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src); + break; + } + + return rv; +} + +static int dfd_write_info(info_src_t src, char *fpath, int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask) +{ + int rv = 0; + + switch (src) { + case INFO_SRC_CPLD: + rv = dfd_write_info_to_cpld(addr, write_bytes, val, bit_mask); + break; + case INFO_SRC_FPGA: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to fpga\n"); + break; + case INFO_SRC_OTHER_I2C: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to other i2c\n"); + break; + case INFO_SRC_FILE: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to file\n"); + break; + default: + rv = -1; + DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src); + break; + } + + return rv; +} + +int dfd_info_get_int(int key, int *ret, info_num_buf_to_value_f pfun) +{ + int i, rv; + int read_bytes, readed_bytes, int_tmp; + uint8_t byte_tmp, val[INFO_INT_MAX_LEN + 1] = {0}; + info_ctrl_t *info_ctrl; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (ret == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08x\n", key); + return -DFD_RV_INDEX_INVALID; + } + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if (info_ctrl->mode == INFO_CTRL_MODE_CONS) { + *ret = info_ctrl->int_cons; + return DFD_RV_OK; + } else if (info_ctrl->mode == INFO_CTRL_MODE_TLV) { + return INFO_CTRL_MODE_TLV; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + + if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] bit_offsest[%d] invalid\n", + key, info_ctrl->bit_offset); + return -DFD_RV_TYPE_ERR; + } + + read_bytes = 1; + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt) || IS_INFO_FRMT_NUM_STR(info_ctrl->frmt) + || IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) { + + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + read_bytes = info_ctrl->len; + } else { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] info format[%d] error\n", key, info_ctrl->frmt); + return -DFD_RV_TYPE_ERR; + } + + readed_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, read_bytes, &(val[0])); + if (readed_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read int info[key=0x%08x src=%s frmt=%s fpath=%s addr=0x%x read_bytes=%d] fail, rv=%d\n", + key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, read_bytes, readed_bytes); + return -DFD_RV_DEV_FAIL; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + + if (info_ctrl->pola == INFO_POLA_NEGA) { + val[0] = ~val[0]; + } + + byte_tmp = (val[0] >> info_ctrl->bit_offset) & (~(0xff << info_ctrl->len)); + + if (pfun) { + rv = pfun(&byte_tmp, sizeof(byte_tmp), &int_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] bit process fail, rv=%d\n", key, rv); + return rv; + } + } else { + int_tmp = (int)byte_tmp; + } + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) { + + int_tmp = 0; + for (i = 0; i < info_ctrl->len; i++) { + if (info_ctrl->pola == INFO_POLA_NEGA) { + int_tmp |= val[info_ctrl->len - i - 1]; + } else { + int_tmp |= val[i]; + } + + if (i != (info_ctrl->len - 1)) { + int_tmp <<= 8; + } + } + } else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) { + + val[readed_bytes] = '\0'; + int_tmp = simple_strtol((char *)(&(val[0])), NULL, 10); + } else { + if (pfun == NULL) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] number buf process function is null\n", key); + return -DFD_RV_INDEX_INVALID; + } + + rv = pfun(val, readed_bytes, &int_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] number buf process fail, rv=%d\n", key, rv); + return rv; + } + } + + *ret = int_tmp; + DBG_DEBUG(DBG_VERBOSE, "read int info[key=0x%08x src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d] success, ret=%d\n", + key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola], + info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, *ret); + return DFD_RV_OK; +} + +int dfd_info_get_buf(int key, uint8_t *buf, int buf_len, info_buf_to_buf_f pfun) +{ + int rv; + int read_bytes, buf_real_len; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + info_ctrl_t *info_ctrl; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (buf == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08x\n", key); + return -DFD_RV_INDEX_INVALID; + } + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if (info_ctrl->mode != INFO_CTRL_MODE_CFG) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] mode[%d] invalid\n", key, info_ctrl->mode); + return -DFD_RV_TYPE_ERR; + } + + if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len) + || (buf_len <= info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] format=%d or len=%d invlaid, buf_len=%d\n", + key, info_ctrl->frmt, info_ctrl->len, buf_len); + return -DFD_RV_TYPE_ERR; + } + + read_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, buf_tmp); + if (read_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read buf info[key=0x%08x src=%s frmt=%s fpath=%s addr=0x%x len=%d] fail, rv=%d\n", + key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, info_ctrl->len, read_bytes); + return -DFD_RV_DEV_FAIL; + } + + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] buf process fail, rv=%d\n", key, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + } else { + buf_real_len = read_bytes; + memcpy(buf, buf_tmp, read_bytes); + } + + return buf_real_len; +} + +static int dfd_2key_info_get_buf(info_ctrl_t *info_ctrl, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun) +{ + int rv; + int read_bytes, buf_real_len; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + char temp_fpath[INFO_FPATH_MAX_LEN]; + + if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len) + || (buf_len <= info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "key_path info ctrl format=%d or len=%d invlaid, buf_len=%d\n", + info_ctrl->frmt, info_ctrl->len, buf_len); + return -DFD_RV_TYPE_ERR; + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + rv = kfile_iterate_dir(info_ctrl->fpath, DFD_HWMON_NAME, buf_tmp, INFO_BUF_MAX_LEN); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dir patch:%s ,can find name %s dir \n", + info_ctrl->fpath, DFD_HWMON_NAME); + return -DFD_RV_NO_NODE; + } + mem_clear(temp_fpath, sizeof(temp_fpath)); + snprintf(temp_fpath, sizeof(temp_fpath), "%s%s/%s", + info_ctrl->fpath, buf_tmp, info_ctrl->str_cons); + DBG_DEBUG(DBG_VERBOSE, "match ok path = %s \n", temp_fpath); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + + read_bytes = dfd_read_info(info_ctrl->src, temp_fpath, info_ctrl->addr, info_ctrl->len, buf_tmp); + if (read_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read buf info[src=%s frmt=%s fpath=%s addr=0x%x len=%d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_src_str[info_ctrl->frmt], temp_fpath, + info_ctrl->addr, info_ctrl->len, read_bytes); + return -DFD_RV_DEV_FAIL; + } + + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len, info_ctrl); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl buf process fail, rv=%d\n", rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + } else { + buf_real_len = read_bytes; + memcpy(buf, buf_tmp, buf_real_len); + } + return buf_real_len; +} + +int dfd_info_set_int(int key, int val) +{ + int rv; + int write_bytes; + uint8_t byte_tmp, bit_mask; + info_ctrl_t *info_ctrl; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key))) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08x\n", key); + return -DFD_RV_INDEX_INVALID; + } + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if (info_ctrl->mode != INFO_CTRL_MODE_CFG) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] mode[%d] warnning\n", key, info_ctrl->mode); + return -DFD_RV_TYPE_ERR; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + + if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] bit_offsest[%d] invalid\n", + key, info_ctrl->bit_offset); + return -DFD_RV_TYPE_ERR; + } + + write_bytes = 1; + + byte_tmp = (uint8_t)(val & 0xff); + byte_tmp <<= info_ctrl->bit_offset; + if (info_ctrl->pola == INFO_POLA_NEGA) { + byte_tmp = ~byte_tmp; + } + + bit_mask = (~(0xff << info_ctrl->len)) << info_ctrl->bit_offset; + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) { + + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + + write_bytes = 1; + + byte_tmp = (uint8_t)(val & 0xff); + + bit_mask = 0xff; + } else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) { + + DBG_DEBUG(DBG_ERROR, "not support str int set\n"); + return -1; + } else if (IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) { + + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + + write_bytes = 1; + + byte_tmp = (uint8_t)(val & 0xff); + + bit_mask = 0xff; + } else { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] format[%d] error\n", key, info_ctrl->frmt); + return -DFD_RV_TYPE_ERR; + } + + rv = dfd_write_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, write_bytes, + &byte_tmp, bit_mask); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "write int info[src=%s frmt=%s fpath=%s addr=0x%x len=%d val=%d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, info_ctrl->len, val, rv); + return -DFD_RV_DEV_FAIL; + } + + DBG_DEBUG(DBG_VERBOSE, "write int info[src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d val=%d] success\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola], + info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, val); + return DFD_RV_OK; +} + +static int dfd_info_get_cpld_voltage(int key, int *value) +{ + int rv, addr_tmp; + int vol_ref_tmp, vol_ref; + int vol_curr_tmp, vol_curr; + info_ctrl_t *info_ctrl; + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + rv = dfd_info_get_int(key, &vol_curr_tmp, NULL); + if(rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld current voltage error, addr:0x%x, rv =%d\n", info_ctrl->addr, rv); + return rv; + } + vol_curr_tmp = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_curr_tmp); + if(info_ctrl->addr == info_ctrl->int_extra1) { + + vol_curr = DFD_GET_CPLD_VOLATGE_REAL_VALUE(vol_curr_tmp, info_ctrl->int_extra2); + } else { + + addr_tmp = info_ctrl->addr; + info_ctrl->addr = info_ctrl->int_extra1; + rv = dfd_info_get_int(key, &vol_ref_tmp, NULL); + info_ctrl->addr = addr_tmp; + if(rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld reference voltage error, addr:0x%x rv:%d\n", info_ctrl->addr, rv); + return rv; + } + vol_ref = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_ref_tmp); + vol_curr = (vol_curr_tmp * info_ctrl->int_extra2) / vol_ref; + } + *value = vol_curr; + return DFD_RV_OK; +} + +static int dfd_info_get_sensor_value(int key, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun) +{ + int rv, buf_real_len; + int value; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + info_ctrl_t *info_ctrl; + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_ERROR, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if ( DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_IN && info_ctrl->src == INFO_SRC_CPLD) { + + rv = dfd_info_get_cpld_voltage(key, &value); + if(rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld voltage failed.key=0x%08x, rv:%d\n", key, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + DBG_DEBUG(DBG_VERBOSE, "get cpld voltage ok, value:%d\n", value); + mem_clear(buf_tmp, sizeof(buf_tmp)); + snprintf(buf_tmp, sizeof(buf_tmp), "%d\n", value); + buf_real_len = strlen(buf_tmp); + if(buf_len <= buf_real_len) { + DBG_DEBUG(DBG_ERROR, "length not enough.buf_len:%d,need length:%d\n", buf_len, buf_real_len); + return -DFD_RV_DEV_FAIL; + } + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, strlen(buf_tmp), buf, &buf_real_len, info_ctrl); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "deal date error.org value:%s, buf_len:%d, rv=%d\n", + buf_tmp, buf_len, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + } else { + memcpy(buf, buf_tmp, buf_real_len); + } + return buf_real_len; + } + + DBG_DEBUG(DBG_ERROR, "not support mode. key:0x%08x\n", key); + return -DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_info_get_sensor(uint32_t key, char *buf, int buf_len, info_hwmon_buf_f pfun) +{ + info_ctrl_t *key_info_ctrl; + int rv; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || + (buf == NULL) || buf_len <= 0) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key_path=0x%08x, buf_len:%d.\n", + key, buf_len); + return -DFD_RV_INVALID_VALUE; + } + + key_info_ctrl = dfd_ko_cfg_get_item(key); + if (key_info_ctrl == NULL) { + DBG_DEBUG(DBG_ERROR, "key_path info error, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(buf, buf_len); + + if (key_info_ctrl->mode == INFO_CTRL_MODE_SRT_CONS) { + snprintf(buf, buf_len, "%s\n", key_info_ctrl->str_cons); + DBG_DEBUG(DBG_VERBOSE, "get sensor value through string config, key=0x%08x, value:%s\n", key, buf); + return strlen(buf); + } + + if (key_info_ctrl->mode == INFO_CTRL_MODE_CFG && key_info_ctrl->src == INFO_SRC_FILE) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon, key:0x%08x\n", key); + rv = dfd_2key_info_get_buf(key_info_ctrl, buf, buf_len, pfun); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon failed, key:0x%08x, rv:%d\n", key, rv); + } + return rv; + } + rv = dfd_info_get_sensor_value(key, buf, buf_len, pfun); + if( rv < 0) { + DBG_DEBUG(DBG_ERROR, "get sensor value failed, key=0x%08x, rv:%d.\n", key, rv); + } + return rv; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c new file mode 100644 index 000000000000..d6fd7e104c9f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c @@ -0,0 +1,82 @@ +#include +#include + +#include "../include/dfd_cfg_listnode.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +void *lnode_find_node(lnode_root_t *root, int key) +{ + lnode_node_t *lnode; + + if (root == NULL){ + return NULL; + } + + list_for_each_entry(lnode, &(root->root), lst) { + if (lnode->key == key) { + return lnode->data; + } + } + + return NULL; +} + +int lnode_insert_node(lnode_root_t *root, int key, void *data) +{ + lnode_node_t *lnode; + void *data_tmp; + + if ((root == NULL) || (data == NULL)) { + return LNODE_RV_INPUT_ERR; + } + + data_tmp = lnode_find_node(root, key); + if (data_tmp != NULL) { + return LNODE_RV_NODE_EXIST; + } + + lnode = kmalloc(sizeof(lnode_node_t), GFP_KERNEL); + if (lnode == NULL) { + return LNODE_RV_NOMEM; + } + + lnode->key = key; + lnode->data = data; + list_add_tail(&(lnode->lst), &(root->root)); + + return LNODE_RV_OK; +} + +int lnode_init_root(lnode_root_t *root) +{ + if (root == NULL) { + return LNODE_RV_INPUT_ERR; + } + + INIT_LIST_HEAD(&(root->root)); + + return LNODE_RV_OK; +} + +void lnode_free_list(lnode_root_t *root) +{ + lnode_node_t *lnode, *lnode_next; + + if (root == NULL){ + return ; + } + + list_for_each_entry_safe(lnode, lnode_next, &(root->root), lst) { + if ( lnode->data ) { + kfree(lnode->data); + lnode->data = NULL; + lnode->key = 0; + } + list_del(&lnode->lst); + kfree(lnode); + lnode = NULL; + } + + return ; + +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c new file mode 100644 index 000000000000..efc322046c07 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c @@ -0,0 +1,170 @@ +#include +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_adapter.h" +#include "./include/dfd_cfg_info.h" +#include "../dev_sysfs/include/sysfs_common.h" + +#define FAN_SIZE (256) + +int g_dfd_fan_dbg_level = 0; +module_param(g_dfd_fan_dbg_level, int, S_IRUGO | S_IWUSR); + +int dfd_get_fan_roll_status(unsigned int fan_index, unsigned int motor_index) +{ + int key, ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_ROLL_STATUS, fan_index, motor_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan roll status error, fan:%d,motor:%d\n", + fan_index, motor_index); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan%u motor%u get fan roll status success, status:%d.\n", + fan_index, motor_index, status); + return status; +} + +int dfd_get_fan_present_status(unsigned int fan_index) +{ + int key, ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_PRESENT_STATUS, WB_MAIN_DEV_FAN, fan_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan%u get present status error, key:0x%x\n", fan_index, key); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan%u get present status success, status:%d.\n", fan_index, status); + return status; +} + +ssize_t dfd_get_fan_speed(unsigned int fan_index, unsigned int motor_index,unsigned int *speed) +{ + int key, ret, speed_tmp; + + if (speed == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SPEED, fan_index, motor_index); + ret = dfd_info_get_int(key, &speed_tmp, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan speed error, key:0x%x,ret:%d\n",key, ret); + return ret; + } + + if (speed_tmp == 0 || speed_tmp == 0xffff) { + *speed = 0; + } else { + *speed = 15000000 / speed_tmp; + } + return DFD_RV_OK; +} + +int dfd_set_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int level) +{ + int key, ret; + + if (level < 0 || level > 0xff) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, can not set fan speed level: %d.\n", + fan_index, motor_index, level); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, motor_index); + ret = dfd_info_set_int(key, level); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, set fan level 0x%02x error, key:0x%x,ret:%d\n", + fan_index, motor_index, level, key, ret); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, set fan speed level 0x%02x success.\n", + fan_index, motor_index, level); + return DFD_RV_OK; +} + +int dfd_set_fan_pwm(unsigned int fan_index, unsigned int motor_index, int pwm) +{ + int ret, data; + + if (pwm < 0 || pwm > 100) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, can't set pwm: %d.\n", + fan_index, motor_index, pwm); + return -DFD_RV_INVALID_VALUE; + } + + data = pwm * 255 / 100; + ret = dfd_set_fan_speed_level(fan_index, motor_index, data); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, set fan ratio:%d error, ret:%d\n", + fan_index, motor_index, data, ret); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, set fan ratio %d success.\n", + fan_index, motor_index, data); + return DFD_RV_OK; +} + +int dfd_get_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int *level) +{ + int key, ret, speed_level; + + if (level == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, motor_index); + ret = dfd_info_get_int(key, &speed_level, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, get fan speed level error, key:0x%x,ret:%d\n", + fan_index, motor_index, key, ret); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, get fan speed level success, value:0x%02x.\n", + fan_index, motor_index, speed_level); + *level = speed_level; + return DFD_RV_OK; +} + +int dfd_get_fan_pwm(unsigned int fan_index, unsigned int motor_index, int *pwm) +{ + int ret, level; + + if (pwm == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + ret = dfd_get_fan_speed_level(fan_index, motor_index, &level); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, get fan pwm error, ret:%d\n", + fan_index, motor_index, ret); + return ret; + } + + if ((level * 100) % 255 > 0) { + *pwm = level * 100 / 255 + 1; + } else { + *pwm = level * 100 / 255; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, get fan pwm success, value:%d.\n", + fan_index, motor_index, *pwm); + return DFD_RV_OK; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_module.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_module.c new file mode 100644 index 000000000000..9e5b00b795de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_module.c @@ -0,0 +1,95 @@ +#include + +#include "../dev_sysfs/include/sysfs_common.h" +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_fan_driver.h" +#include "./include/dfd_slot_driver.h" +#include "./include/dfd_sensors_driver.h" +#include "./include/dfd_psu_driver.h" +#include "./include/dfd_sff_driver.h" + +typedef enum dfd_dev_init_fail_s { + DFD_KO_INIT_CPLD_FAIL = 1, + DFD_KO_INIT_FPGA_FAIL = 2, + DFD_KO_INIT_IRQ_FAIL = 3, + DFD_KO_INIT_CFG_FAIL = 4, + DFD_KO_INIT_DATA_FAIL = 5, +} dfd_dev_init_fail_t; + +int g_dfd_dbg_level = 0; + +int dfd_get_dev_number(unsigned int main_dev_id, unsigned int minor_dev_id) +{ + int key,dev_num; + int *p_dev_num; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_NUM, main_dev_id, minor_dev_id); + p_dev_num = dfd_ko_cfg_get_item(key); + if (p_dev_num == NULL) { + DBG_DEBUG(DBG_ERROR, "get device number failed, key:0x%x\n",key); + return -DFD_RV_DEV_NOTSUPPORT; + } + dev_num = *p_dev_num; + DBG_DEBUG(DBG_VERBOSE, "get device number ok, number:%d\n",dev_num); + return dev_num; +} + +static struct switch_drivers_t switch_drivers= { + .get_dev_number = dfd_get_dev_number, + /* fan */ + .get_fan_speed = dfd_get_fan_speed, + .get_fan_pwm = dfd_get_fan_pwm, + .set_fan_pwm = dfd_set_fan_pwm, + .get_fan_present_status = dfd_get_fan_present_status, + .get_fan_roll_status = dfd_get_fan_roll_status, + .get_fan_speed_level = dfd_get_fan_speed_level, + .set_fan_speed_level = dfd_set_fan_speed_level, + /* slot */ + .get_slot_present_status = dfd_get_slot_present_status, + /* sensors */ + .get_temp_info = dfd_get_temp_info, + .get_voltage_info = dfd_get_voltage_info, + /* psu */ + .get_psu_present_status = dfd_get_psu_present_status, + .get_psu_output_status = dfd_get_psu_output_status, + .get_psu_alert_status = dfd_get_psu_alert_status, + /* sff */ + .get_sff_cpld_info = dfd_get_sff_cpld_info, + .get_sff_dir_name = dfd_get_sff_dir_name, +}; + +struct switch_drivers_t * dfd_plat_driver_get(void) { + return &switch_drivers; +} + +static int32_t __init dfd_dev_init(void) +{ + int ret; + + DBG_DEBUG(DBG_VERBOSE, "Enter.\n"); + + ret = dfd_dev_cfg_init(); + if (ret != 0) { + DBG_DEBUG(DBG_ERROR, "dfd_dev_cfg_init failed ret %d.\n", ret); + ret = -DFD_KO_INIT_CFG_FAIL; + return ret; + } + + DBG_DEBUG(DBG_VERBOSE, "success.\n"); + return 0; +} + +static void __exit dfd_dev_exit(void) +{ + DBG_DEBUG(DBG_VERBOSE, "dfd_dev_exit.\n"); + dfd_dev_cfg_exit(); + return ; +} + +module_init(dfd_dev_init); +module_exit(dfd_dev_exit); +module_param(g_dfd_dbg_level, int, S_IRUGO | S_IWUSR); +EXPORT_SYMBOL(dfd_plat_driver_get); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c new file mode 100644 index 000000000000..55e2e4339ae7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c @@ -0,0 +1,70 @@ +#include +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_adapter.h" +#include "./include/dfd_cfg_info.h" +#include "../dev_sysfs/include/sysfs_common.h" + +#define PSU_SIZE (256) + +typedef enum dfd_psu_status_e { + DFD_PSU_PRESENT_STATUS = 0, + DFD_PSU_OUTPUT_STATUS = 1, + DFD_PSU_ALERT_STATUS = 2, +} dfd_psu_status_t; + +int g_dfd_psu_dbg_level = 0; +module_param(g_dfd_psu_dbg_level, int, S_IRUGO | S_IWUSR); + +int dfd_get_psu_present_status(unsigned int psu_index) +{ + int ret, present_key, present_status; + + present_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_PRESENT_STATUS); + ret = dfd_info_get_int(present_key, &present_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "dfd_get_psu_present_status error. psu_index:%d, ret:%d\n", + psu_index, ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "dfd_get_psu_present_status success. psu_index:%d, status:%d\n", + psu_index, present_status); + return present_status; +} + +int dfd_get_psu_output_status(unsigned int psu_index) +{ + int ret, output_key, output_status; + + output_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_OUTPUT_STATUS); + ret = dfd_info_get_int(output_key, &output_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "dfd_get_psu_output_status error. psu_index:%d, ret:%d\n", + psu_index, ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "dfd_get_psu_output_status success. psu_index:%d, status:%d\n", + psu_index, output_status); + return output_status; +} + +int dfd_get_psu_alert_status(unsigned int psu_index) +{ + int ret, alert_key, alert_status; + + alert_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_ALERT_STATUS); + ret = dfd_info_get_int(alert_key, &alert_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "dfd_get_psu_alert_status error. psu_index:%d, ret:%d\n", + psu_index, ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "dfd_get_psu_alert_status success. psu_index:%d, status:%d\n", + psu_index, alert_status); + return alert_status; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c new file mode 100644 index 000000000000..bfca20290efb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c @@ -0,0 +1,149 @@ +#include +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_adapter.h" +#include "./include/dfd_cfg_info.h" +#include "./include/dfd_cfg_file.h" +#include "../dev_sysfs/include/sysfs_common.h" + +#define DFD_GET_TEMP_SENSOR_KEY1(dev_index, temp_index) \ + (((dev_index & 0xff) << 8) | (temp_index & 0xff)) +#define DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, temp_type) \ + (((main_dev_id & 0x0f) << 4) | (temp_type & 0x0f)) +#define DFD_FORMAT_STR_MAX_LEN (32) + +int g_dfd_sensor_dbg_level = 0; +module_param(g_dfd_sensor_dbg_level, int, S_IRUGO | S_IWUSR); + +static int dfd_deal_hwmon_buf(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, info_ctrl_t *info_ctrl) +{ + int i, tmp_len; + int exp, decimal, divisor; + int org_value, tmp_value; + int div_result, div_mod; + char fmt_str[DFD_FORMAT_STR_MAX_LEN]; + + exp = info_ctrl->int_cons; + decimal = info_ctrl->bit_offset; + + if (exp <= 0) { + DBG_DEBUG(DBG_VERBOSE, "exponent %d, don't need transform. buf_len:%d, buf_len_new:%d\n", + exp, buf_len, *buf_len_new); + snprintf(buf_new, *buf_len_new, "%s", buf); + *buf_len_new = strlen(buf_new); + return DFD_RV_OK; + } + divisor = 1; + for (i = 0; i < exp; i++) { + divisor *= 10; + } + org_value = simple_strtol(buf, NULL, 10); + if (org_value < 0) { + tmp_value = 0 - org_value; + } else { + tmp_value = org_value; + } + div_result = tmp_value / divisor; + div_mod = tmp_value % divisor; + DBG_DEBUG(DBG_VERBOSE, "exp:%d, decimal:%d, original value:%d, divisor:%d, result :%d, mod:%d\n", + exp, decimal, org_value, divisor, div_result, div_mod); + + mem_clear(fmt_str, sizeof(fmt_str)); + if (org_value < 0) { + snprintf(fmt_str, sizeof(fmt_str), "-%%d.%%0%dd\n",exp); + } else { + snprintf(fmt_str, sizeof(fmt_str), "%%d.%%0%dd\n",exp); + } + DBG_DEBUG(DBG_VERBOSE, "format string:%s",fmt_str); + snprintf(buf_new, *buf_len_new, fmt_str, div_result, div_mod); + *buf_len_new = strlen(buf_new); + tmp_len = *buf_len_new; + + if ( decimal > 0) { + for(i = 0; i < *buf_len_new; i++) { + if (buf_new[i] == '.') { + if( i + decimal + 2 <= *buf_len_new ) { + buf_new[i + decimal + 1 ] = '\n'; + buf_new[i + decimal + 2 ] = '\0'; + *buf_len_new = strlen(buf_new); + DBG_DEBUG(DBG_VERBOSE, "deal decimal[%d] ok, str len:%d, value:%s\n", + decimal, *buf_len_new, buf_new); + } + break; + } + } + if (tmp_len == *buf_len_new) { + DBG_DEBUG(DBG_WARN, "deal decimal[%d] failed, use original value:%s\n", decimal, buf_new); + } + } + return DFD_RV_OK; +} + +static int dfd_get_sensor_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t sensor_type, + uint8_t sensor_index, uint8_t sensor_attr, char *buf) +{ + uint32_t key; + uint16_t key_index1; + uint8_t key_index2; + int rv; + info_hwmon_buf_f pfunc; + + key_index1 = DFD_GET_TEMP_SENSOR_KEY1(dev_index, sensor_index); + key_index2 = DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, sensor_attr); + if (sensor_type == WB_MINOR_DEV_TEMP ) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_TEMP, key_index1, key_index2); + } else if (sensor_type == WB_MINOR_DEV_IN) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_IN, key_index1, key_index2); + } else { + DFD_SENSOR_DEBUG(DBG_ERROR, "unknow sensor type:%d.\n",sensor_type); + return -DFD_RV_INVALID_VALUE; + } + + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get sensor info.main_dev_id:%d, dev_index:0x%x, sensor_index:0x%x, sensor_attr:0x%x, key:0x%x,\n", + main_dev_id, dev_index, sensor_index, sensor_attr, key); + + pfunc = dfd_deal_hwmon_buf; + mem_clear(buf, PAGE_SIZE); + rv = dfd_info_get_sensor(key, buf, PAGE_SIZE, pfunc); + return rv; +} + +ssize_t dfd_get_temp_info(uint8_t main_dev_id, uint8_t dev_index, + uint8_t temp_index, uint8_t temp_attr, char *buf) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error. buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_TEMP, temp_index, temp_attr, buf); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get temp info error. rv:%d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get temp info ok.value:%s\n", buf); + } + return rv; +} + +ssize_t dfd_get_voltage_info(uint8_t main_dev_id, uint8_t dev_index, + uint8_t in_index, uint8_t in_attr, char *buf) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error. buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_IN, in_index, in_attr, buf); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get voltage info error. rv:%d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get voltage info ok.value:%s\n", buf); + } + return rv; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c new file mode 100644 index 000000000000..5c1faff975b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c @@ -0,0 +1,56 @@ +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_info.h" +#include "./include/dfd_cfg_adapter.h" +#include "../dev_sysfs/include/sysfs_common.h" + +int g_dfd_sff_dbg_level = 0; +module_param(g_dfd_sff_dbg_level, int, S_IRUGO | S_IWUSR); + +ssize_t dfd_get_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, char *buf, int len) +{ + int key, ret, value; + + if(buf == NULL) { + DFD_SFF_DEBUG(DBG_ERROR, "param error, buf is NULL. sff_index:%d, cpld_reg_type:%d.\n", + sff_index, cpld_reg_type); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_CPLD_REG, sff_index, cpld_reg_type); + ret = dfd_info_get_int(key, &value, NULL); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "get sff cpld reg error, key:0x%x,ret:%d.\n", key, ret); + return ret; + } + + mem_clear(buf, len); + return (ssize_t)snprintf(buf, len, "%d\n", value); +} + +ssize_t dfd_get_sff_dir_name(unsigned int sff_index, char *buf, int buf_len) +{ + int key; + char *sff_dir_name; + + if (buf == NULL) { + DFD_SFF_DEBUG(DBG_ERROR, "param error. buf is NULL.sff index:%d", sff_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, buf_len); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_DIR_NAME, sff_index, 0); + sff_dir_name = dfd_ko_cfg_get_item(key); + if (sff_dir_name == NULL) { + DFD_SFF_DEBUG(DBG_ERROR, "sff dir name config error, key=0x%08x\n", key); + return -DFD_RV_NODE_FAIL; + } + + DFD_SFF_DEBUG(DBG_VERBOSE, "%s\n", sff_dir_name); + snprintf(buf, buf_len, "%s", sff_dir_name); + return strlen(buf); + +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c new file mode 100644 index 000000000000..69c82adabef0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c @@ -0,0 +1,27 @@ +#include +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_adapter.h" +#include "./include/dfd_cfg_info.h" +#include "../dev_sysfs/include/sysfs_common.h" + +#define SLOT_SIZE (256) + +int g_dfd_slot_dbg_level = 0; +module_param(g_dfd_slot_dbg_level, int, S_IRUGO | S_IWUSR); + +int dfd_get_slot_present_status(unsigned int slot_index) +{ + int key, ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_PRESENT_STATUS, WB_MAIN_DEV_SLOT, slot_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "get slot status error, key:0x%x\n",key); + return ret; + } + return status; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h new file mode 100644 index 000000000000..062654d01504 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h @@ -0,0 +1,97 @@ +#ifndef __DFD_CFG_H__ +#define __DFD_CFG_H__ + +#include + +#define DFD_KO_CFG_FILE_NAME "/etc/plat_sysfs_cfg/cfg_file_name" +#define DFD_KO_CFG_FILE_DIR "/etc/plat_sysfs_cfg/" +#define DFD_PUB_CARDTYPE_FILE "/sys/module/platform_common/parameters/dfd_my_type" + +#define DFD_CFG_CMDLINE_MAX_LEN (256) +#define DFD_CFG_NAME_MAX_LEN (256) +#define DFD_CFG_VALUE_MAX_LEN (256) +#define DFD_CFG_STR_MAX_LEN (64) +#define DFD_CFG_CPLD_NUM_MAX (16) +#define DFD_PRODUCT_ID_LENGTH (8) +#define DFD_PID_BUF_LEN (32) +#define DFD_TEMP_NAME_BUF_LEN (32) + +#define DFD_CFG_EMPTY_VALUE (-1) +#define DFD_CFG_INVALID_VALUE (0) + +#define DFD_CFG_KEY(item, index1, index2) \ + ((((item) & 0xff) << 24) | (((index1) & 0xffff) << 8) | ((index2) & 0xff)) +#define DFD_CFG_ITEM_ID(key) (((key) >> 24) & 0xff) +#define DFD_CFG_INDEX1(key) (((key) >> 8) & 0xffff) +#define DFD_CFG_INDEX2(key) ((key)& 0xff) + +#define INDEX_NOT_EXIST (-1) +#define INDEX1_MAX (0xffff) +#define INDEX2_MAX (0xff) + +#define DFD_CFG_ITEM_ALL \ + DFD_CFG_ITEM(DFD_CFG_ITEM_NONE, "none", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DEV_NUM, "dev_num", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_LPC_DEV, "cpld_lpc_dev", INDEX1_MAX, DFD_CFG_CPLD_NUM_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_INT_END, "end_int", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_MODE, "mode_cpld", INDEX1_MAX, DFD_CFG_CPLD_NUM_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SFF_DIR_NAME, "sff_dir_name", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_STRING_END, "end_string", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_I2C_DEV, "cpld_i2c_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_OTHER_I2C_DEV, "other_i2c_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_I2C_DEV_END, "end_i2c_dev", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_ROLL_STATUS, "fan_roll_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_SPEED, "fan_speed", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_RATIO, "fan_ratio", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DEV_PRESENT_STATUS, "dev_present_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_STATUS, "psu_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_TEMP, "hwmon_temp", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_IN, "hwmon_in", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SFF_CPLD_REG, "sff_cpld_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_INFO_CTRL_END, "end_info_ctrl", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) _id, +typedef enum dfd_cfg_item_id_s { + DFD_CFG_ITEM_ALL +} dfd_cfg_item_id_t; + +#define DFD_CFG_ITEM_IS_INT(item_id) \ + (((item_id) > DFD_CFG_ITEM_NONE) && ((item_id) < DFD_CFG_ITEM_INT_END)) + +#define DFD_CFG_ITEM_IS_STRING(item_id) \ + (((item_id) > DFD_CFG_ITEM_INT_END) && ((item_id) < DFD_CFG_ITEM_STRING_END)) + +#define DFD_CFG_ITEM_IS_I2C_DEV(item_id) \ + (((item_id) > DFD_CFG_ITEM_STRING_END) && ((item_id) < DFD_CFG_ITEM_I2C_DEV_END)) + +#define DFD_CFG_ITEM_IS_INFO_CTRL(item_id) \ + (((item_id) > DFD_CFG_ITEM_I2C_DEV_END) && ((item_id) < DFD_CFG_ITEM_INFO_CTRL_END)) + +typedef struct index_range_s { + int index1_max; + int index2_max; +} index_range_t; + +typedef struct val_convert_node_s { + struct list_head lst; + int int_val; + char str_val[DFD_CFG_STR_MAX_LEN]; + int index1; + int index2; +} val_convert_node_t; + +void *dfd_ko_cfg_get_item(int key); + +void dfd_ko_cfg_show_item(int key); + +int32_t dfd_dev_cfg_init(void); + +void dfd_dev_cfg_exit(void); + +#endif /* __DFD_CFG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h new file mode 100644 index 000000000000..70d8b536c437 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h @@ -0,0 +1,46 @@ +#ifndef __DFD_CFG_ADAPTER_H__ +#define __DFD_CFG_ADAPTER_H__ + +#define DFD_KO_CPLD_I2C_RETRY_SLEEP (10) /* ms */ +#define DFD_KO_CPLD_I2C_RETRY_TIMES (50 / DFD_KO_CPLD_I2C_RETRY_SLEEP) + +#define DFD_KO_CPLD_GET_SLOT(addr) ((addr >> 24) & 0xff) +#define DFD_KO_CPLD_GET_ID(addr) ((addr >> 16) & 0xff) +#define DFD_KO_CPLD_GET_INDEX(addr) (addr & 0xffff) +#define DFD_KO_CPLD_MODE_I2C_STRING "i2c" +#define DFD_KO_CPLD_MODE_LPC_STRING "lpc" + +typedef struct dfd_i2c_dev_s { + int bus; + int addr; +} dfd_i2c_dev_t; + +typedef enum dfd_i2c_dev_mem_s { + DFD_I2C_DEV_MEM_BUS, + DFD_I2C_DEV_MEM_ADDR, + DFD_I2C_DEV_MEM_END +} dfd_i2c_dev_mem_t; + +typedef enum cpld_mode_e { + DFD_CPLD_MODE_I2C, + DFD_CPLD_MODE_LPC, +} cpld_mode_t; + +typedef enum i2c_mode_e { + DFD_I2C_MODE_NORMAL_I2C, + DFD_I2C_MODE_SMBUS, +} i2c_mode_t; + +extern char *g_dfd_i2c_dev_mem_str[DFD_I2C_DEV_MEM_END]; + +int32_t dfd_ko_cpld_read(int32_t addr, uint8_t *buf); + +int32_t dfd_ko_cpld_write(int32_t addr, uint8_t val); + +int32_t dfd_ko_i2c_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size); + +int32_t dfd_ko_i2c_write(int bus, int addr, int offset, uint8_t *buf, uint32_t size); + +int32_t dfd_ko_read_file(char *fpath, int32_t addr, uint8_t *val, int32_t read_bytes); + +#endif /* __DFD_CFG_ADAPTER_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h new file mode 100644 index 000000000000..50d7a42d5564 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h @@ -0,0 +1,37 @@ +#ifndef __DFD_CFG_FILE_H__ +#define __DFD_CFG_FILE_H__ + +#include + +#define KFILE_RV_OK (0) +#define KFILE_RV_INPUT_ERR (-1) +#define KFILE_RV_STAT_FAIL (-2) +#define KFILE_RV_OPEN_FAIL (-3) +#define KFILE_RV_MALLOC_FAIL (-4) +#define KFILE_RV_RD_FAIL (-5) +#define KFILE_RV_ADDR_ERR (-6) +#define KFILE_RV_WR_FAIL (-7) + +#define IS_CR(c) ((c) == '\n') + +typedef struct kfile_ctrl_s { + int32_t size; + int32_t pos; + char *buf; +} kfile_ctrl_t; + +int kfile_open(char *fname, kfile_ctrl_t *kfile_ctrl); + +void kfile_close(kfile_ctrl_t *kfile_ctrl); + +int kfile_gets(char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl); + +int kfile_read(int32_t addr, char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl); + +int kfile_iterate_dir(const char *dir_path, const char *obj_name, char *match_name, int len); + +#if 0 + +int kfile_write(char *fpath, int32_t addr, char *buf, int buf_size); +#endif +#endif /* __DFD_CFG_FILE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h new file mode 100644 index 000000000000..dc1ed17651b9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h @@ -0,0 +1,109 @@ +#ifndef __DFD_CFG_INFO_H__ +#define __DFD_CFG_INFO_H__ + +#include + +typedef int (*info_num_buf_to_value_f)(uint8_t *num_buf, int buf_len, int *num_val); + +typedef int (*info_buf_to_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new); + +#define IS_INFO_FRMT_BIT(frmt) ((frmt) == INFO_FRMT_BIT) +#define IS_INFO_FRMT_BYTE(frmt) (((frmt) == INFO_FRMT_BYTE) || ((frmt) == INFO_FRMT_NUM_BYTES)) +#define IS_INFO_FRMT_NUM_STR(frmt) ((frmt) == INFO_FRMT_NUM_STR) +#define IS_INFO_FRMT_NUM_BUF(frmt) ((frmt) == INFO_FRMT_NUM_BUF) +#define IS_INFO_FRMT_BUF(frmt) ((frmt) == INFO_FRMT_BUF) + +#define INFO_INT_MAX_LEN (32) +#define INFO_INT_LEN_VALAID(len) (((len) > 0) && ((len) < INFO_INT_MAX_LEN)) + +#define INFO_BUF_MAX_LEN (128) +#define INFO_BUF_LEN_VALAID(len) (((len) > 0) && ((len) < INFO_BUF_MAX_LEN)) + +#define INFO_BIT_OFFSET_VALID(bit_offset) (((bit_offset) >= 0) && ((bit_offset) < 8)) + +typedef enum info_ctrl_mode_e { + INFO_CTRL_MODE_NONE, + INFO_CTRL_MODE_CFG, + INFO_CTRL_MODE_CONS, + INFO_CTRL_MODE_TLV, + INFO_CTRL_MODE_SRT_CONS, + INFO_CTRL_MODE_END +} info_ctrl_mode_t; + +typedef enum info_frmt_e { + INFO_FRMT_NONE, + INFO_FRMT_BIT, + INFO_FRMT_BYTE, + INFO_FRMT_NUM_BYTES, + INFO_FRMT_NUM_STR, + INFO_FRMT_NUM_BUF, + INFO_FRMT_BUF, + INFO_FRMT_END +} info_frmt_t; + +typedef enum info_src_e { + INFO_SRC_NONE, + INFO_SRC_CPLD, + INFO_SRC_FPGA, + INFO_SRC_OTHER_I2C, + INFO_SRC_FILE, + INFO_SRC_END +} info_src_t; + +typedef enum info_pola_e { + INFO_POLA_NONE, + INFO_POLA_POSI, + INFO_POLA_NEGA, + INFO_POLA_END +} info_pola_t; + +#define INFO_FPATH_MAX_LEN (128) +#define INFO_STR_CONS_MAX_LEN (64) +typedef struct info_ctrl_s { + info_ctrl_mode_t mode; + int32_t int_cons; + info_src_t src; + info_frmt_t frmt; + info_pola_t pola; + char fpath[INFO_FPATH_MAX_LEN]; + int32_t addr; + int32_t len; + int32_t bit_offset; + char str_cons[INFO_STR_CONS_MAX_LEN]; + int32_t int_extra1; + int32_t int_extra2; +} info_ctrl_t; + +typedef enum info_ctrl_mem_s { + INFO_CTRL_MEM_MODE, + INFO_CTRL_MEM_INT_CONS, + INFO_CTRL_MEM_SRC, + INFO_CTRL_MEM_FRMT, + INFO_CTRL_MEM_POLA, + INFO_CTRL_MEM_FPATH, + INFO_CTRL_MEM_ADDR, + INFO_CTRL_MEM_LEN, + INFO_CTRL_MEM_BIT_OFFSET, + INFO_CTRL_MEM_STR_CONS, + INFO_CTRL_MEM_INT_EXTRA1, + INFO_CTRL_MEM_INT_EXTRA2, + INFO_CTRL_MEM_END +} info_ctrl_mem_t; + +typedef int (*info_hwmon_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, info_ctrl_t *info_ctrl); + +extern char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END]; +extern char *g_info_src_str[INFO_SRC_END]; +extern char *g_info_frmt_str[INFO_FRMT_END]; +extern char *g_info_pola_str[INFO_POLA_END]; +extern char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END]; + +int dfd_info_get_int(int key, int *ret, info_num_buf_to_value_f pfun); + +int dfd_info_get_buf(int key, uint8_t *buf, int buf_len, info_buf_to_buf_f pfun); + +int dfd_info_set_int(int key, int val); + +int dfd_info_get_sensor(uint32_t key, char *buf, int buf_len, info_hwmon_buf_f pfun); + +#endif /* __DFD_CFG_INFO_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h new file mode 100644 index 000000000000..955dfa96e42e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h @@ -0,0 +1,30 @@ +#ifndef __DFD_CFG_LISTNODE_H__ +#define __DFD_CFG_LISTNODE_H__ + +#include + +#define LNODE_RV_OK (0) +#define LNODE_RV_INPUT_ERR (-1) +#define LNODE_RV_NODE_EXIST (-2) +#define LNODE_RV_NOMEM (-3) + +typedef struct lnode_root_s { + struct list_head root; +} lnode_root_t; + +typedef struct lnode_node_s { + struct list_head lst; + + int key; + void *data; +} lnode_node_t; + +void *lnode_find_node(lnode_root_t *root, int key); + +int lnode_insert_node(lnode_root_t *root, int key, void *data); + +int lnode_init_root(lnode_root_t *root); + +void lnode_free_list(lnode_root_t *root); + +#endif /* __DFD_CFG_LISTNODE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h new file mode 100644 index 000000000000..1065fd9eed3f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h @@ -0,0 +1,18 @@ +#ifndef _DFD_FAN_DRIVER_H_ +#define _DFD_FAN_DRIVER_H_ + +ssize_t dfd_get_fan_speed(unsigned int fan_index, unsigned int motor_index,unsigned int *speed); + +int dfd_set_fan_pwm(unsigned int fan_index, unsigned int motor_index, int pwm); + +int dfd_get_fan_pwm(unsigned int fan_index, unsigned int motor_index, int *pwm); + +int dfd_get_fan_present_status(unsigned int fan_index); + +int dfd_get_fan_roll_status(unsigned int fan_index, unsigned int motor_index); + +int dfd_get_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int *level); + +int dfd_set_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int level); + +#endif /* _DFD_FAN_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h new file mode 100644 index 000000000000..a547255cf3ab --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h @@ -0,0 +1,96 @@ +#ifndef __DFD_MODULE_H__ +#define __DFD_MODULE_H__ + +typedef enum dfd_rv_s { + DFD_RV_OK = 0, + DFD_RV_INIT_ERR = 1, + DFD_RV_SLOT_INVALID = 2, + DFD_RV_MODE_INVALID = 3, + DFD_RV_MODE_NOTSUPPORT = 4, + DFD_RV_TYPE_ERR = 5, + DFD_RV_DEV_NOTSUPPORT = 6, + DFD_RV_DEV_FAIL = 7, + DFD_RV_INDEX_INVALID = 8, + DFD_RV_NO_INTF = 9, + DFD_RV_NO_NODE = 10, + DFD_RV_NODE_FAIL = 11, + DFD_RV_INVALID_VALUE = 12, + DFD_RV_NO_MEMORY = 13, +} dfd_rv_t; + +typedef enum { + DBG_VERBOSE = 0x01, + DBG_WARN = 0x02, + DBG_ERROR = 0x04, +} dbg_level_t; + +extern int g_dfd_dbg_level; +extern int g_dfd_fan_dbg_level; +extern int g_dfd_slot_dbg_level; +extern int g_dfd_sensor_dbg_level; +extern int g_dfd_psu_dbg_level; +extern int g_dfd_sff_dbg_level; + +#define DBG_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_FAN_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_fan_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SLOT_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_slot_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SENSOR_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sensor_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_PSU_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_psu_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SFF_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sff_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +int dfd_get_dev_number(unsigned int main_dev_id, unsigned int minor_dev_id); + +#endif /* __DFD_MODULE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h new file mode 100644 index 000000000000..ce7199660557 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h @@ -0,0 +1,10 @@ +#ifndef _DFD_PSU_DRIVER_H_ +#define _DFD_PSU_DRIVER_H_ + +int dfd_get_psu_present_status(unsigned int psu_index); + +int dfd_get_psu_output_status(unsigned int psu_index); + +int dfd_get_psu_alert_status(unsigned int psu_index); + +#endif /* _DFD_PSU_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h new file mode 100644 index 000000000000..16733b26029f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h @@ -0,0 +1,10 @@ +#ifndef _DFD_SENSORS_DRIVER_H_ +#define _DFD_SENSORS_DRIVER_H_ + +ssize_t dfd_get_temp_info(uint8_t main_dev_id, uint8_t dev_index, + uint8_t temp_index, uint8_t temp_attr, char *buf); + +ssize_t dfd_get_voltage_info(uint8_t main_dev_id, uint8_t dev_index, + uint8_t in_index, uint8_t in_attr, char *buf); + +#endif /* _DFD_SENSORS_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h new file mode 100644 index 000000000000..7107b72ee4b2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h @@ -0,0 +1,8 @@ +#ifndef _DFD_SFF_DRIVER_H_ +#define _DFD_SFF_DRIVER_H_ + +ssize_t dfd_get_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, char *buf, int len); + +ssize_t dfd_get_sff_dir_name(unsigned int sff_index, char *buf, int buf_len); + +#endif /* _DFD_SFF_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h new file mode 100644 index 000000000000..c68caecd2e66 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h @@ -0,0 +1,6 @@ +#ifndef _DFD_SLOT_DRIVER_H_ +#define _DFD_SLOT_DRIVER_H_ + +int dfd_get_slot_present_status(unsigned int slot_index); + +#endif /* _DFD_SLOT_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/Makefile new file mode 100644 index 000000000000..1a1044bb1fe8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/Makefile @@ -0,0 +1,21 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +KBUILD_EXTRA_SYMBOLS += $(PLAT_SYSFS_DIR)/dev_cfg/Module.symvers + +obj-m := plat_switch.o +obj-m += plat_fan.o +obj-m += plat_psu.o +obj-m += plat_sff.o +obj-m += plat_sensor.o +obj-m += plat_slot.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/*.mod + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h new file mode 100644 index 000000000000..bbd813e87114 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h @@ -0,0 +1,86 @@ +#ifndef _PLAT_SWITCH_H_ +#define _PLAT_SWITCH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +enum LOG_LEVEL{ + INFO = 0x1, + ERR = 0x2, + DBG = 0x4, + ALL = 0xf +}; + +#define LOG_INFO(_prefix, fmt, args...) \ + do { \ + if (g_loglevel & INFO) \ + { \ + printk( KERN_INFO _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ + } while (0) + +#define LOG_ERR(_prefix, fmt, args...) \ + do { \ + if (g_loglevel & ERR) \ + { \ + printk( KERN_ERR _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ + } while (0) + +#define LOG_DBG(_prefix, fmt, args...) \ + do { \ + if (g_loglevel & DBG) \ + { \ + printk( KERN_DEBUG _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ + } while (0) + +#define check_pfun(p) \ + do { \ + if (p == NULL) { \ + printk( KERN_ERR "%s, %s = NULL.\n", __FUNCTION__, #p); \ + return -ENOSYS; \ + } \ + }while(0) + +#define check_p(p) check_pfun(p) + +#define to_switch_obj(x) container_of(x, struct switch_obj, kobj) +#define to_switch_attr(x) container_of(x, struct switch_attribute, attr) +#define to_switch_device_attr(x) container_of(x, struct switch_device_attribute, switch_attr) + +#define SWITCH_ATTR(_name, _mode, _show, _store, _type) \ + { .switch_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type } + +#define SWITCH_DEVICE_ATTR(_name, _mode, _show, _store, _type) \ +struct switch_device_attribute switch_dev_attr_##_name \ + = SWITCH_ATTR(_name, _mode, _show, _store, _type) + +struct switch_obj { + struct kobject kobj; + unsigned int index; +}; + +/* a custom attribute that works just for a struct switch_obj. */ +struct switch_attribute { + struct attribute attr; + ssize_t (*show)(struct switch_obj *foo, struct switch_attribute *attr, char *buf); + ssize_t (*store)(struct switch_obj *foo, struct switch_attribute *attr, const char *buf, size_t count); +}; + +struct switch_device_attribute { + struct switch_attribute switch_attr; + int type; +}; + +extern struct switch_obj *wb_plat_kobject_create(const char *name, struct kobject *parent); +extern void wb_plat_kobject_delete(struct switch_obj **obj); + +#endif /* _PLAT_SWITCH_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h new file mode 100644 index 000000000000..5b73731e1fbf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h @@ -0,0 +1,90 @@ +#ifndef _SYSFS_COMMON_H_ +#define _SYSFS_COMMON_H_ + +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define DIR_NAME_MAX_LEN (64) + +#define WB_SYSFS_DEV_ERROR "NA" +/* sysfs directory name */ +#define FAN_SYSFS_NAME "fan" +#define PSU_SYSFS_NAME "psu" +#define SLOT_SYSFS_NAME "slot" +#define VOLTAGE_SYSFS_NAME "in" +#define TEMP_SYSFS_NAME "temp" +#define SFF_SYSFS_NAME "sff" + +typedef enum wb_main_dev_type_e { + WB_MAIN_DEV_MAINBOARD = 0, + WB_MAIN_DEV_FAN = 1, + WB_MAIN_DEV_PSU = 2, + WB_MAIN_DEV_SFF = 3, + WB_MAIN_DEV_CPLD = 4, + WB_MAIN_DEV_SLOT = 5, +} wb_main_dev_type_t; + +typedef enum wb_minor_dev_type_e { + WB_MINOR_DEV_NONE = 0, /* None */ + WB_MINOR_DEV_TEMP = 1, + WB_MINOR_DEV_IN = 2, + WB_MINOR_DEV_CURR = 3, + WB_MINOR_DEV_POWER = 4, + WB_MINOR_DEV_MOTOR = 5, + WB_MINOR_DEV_PSU = 6, +} wb_minor_dev_type_t; + +typedef enum wb_sensor_type_e { + WB_SENSOR_INPUT = 0, + WB_SENSOR_ALIAS = 1, + WB_SENSOR_TYPE = 2, + WB_SENSOR_MAX = 3, + WB_SENSOR_MAX_HYST = 4, + WB_SENSOR_MIN = 5, + WB_SENSOR_CRIT = 6, +} wb_sensor_type_t; + +typedef enum wb_sff_cpld_attr_e { + WB_SFF_POWER_ON = 0x01, + WB_SFF_TX_FAULT, + WB_SFF_TX_DIS, + WB_SFF_PRE_N, + WB_SFF_RX_LOS, + WB_SFF_RESET, + WB_SFF_LPMODE, + WB_SFF_MODULE_PRESENT, + WB_SFF_INTERRUPT, +} wb_sff_cpld_attr_t; + +struct switch_drivers_t{ + /* device */ + int (*get_dev_number) (unsigned int main_dev_id, unsigned int minor_dev_id); + /* fan */ + int (*get_fan_number) (void); + ssize_t (*get_fan_speed) (unsigned int fan_index, unsigned int motor_index, unsigned int *speed); + int (*get_fan_pwm) (unsigned int fan_index, unsigned int motor_index, int *pwm); + int (*set_fan_pwm) (unsigned int fan_index, unsigned int motor_index, int pwm); + int (*get_fan_present_status)(unsigned int fan_index); + int (*get_fan_roll_status)(unsigned int fan_index, unsigned int motor_index); + int (*get_fan_speed_level)(unsigned int fan_index, unsigned int motor_index, int *level); + int (*set_fan_speed_level)(unsigned int fan_index, unsigned int motor_index, int level); + /* slot */ + int (*get_slot_present_status) (unsigned int slot_index); + /* sensors */ + ssize_t (*get_temp_info)( uint8_t main_dev_id, uint8_t dev_index, + uint8_t temp_index, uint8_t temp_attr, char *buf); + ssize_t (*get_voltage_info)( uint8_t main_dev_id, uint8_t dev_index, + uint8_t in_index, uint8_t in_attr, char *buf); + /* psu */ + int (*get_psu_present_status)(unsigned int psu_index); + int (*get_psu_output_status)(unsigned int psu_index); + int (*get_psu_alert_status)(unsigned int psu_index); + /* sff */ + ssize_t (*get_sff_cpld_info)( unsigned int sff_index, int cpld_reg_type, char *buf, int len); + ssize_t (*get_sff_dir_name)(unsigned int sff_index, char *buf, int buf_len); +}; + +extern struct switch_drivers_t * dfd_plat_driver_get(void); + +#endif /*_SYSFS_COMMON_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_fan.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_fan.c new file mode 100644 index 000000000000..d841f2547b6f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_fan.c @@ -0,0 +1,505 @@ +/* + * plat_fan.c + * Original Author: support 2020-02-17 + * + * This module create fan kobjects and attributes in /sys/wb_plat/fan + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define FAN_INFO(fmt, args...) LOG_INFO("fan: ", fmt, ##args) +#define FAN_ERR(fmt, args...) LOG_ERR("fan: ", fmt, ##args) +#define FAN_DBG(fmt, args...) LOG_DBG("fan: ", fmt, ##args) + +struct motor_obj_t{ + struct switch_obj *obj; +}; + +struct fan_obj_t{ + unsigned int motor_number; + struct motor_obj_t *motor; + struct switch_obj *obj; +}; + +struct fan_t{ + unsigned int fan_number; + struct fan_obj_t *fan; +}; + +static int g_loglevel = 0; +static struct fan_t g_fan; +static struct switch_obj *g_fan_obj = NULL; +static struct switch_drivers_t *g_drv = NULL; + +static ssize_t fan_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_fan.fan_number); +} + +static ssize_t fan_motor_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int index; + + index = obj->index; + FAN_DBG("fan_motor_number_show,fan index:%d\n",index); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_fan.fan[index-1].motor_number); +} + +static ssize_t fan_roll_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + int ret; + + check_p(g_drv); + check_p(g_drv->get_fan_roll_status); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + fan_index = p_obj->index; + motor_index = obj->index; + + ret = g_drv->get_fan_roll_status(fan_index, motor_index); + if (ret < 0 ) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t fan_present_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + int ret; + + fan_index = obj->index; + FAN_DBG("fan_present_status_show, fan index:%d\n",fan_index); + check_p(g_drv); + check_p(g_drv->get_fan_present_status); + + ret = g_drv->get_fan_present_status(fan_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t fan_speed_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index, motor_index, speed; + int ret; + struct switch_obj *p_obj; + + check_p(g_drv); + check_p(g_drv->get_fan_speed); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + fan_index = p_obj->index; + motor_index = obj->index; + + ret = g_drv->get_fan_speed(fan_index, motor_index, &speed); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", speed); +} + +static ssize_t fan_motor_ratio_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + int ret, pwm; + + check_p(g_drv); + check_p(g_drv->get_fan_pwm); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + fan_index = p_obj->index; + motor_index = obj->index; + ret = g_drv->get_fan_pwm(fan_index, motor_index, &pwm); + + if (ret < 0 ) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", pwm); +} + +static ssize_t fan_motor_ratio_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + int ret, pwm; + + check_p(g_drv); + check_p(g_drv->set_fan_pwm); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + fan_index = p_obj->index; + motor_index = obj->index; + sscanf(buf, "%d", &pwm); + + if (pwm < 0 || pwm > 100) { + FAN_ERR("can not set pwm = %d.\n", pwm); + return -EINVAL; + } + ret = g_drv->set_fan_pwm(fan_index, motor_index, pwm); + if (ret < 0) { + FAN_ERR("can not set pwm = %d.\n", pwm); + return -EIO; + } + return count; +} + +/************************************fan dir and attrs*******************************************/ +static struct switch_attribute fan_number_att = __ATTR(num_fans, S_IRUGO, fan_number_show, NULL); + +static struct attribute *fan_dir_attrs[] = { + &fan_number_att.attr, + NULL, +}; + +static struct attribute_group fan_root_attr_group = { + .attrs = fan_dir_attrs, +}; + +/*******************************fan1 fan2 dir and attrs*******************************************/ +static struct switch_attribute fan_num_motors_att = __ATTR(num_motors, S_IRUGO, fan_motor_number_show, NULL); +static struct switch_attribute fan_present_att = __ATTR(present, S_IRUGO, fan_present_status_show, NULL); + +static struct attribute *fan_attrs[] = { + &fan_num_motors_att.attr, + &fan_present_att.attr, + NULL, +}; + +static struct attribute_group fan_attr_group = { + .attrs = fan_attrs, +}; + +/*******************************motor0 motor1 dir and attrs*******************************************/ +static struct switch_attribute motor_speed_att = __ATTR(speed, S_IRUGO, fan_speed_show, NULL); +static struct switch_attribute motor_status_att = __ATTR(status, S_IRUGO, fan_roll_status_show, NULL); +static struct switch_attribute motor_ratio_att = __ATTR(ratio, S_IRUGO | S_IWUSR, fan_motor_ratio_show, fan_motor_ratio_store); + +static struct attribute *motor_attrs[] = { + &motor_speed_att.attr, + &motor_status_att.attr, + &motor_ratio_att.attr, + NULL, +}; + +static struct attribute_group motor_attr_group = { + .attrs = motor_attrs, +}; + +static void fanindex_single_motor_remove_kobj_and_attrs(struct fan_obj_t * curr_fan, unsigned int motor_index) +{ + struct motor_obj_t *curr_motor; /* point to motor0 motor1...*/ + + curr_motor = &curr_fan->motor[motor_index]; + if (curr_motor->obj) { + sysfs_remove_group(&curr_motor->obj->kobj, &motor_attr_group); + wb_plat_kobject_delete(&curr_motor->obj); + FAN_DBG("delete fan:%d motor%d.\n", curr_fan->obj->index, motor_index); + } + return; +} + +static int fanindex_single_motor_create_kobj_and_attrs(struct fan_obj_t * curr_fan, unsigned int motor_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct motor_obj_t *curr_motor; /* point to motor0 motor1...*/ + + FAN_DBG("create fan_index:%d, motor%d ...\n", curr_fan->obj->index, motor_index); + + curr_motor = &curr_fan->motor[motor_index]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "motor%d", motor_index); + curr_motor->obj = wb_plat_kobject_create(name, &curr_fan->obj->kobj); + if (!curr_motor->obj) { + FAN_ERR("create fan_index:%d, motor%d object error!\n", curr_fan->obj->index, motor_index); + return -EBADRQC; + } + curr_motor->obj->index = motor_index; + if (sysfs_create_group(&curr_motor->obj->kobj, &motor_attr_group) != 0) { + FAN_ERR("create fan_index:%d, motor%d attrs error.\n", curr_fan->obj->index, motor_index); + wb_plat_kobject_delete(&curr_motor->obj); + return -EBADRQC; + } + FAN_DBG("create fan_index:%d, motor%d ok.\n", curr_fan->obj->index, motor_index); + return 0; +} + +static int fanindex_motor_create_kobj_and_attrs(struct fan_obj_t * curr_fan, int motor_num) +{ + int motor_index, i; + + curr_fan->motor = kzalloc(sizeof(struct motor_obj_t) * motor_num, GFP_KERNEL); + if (!curr_fan->motor) { + FAN_ERR("kzalloc motor error, fan index = %d, motor number = %d.\n", curr_fan->obj->index, motor_num); + return -ENOMEM; + } + curr_fan->motor_number = motor_num; + for (motor_index = 0; motor_index < motor_num; motor_index++) { + if (fanindex_single_motor_create_kobj_and_attrs(curr_fan, motor_index) != 0) { + goto motor_error; + } + } + return 0; +motor_error: + for(i = motor_index - 1; i >= 0; i--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, i); + } + if(curr_fan->motor) { + kfree(curr_fan->motor); + curr_fan->motor = NULL; + } + return -EBADRQC; +} + +static void fanindex_motor_remove_kobj_and_attrs(struct fan_obj_t *curr_fan, int motor_num) +{ + int motor_index; + + for (motor_index = motor_num - 1; motor_index >= 0; motor_index--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, motor_index); + } + return; +} + +static int fan_motor_create(void) +{ + int fan_num, motor_num; + unsigned int fan_index, i; + struct fan_obj_t *curr_fan; /* point to fan1 fan2...*/ + + check_p(g_drv->get_dev_number); + + motor_num = g_drv->get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_MOTOR); + if (motor_num <= 0) { + FAN_ERR("get fan motor number error, motor_num:%d error.\n", motor_num); + return -ENODEV; + } + + fan_num = g_fan.fan_number; + for (fan_index = 1; fan_index <= fan_num; fan_index++) { + curr_fan = &g_fan.fan[fan_index - 1]; + if (fanindex_motor_create_kobj_and_attrs(curr_fan, motor_num) != 0) { + goto error; + } + } + return 0; +error: + for (i = fan_index - 1; i > 0; i--) { + curr_fan = &g_fan.fan[i - 1]; + motor_num = curr_fan->motor_number; + fanindex_motor_remove_kobj_and_attrs(curr_fan, motor_num); + } + return -EBADRQC; +} + +static void fan_motor_remove(void) +{ + unsigned int fan_index; + struct fan_obj_t *curr_fan; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + curr_fan = &g_fan.fan[fan_index - 1]; + if (curr_fan->motor) { + fanindex_motor_remove_kobj_and_attrs(curr_fan, curr_fan->motor_number); + kfree(curr_fan->motor); + curr_fan->motor = NULL; + curr_fan->motor_number = 0; + } + } + } + return; +} + +static void fan_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct fan_obj_t *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + if (curr_fan->obj) { + sysfs_remove_group(&curr_fan->obj->kobj, &fan_attr_group); + wb_plat_kobject_delete(&curr_fan->obj); + FAN_DBG("delete fan%d.\n", index); + } + return; +} + +static int fan_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct fan_obj_t *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + FAN_DBG("create fan%d ...\n", index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "fan%d", index); + curr_fan->obj = wb_plat_kobject_create(name, parent); + if (!curr_fan->obj) { + FAN_ERR("create fan%d object error!\n", index); + return -EBADRQC; + } + curr_fan->obj->index = index; + if (sysfs_create_group(&curr_fan->obj->kobj, &fan_attr_group) != 0) { + FAN_ERR("create fan%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_fan->obj); + return -EBADRQC; + } + FAN_DBG("create fan%d ok.\n", index); + return 0; +} + +static int fan_sub_create_kobj_and_attrs(struct kobject *parent, int fan_num) +{ + unsigned int fan_index, i; + + g_fan.fan = kzalloc(sizeof(struct fan_obj_t) * fan_num, GFP_KERNEL); + if (!g_fan.fan) { + FAN_ERR("kzalloc fan.fan error, fan number = %d.\n", fan_num); + return -ENOMEM; + } + + for (fan_index = 1; fan_index <= fan_num; fan_index++) { + if(fan_sub_single_create_kobj_and_attrs(parent, fan_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = fan_index - 1; i > 0; i--) { + fan_sub_single_remove_kobj_and_attrs(i); + } + if (g_fan.fan) { + kfree(g_fan.fan); + g_fan.fan = NULL; + } + return -EBADRQC; +} + +static int fan_sub_create(void) +{ + int ret, fan_num; + + check_p(g_drv->get_dev_number); + fan_num = g_drv->get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_NONE); + if (fan_num < 0) { + FAN_ERR("fan number = %d error.\n", fan_num); + return -EINVAL; + } + g_fan.fan_number = fan_num; + ret = fan_sub_create_kobj_and_attrs(&g_fan_obj->kobj, fan_num); + return ret; +} + +static void fan_sub_remove(void) +{ + unsigned int fan_index; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + fan_sub_single_remove_kobj_and_attrs(fan_index); + } + kfree(g_fan.fan); + } + mem_clear(&g_fan, sizeof(struct fan_t)); + return; +} + +static int fan_root_create(void) +{ + g_fan_obj = wb_plat_kobject_create("fan", NULL); + if (!g_fan_obj) { + FAN_ERR("wb_plat_kobject_create fan error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_fan_obj->kobj, &fan_root_attr_group) != 0) { + wb_plat_kobject_delete(&g_fan_obj); + FAN_ERR("create fan dir attrs error!\n"); + return -EBADRQC; + } + FAN_DBG("wb_plat_kobject_create fan directory and attribute success.\n"); + return 0; +} + +static void fan_root_remove(void) +{ + if (g_fan_obj) { + sysfs_remove_group(&g_fan_obj->kobj, &fan_root_attr_group); + wb_plat_kobject_delete(&g_fan_obj); + FAN_DBG("delete fan root success\n"); + } + + return; +} + +static int fan_init(void) +{ + int ret; + + FAN_INFO("fan_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = fan_root_create(); + if (ret < 0) { + goto fan_root_error; + } + + ret = fan_sub_create(); + if (ret < 0) { + goto fan_sub_error; + } + + ret = fan_motor_create(); + if (ret < 0) { + goto fan_motor_error; + } + + FAN_INFO("fan_init ok.\n"); + return 0; +fan_motor_error: + fan_sub_remove(); +fan_sub_error: + fan_root_remove(); +fan_root_error: + return ret; +} + +static void fan_exit(void) +{ + fan_motor_remove(); + fan_sub_remove(); + fan_root_remove(); + FAN_INFO("fan_exit ok.\n"); + return ; +} + +module_init(fan_init); +module_exit(fan_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("fan sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_psu.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_psu.c new file mode 100644 index 000000000000..af3b414314ff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_psu.c @@ -0,0 +1,430 @@ +/* + * plat_psu.c + * Original Author: support 2020-02-17 + * + * This module create psu kobjects and attributes in /sys/wb_plat/psu + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define PSU_INFO(fmt, args...) LOG_INFO("psu: ", fmt, ##args) +#define PSU_ERR(fmt, args...) LOG_ERR("psu: ", fmt, ##args) +#define PSU_DBG(fmt, args...) LOG_DBG("psu: ", fmt, ##args) + +struct temp_obj_t{ + struct switch_obj *obj; +}; + +struct psu_obj_t{ + unsigned int temp_number; + struct temp_obj_t *temp; + struct switch_obj *obj; +}; + +struct psu_t{ + unsigned int psu_number; + struct psu_obj_t *psu; +}; + +static int g_loglevel = 0; +static struct psu_t g_psu; +static struct switch_obj *g_psu_obj = NULL; +static struct switch_drivers_t *g_drv = NULL; + +static ssize_t psu_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_psu.psu_number); +} + +static ssize_t psu_present_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + psu_index = obj->index; + PSU_DBG("psu_present_status_show, psu index:%d\n",psu_index); + check_p(g_drv); + check_p(g_drv->get_psu_present_status); + + ret = g_drv->get_psu_present_status(psu_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t psu_output_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + psu_index = obj->index; + PSU_DBG("psu_output_status_show, psu index:%d\n",psu_index); + check_p(g_drv); + check_p(g_drv->get_psu_output_status); + + ret = g_drv->get_psu_output_status(psu_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t psu_alert_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + psu_index = obj->index; + PSU_DBG("psu_alert_status_show, psu index:%d\n",psu_index); + check_p(g_drv); + check_p(g_drv->get_psu_alert_status); + + ret = g_drv->get_psu_alert_status(psu_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +/************************************psu dir and attrs*******************************************/ +static struct switch_attribute psu_number_att = __ATTR(num_psus, S_IRUGO, psu_number_show, NULL); + +static struct attribute *psu_dir_attrs[] = { + &psu_number_att.attr, + NULL, +}; + +static struct attribute_group psu_root_attr_group = { + .attrs = psu_dir_attrs, +}; + +/*******************************psu1 psu2 dir and attrs*******************************************/ +static struct switch_attribute psu_present_status_att = __ATTR(present, S_IRUGO, psu_present_status_show, NULL); +static struct switch_attribute psu_output_status_att = __ATTR(output, S_IRUGO, psu_output_status_show, NULL); +static struct switch_attribute psu_alert_status_att = __ATTR(alert, S_IRUGO, psu_alert_status_show, NULL); + +static struct attribute *psu_attrs[] = { + &psu_present_status_att.attr, + &psu_output_status_att.attr, + &psu_alert_status_att.attr, + NULL, +}; + +static struct attribute_group psu_attr_group = { + .attrs = psu_attrs, +}; + +/*******************************psu temp0 temp1 dir and attrs*******************************************/ +static struct attribute *psu_temp_attrs[] = { + NULL, +}; + +static struct attribute_group psu_temp_attr_group = { + .attrs = psu_temp_attrs, +}; + +static void psuindex_single_temp_remove_kobj_and_attrs(struct psu_obj_t * curr_psu, unsigned int temp_index) +{ + + struct temp_obj_t *curr_temp; /* point to temp0 temp1...*/ + + curr_temp = &curr_psu->temp[temp_index]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &psu_temp_attr_group); + wb_plat_kobject_delete(&curr_temp->obj); + PSU_DBG("delete psu:%d temp%d.\n", curr_psu->obj->index, temp_index); + } + return; +} + +static int psuindex_single_temp_create_kobj_and_attrs(struct psu_obj_t * curr_psu, unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct temp_obj_t *curr_temp; /* point to temp0 temp1...*/ + + PSU_DBG("create psu_index:%d, temp%d ...\n", curr_psu->obj->index, temp_index); + + curr_temp = &curr_psu->temp[temp_index]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp%d", temp_index); + curr_temp->obj = wb_plat_kobject_create(name, &curr_psu->obj->kobj); + if (!curr_temp->obj) { + PSU_ERR("create psu_index:%d, temp%d object error!\n", curr_psu->obj->index, temp_index); + return -EBADRQC; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &psu_temp_attr_group) != 0) { + PSU_ERR("create psu_index:%d, temp%d attrs error.\n", curr_psu->obj->index, temp_index); + wb_plat_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + PSU_DBG("create psu_index:%d, temp%d ok.\n", curr_psu->obj->index, temp_index); + return 0; +} + +static int psuindex_temp_create_kobj_and_attrs(struct psu_obj_t * curr_psu, int temp_num) +{ + int temp_index, i; + + curr_psu->temp = kzalloc(sizeof(struct temp_obj_t) * temp_num, GFP_KERNEL); + if (!curr_psu->temp) { + PSU_ERR("kzalloc temp error, psu index = %d, temp number = %d.\n", curr_psu->obj->index, temp_num); + return -ENOMEM; + } + curr_psu->temp_number = temp_num; + for (temp_index = 0; temp_index < temp_num; temp_index++) { + if (psuindex_single_temp_create_kobj_and_attrs(curr_psu, temp_index) != 0) { + goto temp_error; + } + } + return 0; +temp_error: + for (i = temp_index - 1; i >= 0; i--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, i); + } + if (curr_psu->temp) { + kfree(curr_psu->temp); + curr_psu->temp = NULL; + } + return -EBADRQC; +} + +static void psuindex_temp_remove_kobj_and_attrs(struct psu_obj_t * curr_psu, int temp_num) +{ + unsigned int temp_index; + + for (temp_index = temp_num - 1; temp_index >= 0; temp_index--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, temp_index); + } + return; +} + +static int psu_temp_create(void) +{ + int psu_num, temp_num; + unsigned int psu_index, i; + struct psu_obj_t *curr_psu; /* point to psu1 psu2...*/ + + check_p(g_drv->get_dev_number); + temp_num = g_drv->get_dev_number(WB_MAIN_DEV_PSU, WB_MINOR_DEV_TEMP); + if (temp_num <= 0) { + PSU_INFO("psu temp_num:%d, don't need creat temp directory.\n", temp_num); + return 0; + } + + psu_num = g_psu.psu_number; + for(psu_index = 1; psu_index <= psu_num; psu_index++) { + curr_psu = &g_psu.psu[psu_index - 1]; + if(psuindex_temp_create_kobj_and_attrs(curr_psu, temp_num) != 0) { + goto error; + } + } + return 0; +error: + for(i = psu_index - 1; i > 0; i--) { + curr_psu = &g_psu.psu[i - 1]; + temp_num = curr_psu->temp_number; + psuindex_temp_remove_kobj_and_attrs(curr_psu, temp_num); + } + return -EBADRQC; +} + +static void psu_temp_remove(void) +{ + unsigned int psu_index; + struct psu_obj_t *curr_psu; + + if (g_psu.psu) { + for (psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + curr_psu = &g_psu.psu[psu_index - 1]; + if (curr_psu->temp) { + psuindex_temp_remove_kobj_and_attrs(curr_psu,curr_psu->temp_number); + kfree(curr_psu->temp); + curr_psu->temp = NULL; + curr_psu->temp_number = 0; + } + } + } + return; +} + +static void psu_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct psu_obj_t *curr_psu; + + curr_psu = &g_psu.psu[index - 1]; + if (curr_psu->obj) { + sysfs_remove_group(&curr_psu->obj->kobj, &psu_attr_group); + wb_plat_kobject_delete(&curr_psu->obj); + PSU_DBG("delete psu%d.\n", index); + } + return; +} + +static int psu_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct psu_obj_t *curr_psu; + + curr_psu = &g_psu.psu[index-1]; + PSU_DBG("create psu%d ...\n", index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "%s%d",PSU_SYSFS_NAME, index); + curr_psu->obj = wb_plat_kobject_create(name, parent); + if (!curr_psu->obj) { + PSU_ERR("create psu%d object error!\n", index); + return -EBADRQC; + } + curr_psu->obj->index = index; + if (sysfs_create_group(&curr_psu->obj->kobj, &psu_attr_group) != 0) { + PSU_ERR("create psu%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_psu->obj); + return -EBADRQC; + } + PSU_DBG("create psu%d ok.\n", index); + return 0; +} + +static int psu_sub_create_kobj_and_attrs(struct kobject *parent, int psu_num) +{ + unsigned int psu_index, i; + + g_psu.psu = kzalloc(sizeof(struct psu_obj_t) * psu_num, GFP_KERNEL); + if (!g_psu.psu) { + PSU_ERR("kzalloc psu.psu error, psu number = %d.\n", psu_num); + return -ENOMEM; + } + + for (psu_index = 1; psu_index <= psu_num; psu_index++) { + if (psu_sub_single_create_kobj_and_attrs(parent, psu_index) != 0) { + goto error; + } + } + return 0; +error: + for(i = psu_index - 1; i > 0; i--) { + psu_sub_single_remove_kobj_and_attrs(i); + } + if(g_psu.psu) { + kfree(g_psu.psu); + g_psu.psu = NULL; + } + return -EBADRQC; +} + +static int psu_sub_create(void) +{ + int ret, psu_num; + + check_p(g_drv->get_dev_number); + psu_num = g_drv->get_dev_number(WB_MAIN_DEV_PSU, WB_MINOR_DEV_NONE); + if (psu_num < 0) { + PSU_ERR("psu number = %d error.\n", psu_num); + return -EINVAL; + } + g_psu.psu_number = psu_num; + ret = psu_sub_create_kobj_and_attrs(&g_psu_obj->kobj, psu_num); + return ret; +} + +static void psu_sub_remove(void) +{ + unsigned int psu_index; + + if (g_psu.psu) { + for (psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + psu_sub_single_remove_kobj_and_attrs(psu_index); + } + kfree(g_psu.psu); + } + mem_clear(&g_psu, sizeof(struct psu_t)); + return ; +} + +static int psu_root_create(void) +{ + g_psu_obj = wb_plat_kobject_create(PSU_SYSFS_NAME, NULL); + if (!g_psu_obj) { + PSU_ERR("wb_plat_kobject_create psu error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_psu_obj->kobj, &psu_root_attr_group) != 0) { + wb_plat_kobject_delete(&g_psu_obj); + PSU_ERR("create psu dir attrs error!\n"); + return -EBADRQC; + } + PSU_DBG("wb_plat_kobject_create psu directory and attribute success.\n"); + return 0; +} + +static void psu_root_remove(void) +{ + if (g_psu_obj) { + sysfs_remove_group(&g_psu_obj->kobj, &psu_root_attr_group); + wb_plat_kobject_delete(&g_psu_obj); + PSU_DBG("delete psu root success\n"); + } + return; +} + +static int wb_psu_init(void) +{ + int ret; + + PSU_INFO("wb_psu_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = psu_root_create(); + if (ret < 0) { + goto psu_root_error; + } + + ret = psu_sub_create(); + if (ret < 0) { + goto psu_sub_error; + } + + ret = psu_temp_create(); + if (ret < 0) { + goto psu_temp_error; + } + + PSU_INFO("wb_psu_init ok.\n"); + return 0; +psu_temp_error: + psu_sub_remove(); +psu_sub_error: + psu_root_remove(); +psu_root_error: + return ret; +} + +static void wb_psu_exit(void) +{ + psu_temp_remove(); + psu_sub_remove(); + psu_root_remove(); + PSU_INFO("wb_psu_exit ok.\n"); + return ; +} + +module_init(wb_psu_init); +module_exit(wb_psu_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("psu sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c new file mode 100644 index 000000000000..04b764e82df9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c @@ -0,0 +1,457 @@ +/* + * plat_sensor.c + * Original Author: support 2020-02-17 + * + * This module create sensor kobjects and attributes in /sys/wb_plat/sensor + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define SENSOR_INFO(fmt, args...) LOG_INFO("sensor: ", fmt, ##args) +#define SENSOR_ERR(fmt, args...) LOG_ERR("sensor: ", fmt, ##args) +#define SENSOR_DBG(fmt, args...) LOG_DBG("sensor: ", fmt, ##args) + +struct sensor_t { + unsigned int in_number; + unsigned int temp_number; + struct sensor_in_t *in; + struct sensor_temp_t *temp; +}; + +struct sensor_temp_t { + struct switch_obj *obj; +}; + +struct sensor_in_t { + struct switch_obj *obj; +}; + +static int g_loglevel = 0; +static struct switch_drivers_t *g_drv = NULL; +static struct sensor_t g_sensor; +static struct switch_obj *g_sensor_obj = NULL; + +static ssize_t sensor_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_sensor.temp_number); +} + +static ssize_t sensor_in_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_sensor.in_number); +} + +static ssize_t sensor_voltage_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int in_index; + int ret; + struct switch_device_attribute *in_attr; + + check_p(g_drv); + check_p(g_drv->get_voltage_info); + in_index = obj->index; + + in_attr = to_switch_device_attr(attr); + check_p(in_attr); + SENSOR_DBG("sensor_in_show, in index:0x%x, in type:0x%x\n",in_index, in_attr->type); + ret = g_drv->get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, in_index, in_attr->type, buf); + if (ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t sensor_temp_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + int ret; + struct switch_device_attribute *temp_attr; + + check_p(g_drv); + check_p(g_drv->get_temp_info); + temp_index = obj->index; + + temp_attr = to_switch_device_attr(attr); + check_p(temp_attr); + SENSOR_DBG("sensor_temp_show, temp index:0x%x, temp type:0x%x\n", temp_index, temp_attr->type); + ret = g_drv->get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, temp_attr->type, buf); + if (ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return ret; +} + +/************************************sensor dir and attrs*******************************************/ +static struct switch_attribute num_temp_att = __ATTR(num_temp_sensors, S_IRUGO, sensor_temp_number_show, NULL); +static struct switch_attribute num_in_att = __ATTR(num_in_sensors, S_IRUGO, sensor_in_number_show, NULL); + +static struct attribute *sensor_dir_attrs[] = { + &num_temp_att.attr, + &num_in_att.attr, + NULL, +}; + +static struct attribute_group sensor_root_attr_group = { + .attrs = sensor_dir_attrs, +}; + +/*******************************temp0 temp1 dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(temp_input, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_INPUT); +static SWITCH_DEVICE_ATTR(temp_alias, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_ALIAS); +static SWITCH_DEVICE_ATTR(temp_type, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_TYPE); +static SWITCH_DEVICE_ATTR(temp_max, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_MAX); +static SWITCH_DEVICE_ATTR(temp_max_hyst, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_MAX_HYST); +static SWITCH_DEVICE_ATTR(temp_min, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_MIN); + +static struct attribute *sensor_temp_attrs[] = { + &switch_dev_attr_temp_input.switch_attr.attr, + &switch_dev_attr_temp_alias.switch_attr.attr, + &switch_dev_attr_temp_type.switch_attr.attr, + &switch_dev_attr_temp_max.switch_attr.attr, + &switch_dev_attr_temp_max_hyst.switch_attr.attr, + &switch_dev_attr_temp_min.switch_attr.attr, + NULL, +}; + +static struct attribute_group sensor_temp_attr_group = { + .attrs = sensor_temp_attrs, +}; + +/*******************************in0 in1 dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(in_input, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_INPUT); +static SWITCH_DEVICE_ATTR(in_alias, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_ALIAS); +static SWITCH_DEVICE_ATTR(in_type, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_TYPE); +static SWITCH_DEVICE_ATTR(in_max, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_MAX); +static SWITCH_DEVICE_ATTR(in_min, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_MIN); +static SWITCH_DEVICE_ATTR(in_crit, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_CRIT); + +static struct attribute *sensor_in_attrs[] = { + &switch_dev_attr_in_input.switch_attr.attr, + &switch_dev_attr_in_alias.switch_attr.attr, + &switch_dev_attr_in_type.switch_attr.attr, + &switch_dev_attr_in_max.switch_attr.attr, + &switch_dev_attr_in_min.switch_attr.attr, + &switch_dev_attr_in_crit.switch_attr.attr, + NULL, +}; + +static struct attribute_group sensor_in_attr_group = { + .attrs = sensor_in_attrs, +}; + +static int sensor_in_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct sensor_in_t *curr_sensor; + + curr_sensor = &g_sensor.in[index - 1]; + SENSOR_DBG("create sensor in%d ...\n", index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "in%d", index); + curr_sensor->obj = wb_plat_kobject_create(name, parent); + if (!curr_sensor->obj) { + SENSOR_ERR("create sensor in%d object error!\n", index); + return -EBADRQC; + } + curr_sensor->obj->index = index; + if (sysfs_create_group(&curr_sensor->obj->kobj, &sensor_in_attr_group) != 0) { + SENSOR_ERR("create sensor in%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_sensor->obj); + return -EBADRQC; + } + SENSOR_DBG("create sensor in%d ok.\n", index); + return 0; + +} + +static void sensor_in_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sensor_in_t *curr_in; + + curr_in = &g_sensor.in[index - 1]; + if (curr_in->obj) { + sysfs_remove_group(&curr_in->obj->kobj, &sensor_in_attr_group); + wb_plat_kobject_delete(&curr_in->obj); + SENSOR_DBG("delete in%d.\n", index); + } + return; +} + +static int sensor_temp_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct sensor_temp_t *curr_sensor; + + curr_sensor = &g_sensor.temp[index - 1]; + SENSOR_DBG("create sensor temp%d ...\n", index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp%d", index); + curr_sensor->obj = wb_plat_kobject_create(name, parent); + if (!curr_sensor->obj) { + SENSOR_ERR("create sensor temp%d object error!\n", index); + return -EBADRQC; + } + curr_sensor->obj->index = index; + if (sysfs_create_group(&curr_sensor->obj->kobj, &sensor_temp_attr_group) != 0) { + SENSOR_ERR("create sensor temp%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_sensor->obj); + return -EBADRQC; + } + SENSOR_DBG("create sensor temp%d ok.\n", index); + return 0; + +} + +static void sensor_temp_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sensor_temp_t *curr_temp; + + curr_temp = &g_sensor.temp[index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &sensor_temp_attr_group); + wb_plat_kobject_delete(&curr_temp->obj); + SENSOR_DBG("delete temp%d.\n", index); + } + return; +} + +static int sensor_temp_sub_create_kobj_and_attrs(struct kobject *parent, int temp_num) +{ + unsigned int temp_index, i; + + g_sensor.temp = kzalloc(sizeof(struct sensor_temp_t) * temp_num, GFP_KERNEL); + if (!g_sensor.temp ) { + SENSOR_ERR("kzalloc g_sensor.temp error, temp number = %d.\n", temp_num); + return -ENOMEM; + } + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (sensor_temp_sub_single_create_kobj_and_attrs(parent, temp_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = temp_index - 1; i > 0; i--) { + sensor_temp_sub_single_remove_kobj_and_attrs(i); + } + + if (g_sensor.temp) { + kfree(g_sensor.temp); + g_sensor.temp = NULL; + } + return -EBADRQC; +} + +static int sensor_in_sub_create_kobj_and_attrs(struct kobject *parent, int in_num) +{ + unsigned int in_index, i; + + g_sensor.in = kzalloc(sizeof(struct sensor_in_t) * in_num, GFP_KERNEL); + if (!g_sensor.in) { + SENSOR_ERR("kzalloc g_sensor.in error, in number = %d.\n", in_num); + return -ENOMEM; + } + + for (in_index = 1; in_index <= in_num; in_index++) { + if (sensor_in_sub_single_create_kobj_and_attrs(parent, in_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = in_index - 1; i > 0; i--) { + sensor_in_sub_single_remove_kobj_and_attrs(i); + } + + if (g_sensor.in) { + kfree(g_sensor.in); + g_sensor.in = NULL; + } + return -EBADRQC; +} + +static int sensor_temp_sub_create(void) +{ + int ret, temp_num; + + check_p(g_drv->get_dev_number); + temp_num = g_drv->get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_TEMP); + g_sensor.temp_number = temp_num; + if (temp_num <= 0) { + SENSOR_DBG("Warning:sensor temp number = %d \n", temp_num); + return 0; + } + ret = sensor_temp_sub_create_kobj_and_attrs(&g_sensor_obj->kobj, temp_num); + return ret; +} + +static int sensor_in_sub_create(void) +{ + int ret, in_num; + + check_p(g_drv->get_dev_number); + in_num = g_drv->get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_IN); + g_sensor.in_number = in_num; + + if (in_num <= 0) { + SENSOR_DBG("Warning:sensor in number = %d \n", in_num); + return 0; + } + ret = sensor_in_sub_create_kobj_and_attrs(&g_sensor_obj->kobj, in_num); + return ret; +} + +static void temp_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sensor_temp_t * curr_temp; + + curr_temp = &g_sensor.temp[index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &sensor_temp_attr_group); + wb_plat_kobject_delete(&curr_temp->obj); + SENSOR_DBG("delete sensor temp%d.\n", index); + } + return; +} + +static void in_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sensor_in_t * curr_in; + + curr_in = &g_sensor.in[index - 1]; + if (curr_in->obj) { + sysfs_remove_group(&curr_in->obj->kobj, &sensor_in_attr_group); + wb_plat_kobject_delete(&curr_in->obj); + SENSOR_DBG("delete sensor in%d.\n", index); + } + return; +} + +static void sensor_temp_sub_remove(void) +{ + unsigned int temp_index; + + if (g_sensor.temp) { + for (temp_index = g_sensor.temp_number; temp_index > 0; temp_index--) { + temp_sub_single_remove_kobj_and_attrs(temp_index); + } + kfree(g_sensor.temp); + g_sensor.temp = NULL; + } + return; +} + +static void sensor_in_sub_remove(void) +{ + unsigned int in_index; + + if (g_sensor.in) { + for (in_index = g_sensor.in_number; in_index > 0; in_index--) { + in_sub_single_remove_kobj_and_attrs(in_index); + } + kfree(g_sensor.in); + g_sensor.in = NULL; + } + return; +} + +static void sensor_sub_remove(void) +{ + sensor_temp_sub_remove(); + sensor_in_sub_remove(); +} + +static int sensor_sub_create(void) +{ + int ret; + /* temp creat */ + ret = sensor_temp_sub_create(); + if (ret < 0) { + goto temp_err; + } + /* Voltage creat */ + ret = sensor_in_sub_create(); + if (ret < 0) { + goto in_err; + } + return 0; +in_err: + sensor_temp_sub_remove(); +temp_err: + return ret; +} +static void sensor_root_remove(void) +{ + if (g_sensor_obj) { + sysfs_remove_group(&g_sensor_obj->kobj, &sensor_root_attr_group); + wb_plat_kobject_delete(&g_sensor_obj); + SENSOR_DBG("delete sensor root success\n"); + } + + return; +} + +static int sensor_root_create(void) +{ + g_sensor_obj = wb_plat_kobject_create("sensor", NULL); + if (!g_sensor_obj) { + SENSOR_ERR("wb_plat_kobject_create sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_sensor_obj->kobj, &sensor_root_attr_group) != 0) { + wb_plat_kobject_delete(&g_sensor_obj); + SENSOR_ERR("create sensor dir attrs error!\n"); + return -EBADRQC; + } + SENSOR_DBG("wb_plat_kobject_create sensor directory and attribute success.\n"); + return 0; +} + +static int wb_sensor_init(void) +{ + int ret; + + SENSOR_INFO("wb_sensor_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = sensor_root_create(); + if (ret < 0) { + goto sensor_root_error; + } + + ret = sensor_sub_create(); + if (ret < 0) { + goto sensor_sub_error; + } + SENSOR_INFO("sensor_init ok.\n"); + return 0; +sensor_sub_error: + sensor_root_remove(); +sensor_root_error: + return ret; +} + +static void wb_sensor_exit(void) +{ + sensor_sub_remove(); + sensor_root_remove(); + SENSOR_INFO("sensor_exit ok.\n"); + return; +} + +module_init(wb_sensor_init); +module_exit(wb_sensor_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("sensors sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sff.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sff.c new file mode 100644 index 000000000000..8f09c551f62c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sff.c @@ -0,0 +1,291 @@ +/* + * plat_sff.c + * Original Author: support 2020-02-17 + * + * This module create sff kobjects and attributes in /sys/wb_plat/sff + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define SFF_INFO(fmt, args...) LOG_INFO("sff: ", fmt, ##args) +#define SFF_ERR(fmt, args...) LOG_ERR("sff: ", fmt, ##args) +#define SFF_DBG(fmt, args...) LOG_DBG("sff: ", fmt, ##args) + +struct sff_obj_t{ + struct switch_obj *sff_obj; + struct bin_attribute bin; + int sff_creat_bin_flag; +}; + +struct sff_t{ + unsigned int sff_number; + struct sff_obj_t *sff; +}; + +static int g_loglevel = 0; +static struct sff_t g_sff; +static struct switch_obj *g_sff_obj = NULL; +static struct switch_drivers_t *g_drv = NULL; + +static ssize_t sff_cpld_info_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int sff_index; + int ret; + struct switch_device_attribute *sff_cpld_attr; + + check_p(g_drv); + check_p(g_drv->get_sff_cpld_info); + + sff_index = obj->index; + sff_cpld_attr = to_switch_device_attr(attr); + check_p(sff_cpld_attr); + SFF_DBG("sff_cpld_info_show, sff index:0x%x, sff cpld attr type:0x%x\n", sff_index, sff_cpld_attr->type); + ret = g_drv->get_sff_cpld_info(sff_index, sff_cpld_attr->type, buf, PAGE_SIZE); + if(ret < 0) { + SFF_ERR("sff_cpld_info_show error. sff index:0x%x, sff cpld attr type:0x%x, ret:%d\n", + sff_index, sff_cpld_attr->type,ret ); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + SFF_DBG("sff_cpld_info_show ok. sff index:0x%x, sff cpld attr type:0x%x, ret:%d\n", sff_index, sff_cpld_attr->type, ret); + return ret; +} + +static ssize_t sff_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_sff.sff_number); +} + +/************************************sff attrs*******************************************/ +static struct switch_attribute sff_number_att = __ATTR(num_sffs, S_IRUGO, sff_number_show, NULL); +static SWITCH_DEVICE_ATTR(present, S_IRUGO, sff_cpld_info_show, NULL, WB_SFF_MODULE_PRESENT); + +/*******************************xcvr dir and attrs*******************************************/ +static struct attribute *xcvr_dir_attrs[] = { + &sff_number_att.attr, + NULL, +}; + +static struct attribute_group sff_xcvr_attr_group = { + .attrs = xcvr_dir_attrs, +}; + +/*******************************sff dir and attrs*******************************************/ +static struct attribute *sff_attrs[] = { + &switch_dev_attr_present.switch_attr.attr, + NULL, +}; + +static struct attribute_group sff_attr_group = { + .attrs = sff_attrs, +}; + +static int sff_sub_single_create_attrs(unsigned int index) +{ + struct sff_obj_t *curr_sff; + + curr_sff = &g_sff.sff[index-1]; + if (sysfs_create_group(&curr_sff->sff_obj->kobj, &sff_attr_group) != 0) { + SFF_ERR("create sff%d dir attrs error!\n", index); + wb_plat_kobject_delete(&curr_sff->sff_obj); + return -EBADRQC; + } + SFF_DBG("create sff%d dir attrs ok!\n", index); + return 0; +} + +static int sff_sub_single_create_kobj(struct kobject *parent, unsigned int index) +{ + struct sff_obj_t *curr_sff; + char sff_dir_name[DIR_NAME_MAX_LEN]; + int ret; + + check_p(g_drv->get_sff_dir_name); + ret = g_drv->get_sff_dir_name(index, sff_dir_name, sizeof(sff_dir_name)); + if (ret < 0) { + SFF_ERR("sff index:%d, get sff dir name error. please check sff config.\n", index); + return -ENOSYS; + } + + curr_sff = &g_sff.sff[index - 1]; + + curr_sff->sff_obj = wb_plat_kobject_create(sff_dir_name, parent); + if (!curr_sff->sff_obj) { + SFF_ERR("sff index:%d, create %s object error! \n", index, sff_dir_name); + return -EBADRQC; + } + + SFF_DBG("create sff kobj ok. sff index:%d, dir name:%s\n",index, sff_dir_name); + curr_sff->sff_obj->index = index; + + return 0; +} + +static void sff_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sff_obj_t *curr_sff; + + curr_sff = &g_sff.sff[index - 1]; + /* remove sff dir and attr */ + if (curr_sff->sff_obj) { + SFF_DBG("delete sff%d attrs.\n", curr_sff->sff_obj->index); + curr_sff->sff_obj->index = 0; + sysfs_remove_group(&curr_sff->sff_obj->kobj, &sff_attr_group); + wb_plat_kobject_delete(&curr_sff->sff_obj); + } + + return; +} + +static int sff_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + int ret; + + ret = sff_sub_single_create_kobj(parent, index); + if (ret < 0) { + SFF_ERR("sff index:%d, create sff dir error.\n", index); + return ret; + } + + ret = sff_sub_single_create_attrs(index); + if (ret < 0) { + SFF_ERR("sff index:%d, create sff attr error.\n", index); + return ret; + } + return 0; +} + +static int sff_sub_create_kobj_and_attrs(struct kobject *parent, int sff_num) +{ + unsigned int sff_index, i; + + g_sff.sff = kzalloc(sizeof(struct sff_obj_t) * sff_num, GFP_KERNEL); + if (!g_sff.sff) { + SFF_ERR("kzalloc g_sff.sff error, sff number = %d.\n", sff_num); + return -ENOMEM; + } + + for (sff_index = 1; sff_index <= sff_num; sff_index++) { + if (sff_sub_single_create_kobj_and_attrs(parent, sff_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = sff_index - 1; i > 0; i--) { + sff_sub_single_remove_kobj_and_attrs(i); + } + if (g_sff.sff) { + kfree(g_sff.sff); + g_sff.sff = NULL; + } + return -EBADRQC; +} + +static int sff_sub_create(void) +{ + int ret, sff_num; + + check_p(g_drv->get_dev_number); + sff_num = g_drv->get_dev_number(WB_MAIN_DEV_SFF, WB_MINOR_DEV_NONE); + g_sff.sff_number = sff_num; + if (sff_num <= 0) { + SFF_ERR("ERROR. port number:%d\n", sff_num); + return -EINVAL; + } + + ret = sff_sub_create_kobj_and_attrs(&g_sff_obj->kobj, sff_num); + + return ret; +} + +static void sff_sub_remove(void) +{ + unsigned int sff_index; + + if (g_sff.sff) { + for (sff_index = g_sff.sff_number; sff_index > 0; sff_index--) { + sff_sub_single_remove_kobj_and_attrs(sff_index); + } + kfree(g_sff.sff); + } + mem_clear(&g_sff, sizeof(struct sff_t)); + return ; +} + +static int sff_xcvr_create(void) +{ + g_sff_obj = wb_plat_kobject_create(SFF_SYSFS_NAME, NULL); + if (!g_sff_obj) { + SFF_ERR("wb_plat_kobject_create sff error!\n"); + return -ENOMEM; + } + + g_sff_obj->index = 0; + if (sysfs_create_group(&g_sff_obj->kobj, &sff_xcvr_attr_group) != 0) { + wb_plat_kobject_delete(&g_sff_obj); + SFF_ERR("create sff dir attrs error!\n"); + return -EBADRQC; + } + SFF_DBG("wb_plat_kobject_create sff directory and attribute success.\n"); + return 0; +} + +static void sff_xcvr_remove(void) +{ + if (g_sff_obj) { + sysfs_remove_group(&g_sff_obj->kobj, &sff_xcvr_attr_group); + wb_plat_kobject_delete(&g_sff_obj); + SFF_DBG("delete sff root success\n"); + } + + return; +} + +static int wb_sff_init(void) +{ + int ret; + + SFF_INFO("wb_sff_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = sff_xcvr_create(); + if (ret < 0) { + goto sff_root_error; + } + + ret = sff_sub_create(); + if (ret < 0) { + goto sff_sub_error; + } + SFF_INFO("wb_sff_init ok.\n"); + return 0; + +sff_sub_error: + sff_xcvr_remove(); +sff_root_error: + return ret; +} + +static void wb_sff_exit(void) +{ + sff_sub_remove(); + sff_xcvr_remove(); + SFF_INFO("wb_sff_exit ok.\n"); + return ; +} + +module_init(wb_sff_init); +module_exit(wb_sff_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("sff sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_slot.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_slot.c new file mode 100644 index 000000000000..97539a4c24cc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_slot.c @@ -0,0 +1,667 @@ +/* + * plat_slot.c + * Original Author: support 2020-02-17 + * + * This module create sff kobjects and attributes in /sys/wb_plat/slot + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define SLOT_INFO(fmt, args...) LOG_INFO("slot: ", fmt, ##args) +#define SLOT_ERR(fmt, args...) LOG_ERR("slot: ", fmt, ##args) +#define SLOT_DBG(fmt, args...) LOG_DBG("slot: ", fmt, ##args) + +struct slot_temp_obj_t{ + struct switch_obj *obj; +}; + +struct slot_in_obj_t{ + struct switch_obj *obj; +}; + +struct slot_obj_t{ + unsigned int temp_number; + unsigned int in_number; + struct slot_temp_obj_t *temp; + struct slot_in_obj_t *in; + struct switch_obj *obj; +}; + +struct slot_t{ + unsigned int slot_number; + struct slot_obj_t *slot; +}; + +static int g_loglevel = 0; +static struct slot_t g_slot; +static struct switch_obj *g_slot_obj = NULL; +static struct switch_drivers_t *g_drv = NULL; + +static ssize_t slot_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_slot.slot_number); +} + +static ssize_t slot_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int index; + + index = obj->index; + SLOT_DBG("slot_temp_number_show,slot index:%d\n",index); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_slot.slot[index-1].temp_number); +} + +static ssize_t slot_in_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int index; + + index = obj->index; + SLOT_DBG("slot_in_number_show,slot index:%d\n",index); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_slot.slot[index-1].in_number); +} + +static ssize_t slot_present_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + int ret; + + slot_index = obj->index; + SLOT_DBG("slot_present_status_show, slot index:%d\n",slot_index); + check_p(g_drv); + check_p(g_drv->get_slot_present_status); + + ret = g_drv->get_slot_present_status(slot_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t slot_voltage_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, in_index; + int ret; + struct switch_obj *p_obj; + struct switch_device_attribute *in_attr; + + check_p(g_drv); + check_p(g_drv->get_voltage_info); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + slot_index = p_obj->index; + in_index = obj->index; + + in_attr = to_switch_device_attr(attr); + check_p(in_attr); + SLOT_DBG("slot_voltage_show, slot index:0x%x, temp index:0x%x, temp type:0x%x\n",slot_index, in_index, in_attr->type); + ret = g_drv->get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, in_index, in_attr->type, buf); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_temp_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + struct switch_device_attribute *temp_attr; + + check_p(g_drv); + check_p(g_drv->get_temp_info); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + slot_index = p_obj->index; + temp_index = obj->index; + + temp_attr = to_switch_device_attr(attr); + check_p(temp_attr); + SLOT_DBG("slot_temp_show, slot index:0x%x, temp index:0x%x, temp type:0x%x\n",slot_index, temp_index, temp_attr->type); + ret = g_drv->get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, temp_attr->type, buf); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return ret; +} + +/************************************slot dir and attrs*******************************************/ +static struct switch_attribute slot_number_att = __ATTR(num_slots, S_IRUGO, slot_number_show, NULL); + +static struct attribute *slot_dir_attrs[] = { + &slot_number_att.attr, + NULL, +}; + +static struct attribute_group slot_root_attr_group = { + .attrs = slot_dir_attrs, +}; + +/*******************************slot1 slot2 dir and attrs*******************************************/ +static struct switch_attribute num_temp_sensors_att = __ATTR(num_temp_sensors, S_IRUGO, slot_temp_number_show, NULL); +static struct switch_attribute num_in_sensors_att = __ATTR(num_in_sensors, S_IRUGO, slot_in_number_show, NULL); +static struct switch_attribute slot_present_status_att = __ATTR(present, S_IRUGO, slot_present_status_show, NULL); + +static struct attribute *slot_attrs[] = { + &num_temp_sensors_att.attr, + &num_in_sensors_att.attr, + &slot_present_status_att.attr, + NULL, +}; + +static struct attribute_group slot_attr_group = { + .attrs = slot_attrs, +}; + +/*******************************temp dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(temp_alias, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_ALIAS); +static SWITCH_DEVICE_ATTR(temp_type, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_TYPE); +static SWITCH_DEVICE_ATTR(temp_max, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_MAX); +static SWITCH_DEVICE_ATTR(temp_max_hyst, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_MAX_HYST); +static SWITCH_DEVICE_ATTR(temp_min, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_MIN); +static SWITCH_DEVICE_ATTR(temp_input, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_INPUT); + +static struct attribute *temp_attrs[] = { + &switch_dev_attr_temp_alias.switch_attr.attr, + &switch_dev_attr_temp_type.switch_attr.attr, + &switch_dev_attr_temp_max.switch_attr.attr, + &switch_dev_attr_temp_max_hyst.switch_attr.attr, + &switch_dev_attr_temp_min.switch_attr.attr, + &switch_dev_attr_temp_input.switch_attr.attr, + NULL, +}; + +static struct attribute_group temp_attr_group = { + .attrs = temp_attrs, +}; + +/*******************************Voltage dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(in_alias, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_ALIAS); +static SWITCH_DEVICE_ATTR(in_type, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_TYPE); +static SWITCH_DEVICE_ATTR(in_max, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_MAX); +static SWITCH_DEVICE_ATTR(in_crit, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_CRIT); +static SWITCH_DEVICE_ATTR(in_min, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_MIN); +static SWITCH_DEVICE_ATTR(in_input, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_INPUT); + +static struct attribute *in_attrs[] = { + &switch_dev_attr_in_alias.switch_attr.attr, + &switch_dev_attr_in_type.switch_attr.attr, + &switch_dev_attr_in_max.switch_attr.attr, + &switch_dev_attr_in_crit.switch_attr.attr, + &switch_dev_attr_in_min.switch_attr.attr, + &switch_dev_attr_in_input.switch_attr.attr, + NULL, +}; + +static struct attribute_group in_attr_group = { + .attrs = in_attrs, +}; + +static void slotindex_single_temp_remove_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int temp_index) +{ + + struct slot_temp_obj_t *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_slot->temp[temp_index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &temp_attr_group); + wb_plat_kobject_delete(&curr_temp->obj); + SLOT_DBG("delete slot:%d temp%d.\n", curr_slot->obj->index, temp_index); + } + return; +} + +static int slotindex_single_temp_create_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_temp_obj_t *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_slot->temp[temp_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "%s%d", TEMP_SYSFS_NAME, temp_index); + + curr_temp->obj = wb_plat_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_temp->obj) { + SLOT_ERR("create slot_index:%d, temp%d object error!\n", curr_slot->obj->index, temp_index); + return -EBADRQC; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &temp_attr_group) != 0) { + SLOT_ERR("create slot_index:%d, temp%d attrs error.\n", curr_slot->obj->index, temp_index); + wb_plat_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + SLOT_DBG("create slot_index:%d, temp%d ok.\n", curr_slot->obj->index, temp_index); + return 0; +} + +static void slotindex_temp_remove_kobj_and_attrs(struct slot_obj_t * curr_slot) +{ + int temp_index; + + for(temp_index = curr_slot->temp_number; temp_index > 0; temp_index--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, temp_index); + } + + if(curr_slot->temp) { + kfree(curr_slot->temp); + curr_slot->temp = NULL; + curr_slot->temp_number = 0; + } + return; +} + +static int slotindex_temp_create_kobj_and_attrs(struct slot_obj_t * curr_slot, int temp_num) +{ + int temp_index, i; + + curr_slot->temp_number = temp_num; + curr_slot->temp = kzalloc(sizeof(struct slot_temp_obj_t) * temp_num, GFP_KERNEL); + if (!curr_slot->temp) { + SLOT_ERR("kzalloc slot temp error, slot index = %d, temp number = %d.\n", curr_slot->obj->index, temp_num); + return -ENOMEM; + } + + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (slotindex_single_temp_create_kobj_and_attrs(curr_slot, temp_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = temp_index - 1; i > 0; i--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, i); + } + + if (curr_slot->temp) { + kfree(curr_slot->temp); + curr_slot->temp = NULL; + curr_slot->temp_number = 0; + } + return -EBADRQC; +} + +static void slotindex_single_in_remove_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int in_index) +{ + + struct slot_in_obj_t *curr_in; /* point to in1 in2...*/ + + curr_in = &curr_slot->in[in_index - 1]; + if (curr_in->obj) { + sysfs_remove_group(&curr_in->obj->kobj, &in_attr_group); + wb_plat_kobject_delete(&curr_in->obj); + SLOT_DBG("delete slot:%d in%d.\n", curr_slot->obj->index, in_index); + } + return; +} + +static int slotindex_single_in_create_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int in_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_in_obj_t *curr_in; /* point to in1 in2...*/ + + curr_in = &curr_slot->in[in_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "%s%d", VOLTAGE_SYSFS_NAME, in_index); + curr_in->obj = wb_plat_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_in->obj) { + SLOT_ERR("create slot_index:%d, in%d object error!\n", curr_slot->obj->index, in_index); + return -EBADRQC; + } + curr_in->obj->index = in_index; + if (sysfs_create_group(&curr_in->obj->kobj, &in_attr_group) != 0) { + SLOT_ERR("create slot_index:%d, in%d attrs error.\n", curr_slot->obj->index, in_index); + wb_plat_kobject_delete(&curr_in->obj); + return -EBADRQC; + } + SLOT_DBG("create slot_index:%d, in%d ok.\n", curr_slot->obj->index, in_index); + return 0; +} + +static void slotindex_in_remove_kobj_and_attrs(struct slot_obj_t * curr_slot) +{ + int in_index; + + for(in_index = curr_slot->in_number; in_index > 0; in_index--) { + slotindex_single_in_remove_kobj_and_attrs(curr_slot, in_index); + } + + if(curr_slot->in) { + kfree(curr_slot->in); + curr_slot->in = NULL; + curr_slot->in_number = 0; + } + return; +} + +static int slotindex_in_create_kobj_and_attrs(struct slot_obj_t * curr_slot, int in_num) +{ + int in_index, i; + + curr_slot->in_number = in_num; + curr_slot->in = kzalloc(sizeof(struct slot_in_obj_t) * in_num, GFP_KERNEL); + if (!curr_slot->in) { + SLOT_ERR("kzalloc slot Voltage error, slot index = %d, Voltage number = %d.\n", curr_slot->obj->index, in_num); + return -ENOMEM; + } + + for (in_index = 1; in_index <= in_num; in_index++) { + if (slotindex_single_in_create_kobj_and_attrs(curr_slot, in_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = in_index - 1; i > 0; i++) { + slotindex_single_in_remove_kobj_and_attrs(curr_slot, i); + } + + if (curr_slot->in) { + kfree(curr_slot->in); + curr_slot->in = NULL; + curr_slot->in_number = 0; + } + return -EBADRQC; +} + +static void slotindex_obj_remove_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int obj_id) +{ + switch (obj_id) { + case WB_MINOR_DEV_TEMP: + slotindex_temp_remove_kobj_and_attrs(curr_slot); + break; + case WB_MINOR_DEV_IN: + slotindex_in_remove_kobj_and_attrs(curr_slot); + break; + default: + SLOT_ERR("Unknow obj id:%d\n", obj_id); + } + return ; +} + +static int slotindex_obj_create_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int obj_id, int obj_num) +{ + int ret; + + switch (obj_id) { + case WB_MINOR_DEV_TEMP: + ret = slotindex_temp_create_kobj_and_attrs(curr_slot, obj_num); + break; + case WB_MINOR_DEV_IN: + ret = slotindex_in_create_kobj_and_attrs(curr_slot, obj_num); + break; + default: + SLOT_ERR("Unknow obj id:%d\n", obj_id); + ret = -EINVAL; + } + return ret; +} + +static void slot_child_obj_remove_by_id(unsigned int obj_id) +{ + int slot_num; + unsigned int slot_index; + struct slot_obj_t *curr_slot; /* point to slot1 slot2...*/ + + slot_num = g_slot.slot_number; + if (slot_num <= 0 || !g_slot.slot) { + SLOT_DBG("Warning:slot number = %d\n", slot_num); + return; + } + + for(slot_index = slot_num; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_obj_remove_kobj_and_attrs(curr_slot, obj_id); + } + return; +} + +static int slot_child_obj_create_by_id(unsigned int obj_id) +{ + int slot_num, obj_num; + unsigned int slot_index, i; + struct slot_obj_t *curr_slot; /* point to slot1 slot2...*/ + + check_p(g_drv->get_dev_number); + obj_num = g_drv->get_dev_number(WB_MAIN_DEV_SLOT,obj_id); + slot_num = g_slot.slot_number; + if (obj_num <= 0 || slot_num <= 0 || !g_slot.slot) { + SLOT_DBG("Warning:slot number = %d, object number:%d.obj_id:%d\n", slot_num, obj_num, obj_id); + return 0; + } + + for (slot_index = 1; slot_index <= slot_num; slot_index++) { + curr_slot = &g_slot.slot[slot_index - 1]; + if (slotindex_obj_create_kobj_and_attrs(curr_slot, obj_id, obj_num) != 0) { + goto error; + } + } + return 0; +error: + for(i = slot_index - 1; i > 0; i++) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_obj_remove_kobj_and_attrs(curr_slot, obj_id); + } + return -EBADRQC; +} + +static void slot_child_obj_remove(void) +{ + /* temp remove */ + slot_child_obj_remove_by_id(WB_MINOR_DEV_TEMP); + + /* in creat */ + slot_child_obj_remove_by_id(WB_MINOR_DEV_IN); + return; +} + +static int slot_child_obj_create(void) +{ + int ret; + + /* temp creat */ + ret = slot_child_obj_create_by_id(WB_MINOR_DEV_TEMP); + if (ret < 0) { + goto temp_err; + } + /* Voltage creat */ + ret = slot_child_obj_create_by_id(WB_MINOR_DEV_IN); + if(ret < 0) { + goto in_err; + } + return 0; +in_err: + slot_child_obj_remove_by_id(WB_MINOR_DEV_TEMP); +temp_err: + return ret; +} + +static void slot_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct slot_obj_t *curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + if (curr_slot->obj) { + sysfs_remove_group(&curr_slot->obj->kobj, &slot_attr_group); + wb_plat_kobject_delete(&curr_slot->obj); + SLOT_DBG("delete slot%d.\n", index); + } + return; +} + +static int slot_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_obj_t *curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + SLOT_DBG("create %s%d ...\n", SLOT_SYSFS_NAME, index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "%s%d", SLOT_SYSFS_NAME, index); + curr_slot->obj = wb_plat_kobject_create(name, parent); + if (!curr_slot->obj) { + SLOT_ERR("create slot%d object error!\n", index); + return -EBADRQC; + } + curr_slot->obj->index = index; + if (sysfs_create_group(&curr_slot->obj->kobj, &slot_attr_group) != 0) { + SLOT_ERR("create slot%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_slot->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%d ok.\n", index); + return 0; +} + +static int slot_sub_create_kobj_and_attrs(struct kobject *parent, int slot_num) +{ + unsigned int slot_index, i; + + g_slot.slot = kzalloc(sizeof(struct slot_obj_t) * slot_num, GFP_KERNEL); + if (!g_slot.slot) { + SLOT_ERR("kzalloc slot.slot error, slot number = %d.\n", slot_num); + return -ENOMEM; + } + + for (slot_index = 1; slot_index <= slot_num; slot_index++) { + if (slot_sub_single_create_kobj_and_attrs(parent, slot_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index - 1; i > 0; i--) { + slot_sub_single_remove_kobj_and_attrs(i); + } + if (g_slot.slot) { + kfree(g_slot.slot); + g_slot.slot = NULL; + } + return -EBADRQC; +} + +/* create slot1 slot2...dir and attrs */ +static int slot_sub_create(void) +{ + int ret, slot_num; + + check_p(g_drv->get_dev_number); + slot_num = g_drv->get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_NONE); + g_slot.slot_number = slot_num; + if (slot_num <= 0) { + SLOT_DBG("Warning:slot number = %d \n", slot_num); + return 0; + } + ret = slot_sub_create_kobj_and_attrs(&g_slot_obj->kobj, slot_num); + return ret; +} + +/** + * slot_sub_remove - delete slot1 slot2...dir and attrs + */ +static void slot_sub_remove(void) +{ + unsigned int slot_index; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + slot_sub_single_remove_kobj_and_attrs(slot_index); + } + kfree(g_slot.slot); + } + mem_clear(&g_slot, sizeof(struct slot_t)); + return ; +} + +/* create slot dir and num_slots attr */ +static int slot_root_create(void) +{ + g_slot_obj = wb_plat_kobject_create(SLOT_SYSFS_NAME, NULL); + if (!g_slot_obj) { + SLOT_ERR("wb_plat_kobject_create slot error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_slot_obj->kobj, &slot_root_attr_group) != 0) { + wb_plat_kobject_delete(&g_slot_obj); + SLOT_ERR("create slot dir attrs error!\n"); + return -EBADRQC; + } + SLOT_DBG("wb_plat_kobject_create slot directory and attribute success.\n"); + return 0; +} + +static void slot_root_remove(void) +{ + if (g_slot_obj) { + sysfs_remove_group(&g_slot_obj->kobj, &slot_root_attr_group); + wb_plat_kobject_delete(&g_slot_obj); + SLOT_DBG("delete slot root success\n"); + } + + return; +} + +static int wb_slot_init(void) +{ + int ret; + + SLOT_INFO("wb_slot_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = slot_root_create(); + if (ret < 0) { + goto slot_root_error; + } + + ret = slot_sub_create(); + if (ret < 0) { + goto slot_sub_error; + } + + ret = slot_child_obj_create(); + if (ret < 0) { + goto slot_child_obj_error; + } + + SLOT_INFO("wb_slot_init ok.\n"); + return 0; +slot_child_obj_error: + slot_sub_remove(); +slot_sub_error: + slot_root_remove(); +slot_root_error: + return ret; +} + +static void wb_slot_exit(void) +{ + slot_child_obj_remove(); + slot_sub_remove(); + slot_root_remove(); + SLOT_INFO("wb_slot_exit ok.\n"); + return ; +} + +module_init(wb_slot_init); +module_exit(wb_slot_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("slot sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_switch.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_switch.c new file mode 100644 index 000000000000..7c71fdb3bd62 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_switch.c @@ -0,0 +1,135 @@ +/* + * plat_switch.c + * Original Author: support 2020-02-17 + * + * This module create a kset in sysfs called /sys/wb_plat + * Then other switch kobjects are created and assigned to this kset, + * such as "board", "cpld", "fan", "psu", "sff", ... + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ +#include "./include/plat_switch.h" + +#define SWITCH_INFO(fmt, args...) LOG_INFO("switch: ", fmt, ##args) +#define SWITCH_ERR(fmt, args...) LOG_ERR("switch: ", fmt, ##args) +#define SWITCH_DBG(fmt, args...) LOG_DBG("switch: ", fmt, ##args) + +static int g_loglevel = 0; + +static ssize_t switch_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct switch_attribute *attribute; + struct switch_obj *device; + + attribute = to_switch_attr(attr); + device = to_switch_obj(kobj); + + if (!attribute->show) + return -ENOSYS; + + return attribute->show(device, attribute, buf); +} + +static ssize_t switch_attr_store(struct kobject *kobj, + struct attribute *attr, const char *buf, size_t len) +{ + struct switch_attribute *attribute; + struct switch_obj *obj; + + attribute = to_switch_attr(attr); + obj = to_switch_obj(kobj); + + if (!attribute->store) + return -ENOSYS; + + return attribute->store(obj, attribute, buf, len); +} + +static const struct sysfs_ops switch_sysfs_ops = { + .show = switch_attr_show, + .store = switch_attr_store, +}; + +static void switch_obj_release(struct kobject *kobj) +{ + struct switch_obj *obj; + + obj = to_switch_obj(kobj); + kfree(obj); +} + +static struct kobj_type switch_ktype = { + .sysfs_ops = &switch_sysfs_ops, + .release = switch_obj_release, + .default_attrs = NULL, +}; + +static struct kset *switch_kset; + +struct switch_obj *wb_plat_kobject_create(const char *name, struct kobject *parent) +{ + struct switch_obj *obj = NULL; + int ret = 0; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) { + SWITCH_DBG("wb_plat_kobject_create %s kzalloc error", name); + return NULL; + } + + obj->kobj.kset = switch_kset; + + ret = kobject_init_and_add(&obj->kobj, &switch_ktype, parent, "%s", name); + if (ret) { + kobject_put(&obj->kobj); + SWITCH_DBG("kobject_init_and_add %s error", name); + return NULL; + } + + return obj; +} + +void wb_plat_kobject_delete(struct switch_obj **obj) +{ + if (*obj) { + SWITCH_DBG("%s delete %s.\n", (*obj)->kobj.parent->name, (*obj)->kobj.name); + kobject_put(&((*obj)->kobj)); + *obj = NULL; + } +} + +static int __init switch_init(void) +{ + SWITCH_INFO("...\n"); + + switch_kset = kset_create_and_add("wb_plat", NULL, NULL); + if (!switch_kset) { + SWITCH_ERR("create switch_kset error.\n"); + return -ENOMEM; + } + + SWITCH_INFO("ok.\n"); + return 0; +} + +static void __exit switch_exit(void) +{ + if (switch_kset) { + kset_unregister(switch_kset); + } + + SWITCH_INFO("ok.\n"); +} + +module_init(switch_init); +module_exit(switch_exit); +EXPORT_SYMBOL(wb_plat_kobject_create); +EXPORT_SYMBOL(wb_plat_kobject_delete); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Switch driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common.h new file mode 100644 index 000000000000..9e4a4fae00c1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common.h @@ -0,0 +1,74 @@ +#ifndef __PLATFORM_COMMON_H__ +#define __PLATFORM_COMMON_H__ + +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef enum { + DBG_START, + DBG_VERBOSE, + DBG_KEY, + DBG_WARN, + DBG_ERROR, + DBG_END, +} dbg_level_t; + + typedef struct dfd_i2c_dev_s { + int bus; + int addr; + } dfd_i2c_dev_t; + +typedef struct dfd_dev_head_info_s { + uint8_t ver; + uint8_t flag; + uint8_t hw_ver; + uint8_t type; + int16_t tlv_len; +} dfd_dev_head_info_t; + +typedef struct dfd_dev_tlv_info_s { + uint8_t type; + uint8_t len; + uint8_t data[0]; +} dfd_dev_tlv_info_t; + +typedef enum dfd_dev_info_type_e { + DFD_DEV_INFO_TYPE_MAC = 1, + DFD_DEV_INFO_TYPE_NAME = 2, + DFD_DEV_INFO_TYPE_SN = 3, + DFD_DEV_INFO_TYPE_PWR_CONS = 4, + DFD_DEV_INFO_TYPE_HW_INFO = 5, + DFD_DEV_INFO_TYPE_DEV_TYPE = 6, +} dfd_dev_tlv_type_t; + +extern int debuglevel; +extern s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command); +extern s32 platform_i2c_smbus_read_i2c_block_data(const struct i2c_client *client, + u8 command, u8 length, u8 *values); +extern s32 platform_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command); + +#define DBG_DEBUG(fmt, arg...) do { \ + if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ + printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else if ( debuglevel >= DBG_ERROR ) { \ + printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else { } \ +} while (0) + +#define DBG_INFO(fmt, arg...) do { \ + if ( debuglevel > DBG_KEY) { \ + printk(KERN_INFO "[INFO]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +#define DBG_ERROR(fmt, arg...) do { \ + if ( debuglevel > DBG_START) { \ + printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common_module.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common_module.c new file mode 100644 index 000000000000..62e04b7db837 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common_module.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,152) +#include +#else +#include +#endif +#include +#include +#include +#include +#include "platform_common.h" +#include "dfd_tlveeprom.h" + +#define PLATFORM_I2C_RETRY_TIMES 3 + +#define DFD_TLVEEPROM_I2C_BUS (0) +#define DFD_TLVEEPROM_I2C_ADDR (0x56) +#define DFD_E2PROM_MAX_LEN (256) +#define DFD_CARDTYPE_EXT_TLVLEN (4) + +#define PLATFORM_CARDTYPE_RETRY_CNT (10) +#define PLATFORM_CARDTYPE_RETRY_TIMES (1000) + +int debuglevel = 0; +module_param(debuglevel, int, S_IRUGO | S_IWUSR); + +static int dfd_my_type = 0; +module_param(dfd_my_type, int, S_IRUGO | S_IWUSR); + +int g_common_debug_error = 0; +module_param(g_common_debug_error, int, S_IRUGO | S_IWUSR); + +int g_common_debug_verbose = 0; +module_param(g_common_debug_verbose, int, S_IRUGO | S_IWUSR); + +uint32_t dfd_my_type_i2c_bus = 0; +module_param(dfd_my_type_i2c_bus, int, S_IRUGO | S_IWUSR); + +uint32_t dfd_my_type_i2c_addr = 0; +module_param(dfd_my_type_i2c_addr, int, S_IRUGO | S_IWUSR); + +#define RUJIE_COMMON_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_common_debug_verbose) { \ + printk(KERN_ERR "[PLATFORM_COMMON][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define RUJIE_COMMON_DEBUG_ERROR(fmt, args...) do { \ + if (g_common_debug_error) { \ + printk(KERN_ERR "[PLATFORM_COMMON][ERROR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static int32_t dfd_i2c_read(char *dev, uint32_t addr, uint32_t offset_addr, unsigned char * +buf, int32_t size) +{ + struct file *fp; + struct i2c_client client; + int i ,j; + int rv; + s32 val_t; + + val_t = -1; + rv = 0; + fp = filp_open(dev, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + DBG_ERROR("i2c open fail.\n"); + RUJIE_COMMON_DEBUG_ERROR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = addr; + for (j = 0 ;j < size ;j++){ + for (i = 0; i < PLATFORM_I2C_RETRY_TIMES; i++) { + if ((val_t = i2c_smbus_read_byte_data(&client, (offset_addr + j)))< 0) { + DBG_DEBUG("read try(%d)time offset_addr:%x \n", i, offset_addr); + continue; + } else { + * (buf + j) = val_t; + break; + } + } + if (val_t < 0) { + rv = -1; + break; + } + } + filp_close(fp, NULL); + return rv; +} + +static int dfd_tlvinfo_get_cardtype(void) +{ + char i2c_path[16] = {0}; + int ret; + int cardtype; + u_int8_t eeprom[DFD_E2PROM_MAX_LEN]; + dfd_i2c_dev_t i2c_dev; + uint8_t buf[DFD_CARDTYPE_EXT_TLVLEN]; + uint8_t len; + dfd_tlv_type_t tlv_type; + + if (dfd_my_type_i2c_bus != 0) { + i2c_dev.bus = dfd_my_type_i2c_bus; + } else { + i2c_dev.bus = DFD_TLVEEPROM_I2C_BUS; + } + + if (dfd_my_type_i2c_addr != 0) { + i2c_dev.addr = dfd_my_type_i2c_addr; + } else { + i2c_dev.addr = DFD_TLVEEPROM_I2C_ADDR; + } + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_dev.bus); + RUJIE_COMMON_DEBUG_VERBOSE("Read device eeprom info:(dev:%s, addr:%02x).\n", i2c_path, i2c_dev.addr); + + ret = dfd_i2c_read(i2c_path, i2c_dev.addr, 0, eeprom, DFD_E2PROM_MAX_LEN); + if (ret != 0) { + DBG_ERROR("Read eeprom info error(dev: %s, addr: %02x).\n", i2c_path, i2c_dev.addr); + RUJIE_COMMON_DEBUG_ERROR("Read eeprom info error(dev: %s, addr: %02x).\n", i2c_path, i2c_dev.addr); + return ret; + } + + tlv_type.main_type = TLV_CODE_VENDOR_EXT; + tlv_type.ext_type = DFD_TLVINFO_EXT_TLV_TYPE_DEV_TYPE; + len = sizeof(buf); + mem_clear(buf, len); + ret = dfd_tlvinfo_get_e2prom_info(eeprom, DFD_E2PROM_MAX_LEN, &tlv_type, buf, &len); + if (ret) { + DBG_ERROR("dfd_tlvinfo_get_e2prom_info failed ret %d.\n", ret); + return -1; + } + for (ret = 0; ret < 4; ret++) { + DBG_DEBUG("buf 0x%02x.\n", buf[ret]); + } + + cardtype = ntohl(*((uint32_t *)buf)); + DBG_DEBUG("cardtype 0x%x.\n", cardtype); + return cardtype; +} + +static int __dfd_get_my_card_type(void) +{ + return dfd_tlvinfo_get_cardtype(); +} + +int dfd_get_my_card_type(void) +{ + int type; + int cnt; + + if (dfd_my_type != 0) { + DBG_DEBUG("my_type = 0x%x\r\n", dfd_my_type); + return dfd_my_type; + } + + cnt = PLATFORM_CARDTYPE_RETRY_CNT; + while (cnt--) { + type = __dfd_get_my_card_type(); + if (type < 0) { + RUJIE_COMMON_DEBUG_ERROR("__dfd_get_my_card_type fail cnt %d, ret %d.\n", cnt, type); + msleep(PLATFORM_CARDTYPE_RETRY_TIMES); + continue; + } + RUJIE_COMMON_DEBUG_VERBOSE("success to get type 0x%x.\n", type); + break; + } + + dfd_my_type = type; + return dfd_my_type; +} +EXPORT_SYMBOL(dfd_get_my_card_type); + +static int __init platform_common_init(void) +{ + int ret; + + RUJIE_COMMON_DEBUG_VERBOSE("Enter.\n"); + ret = dfd_get_my_card_type(); + if (ret <= 0) { + RUJIE_COMMON_DEBUG_ERROR("dfd_get_my_card_type failed, ret %d.\n", ret); + printk(KERN_ERR "Warning: Device type get failed, please check the TLV-EEPROM!\n"); + return -1; + } + + RUJIE_COMMON_DEBUG_VERBOSE("Leave success type 0x%x.\n", ret); + return 0; +} + +static void __exit platform_common_exit(void) +{ + RUJIE_COMMON_DEBUG_VERBOSE("Exit.\n"); +} + +module_init(platform_common_init); +module_exit(platform_common_exit); + +MODULE_DESCRIPTION("Platform Support"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/spi-bitbang-txrx.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/spi-bitbang-txrx.h new file mode 100644 index 000000000000..47bb9b898dfd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/spi-bitbang-txrx.h @@ -0,0 +1,107 @@ +/* + * Mix this utility code with some glue code to get one of several types of + * simple SPI master driver. Two do polled word-at-a-time I/O: + * + * - GPIO/parport bitbangers. Provide chipselect() and txrx_word[](), + * expanding the per-word routines from the inline templates below. + * + * - Drivers for controllers resembling bare shift registers. Provide + * chipselect() and txrx_word[](), with custom setup()/cleanup() methods + * that use your controller's clock and chipselect registers. + * + * Some hardware works well with requests at spi_transfer scope: + * + * - Drivers leveraging smarter hardware, with fifos or DMA; or for half + * duplex (MicroWire) controllers. Provide chipselect() and txrx_bufs(), + * and custom setup()/cleanup() methods. + */ + +/* + * The code that knows what GPIO pins do what should have declared four + * functions, ideally as inlines, before including this header: + * + * void setsck(struct spi_device *, int is_on); + * void setmosi(struct spi_device *, int is_on); + * int getmiso(struct spi_device *); + * void spidelay(unsigned); + * + * setsck()'s is_on parameter is a zero/nonzero boolean. + * + * setmosi()'s is_on parameter is a zero/nonzero boolean. + * + * getmiso() is required to return 0 or 1 only. Any other value is invalid + * and will result in improper operation. + * + * A non-inlined routine would call bitbang_txrx_*() routines. The + * main loop could easily compile down to a handful of instructions, + * especially if the delay is a NOP (to run at peak speed). + * + * Since this is software, the timings may not be exactly what your board's + * chips need ... there may be several reasons you'd need to tweak timings + * in these routines, not just to make it faster or slower to match a + * particular CPU clock rate. + */ + +static inline u32 +bitbang_txrx_be_cpha0(struct spi_device *spi, + unsigned nsecs, unsigned cpol, unsigned flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ + + u32 oldbit = (!(word & (1<<(bits-1)))) << 31; + /* clock starts at inactive polarity */ + for (word <<= (32 - bits); likely(bits); bits--) { + + /* setup MSB (to slave) on trailing edge */ + if ((flags & SPI_MASTER_NO_TX) == 0) { + if ((word & (1 << 31)) != oldbit) { + setmosi(spi, word & (1 << 31)); + oldbit = word & (1 << 31); + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, !cpol); + spidelay(nsecs); + + /* sample MSB (from slave) on leading edge */ + word <<= 1; + if ((flags & SPI_MASTER_NO_RX) == 0) + word |= getmiso(spi); + setsck(spi, cpol); + } + return word; +} + +static inline u32 +bitbang_txrx_be_cpha1(struct spi_device *spi, + unsigned nsecs, unsigned cpol, unsigned flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ + + u32 oldbit = (!(word & (1<<(bits-1)))) << 31; + /* clock starts at inactive polarity */ + for (word <<= (32 - bits); likely(bits); bits--) { + + /* setup MSB (to slave) on leading edge */ + setsck(spi, !cpol); + if ((flags & SPI_MASTER_NO_TX) == 0) { + if ((word & (1 << 31)) != oldbit) { + setmosi(spi, word & (1 << 31)); + oldbit = word & (1 << 31); + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, cpol); + spidelay(nsecs); + + /* sample MSB (from slave) on trailing edge */ + word <<= 1; + if ((flags & SPI_MASTER_NO_RX) == 0) + word |= getmiso(spi); + } + return word; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_eeprom_93xx46.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_eeprom_93xx46.c new file mode 100644 index 000000000000..2ba7e7912ed5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_eeprom_93xx46.c @@ -0,0 +1,558 @@ +/* + * Driver for 93xx46 EEPROMs + * + * (C) 2011 DENX Software Engineering, Anatolij Gustschin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define OP_START 0x4 +#define OP_WRITE (OP_START | 0x1) +#define OP_READ (OP_START | 0x2) +#define ADDR_EWDS 0x00 +#define ADDR_ERAL 0x20 +#define ADDR_EWEN 0x30 + +static int g_wb_eeprom_93xx46_debug = 0; + +module_param(g_wb_eeprom_93xx46_debug, int, S_IRUGO | S_IWUSR); + +#define SPI_93xx46_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_eeprom_93xx46_debug) { \ + printk(KERN_INFO "[EEPROM-93xx46][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct eeprom_93xx46_devtype_data { + unsigned int quirks; +}; + +static const struct eeprom_93xx46_devtype_data atmel_at93c46d_data = { + .quirks = EEPROM_93XX46_QUIRK_SINGLE_WORD_READ | + EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH, +}; + +struct eeprom_93xx46_dev { + struct spi_device *spi; + struct eeprom_93xx46_platform_data *pdata; + struct mutex lock; + struct nvmem_config nvmem_config; + struct nvmem_device *nvmem; + int addrlen; + int size; +}; + +static inline bool has_quirk_single_word_read(struct eeprom_93xx46_dev *edev) +{ + return edev->pdata->quirks & EEPROM_93XX46_QUIRK_SINGLE_WORD_READ; +} + +static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev) +{ + return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; +} + +static int eeprom_93xx46_read(void *priv, unsigned int off, + void *val, size_t count) +{ + struct eeprom_93xx46_dev *edev = priv; + char *buf = val; + int err = 0; + + if (unlikely(off >= edev->size)) + return 0; + if ((off + count) > edev->size) + count = edev->size - off; + if (unlikely(!count)) + return count; + + mutex_lock(&edev->lock); + + if (edev->pdata->prepare) + edev->pdata->prepare(edev); + + while (count) { + struct spi_message m; + struct spi_transfer t[2] = { { 0 } }; + u16 cmd_addr = OP_READ << edev->addrlen; + size_t nbytes = count; + int bits; + int data_bit; + + if (edev->addrlen == 7) { + cmd_addr |= off & 0x7f; + bits = 10; + data_bit = 8; + if (has_quirk_single_word_read(edev)) + nbytes = 1; + } else { + cmd_addr |= (off >> 1) & 0x3f; + bits = 9; + data_bit = 16; + if (has_quirk_single_word_read(edev)) + nbytes = 2; + } + + dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n", + cmd_addr, edev->spi->max_speed_hz); + + spi_message_init(&m); + + t[0].tx_buf = (char *)&cmd_addr; + t[0].len = 2; + t[0].bits_per_word = bits; + spi_message_add_tail(&t[0], &m); + + t[1].rx_buf = buf; + t[1].len = nbytes; + t[1].bits_per_word = data_bit; + spi_message_add_tail(&t[1], &m); + + err = spi_sync(edev->spi, &m); + /* have to wait at least Tcsl ns */ + ndelay(250); + + if (err) { + dev_err(&edev->spi->dev, "read %zu bytes at %d: err. %d\n", + nbytes, (int)off, err); + break; + } + + buf += nbytes; + off += nbytes; + count -= nbytes; + } + + if (edev->pdata->finish) + edev->pdata->finish(edev); + + mutex_unlock(&edev->lock); + + return err; +} + +static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on) +{ + struct spi_message m; + struct spi_transfer t; + int bits, ret; + u16 cmd_addr; + + cmd_addr = OP_START << edev->addrlen; + if (edev->addrlen == 7) { + cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS) << 1; + bits = 10; + } else { + cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS); + bits = 9; + } + + if (has_quirk_instruction_length(edev)) { + cmd_addr <<= 2; + bits += 2; + } + + dev_dbg(&edev->spi->dev, "ew%s cmd 0x%04x, %d bits\n", + is_on ? "en" : "ds", cmd_addr, bits); + + spi_message_init(&m); + mem_clear(&t, sizeof(t)); + + t.tx_buf = &cmd_addr; + t.len = 2; + t.bits_per_word = bits; + spi_message_add_tail(&t, &m); + + mutex_lock(&edev->lock); + + if (edev->pdata->prepare) + edev->pdata->prepare(edev); + + ret = spi_sync(edev->spi, &m); + /* have to wait at least Tcsl ns */ + ndelay(250); + if (ret) + dev_err(&edev->spi->dev, "erase/write %sable error %d\n", + is_on ? "en" : "dis", ret); + + if (edev->pdata->finish) + edev->pdata->finish(edev); + + mutex_unlock(&edev->lock); + return ret; +} + +static ssize_t +eeprom_93xx46_write_word(struct eeprom_93xx46_dev *edev, + char *buf, unsigned off) +{ + struct spi_message m; + struct spi_transfer t[2]; + int bits, data_len, ret; + u16 cmd_addr; + int data_bit; + + cmd_addr = OP_WRITE << edev->addrlen; + + if (edev->addrlen == 7) { + cmd_addr |= off & 0x7f; + bits = 10; + data_len = 1; + data_bit = 8; + } else { + cmd_addr |= (off >> 1) & 0x3f; + bits = 9; + data_len = 2; + data_bit = 16; + } + + dev_dbg(&edev->spi->dev, "write cmd 0x%x\n", cmd_addr); + + spi_message_init(&m); + mem_clear(t, sizeof(t)); + + t[0].tx_buf = (char *)&cmd_addr; + t[0].len = 2; + t[0].bits_per_word = bits; + spi_message_add_tail(&t[0], &m); + + t[1].tx_buf = buf; + t[1].len = data_len; + t[1].bits_per_word = data_bit; + spi_message_add_tail(&t[1], &m); + + ret = spi_sync(edev->spi, &m); + /* have to wait program cycle time Twc ms */ + mdelay(6); + return ret; +} + +static int eeprom_93xx46_write(void *priv, unsigned int off, + void *val, size_t count) +{ + struct eeprom_93xx46_dev *edev = priv; + char *buf = val; + int i, ret, step = 1; + + if (unlikely(off >= edev->size)) + return -EFBIG; + if ((off + count) > edev->size) + count = edev->size - off; + if (unlikely(!count)) + return count; + + /* only write even number of bytes on 16-bit devices */ + if (edev->addrlen == 6) { + step = 2; + count &= ~1; + } + + /* erase/write enable */ + ret = eeprom_93xx46_ew(edev, 1); + if (ret) + return ret; + + mutex_lock(&edev->lock); + + if (edev->pdata->prepare) + edev->pdata->prepare(edev); + + for (i = 0; i < count; i += step) { + ret = eeprom_93xx46_write_word(edev, &buf[i], off + i); + if (ret) { + dev_err(&edev->spi->dev, "write failed at %d: %d\n", + (int)off + i, ret); + break; + } + } + + if (edev->pdata->finish) + edev->pdata->finish(edev); + + mutex_unlock(&edev->lock); + + /* erase/write disable */ + eeprom_93xx46_ew(edev, 0); + return ret; +} + +static int eeprom_93xx46_eral(struct eeprom_93xx46_dev *edev) +{ + struct eeprom_93xx46_platform_data *pd = edev->pdata; + struct spi_message m; + struct spi_transfer t; + int bits, ret; + u16 cmd_addr; + + cmd_addr = OP_START << edev->addrlen; + if (edev->addrlen == 7) { + cmd_addr |= ADDR_ERAL << 1; + bits = 10; + } else { + cmd_addr |= ADDR_ERAL; + bits = 9; + } + + if (has_quirk_instruction_length(edev)) { + cmd_addr <<= 2; + bits += 2; + } + + dev_dbg(&edev->spi->dev, "eral cmd 0x%04x, %d bits\n", cmd_addr, bits); + + spi_message_init(&m); + mem_clear(&t, sizeof(t)); + + t.tx_buf = &cmd_addr; + t.len = 2; + t.bits_per_word = bits; + spi_message_add_tail(&t, &m); + + mutex_lock(&edev->lock); + + if (edev->pdata->prepare) + edev->pdata->prepare(edev); + + ret = spi_sync(edev->spi, &m); + if (ret) + dev_err(&edev->spi->dev, "erase error %d\n", ret); + /* have to wait erase cycle time Tec ms */ + mdelay(6); + + if (pd->finish) + pd->finish(edev); + + mutex_unlock(&edev->lock); + return ret; +} + +static ssize_t eeprom_93xx46_store_erase(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct eeprom_93xx46_dev *edev = dev_get_drvdata(dev); + int erase = 0, ret; + + sscanf(buf, "%d", &erase); + if (erase) { + ret = eeprom_93xx46_ew(edev, 1); + if (ret) + return ret; + ret = eeprom_93xx46_eral(edev); + if (ret) + return ret; + ret = eeprom_93xx46_ew(edev, 0); + if (ret) + return ret; + } + return count; +} +static DEVICE_ATTR(erase, S_IWUSR, NULL, eeprom_93xx46_store_erase); + +static void select_assert(void *context) +{ + struct eeprom_93xx46_dev *edev = context; + + gpiod_set_value_cansleep(edev->pdata->select, 1); +} + +static void select_deassert(void *context) +{ + struct eeprom_93xx46_dev *edev = context; + + gpiod_set_value_cansleep(edev->pdata->select, 0); +} + +static const struct of_device_id eeprom_93xx46_of_table[] = { + { .compatible = "eeprom-93xx46", }, + { .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, }, + {} +}; +MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table); + +static int eeprom_93xx46_probe_dt(struct spi_device *spi) +{ + const struct of_device_id *of_id = + of_match_device(eeprom_93xx46_of_table, &spi->dev); + struct device_node *np = spi->dev.of_node; + struct eeprom_93xx46_platform_data *pd; + u32 tmp; + int gpio; + enum of_gpio_flags of_flags; + int ret; + + pd = devm_kzalloc(&spi->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; + + ret = of_property_read_u32(np, "data-size", &tmp); + if (ret < 0) { + dev_err(&spi->dev, "data-size property not found\n"); + return ret; + } + + if (tmp == 8) { + pd->flags |= EE_ADDR8; + } else if (tmp == 16) { + pd->flags |= EE_ADDR16; + } else { + dev_err(&spi->dev, "invalid data-size (%d)\n", tmp); + return -EINVAL; + } + + if (of_property_read_bool(np, "read-only")) + pd->flags |= EE_READONLY; + + gpio = of_get_named_gpio_flags(np, "select-gpios", 0, &of_flags); + if (gpio_is_valid(gpio)) { + unsigned long flags = + of_flags == OF_GPIO_ACTIVE_LOW ? GPIOF_ACTIVE_LOW : 0; + + ret = devm_gpio_request_one(&spi->dev, gpio, flags, + "eeprom_93xx46_select"); + if (ret) + return ret; + + pd->select = gpio_to_desc(gpio); + pd->prepare = select_assert; + pd->finish = select_deassert; + + gpiod_direction_output(pd->select, 0); + } + + if (of_id) { + if (of_id->data) { + const struct eeprom_93xx46_devtype_data *data = of_id->data; + + pd->quirks = data->quirks; + } + } + + spi->dev.platform_data = pd; + + return 0; +} + +static int eeprom_93xx46_probe(struct spi_device *spi) +{ + struct eeprom_93xx46_platform_data *pd; + struct eeprom_93xx46_dev *edev; + int err; + + if (spi->dev.of_node) { + err = eeprom_93xx46_probe_dt(spi); + if (err < 0) + return err; + } + + pd = spi->dev.platform_data; + if (!pd) { + dev_err(&spi->dev, "missing platform data\n"); + return -ENODEV; + } + + edev = kzalloc(sizeof(*edev), GFP_KERNEL); + if (!edev) + return -ENOMEM; + + if (pd->flags & EE_ADDR8) + edev->addrlen = 7; + else if (pd->flags & EE_ADDR16) + edev->addrlen = 6; + else { + dev_err(&spi->dev, "unspecified address type\n"); + err = -EINVAL; + goto fail; + } + + mutex_init(&edev->lock); + + edev->spi = spi; + edev->pdata = pd; + + edev->size = 128; + edev->nvmem_config.name = dev_name(&spi->dev); + edev->nvmem_config.dev = &spi->dev; + edev->nvmem_config.read_only = pd->flags & EE_READONLY; + edev->nvmem_config.root_only = true; + edev->nvmem_config.owner = THIS_MODULE; + edev->nvmem_config.compat = true; + edev->nvmem_config.base_dev = &spi->dev; + edev->nvmem_config.reg_read = eeprom_93xx46_read; + edev->nvmem_config.reg_write = eeprom_93xx46_write; + edev->nvmem_config.priv = edev; + edev->nvmem_config.stride = 4; + edev->nvmem_config.word_size = 1; + edev->nvmem_config.size = edev->size; + + edev->nvmem = nvmem_register(&edev->nvmem_config); + if (IS_ERR(edev->nvmem)) { + err = PTR_ERR(edev->nvmem); + goto fail; + } + + if (g_wb_eeprom_93xx46_debug) { + dev_info(&spi->dev, "%d-bit eeprom %s\n", + (pd->flags & EE_ADDR8) ? 8 : 16, + (pd->flags & EE_READONLY) ? "(readonly)" : ""); + } + + if (!(pd->flags & EE_READONLY)) { + if (device_create_file(&spi->dev, &dev_attr_erase)) + dev_err(&spi->dev, "can't create erase interface\n"); + } + + spi_set_drvdata(spi, edev); + return 0; +fail: + kfree(edev); + return err; +} + +static int eeprom_93xx46_remove(struct spi_device *spi) +{ + struct eeprom_93xx46_dev *edev = spi_get_drvdata(spi); + + nvmem_unregister(edev->nvmem); + + if (!(edev->pdata->flags & EE_READONLY)) + device_remove_file(&spi->dev, &dev_attr_erase); + + kfree(edev); + return 0; +} + +static struct spi_driver wb_eeprom_93xx46_driver = { + .driver = { + .name = "wb_93xx46", + .of_match_table = of_match_ptr(eeprom_93xx46_of_table), + }, + .probe = eeprom_93xx46_probe, + .remove = eeprom_93xx46_remove, +}; + +module_spi_driver(wb_eeprom_93xx46_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs"); +MODULE_AUTHOR("support"); +MODULE_ALIAS("spi:93xx46"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_i2c_bus_drv.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_i2c_bus_drv.c new file mode 100644 index 000000000000..c1c4544db1d9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_i2c_bus_drv.c @@ -0,0 +1,1103 @@ +/* + * fpga_i2c_bus_drv.c + * ko to create fpga i2c adapter + */ +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) +#include +#endif +#include +#include +#include +#include +#include +#include +#include "fpga_i2c.h" + +#include +#include + +#define DRV_NAME "wb-fpga-i2c" +#define DRV_VERSION "1.0" +#define DTS_NO_CFG_FLAG (0) + +extern int i2c_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); +extern int i2c_device_func_read(const char *path, uint32_t pos, uint8_t *val, size_t size); +extern int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); + +#define FPGA_I2C_STRETCH_TIMEOUT (0x01) +#define FPGA_I2C_DEADLOCK_FAILED (0x02) +#define FPGA_I2C_SLAVE_NO_RESPOND (0x03) +#define FPGA_I2C_STA_FAIL (0x01) +#define FPGA_I2C_STA_BUSY (0x02) +#define FPGA_I2C_CTL_BG (0x01 << 1) +#define FPGA_I2C_CTL_NO_REG (0x01 << 2) +#define FPGA_I2C_CTL_RD (0x01) +#define FPGA_I2C_CTL_WR (0x00) +#define I2C_READ_MSG_NUM (0x02) +#define I2C_WRITE_MSG_NUM (0x01) +#define FPGA_REG_WIDTH (4) + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) + +int g_wb_fpga_i2c_debug = 0; +int g_wb_fpga_i2c_error = 0; + +module_param(g_wb_fpga_i2c_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_fpga_i2c_error, int, S_IRUGO | S_IWUSR); + +#define FPGA_I2C_VERBOSE(fmt, args...) do { \ + if (g_wb_fpga_i2c_debug) { \ + printk(KERN_INFO "[FPFA_I2C_BUS][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_I2C_ERROR(fmt, args...) do { \ + if (g_wb_fpga_i2c_error) { \ + printk(KERN_ERR "[FPFA_I2C_BUS][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static int fpga_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + FPGA_I2C_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + FPGA_I2C_ERROR("kernel_read failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int fpga_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + FPGA_I2C_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + FPGA_I2C_ERROR("kernel_write failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int fpga_device_write(fpga_i2c_dev_t *fpga_i2c, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (fpga_i2c->i2c_func_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = fpga_file_write(fpga_i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; + default: + FPGA_I2C_ERROR("err func_mode, write failed.\n"); + return -EINVAL; + } + return ret; + +} + +static int fpga_device_read(fpga_i2c_dev_t *fpga_i2c, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (fpga_i2c->i2c_func_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_read(fpga_i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = fpga_file_read(fpga_i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_read(fpga_i2c->dev_name, pos, val, size); + break; + default: + FPGA_I2C_ERROR("err func_mode, read failed.\n"); + return -EINVAL; + } + + return ret; +} + +static int little_endian_dword_to_buf(uint8_t *buf, int len, uint32_t dword) +{ + uint8_t tmp_buf[FPGA_REG_WIDTH]; + + if (len < 4) { + FPGA_I2C_ERROR("Not enough buf, dword to buf: len[%d], dword[0x%x]\n", len, dword); + return -1; + } + + mem_clear(tmp_buf, sizeof(tmp_buf)); + tmp_buf[0] = dword & 0xff; + tmp_buf[1] = (dword >> 8) & 0xff; + tmp_buf[2] = (dword >> 16) & 0xff; + tmp_buf[3] = (dword >> 24) & 0xff; + + memcpy(buf, tmp_buf, sizeof(tmp_buf)); + + return 0; +} + +static int little_endian_buf_to_dword(uint8_t *buf, int len, uint32_t *dword) +{ + int i; + uint32_t dword_tmp; + + if (len != FPGA_REG_WIDTH) { + FPGA_I2C_ERROR("buf length %d error, can't convert to dowrd.\n", len); + return -1; + } + dword_tmp = 0; + for (i = 0; i < FPGA_REG_WIDTH; i++) { + dword_tmp |= (buf[i] << (i * 8)); + } + *dword = dword_tmp; + return 0; +} + +static int fpga_reg_write(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t val) +{ + int ret; + + ret = fpga_device_write(fpga_i2c, addr, &val, sizeof(uint8_t)); + if (ret < 0) { + FPGA_I2C_ERROR("fpga reg write failed, dev name:%s, offset:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, val); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga reg write success, dev name:%s, offset:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, val); + return 0; +} + +static int fpga_reg_read(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t *val) +{ + int ret; + + ret = fpga_device_read(fpga_i2c, addr, val, sizeof(uint8_t)); + if (ret < 0) { + FPGA_I2C_ERROR("fpga reg read failed, dev name:%s, offset:0x%x\n", + fpga_i2c->dev_name, addr); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga reg read success, dev name:%s, offset:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, *val); + return 0; +} + +static int fpga_data_write(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + + ret = fpga_device_write(fpga_i2c, addr, val, size); + if (ret < 0) { + FPGA_I2C_ERROR("fpga data write failed, dev name:%s, offset:0x%x, size:%lu.\n", + fpga_i2c->dev_name, addr, size); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga data write success, dev name:%s, offset:0x%x, size:%lu.\n", + fpga_i2c->dev_name, addr, size); + return 0; +} + +static int fpga_data_read(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + + ret = fpga_device_read(fpga_i2c, addr, val, size); + if (ret < 0) { + FPGA_I2C_ERROR("fpga data read failed, dev name:%s, offset:0x%x, size:%lu.\n", + fpga_i2c->dev_name, addr, size); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga data read success, dev name:%s, offset:0x%x, size:%lu.\n", + fpga_i2c->dev_name, addr, size); + return 0; +} + +static int fpga_reg_write_32(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint32_t val) +{ + int ret; + uint8_t buf[FPGA_REG_WIDTH]; + + mem_clear(buf, sizeof(buf)); + little_endian_dword_to_buf(buf, sizeof(buf), val); + ret = fpga_device_write(fpga_i2c, addr, buf, sizeof(buf)); + if (ret < 0) { + FPGA_I2C_ERROR("fpga reg write failed, dev name: %s, offset: 0x%x, value: 0x%x.\n", + fpga_i2c->dev_name, addr, val); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga reg write success, dev name: %s, offset: 0x%x, value: 0x%x.\n", + fpga_i2c->dev_name, addr, val); + return 0; +} + +static int fpga_reg_read_32(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint32_t *val) +{ + int ret; + uint8_t buf[FPGA_REG_WIDTH]; + + mem_clear(buf, sizeof(buf)); + ret = fpga_device_read(fpga_i2c, addr, buf, sizeof(buf)); + if (ret < 0) { + FPGA_I2C_ERROR("fpga reg read failed, dev name: %s, offset: 0x%x, ret: %d\n", + fpga_i2c->dev_name, addr, ret); + return -EIO; + } + little_endian_buf_to_dword(buf, sizeof(buf), val); + FPGA_I2C_VERBOSE("fpga reg read success, dev name: %s, offset: 0x%x, value: 0x%x.\n", + fpga_i2c->dev_name, addr, *val); + return 0; +} + +static int fpga_i2c_is_busy(fpga_i2c_dev_t *fpga_i2c) +{ + uint8_t val; + int ret; + fpga_i2c_reg_t *reg; + + reg = &fpga_i2c->reg; + ret = fpga_reg_read(fpga_i2c, reg->i2c_status, &val); + if (ret < 0 ) { + FPGA_I2C_ERROR("read fpga i2c status reg failed, reg addr:0x%x, ret:%d.\n", + reg->i2c_status, ret); + return 1; + } + if (val & FPGA_I2C_STA_BUSY) { + FPGA_I2C_ERROR("fpga i2c status busy, reg addr:0x%x, value:0x%x.\n", + reg->i2c_status, val); + return 1; + } else { + return 0; + } +} + +static int fpga_i2c_wait(fpga_i2c_dev_t *fpga_i2c) +{ + int retry_cnt; + + retry_cnt = FPGA_I2C_XFER_TIME_OUT/FPGA_I2C_SLEEP_TIME; + while (retry_cnt--) { + if (fpga_i2c_is_busy(fpga_i2c)) { + usleep_range(FPGA_I2C_SLEEP_TIME, FPGA_I2C_SLEEP_TIME + 1); + } else { + return 0; + } + } + + return -EBUSY; +} + +static int fpga_i2c_check_status(fpga_i2c_dev_t *fpga_i2c) +{ + uint8_t data; + int ret; + fpga_i2c_reg_t *reg; + + reg = &fpga_i2c->reg; + + ret = fpga_reg_read(fpga_i2c, reg->i2c_status, &data); + if (ret) { + FPGA_I2C_ERROR("read fpga i2c status reg failed, reg addr:0x%x, ret:%d.\n", + reg->i2c_status, ret); + return ret; + } + + if (data & FPGA_I2C_STA_FAIL) { + FPGA_I2C_ERROR("fpga i2c status error, reg addr:0x%x, value:%d.\n", + reg->i2c_status, data); + + /* read i2c_err_vec to confirm err type*/ + if (reg->i2c_err_vec != DTS_NO_CFG_FLAG) { + /* read i2c_err_vec reg */ + ret = fpga_reg_read(fpga_i2c, reg->i2c_err_vec, &data); + if (ret) { + FPGA_I2C_ERROR("read fpga i2c err vec reg failed, reg addr:0x%x, ret:%d.\n", + reg->i2c_err_vec, ret); + return ret; + } + FPGA_I2C_VERBOSE("get i2c err vec, reg addr:0x%x, read value:0x%x\n", reg->i2c_err_vec, data); + + /* match i2c_err_vec reg value and err type*/ + switch (data) { + case FPGA_I2C_STRETCH_TIMEOUT: + ret = -ETIMEDOUT; + break; + case FPGA_I2C_DEADLOCK_FAILED: + ret = -EDEADLK; + break; + case FPGA_I2C_SLAVE_NO_RESPOND: + ret = -ENXIO; + break; + default: + FPGA_I2C_ERROR("get i2c err vec value out of range, reg addr:0x%x, read value:0x%x\n", + reg->i2c_err_vec, data); + ret = -EREMOTEIO; + break; + } + return ret; + } else { + FPGA_I2C_VERBOSE("i2c err vec not config, fpga i2c status check return -1\n"); + return -EREMOTEIO; + } + } + return 0; +} + +static int fpga_i2c_do_work(fpga_i2c_dev_t *fpga_i2c, int i2c_addr, + unsigned char *data, uint32_t length, int is_read) +{ + int ret, i; + uint8_t op, i2c_reg_addr_len; + uint8_t *i2c_read_addr_buf; + fpga_i2c_reg_t *reg; + fpga_i2c_reg_addr_t *i2c_addr_desc; + + reg = &fpga_i2c->reg; + + ret = fpga_reg_write(fpga_i2c, reg->i2c_slave, i2c_addr); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c slave reg failed, reg addr:0x%x, value:0x%x, ret:%d.\n", + reg->i2c_slave, i2c_addr, ret); + goto exit; + } + + i2c_addr_desc = &fpga_i2c->i2c_addr_desc; + i2c_reg_addr_len = i2c_addr_desc->reg_addr_len; + i2c_read_addr_buf = &i2c_addr_desc->read_reg_addr[0]; + + if (i2c_reg_addr_len > 0 && i2c_reg_addr_len <= I2C_REG_MAX_WIDTH) { + ret = fpga_data_write(fpga_i2c, reg->i2c_reg, i2c_read_addr_buf, i2c_reg_addr_len); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c offset reg failed, fpga addr:0x%x, reg len:%d, ret:%d\n", + reg->i2c_reg, i2c_reg_addr_len, ret); + for (i = 0; i < i2c_reg_addr_len; i++) { + FPGA_I2C_ERROR("%02d : %02x\n", i, i2c_read_addr_buf[i]); + } + goto exit; + } + } + + ret = fpga_reg_write_32(fpga_i2c, reg->i2c_data_len, length); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c date len reg failed, reg addr:0x%x, value:0x%x, ret:%d.\n", + reg->i2c_data_len, length, ret); + goto exit; + } + + ret = fpga_reg_write(fpga_i2c, reg->i2c_reg_len, i2c_reg_addr_len); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c reg len reg failed, reg addr:0x%x, value:0x%x, ret:%d.\n", + reg->i2c_reg_len, i2c_reg_addr_len, ret); + goto exit; + } + + if (is_read) { + op = FPGA_I2C_CTL_RD | FPGA_I2C_CTL_BG; + } else { + + ret = fpga_data_write(fpga_i2c, reg->i2c_data_buf, data, length); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c date buf failed, reg addr:0x%x, write len:%d, ret:%d.\n", + reg->i2c_data_buf, length, ret); + goto exit; + } + op = FPGA_I2C_CTL_WR | FPGA_I2C_CTL_BG ; + } + + ret = fpga_reg_write(fpga_i2c, reg->i2c_ctrl, op); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c control reg failed, reg addr:0x%x, value:%d, ret:%d.\n", + reg->i2c_ctrl, op, ret); + goto exit; + } + + ret = fpga_i2c_wait(fpga_i2c); + if (ret) { + FPGA_I2C_ERROR("wait fpga i2c status timeout.\n"); + goto exit; + } + + ret = fpga_i2c_check_status(fpga_i2c); + if (ret) { + FPGA_I2C_ERROR("check fpga i2c status error.\n"); + goto exit; + } + + if (is_read) { + + ret = fpga_data_read(fpga_i2c, reg->i2c_data_buf, data, length); + if (ret) { + FPGA_I2C_ERROR("read fpga i2c data buf failed, reg addr:0x%x, read len:%d, ret:%d.\n", + reg->i2c_data_buf, length, ret); + goto exit; + } + } + +exit: + return ret; +} + +static int fpga_i2c_write(fpga_i2c_dev_t *fpga_i2c, int target, + u8 *data, int length, int i2c_msg_num) +{ + int ret, i; + fpga_i2c_reg_addr_t *i2c_addr_desc; + + if (i2c_msg_num == I2C_READ_MSG_NUM) { + + if (length > I2C_REG_MAX_WIDTH) { + FPGA_I2C_ERROR("read reg addr len %d, more than max length.\n", length); + return -EINVAL; + } + + i2c_addr_desc = &fpga_i2c->i2c_addr_desc; + for (i = 0; i < length; i++) { + i2c_addr_desc->read_reg_addr[i] = data[length -i -1]; + FPGA_I2C_VERBOSE("%02d : %02x\n", i, i2c_addr_desc->read_reg_addr[i]); + } + i2c_addr_desc->reg_addr_len = length; + ret = 0; + } else { + + ret = fpga_i2c_do_work(fpga_i2c, target, data, length, 0); + } + + return ret; +} + +/** + * fpga_i2c_read - receive data from the bus. + * @i2c: The struct fpga_i2c_dev_t. + * @target: Target address. + * @data: Pointer to the location to store the datae . + * @length: Length of the data. + * + * The address is sent over the bus, then the data is read. + * + * Returns 0 on success, otherwise a negative errno. + */ +static int fpga_i2c_read(fpga_i2c_dev_t *fpga_i2c, int target, + u8 *data, int length) +{ + int ret, offset_size; + int i, tmp_val; + fpga_i2c_reg_addr_t *i2c_addr_desc; + uint8_t i2c_reg_addr_len; + uint8_t *i2c_read_addr_buf; + + offset_size = 0; + i2c_addr_desc = &fpga_i2c->i2c_addr_desc; + i2c_reg_addr_len = i2c_addr_desc->reg_addr_len; + i2c_read_addr_buf = &i2c_addr_desc->read_reg_addr[0]; + + while (1) { + if (length <= fpga_i2c->reg.i2c_data_buf_len) { + return fpga_i2c_do_work(fpga_i2c, target, data + offset_size, length, 1); + } + + ret = fpga_i2c_do_work(fpga_i2c, target, data + offset_size, fpga_i2c->reg.i2c_data_buf_len, 1); + if (ret != 0) { + FPGA_I2C_ERROR("fpga_i2c_read failed, i2c addr:0x%x, offset:0x%x, ret:%d.\n", + target, offset_size, ret); + return ret; + } + + tmp_val = i2c_read_addr_buf[0]; + tmp_val += fpga_i2c->reg.i2c_data_buf_len; + if (tmp_val > 0xff) { + i2c_read_addr_buf[0] = tmp_val & 0xff; + for (i = 1; i < i2c_reg_addr_len; i++) { + if (i2c_read_addr_buf[i] == 0xff) { + i2c_read_addr_buf[i] = 0; + } else { + i2c_read_addr_buf[i]++; + break; + } + } + } else { + i2c_read_addr_buf[0] = tmp_val & 0xff; + } + offset_size += fpga_i2c->reg.i2c_data_buf_len; + length -= fpga_i2c->reg.i2c_data_buf_len; + } + + return ret; +} + +static void fpga_i2c_reset(fpga_i2c_dev_t *fpga_i2c) { + fpga_i2c_reset_cfg_t *reset_cfg; + uint32_t reset_addr; + + reset_cfg = &fpga_i2c->reset_cfg; + reset_addr = reset_cfg->reset_addr; + if (reset_cfg->reset_delay_b) { + usleep_range(reset_cfg->reset_delay_b, reset_cfg->reset_delay_b + 1); + } + + fpga_reg_write_32(fpga_i2c, reset_addr, reset_cfg->reset_on); + if (reset_cfg->reset_delay) { + usleep_range(reset_cfg->reset_delay, reset_cfg->reset_delay + 1); + } + + fpga_reg_write_32(fpga_i2c, reset_addr, reset_cfg->reset_off); + if (reset_cfg->reset_delay_a) { + usleep_range(reset_cfg->reset_delay_a, reset_cfg->reset_delay_a + 1); + } + + return; +} + +/** + * fpga_i2c_xfer - The driver's master_xfer function. + * @adap: Pointer to the i2c_adapter structure. + * @msgs: Pointer to the messages to be processed. + * @num: Length of the MSGS array. + * + * Returns the number of messages processed, or a negative errno on + * failure. + */ +static int fpga_i2c_adapter_init(fpga_i2c_dev_t *fpga_i2c) +{ + int ret; + fpga_i2c_reg_t *reg; + + reg = &fpga_i2c->reg; + + ret = 0; + ret += fpga_reg_write(fpga_i2c, reg->i2c_scale, fpga_i2c->i2c_scale_value); + ret += fpga_reg_write(fpga_i2c, reg->i2c_filter, fpga_i2c->i2c_filter_value); + ret += fpga_reg_write(fpga_i2c, reg->i2c_stretch, fpga_i2c->i2c_stretch_value); + if (ret < 0) { + FPGA_I2C_ERROR("fpga_i2c_init failed.\n"); + return ret; + } + + FPGA_I2C_VERBOSE("fpga_i2c_init ok.\n"); + return 0; +} + +static int fpga_i2c_params_check(fpga_i2c_dev_t *fpga_i2c) +{ + int ret; + fpga_i2c_reg_t *reg; + uint8_t i2c_scale_value, i2c_filter_value, i2c_stretch_value; + + reg = &fpga_i2c->reg; + ret = 0; + ret += fpga_reg_read(fpga_i2c, reg->i2c_scale, &i2c_scale_value); + ret += fpga_reg_read(fpga_i2c, reg->i2c_filter, &i2c_filter_value); + ret += fpga_reg_read(fpga_i2c, reg->i2c_stretch, &i2c_stretch_value); + if (ret < 0) { + FPGA_I2C_ERROR("read fpga i2c params failed.\n"); + return 1; + } + + if ((i2c_scale_value != fpga_i2c->i2c_scale_value) + || (i2c_filter_value != fpga_i2c->i2c_filter_value) + || (i2c_stretch_value != fpga_i2c->i2c_stretch_value)) { + FPGA_I2C_ERROR("fpga i2c params check error, read value: i2c_scale 0x%x, i2c_filter:0x%x, i2c_stretch:0x%x.\n", + i2c_scale_value, i2c_filter_value, i2c_stretch_value); + FPGA_I2C_ERROR("fpga i2c params check error, config value: i2c_scale 0x%x, i2c_filter:0x%x, i2c_stretch:0x%x.\n", + fpga_i2c->i2c_scale_value, fpga_i2c->i2c_filter_value, fpga_i2c->i2c_stretch_value); + return 1; + } + + FPGA_I2C_VERBOSE("fpga i2c params check ok.\n"); + return 0; +} + +static int fpga_i2c_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct i2c_msg *pmsg; + int i; + int ret; + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_addr_t *i2c_addr_desc; + + fpga_i2c = i2c_get_adapdata(adap); + + if (num != I2C_READ_MSG_NUM && num != I2C_WRITE_MSG_NUM) { + FPGA_I2C_ERROR("unsupport i2c_msg len:%d.\n", num); + return -EINVAL; + } + + if ((num == I2C_WRITE_MSG_NUM) && (msgs[0].len > fpga_i2c->reg.i2c_data_buf_len)) { + FPGA_I2C_ERROR("unsupport i2c_msg type:msg[0].flag:0x%x, buf len:0x%x.\n", + msgs[0].flags, msgs[0].len); + return -EINVAL; + } + + if (num == I2C_READ_MSG_NUM ) { + if ((msgs[0].flags & I2C_M_RD) ||!(msgs[1].flags & I2C_M_RD)) { + FPGA_I2C_ERROR("unsupport i2c_msg type:msg[0].flag:0x%x, msg[1].flag:0x%x.\n", + msgs[0].flags, msgs[1].flags); + return -EINVAL; + } + } + + if (fpga_i2c_is_busy(fpga_i2c)) { + FPGA_I2C_ERROR("fpga i2c adapter %d is busy, do reset.\n", adap->nr); + if (fpga_i2c->reset_cfg.i2c_adap_reset_flag == 1) { + + fpga_i2c_reset(fpga_i2c); + + fpga_i2c_adapter_init(fpga_i2c); + } + return -EAGAIN; + } + + if (fpga_i2c->i2c_params_check && fpga_i2c_params_check(fpga_i2c)) { + FPGA_I2C_ERROR("fpga i2c params check failed, try to reinitialize.\n"); + fpga_i2c_adapter_init(fpga_i2c); + } + + ret = 0; + i2c_addr_desc = &fpga_i2c->i2c_addr_desc; + i2c_addr_desc->reg_addr_len = 0; + mem_clear(i2c_addr_desc->read_reg_addr, sizeof(i2c_addr_desc->read_reg_addr)); + + for (i = 0; ret == 0 && i < num; i++) { + pmsg = &msgs[i]; + FPGA_I2C_VERBOSE("Doing %s %d byte(s) to/from 0x%02x - %d of %d messages\n", + pmsg->flags & I2C_M_RD ? "read" : "write", pmsg->len, pmsg->addr, i + 1, num); + + if (pmsg->flags & I2C_M_RD) { + ret = fpga_i2c_read(fpga_i2c, pmsg->addr, pmsg->buf, pmsg->len); + + if ((pmsg->len == 1) && (pmsg->flags & I2C_M_RECV_LEN)) { + if ((ret != 0) || (pmsg->buf[0] > I2C_SMBUS_BLOCK_MAX)) { + FPGA_I2C_ERROR("smbus block data read failed, ret:%d, read len:%u.\n", + ret, pmsg->buf[0]); + return -EPROTO; + } + pmsg->len = 1 + pmsg->buf[0]; + FPGA_I2C_VERBOSE("smbus block data read, read len:%d.\n", pmsg->len); + ret = fpga_i2c_read(fpga_i2c, pmsg->addr, pmsg->buf, pmsg->len); + } + } else { + ret = fpga_i2c_write(fpga_i2c, pmsg->addr, pmsg->buf, pmsg->len, num); + } + } + + return (ret != 0) ? ret : num; +} + +static u32 fpga_i2c_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static const struct i2c_algorithm fpga_i2c_algo = { + .master_xfer = fpga_i2c_xfer, + .functionality = fpga_i2c_functionality, +}; + +static struct i2c_adapter fpga_i2c_ops = { + .owner = THIS_MODULE, + .name = "wb_fpga_i2c", + .algo = &fpga_i2c_algo, +}; + +static int fpga_i2c_config_init(fpga_i2c_dev_t *fpga_i2c) +{ + int ret = 0, rv = 0; + fpga_i2c_reg_t *reg; + fpga_i2c_reset_cfg_t *reset_cfg; + struct device *dev; + uint32_t i2c_offset_reg, i2c_data_buf_len_reg; + int32_t i2c_offset_val; + + fpga_i2c_bus_device_t *fpga_i2c_bus_device; + + dev = fpga_i2c->dev; + reg = &fpga_i2c->reg; + reset_cfg = &fpga_i2c->reset_cfg; + + i2c_offset_val = 0; + + if (dev->of_node) { + ret = 0; + ret += of_property_read_u32(dev->of_node, "i2c_ext_9548_addr", ®->i2c_ext_9548_addr); + ret += of_property_read_u32(dev->of_node, "i2c_ext_9548_chan", ®->i2c_ext_9548_chan); + ret += of_property_read_u32(dev->of_node, "i2c_slave", ®->i2c_slave); + ret += of_property_read_u32(dev->of_node, "i2c_reg", ®->i2c_reg); + ret += of_property_read_u32(dev->of_node, "i2c_data_len", ®->i2c_data_len); + ret += of_property_read_u32(dev->of_node, "i2c_ctrl", ®->i2c_ctrl); + ret += of_property_read_u32(dev->of_node, "i2c_status", ®->i2c_status); + ret += of_property_read_u32(dev->of_node, "i2c_scale", ®->i2c_scale); + ret += of_property_read_u32(dev->of_node, "i2c_filter", ®->i2c_filter); + ret += of_property_read_u32(dev->of_node, "i2c_stretch", ®->i2c_stretch); + ret += of_property_read_u32(dev->of_node, "i2c_ext_9548_exits_flag", ®->i2c_ext_9548_exits_flag); + ret += of_property_read_u32(dev->of_node, "i2c_reg_len", ®->i2c_reg_len); + ret += of_property_read_u32(dev->of_node, "i2c_in_9548_chan", ®->i2c_in_9548_chan); + ret += of_property_read_u32(dev->of_node, "i2c_data_buf", ®->i2c_data_buf); + ret += of_property_read_string(dev->of_node, "dev_name", &fpga_i2c->dev_name); + ret += of_property_read_u32(dev->of_node, "i2c_scale_value", &fpga_i2c->i2c_scale_value); + ret += of_property_read_u32(dev->of_node, "i2c_filter_value", &fpga_i2c->i2c_filter_value); + ret += of_property_read_u32(dev->of_node, "i2c_stretch_value", &fpga_i2c->i2c_stretch_value); + ret += of_property_read_u32(dev->of_node, "i2c_timeout", &fpga_i2c->i2c_timeout); + ret += of_property_read_u32(dev->of_node, "i2c_func_mode", &fpga_i2c->i2c_func_mode); + ret += of_property_read_u32(dev->of_node, "i2c_reset_addr", &reset_cfg->reset_addr); + ret += of_property_read_u32(dev->of_node, "i2c_reset_on", &reset_cfg->reset_on); + ret += of_property_read_u32(dev->of_node, "i2c_reset_off", &reset_cfg->reset_off); + ret += of_property_read_u32(dev->of_node, "i2c_rst_delay_b", &reset_cfg->reset_delay_b); + ret += of_property_read_u32(dev->of_node, "i2c_rst_delay", &reset_cfg->reset_delay); + ret += of_property_read_u32(dev->of_node, "i2c_rst_delay_a", &reset_cfg->reset_delay_a); + ret += of_property_read_u32(dev->of_node, "i2c_adap_reset_flag", &reset_cfg->i2c_adap_reset_flag); + + if (ret != 0) { + FPGA_I2C_ERROR("dts config error, ret:%d.\n", ret); + ret = -ENXIO; + return ret; + } + + rv = of_property_read_u32(dev->of_node, "i2c_data_buf_len_reg", &i2c_data_buf_len_reg); + if (rv == 0) { + ret = fpga_reg_read_32(fpga_i2c, i2c_data_buf_len_reg, ®->i2c_data_buf_len); + if (ret < 0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c data buf length, reg addr: 0x%x, ret: %d\n", + i2c_data_buf_len_reg, ret); + return ret; + } + FPGA_I2C_VERBOSE("fpga i2c data buf length reg addr: 0x%x, value: %d\n", + i2c_data_buf_len_reg, reg->i2c_data_buf_len); + if (reg->i2c_data_buf_len == 0) { + reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT; + } + } else { + ret = of_property_read_u32(dev->of_node, "i2c_data_buf_len", ®->i2c_data_buf_len); + if (ret != 0) { + reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT; + ret = 0; + } + } + + rv = of_property_read_u32(dev->of_node, "i2c_offset_reg", &i2c_offset_reg); + if (rv == 0) { + ret = fpga_reg_read_32(fpga_i2c, i2c_offset_reg, &i2c_offset_val); + if (ret < 0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c adapter offset value, reg addr: 0x%x, ret: %d\n", + i2c_offset_reg, ret); + return ret; + } + FPGA_I2C_VERBOSE("fpga i2c adapter offset reg addr: 0x%x, value: %d\n", + i2c_offset_reg, i2c_offset_val); + reg->i2c_scale +=i2c_offset_val; + reg->i2c_filter += i2c_offset_val; + reg->i2c_stretch += i2c_offset_val; + reg->i2c_ext_9548_exits_flag += i2c_offset_val; + reg->i2c_ext_9548_addr += i2c_offset_val; + reg->i2c_ext_9548_chan += i2c_offset_val; + reg->i2c_in_9548_chan += i2c_offset_val; + reg->i2c_slave += i2c_offset_val; + reg->i2c_reg += i2c_offset_val; + reg->i2c_reg_len += i2c_offset_val; + reg->i2c_data_len += i2c_offset_val; + reg->i2c_ctrl += i2c_offset_val; + reg->i2c_status += i2c_offset_val; + reg->i2c_data_buf += i2c_offset_val; + } + + ret = of_property_read_u32(dev->of_node, "i2c_err_vec", ®->i2c_err_vec); + if (ret != 0) { + reg->i2c_err_vec = DTS_NO_CFG_FLAG; + FPGA_I2C_VERBOSE("not support i2c_err_vec cfg. ret: %d, set DTS_NO_CFG_FLAG: %d\n", + ret, reg->i2c_err_vec); + ret = 0; /* Not configuring i2c_err_vec is not an error */ + } else { + if (i2c_offset_val != 0) { + reg->i2c_err_vec += i2c_offset_val; + } + } + } else { + if (dev->platform_data == NULL) { + dev_err(fpga_i2c->dev, "Failed to get platform data config.\n"); + ret = -ENXIO; + return ret; + } + fpga_i2c_bus_device = dev->platform_data; + fpga_i2c->dev_name = fpga_i2c_bus_device->dev_name; + fpga_i2c->adap_nr = fpga_i2c_bus_device->adap_nr; + fpga_i2c->i2c_scale_value = fpga_i2c_bus_device->i2c_scale_value; + fpga_i2c->i2c_filter_value = fpga_i2c_bus_device->i2c_filter_value; + fpga_i2c->i2c_stretch_value = fpga_i2c_bus_device->i2c_stretch_value; + fpga_i2c->i2c_timeout = fpga_i2c_bus_device->i2c_timeout; + fpga_i2c->i2c_func_mode = fpga_i2c_bus_device->i2c_func_mode; + fpga_i2c->i2c_params_check = fpga_i2c_bus_device->i2c_func_mode; + + reset_cfg->reset_addr = fpga_i2c_bus_device->i2c_reset_addr; + reset_cfg->reset_on = fpga_i2c_bus_device->i2c_reset_on; + reset_cfg->reset_off = fpga_i2c_bus_device->i2c_reset_off; + reset_cfg->reset_delay_b = fpga_i2c_bus_device->i2c_rst_delay_b; + reset_cfg->reset_delay = fpga_i2c_bus_device->i2c_rst_delay; + reset_cfg->reset_delay_a = fpga_i2c_bus_device->i2c_rst_delay_a; + reset_cfg->i2c_adap_reset_flag = fpga_i2c_bus_device->i2c_adap_reset_flag; + + reg->i2c_ext_9548_addr = fpga_i2c_bus_device->i2c_ext_9548_addr; + reg->i2c_ext_9548_chan = fpga_i2c_bus_device->i2c_ext_9548_chan; + reg->i2c_slave = fpga_i2c_bus_device->i2c_slave; + reg->i2c_reg = fpga_i2c_bus_device->i2c_reg; + reg->i2c_data_len = fpga_i2c_bus_device->i2c_data_len; + reg->i2c_ctrl = fpga_i2c_bus_device->i2c_ctrl; + reg->i2c_status = fpga_i2c_bus_device->i2c_status; + reg->i2c_scale = fpga_i2c_bus_device->i2c_scale; + reg->i2c_filter = fpga_i2c_bus_device->i2c_filter; + reg->i2c_stretch = fpga_i2c_bus_device->i2c_stretch; + reg->i2c_ext_9548_exits_flag = fpga_i2c_bus_device->i2c_ext_9548_exits_flag; + reg->i2c_reg_len = fpga_i2c_bus_device->i2c_reg_len; + reg->i2c_in_9548_chan = fpga_i2c_bus_device->i2c_in_9548_chan; + reg->i2c_data_buf = fpga_i2c_bus_device->i2c_data_buf; + + i2c_data_buf_len_reg = fpga_i2c_bus_device->i2c_data_buf_len_reg; + if (i2c_data_buf_len_reg > 0) { + ret = fpga_reg_read_32(fpga_i2c, i2c_data_buf_len_reg, ®->i2c_data_buf_len); + if (ret < 0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c data buf length, reg addr: 0x%x, ret: %d\n", + i2c_data_buf_len_reg, ret); + return ret; + } + FPGA_I2C_VERBOSE("fpga i2c data buf length reg addr: 0x%x, value: %d\n", + i2c_data_buf_len_reg, reg->i2c_data_buf_len); + if (reg->i2c_data_buf_len == 0) { + reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT; + } + } else { + if (fpga_i2c_bus_device->i2c_data_buf_len == 0) { + reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT; + FPGA_I2C_VERBOSE("not support i2c_data_buf_len cfg, set default_val:%d\n", + reg->i2c_data_buf_len); + } else { + reg->i2c_data_buf_len = fpga_i2c_bus_device->i2c_data_buf_len; + } + } + + i2c_offset_reg = fpga_i2c_bus_device->i2c_offset_reg; + if (i2c_offset_reg > 0) { + rv = fpga_reg_read_32(fpga_i2c, i2c_offset_reg, &i2c_offset_val); + if (rv < 0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c adapter offset value, reg addr: 0x%x, rv: %d\n", + i2c_offset_reg, rv); + return rv; + } + FPGA_I2C_VERBOSE("fpga i2c adapter offset reg addr: 0x%x, value: %d\n", + i2c_offset_reg, i2c_offset_val); + reg->i2c_scale +=i2c_offset_val; + reg->i2c_filter += i2c_offset_val; + reg->i2c_stretch += i2c_offset_val; + reg->i2c_ext_9548_exits_flag += i2c_offset_val; + reg->i2c_ext_9548_addr += i2c_offset_val; + reg->i2c_ext_9548_chan += i2c_offset_val; + reg->i2c_in_9548_chan += i2c_offset_val; + reg->i2c_slave += i2c_offset_val; + reg->i2c_reg += i2c_offset_val; + reg->i2c_reg_len += i2c_offset_val; + reg->i2c_data_len += i2c_offset_val; + reg->i2c_ctrl += i2c_offset_val; + reg->i2c_status += i2c_offset_val; + reg->i2c_data_buf += i2c_offset_val; + } + + if (fpga_i2c_bus_device->i2c_err_vec == 0) { + reg->i2c_err_vec = DTS_NO_CFG_FLAG; + FPGA_I2C_VERBOSE("not support i2c_err_vec cfg, set DTS_NO_CFG_FLAG:%d\n", + reg->i2c_err_vec); + } else { + reg->i2c_err_vec = fpga_i2c_bus_device->i2c_err_vec; + if (i2c_offset_val != 0) { + reg->i2c_err_vec += i2c_offset_val; + } + } + } + + FPGA_I2C_VERBOSE("i2c_ext_9548_addr:0x%x, i2c_ext_9548_chan:0x%x, i2c_slave:0x%x, i2c_reg:0x%x, i2c_data_len:0x%x.\n", + reg->i2c_ext_9548_addr, reg->i2c_ext_9548_chan, reg->i2c_slave, reg->i2c_reg, reg->i2c_data_len); + FPGA_I2C_VERBOSE("i2c_ctrl:0x%x, i2c_status:0x%x, i2c_scale:0x%x, i2c_filter:0x%x, i2c_stretch:0x%x.\n", + reg->i2c_ctrl, reg->i2c_status, reg->i2c_scale, reg->i2c_filter, reg->i2c_stretch); + FPGA_I2C_VERBOSE("i2c_ext_9548_exits_flag:0x%x, i2c_in_9548_chan:0x%x, i2c_data_buf:0x%x, i2c_reg_len:0x%x, i2c_data_buf_len:0x%x.\n", + reg->i2c_ext_9548_exits_flag, reg->i2c_in_9548_chan, reg->i2c_data_buf, reg->i2c_reg_len, reg->i2c_data_buf_len); + FPGA_I2C_VERBOSE("dev_name:%s, i2c_scale_value:0x%x, i2c_filter_value:0x%x, i2c_stretch_value:0x%x, i2c_timeout:0x%x.\n", + fpga_i2c->dev_name, fpga_i2c->i2c_scale_value, fpga_i2c->i2c_filter_value, fpga_i2c->i2c_stretch_value, fpga_i2c->i2c_timeout); + FPGA_I2C_VERBOSE("i2c_reset_addr:0x%x, i2c_reset_on:0x%x, i2c_reset_off:0x%x, i2c_rst_delay_b:0x%x, i2c_rst_delay:0x%x, i2c_rst_delay_a:0x%x.\n", + reset_cfg->reset_addr, reset_cfg->reset_on, reset_cfg->reset_off, reset_cfg->reset_delay_b, reset_cfg->reset_delay, reset_cfg->reset_delay_a); + FPGA_I2C_VERBOSE("i2c_adap_reset_flag:0x%x.\n", reset_cfg->i2c_adap_reset_flag); + FPGA_I2C_VERBOSE("i2c_err_vec:0x%x\n", reg->i2c_err_vec); + + return ret; +} + +static int fpga_i2c_probe(struct platform_device *pdev) +{ + int ret; + fpga_i2c_dev_t *fpga_i2c; + struct device *dev; + + fpga_i2c = devm_kzalloc(&pdev->dev, sizeof(fpga_i2c_dev_t), GFP_KERNEL); + if (!fpga_i2c) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + ret = -ENOMEM; + goto out; + } + + fpga_i2c->dev = &pdev->dev; + + ret = fpga_i2c_config_init(fpga_i2c); + if (ret !=0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c dts config.\n"); + goto out; + } + + ret = fpga_i2c_adapter_init(fpga_i2c); + if (ret !=0) { + dev_err(fpga_i2c->dev, "Failed to init fpga i2c adapter.\n"); + goto out; + } + + if (fpga_i2c->dev->of_node) { + fpga_i2c->i2c_params_check = of_property_read_bool(fpga_i2c->dev->of_node, "i2c_params_check"); + } + FPGA_I2C_VERBOSE("fpga i2c params check flag:%d.\n", fpga_i2c->i2c_params_check); + + init_waitqueue_head(&fpga_i2c->queue); + + dev = fpga_i2c->dev; + fpga_i2c->adap = fpga_i2c_ops; + fpga_i2c->adap.timeout = msecs_to_jiffies(fpga_i2c->i2c_timeout); + fpga_i2c->adap.dev.parent = &pdev->dev; + fpga_i2c->adap.dev.of_node = pdev->dev.of_node; + i2c_set_adapdata(&fpga_i2c->adap, fpga_i2c); + platform_set_drvdata(pdev, fpga_i2c); + + if (fpga_i2c->dev->of_node) { + /* adap.nr get from dts aliases */ + ret = i2c_add_adapter(&fpga_i2c->adap); + } else { + fpga_i2c->adap.nr = fpga_i2c->adap_nr; + ret = i2c_add_numbered_adapter(&fpga_i2c->adap); + } + + if (ret < 0) { + dev_info(fpga_i2c->dev, "Failed to add adapter.\n"); + goto fail_add; + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) + of_i2c_register_devices(&fpga_i2c->adap); +#endif + dev_info(fpga_i2c->dev, "registered i2c-%d for %s using mode %d with base address:0x%x, data buf len: %d success.\n", + fpga_i2c->adap.nr, fpga_i2c->dev_name, fpga_i2c->i2c_func_mode, fpga_i2c->reg.i2c_scale, + fpga_i2c->reg.i2c_data_buf_len); + return 0; + +fail_add: + platform_set_drvdata(pdev, NULL); +out: + return ret; +}; + +static int fpga_i2c_remove(struct platform_device *pdev) +{ + fpga_i2c_dev_t *fpga_i2c; + + fpga_i2c = platform_get_drvdata(pdev); + i2c_del_adapter(&fpga_i2c->adap); + platform_set_drvdata(pdev, NULL); + return 0; +}; + +static struct of_device_id fpga_i2c_match[] = { + { + .compatible = "wb-fpga-i2c", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, fpga_i2c_match); + +static struct platform_driver wb_fpga_i2c_driver = { + .probe = fpga_i2c_probe, + .remove = fpga_i2c_remove, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = fpga_i2c_match, + }, +}; + +static int __init wb_fpga_i2c_init(void) +{ + return platform_driver_register(&wb_fpga_i2c_driver); +} + +static void __exit wb_fpga_i2c_exit(void) +{ + platform_driver_unregister(&wb_fpga_i2c_driver); +} + +module_init(wb_fpga_i2c_init); +module_exit(wb_fpga_i2c_exit); +MODULE_DESCRIPTION("fpga i2c adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pca954x_drv.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pca954x_drv.c new file mode 100644 index 000000000000..5845195bb310 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pca954x_drv.c @@ -0,0 +1,525 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fpga_i2c.h" + +extern int i2c_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); + +#define PCA954X_MAX_NCHANS (8) +#define FPGA_INTERNAL_PCA9548 (1) +#define FPGA_EXTERNAL_PCA9548 (2) +#define FPGA_I2C_EXT_9548_EXITS (0x01 << 0) +#define FPGA_I2C_9548_NO_RESET (0x01 << 1) + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) + +int g_fpga_pca954x_debug = 0; +int g_fpga_pca954x_error = 0; + +module_param(g_fpga_pca954x_debug, int, S_IRUGO | S_IWUSR); +module_param(g_fpga_pca954x_error, int, S_IRUGO | S_IWUSR); + +#define FPGA_PCA954X_VERBOSE(fmt, args...) do { \ + if (g_fpga_pca954x_debug) { \ + printk(KERN_INFO "[FPGA_PCA954X][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_PCA954X_ERROR(fmt, args...) do { \ + if (g_fpga_pca954x_error) { \ + printk(KERN_ERR "[FPGA_PCA954X][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +enum pca_type { + pca_9540, + pca_9541, + pca_9542, + pca_9543, + pca_9544, + pca_9545, + pca_9546, + pca_9547, + pca_9548, +}; + +struct pca954x { + enum pca_type type; + struct i2c_adapter *virt_adaps[PCA954X_MAX_NCHANS]; + u8 last_chan; /* last register value */ + uint32_t fpga_9548_flag; + uint32_t fpga_9548_reset_flag; + uint32_t pca9548_base_nr; + struct i2c_client *client; +}; + +struct chip_desc { + u8 nchans; + u8 enable; /* used for muxes only */ + enum muxtype { + pca954x_ismux = 0, + pca954x_isswi + } muxtype; +}; + +/* Provide specs for the PCA954x types we know about */ +static const struct chip_desc chips[] = { + [pca_9540] = { + .nchans = 2, + .enable = 0x4, + .muxtype = pca954x_ismux, + }, + [pca_9541] = { + .nchans = 1, + .muxtype = pca954x_isswi, + }, + [pca_9543] = { + .nchans = 2, + .muxtype = pca954x_isswi, + }, + [pca_9544] = { + .nchans = 4, + .enable = 0x4, + .muxtype = pca954x_ismux, + }, + [pca_9545] = { + .nchans = 4, + .muxtype = pca954x_isswi, + }, + [pca_9547] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + }, + [pca_9548] = { + .nchans = 8, + .muxtype = pca954x_isswi, + }, +}; + +static const struct i2c_device_id fpga_pca954x_id[] = { + { "wb_fpga_pca9540", pca_9540 }, + { "wb_fpga_pca9541", pca_9541 }, + { "wb_fpga_pca9542", pca_9543 }, + { "wb_fpga_pca9543", pca_9543 }, + { "wb_fpga_pca9544", pca_9544 }, + { "wb_fpga_pca9545", pca_9545 }, + { "wb_fpga_pca9546", pca_9545 }, + { "wb_fpga_pca9547", pca_9547 }, + { "wb_fpga_pca9548", pca_9548 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, fpga_pca954x_id); + +static int fpga_file_write(const char *path, int pos, unsigned char *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + FPGA_PCA954X_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + FPGA_PCA954X_ERROR("kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; + +} +static int fpga_device_write(fpga_i2c_dev_t *fpga_i2c, int pos, unsigned char *val, size_t size) +{ + int ret; + + switch (fpga_i2c->i2c_func_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = fpga_file_write(fpga_i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; + default: + FPGA_PCA954X_ERROR("err func mode, write failed.\n"); + return -EINVAL; + } + + return ret; +} + +static int fpga_reg_write(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t val) +{ + int ret; + + ret = fpga_device_write(fpga_i2c, addr, &val, sizeof(uint8_t)); + if (ret < 0) { + FPGA_PCA954X_ERROR("fpga_device_write failed. name:%s, addr:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, val); + return ret; + } + + FPGA_PCA954X_VERBOSE("fpga reg write success, dev name:%s, offset:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, val); + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,7) +static int pca954x_select_chan(struct i2c_adapter *adap, void *client, u32 chan) +{ + struct pca954x *data = i2c_get_clientdata(client); + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_t *reg; + int ret; + u8 regval, i2c_9548_opt; + + while(i2c_parent_is_i2c_adapter(adap)){ + adap = to_i2c_adapter(adap->dev.parent); + } + + FPGA_PCA954X_VERBOSE("root bus:%d, chan:0x%x, 9548 flag:0x%x, 9548 addr:0x%x.\n", + adap->nr, chan, data->fpga_9548_flag, client->addr); + fpga_i2c = i2c_get_adapdata(adap); + reg = &fpga_i2c->reg; + + regval = 1 << chan; + if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) { + ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, regval); + } else { + if (data->fpga_9548_reset_flag == 1) { + i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS & ~(FPGA_I2C_9548_NO_RESET); + } else { + i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS | FPGA_I2C_9548_NO_RESET; + } + FPGA_PCA954X_VERBOSE("fpga pca9548 reset flag:0x%x, opt:0x%x.\n", + data->fpga_9548_reset_flag, i2c_9548_opt); + ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, i2c_9548_opt); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_addr, client->addr); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, regval); + } + + return ret; +} + +static int pca954x_deselect_mux(struct i2c_adapter *adap, void *client, u32 chan) +{ + struct pca954x *data = i2c_get_clientdata(client); + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_t *reg; + int ret; + + while(i2c_parent_is_i2c_adapter(adap)){ + adap = to_i2c_adapter(adap->dev.parent); + } + + fpga_i2c = i2c_get_adapdata(adap); + reg = &fpga_i2c->reg; + /* Deselect active channel */ + data->last_chan = 0; + if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) { + ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, 0); + } else { + + ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, FPGA_I2C_9548_NO_RESET); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, 0); + } + + return ret; +} +#else +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; + struct i2c_adapter *adap; + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_t *reg; + int ret; + u8 regval, i2c_9548_opt; + + adap = muxc->parent; + while(i2c_parent_is_i2c_adapter(adap)){ + adap = to_i2c_adapter(adap->dev.parent); + } + + FPGA_PCA954X_VERBOSE("root bus:%d, chan:0x%x, 9548 flag:0x%x, 9548 addr:0x%x.\n", + adap->nr, chan, data->fpga_9548_flag, client->addr); + fpga_i2c = i2c_get_adapdata(adap); + reg = &fpga_i2c->reg; + + regval = 1 << chan; + if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) { + ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, regval); + } else { + if (data->fpga_9548_reset_flag == 1) { + i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS & ~(FPGA_I2C_9548_NO_RESET); + } else { + i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS | FPGA_I2C_9548_NO_RESET; + } + FPGA_PCA954X_VERBOSE("fpga pca9548 reset flag:0x%x, opt:0x%x.\n", + data->fpga_9548_reset_flag, i2c_9548_opt); + ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, i2c_9548_opt); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_addr, client->addr); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, regval); + } + + return ret; +} + +static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_adapter *adap; + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_t *reg; + int ret; + + adap = muxc->parent; + while(i2c_parent_is_i2c_adapter(adap)){ + adap = to_i2c_adapter(adap->dev.parent); + } + + fpga_i2c = i2c_get_adapdata(adap); + reg = &fpga_i2c->reg; + ret = 0; + /* Deselect active channel */ + data->last_chan = 0; + + if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) { + ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, 0); + } else { + + ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, FPGA_I2C_9548_NO_RESET); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, 0); + } + + return ret; +} +#endif +/* + * I2C init/probing/exit functions + */ +static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + int num, force, class; + struct pca954x *data; + int ret = -ENODEV; + struct device *dev; + int dynamic_nr = 1; + fpga_pca954x_device_t *fpga_pca954x_device; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(4,6,7) + struct i2c_mux_core *muxc; +#endif + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) { + dev_err(&client->dev, "i2c adapter:%d, unsupport I2C_FUNC_SMBUS_BYTE.\n", adap->nr); + goto err; + } + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) + data = kzalloc(sizeof(struct pca954x), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "kzalloc failed.\n"); + ret = -ENOMEM; + goto err; + } + + i2c_set_clientdata(client, data); +#else + muxc = i2c_mux_alloc(adap, &client->dev, + PCA954X_MAX_NCHANS, sizeof(*data), 0, + pca954x_select_chan, pca954x_deselect_mux); + if (!muxc) { + dev_err(&client->dev, "i2c_mux_alloc failed.\n"); + return -ENOMEM; + } + data = i2c_mux_priv(muxc); + i2c_set_clientdata(client, muxc); + data->client = client; +#endif + + dev = &client->dev; + if (dev == NULL) { + dev_err(&client->dev, "dev is NULL.\n"); + ret = -ENODEV; + goto exit_free; + } + + if (dev->of_node == NULL) { + if (client->dev.platform_data == NULL) { + dev_err(&client->dev, "Failed to get 954x platform data config.\n"); + ret = -EINVAL; + goto exit_free; + } + fpga_pca954x_device = client->dev.platform_data; + data->fpga_9548_flag = fpga_pca954x_device->fpga_9548_flag; + data->fpga_9548_reset_flag = fpga_pca954x_device->fpga_9548_reset_flag; + data->pca9548_base_nr = fpga_pca954x_device->pca9548_base_nr; + if (data->pca9548_base_nr == 0) { + + dynamic_nr = 1; + } else { + dynamic_nr = 0; + FPGA_PCA954X_VERBOSE("pca9548_base_nr:%u.\n", data->pca9548_base_nr); + } + } else { + data->type = id->driver_data; + /* BUS ID */ + ret = of_property_read_u32(dev->of_node, "fpga_9548_flag", &data->fpga_9548_flag); + ret += of_property_read_u32(dev->of_node, "fpga_9548_reset_flag", &data->fpga_9548_reset_flag); + if (ret != 0) { + dev_err(&client->dev, "Failed to get 954x dts config, ret:%d.\n", ret); + ret = -EINVAL; + goto exit_free; + } + if (of_property_read_u32(dev->of_node, "pca9548_base_nr", &data->pca9548_base_nr)) { + + dynamic_nr = 1; + FPGA_PCA954X_VERBOSE("pca9548_base_nr not found, use dynamic adap number"); + } else { + dynamic_nr = 0; + FPGA_PCA954X_VERBOSE("pca9548_base_nr:%u.\n", data->pca9548_base_nr); + } + } + + if (data->fpga_9548_flag != FPGA_EXTERNAL_PCA9548 && data->fpga_9548_flag != FPGA_INTERNAL_PCA9548) { + dev_err(&client->dev, "Error: fpga 954x flag config error, value:0x%x.\n", data->fpga_9548_flag); + ret = -EINVAL; + goto exit_free; + } + + data->type = id->driver_data; + data->last_chan = 0; /* force the first selection */ + + /* Now create an adapter for each channel */ + for (num = 0; num < chips[data->type].nchans; num++) { + if (dynamic_nr == 1) { + force = 0; /* dynamic adap number */ + } else { + force = data->pca9548_base_nr + num; + } + class = 0; /* no class by default */ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) + data->virt_adaps[num] = + i2c_add_mux_adapter(adap, &client->dev, client, + force, num, class, pca954x_select_chan, pca954x_deselect_mux); + + if (data->virt_adaps[num] == NULL) { + ret = -ENODEV; + dev_err(&client->dev, "Failed to register multiplexed adapter %d as bus %d\n", + num, force); + goto virt_reg_failed; + } +#else + ret = i2c_mux_add_adapter(muxc, force, num, class); + if (ret) { + dev_err(&client->dev, "Failed to register multiplexed adapter %d as bus %d\n", + num, force); + goto virt_reg_failed; + } +#endif + } /* end for num = 0; num < chips[data->type].nchans... */ + + dev_info(&client->dev, "registered %d multiplexed busses for I2C %s %s\n", + num, chips[data->type].muxtype == pca954x_ismux ? "mux" : "switch", client->name); + + return 0; + +virt_reg_failed: +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) + for (num--; num >= 0; num--) + i2c_del_mux_adapter(data->virt_adaps[num]); +exit_free: + kfree(data); +#else +exit_free: + i2c_mux_del_adapters(muxc); +#endif +err: + return ret; +} + +static int fpga_i2c_pca954x_remove(struct i2c_client *client) +{ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) + struct pca954x *data = i2c_get_clientdata(client); + const struct chip_desc *chip = &chips[data->type]; + int i; + + for (i = 0; i < chip->nchans; ++i) + if (data->virt_adaps[i]) { + i2c_del_mux_adapter(data->virt_adaps[i]); + data->virt_adaps[i] = NULL; + } + + kfree(data); +#else + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + i2c_mux_del_adapters(muxc); +#endif + + return 0; +} + +static struct i2c_driver fpga_i2c_pca954x_driver = { + .driver = { + .name = "wb_fpga_pca954x", + .owner = THIS_MODULE, + }, + .probe = fpga_i2c_pca954x_probe, + .remove = fpga_i2c_pca954x_remove, + .id_table = fpga_pca954x_id, +}; + +static int __init fpga_i2c_pca954x_init(void) +{ + int ret; + + ret = i2c_add_driver(&fpga_i2c_pca954x_driver); + return ret; +} + +static void __exit fpga_i2c_pca954x_exit(void) +{ + i2c_del_driver(&fpga_i2c_pca954x_driver); +} + +module_init(fpga_i2c_pca954x_init); +module_exit(fpga_i2c_pca954x_exit); +MODULE_DESCRIPTION("fpga pca954x driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pcie.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pcie.c new file mode 100644 index 000000000000..aedcc78dab90 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pcie.c @@ -0,0 +1,164 @@ +/* + * wb_fpga_pcie.c + * ko to enable fpga pcie + */ +#include +#include +#include +#include +#include + +#define FPGA_MSI_IRQ_NUM (14) +#define FPGA_MSI_IRQ_BEGIN (0) +#define XILINX_FPGA_USE_MSI (0) +#define XILINX_FPGA_NUSE_MSI (1) + +int g_fpga_pcie_dev_debug = 0; +int g_fpga_pcie_dev_error = 0; +module_param(g_fpga_pcie_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_fpga_pcie_dev_error, int, S_IRUGO | S_IWUSR); + +#define FPGA_PCIE_DEV_VERBOSE(fmt, args...) do { \ + if (g_fpga_pcie_dev_debug) { \ + printk(KERN_INFO "[FPGA_PCIE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_PCIE_DEV_ERROR(fmt, args...) do { \ + if (g_fpga_pcie_dev_error) { \ + printk(KERN_ERR "[FPGA_PCIE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef struct wb_fpga_pcie_s { + struct pci_dev *pci_dev; + int driver_data; +} wb_fpga_pcie_t; + +static void fpga_pcie_recover(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct resource *mem_base; + u32 bar0_val; + int ret; + + mem_base = &pdev->resource[0]; + ret = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &bar0_val); + if (ret) { + FPGA_PCIE_DEV_ERROR("pci_read_config_dword failed ret %d.\n", ret); + return; + } + FPGA_PCIE_DEV_VERBOSE("mem_base->start[0x%llx], bar0_val[0x%x], ret %d.\n", + mem_base->start, bar0_val, ret); + + if (bar0_val != mem_base->start) { + ret = pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, mem_base->start); + if (ret) { + FPGA_PCIE_DEV_ERROR("pci_write_config_dword mem_base->start[0x%llx], failed ret %d.\n", mem_base->start, ret); + return; + } + FPGA_PCIE_DEV_VERBOSE("pci_write_config_dword mem_base->start[0x%llx] success.\n", mem_base->start); + } else { + FPGA_PCIE_DEV_VERBOSE("mem_base->start[0x%llx], bar0_val[0x%x], do nothing.\n", + mem_base->start, bar0_val); + } +} + +static int fpga_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int err; + wb_fpga_pcie_t *wb_fpga_pcie; + + FPGA_PCIE_DEV_VERBOSE("Enter vendor 0x%x, subsystem_vendor 0x%x.\n", pdev->vendor, pdev->subsystem_vendor); + + wb_fpga_pcie = devm_kzalloc(&pdev->dev, sizeof(wb_fpga_pcie_t), GFP_KERNEL); + if (!wb_fpga_pcie) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + fpga_pcie_recover(pdev, id); + + /* enable device: ask low-level code to enable I/O and memory */ + FPGA_PCIE_DEV_VERBOSE("start pci_enable_device!\n"); + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Failed to enable pci device, ret:%d.\n", err); + return err; + } + + FPGA_PCIE_DEV_VERBOSE("start pci_set_master!\n"); + pci_set_master(pdev); + + wb_fpga_pcie->driver_data = id->driver_data; + wb_fpga_pcie->pci_dev = pdev; + pci_set_drvdata(pdev, wb_fpga_pcie); + + if (wb_fpga_pcie->driver_data == XILINX_FPGA_USE_MSI) { + FPGA_PCIE_DEV_VERBOSE("start pci_enable_msi_range!\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,152) + err = pci_enable_msi_range(pdev, FPGA_MSI_IRQ_BEGIN + 1, FPGA_MSI_IRQ_NUM); +#else + err = pci_alloc_irq_vectors_affinity(pdev, FPGA_MSI_IRQ_BEGIN + 1, + FPGA_MSI_IRQ_NUM, PCI_IRQ_MSI, NULL); +#endif + if (err != FPGA_MSI_IRQ_NUM) { + FPGA_PCIE_DEV_ERROR("pci_enable_msi_block err %d FPGA_MSI_IRQ_NUM %d.\n", err, + FPGA_MSI_IRQ_NUM); + dev_err(&pdev->dev, "Failed to enable pci msi, ret:%d.\n", err); + return -EINVAL; + } + } + + dev_info(&pdev->dev, "fpga pci device init success.\n"); + return 0; +} + +static void fpga_pcie_remove(struct pci_dev *pdev) +{ + wb_fpga_pcie_t *wb_fpga_pcie; + + FPGA_PCIE_DEV_VERBOSE("fpga_pcie_remove.\n"); + + wb_fpga_pcie = pci_get_drvdata(pdev); + if (wb_fpga_pcie->driver_data == XILINX_FPGA_USE_MSI) { + FPGA_PCIE_DEV_VERBOSE("start pci_disable_msi!\n"); + pci_disable_msi(pdev); + } + + pci_disable_device(pdev); + return; +} + +static const struct pci_device_id fpga_pci_ids[] = { + { PCI_DEVICE(0x10ee, 0x7022), .driver_data = XILINX_FPGA_USE_MSI}, + { PCI_DEVICE(0x10ee, 0x7011), .driver_data = XILINX_FPGA_NUSE_MSI}, + {0} +}; +MODULE_DEVICE_TABLE(pci, fpga_pci_ids); + +static struct pci_driver wb_fpga_pcie_driver = { + .name = "wb_fpga_pcie", + .id_table = fpga_pci_ids,/* only dynamic id's */ + .probe = fpga_pcie_probe, + .remove = fpga_pcie_remove, +}; + +static int __init wb_fpga_pcie_init(void) +{ + + FPGA_PCIE_DEV_VERBOSE("wb_fpga_pcie_init enter!\n"); + return pci_register_driver(&wb_fpga_pcie_driver); +} + +static void __exit wb_fpga_pcie_exit(void) +{ + FPGA_PCIE_DEV_VERBOSE("wb_fpga_pcie_exit enter!\n"); + pci_unregister_driver(&wb_fpga_pcie_driver); + return; +} + +module_init(wb_fpga_pcie_init); +module_exit(wb_fpga_pcie_exit); +MODULE_DESCRIPTION("fpga pcie driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_d1500.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_d1500.c new file mode 100644 index 000000000000..7d5d5da87ea7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_d1500.c @@ -0,0 +1,367 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2011, 2012 Cavium Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GPIO_NAME "wb_gpio_d1500" + +#define GPIO_BASE (0x500) +#define GP_IO_SEL (GPIO_BASE + 0x4) +#define GP_LVL (GPIO_BASE + 0xC) +#define GPI_NMI_EN (GPIO_BASE + 0x28) +#define GPI_NMI_STS (GPIO_BASE + 0x2a) +#define GPI_INV (GPIO_BASE + 0x2c) +#define GPIO_USE_SEL2 (GPIO_BASE + 0x30) +#define GP_IO_SEL2 (GPIO_BASE + 0x34) +#define GP_LVL2 (GPIO_BASE + 0x38) +#define GPI_NMI_EN_2 (GPIO_BASE + 0x3c) +#define GPI_NMI_STS_2 (GPIO_BASE + 0x3e) +#define GPIO_USE_SEL3 (GPIO_BASE + 0x40) +#define GP_IO_SEL3 (GPIO_BASE + 0x44) +#define GP_LVL3 (GPIO_BASE + 0x48) +#define GPI_NMI_EN_3 (GPIO_BASE + 0x50) +#define GPI_NMI_STS_3 (GPIO_BASE + 0x54) + +#define GPIO_BASE_ID (0) +#define BANKSIZE (32) +#define D1500_GPIO_PIN_NUM (96) +#define CELL_NUM (2) + +int g_gpio_d1500_debug = 0; +int g_gpio_d1500_error = 0; +module_param(g_gpio_d1500_debug, int, S_IRUGO | S_IWUSR); +module_param(g_gpio_d1500_error, int, S_IRUGO | S_IWUSR); + +#define GPIO_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_gpio_d1500_debug) { \ + printk(KERN_ERR "[GPIO-D1500][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define GPIO_DEBUG_ERROR(fmt, args...) do { \ + if (g_gpio_d1500_error) { \ + printk(KERN_ERR "[GPIO-D1500][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static DEFINE_SPINLOCK(sio_lock); + +struct gpio_d1500_t { + struct gpio_chip chip; + u64 register_base; +}; + +static int wb_gpio_get(struct gpio_chip *gc, unsigned gpio_num) +{ + u32 data = 0; + unsigned int bank, offset; + unsigned long flags; + + bank = gpio_num / BANKSIZE; + offset = gpio_num % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GP_LVL) & (1 << offset); + if (data) { + data = 1; + } + } else if (bank == 1) { + data = inl(GP_LVL2) & (1 << offset); + if (data) { + data = 1; + } + } else if (bank == 2) { + data = inl(GP_LVL3) & (1 << offset); + if (data) { + data = 1; + } + } + spin_unlock_irqrestore(&sio_lock, flags); + + return data; +} + +static int wb_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num) +{ + u32 data; + unsigned int bank, offset; + unsigned long flags; + + bank = gpio_num / BANKSIZE; + offset = gpio_num % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GP_IO_SEL); + data = data | (1 << offset); + outl(data, GP_IO_SEL); + } else if (bank == 1) { + data = inl(GP_IO_SEL2); + data = data | (1 << offset); + outl(data, GP_IO_SEL2); + } else if (bank == 2) { + data = inl(GP_IO_SEL3); + data = data | (1 << offset); + outl(data, GP_IO_SEL3); + } + spin_unlock_irqrestore(&sio_lock, flags); + + return 0; +} + +static void wb_gpio_set(struct gpio_chip *gc, + unsigned gpio_num, int val) +{ + u32 data; + unsigned int bank, offset; + unsigned long flags; + + bank = gpio_num / BANKSIZE; + offset = gpio_num % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GP_LVL); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL); + } else if (bank == 1) { + data = inl(GP_LVL2); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL2); + } else if (bank == 2) { + data = inl(GP_LVL3); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL3); + } + spin_unlock_irqrestore(&sio_lock, flags); + + return; +} + +static int wb_gpio_direction_out(struct gpio_chip *gc, + unsigned gpio_num, int val) +{ + u32 data; + unsigned int bank, offset; + unsigned long flags; + + bank = gpio_num / BANKSIZE; + offset = gpio_num % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GP_IO_SEL); + data = data & ~(1 << offset); + outl(data, GP_IO_SEL); + + data = inl(GP_LVL); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL); + } else if (bank == 1) { + data = inl(GP_IO_SEL2); + data = data & ~(1 << offset); + outl(data, GP_IO_SEL2); + + data = inl(GP_LVL2); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL2); + } else if (bank == 2) { + data = inl(GP_IO_SEL3); + data = data & ~(1 << offset); + outl(data, GP_IO_SEL3); + + data = inl(GP_LVL3); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL3); + } + spin_unlock_irqrestore(&sio_lock, flags); + + return 0; +} + +#ifdef CONFIG_OF +static int wb_gpio_of_xlate(struct gpio_chip *chip, + const struct of_phandle_args *gpio_desc, + u32 *flags) +{ + if (chip->of_gpio_n_cells < 2) { + return -EINVAL; + } + + if (flags) { + *flags = gpio_desc->args[1]; + } + + return gpio_desc->args[0]; +} +#endif + +static int wb_gpio_request(struct gpio_chip *chip, unsigned int offset) +{ + u32 data; + unsigned int bank, tmp_offset; + unsigned long flags; + + bank = offset / BANKSIZE; + tmp_offset = offset % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GPIO_BASE); + data = data | (1 << tmp_offset); + outl(data, GPIO_BASE); + } else if (bank == 1) { + data = inl(GPIO_USE_SEL2); + data = data | (1 << tmp_offset); + outl(data, GPIO_USE_SEL2); + } else if (bank == 2) { + data = inl(GPIO_USE_SEL3); + data = data | (1 << tmp_offset); + outl(data, GPIO_USE_SEL3); + } + spin_unlock_irqrestore(&sio_lock, flags); + + return 0; +} + +#if 0 +static void wb_gpio_free(struct gpio_chip *chip, unsigned int offset) +{ + u32 data; + unsigned int bank, tmp_offset; + unsigned long flags; + + bank = offset / BANKSIZE; + tmp_offset = offset % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GPIO_BASE); + data = data & ~(1 << tmp_offset); + outl(data, GPIO_BASE); + } else if (bank == 1) { + data = inl(GPIO_USE_SEL2); + data = data & ~(1 << tmp_offset); + outl(data, GPIO_USE_SEL2); + } else if (bank == 2) { + data = inl(GPIO_USE_SEL3); + data = data & ~(1 << tmp_offset); + outl(data, GPIO_USE_SEL3); + } + + spin_unlock_irqrestore(&sio_lock, flags); + + return; +} +#endif + +static struct gpio_chip wb_gpio_chip = { + .label = GPIO_NAME, + .owner = THIS_MODULE, + .base = GPIO_BASE_ID, + .get = wb_gpio_get, + .direction_input = wb_gpio_direction_in, + .set = wb_gpio_set, + .direction_output = wb_gpio_direction_out, +#ifdef CONFIG_OF + .of_xlate = wb_gpio_of_xlate, +#endif + .request = wb_gpio_request, + .ngpio = D1500_GPIO_PIN_NUM, +#ifdef CONFIG_OF + .of_gpio_n_cells = CELL_NUM, +#endif + .can_sleep = false, +}; + +static int wb_gpio_probe(struct platform_device *pdev) +{ + struct gpio_d1500_t *gpio; + int err; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) { + dev_err(&pdev->dev, "gpio kzalloc failed\n"); + return -ENOMEM; + } + + wb_gpio_chip.parent = &pdev->dev; + gpio->register_base = GPIO_BASE; + gpio->chip = wb_gpio_chip; + pdev->dev.platform_data = &wb_gpio_chip; + err = devm_gpiochip_add_data(&pdev->dev, &wb_gpio_chip, gpio); + if (err) { + dev_err(&pdev->dev, "gpiochip add failed\n"); + return err; + } + + dev_info(&pdev->dev, "register %llu gpio success.\n", gpio->register_base); + + return 0; +} + +static int wb_gpio_remove(struct platform_device *pdev) +{ + dev_info(&pdev->dev, "unregister d1500 gpio success\n"); + return 0; +} + +static const struct of_device_id gpio_d1500_match[] = { + { + .compatible = "wb_gpio_d1500", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, gpio_d1500_match); + +static struct platform_driver wb_gpio_driver = { + .driver = { + .name = GPIO_NAME, + .of_match_table = gpio_d1500_match, + }, + .probe = wb_gpio_probe, + .remove = wb_gpio_remove, +}; + +module_platform_driver(wb_gpio_driver); + +MODULE_DESCRIPTION("d1500 gpio driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_device.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_device.c new file mode 100644 index 000000000000..75f883b5909d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_device.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +static int g_wb_gpio_device_debug = 0; +static int g_wb_gpio_device_error = 0; + +module_param(g_wb_gpio_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_gpio_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_GPIO_DEVICE_VERBOSE(fmt, args...) do { \ + if (g_wb_gpio_device_debug) { \ + printk(KERN_INFO "[WB_GPIO_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_GPIO_DEVICE_ERROR(fmt, args...) do { \ + if (g_wb_gpio_device_error) { \ + printk(KERN_ERR "[WB_GPIO_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static void wb_gpio_device_release(struct device *dev) +{ + return; +} + +static struct platform_device wb_gpio_d1500_device = { + .name = "wb_gpio_d1500", + .id = -1, + .dev = { + .release = wb_gpio_device_release, + }, +}; + +static int __init wb_gpio_device_init(void) +{ + WB_GPIO_DEVICE_VERBOSE("wb_gpio_device_init enter!\n"); + return platform_device_register(&wb_gpio_d1500_device); +} + +static void __exit wb_gpio_device_exit(void) +{ + WB_GPIO_DEVICE_VERBOSE("wb_gpio_device_exit enter!\n"); + return platform_device_unregister(&wb_gpio_d1500_device); +} + +module_init(wb_gpio_device_init); +module_exit(wb_gpio_device_exit); +MODULE_DESCRIPTION("GPIO Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.c new file mode 100644 index 000000000000..14f85f33f572 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.c @@ -0,0 +1,774 @@ +/* + * wb_io_dev.c + * ko to read/write i2c client through /dev/XXX device + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_i2c_dev.h" + +#define MAX_I2C_DEV_NUM (256) +#define FPGA_MAX_LEN (256) +#define MAX_NAME_SIZE (20) +#define MAX_BUS_WIDTH (16) +#define TRANSFER_WRITE_BUFF (FPGA_MAX_LEN + MAX_BUS_WIDTH) + +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) + +static int g_i2c_dev_debug = 0; +static int g_i2c_dev_error = 0; + +module_param(g_i2c_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_i2c_dev_error, int, S_IRUGO | S_IWUSR); + +#define I2C_DEV_DEBUG_DMESG(fmt, args...) do { \ + if (g_i2c_dev_debug) { \ + printk(KERN_ERR "[I2C_DEV][DEBUG][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define I2C_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_i2c_dev_error) { \ + printk(KERN_ERR "[I2C_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct i2c_dev_info* i2c_dev_arry[MAX_I2C_DEV_NUM]; + +struct i2c_dev_info { + const char *name; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + uint32_t i2c_len; + struct miscdevice misc; + struct i2c_client *client; +}; + +static int transfer_read(struct i2c_client *client, u8 *buf, loff_t regaddr, size_t count) +{ + struct i2c_adapter *adap; + int i; + u8 offset_buf[MAX_BUS_WIDTH]; + struct i2c_msg msgs[2]; + int msgs_num, ret; + struct i2c_dev_info *i2c_dev; + + if (!client) { + I2C_DEV_DEBUG_ERROR("can't get read client\n"); + return -ENODEV; + } + + adap = client->adapter; + if (!adap) { + I2C_DEV_DEBUG_ERROR("can't get read adap\n"); + return -ENODEV; + } + + i2c_dev = i2c_get_clientdata(client); + if (!i2c_dev) { + I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\n"); + return -ENODEV; + } + + i = 0; + + mem_clear(offset_buf, sizeof(offset_buf)); + + switch (i2c_dev->addr_bus_width) { + case WIDTH_4Byte: + offset_buf[i++] = (regaddr >> 24) & 0xFF; + offset_buf[i++] = (regaddr >> 16) & 0xFF; + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + offset_buf[i++] = regaddr & 0xFF; + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\n", + i2c_dev->addr_bus_width); + return -EINVAL; + } + + if (adap->algo->master_xfer) { + mem_clear(msgs, sizeof(msgs)); + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = i2c_dev->addr_bus_width; + msgs[0].buf = offset_buf; + + msgs[1].addr = client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = count; + msgs[1].buf = buf; + + msgs_num = 2; + ret = i2c_transfer(client->adapter, msgs, msgs_num); + if (ret != msgs_num) { + I2C_DEV_DEBUG_ERROR("i2c_transfer read error\n"); + return -EINVAL; + } + } else { + I2C_DEV_DEBUG_ERROR("don't find read master_xfer\n"); + return -EINVAL; + + } + return 0; +} + +static int transfer_write(struct i2c_client *client, u8 *buf, loff_t regaddr, size_t count) +{ + struct i2c_adapter *adap; + int i; + u8 offset_buf[TRANSFER_WRITE_BUFF]; + struct i2c_msg msgs[1]; + int msgs_num, ret; + struct i2c_dev_info *i2c_dev; + + if (!client) { + I2C_DEV_DEBUG_ERROR("can't get write client\n"); + return -ENODEV; + } + + adap = client->adapter; + if (!adap) { + I2C_DEV_DEBUG_ERROR("can't get write adap\n"); + return -ENODEV; + } + + i2c_dev = i2c_get_clientdata(client); + if (!i2c_dev) { + I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\n"); + return -ENODEV; + } + + i = 0; + + mem_clear(offset_buf, sizeof(offset_buf)); + + switch (i2c_dev->addr_bus_width) { + case WIDTH_4Byte: + offset_buf[i++] = (regaddr >> 24) & 0xFF; + offset_buf[i++] = (regaddr >> 16) & 0xFF; + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + offset_buf[i++] = regaddr & 0xFF; + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\n", + i2c_dev->addr_bus_width); + return -EINVAL; + } + + memcpy(offset_buf + i2c_dev->addr_bus_width, buf, count); + + if (adap->algo->master_xfer) { + mem_clear(msgs, sizeof(msgs)); + + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = i2c_dev->addr_bus_width + count; + msgs[0].buf = offset_buf; + + msgs_num = 1; + ret = i2c_transfer(adap, msgs, msgs_num); + if (ret != msgs_num) { + I2C_DEV_DEBUG_ERROR("i2c_transfer write error\n"); + return -EINVAL; + } + } else { + I2C_DEV_DEBUG_ERROR("don't find write master_xfer\n"); + return -EINVAL; + } + + return 0; +} + +static long i2c_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int i2c_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct i2c_dev_info *i2c_dev; + + i2c_dev = i2c_dev_arry[minor]; + if (i2c_dev == NULL) { + return -ENODEV; + } + + file->private_data = i2c_dev; + + return 0; +} + +static int i2c_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static int device_read(struct i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u8 tmp_offset; + u8 val[FPGA_MAX_LEN]; + u32 width, rd_len, per_len, tmp; + u32 max_per_len; + + if (offset > i2c_dev->i2c_len) { + I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, count: %lu, EOF.\n", + offset, i2c_dev->i2c_len, count); + return 0; + } + + if (count > (i2c_dev->i2c_len - offset)) { + I2C_DEV_DEBUG_DMESG("read count out of range. input len:%lu, read len:%u.\n", + count, i2c_dev->i2c_len - offset); + count = i2c_dev->i2c_len - offset; + } + + if (count == 0) { + I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, read len: %lu, EOF.\n", + offset, i2c_dev->i2c_len, count); + return 0; + } + + width = i2c_dev->data_bus_width; + switch (width) { + case WIDTH_4Byte: + tmp_offset = offset & 0x3; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + break; + case WIDTH_2Byte: + tmp_offset = offset & 0x1; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + break; + case WIDTH_1Byte: + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\n", width); + return -EINVAL; + } + + max_per_len = i2c_dev->per_rd_len; + tmp = (width - 1) & count; + rd_len = (tmp == 0) ? count : count + width - tmp; + per_len = (rd_len > max_per_len) ? (max_per_len) : (rd_len); + + mem_clear(val, sizeof(val)); + for (i = 0; i < rd_len; i += per_len) { + ret = transfer_read(i2c_dev->client, val + i, offset + i, per_len); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("read error.read offset = %u\n", (offset + i)); + return -EFAULT; + } + } + + if (width == WIDTH_1Byte) { + memcpy(buf, val, count); + } else { + for (i = 0; i < count; i += width) { + for (j = 0; (j < width) && (i + j < count); j++) { + buf[i + j] = val[i + width - j - 1]; + } + } + } + + return count; +} + +static int device_write(struct i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u8 tmp_offset; + u32 width; + u8 val[FPGA_MAX_LEN]; + u32 wr_len, per_len, tmp; + u32 max_per_len; + + if (offset > i2c_dev->i2c_len) { + I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, count: %lu, EOF.\n", + offset, i2c_dev->i2c_len, count); + return 0; + } + + if (count > (i2c_dev->i2c_len - offset)) { + I2C_DEV_DEBUG_DMESG("read count out of range. input len:%lu, read len:%u.\n", + count, i2c_dev->i2c_len - offset); + count = i2c_dev->i2c_len - offset; + } + + if (count == 0) { + I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, read len: %lu, EOF.\n", + offset, i2c_dev->i2c_len, count); + return 0; + } + + width = i2c_dev->data_bus_width; + switch (width) { + case WIDTH_4Byte: + tmp_offset = offset & 0x3; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + break; + case WIDTH_2Byte: + tmp_offset = offset & 0x1; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + break; + case WIDTH_1Byte: + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\n", width); + return -EINVAL; + } + + mem_clear(val, sizeof(val)); + + if (width == WIDTH_1Byte) { + memcpy(val, buf, count); + } else { + for (i = 0; i < count; i += width) { + for (j = 0; (j < width) && (i + j < count); j++) { + val[i + width - j - 1] = buf[i + j]; + } + } + } + + max_per_len = i2c_dev->per_wr_len; + tmp = (width - 1) & count; + wr_len = (tmp == 0) ? count : count + width - tmp; + per_len = (wr_len > max_per_len) ? (max_per_len) : (wr_len); + + for (i = 0; i < wr_len; i += per_len) { + ret = transfer_write(i2c_dev->client, val + i, offset + i, per_len); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("write error.offset = %u\n", (offset + i)); + return -EFAULT; + } + } + return count; +} + +static ssize_t i2c_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + u8 val[FPGA_MAX_LEN]; + int ret, read_len; + struct i2c_dev_info *i2c_dev; + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("can't get read private_data.n"); + return -EINVAL; + } + + if (count == 0) { + I2C_DEV_DEBUG_ERROR("Invalid params, read count is 0.n"); + return -EINVAL; + } + + if (count > sizeof(val)) { + I2C_DEV_DEBUG_DMESG("read conut %lu exceed max %lu.\n", count, sizeof(val)); + count = sizeof(val); + } + + mem_clear(val, sizeof(val)); + read_len = device_read(i2c_dev, (uint32_t)*offset, val, count); + if (read_len < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, (uint32_t)*offset, count); + return read_len; + } + + if (access_ok(buf, read_len)) { + I2C_DEV_DEBUG_DMESG("user space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + if (copy_to_user(buf, val, read_len)) { + I2C_DEV_DEBUG_ERROR("copy_to_user failed.\n"); + return -EFAULT; + } + } else { + I2C_DEV_DEBUG_DMESG("kernel space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + memcpy(buf, val, read_len); + } + + *offset += read_len; + ret = read_len; + return ret; +} + +static ssize_t i2c_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + int ret; + + I2C_DEV_DEBUG_DMESG("i2c_dev_read_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, to->count, iocb->ki_pos); + ret = i2c_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos); + return ret; +} + +static ssize_t i2c_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) +{ + u8 val[FPGA_MAX_LEN]; + int write_len; + struct i2c_dev_info *i2c_dev; + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("get write private_data error.\n"); + return -EINVAL; + } + + if (count == 0) { + I2C_DEV_DEBUG_ERROR("Invalid params, write count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(val)) { + I2C_DEV_DEBUG_DMESG("write conut %lu exceed max %lu.\n", count, sizeof(val)); + count = sizeof(val); + } + + mem_clear(val, sizeof(val)); + if (access_ok(buf, count)) { + I2C_DEV_DEBUG_DMESG("user space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + if (copy_from_user(val, buf, count)) { + I2C_DEV_DEBUG_ERROR("copy_from_user failed.\n"); + return -EFAULT; + } + } else { + I2C_DEV_DEBUG_DMESG("kernel space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + memcpy(val, buf, count); + } + + write_len = device_write(i2c_dev, (uint32_t)*offset, val, count); + if (write_len < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%llx, len:%lu.\n", + i2c_dev->name, *offset, count); + return write_len; + } + + *offset += write_len; + return write_len; +} + +static ssize_t i2c_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + int ret; + + I2C_DEV_DEBUG_DMESG("i2c_dev_write_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, from->count, iocb->ki_pos); + ret = i2c_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos); + return ret; +} + +static loff_t i2c_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + struct i2c_dev_info *i2c_dev; + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev is NULL, llseek failed.\n"); + return -EINVAL; + } + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + I2C_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + if (offset > i2c_dev->i2c_len) { + I2C_DEV_DEBUG_ERROR("SEEK_SET out of range, offset:%lld, i2c_len:0x%x.\n", + offset, i2c_dev->i2c_len); + ret = - EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (((file->f_pos + offset) > i2c_dev->i2c_len) || ((file->f_pos + offset) < 0)) { + I2C_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld, i2c_len:0x%x.\n", + file->f_pos, offset, i2c_dev->i2c_len); + ret = - EINVAL; + break; + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + I2C_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static const struct file_operations i2c_dev_fops = { + .owner = THIS_MODULE, + .llseek = i2c_dev_llseek, + .read_iter = i2c_dev_read_iter, + .write_iter = i2c_dev_write_iter, + .unlocked_ioctl = i2c_dev_ioctl, + .open = i2c_dev_open, + .release = i2c_dev_release, +}; + +static struct i2c_dev_info * dev_match(const char *path) +{ + struct i2c_dev_info * i2c_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + for (i = 0; i < MAX_I2C_DEV_NUM; i++) { + if (i2c_dev_arry[ i ] == NULL) { + continue; + } + i2c_dev = i2c_dev_arry[ i ]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", i2c_dev->name); + if (!strcmp(path, dev_name)) { + I2C_DEV_DEBUG_DMESG("get dev_name = %s, minor = %d\n", dev_name, i); + return i2c_dev; + } + } + + return NULL; +} + +int i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct i2c_dev_info *i2c_dev = NULL; + int ret; + + if(path == NULL){ + I2C_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + I2C_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > FPGA_MAX_LEN) { + I2C_DEV_DEBUG_ERROR("read conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN); + return -EINVAL; + } + + i2c_dev = dev_match(path); + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_read(i2c_dev, offset, buf, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("fpga i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(i2c_device_func_read); + +int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct i2c_dev_info *i2c_dev = NULL; + int ret; + + if(path == NULL){ + I2C_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + I2C_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > FPGA_MAX_LEN) { + I2C_DEV_DEBUG_ERROR("write conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN); + return -EINVAL; + } + + i2c_dev = dev_match(path); + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_write (i2c_dev, offset, buf, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(i2c_device_func_write); + +static int i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int ret = 0; + struct i2c_dev_info *i2c_dev; + struct miscdevice *misc; + i2c_dev_device_t *i2c_dev_device; + + i2c_dev = devm_kzalloc(&client->dev, sizeof(struct i2c_dev_info), GFP_KERNEL); + if (!i2c_dev) { + dev_err(&client->dev, "devm_kzalloc error. \n"); + return -ENOMEM; + } + + i2c_set_clientdata(client, i2c_dev); + i2c_dev->client = client; + + if (client->dev.of_node) { + + ret += of_property_read_string(client->dev.of_node, "i2c_name", &i2c_dev->name); + ret += of_property_read_u32(client->dev.of_node, "data_bus_width", &i2c_dev->data_bus_width); + ret += of_property_read_u32(client->dev.of_node, "addr_bus_width", &i2c_dev->addr_bus_width); + ret += of_property_read_u32(client->dev.of_node, "per_rd_len", &i2c_dev->per_rd_len); + ret += of_property_read_u32(client->dev.of_node, "per_wr_len", &i2c_dev->per_wr_len); + ret += of_property_read_u32(client->dev.of_node, "i2c_len", &i2c_dev->i2c_len); + if (ret != 0) { + dev_err(&client->dev, "dts config error.ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (client->dev.platform_data == NULL) { + dev_err(&client->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + i2c_dev_device = client->dev.platform_data; + i2c_dev->name = i2c_dev_device->i2c_name; + i2c_dev->data_bus_width = i2c_dev_device->data_bus_width; + i2c_dev->addr_bus_width = i2c_dev_device->addr_bus_width; + i2c_dev->per_rd_len = i2c_dev_device->per_rd_len; + i2c_dev->per_wr_len = i2c_dev_device->per_wr_len; + i2c_dev->i2c_len = i2c_dev_device->i2c_len; + } + + if ((i2c_dev->per_rd_len & (i2c_dev->data_bus_width - 1)) || + (i2c_dev->per_wr_len & (i2c_dev->data_bus_width - 1))) { + dev_err(&client->dev, "Invalid config per_rd_len %d per_wr_len %d data bus_width %d.\n", + i2c_dev->per_rd_len, i2c_dev->per_wr_len, i2c_dev->data_bus_width); + return -ENXIO; + } + + if ((i2c_dev->i2c_len == 0) || (i2c_dev->i2c_len & (i2c_dev->data_bus_width - 1))) { + dev_err(&client->dev, "Invalid config i2c_len %d, data bus_width %d.\n", + i2c_dev->i2c_len, i2c_dev->data_bus_width); + return -ENXIO; + } + + misc = &i2c_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = i2c_dev->name; + misc->fops = &i2c_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&client->dev, "register %s faild.\n", misc->name); + return -ENXIO; + } + + if (misc->minor >= MAX_I2C_DEV_NUM) { + dev_err(&client->dev, "minor number beyond the limit! is %d.\n", misc->minor); + misc_deregister(misc); + return -ENXIO; + } + i2c_dev_arry[misc->minor] = i2c_dev; + + dev_info(&client->dev, "register %u addr_bus_width %u data_bus_width 0x%x i2c_len device %s with %u per_rd_len %u per_wr_len success.\n", + i2c_dev->addr_bus_width, i2c_dev->data_bus_width, i2c_dev->i2c_len, i2c_dev->name, i2c_dev->per_rd_len, i2c_dev->per_wr_len); + + return 0; +} + +static int i2c_dev_remove(struct i2c_client *client) +{ + int i; + for (i = 0; i < MAX_I2C_DEV_NUM; i++) { + if (i2c_dev_arry[i] != NULL) { + misc_deregister(&i2c_dev_arry[i]->misc); + i2c_dev_arry[i] = NULL; + } + } + return 0; +} + +static const struct i2c_device_id i2c_dev_id[] = { + { "wb-i2c-dev", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, i2c_dev_id); + +static const struct of_device_id i2c_dev_of_match[] = { + { .compatible = "wb-i2c-dev" }, + { }, +}; +MODULE_DEVICE_TABLE(of, i2c_dev_of_match); + +static struct i2c_driver i2c_dev_driver = { + .driver = { + .name = "wb-i2c-dev", + .of_match_table = i2c_dev_of_match, + }, + .probe = i2c_dev_probe, + .remove = i2c_dev_remove, + .id_table = i2c_dev_id, +}; +module_i2c_driver(i2c_dev_driver); + +MODULE_DESCRIPTION("i2c dev driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.h new file mode 100644 index 000000000000..9cc95d88e804 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.h @@ -0,0 +1,20 @@ +#ifndef __WB_I2C_DEV_H__ +#define __WB_I2C_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define I2C_DEV_NAME_MAX_LEN (64) + +typedef struct i2c_dev_device_s { + struct i2c_client *client; + uint32_t i2c_bus; + uint32_t i2c_addr; + char i2c_name[I2C_DEV_NAME_MAX_LEN]; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + uint32_t i2c_len; +} i2c_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.c new file mode 100644 index 000000000000..1f69d96bad0b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.c @@ -0,0 +1,1143 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * i2c-ocores.c: I2C bus driver for OpenCores I2C controller + * (https://opencores.org/project/i2c/overview) + * + * Peter Korsgaard + * + * Support for the GRLIB port of the controller by + * Andreas Larsson + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_i2c_ocores.h" + +#define OCORES_FLAG_POLL BIT(0) + +/* registers */ +#define OCI2C_PRELOW (0) +#define OCI2C_PREHIGH (1) +#define OCI2C_CONTROL (2) +#define OCI2C_DATA (3) +#define OCI2C_CMD (4) /* write only */ +#define OCI2C_STATUS (4) /* read only, same address as OCI2C_CMD */ + +#define OCI2C_CTRL_IEN (0x40) +#define OCI2C_CTRL_EN (0x80) + +#define OCI2C_CMD_START (0x91) +#define OCI2C_CMD_STOP (0x41) +#define OCI2C_CMD_READ (0x21) +#define OCI2C_CMD_WRITE (0x11) +#define OCI2C_CMD_READ_ACK (0x21) +#define OCI2C_CMD_READ_NACK (0x29) +#define OCI2C_CMD_IACK (0x01) + +#define OCI2C_STAT_IF (0x01) +#define OCI2C_STAT_TIP (0x02) +#define OCI2C_STAT_ARBLOST (0x20) +#define OCI2C_STAT_BUSY (0x40) +#define OCI2C_STAT_NACK (0x80) + +#define STATE_DONE (0) +#define STATE_START (1) +#define STATE_WRITE (2) +#define STATE_READ (3) +#define STATE_ERROR (4) + +#define TYPE_OCORES (0) +#define TYPE_GRLIB (1) + +#define OCORE_WAIT_SCH (40) +#define REG_IO_WIDTH_1 (1) +#define REG_IO_WIDTH_2 (2) +#define REG_IO_WIDTH_4 (4) + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) + +typedef struct wb_pci_dev_s { + uint32_t domain; + uint32_t bus; + uint32_t slot; + uint32_t fn; +} wb_pci_dev_t; + +/* + * 'process_lock' exists because ocores_process() and ocores_process_timeout() + * can't run in parallel. + */ +struct ocores_i2c { + uint32_t base_addr; + uint32_t reg_shift; + uint32_t reg_io_width; + unsigned long flags; + wait_queue_head_t wait; + struct i2c_adapter adap; + int adap_nr; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; + spinlock_t process_lock; + uint32_t ip_clock_khz; + uint32_t bus_clock_khz; + void (*setreg)(struct ocores_i2c *i2c, int reg, u32 value); + u32 (*getreg)(struct ocores_i2c *i2c, int reg); + const char *dev_name; + uint32_t reg_access_mode; + uint32_t big_endian; + uint32_t irq_offset; + wb_pci_dev_t wb_pci_dev; + struct device *dev; +}; + +int g_wb_ocores_i2c_debug = 0; +int g_wb_ocores_i2c_error = 0; +int g_wb_ocores_i2c_xfer = 0; + +module_param(g_wb_ocores_i2c_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_ocores_i2c_error, int, S_IRUGO | S_IWUSR); +module_param(g_wb_ocores_i2c_xfer, int, S_IRUGO | S_IWUSR); + +#define OCORES_I2C_VERBOSE(fmt, args...) do { \ + if (g_wb_ocores_i2c_debug) { \ + printk(KERN_INFO "[OCORES_I2C][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define OCORES_I2C_ERROR(fmt, args...) do { \ + if (g_wb_ocores_i2c_error) { \ + printk(KERN_ERR "[OCORES_I2C][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define OCORES_I2C_XFER(fmt, args...) do { \ + if (g_wb_ocores_i2c_xfer) { \ + printk(KERN_INFO "[OCORES_I2C][XFER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +extern int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +#if 0 +int __attribute__((weak)) i2c_device_func_read(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak i2c func read\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) i2c_device_func_write(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak i2c func write\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) pcie_device_func_read(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak pcie func read\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) pcie_device_func_write(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak pcie func write\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) io_device_func_read(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak io func read\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) io_device_func_write(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak io func write\r\n"); + return -EINVAL; +} +#endif +static int ocores_i2c_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + OCORES_I2C_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + OCORES_I2C_ERROR("kernel_read failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int ocores_i2c_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + OCORES_I2C_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + OCORES_I2C_ERROR("kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int ocores_i2c_reg_write(struct ocores_i2c *i2c, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (i2c->reg_access_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = ocores_i2c_file_write(i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(i2c->dev_name, pos, val, size); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_write(i2c->dev_name, pos, val, size); + break; + default: + OCORES_I2C_ERROR("err func_mode, write failed.\n"); + return -EINVAL; + } + + return ret; +} + +static int ocores_i2c_reg_read(struct ocores_i2c *i2c, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (i2c->reg_access_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_read(i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = ocores_i2c_file_read(i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_read(i2c->dev_name, pos, val, size); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_read(i2c->dev_name, pos, val, size); + break; + default: + OCORES_I2C_ERROR("err func_mode, read failed.\n"); + return -EINVAL; + } + + return ret; +} +static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_1]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0Xff); + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_1); + return; +} + +static void oc_setreg_16(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0Xff); + buf_tmp[1] = (value >> 8) & 0xff; + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_2); + return; +} + +static void oc_setreg_32(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0xff); + buf_tmp[1] = (value >> 8) & 0xff; + buf_tmp[2] = (value >> 16) & 0xff; + buf_tmp[3] = (value >> 24) & 0xff; + + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_4); + return; +} + +static void oc_setreg_16be(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value >> 8) & 0xff; + buf_tmp[1] = (value & 0Xff); + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_2); + return; +} + +static void oc_setreg_32be(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value >> 24) & 0xff; + buf_tmp[1] = (value >> 16) & 0xff; + buf_tmp[2] = (value >> 8) & 0xff; + buf_tmp[3] = (value & 0xff); + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_4); + return; +} + +static inline u32 oc_getreg_8(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_1]; + u32 value, pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_1); + value = buf_tmp[0]; + + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + return value; +} + +static inline u32 oc_getreg_16(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 value, pos; + int i; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + mem_clear(buf_tmp, sizeof(buf_tmp)); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_2); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_2 ; i++) { + value |= buf_tmp[i] << (8 * i); + } + + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_getreg_32(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 value, pos; + int i; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + mem_clear(buf_tmp, sizeof(buf_tmp)); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_4); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_4 ; i++) { + value |= buf_tmp[i] << (8 * i); + } + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_getreg_16be(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 value, pos; + int i; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_2); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_2 ; i++) { + value |= buf_tmp[i] << (8 * (REG_IO_WIDTH_2 -i - 1)); + } + + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_getreg_32be(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 value, pos; + int i; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_4); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_4 ; i++) { + value |= buf_tmp[i] << (8 * (REG_IO_WIDTH_4 -i - 1)); + } + + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + return value; + +} + +static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u32 value) +{ + i2c->setreg(i2c, reg, value); + return; +} + +static inline u32 oc_getreg(struct ocores_i2c *i2c, int reg) +{ + return i2c->getreg(i2c, reg); +} + +static int ocores_msg_check(struct i2c_msg *msgs, int num) +{ + int i, ret = 0; + + if (!msgs) { + ret = -EFAULT; + goto out; + } + + for (i = 0; i < num; ++i) { + if (!msgs[i].buf) { + ret = -EFAULT; + goto out; + } + } + +out: + return ret; +} + +static void ocores_process(struct ocores_i2c *i2c, u8 stat) +{ + struct i2c_msg *msg = i2c->msg; + + OCORES_I2C_XFER("Enter nr %d.\n", i2c->adap.nr); + if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + /* stop has been sent */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + wake_up(&i2c->wait); + OCORES_I2C_XFER("stop has been sent, exit.\n"); + goto out; + } + + /* error? */ + if (stat & OCI2C_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + OCORES_I2C_XFER("error exit, lose arbitration.\n"); + goto out; + } + + if (ocores_msg_check(i2c->msg, i2c->nmsgs) != 0) { + OCORES_I2C_XFER("msg buf is NULL\n"); + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + goto out; + } + + if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { + i2c->state = + (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & OCI2C_STAT_NACK) { + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + OCORES_I2C_XFER("OCI2C_STAT_NACK, exit.\n"); + goto out; + } + } else { + msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + OCORES_I2C_XFER("Enter end of msg.\n"); + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { /* end? */ + /* send start? */ + if (!(msg->flags & I2C_M_NOSTART)) { + u8 addr = i2c_8bit_addr_from_msg(msg); + + i2c->state = STATE_START; + + oc_setreg(i2c, OCI2C_DATA, addr); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + OCORES_I2C_XFER("send start, exit.\n"); + goto out; + } + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } else { + i2c->state = STATE_DONE; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + OCORES_I2C_XFER("send OCI2C_CMD_STOP, exit.\n"); + goto out; + } + } + + if (i2c->state == STATE_READ) { + oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? + OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); + } else { + oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); + } + +out: + OCORES_I2C_XFER("normal, exit nr %d.\n", i2c->adap.nr); + return; +} + +static irqreturn_t ocores_isr(int irq, void *dev_id) +{ + struct ocores_i2c *i2c = dev_id; + u8 stat; + unsigned long flags; + + if (!i2c) { + return IRQ_NONE; + } + + spin_lock_irqsave(&i2c->process_lock, flags); + stat = oc_getreg(i2c, OCI2C_STATUS); + if (!(stat & OCI2C_STAT_IF)) { + spin_unlock_irqrestore(&i2c->process_lock, flags); + return IRQ_NONE; + } + OCORES_I2C_XFER("Enter, irq %d nr %d addr 0x%x.\n", irq, i2c->adap.nr, (!i2c->msg)? 0 : i2c->msg->addr); + ocores_process(i2c, stat); + OCORES_I2C_XFER("Leave, irq %d nr %d addr 0x%x.\n", irq, i2c->adap.nr, (!i2c->msg)? 0 : i2c->msg->addr); + spin_unlock_irqrestore(&i2c->process_lock, flags); + + return IRQ_HANDLED; +} + +/** + * Process timeout event + * @i2c: ocores I2C device instance + */ +static void ocores_process_timeout(struct ocores_i2c *i2c) +{ + unsigned long flags; + + spin_lock_irqsave(&i2c->process_lock, flags); + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + mdelay(1); + spin_unlock_irqrestore(&i2c->process_lock, flags); + return; +} + +/** + * Wait until something change in a given register + * @i2c: ocores I2C device instance + * @reg: register to query + * @mask: bitmask to apply on register value + * @val: expected result + * @timeout: timeout in jiffies + * + * Timeout is necessary to avoid to stay here forever when the chip + * does not answer correctly. + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_wait(struct ocores_i2c *i2c, + int reg, u8 mask, u8 val, + const unsigned long timeout) +{ + u8 status; + unsigned long j, jiffies_tmp; + unsigned int usleep; + + usleep = OCORE_WAIT_SCH; + j = jiffies + timeout; + while (1) { + jiffies_tmp = jiffies; + status = oc_getreg(i2c, reg); + + if ((status & mask) == val) { + break; + } + + if (time_after(jiffies_tmp, j)) { + OCORES_I2C_XFER("STATUS timeout, mask[0x%x] val[0x%x] status[0x%x]\n", mask, val, status); + return -ETIMEDOUT; + } + usleep_range(usleep,usleep + 1); + } + return 0; + +} + +/** + * Wait until is possible to process some data + * @i2c: ocores I2C device instance + * + * Used when the device is in polling mode (interrupts disabled). + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_poll_wait(struct ocores_i2c *i2c) +{ + u8 mask; + int err; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* transfer is over */ + mask = OCI2C_STAT_BUSY; + } else { + /* on going transfer */ + mask = OCI2C_STAT_TIP; + /* + * We wait for the data to be transferred (8bit), + * then we start polling on the ACK/NACK bit + */ + udelay((8 * 1000) / i2c->bus_clock_khz); + } + + /* + * once we are here we expect to get the expected result immediately + * so if after 100ms we timeout then something is broken. + */ + err = ocores_wait(i2c, OCI2C_STATUS, mask, 0, msecs_to_jiffies(100)); + if (err) { + OCORES_I2C_XFER("STATUS timeout, bit 0x%x did not clear in 100ms, err %d\n", mask, err); + } + return err; +} + +/** + * It handles an IRQ-less transfer + * @i2c: ocores I2C device instance + * + * Even if IRQ are disabled, the I2C OpenCore IP behavior is exactly the same + * (only that IRQ are not produced). This means that we can re-use entirely + * ocores_isr(), we just add our polling code around it. + * + * It can run in atomic context + */ +static int ocores_process_polling(struct ocores_i2c *i2c) +{ + irqreturn_t ret; + int err; + + while (1) { + err = ocores_poll_wait(i2c); + if (err) { + i2c->state = STATE_ERROR; + break; /* timeout */ + } + + ret = ocores_isr(-1, i2c); + if (ret == IRQ_NONE) { + break; /* all messages have been transferred */ + } + } + + return err; +} + +static int ocores_xfer_core(struct ocores_i2c *i2c, + struct i2c_msg *msgs, int num, + bool polling) +{ + int ret; + u8 ctrl; + unsigned long flags; + + OCORES_I2C_VERBOSE("Enter ocores_xfer_core. polling mode:%d.\n", polling); + spin_lock_irqsave(&i2c->process_lock, flags); + + ctrl = oc_getreg(i2c, OCI2C_CONTROL); + if (polling) { + oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~OCI2C_CTRL_IEN); + } else { + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN); + } + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = STATE_START; + + oc_setreg(i2c, OCI2C_DATA, i2c_8bit_addr_from_msg(i2c->msg)); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + + spin_unlock_irqrestore(&i2c->process_lock, flags); + + if (polling) { + ret = ocores_process_polling(i2c); + if (ret) { + ocores_process_timeout(i2c); + return -ETIMEDOUT; + } + } else { + ret = wait_event_timeout(i2c->wait, + (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ); + if (ret == 0) { + ocores_process_timeout(i2c); + return -ETIMEDOUT; + } + } + + return (i2c->state == STATE_DONE) ? num : -EIO; +} + +static int ocores_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct ocores_i2c *i2c; + int ret; + + OCORES_I2C_VERBOSE("Enter ocores_xfer.\n"); + if (!adap || ocores_msg_check(msgs, num)) { + OCORES_I2C_ERROR("[MAY BE USER SPACE ERROR]:msg buf is NULL\n"); + return -EFAULT; + } + OCORES_I2C_VERBOSE("i2c bus:%d, msgs num:%d.\n", adap->nr, num); + + i2c = i2c_get_adapdata(adap); + + if (i2c->flags & OCORES_FLAG_POLL) { + ret = ocores_xfer_core(i2c, msgs, num, true); + } else { + ret = ocores_xfer_core(i2c, msgs, num, false); + } + + return ret; +} + +static int ocores_init(struct device *dev, struct ocores_i2c *i2c) +{ + int prescale; + int diff; + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* make sure the device is disabled */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); + + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + dev_err(dev, "Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } + + oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); + oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); + + /* Init the device */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); + + return 0; +} + +static u32 ocores_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm ocores_algorithm = { + .master_xfer = ocores_xfer, + .functionality = ocores_func, +}; + +static const struct i2c_adapter ocores_adapter = { + .owner = THIS_MODULE, + .name = "wb-i2c-ocores", + .class = I2C_CLASS_DEPRECATED, + .algo = &ocores_algorithm, +}; + +static const struct of_device_id ocores_i2c_match[] = { + { + .compatible = "opencores,wb-i2c-ocores", + .data = (void *)TYPE_OCORES, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ocores_i2c_match); + +static int fpga_ocores_i2c_get_irq(struct ocores_i2c *i2c) +{ + int devfn, irq; + struct device *dev; + wb_pci_dev_t *wb_pci_dev; + struct pci_dev *pci_dev; + i2c_ocores_device_t *i2c_ocores_device; + int ret; + + dev = i2c->dev; + wb_pci_dev = &i2c->wb_pci_dev; + + if (dev->of_node) { + ret = 0; + ret += of_property_read_u32(dev->of_node, "pci_domain", &wb_pci_dev->domain); + ret += of_property_read_u32(dev->of_node, "pci_bus", &wb_pci_dev->bus); + ret += of_property_read_u32(dev->of_node, "pci_slot", &wb_pci_dev->slot); + ret += of_property_read_u32(dev->of_node, "pci_fn", &wb_pci_dev->fn); + + if (ret != 0) { + OCORES_I2C_ERROR("dts config error, ret:%d.\n", ret); + ret = -EINVAL; + return ret; + } + } else { + if (i2c->dev->platform_data == NULL) { + OCORES_I2C_ERROR("Failed to get platform data config.\n"); + ret = -EINVAL; + return ret; + } + i2c_ocores_device = i2c->dev->platform_data; + wb_pci_dev->domain = i2c_ocores_device->pci_domain; + wb_pci_dev->bus = i2c_ocores_device->pci_bus; + wb_pci_dev->slot = i2c_ocores_device->pci_slot; + wb_pci_dev->fn = i2c_ocores_device->pci_fn; + } + + OCORES_I2C_VERBOSE("pci_domain:0x%x, pci_bus:0x%x, pci_slot:0x%x, pci_fn:0x%x.\n", + wb_pci_dev->domain, wb_pci_dev->bus, wb_pci_dev->slot, wb_pci_dev->fn); + + devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); + if (pci_dev == NULL) { + OCORES_I2C_ERROR("Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bus, devfn); + return -ENODEV; + } + irq = pci_dev->irq + i2c->irq_offset; + OCORES_I2C_VERBOSE("get irq no:%d.\n", irq); + return irq; +} + +static int ocores_i2c_config_init(struct ocores_i2c *i2c) +{ + int ret; + struct device *dev; + i2c_ocores_device_t *i2c_ocores_device; + + dev = i2c->dev; + ret = 0; + + if (dev->of_node) { + ret += of_property_read_string(dev->of_node, "dev_name", &i2c->dev_name); + ret += of_property_read_u32(dev->of_node, "dev_base", &i2c->base_addr); + ret += of_property_read_u32(dev->of_node, "reg_shift", &i2c->reg_shift); + ret += of_property_read_u32(dev->of_node, "reg_io_width", &i2c->reg_io_width); + ret += of_property_read_u32(dev->of_node, "ip_clock_khz", &i2c->ip_clock_khz); + ret += of_property_read_u32(dev->of_node, "bus_clock_khz", &i2c->bus_clock_khz); + ret += of_property_read_u32(dev->of_node, "reg_access_mode", &i2c->reg_access_mode); + + if (ret != 0) { + OCORES_I2C_ERROR("dts config error, ret:%d.\n", ret); + ret = -ENXIO; + return ret; + } + } else { + if (i2c->dev->platform_data == NULL) { + OCORES_I2C_ERROR("Failed to get platform data config.\n"); + ret = -ENXIO; + return ret; + } + i2c_ocores_device = i2c->dev->platform_data; + i2c->dev_name = i2c_ocores_device->dev_name; + i2c->adap_nr = i2c_ocores_device->adap_nr; + i2c->big_endian = i2c_ocores_device->big_endian; + i2c->base_addr = i2c_ocores_device->dev_base; + i2c->reg_shift = i2c_ocores_device->reg_shift; + i2c->reg_io_width = i2c_ocores_device->reg_io_width; + i2c->ip_clock_khz = i2c_ocores_device->ip_clock_khz; + i2c->bus_clock_khz = i2c_ocores_device->bus_clock_khz; + i2c->reg_access_mode = i2c_ocores_device->reg_access_mode; + } + + OCORES_I2C_VERBOSE("name:%s, base:0x%x, reg_shift:0x%x, io_width:0x%x, ip_clock_khz:0x%x, bus_clock_khz:0x%x.\n", + i2c->dev_name, i2c->base_addr, i2c->reg_shift, i2c->reg_io_width, i2c->ip_clock_khz, i2c->bus_clock_khz); + OCORES_I2C_VERBOSE("reg access mode:%d.\n", i2c->reg_access_mode); + return ret; +} + +static int ocores_i2c_probe(struct platform_device *pdev) +{ + struct ocores_i2c *i2c; + int irq, ret; + bool be; + i2c_ocores_device_t *i2c_ocores_device; + + OCORES_I2C_VERBOSE("Enter main probe\n"); + + i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + spin_lock_init(&i2c->process_lock); + + i2c->dev = &pdev->dev; + ret = ocores_i2c_config_init(i2c); + if (ret !=0) { + dev_err(i2c->dev, "Failed to get ocores i2c dts config.\n"); + goto out; + } + + if (i2c->dev->of_node) { + if (of_property_read_u32(i2c->dev->of_node, "big_endian", &i2c->big_endian)) { + + be = 0; + } else { + be = i2c->big_endian; + } + } else { + be = i2c->big_endian; + } + + if (i2c->reg_io_width == 0) { + i2c->reg_io_width = 1; /* Set to default value */ + } + + if (!i2c->setreg || !i2c->getreg) { + switch (i2c->reg_io_width) { + case REG_IO_WIDTH_1: + i2c->setreg = oc_setreg_8; + i2c->getreg = oc_getreg_8; + break; + + case REG_IO_WIDTH_2: + i2c->setreg = be ? oc_setreg_16be : oc_setreg_16; + i2c->getreg = be ? oc_getreg_16be : oc_getreg_16; + break; + + case REG_IO_WIDTH_4: + i2c->setreg = be ? oc_setreg_32be : oc_setreg_32; + i2c->getreg = be ? oc_getreg_32be : oc_getreg_32; + break; + + default: + dev_err(i2c->dev, "Unsupported I/O width (%d)\n", + i2c->reg_io_width); + ret = -EINVAL; + goto out; + } + } + + init_waitqueue_head(&i2c->wait); + irq = -1; + + if (i2c->dev->of_node) { + if (of_property_read_u32(i2c->dev->of_node, "irq_offset", &i2c->irq_offset)) { + + i2c->flags |= OCORES_FLAG_POLL; + } else { + + irq = fpga_ocores_i2c_get_irq(i2c); + if (irq < 0 ) { + dev_err(i2c->dev, "Failed to get ocores i2c irq number, ret: %d.\n", irq); + ret = irq; + goto out; + } + } + } else { + if (i2c->dev->platform_data == NULL) { + + i2c->flags |= OCORES_FLAG_POLL; + OCORES_I2C_VERBOSE("Failed to get platform data config, set OCORES_FLAG_POLL.\n"); + } else { + i2c_ocores_device = i2c->dev->platform_data; + if (i2c_ocores_device->irq_type == 0) { + + i2c->flags |= OCORES_FLAG_POLL; + } else { + + irq = fpga_ocores_i2c_get_irq(i2c); + if (irq < 0 ) { + dev_err(i2c->dev, "Failed to get ocores i2c irq number, ret: %d.\n", irq); + ret = irq; + goto out; + } + } + } + } + + if (!(i2c->flags & OCORES_FLAG_POLL)) { + ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, + pdev->name, i2c); + if (ret) { + dev_err(i2c->dev, "Cannot claim IRQ\n"); + goto out; + } + } + + ret = ocores_init(i2c->dev, i2c); + if (ret) { + goto out; + } + + /* hook up driver to tree */ + platform_set_drvdata(pdev, i2c); + i2c->adap = ocores_adapter; + i2c_set_adapdata(&i2c->adap, i2c); + i2c->adap.dev.parent = &pdev->dev; + i2c->adap.dev.of_node = pdev->dev.of_node; + + if (i2c->dev->of_node) { + /* adap.nr get from dts aliases */ + ret = i2c_add_adapter(&i2c->adap); + } else { + i2c->adap.nr = i2c->adap_nr; + ret = i2c_add_numbered_adapter(&i2c->adap); + } + if (ret) { + goto fail_add; + } + OCORES_I2C_VERBOSE("Main probe out\n"); + dev_info(i2c->dev, "registered i2c-%d for %s with base address:0x%x success.\n", + i2c->adap.nr, i2c->dev_name, i2c->base_addr); + return 0; +fail_add: + platform_set_drvdata(pdev, NULL); +out: + return ret; +} + +static int ocores_i2c_remove(struct platform_device *pdev) +{ + struct ocores_i2c *i2c = platform_get_drvdata(pdev); + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* disable i2c logic */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + /* remove adapter & data */ + i2c_del_adapter(&i2c->adap); + return 0; +} + +static struct platform_driver ocores_i2c_driver = { + .probe = ocores_i2c_probe, + .remove = ocores_i2c_remove, + .driver = { + .name = "wb-ocores-i2c", + .of_match_table = ocores_i2c_match, + }, +}; + +module_platform_driver(ocores_i2c_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("OpenCores I2C bus driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ocores-i2c"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.h new file mode 100644 index 000000000000..acd2710a92f0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.h @@ -0,0 +1,28 @@ +#ifndef __WB_I2C_OCORES_H__ +#define __WB_I2C_OCORES_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define I2C_OCORES_DEV_NAME_MAX_LEN (64) + +typedef struct i2c_ocores_device_s { + uint32_t big_endian; + char dev_name[I2C_OCORES_DEV_NAME_MAX_LEN]; + int adap_nr; + uint32_t dev_base; + uint32_t reg_shift; + uint32_t reg_io_width; + uint32_t ip_clock_khz; + uint32_t bus_clock_khz; + uint32_t reg_access_mode; + + uint32_t irq_type; + uint32_t irq_offset; + uint32_t pci_domain; + uint32_t pci_bus; + uint32_t pci_slot; + uint32_t pci_fn; + int device_flag; +} i2c_ocores_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.c new file mode 100644 index 000000000000..4a4bbba0ade5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.c @@ -0,0 +1,571 @@ +/* + * wb_io_dev.c + * ko to read/write ioports through /dev/XXX device + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_io_dev.h" + +#define PROXY_NAME "wb-io-dev" +#define MAX_IO_DEV_NUM (256) +#define IO_RDWR_MAX_LEN (256) +#define MAX_NAME_SIZE (20) +#define IO_INDIRECT_ADDR_H(addr) ((addr >> 8) & 0xff) +#define IO_INDIRECT_ADDR_L(addr) ((addr) & 0xff) +#define IO_INDIRECT_OP_WRITE (0x2) +#define IO_INDIRECT_OP_READ (0X3) + +static int g_io_dev_debug = 0; +static int g_io_dev_error = 0; + +module_param(g_io_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_io_dev_error, int, S_IRUGO | S_IWUSR); + +#define IO_DEV_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_io_dev_debug) { \ + printk(KERN_INFO "[IO_DEV][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define IO_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_io_dev_error) { \ + printk(KERN_ERR "[IO_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef struct wb_io_dev_s { + const char *name; + uint32_t io_base; + uint32_t io_len; + uint32_t indirect_addr; + uint32_t wr_data; + uint32_t addr_low; + uint32_t addr_high; + uint32_t rd_data; + uint32_t opt_ctl; + spinlock_t io_dev_lock; + struct miscdevice misc; +} wb_io_dev_t; + +static wb_io_dev_t* io_dev_arry[MAX_IO_DEV_NUM]; + +static int io_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + wb_io_dev_t *wb_io_dev; + + if (minor >= MAX_IO_DEV_NUM) { + IO_DEV_DEBUG_ERROR("minor out of range, minor = %d.\n", minor); + return -ENODEV; + } + + wb_io_dev = io_dev_arry[minor]; + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("wb_io_dev is NULL, open failed, minor = %d\n", minor); + return -ENODEV; + } + + file->private_data = wb_io_dev; + return 0; +} + +static int io_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + return 0; +} + +uint8_t io_indirect_addressing_read(wb_io_dev_t *wb_io_dev, uint32_t address) +{ + uint8_t addr_l, addr_h, value; + unsigned long flags; + + addr_h = IO_INDIRECT_ADDR_H(address); + addr_l = IO_INDIRECT_ADDR_L(address); + IO_DEV_DEBUG_VERBOSE("read one count, addr = 0x%x\n", address); + + spin_lock_irqsave(&wb_io_dev->io_dev_lock, flags); + + outb(addr_l, wb_io_dev->io_base + wb_io_dev->addr_low); + + outb(addr_h, wb_io_dev->io_base + wb_io_dev->addr_high); + + outb(IO_INDIRECT_OP_READ, wb_io_dev->io_base + wb_io_dev->opt_ctl); + + value = inb(wb_io_dev->io_base + wb_io_dev->rd_data); + + spin_unlock_irqrestore(&wb_io_dev->io_dev_lock, flags); + + return value; +} + +static int io_dev_read_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i; + + if (offset > wb_io_dev->io_len) { + IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, wb_io_dev->io_len); + return 0; + } + + if (count > wb_io_dev->io_len - offset) { + IO_DEV_DEBUG_VERBOSE("read count out of range. input len:%lu, read len:%u.\n", + count, wb_io_dev->io_len - offset); + count = wb_io_dev->io_len - offset; + } + if (wb_io_dev->indirect_addr) { + for (i = 0; i < count; i++) { + buf[i] = io_indirect_addressing_read(wb_io_dev, offset + i); + } + } else { + for (i = 0; i < count; i++) { + buf[i] = inb(wb_io_dev->io_base + offset + i); + } + } + + return count; +} + +static ssize_t io_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + wb_io_dev_t *wb_io_dev; + int ret, read_len; + u8 buf_tmp[IO_RDWR_MAX_LEN]; + + wb_io_dev = file->private_data; + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("wb_io_dev is NULL, read failed.\n"); + return -EINVAL; + } + + if (count == 0) { + IO_DEV_DEBUG_ERROR("Invalid params, read count is 0.n"); + return -EINVAL; + } + + if (count > sizeof(buf_tmp)) { + IO_DEV_DEBUG_VERBOSE("read conut %lu exceed max %lu.\n", count, sizeof(buf_tmp)); + count = sizeof(buf_tmp); + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + read_len = io_dev_read_tmp(wb_io_dev, *offset, buf_tmp, count); + if (read_len < 0) { + IO_DEV_DEBUG_ERROR("io_dev_read_tmp failed, ret:%d.\n", read_len); + return read_len; + } + + if (access_ok(buf, read_len)) { + IO_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + if (copy_to_user(buf, buf_tmp, read_len)) { + IO_DEV_DEBUG_ERROR("copy_to_user failed.\n"); + return -EFAULT; + } + } else { + IO_DEV_DEBUG_VERBOSE("kernel space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + memcpy(buf, buf_tmp, read_len); + } + *offset += read_len; + ret = read_len; + return ret; +} + +static ssize_t io_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + int ret; + + IO_DEV_DEBUG_VERBOSE("io_dev_read_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, to->count, iocb->ki_pos); + ret = io_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos); + return ret; +} + +void io_indirect_addressing_write(wb_io_dev_t *wb_io_dev, uint32_t address, uint8_t reg_val) +{ + uint8_t addr_l, addr_h; + unsigned long flags; + + addr_h = IO_INDIRECT_ADDR_H(address); + addr_l = IO_INDIRECT_ADDR_L(address); + IO_DEV_DEBUG_VERBOSE("write one count, addr = 0x%x\n", address); + + spin_lock_irqsave(&wb_io_dev->io_dev_lock, flags); + + outb(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + + outb(addr_l, wb_io_dev->io_base + wb_io_dev->addr_low); + + outb(addr_h, wb_io_dev->io_base + wb_io_dev->addr_high); + + outb(IO_INDIRECT_OP_WRITE, wb_io_dev->io_base + wb_io_dev->opt_ctl); + + spin_unlock_irqrestore(&wb_io_dev->io_dev_lock, flags); + + return; +} + +static int io_dev_write_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i; + + if (offset > wb_io_dev->io_len) { + IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, wb_io_dev->io_len); + return 0; + } + + if (count > wb_io_dev->io_len - offset) { + IO_DEV_DEBUG_VERBOSE("write count out of range. input len:%lu, write len:%u.\n", + count, wb_io_dev->io_len - offset); + count = wb_io_dev->io_len - offset; + } + if (wb_io_dev->indirect_addr) { + for (i = 0; i < count; i++) { + io_indirect_addressing_write(wb_io_dev, offset + i, buf[i]); + } + } else { + for (i = 0; i < count; i++) { + outb(buf[i], wb_io_dev->io_base + offset + i); + } + } + + return count; +} + +static ssize_t io_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) +{ + wb_io_dev_t *wb_io_dev; + int write_len; + u8 buf_tmp[IO_RDWR_MAX_LEN]; + + wb_io_dev = file->private_data; + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("wb_io_dev is NULL, write failed.\n"); + return -EINVAL; + } + + if (count == 0) { + IO_DEV_DEBUG_ERROR("Invalid params, write count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(buf_tmp)) { + IO_DEV_DEBUG_VERBOSE("write conut %lu exceed max %lu.\n", count, sizeof(buf_tmp)); + count = sizeof(buf_tmp); + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + if (access_ok(buf, count)) { + IO_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + if (copy_from_user(buf_tmp, buf, count)) { + IO_DEV_DEBUG_ERROR("copy_from_user failed.\n"); + return -EFAULT; + } + } else { + IO_DEV_DEBUG_VERBOSE("kernel space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + memcpy(buf_tmp, buf, count); + } + + write_len = io_dev_write_tmp(wb_io_dev, *offset, buf_tmp, count); + if (write_len < 0) { + IO_DEV_DEBUG_ERROR("io_dev_write_tmp failed, ret:%d.\n", write_len); + return write_len; + } + + *offset += write_len; + return write_len; +} + +static ssize_t io_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + int ret; + + IO_DEV_DEBUG_VERBOSE("io_dev_write_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, from->count, iocb->ki_pos); + ret = io_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos); + return ret; +} + +static loff_t io_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + wb_io_dev_t *wb_io_dev; + + wb_io_dev = file->private_data; + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("wb_io_dev is NULL, llseek failed.\n"); + return -EINVAL; + } + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + IO_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + if (offset > wb_io_dev->io_len) { + IO_DEV_DEBUG_ERROR("SEEK_SET out of range, offset:%lld, io_len:0x%x.\n", + offset, wb_io_dev->io_len); + ret = - EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (((file->f_pos + offset) > wb_io_dev->io_len) || ((file->f_pos + offset) < 0)) { + IO_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld, io_len:0x%x.\n", + file->f_pos, offset, wb_io_dev->io_len); + ret = - EINVAL; + break; + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + IO_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static long io_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static const struct file_operations io_dev_fops = { + .owner = THIS_MODULE, + .llseek = io_dev_llseek, + .read_iter = io_dev_read_iter, + .write_iter = io_dev_write_iter, + .unlocked_ioctl = io_dev_ioctl, + .open = io_dev_open, + .release = io_dev_release, +}; + +static wb_io_dev_t *dev_match(const char *path) +{ + wb_io_dev_t *wb_io_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + + for (i = 0; i < MAX_IO_DEV_NUM; i++) { + if (io_dev_arry[i] == NULL) { + continue; + } + wb_io_dev = io_dev_arry[i]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", wb_io_dev->name); + if (!strcmp(path, dev_name)) { + IO_DEV_DEBUG_VERBOSE("get dev_name = %s, minor = %d\n", dev_name, i); + return wb_io_dev; + } + } + + return NULL; +} + +int io_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + wb_io_dev_t *wb_io_dev; + int read_len; + + if (path == NULL) { + IO_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + IO_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + wb_io_dev = dev_match(path); + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("io_dev match failed. dev path = %s", path); + return -EINVAL; + } + + read_len = io_dev_read_tmp(wb_io_dev, offset, buf, count); + if (read_len < 0) { + IO_DEV_DEBUG_ERROR("io_dev_read_tmp failed, ret:%d.\n", read_len); + } + return read_len; +} +EXPORT_SYMBOL(io_device_func_read); + +int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + wb_io_dev_t *wb_io_dev; + int write_len; + + if (path == NULL) { + IO_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + IO_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + wb_io_dev = dev_match(path); + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + write_len = io_dev_write_tmp(wb_io_dev, offset, buf, count); + if (write_len < 0) { + IO_DEV_DEBUG_ERROR("io_dev_write_tmp failed, ret:%d.\n", write_len); + } + return write_len; +} +EXPORT_SYMBOL(io_device_func_write); + +static int io_dev_probe(struct platform_device *pdev) +{ + int ret; + wb_io_dev_t *wb_io_dev; + struct miscdevice *misc; + io_dev_device_t *io_dev_device; + + wb_io_dev = devm_kzalloc(&pdev->dev, sizeof(wb_io_dev_t), GFP_KERNEL); + if (!wb_io_dev) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + ret = -ENOMEM; + return ret; + } + spin_lock_init(&wb_io_dev->io_dev_lock); + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "io_dev_name", &wb_io_dev->name); + ret += of_property_read_u32(pdev->dev.of_node, "io_base", &wb_io_dev->io_base); + ret += of_property_read_u32(pdev->dev.of_node, "io_len", &wb_io_dev->io_len); + if (of_property_read_bool(pdev->dev.of_node, "indirect_addr")) { + + wb_io_dev->indirect_addr = 1; + ret += of_property_read_u32(pdev->dev.of_node, "wr_data", &wb_io_dev->wr_data); + ret += of_property_read_u32(pdev->dev.of_node, "addr_low", &wb_io_dev->addr_low); + ret += of_property_read_u32(pdev->dev.of_node, "addr_high", &wb_io_dev->addr_high); + ret += of_property_read_u32(pdev->dev.of_node, "rd_data", &wb_io_dev->rd_data); + ret += of_property_read_u32(pdev->dev.of_node, "opt_ctl", &wb_io_dev->opt_ctl); + } else { + + wb_io_dev->indirect_addr = 0; + } + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + io_dev_device = pdev->dev.platform_data; + wb_io_dev->name = io_dev_device->io_dev_name; + wb_io_dev->io_base = io_dev_device->io_base; + wb_io_dev->io_len = io_dev_device->io_len; + wb_io_dev->indirect_addr = io_dev_device->indirect_addr; + if (wb_io_dev->indirect_addr == 1) { + wb_io_dev->wr_data = io_dev_device->wr_data; + wb_io_dev->addr_low = io_dev_device->addr_low; + wb_io_dev->addr_high = io_dev_device->addr_high; + wb_io_dev->rd_data = io_dev_device->rd_data; + wb_io_dev->opt_ctl = io_dev_device->opt_ctl; + } + } + + IO_DEV_DEBUG_VERBOSE("name:%s, io base:0x%x, io len:0x%x, addressing type:%s.\n", + wb_io_dev->name, wb_io_dev->io_base, wb_io_dev->io_len, + wb_io_dev->indirect_addr ? "indirect" : "direct"); + + misc = &wb_io_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = wb_io_dev->name; + misc->fops = &io_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&pdev->dev, "Failed to register %s device.\n", misc->name); + return -ENXIO; + } + if (misc->minor >= MAX_IO_DEV_NUM) { + dev_err(&pdev->dev, "Error: device minor[%d] more than max io device num[%d].\n", + misc->minor, MAX_IO_DEV_NUM); + misc_deregister(misc); + return -EINVAL; + } + io_dev_arry[misc->minor] = wb_io_dev; + dev_info(&pdev->dev, "register %s device [0x%x][0x%x] with minor %d using %s addressing success.\n", + misc->name, wb_io_dev->io_base, wb_io_dev->io_len, misc->minor, + wb_io_dev->indirect_addr ? "indirect" : "direct"); + + return 0; +} + +static int io_dev_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < MAX_IO_DEV_NUM ; i++) { + if (io_dev_arry[i] != NULL) { + misc_deregister(&io_dev_arry[i]->misc); + io_dev_arry[i] = NULL; + } + } + + return 0; +} + +static struct of_device_id io_dev_match[] = { + { + .compatible = "wb-io-dev", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, io_dev_match); + +static struct platform_driver wb_io_dev_driver = { + .probe = io_dev_probe, + .remove = io_dev_remove, + .driver = { + .owner = THIS_MODULE, + .name = PROXY_NAME, + .of_match_table = io_dev_match, + }, +}; + +static int __init wb_io_dev_init(void) +{ + return platform_driver_register(&wb_io_dev_driver); +} + +static void __exit wb_io_dev_exit(void) +{ + platform_driver_unregister(&wb_io_dev_driver); +} + +module_init(wb_io_dev_init); +module_exit(wb_io_dev_exit); +MODULE_DESCRIPTION("IO device driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.h new file mode 100644 index 000000000000..3a1a10f0f20c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.h @@ -0,0 +1,21 @@ +#ifndef __WB_IO_DEV_H__ +#define __WB_IO_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define IO_DEV_NAME_MAX_LEN (64) + +typedef struct io_dev_device_s { + char io_dev_name[IO_DEV_NAME_MAX_LEN]; + uint32_t io_base; + uint32_t io_len; + uint32_t indirect_addr; + uint32_t wr_data; + uint32_t addr_low; + uint32_t addr_high; + uint32_t rd_data; + uint32_t opt_ctl; + int device_flag; +} io_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.c new file mode 100644 index 000000000000..c079dc409696 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.c @@ -0,0 +1,166 @@ +/* + * wb_lpc_drv.c + * ko to set lpc pcie config io addr and enable lpc + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_lpc_drv.h" + +#define LPC_DRIVER_NAME "wb-lpc" +#define LPC_MAKE_PCI_IO_RANGE(__base) ((0xfc0001) | ((__base) & (0xFFFC))) + +int g_lpc_dev_debug = 0; +int g_lpc_dev_error = 0; + +module_param(g_lpc_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_lpc_dev_error, int, S_IRUGO | S_IWUSR); + +#define LPC_DEV_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_lpc_dev_debug) { \ + printk(KERN_INFO "[LPC_DEV][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define LPC_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_lpc_dev_error) { \ + printk(KERN_ERR "[LPC_DEV][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef struct wb_lpc_dev_s { + const char *lpc_io_name; + uint32_t domain; + uint32_t bus; + uint32_t slot; + uint32_t fn; + uint32_t lpc_io_base; + uint32_t lpc_io_size; + uint32_t lpc_gen_dec; +} wb_lpc_dev_t; + +static int wb_lpc_probe(struct platform_device *pdev) +{ + int ret, devfn; + wb_lpc_dev_t *wb_lpc_dev; + struct pci_dev *pci_dev; + lpc_drv_device_t *lpc_drv_device; + + wb_lpc_dev = devm_kzalloc(&pdev->dev, sizeof(wb_lpc_dev_t), GFP_KERNEL); + if (!wb_lpc_dev) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + ret = -ENOMEM; + return ret; + } + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "lpc_io_name", &wb_lpc_dev->lpc_io_name); + ret += of_property_read_u32(pdev->dev.of_node, "pci_domain", &wb_lpc_dev->domain); + ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &wb_lpc_dev->bus); + ret += of_property_read_u32(pdev->dev.of_node, "pci_slot", &wb_lpc_dev->slot); + ret += of_property_read_u32(pdev->dev.of_node, "pci_fn", &wb_lpc_dev->fn); + ret += of_property_read_u32(pdev->dev.of_node, "lpc_io_base", &wb_lpc_dev->lpc_io_base); + ret += of_property_read_u32(pdev->dev.of_node, "lpc_io_size", &wb_lpc_dev->lpc_io_size); + ret += of_property_read_u32(pdev->dev.of_node, "lpc_gen_dec", &wb_lpc_dev->lpc_gen_dec); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + lpc_drv_device = pdev->dev.platform_data; + wb_lpc_dev->lpc_io_name = lpc_drv_device->lpc_io_name; + wb_lpc_dev->domain = lpc_drv_device->pci_domain; + wb_lpc_dev->bus = lpc_drv_device->pci_bus; + wb_lpc_dev->slot = lpc_drv_device->pci_slot; + wb_lpc_dev->fn = lpc_drv_device->pci_fn; + wb_lpc_dev->lpc_io_base = lpc_drv_device->lpc_io_base; + wb_lpc_dev->lpc_io_size = lpc_drv_device->lpc_io_size; + wb_lpc_dev->lpc_gen_dec = lpc_drv_device->lpc_gen_dec; + } + + LPC_DEV_DEBUG_VERBOSE("domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u\n", + wb_lpc_dev->domain,wb_lpc_dev->bus, wb_lpc_dev->slot, wb_lpc_dev->fn); + LPC_DEV_DEBUG_VERBOSE("lpc_io_name:%s, lpc_io_base:0x%x, lpc_io_size:%u, lpc_gen_dec:0x%x.\n", + wb_lpc_dev->lpc_io_name, wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size, wb_lpc_dev->lpc_gen_dec); + + devfn = PCI_DEVFN(wb_lpc_dev->slot, wb_lpc_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_lpc_dev->domain, wb_lpc_dev->bus, devfn); + if (pci_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_lpc_dev->domain, wb_lpc_dev->bus, devfn); + return -ENXIO; + } + + pci_write_config_dword(pci_dev, wb_lpc_dev->lpc_gen_dec, LPC_MAKE_PCI_IO_RANGE(wb_lpc_dev->lpc_io_base)); + if (!request_region(wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size, wb_lpc_dev->lpc_io_name)) { + dev_err(&pdev->dev, "Failed to request_region [0x%x][0x%x].\n", wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size); + return -EBUSY; + } + + platform_set_drvdata(pdev, wb_lpc_dev); + + dev_info(&pdev->dev, "lpc request_region [0x%x][0x%x] success.\n", wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size); + + return 0; +} + +static int wb_lpc_remove(struct platform_device *pdev) +{ + wb_lpc_dev_t *wb_lpc_dev; + + wb_lpc_dev = platform_get_drvdata(pdev); + if (wb_lpc_dev) { + release_region(wb_lpc_dev->lpc_io_base , wb_lpc_dev->lpc_io_size); + LPC_DEV_DEBUG_VERBOSE("lpc base:0x%x, len:0x%x.\n", wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size); + } + LPC_DEV_DEBUG_VERBOSE("lpc remove.\n"); + + return 0; +} + +static struct of_device_id lpc_dev_match[] = { + { + .compatible = "wb-lpc", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, lpc_dev_match); + +static struct platform_driver wb_lpc_driver = { + .probe = wb_lpc_probe, + .remove = wb_lpc_remove, + .driver = { + .owner = THIS_MODULE, + .name = LPC_DRIVER_NAME, + .of_match_table = lpc_dev_match, + }, +}; + +static int __init wb_lpc_init(void) +{ + return platform_driver_register(&wb_lpc_driver); +} + +static void __exit wb_lpc_exit(void) +{ + platform_driver_unregister(&wb_lpc_driver); +} + +module_init(wb_lpc_init); +module_exit(wb_lpc_exit); +MODULE_DESCRIPTION("lpc driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.h new file mode 100644 index 000000000000..76e8c32c12e9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.h @@ -0,0 +1,18 @@ +#ifndef __WB_LPC_DRV_H__ +#define __WB_LPC_DRV_H__ + +#define LPC_IO_NAME_MAX_LEN (64) + +typedef struct lpc_drv_device_s { + char lpc_io_name[LPC_IO_NAME_MAX_LEN]; + int pci_domain; + int pci_bus; + int pci_slot; + int pci_fn; + int lpc_io_base; + int lpc_io_size; + int lpc_gen_dec; + int device_flag; +} lpc_drv_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_mac_bsc.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_mac_bsc.c new file mode 100644 index 000000000000..1e84e65d7b11 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_mac_bsc.c @@ -0,0 +1,660 @@ +/* + * wb_mac_th3.c - A driver for control wb_mac_th3 base on wb_mac.c + * + * Copyright (c) 1998, 1999 Frodo Looijaard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define MAC_TEMP_INVALID (99999999) + +#define MAC_SIZE (256) +#define MAC_TEMP_NUM (16) + +#define MAC_ID_REG (0x02000000) + +typedef enum { + DBG_START, + DBG_VERBOSE, + DBG_KEY, + DBG_WARN, + DBG_ERROR, + DBG_END, +} dbg_level_t; + +typedef enum{ + MAC_TYPE_START, + TD4_X9 = 0xb780, + TD4_X9_8 = 0xb788, + TH3 = 0xb980, + TD3 = 0xb870, + TD4 = 0xb880, + TH4 = 0xb990, + MAC_TYPE_END, +} mac_type; + +typedef struct sensor_regs_s { + int id; + u32 reg; +} sensor_reg_t; + +typedef struct mac_temp_regs_s { + int mac_type; + sensor_reg_t sensor_reg[MAC_TEMP_NUM]; +} mac_temp_reg_t; + +typedef enum { + MAC_TEMP_START, + MAC_TEMP_INDEX1, + MAC_TEMP_INDEX2, + MAC_TEMP_INDEX3, + MAC_TEMP_INDEX4, + MAC_TEMP_INDEX5, + MAC_TEMP_INDEX6, + MAC_TEMP_INDEX7, + MAC_TEMP_INDEX8, + MAC_TEMP_INDEX9, + MAC_TEMP_INDEX10, + MAC_TEMP_INDEX11, + MAC_TEMP_INDEX12, + MAC_TEMP_INDEX13, + MAC_TEMP_INDEX14, + MAC_TEMP_INDEX15, + MAC_TEMP_END, +} mac_hwmon_index; + +static mac_temp_reg_t mac_temp_reg[] = { + { + /* TD3 */ + .mac_type = TD3, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02004700}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02004800}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02004900}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02004a00}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02004b00}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02004c00}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02004d00}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02004e00}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02005200}, + {.id = MAC_TEMP_INDEX10, .reg = 0x02005100}, + {.id = MAC_TEMP_INDEX11, .reg = 0x02005000}, + {.id = MAC_TEMP_INDEX12, .reg = 0x02004f00}, + }, + }, + { + /* TD4 */ + .mac_type = TD4, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02004900}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02004b00}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02004d00}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02004f00}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02005100}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02005300}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02005500}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02005700}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02005900}, + {.id = MAC_TEMP_INDEX10, .reg = 0x02005b00}, + {.id = MAC_TEMP_INDEX11, .reg = 0x02005d00}, + {.id = MAC_TEMP_INDEX12, .reg = 0x02005f00}, + {.id = MAC_TEMP_INDEX13, .reg = 0x02006100}, + {.id = MAC_TEMP_INDEX14, .reg = 0x02006300}, + {.id = MAC_TEMP_INDEX15, .reg = 0x02006500}, + }, + }, + { + /* TD4_X9 */ + .mac_type = TD4_X9, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02005a00}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02005c00}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02005e00}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02006000}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02006200}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02006400}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02006600}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02006800}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02006a00}, + }, + }, + { + /* TD4_X9_8 */ + .mac_type = TD4_X9_8, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02005a00}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02005c00}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02005e00}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02006000}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02006200}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02006400}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02006600}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02006800}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02006a00}, + }, + }, + { + /* TH3 */ + .mac_type = TH3, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02004a00}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02004b00}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02004c00}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02004d00}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02004e00}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02004f00}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02005000}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02005100}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02005200}, + {.id = MAC_TEMP_INDEX10, .reg = 0x02005300}, + {.id = MAC_TEMP_INDEX11, .reg = 0x02005400}, + {.id = MAC_TEMP_INDEX12, .reg = 0x02005500}, + {.id = MAC_TEMP_INDEX13, .reg = 0x02005600}, + {.id = MAC_TEMP_INDEX14, .reg = 0x02005700}, + {.id = MAC_TEMP_INDEX15, .reg = 0x02005800}, + }, + }, + { + /* TH4 */ + .mac_type = TH4, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x0201d800}, + {.id = MAC_TEMP_INDEX2, .reg = 0x0201e000}, + {.id = MAC_TEMP_INDEX3, .reg = 0x0201e800}, + {.id = MAC_TEMP_INDEX4, .reg = 0x0201f000}, + {.id = MAC_TEMP_INDEX5, .reg = 0x0201f800}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02020000}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02020800}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02021000}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02021800}, + {.id = MAC_TEMP_INDEX10, .reg = 0x02022000}, + {.id = MAC_TEMP_INDEX11, .reg = 0x02022800}, + {.id = MAC_TEMP_INDEX12, .reg = 0x02023000}, + {.id = MAC_TEMP_INDEX13, .reg = 0x02023800}, + {.id = MAC_TEMP_INDEX14, .reg = 0x02024000}, + {.id = MAC_TEMP_INDEX15, .reg = 0x02024800}, + }, + }, +}; + +static int debuglevel = 0; +module_param(debuglevel, int, S_IRUGO | S_IWUSR); + +static int mac_pcie_id = MAC_TYPE_START; +module_param(mac_pcie_id, int, S_IRUGO | S_IWUSR); + +#define DBG_DEBUG(fmt, arg...) do { \ + if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ + printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else if ( debuglevel >= DBG_ERROR ) { \ + printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else { } \ +} while (0) + +#define DBG_ERROR(fmt, arg...) do { \ + if ( debuglevel > DBG_START) { \ + printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +struct mac_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct mutex update_lock; + u8 data[MAC_SIZE]; /* Register value */ +}; + +static int wb_i2c_read_one_time(struct i2c_client *client, u8 *recv_buf, int size) +{ + struct i2c_msg msgs[2]; + int ret = 0; + + if ((client == NULL) || (recv_buf == NULL)) { + DBG_DEBUG("i2c_client || recv_buf = NULL\r\n"); + return -1; + } + + mem_clear(msgs, sizeof(msgs)); + + msgs[0].buf = recv_buf; + msgs[0].len = size; + msgs[0].addr = client->addr; + msgs[0].flags |= I2C_M_RD; + + ret = i2c_transfer(client->adapter, msgs, 1); + if (ret < 0) { + return ret; + } + DBG_DEBUG("i2c_transfer, dev_addr 0x%x, size %d.\n", client->addr, size); + + return 0; +} + +static int wb_i2c_write_one_time(struct i2c_client *client, u8 *write_buf, int size) +{ + struct i2c_msg msgs[2]; + int ret = 0; + + if ((client == NULL) || (write_buf == NULL)) { + DBG_DEBUG("i2c_client || write_buf = NULL\r\n"); + return -1; + } + + if ((size <= 0)) { + DBG_DEBUG("size invalid, size %d\n", size); + return -1; + } + + mem_clear(msgs, sizeof(msgs)); + + msgs[0].len = size; + msgs[0].buf = write_buf; + msgs[0].addr = client->addr; + + ret = i2c_transfer(client->adapter, msgs, 1); + if (ret < 0) { + return ret; + } + DBG_DEBUG("i2c_transfer, dev_addr 0x%x, size %d\n", client->addr, size); + + return 0; +} + +static u8 step2_buf1[8] = {0x03, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}; +static u8 step2_buf2[8] = {0x03, 0x21, 0x04, 0x0c, 0x2c, 0x38, 0x02, 0x00}; +static u8 step2_buf3[8] = {0x03, 0x21, 0x04, 0x10, 0x02, 0x00, 0x4a, 0x00}; +static u8 step2_buf4[8] = {0x03, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01}; +static u8 step2_buf5[4] = {0x03, 0x21, 0x04, 0x08}; +static u8 step2_buf6[4] = {0x03, 0x21, 0x04, 0x10}; + +static int getmac_register(struct i2c_client *client, u32 index, int *reg_value) +{ + int i; + int ret = 0; + int value = 0; + unsigned char read_buf[8]; + + if (index == 0) { + DBG_ERROR("invalid index\n"); + return -1; + } + + step2_buf3[7] = index & 0xff; + step2_buf3[6] = (index >> 8) & 0xff; + step2_buf3[5] = (index >> 16) & 0xff; + step2_buf3[4] = (index >> 24) & 0xff; + + ret = wb_i2c_write_one_time(client, step2_buf1, 8); + if (ret < 0) { + DBG_ERROR("write step2_buf1 failed, ret = %d\n", ret); + } + ret = wb_i2c_write_one_time(client, step2_buf2, 8); + if (ret < 0) { + DBG_ERROR("write step2_buf2 failed, ret = %d\n", ret); + } + ret = wb_i2c_write_one_time(client, step2_buf3, 8); + if (ret < 0) { + DBG_ERROR("write step2_buf3 failed, ret = %d\n", ret); + } + ret = wb_i2c_write_one_time(client, step2_buf4, 8); + if (ret < 0) { + DBG_ERROR("write step2_buf4 failed, ret = %d\n", ret); + } + + ret = wb_i2c_write_one_time(client, step2_buf5, 4); + if (ret < 0) { + DBG_ERROR("write step2_buf5 failed, ret = %d\n", ret); + } + ret = wb_i2c_read_one_time(client, read_buf, 4); + if (ret < 0) { + DBG_ERROR("read failed, ret = %d\n", ret); + } + for (i = 0; i < 4; i++) { + DBG_DEBUG("read_buf[%d] = 0x%x \n", i, read_buf[i]); + } + + ret = wb_i2c_write_one_time(client, step2_buf6, 4); + if (ret < 0) { + DBG_ERROR("write step2_buf6 failed, ret = %d\n", ret); + } + + ret = wb_i2c_read_one_time(client, read_buf, 4); + if (ret < 0) { + DBG_ERROR("read failed, ret = %d\n", ret); + return ret; + } + + value = (read_buf[0] << 24)| (read_buf[1] << 16) | (read_buf[2] << 8) | read_buf[3]; + *reg_value = value; + + return ret; +} + +static int mac_calcute(u32 reg, int *temp) +{ + int ret = 0; + u32 tmp = 0; + + switch(mac_pcie_id) { + case TD3: + case TH3: + tmp = reg & 0x3ff; + *temp = 434100 - (tmp * 535); + break; + case TD4: + case TH4: + case TD4_X9: + case TD4_X9_8: + tmp = reg & 0x7ff; + *temp = (356070 - (tmp * 237)); + break; + default: + ret = -1; + DBG_ERROR("read failed, ret = %d\n", ret); + break; + } + + if ((*temp / 1000 < -70) || (*temp / 1000 > 200)) { + ret = -1; + DBG_ERROR("mac temp invalid, temp = %d\n", *temp ); + } + + return ret; +} + +static int find_reg_type(int type, int *type_index) +{ + int i; + int size; + + size = ARRAY_SIZE(mac_temp_reg); + for (i = 0; i < size; i++) { + if (mac_temp_reg[i].mac_type == type) { + *type_index = i; + return 0; + } + } + + return -1; +} + +static sensor_reg_t * find_reg_offset(int type, int index) +{ + int i; + int type_index; + int ret; + + ret = find_reg_type(type, &type_index); + if (ret < 0) { + DBG_ERROR("find_reg_type failed, ret = %d\n", ret); + return NULL; + } + + for (i = 0; i < MAC_TEMP_NUM; i++) { + if (mac_temp_reg[type_index].sensor_reg[i].id == index) { + return &(mac_temp_reg[type_index].sensor_reg[i]); + } + } + + return NULL; +} + +static int get_mactemp(struct i2c_client *client, int index, int *temp) +{ + int ret; + int reg_value; + + if (index == 0) { + DBG_ERROR("invalid index\n"); + return -1; + } + + ret = getmac_register(client, index, ®_value); + if (ret < 0) { + DBG_ERROR("getmac_register failed, ret = %d\n", ret); + return ret; + } + DBG_DEBUG("reg_value = 0x%x \n", reg_value); + + ret = mac_calcute(reg_value, temp); + if (ret < 0) { + DBG_ERROR("mac_calcute failed, ret = %d\n", ret); + return ret; + } + + return 0; +} + +static ssize_t show_mac_temp(struct device *dev, struct device_attribute *da, char *buf) +{ + struct mac_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + u32 index_value = to_sensor_dev_attr_2(da)->index; + sensor_reg_t *t; + int result = 0; + int temp = -MAC_TEMP_INVALID; + + mutex_lock(&data->update_lock); + t = find_reg_offset(mac_pcie_id, index_value); + if (t == NULL) { + temp = -MAC_TEMP_INVALID; + DBG_ERROR("find_reg_offset failed, mac_pcie_id = %d, index_value = %d\n", mac_pcie_id, index_value); + } else { + result = get_mactemp(client, t->reg, &temp); + if (result < 0) { + temp = -MAC_TEMP_INVALID; + DBG_ERROR("get_mactemp failed, ret = %d\n", result); + } + } + + mutex_unlock(&data->update_lock); + return snprintf(buf, MAC_SIZE, "%d\n", temp); +} + +static ssize_t show_mac_max_temp(struct device *dev, struct device_attribute *da, char *buf) +{ + struct mac_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int i; + int result; + int temp = -MAC_TEMP_INVALID; + int type_index; + int tmp; + + mutex_lock(&data->update_lock); + + result = find_reg_type(mac_pcie_id, &type_index); + if (result < 0) { + DBG_ERROR("find_reg_type failed, ret = %d\n", result); + goto exit; + } + + for (i = 0; i < MAC_TEMP_NUM; i++) { + result = get_mactemp(client, mac_temp_reg[type_index].sensor_reg[i].reg, &tmp); + if (result < 0) { + DBG_ERROR("get_mactemp failed, ret = %d\n", result); + tmp = -MAC_TEMP_INVALID; + } + + temp = (temp > tmp) ? temp : tmp; + } + +exit: + mutex_unlock(&data->update_lock); + return snprintf(buf, MAC_SIZE, "%d\n", temp); +} + +static int mac_bsc_init(struct i2c_client *client) +{ + int ret; + int reg_value; + int mac_id = 0; + + ret = getmac_register(client, MAC_ID_REG, ®_value); + if (ret < 0) { + DBG_ERROR("getmac_register failed, ret = %d\n", ret); + return ret; + } + + DBG_DEBUG("reg_value = 0x%x \n", reg_value); + mac_id = reg_value & 0xffff; + return mac_id; +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX1); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX2); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX3); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX4); +static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX5); +static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX6); +static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX7); +static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX8); +static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX9); +static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX10); +static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX11); +static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX12); +static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX13); +static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX14); +static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX15); +static SENSOR_DEVICE_ATTR(temp99_input, S_IRUGO, show_mac_max_temp, NULL, 0); + +static struct attribute *mac_hwmon_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp6_input.dev_attr.attr, + &sensor_dev_attr_temp7_input.dev_attr.attr, + &sensor_dev_attr_temp8_input.dev_attr.attr, + &sensor_dev_attr_temp9_input.dev_attr.attr, + &sensor_dev_attr_temp10_input.dev_attr.attr, + &sensor_dev_attr_temp11_input.dev_attr.attr, + &sensor_dev_attr_temp12_input.dev_attr.attr, + &sensor_dev_attr_temp13_input.dev_attr.attr, + &sensor_dev_attr_temp14_input.dev_attr.attr, + &sensor_dev_attr_temp15_input.dev_attr.attr, + &sensor_dev_attr_temp99_input.dev_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(mac_hwmon); + +static int init_bcs_command(int mac_type) { + int ret; + + ret = 0; + switch (mac_type) { + case TD3: + step2_buf2[5] = 0x38; + break; + case TH3: + case TH4: + case TD4: + case TD4_X9: + case TD4_X9_8: + step2_buf2[5] = 0x40; + break; + default: + ret = -1; + break; + } + return ret; +} + +static int mac_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct mac_data *data; + int mac_type; + int ret; + + mac_type = id->driver_data; + mac_pcie_id = mac_type; + if (init_bcs_command(mac_type) < 0) { + DBG_ERROR("mactype[%x] not support \n", mac_type); + return -1; + }; + + if (mac_type == TD4) { + ret = mac_bsc_init(client); + if (ret < 0) { + DBG_ERROR("mac_bsc_init failed, ret = %d\n", ret); + return -1; + } + mac_type = ret; + mac_pcie_id = mac_type; + } + + DBG_DEBUG("=========mac_probe(%x)===========\n",client->addr); + DBG_DEBUG("mac_type: %x\n", mac_type); + data = devm_kzalloc(&client->dev, sizeof(struct mac_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, mac_hwmon_groups); + if (IS_ERR(data->hwmon_dev)) { + return PTR_ERR(data->hwmon_dev); + } + + return 0; +} + +static int mac_remove(struct i2c_client *client) +{ + struct mac_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + return 0; +} + +static const struct i2c_device_id mac_id[] = { + { "wb_mac_bsc_td3", TD3 }, + { "wb_mac_bsc_td4", TD4 }, + { "wb_mac_bsc_th3", TH3 }, + { "wb_mac_bsc_th4", TH4 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, mac_id); + +static struct i2c_driver wb_mac_bsc_driver = { + .driver = { + .name = "wb_mac_bsc", + }, + .probe = mac_probe, + .remove = mac_remove, + .id_table = mac_id, +}; + +module_i2c_driver(wb_mac_bsc_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("mac bsc driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_optoe.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_optoe.c new file mode 100644 index 000000000000..c09162368ad0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_optoe.c @@ -0,0 +1,1192 @@ +/* + * 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. + * + * The CMIS (Common Management Interface Specification) defines use of + * considerably more pages (at least to page 0xAF), which this driver + * supports. + * + * NOTE: This version of the driver ONLY SUPPORTS BANK 0 PAGES on CMIS + * devices. + * + **/ + +/* #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 +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#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 QSFP_NOT_PAGEABLE (1<<2) +#define CMIS_NOT_PAGEABLE (1<<7) +#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 = 50; + +/* + * 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 +#define CMIS_ADDR 3 + +static const struct i2c_device_id optoe_ids[] = { + { "wb_optoe1", ONE_ADDR }, + { "wb_optoe2", TWO_ADDR }, + { "wb_optoe3", CMIS_ADDR }, + { "wb_sff8436", ONE_ADDR }, + { "wb_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; + + mem_clear(msg, 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; + + /* 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; + uint8_t loc; + 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); + + ret = optoe_eeprom_read(optoe, client, &loc, OPTOE_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_dbg(&client->dev, "Read page register for get now location page failed. ret:%d\n", ret); + return ret; + } + + /* Only when read and now location page is inconsistent, will doing switch page */ + if (loc != page) { + 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; + } + + 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 not_pageable; + 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, CMIS 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 (optoe->dev_class == ONE_ADDR) { + not_pageable = QSFP_NOT_PAGEABLE; + } else { + not_pageable = CMIS_NOT_PAGEABLE; + } + dev_dbg(&client->dev, + "Paging Register: 0x%x; not_pageable mask: 0x%x\n", + regval, not_pageable); + + if (regval & 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) + * And... CMIS spec is 1 i2c address, but puts the pageable + * bit in a different location, so CMIS devices are "3" + */ + + if (kstrtoint(buf, 0, &dev_class) != 0 || + dev_class < 1 || dev_class > 3) + return -EINVAL; + + mutex_lock(&optoe->lock); + if (dev_class == TWO_ADDR) { + /* SFP family */ + /* if it doesn't exist, create 0x51 i2c address */ + if (!optoe->client[1]) { + optoe->client[1] = i2c_new_dummy_device(client->adapter, 0x51); + if (!optoe->client[1]) { + dev_err(&client->dev, + "address 0x51 unavailable\n"); + mutex_unlock(&optoe->lock); + return -EADDRINUSE; + } + } + optoe->bin.size = TWO_ADDR_EEPROM_SIZE; + optoe->num_addresses = 2; + } else { + /* one-address (eg QSFP) and CMIS family */ + /* if it exists, remove 0x51 i2c address */ + if (optoe->client[1]) { + i2c_unregister_device(optoe->client[1]); + optoe->client[1] = NULL; + } + optoe->bin.size = ONE_ADDR_EEPROM_SIZE; + optoe->num_addresses = 1; + } + 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, "wb_optoe1") == 0) || + (strcmp(client->name, "wb_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, "wb_optoe2") == 0) || + (strcmp(client->name, "wb_24c04") == 0)) { + /* SFP family */ + optoe->dev_class = TWO_ADDR; + chip.byte_len = TWO_ADDR_EEPROM_SIZE; + num_addresses = 2; + } else if (strcmp(client->name, "wb_optoe3") == 0) { + /* CMIS spec */ + optoe->dev_class = CMIS_ADDR; + chip.byte_len = ONE_ADDR_EEPROM_SIZE; + num_addresses = 1; + } else { /* those were the only 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]); + optoe->client[1] = NULL; + } + } + + 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 = "wb_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("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.c new file mode 100644 index 000000000000..1f5180ffccdc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.c @@ -0,0 +1,770 @@ +/* + * wb_pcie_dev.c + * ko to read/write pcie iomem and ioports through /dev/XXX device + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_pcie_dev.h" + +#define PROXY_NAME "wb-pci-dev" +#define MAX_NAME_SIZE (20) +#define MAX_PCIE_NUM (256) +#define PCI_RDWR_MAX_LEN (256) +#define PCIE_BUS_WIDTH_1 (1) +#define PCIE_BUS_WIDTH_2 (2) +#define PCIE_BUS_WIDTH_4 (4) + +static int g_pcie_dev_debug = 0; +static int g_pcie_dev_error = 0; + +module_param(g_pcie_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_pcie_dev_error, int, S_IRUGO | S_IWUSR); + +#define PCIE_DEV_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_pcie_dev_debug) { \ + printk(KERN_INFO "[PCIE_DEV][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PCIE_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_pcie_dev_error) { \ + printk(KERN_ERR "[PCIE_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef struct firmware_upg_s { + int upg_ctrl_base; + int upg_flash_base; +} firmware_upg_t; + +typedef struct wb_pci_dev_s { + const char *name; + uint32_t domain; + uint32_t bus; + uint32_t slot; + uint32_t fn; + uint32_t bar; + void __iomem *pci_mem_base; + uint32_t pci_io_base; + uint32_t bar_len; + uint32_t bar_flag; + uint32_t bus_width; + struct miscdevice misc; + void (*setreg)(struct wb_pci_dev_s *wb_pci_dev, int reg, u32 value); + u32 (*getreg)(struct wb_pci_dev_s *wb_pci_dev, int reg); + firmware_upg_t firmware_upg; +} wb_pci_dev_t; + +static wb_pci_dev_t* pcie_dev_arry[MAX_PCIE_NUM]; + +static void pci_dev_setreg_8(wb_pci_dev_t *wb_pci_dev, int reg, u32 value) +{ + u8 w_value; + + w_value = (u8)(value & 0xff); + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + writeb(w_value, wb_pci_dev->pci_mem_base + reg); + } else { + outb(w_value, wb_pci_dev->pci_io_base + reg); + } + return; +} + +static void pci_dev_setreg_16(wb_pci_dev_t *wb_pci_dev, int reg, u32 value) +{ + u16 w_value; + + w_value = (u16)(value & 0xffff); + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + writew(w_value, wb_pci_dev->pci_mem_base + reg); + } else { + outw(w_value, wb_pci_dev->pci_io_base + reg); + } + + return; +} + +static void pci_dev_setreg_32(wb_pci_dev_t *wb_pci_dev, int reg, u32 value) +{ + + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + writel(value, wb_pci_dev->pci_mem_base + reg); + } else { + outl(value, wb_pci_dev->pci_io_base + reg); + } + return; +} + +static inline u32 pci_dev_getreg_8(wb_pci_dev_t *wb_pci_dev, int reg) +{ + u32 value; + + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + value = readb(wb_pci_dev->pci_mem_base + reg); + } else { + value = inb(wb_pci_dev->pci_io_base + reg); + } + + return value; +} + +static inline u32 pci_dev_getreg_16(wb_pci_dev_t *wb_pci_dev, int reg) +{ + u32 value; + + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + value = readw(wb_pci_dev->pci_mem_base + reg); + } else { + value = inw(wb_pci_dev->pci_io_base + reg); + } + + return value; +} + +static inline u32 pci_dev_getreg_32(wb_pci_dev_t *wb_pci_dev, int reg) +{ + u32 value; + + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + value = readl(wb_pci_dev->pci_mem_base + reg); + } else { + value = inl(wb_pci_dev->pci_io_base + reg); + } + + return value; +} + +static inline void pci_dev_setreg(wb_pci_dev_t *wb_pci_dev, int reg, u32 value) +{ + wb_pci_dev->setreg(wb_pci_dev, reg, value); +} + +static inline u32 pci_dev_getreg(wb_pci_dev_t *wb_pci_dev, int reg) +{ + return wb_pci_dev->getreg(wb_pci_dev, reg); +} + +static int pci_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + wb_pci_dev_t *wb_pci_dev; + + PCIE_DEV_DEBUG_VERBOSE("inode: %p, file: %p, minor: %u", inode, file, minor); + + if (minor >= MAX_PCIE_NUM) { + PCIE_DEV_DEBUG_ERROR("minor out of range, minor = %d.\n", minor); + return -ENODEV; + } + + wb_pci_dev = pcie_dev_arry[minor]; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, open failed, minor = %d\n", minor); + return -ENODEV; + } + + file->private_data = wb_pci_dev; + return 0; +} + +static int pci_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + return 0; +} + +static int pci_dev_read_tmp(wb_pci_dev_t *wb_pci_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int width, i, j; + u32 val; + + if (offset > wb_pci_dev->bar_len) { + PCIE_DEV_DEBUG_VERBOSE("offset:0x%x, bar len:0x%x, EOF.\n", offset, wb_pci_dev->bar_len); + return 0; + } + + width = wb_pci_dev->bus_width; + + if (offset % width) { + PCIE_DEV_DEBUG_ERROR("pci bus width:%d, offset:0x%x, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + + if (count > wb_pci_dev->bar_len - offset) { + PCIE_DEV_DEBUG_VERBOSE("read count out of range. input len:%lu, read len:%u.\n", + count, wb_pci_dev->bar_len - offset); + count = wb_pci_dev->bar_len - offset; + } + + for (i = 0; i < count; i += width) { + val = pci_dev_getreg(wb_pci_dev, offset + i); + for (j = 0; (j < width) && (i + j < count); j++) { + buf[i + j] = (val >> (8 * j)) & 0xff; + } + } + return count; +} + +static ssize_t pci_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + wb_pci_dev_t *wb_pci_dev; + int ret, read_len; + u8 buf_tmp[PCI_RDWR_MAX_LEN]; + + wb_pci_dev = file->private_data; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, read failed.\n"); + return -EINVAL; + } + + if (count == 0) { + PCIE_DEV_DEBUG_ERROR("Invalid params, read count is 0.n"); + return -EINVAL; + } + + if (count > sizeof(buf_tmp)) { + PCIE_DEV_DEBUG_VERBOSE("read conut %lu exceed max %lu.\n", count, sizeof(buf_tmp)); + count = sizeof(buf_tmp); + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + read_len = pci_dev_read_tmp(wb_pci_dev, *offset, buf_tmp, count); + if (read_len < 0) { + PCIE_DEV_DEBUG_ERROR("pci_dev_read_tmp failed, ret:%d.\n", read_len); + return read_len; + } + if (access_ok(buf, read_len)) { + PCIE_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + if (copy_to_user(buf, buf_tmp, read_len)) { + PCIE_DEV_DEBUG_ERROR("copy_to_user failed.\n"); + return -EFAULT; + } + } else { + PCIE_DEV_DEBUG_VERBOSE("kernel space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + memcpy(buf, buf_tmp, read_len); + } + *offset += read_len; + ret = read_len; + return ret; +} + +static ssize_t pci_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + int ret; + + PCIE_DEV_DEBUG_VERBOSE("pci_dev_read_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, to->count, iocb->ki_pos); + ret = pci_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos); + return ret; +} + +static int pci_dev_write_tmp(wb_pci_dev_t *wb_pci_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int width, i, j; + u32 val; + + if (offset > wb_pci_dev->bar_len) { + PCIE_DEV_DEBUG_VERBOSE("offset:0x%x, bar len:0x%x, EOF.\n", offset, wb_pci_dev->bar_len); + return 0; + } + + width = wb_pci_dev->bus_width; + + if (offset % width) { + PCIE_DEV_DEBUG_ERROR("pci bus width:%d, offset:0x%x, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + + if (count > wb_pci_dev->bar_len - offset) { + PCIE_DEV_DEBUG_VERBOSE("write count out of range. input len:%lu, write len:%u.\n", + count, wb_pci_dev->bar_len - offset); + count = wb_pci_dev->bar_len - offset; + } + + for (i = 0; i < count; i += width) { + val = 0; + for (j = 0; (j < width) && (i + j < count); j++) { + val |= buf[i + j] << (8 * j); + } + pci_dev_setreg(wb_pci_dev, i + offset, val); + } + + return count; +} + +static ssize_t pci_dev_write(struct file *file, const char __user *buf, size_t count, + loff_t *offset) +{ + wb_pci_dev_t *wb_pci_dev; + u8 buf_tmp[PCI_RDWR_MAX_LEN]; + int write_len; + + wb_pci_dev = file->private_data; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, write failed.\n"); + return -EINVAL; + } + + if (count == 0) { + PCIE_DEV_DEBUG_ERROR("Invalid params, write count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(buf_tmp)) { + PCIE_DEV_DEBUG_VERBOSE("write conut %lu exceed max %lu.\n", count, sizeof(buf_tmp)); + count = sizeof(buf_tmp); + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + if (access_ok(buf, count)) { + PCIE_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + if (copy_from_user(buf_tmp, buf, count)) { + PCIE_DEV_DEBUG_ERROR("copy_from_user failed.\n"); + return -EFAULT; + } + } else { + PCIE_DEV_DEBUG_VERBOSE("kernel space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + memcpy(buf_tmp, buf, count); + } + + write_len = pci_dev_write_tmp(wb_pci_dev, *offset, buf_tmp, count); + if (write_len < 0) { + PCIE_DEV_DEBUG_ERROR("pci_dev_write_tmp failed, ret:%d.\n", write_len); + return write_len; + } + + *offset += write_len; + return write_len; +} + +static ssize_t pci_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + int ret; + + PCIE_DEV_DEBUG_VERBOSE("pci_dev_write_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, from->count, iocb->ki_pos); + ret = pci_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos); + return ret; +} + +static loff_t pci_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + wb_pci_dev_t *wb_pci_dev; + + wb_pci_dev = file->private_data; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, llseek failed.\n"); + return -EINVAL; + } + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + PCIE_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + if (offset > wb_pci_dev->bar_len) { + PCIE_DEV_DEBUG_ERROR("SEEK_SET out of range, offset:%lld, bar len:0x%x.\n", + offset, wb_pci_dev->bar_len); + ret = - EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (((file->f_pos + offset) > wb_pci_dev->bar_len) || ((file->f_pos + offset) < 0)) { + PCIE_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld, bar len:0x%x.\n", + file->f_pos, offset, wb_pci_dev->bar_len); + ret = - EINVAL; + break; + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + PCIE_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static long pci_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + wb_pci_dev_t *wb_pci_dev; + void __user *argp; + firmware_upg_t *firmware_upg; + int upg_ctrl_base; + int upg_flash_base; + + PCIE_DEV_DEBUG_VERBOSE("ioctl, cmd=0x%02x, arg=0x%02lx\n",cmd, arg); + + wb_pci_dev = file->private_data; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, ioctl failed.\n"); + return -EINVAL; + } + + firmware_upg = &wb_pci_dev->firmware_upg; + + argp = (void __user *)arg; + + switch (cmd) { + case GET_FPGA_UPG_CTL_BASE: + if (firmware_upg->upg_ctrl_base < 0) { + PCIE_DEV_DEBUG_ERROR("dts not adaptive upg_ctrl_base\n"); + return -EFAULT; + } else { + upg_ctrl_base = firmware_upg->upg_ctrl_base; + if (copy_to_user(argp, &upg_ctrl_base, sizeof(upg_ctrl_base))) { + PCIE_DEV_DEBUG_ERROR("upg_ctrl_base copy_from_user failed\n"); + return -EFAULT; + } + } + break; + case GET_FPGA_UPG_FLASH_BASE: + if (firmware_upg->upg_flash_base < 0) { + PCIE_DEV_DEBUG_ERROR("dts not adaptive upg_flash_base\n"); + return -EFAULT; + } else { + upg_flash_base = firmware_upg->upg_flash_base; + if (copy_to_user(argp, &upg_flash_base, sizeof(upg_flash_base))) { + PCIE_DEV_DEBUG_ERROR("upg_flash_base copy_from_user failed\n"); + return -EFAULT; + } + } + break; + default: + PCIE_DEV_DEBUG_ERROR("command unsupported \n"); + return -ENOTTY; + } + + return 0; +} + +static const struct file_operations pcie_dev_fops = { + .owner = THIS_MODULE, + .llseek = pci_dev_llseek, + .read_iter = pci_dev_read_iter, + .write_iter = pci_dev_write_iter, + .unlocked_ioctl = pci_dev_ioctl, + .open = pci_dev_open, + .release = pci_dev_release, +}; + +static wb_pci_dev_t *dev_match(const char *path) +{ + wb_pci_dev_t *wb_pci_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + + for (i = 0; i < MAX_PCIE_NUM; i++) { + if (pcie_dev_arry[i] == NULL) { + continue; + } + wb_pci_dev = pcie_dev_arry[i]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", wb_pci_dev->name); + if (!strcmp(path, dev_name)) { + PCIE_DEV_DEBUG_VERBOSE("get dev_name = %s, minor = %d\n", dev_name, i); + return wb_pci_dev; + } + } + + return NULL; +} + +int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + wb_pci_dev_t *wb_pci_dev; + int read_len; + + if (path == NULL) { + PCIE_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + PCIE_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + wb_pci_dev = dev_match(path); + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + read_len = pci_dev_read_tmp(wb_pci_dev, offset, buf, count); + if (read_len < 0) { + PCIE_DEV_DEBUG_ERROR("pci_dev_read_tmp failed, ret:%d.\n", read_len); + } + return read_len; +} +EXPORT_SYMBOL(pcie_device_func_read); + +int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + wb_pci_dev_t *wb_pci_dev; + int write_len; + + if (path == NULL) { + PCIE_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + PCIE_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + wb_pci_dev = dev_match(path); + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + write_len = pci_dev_write_tmp(wb_pci_dev, offset, buf, count); + if (write_len < 0) { + PCIE_DEV_DEBUG_ERROR("pci_dev_write_tmp failed, ret:%d.\n", write_len); + } + return write_len; +} +EXPORT_SYMBOL(pcie_device_func_write); + +static int pci_setup_bars(wb_pci_dev_t *wb_pci_dev, struct pci_dev *dev) +{ + int ret; + uint32_t addr, len, flags; + + ret = 0; + addr = pci_resource_start(dev, wb_pci_dev->bar); + len = pci_resource_len(dev, wb_pci_dev->bar); + if (addr == 0 || len == 0) { + PCIE_DEV_DEBUG_ERROR("get bar addr failed. bar:%d, addr:0x%x, len:0x%x.\n", + wb_pci_dev->bar, addr, len); + return -EFAULT; + } + wb_pci_dev->bar_len = len; + + flags = pci_resource_flags(dev, wb_pci_dev->bar); + PCIE_DEV_DEBUG_VERBOSE("bar:%d, flag:0x%08x, phys addr:0x%x, len:0x%x\n", + wb_pci_dev->bar, flags, addr, len); + if (flags & IORESOURCE_MEM) { + wb_pci_dev->bar_flag = IORESOURCE_MEM; + wb_pci_dev->pci_mem_base = ioremap(addr, len); + PCIE_DEV_DEBUG_VERBOSE("pci mem base:%p.\n", wb_pci_dev->pci_mem_base); + } else if (flags & IORESOURCE_IO) { + wb_pci_dev->bar_flag = IORESOURCE_IO; + wb_pci_dev->pci_io_base = addr; + PCIE_DEV_DEBUG_VERBOSE("pci io base:0x%x.\n", wb_pci_dev->pci_io_base); + } else { + PCIE_DEV_DEBUG_ERROR("unknow pci bar flag:0x%08x.\n", flags); + ret = -EINVAL; + } + + return ret; +} + +static int pci_dev_probe(struct platform_device *pdev) +{ + int ret, devfn; + wb_pci_dev_t *wb_pci_dev; + struct pci_dev *pci_dev; + struct miscdevice *misc; + firmware_upg_t *firmware_upg; + pci_dev_device_t *pci_dev_device; + + wb_pci_dev = devm_kzalloc(&pdev->dev, sizeof(wb_pci_dev_t), GFP_KERNEL); + if (!wb_pci_dev) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + ret = -ENOMEM; + return ret; + } + + firmware_upg = &wb_pci_dev->firmware_upg; + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "pci_dev_name", &wb_pci_dev->name); + ret += of_property_read_u32(pdev->dev.of_node, "pci_domain", &wb_pci_dev->domain); + ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &wb_pci_dev->bus); + ret += of_property_read_u32(pdev->dev.of_node, "pci_slot", &wb_pci_dev->slot); + ret += of_property_read_u32(pdev->dev.of_node, "pci_fn", &wb_pci_dev->fn); + ret += of_property_read_u32(pdev->dev.of_node, "pci_bar", &wb_pci_dev->bar); + ret += of_property_read_u32(pdev->dev.of_node, "bus_width", &wb_pci_dev->bus_width); + + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret); + return -ENXIO; + } + + ret = 0; + ret += of_property_read_u32(pdev->dev.of_node, "upg_ctrl_base", &firmware_upg->upg_ctrl_base); + ret += of_property_read_u32(pdev->dev.of_node, "upg_flash_base", &firmware_upg->upg_flash_base); + if (ret != 0) { + PCIE_DEV_DEBUG_VERBOSE("dts don't adaptive fpga upg related, ret:%d.\n", ret); + firmware_upg->upg_ctrl_base = -1; + firmware_upg->upg_flash_base = -1; + } else { + PCIE_DEV_DEBUG_VERBOSE("upg_ctrl_base:0x%04x, upg_flash_base:0x%02x.\n", + firmware_upg->upg_ctrl_base, firmware_upg->upg_flash_base); + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + pci_dev_device = pdev->dev.platform_data; + wb_pci_dev->name = pci_dev_device->pci_dev_name; + wb_pci_dev->domain = pci_dev_device->pci_domain; + wb_pci_dev->bus = pci_dev_device->pci_bus; + wb_pci_dev->slot = pci_dev_device->pci_slot; + wb_pci_dev->fn = pci_dev_device->pci_fn; + wb_pci_dev->bar = pci_dev_device->pci_bar; + wb_pci_dev->bus_width = pci_dev_device->bus_width; + firmware_upg->upg_ctrl_base = pci_dev_device->upg_ctrl_base; + firmware_upg->upg_flash_base = pci_dev_device->upg_flash_base; + PCIE_DEV_DEBUG_VERBOSE("upg_ctrl_base:0x%04x, upg_flash_base:0x%02x.\n", + firmware_upg->upg_ctrl_base, firmware_upg->upg_flash_base); + } + + PCIE_DEV_DEBUG_VERBOSE("name:%s, domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u, bar:%u, bus_width:%d.\n", + wb_pci_dev->name, wb_pci_dev->domain, wb_pci_dev->bus, wb_pci_dev->slot, wb_pci_dev->fn, + wb_pci_dev->bar, wb_pci_dev->bus_width); + + devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); + if (pci_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bus, devfn); + return -ENXIO; + } + ret = pci_setup_bars(wb_pci_dev, pci_dev); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get pci bar address.\n"); + return ret; + } + + if (!wb_pci_dev->setreg || !wb_pci_dev->getreg) { + switch (wb_pci_dev->bus_width) { + case 1: + wb_pci_dev->setreg = pci_dev_setreg_8; + wb_pci_dev->getreg = pci_dev_getreg_8; + break; + + case 2: + wb_pci_dev->setreg = pci_dev_setreg_16; + wb_pci_dev->getreg = pci_dev_getreg_16; + break; + + case 4: + wb_pci_dev->setreg = pci_dev_setreg_32; + wb_pci_dev->getreg = pci_dev_getreg_32; + break; + default: + dev_err(&pdev->dev, "Error: unsupported I/O width (%d).\n", wb_pci_dev->bus_width); + ret = -EINVAL; + goto io_unmap; + } + } + + misc = &wb_pci_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = wb_pci_dev->name; + misc->fops = &pcie_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&pdev->dev, "Failed to register %s device.\n", misc->name); + ret = -ENXIO; + goto io_unmap; + } + if (misc->minor >= MAX_PCIE_NUM) { + dev_err(&pdev->dev, "Error: device minor[%d] more than max pcie num[%d].\n", + misc->minor, MAX_PCIE_NUM); + misc_deregister(misc); + ret = -EINVAL; + goto io_unmap; + } + pcie_dev_arry[misc->minor] = wb_pci_dev; + dev_info(&pdev->dev, "%04x:%02x:%02x.%d[bar%d: %s]: register %s device with minor:%d success.\n", + wb_pci_dev->domain, wb_pci_dev->bus, wb_pci_dev->slot, wb_pci_dev->fn, wb_pci_dev->bar, + wb_pci_dev->bar_flag == IORESOURCE_MEM ? "IORESOURCE_MEM" : "IORESOURCE_IO", + misc->name, misc->minor ); + return 0; + +io_unmap: + if (wb_pci_dev->pci_mem_base) { + iounmap(wb_pci_dev->pci_mem_base); + } + return ret; +} + +static int pci_dev_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < MAX_PCIE_NUM ; i++) { + if (pcie_dev_arry[i] != NULL) { + if (pcie_dev_arry[i]->pci_mem_base) { + iounmap(pcie_dev_arry[i]->pci_mem_base); + } + misc_deregister(&pcie_dev_arry[i]->misc); + pcie_dev_arry[i] = NULL; + } + } + + return 0; +} + +static struct of_device_id pci_dev_match[] = { + { + .compatible = "wb-pci-dev", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, pci_dev_match); + +static struct platform_driver wb_pci_dev_driver = { + .probe = pci_dev_probe, + .remove = pci_dev_remove, + .driver = { + .owner = THIS_MODULE, + .name = PROXY_NAME, + .of_match_table = pci_dev_match, + }, +}; + +static int __init wb_pci_dev_init(void) +{ + return platform_driver_register(&wb_pci_dev_driver); +} + +static void __exit wb_pci_dev_exit(void) +{ + platform_driver_unregister(&wb_pci_dev_driver); +} + +module_init(wb_pci_dev_init); +module_exit(wb_pci_dev_exit); +MODULE_DESCRIPTION("pcie device driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.h new file mode 100644 index 000000000000..9ba0f3b457ea --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.h @@ -0,0 +1,26 @@ +#ifndef __WB_PCIE_DEV_H__ +#define __WB_PCIE_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define UPG_TYPE 'U' +#define GET_FPGA_UPG_CTL_BASE _IOR(UPG_TYPE, 0, int) +#define GET_FPGA_UPG_FLASH_BASE _IOR(UPG_TYPE, 1, int) + +#define PCI_DEV_NAME_MAX_LEN (64) + +typedef struct pci_dev_device_s { + char pci_dev_name[PCI_DEV_NAME_MAX_LEN]; + int pci_domain; + int pci_bus; + int pci_slot; + int pci_fn; + int pci_bar; + int bus_width; + int upg_ctrl_base; + int upg_flash_base; + int device_flag; +} pci_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.c new file mode 100644 index 000000000000..3fe1c4aa10f5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.c @@ -0,0 +1,749 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_platform_i2c_dev.h" + +#define PROXY_NAME "wb-platform-i2c-dev" +#define MAX_I2C_DEV_NUM (256) +#define FPGA_MAX_LEN (256) +#define MAX_NAME_SIZE (20) +#define MAX_BUS_WIDTH (16) +#define TRANSFER_WRITE_BUFF (FPGA_MAX_LEN + MAX_BUS_WIDTH) + +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) + +int g_i2c_dev_debug = 0; +int g_i2c_dev_error = 0; + +module_param(g_i2c_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_i2c_dev_error, int, S_IRUGO | S_IWUSR); + +#define I2C_DEV_DEBUG_DMESG(fmt, args...) do { \ + if (g_i2c_dev_debug) { \ + printk(KERN_ERR "[I2C_DEV][DEBUG][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define I2C_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_i2c_dev_error) { \ + printk(KERN_ERR "[I2C_DEV][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct platform_i2c_dev_info* i2c_dev_arry[MAX_I2C_DEV_NUM]; + +struct platform_i2c_dev_info { + uint32_t i2c_bus; + uint32_t i2c_addr; + const char *name; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + struct miscdevice misc; +}; + +static int transfer_read(struct platform_i2c_dev_info *i2c_dev, u8 *buf, loff_t regaddr, size_t count) +{ + int i, j; + struct i2c_adapter *adap; + union i2c_smbus_data data; + u8 offset_buf[MAX_BUS_WIDTH]; + struct i2c_msg msgs[2]; + int msgs_num, ret; + u8 offset; + u8 length; + + if (!i2c_dev) { + I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\r\n"); + return -ENODEV; + } + + i = 0; + + mem_clear(offset_buf, sizeof(offset_buf)); + + switch (i2c_dev->addr_bus_width) { + case WIDTH_4Byte: + offset_buf[i++] = (regaddr >> 24) & 0xFF; + offset_buf[i++] = (regaddr >> 16) & 0xFF; + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + offset_buf[i++] = regaddr & 0xFF; + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\r\n", i2c_dev->addr_bus_width); + return -EINVAL; + } + + adap = i2c_get_adapter(i2c_dev->i2c_bus); + if (adap == NULL) { + I2C_DEV_DEBUG_ERROR("get i2c adapter %d faild.\n", i2c_dev->i2c_bus); + return -ENXIO; + } + + if (adap->algo->master_xfer) { + mem_clear(msgs, sizeof(msgs)); + msgs[0].addr = i2c_dev->i2c_addr; + msgs[0].flags = 0; + msgs[0].len = i2c_dev->addr_bus_width; + msgs[0].buf = offset_buf; + + msgs[1].addr = i2c_dev->i2c_addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = count; + msgs[1].buf = buf; + + msgs_num = 2; + ret = i2c_transfer(adap, msgs, msgs_num); + if (ret != msgs_num) { + I2C_DEV_DEBUG_ERROR("i2c_transfer read error\r\n"); + ret = -EFAULT; + goto error_exit; + } + } else { + if (i2c_dev->addr_bus_width == WIDTH_1Byte) { + offset = regaddr & 0xFF; + if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + for (j = 0; j < count; j += I2C_SMBUS_BLOCK_MAX) { + if (count - j > I2C_SMBUS_BLOCK_MAX) { + length = I2C_SMBUS_BLOCK_MAX; + } else { + length = count - j; + } + data.block[0] = length; + ret = adap->algo->smbus_xfer(adap, i2c_dev->i2c_addr, + 0, + I2C_SMBUS_READ, + offset, I2C_SMBUS_I2C_BLOCK_DATA, &data); + if (ret) { + I2C_DEV_DEBUG_ERROR("smbus_xfer read block error, ret = %d\r\n", ret); + ret = -EFAULT; + goto error_exit; + } + memcpy(buf + j, data.block + 1, length); + offset += length; + } + } else { + for (j = 0; j < count; j++) { + ret = adap->algo->smbus_xfer(adap, i2c_dev->i2c_addr, + 0, + I2C_SMBUS_READ, + offset, I2C_SMBUS_BYTE_DATA, &data); + + if (!ret) { + buf[j] = data.byte; + } else { + I2C_DEV_DEBUG_ERROR("smbus_xfer read byte error, ret = %d\r\n", ret); + ret = -EFAULT; + goto error_exit; + } + offset++; + } + } + } else { + I2C_DEV_DEBUG_ERROR("smbus_xfer not support addr_bus_width = %d\r\n", i2c_dev->addr_bus_width); + ret = -EINVAL; + goto error_exit; + } + } + + i2c_put_adapter(adap); + return 0; +error_exit: + i2c_put_adapter(adap); + return ret; +} + +static int transfer_write(struct platform_i2c_dev_info *i2c_dev, u8 *buf, loff_t regaddr, size_t count) +{ + int i, j; + struct i2c_adapter *adap; + union i2c_smbus_data data; + u8 offset_buf[TRANSFER_WRITE_BUFF]; + struct i2c_msg msgs[1]; + int msgs_num, ret; + u8 offset; + u8 length; + + if (!i2c_dev) { + I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\r\n"); + return -ENODEV; + } + + i = 0; + + mem_clear(offset_buf, sizeof(offset_buf)); + + switch (i2c_dev->addr_bus_width) { + case WIDTH_4Byte: + offset_buf[i++] = (regaddr >> 24) & 0xFF; + offset_buf[i++] = (regaddr >> 16) & 0xFF; + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + offset_buf[i++] = regaddr & 0xFF; + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\r\n", i2c_dev->addr_bus_width); + return -EINVAL; + } + + memcpy(offset_buf + i2c_dev->addr_bus_width, buf, count); + + adap = i2c_get_adapter(i2c_dev->i2c_bus); + if (adap == NULL) { + I2C_DEV_DEBUG_ERROR("get i2c adapter %d faild.\n", i2c_dev->i2c_bus); + return -ENXIO; + } + + if (adap->algo->master_xfer) { + mem_clear(msgs, sizeof(msgs)); + + msgs[0].addr = i2c_dev->i2c_addr; + msgs[0].flags = 0; + msgs[0].len = i2c_dev->addr_bus_width + count; + msgs[0].buf = offset_buf; + + msgs_num = 1; + ret = i2c_transfer(adap, msgs, msgs_num); + if (ret != msgs_num) { + I2C_DEV_DEBUG_ERROR("i2c_transfer write error\r\n"); + ret = -EFAULT; + goto error_exit; + } + } else { + if (i2c_dev->addr_bus_width == WIDTH_1Byte) { + offset = regaddr & 0xFF; + if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + for (j = 0; j < count; j += I2C_SMBUS_BLOCK_MAX) { + if (count - j > I2C_SMBUS_BLOCK_MAX) { + length = I2C_SMBUS_BLOCK_MAX; + } else { + length = count - j; + } + data.block[0] = length; + memcpy(data.block + 1, buf + j, length); + ret = adap->algo->smbus_xfer(adap, i2c_dev->i2c_addr, + 0, + I2C_SMBUS_WRITE, + offset, I2C_SMBUS_I2C_BLOCK_DATA, &data); + if (ret) { + I2C_DEV_DEBUG_ERROR("smbus_xfer write block error, ret = %d\r\n", ret); + ret = -EFAULT; + goto error_exit; + } + offset += length; + } + } else { + for (j = 0; j < count; j++) { + data.byte = buf[j]; + ret = adap->algo->smbus_xfer(adap, i2c_dev->i2c_addr, + 0, + I2C_SMBUS_WRITE, + offset, I2C_SMBUS_BYTE_DATA, &data); + if (ret) { + I2C_DEV_DEBUG_ERROR("smbus_xfer write byte error, ret = %d\r\n", ret); + ret = -EFAULT; + goto error_exit; + } + offset += 1; + } + } + } else { + I2C_DEV_DEBUG_ERROR("smbus_xfer not support addr_bus_width = %d\r\n", i2c_dev->addr_bus_width); + ret = -EINVAL; + goto error_exit; + } + } + + i2c_put_adapter(adap); + return 0; +error_exit: + i2c_put_adapter(adap); + return ret; +} + +static long i2c_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int i2c_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct platform_i2c_dev_info *i2c_dev; + + i2c_dev = i2c_dev_arry[minor]; + if (i2c_dev == NULL) { + return -ENODEV; + } + + file->private_data = i2c_dev; + + return 0; +} + +static int i2c_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static int device_read(struct platform_i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, int count) +{ + int i, j, ret; + u8 tmp_offset; + u8 val[FPGA_MAX_LEN]; + u32 width, rd_len, per_len, tmp; + u32 max_per_len; + + width = i2c_dev->data_bus_width; + switch (width) { + case WIDTH_4Byte: + tmp_offset = offset & 0x3; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %d invalid.\r\n", width, offset, count); + return -EINVAL; + } + break; + case WIDTH_2Byte: + tmp_offset = offset & 0x1; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %d invalid.\r\n", width, offset, count); + return -EINVAL; + } + break; + case WIDTH_1Byte: + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\r\n", width); + return -EINVAL; + } + + max_per_len = i2c_dev->per_rd_len; + tmp = (width - 1) & count; + rd_len = (tmp == 0) ? count : count + width - tmp; + per_len = (rd_len > max_per_len) ? (max_per_len) : (rd_len); + + mem_clear(val, sizeof(val)); + for (i = 0; i < rd_len; i += per_len) { + ret = transfer_read(i2c_dev, val + i, offset + i, per_len); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("read error.read offset = %u\r\n", (offset + i)); + return -EFAULT; + } + } + + if (width == WIDTH_1Byte) { + memcpy(buf, val, count); + } else { + for (i = 0; i < count; i += width) { + for (j = 0; (j < width) && (i + j < count); j++) { + buf[i + j] = val[i + width - j - 1]; + } + } + } + + return 0; +} + +static int device_write(struct platform_i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u8 tmp_offset; + u32 width; + u8 val[FPGA_MAX_LEN]; + u32 wr_len, per_len, tmp; + u32 max_per_len; + + width = i2c_dev->data_bus_width; + switch (width) { + case WIDTH_4Byte: + tmp_offset = offset & 0x3; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\r\n", width, offset, count); + return -EINVAL; + } + break; + case WIDTH_2Byte: + tmp_offset = offset & 0x1; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\r\n", width, offset, count); + return -EINVAL; + } + break; + case WIDTH_1Byte: + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\r\n", width); + return -EINVAL; + } + + mem_clear(val, sizeof(val)); + + if (width == WIDTH_1Byte) { + memcpy(val, buf, count); + } else { + for (i = 0; i < count; i += width) { + for (j = 0; (j < width) && (i + j < count); j++) { + val[i + width - j - 1] = buf[i + j]; + } + } + } + + max_per_len = i2c_dev->per_wr_len; + tmp = (width - 1) & count; + wr_len = (tmp == 0) ? count : count + width - tmp; + per_len = (wr_len > max_per_len) ? (max_per_len) : (wr_len); + + for (i = 0; i < wr_len; i += per_len) { + ret = transfer_write(i2c_dev, val + i, offset + i, per_len); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("write error.offset = %u\r\n", (offset + i)); + return -EFAULT; + } + } + return 0; +} + +static ssize_t i2c_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + u8 val[FPGA_MAX_LEN]; + int ret; + struct platform_i2c_dev_info *i2c_dev; + + if (count <= 0 || count > sizeof(val)) { + I2C_DEV_DEBUG_ERROR("read conut %lu , beyond max:%lu.\n", count, sizeof(val)); + return -EINVAL; + } + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("can't get read private_data .\r\n"); + return -EINVAL; + } + + ret = device_read(i2c_dev, (uint32_t)*offset, val, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, (uint32_t)*offset, count); + return -EINVAL; + } + + if (copy_to_user(buf, val, count)) { + I2C_DEV_DEBUG_ERROR("copy_to_user error \r\n"); + return -EFAULT; + } else{ + *offset += count; + } + + return count; +} + +static ssize_t i2c_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) +{ + u8 val[FPGA_MAX_LEN]; + int ret; + struct platform_i2c_dev_info *i2c_dev; + + if (count <= 0 || count > sizeof(val)) { + I2C_DEV_DEBUG_ERROR("write conut %lu, beyond max val:%lu.\n", count, sizeof(val)); + return -EINVAL; + } + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("get write private_data error.\r\n"); + return -EINVAL; + } + + mem_clear(val, sizeof(val)); + if (copy_from_user(val, buf, count)) { + I2C_DEV_DEBUG_ERROR("copy_from_user error.\r\n"); + return -EFAULT; + } + + ret = device_write (i2c_dev, (uint32_t)*offset, val, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%llx, len:%lu.\n", + i2c_dev->name, *offset, count); + return -EINVAL; + } + + *offset += count; + return count; +} + +static loff_t i2c_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + I2C_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\r\n", offset); + ret = -EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (file->f_pos + offset < 0) { + I2C_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld.\n", + file->f_pos, offset); + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + I2C_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static const struct file_operations i2c_dev_fops = { + .owner = THIS_MODULE, + .llseek = i2c_dev_llseek, + .read = i2c_dev_read, + .write = i2c_dev_write, + .unlocked_ioctl = i2c_dev_ioctl, + .open = i2c_dev_open, + .release = i2c_dev_release, +}; + +static struct platform_i2c_dev_info * dev_match(const char *path) +{ + struct platform_i2c_dev_info *i2c_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + for (i = 0; i < MAX_I2C_DEV_NUM; i++) { + if (i2c_dev_arry[ i ] == NULL) { + continue; + } + i2c_dev = i2c_dev_arry[ i ]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", i2c_dev->name); + if (!strcmp(path, dev_name)) { + I2C_DEV_DEBUG_DMESG("get dev_name = %s, minor = %d\n", dev_name, i); + return i2c_dev; + } + } + + return NULL; +} + +int platform_i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct platform_i2c_dev_info *i2c_dev = NULL; + int ret; + + if(path == NULL){ + I2C_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + I2C_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > FPGA_MAX_LEN) { + I2C_DEV_DEBUG_ERROR("read conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN); + return -EINVAL; + } + + i2c_dev = dev_match(path); + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_read(i2c_dev, offset, buf, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("fpga i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(platform_i2c_device_func_read); + +int platform_i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct platform_i2c_dev_info *i2c_dev = NULL; + int ret; + + if(path == NULL){ + I2C_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + I2C_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > FPGA_MAX_LEN) { + I2C_DEV_DEBUG_ERROR("write conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN); + return -EINVAL; + } + + i2c_dev = dev_match(path); + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_write (i2c_dev, offset, buf, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(platform_i2c_device_func_write); + +static int platform_i2c_dev_probe(struct platform_device *pdev) +{ + int ret = 0; + struct platform_i2c_dev_info *i2c_dev; + struct miscdevice *misc; + platform_i2c_dev_device_t *platform_i2c_dev_device; + + i2c_dev = devm_kzalloc(&pdev->dev, sizeof(struct platform_i2c_dev_info), GFP_KERNEL); + if (!i2c_dev) { + dev_err(&pdev->dev, "devm_kzalloc error. \r\n"); + return -ENOMEM; + } + + if (pdev->dev.of_node) { + + ret += of_property_read_u32(pdev->dev.of_node, "i2c_bus", &i2c_dev->i2c_bus); + ret += of_property_read_u32(pdev->dev.of_node, "i2c_addr", &i2c_dev->i2c_addr); + ret += of_property_read_string(pdev->dev.of_node, "i2c_name", &i2c_dev->name); + ret += of_property_read_u32(pdev->dev.of_node, "data_bus_width", &i2c_dev->data_bus_width); + ret += of_property_read_u32(pdev->dev.of_node, "addr_bus_width", &i2c_dev->addr_bus_width); + ret += of_property_read_u32(pdev->dev.of_node, "per_rd_len", &i2c_dev->per_rd_len); + ret += of_property_read_u32(pdev->dev.of_node, "per_wr_len", &i2c_dev->per_wr_len); + if (ret != 0) { + dev_err(&pdev->dev, "dts config error.ret:%d.\r\n", ret); + return -ENXIO; + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + platform_i2c_dev_device = pdev->dev.platform_data; + i2c_dev->i2c_bus = platform_i2c_dev_device->i2c_bus; + i2c_dev->i2c_addr = platform_i2c_dev_device->i2c_addr; + i2c_dev->name = platform_i2c_dev_device->i2c_name; + i2c_dev->data_bus_width = platform_i2c_dev_device->data_bus_width; + i2c_dev->addr_bus_width = platform_i2c_dev_device->addr_bus_width; + i2c_dev->per_rd_len = platform_i2c_dev_device->per_rd_len; + i2c_dev->per_wr_len = platform_i2c_dev_device->per_wr_len; + } + + if ((i2c_dev->per_rd_len & (i2c_dev->data_bus_width - 1)) || (i2c_dev->per_wr_len & (i2c_dev->data_bus_width - 1))) { + dev_err(&pdev->dev, "Invalid config per_rd_len %d per_wr_len %d data bus_width %d.\r\n", i2c_dev->per_rd_len, + i2c_dev->per_wr_len, i2c_dev->data_bus_width); + return -ENXIO; + } + + misc = &i2c_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = i2c_dev->name; + misc->fops = &i2c_dev_fops; + if (misc_register(misc) != 0) { + dev_err(&pdev->dev, "register %s faild.\r\n", misc->name); + return -ENXIO; + } + + if (misc->minor >= MAX_I2C_DEV_NUM) { + dev_err(&pdev->dev, "minor number beyond the limit! is %d.\r\n", misc->minor); + misc_deregister(misc); + return -ENXIO; + } + i2c_dev_arry[misc->minor] = i2c_dev; + + dev_info(&pdev->dev, "register %u addr_bus_width %u data_bus_width device %s with %u per_rd_len %u per_wr_len success.\r\n", + i2c_dev->addr_bus_width, i2c_dev->data_bus_width, i2c_dev->name, i2c_dev->per_rd_len, i2c_dev->per_wr_len); + + return 0; +} + +static int platform_i2c_dev_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < MAX_I2C_DEV_NUM ; i++) { + if (i2c_dev_arry[i] != NULL) { + misc_deregister(&i2c_dev_arry[i]->misc); + i2c_dev_arry[i] = NULL; + } + } + + return 0; +} + +static const struct of_device_id platform_i2c_dev_of_match[] = { + { .compatible = "wb-platform-i2c-dev" }, + { }, +}; +MODULE_DEVICE_TABLE(of, platform_i2c_dev_of_match); + +static struct platform_driver wb_platform_i2c_dev_driver = { + .probe = platform_i2c_dev_probe, + .remove = platform_i2c_dev_remove, + .driver = { + .owner = THIS_MODULE, + .name = PROXY_NAME, + .of_match_table = platform_i2c_dev_of_match, + }, +}; + +static int __init wb_platform_i2c_dev_init(void) +{ + return platform_driver_register(&wb_platform_i2c_dev_driver); +} + +static void __exit wb_platform_i2c_dev_exit(void) +{ + platform_driver_unregister(&wb_platform_i2c_dev_driver); +} + +module_init(wb_platform_i2c_dev_init); +module_exit(wb_platform_i2c_dev_exit); + +MODULE_DESCRIPTION("platform i2c dev driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.h new file mode 100644 index 000000000000..b5158c9fec57 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.h @@ -0,0 +1,19 @@ +#ifndef __WB_PLATFORM_I2C_DEV_H__ +#define __WB_PLATFORM_I2C_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define I2C_DEV_NAME_MAX_LEN (64) + +typedef struct platform_i2c_dev_device_s { + uint32_t i2c_bus; + uint32_t i2c_addr; + char i2c_name[I2C_DEV_NAME_MAX_LEN]; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + int device_flag; +} platform_i2c_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_93xx46.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_93xx46.c new file mode 100644 index 000000000000..abc4f1567aec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_93xx46.c @@ -0,0 +1,111 @@ +/* + * EEPROMs access control driver for display configuration EEPROMs + * on DigsyMTC board. + * + * (C) 2011 DENX Software Engineering, Anatolij Gustschin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_SPI_BUS_NUM (0) +#define DEFAULT_SPI_CS_NUM (0) +#define DEFAULT_SPI_HZ (100000) + +#define GPIO_EEPROM_CS (-1) + +int g_wb_spi_93xx46_debug = 0; +int g_wb_spi_93xx46_error = 0; +int spi_bus_num = DEFAULT_SPI_BUS_NUM; +int spi_cs_gpio = GPIO_EEPROM_CS; + +module_param(g_wb_spi_93xx46_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_93xx46_error, int, S_IRUGO | S_IWUSR); +module_param(spi_bus_num, int, S_IRUGO | S_IWUSR); +module_param(spi_cs_gpio, int, S_IRUGO | S_IWUSR); + +#define SPI_93xx46_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_93xx46_debug) { \ + printk(KERN_INFO "[SPI-93xx46][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SPI_93xx46_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_spi_93xx46_error) { \ + printk(KERN_ERR "[SPI-93xx46][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct eeprom_93xx46_platform_data eeprom_data = { + .flags = EE_ADDR16, + .quirks = EEPROM_93XX46_QUIRK_SINGLE_WORD_READ, +}; + +struct spi_board_info eeprom_93xx46_info __initdata = { + .modalias = "wb_93xx46", + .max_speed_hz = DEFAULT_SPI_HZ, + .bus_num = DEFAULT_SPI_BUS_NUM, + .chip_select = DEFAULT_SPI_CS_NUM, + .mode = SPI_MODE_0 | SPI_CS_HIGH, + .controller_data = (void *)GPIO_EEPROM_CS, + .platform_data = &eeprom_data, +}; + +static struct spi_device *g_spi_device; + +static int __init wb_spi_93xx46_init(void) +{ + struct spi_master *master; + + SPI_93xx46_DEBUG_VERBOSE("Enter.\n"); + + eeprom_93xx46_info.bus_num = spi_bus_num; + eeprom_93xx46_info.controller_data = (void *)(long)spi_cs_gpio; + master = spi_busnum_to_master(eeprom_93xx46_info.bus_num); + if (!master) { + SPI_93xx46_DEBUG_ERROR("get bus_num %u spi master failed.\n", + eeprom_93xx46_info.bus_num); + return -EINVAL; + } + + g_spi_device = spi_new_device(master, &eeprom_93xx46_info); + put_device(&master->dev); + if (!g_spi_device) { + SPI_93xx46_DEBUG_ERROR("register spi new device failed.\n"); + return -EPERM; + } + + if (g_wb_spi_93xx46_debug) { + dev_info(&g_spi_device->dev, "register %u bus_num spi 93xx46 eeprom success\n", + eeprom_93xx46_info.bus_num); + } + + return 0; +} + +static void __exit wb_spi_93xx46_exit(void) +{ + spi_unregister_device(g_spi_device); + + if (g_wb_spi_93xx46_debug) { + dev_info(&g_spi_device->dev, "unregister spi 93xx46 eeprom success\n"); + } + + return; +} + +module_init(wb_spi_93xx46_init); +module_exit(wb_spi_93xx46_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("create 93xx46 eeprom device"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.c new file mode 100644 index 000000000000..807663592db4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.c @@ -0,0 +1,583 @@ +/* + * wb_spi_dev.c + * ko to read/write spi device through /dev/XXX device + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_spi_dev.h" + +#define MAX_SPI_DEV_NUM (256) +#define MAX_RW_LEN (256) +#define MAX_NAME_SIZE (20) +#define MAX_ADDR_BUS_WIDTH (4) + +#define TRANSFER_WRITE_BUFF (1 + MAX_ADDR_BUS_WIDTH + MAX_RW_LEN) + +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) + +#define OP_READ (0x3) +#define OP_WRITE (0x2) + +int g_spi_dev_debug = 0; +int g_spi_dev_error = 0; + +module_param(g_spi_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_spi_dev_error, int, S_IRUGO | S_IWUSR); + +#define SPI_DEV_DEBUG(fmt, args...) do { \ + if (g_spi_dev_debug) { \ + printk(KERN_ERR "[SPI_DEV][DEBUG][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SPI_DEV_ERROR(fmt, args...) do { \ + if (g_spi_dev_error) { \ + printk(KERN_ERR "[SPI_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct spi_dev_info* spi_dev_arry[MAX_SPI_DEV_NUM]; + +struct spi_dev_info { + const char *name; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + struct miscdevice misc; + struct spi_device *spi_device; +}; + +static int transfer_read(struct spi_dev_info *spi_dev, u8 *buf, uint32_t regaddr, size_t count) +{ + int i, ret; + u8 tx_buf[MAX_ADDR_BUS_WIDTH + 1]; + struct spi_message m; + struct spi_transfer xfer[2]; + + i = 0; + mem_clear(tx_buf, sizeof(tx_buf)); + tx_buf[i++] = OP_READ; + + switch (spi_dev->addr_bus_width) { + case WIDTH_4Byte: + tx_buf[i++] = (regaddr >> 24) & 0xFF; + tx_buf[i++] = (regaddr >> 16) & 0xFF; + tx_buf[i++] = (regaddr >> 8) & 0xFF; + tx_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + tx_buf[i++] = (regaddr >> 8) & 0xFF; + tx_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + tx_buf[i++] = regaddr & 0xFF; + break; + default: + SPI_DEV_ERROR("Only support 1,2,4 Byte Width,but set width = %u\n", + spi_dev->addr_bus_width); + return -EINVAL; + } + + mem_clear(xfer, sizeof(xfer)); + spi_message_init(&m); + xfer[0].tx_buf = tx_buf; + xfer[0].len = spi_dev->addr_bus_width + 1; + spi_message_add_tail(&xfer[0], &m); + + xfer[1].rx_buf = buf; + xfer[1].len = count; + spi_message_add_tail(&xfer[1], &m); + + ret = spi_sync(spi_dev->spi_device, &m); + if (ret) { + SPI_DEV_ERROR("transfer_read failed, reg addr:0x%x, len:%lu, ret:%d.\n", + regaddr, count, ret); + return -EIO; + } + return 0; +} + +static int transfer_write(struct spi_dev_info *spi_dev, u8 *buf, uint32_t regaddr, size_t count) +{ + int i, ret; + u8 tx_buf[TRANSFER_WRITE_BUFF]; + struct spi_message m; + struct spi_transfer xfer ; + + i = 0; + mem_clear(tx_buf, sizeof(tx_buf)); + tx_buf[i++] = OP_WRITE; + switch (spi_dev->addr_bus_width) { + case WIDTH_4Byte: + tx_buf[i++] = (regaddr >> 24) & 0xFF; + tx_buf[i++] = (regaddr >> 16) & 0xFF; + tx_buf[i++] = (regaddr >> 8) & 0xFF; + tx_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + tx_buf[i++] = (regaddr >> 8) & 0xFF; + tx_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + tx_buf[i++] = regaddr & 0xFF; + break; + default: + SPI_DEV_ERROR("Only support 1,2,4 Byte Width, but set width = %u\n", + spi_dev->addr_bus_width); + return -EINVAL; + } + + memcpy(tx_buf + i, buf, count); + + mem_clear(&xfer, sizeof(xfer)); + spi_message_init(&m); + xfer.tx_buf = tx_buf; + xfer.len = count + i; + spi_message_add_tail(&xfer, &m); + + ret = spi_sync(spi_dev->spi_device, &m); + if (ret) { + SPI_DEV_ERROR("transfer_write failed, reg addr:0x%x, len:%lu, ret:%d.\n", + regaddr, count, ret); + return -EIO; + } + return 0; +} + +static long spi_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int spi_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct spi_dev_info *spi_dev; + + if (minor >= MAX_SPI_DEV_NUM) { + SPI_DEV_ERROR("minor out of range, minor = %d.\n", minor); + return -ENODEV; + } + + spi_dev = spi_dev_arry[minor]; + if (spi_dev == NULL) { + SPI_DEV_ERROR("spi_dev is NULL, open failed, minor = %d\n", minor); + return -ENODEV; + } + + file->private_data = spi_dev; + + return 0; +} + +static int spi_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static int device_read(struct spi_dev_info *spi_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u8 val[MAX_RW_LEN]; + u32 data_width, rd_len, per_len, tmp; + u32 max_per_len; + + data_width = spi_dev->data_bus_width; + + if (offset % data_width) { + SPI_DEV_ERROR("data bus width:%d, offset:0x%x, read size %lu invalid.\n", + data_width, offset, count); + return -EINVAL; + } + + max_per_len = spi_dev->per_rd_len; + tmp = (data_width - 1) & count; + rd_len = (tmp == 0) ? count : count + data_width - tmp; + per_len = (rd_len > max_per_len) ? (max_per_len) : (rd_len); + + mem_clear(val, sizeof(val)); + for (i = 0; i < rd_len; i += per_len) { + ret = transfer_read(spi_dev, val + i, offset + i, per_len); + if (ret < 0) { + SPI_DEV_ERROR("read error.read offset = %u\n", (offset + i)); + return -EFAULT; + } + } + + if (data_width == WIDTH_1Byte) { + memcpy(buf, val, count); + } else { + for (i = 0; i < count; i += data_width) { + for (j = 0; (j < data_width) && (i + j < count); j++) { + buf[i + j] = val[i + data_width - j - 1]; + } + } + } + + return 0; +} + +static int device_write(struct spi_dev_info *spi_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u32 data_width; + u8 val[MAX_RW_LEN]; + u32 wr_len, per_len, tmp; + u32 max_per_len; + + data_width = spi_dev->data_bus_width; + + if (offset % data_width) { + SPI_DEV_ERROR("data bus width:%d, offset:0x%x, read size %lu invalid.\n", + data_width, offset, count); + return -EINVAL; + } + mem_clear(val, sizeof(val)); + + if (data_width == WIDTH_1Byte) { + memcpy(val, buf, count); + } else { + for (i = 0; i < count; i += data_width) { + for (j = 0; (j < data_width) && (i + j < count); j++) { + val[i + data_width - j - 1] = buf[i + j]; + } + } + } + + max_per_len = spi_dev->per_wr_len; + tmp = (data_width - 1) & count; + wr_len = (tmp == 0) ? count : count + data_width - tmp; + per_len = (wr_len > max_per_len) ? (max_per_len) : (wr_len); + + for (i = 0; i < wr_len; i += per_len) { + ret = transfer_write(spi_dev, val + i, offset + i, per_len); + if (ret < 0) { + SPI_DEV_ERROR("write error.offset = %u\n", (offset + i)); + return -EFAULT; + } + } + return 0; +} + +static ssize_t spi_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + u8 val[MAX_RW_LEN]; + int ret; + struct spi_dev_info *spi_dev; + + if (count <= 0 || count > sizeof(val)) { + SPI_DEV_ERROR("read conut %lu , beyond max:%lu.\n", count, sizeof(val)); + return -EINVAL; + } + + spi_dev = file->private_data; + if (spi_dev == NULL) { + SPI_DEV_ERROR("can't get read private_data .\n"); + return -EINVAL; + } + + ret = device_read(spi_dev, (uint32_t)*offset, val, count); + if (ret < 0) { + SPI_DEV_ERROR("spi dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + spi_dev->name, (uint32_t)*offset, count); + return -EINVAL; + } + + if (copy_to_user(buf, val, count)) { + SPI_DEV_ERROR("copy_to_user error \n"); + return -EFAULT; + } else{ + *offset += count; + } + + return count; +} + +static ssize_t spi_dev_write(struct file *file, const char __user *buf, + size_t count, loff_t *offset) +{ + u8 val[MAX_RW_LEN]; + int ret; + struct spi_dev_info *spi_dev; + + if (count <= 0 || count > sizeof(val)) { + SPI_DEV_ERROR("write conut %lu, beyond max val:%lu.\n", count, sizeof(val)); + return -EINVAL; + } + + spi_dev = file->private_data; + if (spi_dev == NULL) { + SPI_DEV_ERROR("get write private_data error.\n"); + return -EINVAL; + } + + mem_clear(val, sizeof(val)); + if (copy_from_user(val, buf, count)) { + SPI_DEV_ERROR("copy_from_user error.\n"); + return -EFAULT; + } + + ret = device_write(spi_dev, (uint32_t)*offset, val, count); + if (ret < 0) { + SPI_DEV_ERROR("spi dev write failed, dev name:%s, offset:0x%llx, len:%lu.\n", + spi_dev->name, *offset, count); + return -EINVAL; + } + + *offset += count; + return count; +} + +static loff_t spi_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + SPI_DEV_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (file->f_pos + offset < 0) { + SPI_DEV_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld.\n", + file->f_pos, offset); + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + SPI_DEV_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static const struct file_operations spi_dev_fops = { + .owner = THIS_MODULE, + .llseek = spi_dev_llseek, + .read = spi_dev_read, + .write = spi_dev_write, + .unlocked_ioctl = spi_dev_ioctl, + .open = spi_dev_open, + .release = spi_dev_release, +}; + +static struct spi_dev_info * dev_match(const char *path) +{ + struct spi_dev_info * spi_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + for (i = 0; i < MAX_SPI_DEV_NUM; i++) { + if (spi_dev_arry[ i ] == NULL) { + continue; + } + spi_dev = spi_dev_arry[ i ]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", spi_dev->name); + if (!strcmp(path, dev_name)) { + SPI_DEV_DEBUG("get dev_name = %s, minor = %d\n", dev_name, i); + return spi_dev; + } + } + + return NULL; +} + +int spi_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct spi_dev_info *spi_dev = NULL; + int ret; + + if(path == NULL){ + SPI_DEV_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + SPI_DEV_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > MAX_RW_LEN) { + SPI_DEV_ERROR("read conut %lu, beyond max:%d.\n", count, MAX_RW_LEN); + return -EINVAL; + } + + spi_dev = dev_match(path); + if (spi_dev == NULL) { + SPI_DEV_ERROR("spi_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_read(spi_dev, offset, buf, count); + if (ret < 0) { + SPI_DEV_ERROR("spi dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + spi_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(spi_device_func_read); + +int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct spi_dev_info *spi_dev = NULL; + int ret; + + if(path == NULL){ + SPI_DEV_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + SPI_DEV_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > MAX_RW_LEN) { + SPI_DEV_ERROR("write conut %lu, beyond max:%d.\n", count, MAX_RW_LEN); + return -EINVAL; + } + + spi_dev = dev_match(path); + if (spi_dev == NULL) { + SPI_DEV_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_write (spi_dev, offset, buf, count); + if (ret < 0) { + SPI_DEV_ERROR("i2c dev write failed, dev name:%s, offset:0x%x, len:%lu.\n", + spi_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(spi_device_func_write); + +static int spi_dev_probe(struct spi_device *spi) +{ + int ret; + struct spi_dev_info *spi_dev; + struct miscdevice *misc; + spi_dev_device_t *spi_dev_device; + + spi_dev = devm_kzalloc(&spi->dev, sizeof(struct spi_dev_info), GFP_KERNEL); + if (!spi_dev) { + dev_err(&spi->dev, "devm_kzalloc error. \n"); + return -ENOMEM; + } + + spi_set_drvdata(spi, spi_dev); + spi_dev->spi_device = spi; + + if (spi->dev.of_node) { + + ret = 0; + ret += of_property_read_string(spi->dev.of_node, "spi_dev_name", &spi_dev->name); + ret += of_property_read_u32(spi->dev.of_node, "data_bus_width", &spi_dev->data_bus_width); + ret += of_property_read_u32(spi->dev.of_node, "addr_bus_width", &spi_dev->addr_bus_width); + ret += of_property_read_u32(spi->dev.of_node, "per_rd_len", &spi_dev->per_rd_len); + ret += of_property_read_u32(spi->dev.of_node, "per_wr_len", &spi_dev->per_wr_len); + if (ret != 0) { + dev_err(&spi->dev, "dts config error.ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (spi->dev.platform_data == NULL) { + dev_err(&spi->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + spi_dev_device = spi->dev.platform_data; + spi_dev->name = spi_dev_device->spi_dev_name; + spi_dev->data_bus_width = spi_dev_device->data_bus_width; + spi_dev->addr_bus_width = spi_dev_device->addr_bus_width; + spi_dev->per_rd_len = spi_dev_device->per_rd_len; + spi_dev->per_wr_len = spi_dev_device->per_wr_len; + } + + if ((spi_dev->per_rd_len & (spi_dev->data_bus_width - 1)) + || (spi_dev->per_wr_len & (spi_dev->data_bus_width - 1))) { + dev_err(&spi->dev, "Invalid config per_rd_len [%u] per_wr_len [%u] data bus_width [%u], addr bus width [%u].\n", + spi_dev->per_rd_len, spi_dev->per_wr_len, spi_dev->data_bus_width, spi_dev->addr_bus_width); + return -ENXIO; + } + + misc = &spi_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = spi_dev->name; + misc->fops = &spi_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&spi->dev, "register %s faild.\n", misc->name); + return -ENXIO; + } + + if (misc->minor >= MAX_SPI_DEV_NUM) { + dev_err(&spi->dev, "minor number beyond the limit! is %d.\n", misc->minor); + misc_deregister(misc); + return -ENXIO; + } + spi_dev_arry[misc->minor] = spi_dev; + + dev_info(&spi->dev, "register %u data_bus_width %u addr_bus_witdh device %s with %u per_rd_len %u per_wr_len success.\n", + spi_dev->data_bus_width, spi_dev->addr_bus_width, spi_dev->name, spi_dev->per_rd_len, spi_dev->per_wr_len); + + return 0; +} + +static int spi_dev_remove(struct spi_device *spi) +{ + int i; + + for (i = 0; i < MAX_SPI_DEV_NUM; i++) { + if (spi_dev_arry[i] != NULL) { + misc_deregister(&spi_dev_arry[i]->misc); + spi_dev_arry[i] = NULL; + } + } + return 0; +} + +static const struct of_device_id spi_dev_of_match[] = { + { .compatible = "wb-spi-dev" }, + { }, +}; + +MODULE_DEVICE_TABLE(of, spi_dev_of_match); + +static struct spi_driver spi_dev_driver = { + .driver = { + .name = "wb-spi-dev", + .of_match_table = of_match_ptr(spi_dev_of_match), + }, + .probe = spi_dev_probe, + .remove = spi_dev_remove, +}; + +module_spi_driver(spi_dev_driver); + +MODULE_DESCRIPTION("spi dev driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.h new file mode 100644 index 000000000000..6afc0145638d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.h @@ -0,0 +1,16 @@ +#ifndef __WB_SPI_DEV_H__ +#define __WB_SPI_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define SPI_DEV_NAME_MAX_LEN (64) + +typedef struct spi_dev_device_s { + char spi_dev_name[SPI_DEV_NAME_MAX_LEN]; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; +} spi_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio.c new file mode 100644 index 000000000000..16408f067be1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio.c @@ -0,0 +1,477 @@ +/* + * SPI master driver using generic bitbanged GPIO + * + * Copyright (C) 2006,2008 David Brownell + * Copyright (C) 2017 Linus Walleij + * + * 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. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * This bitbanging SPI master driver should help make systems usable + * when a native hardware SPI engine is not available, perhaps because + * its driver isn't yet working or because the I/O pins it requires + * are used for other purposes. + * + * platform_device->driver_data ... points to spi_gpio + * + * spi->controller_state ... reserved for bitbang framework code + * spi->controller_data ... holds chipselect GPIO + * + * spi->master->dev.driver_data ... points to spi_gpio->bitbang + */ + +struct spi_gpio { + struct spi_bitbang bitbang; + struct spi_gpio_platform_data pdata; + struct platform_device *pdev; + struct gpio_desc *sck; + struct gpio_desc *miso; + struct gpio_desc *mosi; + struct gpio_desc **cs_gpios; + bool has_cs; +}; + +/*----------------------------------------------------------------------*/ + +/* + * Because the overhead of going through four GPIO procedure calls + * per transferred bit can make performance a problem, this code + * is set up so that you can use it in either of two ways: + * + * - The slow generic way: set up platform_data to hold the GPIO + * numbers used for MISO/MOSI/SCK, and issue procedure calls for + * each of them. This driver can handle several such busses. + * + * - The quicker inlined way: only helps with platform GPIO code + * that inlines operations for constant GPIOs. This can give + * you tight (fast!) inner loops, but each such bus needs a + * new driver. You'll define a new C file, with Makefile and + * Kconfig support; the C code can be a total of six lines: + * + * #define DRIVER_NAME "myboard_spi2" + * #define SPI_MISO_GPIO 119 + * #define SPI_MOSI_GPIO 120 + * #define SPI_SCK_GPIO 121 + * #define SPI_N_CHIPSEL 4 + * #include "spi-gpio.c" + */ + +#ifndef DRIVER_NAME +#define DRIVER_NAME "wb_spi_gpio" + +#define GENERIC_BITBANG /* vs tight inlines */ + +#endif + +/*----------------------------------------------------------------------*/ + +static inline struct spi_gpio *__pure +spi_to_spi_gpio(const struct spi_device *spi) +{ + const struct spi_bitbang *bang; + struct spi_gpio *spi_gpio; + + bang = spi_master_get_devdata(spi->master); + spi_gpio = container_of(bang, struct spi_gpio, bitbang); + return spi_gpio; +} + +static inline struct spi_gpio_platform_data *__pure +spi_to_pdata(const struct spi_device *spi) +{ + return &spi_to_spi_gpio(spi)->pdata; +} + +/* These helpers are in turn called by the bitbang inlines */ +static inline void setsck(const struct spi_device *spi, int is_on) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + gpiod_set_value_cansleep(spi_gpio->sck, is_on); +} + +static inline void setmosi(const struct spi_device *spi, int is_on) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + gpiod_set_value_cansleep(spi_gpio->mosi, is_on); +} + +static inline int getmiso(const struct spi_device *spi) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + if (spi->mode & SPI_3WIRE) + return !!gpiod_get_value_cansleep(spi_gpio->mosi); + else + return !!gpiod_get_value_cansleep(spi_gpio->miso); +} + +/* + * NOTE: this clocks "as fast as we can". It "should" be a function of the + * requested device clock. Software overhead means we usually have trouble + * reaching even one Mbit/sec (except when we can inline bitops), so for now + * we'll just assume we never need additional per-bit slowdowns. + */ +#define spidelay(nsecs) do {} while (0) + +#include "spi-bitbang-txrx.h" + +/* + * These functions can leverage inline expansion of GPIO calls to shrink + * costs for a txrx bit, often by factors of around ten (by instruction + * count). That is particularly visible for larger word sizes, but helps + * even with default 8-bit words. + * + * REVISIT overheads calling these functions for each word also have + * significant performance costs. Having txrx_bufs() calls that inline + * the txrx_word() logic would help performance, e.g. on larger blocks + * used with flash storage or MMC/SD. There should also be ways to make + * GCC be less stupid about reloading registers inside the I/O loops, + * even without inlined GPIO calls; __attribute__((hot)) on GCC 4.3? + */ + +static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); +} + +static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); +} + +/* + * These functions do not call setmosi or getmiso if respective flag + * (SPI_MASTER_NO_RX or SPI_MASTER_NO_TX) is set, so they are safe to + * call when such pin is not present or defined in the controller. + * A separate set of callbacks is defined to get highest possible + * speed in the generic case (when both MISO and MOSI lines are + * available), as optimiser will remove the checks when argument is + * constant. + */ + +static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + flags = spi->master->flags; + return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + flags = spi->master->flags; + return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + flags = spi->master->flags; + return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); +} + +static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + flags = spi->master->flags; + return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); +} + +/*----------------------------------------------------------------------*/ + +static void spi_gpio_chipselect(struct spi_device *spi, int is_active) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + /* set initial clock line level */ + if (is_active) + gpiod_set_value_cansleep(spi_gpio->sck, spi->mode & SPI_CPOL); + + /* Drive chip select line, if we have one */ + if (spi_gpio->has_cs) { + struct gpio_desc *cs = spi_gpio->cs_gpios[spi->chip_select]; + + /* SPI chip selects are normally active-low */ + gpiod_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); + } +} + +static int spi_gpio_setup(struct spi_device *spi) +{ + struct gpio_desc *cs; + int status = 0; + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + /* + * The CS GPIOs have already been + * initialized from the descriptor lookup. + */ + cs = spi_gpio->cs_gpios[spi->chip_select]; + if (!spi->controller_state && cs) + status = gpiod_direction_output(cs, + !(spi->mode & SPI_CS_HIGH)); + + if (!status) + status = spi_bitbang_setup(spi); + + return status; +} + +static int spi_gpio_set_direction(struct spi_device *spi, bool output) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + if (output) + return gpiod_direction_output(spi_gpio->mosi, 1); + else + return gpiod_direction_input(spi_gpio->mosi); +} + +static void spi_gpio_cleanup(struct spi_device *spi) +{ + spi_bitbang_cleanup(spi); +} + +/* + * It can be convenient to use this driver with pins that have alternate + * functions associated with a "native" SPI controller if a driver for that + * controller is not available, or is missing important functionality. + * + * On platforms which can do so, configure MISO with a weak pullup unless + * there's an external pullup on that signal. That saves power by avoiding + * floating signals. (A weak pulldown would save power too, but many + * drivers expect to see all-ones data as the no slave "response".) + */ +static int spi_gpio_request(struct device *dev, + struct spi_gpio *spi_gpio, + unsigned int num_chipselects, + u16 *mflags) +{ + int i; + + spi_gpio->mosi = devm_gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW); + if (IS_ERR(spi_gpio->mosi)) + return PTR_ERR(spi_gpio->mosi); + if (!spi_gpio->mosi) + /* HW configuration without MOSI pin */ + *mflags |= SPI_MASTER_NO_TX; + + spi_gpio->miso = devm_gpiod_get_optional(dev, "miso", GPIOD_IN); + if (IS_ERR(spi_gpio->miso)) + return PTR_ERR(spi_gpio->miso); + /* + * No setting SPI_MASTER_NO_RX here - if there is only a MOSI + * pin connected the host can still do RX by changing the + * direction of the line. + */ + + spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW); + if (IS_ERR(spi_gpio->sck)) + return PTR_ERR(spi_gpio->sck); + + for (i = 0; i < num_chipselects; i++) { + spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", + i, GPIOD_OUT_HIGH); + if (IS_ERR(spi_gpio->cs_gpios[i])) + return PTR_ERR(spi_gpio->cs_gpios[i]); + } + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id spi_gpio_dt_ids[] = { + { .compatible = "wb-spi-gpio" }, + {} +}; +MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids); + +static int spi_gpio_probe_dt(struct platform_device *pdev) +{ + int ret; + u32 tmp; + struct spi_gpio_platform_data *pdata; + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *of_id = + of_match_device(spi_gpio_dt_ids, &pdev->dev); + + if (!of_id) + return 0; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + ret = of_property_read_u32(np, "num-chipselects", &tmp); + if (ret < 0) { + dev_err(&pdev->dev, "num-chipselects property not found\n"); + goto error_free; + } + + pdata->num_chipselect = tmp; + pdev->dev.platform_data = pdata; + + return 1; + +error_free: + devm_kfree(&pdev->dev, pdata); + return ret; +} +#else +static inline int spi_gpio_probe_dt(struct platform_device *pdev) +{ + return 0; +} +#endif + +static int spi_gpio_probe(struct platform_device *pdev) +{ + int status; + struct spi_master *master; + struct spi_gpio *spi_gpio; + struct spi_gpio_platform_data *pdata; + u16 master_flags = 0; + bool use_of = 0; + + status = spi_gpio_probe_dt(pdev); + if (status < 0) + return status; + if (status > 0) + use_of = 1; + + pdata = dev_get_platdata(&pdev->dev); +#ifdef GENERIC_BITBANG + if (!pdata || (!use_of && !pdata->num_chipselect)) + return -ENODEV; +#endif + + master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio)); + if (!master) + return -ENOMEM; + + spi_gpio = spi_master_get_devdata(master); + + spi_gpio->cs_gpios = devm_kcalloc(&pdev->dev, + pdata->num_chipselect, + sizeof(*spi_gpio->cs_gpios), + GFP_KERNEL); + if (!spi_gpio->cs_gpios) + return -ENOMEM; + + platform_set_drvdata(pdev, spi_gpio); + + /* Determine if we have chip selects connected */ + spi_gpio->has_cs = !!pdata->num_chipselect; + + spi_gpio->pdev = pdev; + if (pdata) + spi_gpio->pdata = *pdata; + + status = spi_gpio_request(&pdev->dev, spi_gpio, + pdata->num_chipselect, &master_flags); + if (status) + return status; + + master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); + master->mode_bits = SPI_3WIRE | SPI_CPHA | SPI_CPOL | SPI_CS_HIGH; + master->flags = master_flags; + master->bus_num = pdev->id; + /* The master needs to think there is a chipselect even if not connected */ + master->num_chipselect = spi_gpio->has_cs ? pdata->num_chipselect : 1; + master->setup = spi_gpio_setup; + master->cleanup = spi_gpio_cleanup; + + if (pdev->dev.of_node) { + master->dev.of_node = pdev->dev.of_node; + } + + spi_gpio->bitbang.master = master; + spi_gpio->bitbang.chipselect = spi_gpio_chipselect; + spi_gpio->bitbang.set_line_direction = spi_gpio_set_direction; + + if ((master_flags & SPI_MASTER_NO_TX) == 0) { + spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; + spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; + spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; + spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3; + } else { + spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0; + spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1; + spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2; + spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3; + } + spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer; + + status = spi_bitbang_start(&spi_gpio->bitbang); + if (status) + spi_master_put(master); + + return status; +} + +static int spi_gpio_remove(struct platform_device *pdev) +{ + struct spi_gpio *spi_gpio; + struct spi_gpio_platform_data *pdata; + + spi_gpio = platform_get_drvdata(pdev); + pdata = dev_get_platdata(&pdev->dev); + + /* stop() unregisters child devices too */ + spi_bitbang_stop(&spi_gpio->bitbang); + + spi_master_put(spi_gpio->bitbang.master); + + return 0; +} + +MODULE_ALIAS("platform:" DRIVER_NAME); + +static struct platform_driver spi_gpio_driver = { + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(spi_gpio_dt_ids), + }, + .probe = spi_gpio_probe, + .remove = spi_gpio_remove, +}; +module_platform_driver(spi_gpio_driver); + +MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO "); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio_device.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio_device.c new file mode 100644 index 000000000000..e70c97b1af9d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio_device.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define DEFAULT_GPIO_SCK (67) +#define DEFAULT_GPIO_MISO (32) +#define DEFAULT_GPIO_MOSI (65) +#define DEFAULT_GPIO_CS (6) +#define DEFAULT_SPI_BUS (0) + +static int sck = DEFAULT_GPIO_SCK; +module_param(sck, int, S_IRUGO | S_IWUSR); + +static int miso = DEFAULT_GPIO_MISO; +module_param(miso, int, S_IRUGO | S_IWUSR); + +static int mosi = DEFAULT_GPIO_MOSI; +module_param(mosi, int, S_IRUGO | S_IWUSR); + +static int cs = DEFAULT_GPIO_CS; +module_param(cs, int, S_IRUGO | S_IWUSR); + +static int bus = DEFAULT_SPI_BUS; +module_param(bus, int, S_IRUGO | S_IWUSR); + +static int g_wb_spi_gpio_device_debug = 0; +static int g_wb_spi_gpio_device_error = 0; + +module_param(g_wb_spi_gpio_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_gpio_device_error, int, S_IRUGO | S_IWUSR); + +static char gpiod_lookup_table_devid[64]; + +#define WB_SPI_GPIO_DEVICE_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_gpio_device_debug) { \ + printk(KERN_INFO "[WB_SPI_GPIO_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_SPI_GPIO_DEVICE_ERROR(fmt, args...) do { \ + if (g_wb_spi_gpio_device_error) { \ + printk(KERN_ERR "[WB_SPI_GPIO_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct gpiod_lookup_table wb_spi_gpio_table = { + .table = { + GPIO_LOOKUP("wb_gpio_d1500", DEFAULT_GPIO_SCK, + "sck", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("wb_gpio_d1500", DEFAULT_GPIO_MOSI, + "mosi", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("wb_gpio_d1500", DEFAULT_GPIO_MISO, + "miso", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("wb_gpio_d1500", DEFAULT_GPIO_CS, + "cs", GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static struct spi_gpio_platform_data spi_pdata = { + .num_chipselect = 1, +}; + +static void spi_gpio_release(struct device *dev) +{ + return; +} + +static struct platform_device wb_spi_gpio_device = { + .name = "wb_spi_gpio", + .num_resources = 0, + .id = -1, + + .dev = { + .platform_data = &spi_pdata, + .release = spi_gpio_release, + } +}; + +static void wb_spi_gpio_table_devid_name_set(void) { + int size; + + size = sizeof(gpiod_lookup_table_devid); + wb_spi_gpio_device.id = bus; + + mem_clear(gpiod_lookup_table_devid, size); + switch (bus) { + case PLATFORM_DEVID_NONE: + snprintf(gpiod_lookup_table_devid, size, "%s", wb_spi_gpio_device.name); + break; + case PLATFORM_DEVID_AUTO: + snprintf(gpiod_lookup_table_devid, size, "%s.%d.auto", wb_spi_gpio_device.name, bus); + break; + default: + snprintf(gpiod_lookup_table_devid, size, "%s.%d", wb_spi_gpio_device.name, bus); + break; + } + + wb_spi_gpio_table.dev_id = gpiod_lookup_table_devid; + return ; +} +static int __init wb_spi_gpio_device_init(void) +{ + int err; + struct gpiod_lookup *p; + + WB_SPI_GPIO_DEVICE_VERBOSE("enter!\n"); + wb_spi_gpio_table.table[0].chip_hwnum = sck; + wb_spi_gpio_table.table[1].chip_hwnum = mosi; + wb_spi_gpio_table.table[2].chip_hwnum = miso; + wb_spi_gpio_table.table[3].chip_hwnum = cs; + wb_spi_gpio_table_devid_name_set(); + WB_SPI_GPIO_DEVICE_VERBOSE("spi gpi device table bus[%d] dev id[%s]\n", bus, wb_spi_gpio_table.dev_id); + for (p = &wb_spi_gpio_table.table[0]; p->key; p++) { + WB_SPI_GPIO_DEVICE_VERBOSE("con_id:%s gpio:%d\n", p->con_id, p->chip_hwnum); + } + + gpiod_add_lookup_table(&wb_spi_gpio_table); + err = platform_device_register(&wb_spi_gpio_device); + if (err < 0) { + printk(KERN_ERR "register spi gpio device fail(%d). \n", err); + gpiod_remove_lookup_table(&wb_spi_gpio_table); + return -1; + } + + return 0; +} + +static void __exit wb_spi_gpio_device_exit(void) +{ + WB_SPI_GPIO_DEVICE_VERBOSE("enter!\n"); + platform_device_unregister(&wb_spi_gpio_device); + gpiod_remove_lookup_table(&wb_spi_gpio_table); +} + +module_init(wb_spi_gpio_device_init); +module_exit(wb_spi_gpio_device_exit); +MODULE_DESCRIPTION("SPI GPIO Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_nor_device.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_nor_device.c new file mode 100644 index 000000000000..4196601f717b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_nor_device.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include + +/* The SPI Bus number that the device is mounted on can be specified manually when this module is loaded */ +#define DEFAULT_SPI_BUS_NUM (0) +#define DEFAULT_SPI_CS_NUM (0) +#define DEFAULT_SPI_HZ (100000) + +int g_wb_spi_nor_dev_debug = 0; +int g_wb_spi_nor_dev_error = 0; +int spi_bus_num = DEFAULT_SPI_BUS_NUM; + +module_param(g_wb_spi_nor_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_nor_dev_error, int, S_IRUGO | S_IWUSR); +module_param(spi_bus_num, int, S_IRUGO | S_IWUSR); + +#define SPI_NOR_DEV_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_nor_dev_debug) { \ + printk(KERN_INFO "[SPI_NOR_DEV][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SPI_NOR_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_spi_nor_dev_error) { \ + printk(KERN_ERR "[SPI_NOR_DEV][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct spi_board_info spi_nor_device_info __initdata= { + .modalias = "mx25l6405d", + .bus_num = DEFAULT_SPI_BUS_NUM, + .chip_select = DEFAULT_SPI_CS_NUM, + .max_speed_hz = 10 * 1000 * 1000, +}; + +static struct spi_device *g_spi_device; + +static int __init wb_spi_nor_dev_init(void) +{ + struct spi_master *master; + + SPI_NOR_DEV_DEBUG_VERBOSE("Enter.\n"); + + spi_nor_device_info.bus_num = spi_bus_num; + master = spi_busnum_to_master(spi_nor_device_info.bus_num); /* Get the controller according to the SPI Bus number */ + if (!master) { + SPI_NOR_DEV_DEBUG_ERROR("get bus_num %u spi master failed.\n", + spi_nor_device_info.bus_num); + return -EINVAL; + } + + g_spi_device = spi_new_device(master, &spi_nor_device_info); + put_device(&master->dev); + if (!g_spi_device) { + SPI_NOR_DEV_DEBUG_ERROR("register spi new device failed.\n"); + return -EPERM; + } + + if (g_wb_spi_nor_dev_debug) { + dev_info(&g_spi_device->dev, "register %u bus_num spi nor device success\n", + spi_nor_device_info.bus_num); + } + + return 0; +} + +static void __exit wb_spi_nor_dev_exit(void) +{ + spi_unregister_device(g_spi_device); + + if (g_wb_spi_nor_dev_debug) { + dev_info(&g_spi_device->dev, "unregister spi nor device success\n"); + } + + return; +} + +module_init(wb_spi_nor_dev_init); +module_exit(wb_spi_nor_dev_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("create spi nor device"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.c new file mode 100644 index 000000000000..a709427c5b73 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.c @@ -0,0 +1,1025 @@ +/* + * wb_spi_ocores.c + * ko to create ocores spi adapter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_spi_ocores.h" + +#define SPIOC_WAIT_SCH (5) +#define SPIOC_CONF (0x00) +#define SPIOC_LSBF BIT(0) /* 0:MSB 1:LSB */ +#define SPIOC_IDLE_LOW BIT(1) +#define SPIOC_INTREN BIT(2) /* 0:enable 1:disabel */ +#define SPIOC_DIV_MASK (0xf0) +#define SPIOC_MAX_DIV (0x0E) +#define SPIOC_DIV(div) (((div) & 0x0f) << 4) + +#define SPIOC_STS (0x01) +#define SPIOC_INTR_STS BIT(0) +#define SPIOC_BUSY_STS BIT(1) +#define SPIOC_RXNUM_SHIFT (4) +#define SPIOC_RXNUM_MASK (0xf << SPIOC_RXNUM_SHIFT) +/* Just for read */ +#define SPIOC_RXNUM(reg) (((reg) & SPIOC_RXNUM_MASK) >> SPIOC_RXNUM_SHIFT ) + +#define SPIOC_TXTOT_NUM (0x02) +#define SPIOC_TXNUM(reg) ((reg) & 0x0f) +#define SPIOC_TOTNUM(reg) (((reg) & 0x0f) << 4) + +#define SPIOC_TXCTL (0x03) +#define SPIOC_CSLV BIT(0) /* 0:Deassert SPICS 1:Laeve SPICS */ +#define SPIOC_TRSTART BIT(1) +#define SPIOC_CSID_SHIFT (5) +#define SPIOC_CSID_MASK (0x7 << SPIOC_CSID_SHIFT) +/* Just for write */ +#define SPIOC_CSID(id) (((id) << SPIOC_CSID_SHIFT) & SPIOC_CSID_MASK) + +/* Just single byte */ +#define SPIOC_RX(i) ((0x4) + i) +#define SPIOC_TX(i) ((0x4) + i) + +#define SPIOC_MAX_LEN ((unsigned int)8) +#define SPIOC_TXRX_MAX_LEN ((unsigned int)7) + +#define MODEBITS (SPI_CPHA |SPI_CPOL | SPI_LSB_FIRST |SPI_CS_HIGH) + +#define REG_IO_WIDTH_1 (1) +#define REG_IO_WIDTH_2 (2) +#define REG_IO_WIDTH_4 (4) + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) + +int g_spi_oc_debug = 0; +int g_spi_oc_error = 0; + +module_param(g_spi_oc_debug, int, S_IRUGO | S_IWUSR); +module_param(g_spi_oc_error, int, S_IRUGO | S_IWUSR); + +#define SPI_OC_VERBOSE(fmt, args...) do { \ + if (g_spi_oc_debug) { \ + printk(KERN_INFO "[OC_SPI_BUS][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SPI_OC_ERROR(fmt, args...) do { \ + if (g_spi_oc_error) { \ + printk(KERN_ERR "[OC_SPI_BUS][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct spioc { + /* bitbang has to be first */ + struct spi_bitbang bitbang; + int irq; + struct completion done; + unsigned int reamin_len; + unsigned int cur_pos; + unsigned int cur_len; + const u8 *txp; + u8 *rxp; + u8 chip_select; + void (*setreg)(struct spioc *spioc, int reg, u32 value); + u32 (*getreg)(struct spioc *spioc, int reg); + uint32_t bus_num; + const char *dev_name; + uint32_t reg_access_mode; + uint32_t base_addr; + uint32_t reg_shift; + uint32_t reg_io_width; + uint32_t num_chipselect; + uint32_t freq; + uint32_t big_endian; + struct device *dev; + int transfer_busy_flag; +}; + +extern int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); + +static int oc_spi_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + SPI_OC_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + SPI_OC_ERROR("kernel_read failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int oc_spi_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + SPI_OC_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + SPI_OC_ERROR("kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int oc_spi_reg_write(struct spioc *spioc, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (spioc->reg_access_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(spioc->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = oc_spi_file_write(spioc->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(spioc->dev_name, pos, val, size); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_write(spioc->dev_name, pos, val, size); + break; + default: + SPI_OC_ERROR("err func_mode, write failed.\n"); + return -EINVAL; + } + + return ret; +} + +static int oc_spi_reg_read(struct spioc *spioc, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (spioc->reg_access_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_read(spioc->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = oc_spi_file_read(spioc->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_read(spioc->dev_name, pos, val, size); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_read(spioc->dev_name, pos, val, size); + break; + default: + SPI_OC_ERROR("err func_mode, read failed.\n"); + return -EINVAL; + } + + return ret; +} + +static void oc_spi_setreg_8(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_1]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0Xff); + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_1); + return; +} + +static void oc_spi_setreg_16(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0Xff); + buf_tmp[1] = (value >> 8) & 0xff; + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_2); + return; +} + +static void oc_spi_setreg_32(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0xff); + buf_tmp[1] = (value >> 8) & 0xff; + buf_tmp[2] = (value >> 16) & 0xff; + buf_tmp[3] = (value >> 24) & 0xff; + + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_4); + return; +} + +static void oc_spi_setreg_16be(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value >> 8) & 0xff; + buf_tmp[1] = (value & 0Xff); + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_2); + return; +} + +static void oc_spi_setreg_32be(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value >> 24) & 0xff; + buf_tmp[1] = (value >> 16) & 0xff; + buf_tmp[2] = (value >> 8) & 0xff; + buf_tmp[3] = (value & 0xff); + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_4); + return; +} + +static inline u32 oc_spi_getreg_8(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_1]; + u32 value, pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_1); + value = buf_tmp[0]; + + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + return value; +} + +static inline u32 oc_spi_getreg_16(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 value, pos; + int i; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + mem_clear(buf_tmp, sizeof(buf_tmp)); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_2); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_2 ; i++) { + value |= buf_tmp[i] << (8 * i); + } + + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_spi_getreg_32(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 value, pos; + int i; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + mem_clear(buf_tmp, sizeof(buf_tmp)); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_4); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_4 ; i++) { + value |= buf_tmp[i] << (8 * i); + } + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_spi_getreg_16be(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 value, pos; + int i; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_2); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_2 ; i++) { + value |= buf_tmp[i] << (8 * (REG_IO_WIDTH_2 -i - 1)); + } + + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_spi_getreg_32be(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 value, pos; + int i; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_4); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_4 ; i++) { + value |= buf_tmp[i] << (8 * (REG_IO_WIDTH_4 -i - 1)); + } + + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + return value; + +} + +static inline void oc_spi_setreg(struct spioc *spioc, int reg, u32 value) +{ + spioc->setreg(spioc, reg, value); + return; +} + +static inline u32 oc_spi_getreg(struct spioc *spioc, int reg) +{ + return spioc->getreg(spioc, reg); +} + +static int spioc_get_clkdiv(struct spioc *spioc, u32 speed) +{ + u32 rate, div; + + rate = spioc->freq; + SPI_OC_VERBOSE("clk get rate:%u, speed:%u\n", rate, speed); + /* fs = fw/((DIV+2)*2) */ + + if (speed > (rate / 4)) { + div = 0; + SPI_OC_VERBOSE("spi device speed[%u] more than a quarter of clk rate[%u].\n", + speed, rate); + return div; + } + div = (rate/(2 * speed)) - 2; + if (div > SPIOC_MAX_DIV) { + SPI_OC_ERROR("Unsupport spi device speed, div:%u.\n", div); + return -1; + } + SPI_OC_VERBOSE("DIV is:0x%x\n", div); + return div; +} + +static inline int spioc_wait_trans(struct spioc *spioc, const unsigned long timeout) +{ + unsigned long j; + unsigned int sch_time; + u8 reg; + + j = jiffies + timeout; + sch_time = SPIOC_WAIT_SCH; + while (1) { + reg = oc_spi_getreg(spioc, SPIOC_STS); + if (!(reg & SPIOC_BUSY_STS)) { + SPI_OC_VERBOSE("wait ok!\n"); + break; + } + + if (time_after(jiffies, j)) { + return -ETIMEDOUT; + } + + usleep_range(sch_time, sch_time + 1); + } + + return 0; +} + +static void spioc_chipselect(struct spi_device *spi, int is_active) +{ + struct spioc *spioc; + u8 tx_conf; + int ret; + + spioc = spi_master_get_devdata(spi->master); + spioc->transfer_busy_flag = 0; + ret = spioc_wait_trans(spioc, msecs_to_jiffies(100)); + if (ret < 0) { + SPI_OC_ERROR("spi transfer is busy, ret=%d.\n", ret); + spioc->transfer_busy_flag = 1; + return; + } + spioc->chip_select = spi->chip_select; + SPI_OC_VERBOSE("spioc_chipselect:%u, value:%d.\n", spioc->chip_select, is_active); + tx_conf = 0; + tx_conf |= SPIOC_CSID(spioc->chip_select); + if (is_active) { + tx_conf |= SPIOC_CSLV; + } + + SPI_OC_VERBOSE("tx_config:[0x%x]\n", tx_conf); + oc_spi_setreg(spioc, SPIOC_TXCTL, tx_conf); + return; +} + +static void spioc_copy_tx(struct spioc *spioc) +{ + const u8 *src; + int i; + + if (!spioc->txp) { + SPI_OC_ERROR("spioc->txp is NULL.\n"); + return; + } + + src = (u8 *)spioc->txp + spioc->cur_pos; + SPI_OC_VERBOSE("current tx len:0x%x, tx pos:[0x%x]\n", spioc->cur_len, spioc->cur_pos); + + for (i = 0; i < spioc->cur_len; i++) { + SPI_OC_VERBOSE("write %d, val:[0x%x]\n", i, src[i]); + oc_spi_setreg(spioc, SPIOC_TX(i), src[i]); + } +} + +static void spioc_copy_rx(struct spioc *spioc) +{ + u8 *dest; + int i; + + if (!spioc->rxp) { + SPI_OC_ERROR("spioc->rxp is NULL.\n"); + return; + } + + dest = (u8 *)spioc->rxp + spioc->cur_pos; + SPI_OC_VERBOSE("current rx len:0x%x, rx pos:[0x%x]\n", spioc->cur_len, spioc->cur_pos); + + for (i = 0; i < spioc->cur_len; i++) { + dest[i] = oc_spi_getreg(spioc, SPIOC_RX(i)); + SPI_OC_VERBOSE("read %d, val:[0x%x]\n", i, dest[i]); + } +} + +static int spioc_setup_transfer(struct spi_device *spi, struct spi_transfer *transfer) +{ + struct spioc *spioc; + u8 ctrl; + u32 hz; + int div; + + spioc = spi_master_get_devdata(spi->master); + ctrl = 0; + + if (spi->mode & SPI_LSB_FIRST) { + ctrl |= SPIOC_LSBF; + } + + if (!(spi->mode & SPI_CPOL)) { + ctrl |= SPIOC_IDLE_LOW; + } + + if (spioc->irq < 0) { + + ctrl |= SPIOC_INTREN; + } + + if (transfer != NULL) { + hz = transfer->speed_hz; + + if (hz == 0) { + hz = spi->max_speed_hz; + } + } else { + hz = spi->max_speed_hz; + } + + if (hz == 0) { + SPI_OC_ERROR("Unsupport zero speed.\n"); + return -EINVAL; + } + + div = spioc_get_clkdiv(spioc, hz); + if (div < 0) { + SPI_OC_ERROR("get div error, div:%d.\n", div); + return -EINVAL; + } + ctrl |= SPIOC_DIV(div); + + SPI_OC_VERBOSE("ctrl:[0x%x].\n", ctrl); + + oc_spi_setreg(spioc, SPIOC_CONF, ctrl); + return 0; +} + +static int spioc_spi_setup(struct spi_device *spi) +{ + struct spioc *spioc; + + if (!(spi->mode & SPI_CPHA)) { + SPI_OC_ERROR("Unsupport spi device mde:0x%x, SPI_CPHA must be 1.\n", spi->mode); + return -EINVAL; + } + + spioc = spi_master_get_devdata(spi->master); + if (spi->chip_select >= spioc->num_chipselect) { + SPI_OC_ERROR("Spi device chipselect:%u, more than max chipselect:%u.\n", + spi->chip_select, spioc->num_chipselect); + return -EINVAL; + } + SPI_OC_VERBOSE("Support spi device mode:0x%x, chip_select:%u.\n", + spi->mode, spi->chip_select); + return 0; +} + +static int spioc_transfer_start(struct spioc *spioc) +{ + u8 tx_conf; + int ret; + + tx_conf = oc_spi_getreg(spioc, SPIOC_TXCTL); + tx_conf |= SPIOC_TRSTART; + + SPI_OC_VERBOSE("tx_config:[0x%x]\n", tx_conf); + oc_spi_setreg(spioc, SPIOC_TXCTL, tx_conf); + + ret = spioc_wait_trans(spioc, msecs_to_jiffies(100)); + return ret; +} + +static int spioc_tx_start_one(struct spioc *spioc) +{ + unsigned int txlen; + u8 txreg; + int ret; + + if (!spioc->reamin_len) { + SPI_OC_VERBOSE("spioc txlen:[0x0]\n"); + return 0; + } + + spioc->cur_len = spioc->reamin_len > SPIOC_MAX_LEN ? SPIOC_MAX_LEN : spioc->reamin_len; + + txlen = spioc->cur_len; + spioc->reamin_len -= txlen; + SPI_OC_VERBOSE("txlen:[0x%x], tx len remain:[0x%x]\n", txlen, spioc->reamin_len); + + spioc_copy_tx(spioc); + + /* when we only send, txlen == totlen */ + txreg = SPIOC_TXNUM(txlen) | SPIOC_TOTNUM(txlen); + SPI_OC_VERBOSE("txreg:[0x%x]\n", txreg); + oc_spi_setreg(spioc, SPIOC_TXTOT_NUM, txreg); + + ret = spioc_transfer_start(spioc); + if (ret) { + SPI_OC_ERROR("spioc tx rx poll wait for transfer timeout.\n"); + return ret; + } + + if (spioc->reamin_len) { + spioc->cur_pos += txlen; + SPI_OC_VERBOSE("cur_txpos:[0x%x]\n", spioc->cur_pos); + } + + return 0; +} + +static int spioc_rx_start_one(struct spioc *spioc) +{ + unsigned int rxlen; + u8 txtnum; + int ret; + + if (!spioc->reamin_len) { + SPI_OC_VERBOSE("spioc reamin_len:[0x0]\n"); + return 0; + } + + spioc->cur_len = spioc->reamin_len > SPIOC_MAX_LEN ? SPIOC_MAX_LEN : spioc->reamin_len; + + rxlen = spioc->cur_len; + spioc->reamin_len -= rxlen; + SPI_OC_VERBOSE("rxlen:[0x%x], rx len remain:[0x%x]\n", rxlen, spioc->reamin_len); + + /* when we only receive, rxnum=totnum. txnum=0 */ + txtnum = SPIOC_TOTNUM(rxlen); + SPI_OC_VERBOSE("tx total reg:0x%x\n", txtnum); + oc_spi_setreg(spioc, SPIOC_TXTOT_NUM, txtnum); + + ret = spioc_transfer_start(spioc); + if (ret) { + SPI_OC_ERROR("spioc tx rx poll wait for transfer timeout.\n"); + return ret; + } + + spioc_copy_rx(spioc); + + if (spioc->reamin_len) { + spioc->cur_pos += rxlen; + SPI_OC_VERBOSE("cur_rxpos:[0x%x]\n", spioc->cur_pos); + } + + return 0; +} + +static int spioc_tx_rx_start_one(struct spioc *spioc) +{ + unsigned int txlen, total_len; + u8 txreg; + int ret; + + if (!spioc->reamin_len) { + SPI_OC_VERBOSE("spioc reamin_len:[0x0]\n"); + return 0; + } + + spioc->cur_len = spioc->reamin_len > SPIOC_TXRX_MAX_LEN ? SPIOC_TXRX_MAX_LEN : spioc->reamin_len; + + txlen = spioc->cur_len; + spioc->reamin_len -= txlen; + SPI_OC_VERBOSE("tx len:[0x%x], tx len remain:[0x%x]\n", txlen, spioc->reamin_len); + + spioc_copy_tx(spioc); + + total_len = 2 * txlen; /* total_len=txlen + rxlen; rxlen=txlen */ + txreg = SPIOC_TXNUM(txlen) | SPIOC_TOTNUM(total_len); + SPI_OC_VERBOSE("txreg:[0x%x]\n", txreg); + oc_spi_setreg(spioc, SPIOC_TXTOT_NUM, txreg); + + ret = spioc_transfer_start(spioc); + if (ret) { + SPI_OC_ERROR("spioc tx rx poll wait for transfer timeout.\n"); + return ret; + } + + spioc_copy_rx(spioc); + if (spioc->reamin_len) { + spioc->cur_pos += txlen; + SPI_OC_VERBOSE("cur_txrx pos:[0x%x]\n", spioc->cur_pos); + } + return 0; +} + +static int spioc_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) +{ + struct spioc *spioc; + int ret , len; + + if(!t->len || (!t->tx_buf && !t->rx_buf)) { + SPI_OC_ERROR("params error, tx_buf and rx_buf may both NULL, transfer len:0x%x.\n", + t->len); + return 0; + } + + spioc = spi_master_get_devdata(spi->master); + if (spioc->transfer_busy_flag) { + ret = -EBUSY; + goto err; + } + + spioc->txp = t->tx_buf; + spioc->rxp = t->rx_buf; + spioc->reamin_len = t->len; + spioc->cur_len = 0; + spioc->cur_pos = 0; + len = t->len; + ret = 0; + if (spioc->irq >= 0) { + /* use interrupt driven data transfer */ + if (t->tx_buf && t->rx_buf) { + spioc_tx_rx_start_one(spioc); + wait_for_completion(&spioc->done); + } else if (t->tx_buf) { + spioc_tx_start_one(spioc); + wait_for_completion(&spioc->done); + + } else { + spioc_rx_start_one(spioc); + wait_for_completion(&spioc->done); + } + } else { + if (t->tx_buf && t->rx_buf) { + SPI_OC_VERBOSE("start tx rx, len:0x%x\n", t->len); + while (spioc->reamin_len) { + ret = spioc_tx_rx_start_one(spioc); + if (ret) { + goto err; + } + } + } else if (t->tx_buf) { + SPI_OC_VERBOSE("start tx, txlen:0x%x\n", t->len); + while (spioc->reamin_len) { + ret = spioc_tx_start_one(spioc); + if (ret) { + goto err; + } + } + } else { + SPI_OC_VERBOSE("start rx, rxlen:0x%x\n", t->len); + while (spioc->reamin_len) { + ret = spioc_rx_start_one(spioc); + if (ret) { + goto err; + } + } + } + } + SPI_OC_VERBOSE("return num: 0x%x\n", len); + return len; +err: + return ret; +} + +static irqreturn_t spioc_spi_irq(int irq, void *dev) +{ + struct spioc *spioc; + + spioc = dev; + /* gooooohi, interrupt status bit judgment is not done */ + + if (spioc->txp && spioc->rxp) { + if (!spioc->reamin_len) { + complete(&spioc->done); + } else { + spioc_tx_rx_start_one(spioc); + } + } else if (spioc->txp) { + if (!spioc->reamin_len) { + complete(&spioc->done); + } else { + spioc_tx_start_one(spioc); + } + } else if (spioc->rxp){ + if (!spioc->reamin_len) { + complete(&spioc->done); + } else { + spioc_rx_start_one(spioc); + } + } + + return IRQ_HANDLED; +} + +static int ocores_spi_config_init(struct spioc *spioc) +{ + int ret = 0; + struct device *dev; + spi_ocores_device_t *spi_ocores_device; + + dev = spioc->dev; + if (dev->of_node) { + ret += of_property_read_string(dev->of_node, "dev_name", &spioc->dev_name); + ret += of_property_read_u32(dev->of_node, "dev_base", &spioc->base_addr); + ret += of_property_read_u32(dev->of_node, "reg_shift", &spioc->reg_shift); + ret += of_property_read_u32(dev->of_node, "reg_io_width", &spioc->reg_io_width); + ret += of_property_read_u32(dev->of_node, "clock-frequency", &spioc->freq); + ret += of_property_read_u32(dev->of_node, "reg_access_mode", &spioc->reg_access_mode); + ret += of_property_read_u32(dev->of_node, "num_chipselect", &spioc->num_chipselect); + + if (ret != 0) { + SPI_OC_ERROR("dts config error, ret:%d.\n", ret); + ret = -ENXIO; + return ret; + } + } else { + if (spioc->dev->platform_data == NULL) { + SPI_OC_ERROR("platform data config error.\n"); + ret = -ENXIO; + return ret; + } + spi_ocores_device = spioc->dev->platform_data; + spioc->bus_num = spi_ocores_device->bus_num; + spioc->dev_name = spi_ocores_device->dev_name; + spioc->big_endian = spi_ocores_device->big_endian; + spioc->base_addr = spi_ocores_device->dev_base; + spioc->reg_shift = spi_ocores_device->reg_shift; + spioc->reg_io_width = spi_ocores_device->reg_io_width; + spioc->freq = spi_ocores_device->clock_frequency; + spioc->reg_access_mode = spi_ocores_device->reg_access_mode; + spioc->num_chipselect = spi_ocores_device->num_chipselect; + } + + SPI_OC_VERBOSE("name:%s, base:0x%x, reg_shift:0x%x, io_width:0x%x, clock-frequency:0x%x.\n", + spioc->dev_name, spioc->base_addr, spioc->reg_shift, spioc->reg_io_width, spioc->freq); + SPI_OC_VERBOSE("reg access mode:%u, num_chipselect:%u.\n", + spioc->reg_access_mode, spioc->num_chipselect); + return ret; +} + +static int spioc_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct spioc *spioc; + int ret; + bool be; + + ret = -1; + master = spi_alloc_master(&pdev->dev, sizeof(struct spioc)); + if (!master) { + dev_err(&pdev->dev, "Failed to alloc spi master.\n"); + goto out; + } + + spioc = spi_master_get_devdata(master); + platform_set_drvdata(pdev, spioc); + + spioc->dev = &pdev->dev; + ret = ocores_spi_config_init(spioc); + if (ret != 0) { + dev_err(spioc->dev, "Failed to get ocores spi dts config.\n"); + goto free; + } + + if (spioc->dev->of_node) { + if (of_property_read_u32(spioc->dev->of_node, "big_endian", &spioc->big_endian)) { + + be = 0; + } else { + be = spioc->big_endian; + } + } else { + be = spioc->big_endian; + } + + if (spioc->reg_io_width == 0) { + spioc->reg_io_width = 1; /* Set to default value */ + } + + if (!spioc->setreg || !spioc->getreg) { + switch (spioc->reg_io_width) { + case REG_IO_WIDTH_1: + spioc->setreg = oc_spi_setreg_8; + spioc->getreg = oc_spi_getreg_8; + break; + + case REG_IO_WIDTH_2: + spioc->setreg = be ? oc_spi_setreg_16be : oc_spi_setreg_16; + spioc->getreg = be ? oc_spi_getreg_16be : oc_spi_getreg_16; + break; + + case REG_IO_WIDTH_4: + spioc->setreg = be ? oc_spi_setreg_32be : oc_spi_setreg_32; + spioc->getreg = be ? oc_spi_getreg_32be : oc_spi_getreg_32; + break; + + default: + dev_err(spioc->dev, "Unsupported I/O width (%d)\n", spioc->reg_io_width); + ret = -EINVAL; + goto free; + } + } + + /* master state */ + master->num_chipselect = spioc->num_chipselect; + master->mode_bits = MODEBITS; + master->setup = spioc_spi_setup; + if (spioc->dev->of_node) { + master->dev.of_node = pdev->dev.of_node; + } else { + master->bus_num = spioc->bus_num; + } + + /* setup the state for the bitbang driver */ + spioc->bitbang.master = master; + spioc->bitbang.setup_transfer = spioc_setup_transfer; + spioc->bitbang.chipselect = spioc_chipselect; + spioc->bitbang.txrx_bufs = spioc_spi_txrx_bufs; + + /* gooooohi need revision */ + spioc->irq = platform_get_irq(pdev, 0); + if (spioc->irq >= 0) { + SPI_OC_VERBOSE("spi oc use irq, irq number:%d.\n", spioc->irq); + init_completion(&spioc->done); + ret = devm_request_irq(&pdev->dev, spioc->irq, spioc_spi_irq, 0, + pdev->name, spioc); + if (ret) { + dev_err(spioc->dev, "Failed to request irq:%d.\n", spioc->irq); + goto free; + } + } + + ret = spi_bitbang_start(&spioc->bitbang); + if (ret) { + dev_err(spioc->dev, "Failed to start spi bitbang, ret:%d.\n", ret); + goto free; + } + dev_info(spioc->dev, "registered spi-%d for %s with base address:0x%x success.\n", + master->bus_num, spioc->dev_name, spioc->base_addr); + + return ret; +free: + spi_master_put(master); +out: + return ret; +} + +static int spioc_remove(struct platform_device *pdev) +{ + struct spioc *spioc; + struct spi_master *master; + + spioc = platform_get_drvdata(pdev); + master = spioc->bitbang.master; + spi_bitbang_stop(&spioc->bitbang); + platform_set_drvdata(pdev, NULL); + spi_master_put(master); + + return 0; +} + +static const struct of_device_id spioc_match[] = { + { .compatible = "wb-spi-oc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, spioc_match); + +static struct platform_driver spioc_driver = { + .probe = spioc_probe, + .remove = spioc_remove, + .driver = { + .name = "wb-spioc", + .owner = THIS_MODULE, + .of_match_table = spioc_match, + }, +}; + +module_platform_driver(spioc_driver); + +MODULE_DESCRIPTION("spi open core adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.h new file mode 100644 index 000000000000..647ff0c5f9cf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.h @@ -0,0 +1,21 @@ +#ifndef __WB_SPI_OCORES_H__ +#define __WB_SPI_OCORES_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define SPI_OCORES_DEV_NAME_MAX_LEN (64) + +typedef struct spi_ocores_device_s { + uint32_t bus_num; + uint32_t big_endian; + char dev_name[SPI_OCORES_DEV_NAME_MAX_LEN]; + uint32_t reg_access_mode; + uint32_t dev_base; + uint32_t reg_shift; + uint32_t reg_io_width; + uint32_t clock_frequency; + uint32_t num_chipselect; + int device_flag; +} spi_ocores_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_uio_irq.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_uio_irq.c new file mode 100644 index 000000000000..da2b582443b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_uio_irq.c @@ -0,0 +1,282 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct dfd_irq_s { + int gpio; + int irq_type; + struct uio_info dfd_irq_info; + spinlock_t lock; + struct attribute_group attr_group; +} dfd_irq_t; + +#define DRV_NAME "uio-irq" +#define DRV_VERSION "1.0" +#define ENABLE_VAL (1) +#define DISABLE_VAL (0) + +#define DEBUG_ERR_LEVEL (0x1) +#define DEBUG_WARN_LEVEL (0x2) +#define DEBUG_INFO_LEVEL (0x4) +#define DEBUG_VER_LEVEL (0x8) + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); +#define DEBUG_ERROR(fmt, args...) \ + do { \ + if (debug & DEBUG_ERR_LEVEL) { \ + printk(KERN_ERR "[ERR][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define DEBUG_WARN(fmt, args...) \ + do { \ + if (debug & DEBUG_WARN_LEVEL) { \ + printk(KERN_WARNING "[WARN][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define DEBUG_INFO(fmt, args...) \ + do { \ + if (debug & DEBUG_INFO_LEVEL) { \ + printk(KERN_INFO "[INFO][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define DEBUG_VERBOSE(fmt, args...) \ + do { \ + if (debug & DEBUG_VER_LEVEL) { \ + printk(KERN_DEBUG "[VER][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +static irqreturn_t dfd_genirq_handler(int irq, struct uio_info *dev_info) +{ + disable_irq_nosync(irq); + DEBUG_VERBOSE("handler disable irq"); + return IRQ_HANDLED; +} + +static int dfd_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on) +{ + struct irq_data *irqdata; + + irqdata = irq_get_irq_data(dev_info->irq); + + if (irqd_irq_disabled(irqdata) == !irq_on) { + DEBUG_VERBOSE("irq already disable"); + return 0; + } + if (irq_on) { + DEBUG_VERBOSE("irqcontrol enable irq"); + enable_irq(dev_info->irq); + } else { + DEBUG_VERBOSE("irqcontrol disable irq"); + disable_irq(dev_info->irq); + } + + return 0; +} + +static ssize_t set_irq_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + dfd_irq_t *dfd_irq; + struct uio_info *dev_info; + unsigned long flags; + int ret, val; + + dfd_irq = dev_get_drvdata(dev); + dev_info = &dfd_irq->dfd_irq_info; + + spin_lock_irqsave(&dfd_irq->lock, flags); + + sscanf(buf, "%d", &val); + DEBUG_VERBOSE("set val:%d.\n", val); + + if ((val != ENABLE_VAL) && (val != DISABLE_VAL)) { + DEBUG_ERROR("unsupport val:%d ", val); + ret = -EINVAL; + goto fail; + } + + if (val) { + DEBUG_VERBOSE("sysfs enable irq"); + enable_irq(dev_info->irq); + } else { + DEBUG_VERBOSE("sysfs disable irq"); + disable_irq(dev_info->irq); + } + + spin_unlock_irqrestore(&dfd_irq->lock, flags); + return count; + +fail: + spin_unlock_irqrestore(&dfd_irq->lock, flags); + return ret; +} + +static DEVICE_ATTR(irq_enable, S_IWUSR, NULL, set_irq_enable); + +static struct attribute *irq_attrs[] = { + &dev_attr_irq_enable.attr, + NULL, +}; + +static struct attribute_group irq_attr_group = { + .attrs = irq_attrs, +}; + +static int dfd_irq_probe(struct platform_device *pdev) +{ + u32 gpio, irq_type, pirq_line; + int ret, ret1, ret2; + struct uio_info *dfd_irq_info; + dfd_irq_t *dfd_irq; + + dfd_irq = kzalloc(sizeof(dfd_irq_t), GFP_KERNEL); + if (!dfd_irq) { + dev_err(&pdev->dev, "dfd_irq_t kzalloc failed.\n"); + return -ENOMEM; + } + + dfd_irq_info = &dfd_irq->dfd_irq_info; + dfd_irq_info->version = "1.0"; + dfd_irq_info->name = "uio-irq"; + + /* get pirq line for x86 */ + ret1 = of_property_read_u32(pdev->dev.of_node, "pirq-line", &pirq_line); + if (!ret1) { + DEBUG_VERBOSE("use pirq-line method, pirq-line:%u", pirq_line); + dfd_irq_info->irq = pirq_line; + } + + ret2 = of_property_read_u32(pdev->dev.of_node, "gpio", &gpio); + if (!ret2 && ret1) { + dfd_irq->gpio = gpio; + gpio_request(dfd_irq->gpio, "GPIOA"); + dfd_irq_info->irq = gpio_to_irq(dfd_irq->gpio); + DEBUG_VERBOSE("use gpio:%u, irq num:%ld", gpio, dfd_irq_info->irq); + } else if (ret2 && ret1){ + ret = -ENXIO; + dev_err(&pdev->dev, "no define irq num. ret2:%d, ret1:%d.\n", ret2, ret1); + goto free_mem; + } + + ret = of_property_read_u32(pdev->dev.of_node, "irq_type", &irq_type); + if (!ret && ret1) { + DEBUG_VERBOSE("use irq_type:%u", irq_type); + dfd_irq->irq_type = irq_type; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) + irq_set_irq_type(dfd_irq_info->irq, dfd_irq->irq_type); +#else + set_irq_type(dfd_irq_info->irq, dfd_irq->irq_type); +#endif + } else if (ret && ret1){ + ret = -ENXIO; + dev_err(&pdev->dev, "no define irq type. ret:%d, ret1:%d.\n", ret, ret1); + goto free_mem; + } + + dfd_irq_info->irq_flags = IRQF_SHARED; + dfd_irq_info->handler = dfd_genirq_handler; + dfd_irq_info->irqcontrol = dfd_genirq_irqcontrol; + + if(uio_register_device(&pdev->dev, dfd_irq_info)){ + ret = -ENODEV; + dev_err(&pdev->dev, "uio register failed.\n"); + goto free_mem; + } + + spin_lock_init(&dfd_irq->lock); + + dfd_irq->attr_group = irq_attr_group; + ret = sysfs_create_group(&pdev->dev.kobj, &dfd_irq->attr_group); + if (ret != 0) { + dev_err(&pdev->dev, "sysfs_create_group failed. ret:%d.\n", ret); + goto free_mem; + } + DEBUG_VERBOSE("sysfs create group success\n"); + + platform_set_drvdata(pdev, dfd_irq); + + return 0; + +free_mem: + kfree(dfd_irq); + + return ret; +} + +static int dfd_irq_remove(struct platform_device *pdev) +{ + dfd_irq_t *dfd_irq; + struct uio_info *dfd_irq_info; + + dfd_irq = platform_get_drvdata(pdev); + dfd_irq_info = &dfd_irq->dfd_irq_info; + + uio_unregister_device(dfd_irq_info); + kfree(dfd_irq); + + sysfs_remove_group(&pdev->dev.kobj, &dfd_irq->attr_group); + + return 0; +} + +static struct of_device_id dfd_irq_match[] = { + { + .compatible = "uio-irq", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, dfd_irq_match); + +static struct platform_driver dfd_irq_driver = { + .probe = dfd_irq_probe, + .remove = dfd_irq_remove, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = dfd_irq_match, + }, +}; + +static int __init dfd_irq_init(void) +{ + int ret; + + ret = platform_driver_register(&dfd_irq_driver); + if (ret != 0 ) { + return ret; + } + + return 0; +} + +static void __exit dfd_irq_exit(void) +{ + platform_driver_unregister(&dfd_irq_driver); +} + +module_init(dfd_irq_init); +module_exit(dfd_irq_exit); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.c new file mode 100644 index 000000000000..8c02d981843a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.c @@ -0,0 +1,1038 @@ +/* + * wb_wdt.c + * ko for watchdog function + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_wdt.h" + +#define GPIO_FEED_WDT_MODE (1) +#define LOGIC_FEED_WDT_MODE (2) + +#define SYMBOL_I2C_DEV_MODE (1) +#define SYMBOL_PCIE_DEV_MODE (2) +#define SYMBOL_IO_DEV_MODE (3) +#define FILE_MODE (4) + +#define ONE_BYTE (1) + +#define WDT_OFF (0) +#define WDT_ON (1) + +#define MS_TO_S (1000) +#define MS_TO_NS (1000 * 1000) + +#define MAX_REG_VAL (255) + +extern int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); + +int g_wb_wdt_debug = 0; +int g_wb_wdt_error = 0; + +module_param(g_wb_wdt_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_wdt_error, int, S_IRUGO | S_IWUSR); + +#define WDT_VERBOSE(fmt, args...) do { \ + if (g_wb_wdt_debug) { \ + printk(KERN_INFO "[WDT][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WDT_ERROR(fmt, args...) do { \ + if (g_wb_wdt_error) { \ + printk(KERN_ERR "[WDT][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +enum { + HW_ALGO_TOGGLE, + HW_ALGO_LEVEL, +}; + +enum { + WATCHDOG_DEVICE_TYPE = 0, + HRTIMER_TYPE, + THREAD_TYPE, +}; + +typedef struct wb_wdt_priv_s { + + struct task_struct *thread; + struct hrtimer hrtimer; + ktime_t m_kt; + const char *config_dev_name; + uint8_t config_mode; + uint8_t hw_algo; + uint8_t enable_val; + uint8_t disable_val; + uint8_t enable_mask; + uint8_t priv_func_mode; + uint8_t feed_wdt_type; + uint32_t enable_reg; + uint32_t timeout_cfg_reg; + uint32_t timeleft_cfg_reg; + uint32_t hw_margin; + uint32_t feed_time; + uint32_t timer_accuracy; + gpio_wdt_info_t gpio_wdt; + logic_wdt_info_t logic_wdt; + struct device *dev; + const struct attribute_group *sysfs_group; + uint8_t sysfs_index; + struct mutex update_lock; + struct watchdog_device wdd; +}wb_wdt_priv_t; + +static int wdt_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + WDT_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + WDT_ERROR("kernel_read failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int wdt_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + WDT_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + WDT_ERROR("kernel_write failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int wb_wdt_read(uint8_t mode, const char *path, + uint32_t offset, uint8_t *buf, size_t count) +{ + int ret; + + switch (mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_read(path, offset, buf, count); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_read(path, offset, buf, count); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_read(path, offset, buf, count); + break; + case FILE_MODE: + ret = wdt_file_read(path, offset, buf, count); + break; + default: + WDT_ERROR("mode %u error, wdt func read failed.\n", mode); + return -EINVAL; + } + + WDT_VERBOSE("wdt func read mode:%u,dev_nam:%s, offset:0x%x, read_val:0x%x, size:%lu.\n", + mode, path, offset, *buf, count); + + return ret; +} + +static int wb_wdt_write(uint8_t mode, const char *path, + uint32_t offset, uint8_t *buf, size_t count) +{ + int ret; + + switch (mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(path, offset, buf, count); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(path, offset, buf, count); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_write(path, offset, buf, count); + break; + case FILE_MODE: + ret = wdt_file_write(path, offset, buf, count); + break; + default: + WDT_ERROR("mode %u error, wdt func write failed.\n", mode); + return -EINVAL; + } + + WDT_VERBOSE("wdt func write mode:%u, dev_nam:%s, offset:0x%x, write_val:0x%x, size:%lu.\n", + mode, path, offset, *buf, count); + + return ret; +} + +static int wb_wdt_enable_ctrl(wb_wdt_priv_t *priv, uint8_t flag) +{ + int ret; + uint8_t val; + uint8_t ctrl_val; + + switch (flag) { + case WDT_ON: + ctrl_val = priv->enable_val; + break; + case WDT_OFF: + ctrl_val = priv->disable_val; + break; + default: + WDT_ERROR("unsupport wdt enable ctrl:%u.\n", flag); + return -EINVAL; + } + + ret = wb_wdt_read(priv->priv_func_mode, priv->config_dev_name, + priv->enable_reg, &val, ONE_BYTE); + if (ret < 0) { + dev_err(priv->dev, "read wdt control reg error.\n"); + return ret; + } + + val &= ~priv->enable_mask; + + val |= ctrl_val & priv->enable_mask; + + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->enable_reg, &val, ONE_BYTE); + if (ret < 0) { + dev_err(priv->dev, "write wdt control reg error.\n"); + return ret; + } + + return 0; +} + +static void wdt_hwping(wb_wdt_priv_t *priv) +{ + gpio_wdt_info_t *gpio_wdt; + logic_wdt_info_t *logic_wdt; + uint8_t tmp_val; + int ret; + + if (priv->config_mode == GPIO_FEED_WDT_MODE) { + gpio_wdt = &priv->gpio_wdt; + switch (priv->hw_algo) { + case HW_ALGO_TOGGLE: + gpio_wdt = &priv->gpio_wdt; + gpio_wdt->state = !gpio_wdt->state; + gpio_set_value_cansleep(gpio_wdt->gpio, gpio_wdt->state); + WDT_VERBOSE("gpio toggle wdt work. val:%u\n", gpio_wdt->state); + break; + case HW_ALGO_LEVEL: + gpio_wdt = &priv->gpio_wdt; + /* Pulse */ + gpio_set_value_cansleep(gpio_wdt->gpio, !gpio_wdt->active_low); + udelay(1); + gpio_set_value_cansleep(gpio_wdt->gpio, gpio_wdt->active_low); + WDT_VERBOSE("gpio level wdt work.\n"); + break; + } + } else { + logic_wdt = &priv->logic_wdt; + switch (priv->hw_algo) { + case HW_ALGO_TOGGLE: + logic_wdt->active_val = !logic_wdt->active_val; + ret = wb_wdt_write(logic_wdt->logic_func_mode, logic_wdt->feed_dev_name, + logic_wdt->feed_reg, &logic_wdt->active_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("logic toggle wdt write failed.ret = %d\n", ret); + } + WDT_VERBOSE("logic toggle wdt work.\n"); + break; + case HW_ALGO_LEVEL: + tmp_val = !logic_wdt->active_val; + ret = wb_wdt_write(logic_wdt->logic_func_mode, logic_wdt->feed_dev_name, + logic_wdt->feed_reg, &tmp_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("logic level wdt write first failed.ret = %d\n", ret); + } + udelay(1); + ret = wb_wdt_write(logic_wdt->logic_func_mode, logic_wdt->feed_dev_name, + logic_wdt->feed_reg, &logic_wdt->active_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("logic level wdt write second failed.ret = %d\n", ret); + } + WDT_VERBOSE("logic level wdt work.\n"); + break; + } + } + return; +} + +static enum hrtimer_restart hrtimer_hwping(struct hrtimer *timer) +{ + wb_wdt_priv_t *priv = container_of(timer, wb_wdt_priv_t, hrtimer); + + wdt_hwping(priv); + hrtimer_forward(timer, timer->base->get_time(), priv->m_kt); + return HRTIMER_RESTART; +} + +static int thread_timer_cfg(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct device *dev; + uint32_t hw_margin; + uint32_t feed_time; + uint32_t accuracy; + uint8_t set_time_val; + int ret; + + dev = priv->dev; + + ret = 0; + if (dev->of_node) { + ret += of_property_read_u32(dev->of_node, "feed_time", &priv->feed_time); + if (ret != 0) { + dev_err(dev, "thread Failed to priv dts.\n"); + return -ENXIO; + } + } else { + priv->feed_time = wb_wdt_device->feed_time; + } + WDT_VERBOSE("thread priv->feed_time: %u.\n", priv->feed_time); + + hw_margin = priv->hw_margin; + feed_time = priv->feed_time; + accuracy = priv->timer_accuracy; + + if ((feed_time > (hw_margin / 2)) || (feed_time == 0)) { + dev_err(dev, "thread timer feed_time[%d] should be less than half hw_margin or zero.\n", feed_time); + return -EINVAL; + } + + set_time_val = hw_margin / accuracy; + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->timeout_cfg_reg, &set_time_val, ONE_BYTE); + if (ret < 0) { + dev_err(dev, "set wdt thread timer reg error.\n"); + return ret; + } + return 0; +} + +static int wdt_thread_timer(void *data) +{ + wb_wdt_priv_t *priv = data; + + while (!kthread_should_stop()) { + schedule_timeout_uninterruptible(msecs_to_jiffies(priv->feed_time)); + wdt_hwping(priv); + } + return 0; +} + +static int thread_timer_create(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct task_struct *p; + int ret; + + ret = thread_timer_cfg(priv, wb_wdt_device); + if (ret < 0) { + dev_err(priv->dev, "set wdt thread timer failed.\n"); + return ret; + } + + p = kthread_create(wdt_thread_timer, (void *)priv, "%s", "wb_wdt"); + if (!IS_ERR(p)) { + WDT_VERBOSE("timer thread create success.\n"); + priv->thread = p; + wake_up_process(p); + } else { + dev_err(priv->dev, "timer thread create failed.\n"); + return -ENXIO; + } + + ret = wb_wdt_enable_ctrl(priv, WDT_ON); + if (ret < 0) { + dev_err(priv->dev, "thread enable wdt failed.\n"); + return -ENXIO; + } + + return 0; +} + +static int hrtimer_cfg(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct device *dev; + struct hrtimer *hrtimer; + uint8_t set_time_val; + uint8_t hrtimer_s; + uint32_t hrtimer_ns; + int ret; + uint32_t hw_margin; + uint32_t feed_time; + uint32_t accuracy; + uint32_t max_timeout; + + dev = priv->dev; + + ret = 0; + if (dev->of_node) { + ret += of_property_read_u32(dev->of_node, "feed_time", &priv->feed_time); + if (ret != 0) { + dev_err(dev, "hrtimer Failed to priv dts.\n"); + return -ENXIO; + } + } else { + priv->feed_time = wb_wdt_device->feed_time; + } + WDT_VERBOSE("hrtimer priv->feed_time: %u.\n", priv->feed_time); + + hrtimer = &priv->hrtimer; + hw_margin = priv->hw_margin; + feed_time = priv->feed_time; + accuracy = priv->timer_accuracy; + max_timeout = accuracy * 255; + + if (hw_margin < accuracy || hw_margin > max_timeout) { + dev_err(dev, "hrtimer_hw_margin should be between %u and %u.\n", + accuracy, max_timeout); + return -EINVAL; + } + if ((feed_time > (hw_margin / 2)) || (feed_time == 0)) { + dev_err(dev, "feed_time[%d] should be less than half hw_margin or zeor.\n", feed_time); + return -EINVAL; + } + + hrtimer_s = feed_time / MS_TO_S; + hrtimer_ns = (feed_time % MS_TO_S) * MS_TO_NS; + set_time_val = hw_margin / accuracy; + + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->timeout_cfg_reg, &set_time_val, ONE_BYTE); + if (ret < 0) { + dev_err(dev, "set wdt time reg error.\n"); + return ret; + } + + priv->m_kt = ktime_set(hrtimer_s, hrtimer_ns); + hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer->function = hrtimer_hwping; + hrtimer_start(hrtimer, priv->m_kt, HRTIMER_MODE_REL); + + ret = wb_wdt_enable_ctrl(priv, WDT_ON); + if (ret < 0) { + dev_err(dev, "hrtimer enable wdt failed.\n"); + return -ENXIO; + } + + return 0; +} + +static int wb_wdt_ping(struct watchdog_device *wdd) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + + wdt_hwping(priv); + return 0; +} + +static int wb_wdt_start(struct watchdog_device *wdd) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + int ret; + + ret = wb_wdt_enable_ctrl(priv, WDT_ON); + if (ret < 0) { + WDT_ERROR("start wdt enable failed.\n"); + return -ENXIO; + } + set_bit(WDOG_HW_RUNNING, &wdd->status); + return 0; +} + +static int wb_wdt_stop(struct watchdog_device *wdd) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + int ret; + + ret = wb_wdt_enable_ctrl(priv, WDT_OFF); + if (ret < 0) { + WDT_ERROR("stop wdt enable failed.\n"); + return -ENXIO; + } + clear_bit(WDOG_HW_RUNNING, &wdd->status); + return 0; +} + +static int wb_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + uint32_t timeout_ms; + uint32_t accuracy; + uint8_t set_time_val; + int ret; + + accuracy = priv->timer_accuracy; + timeout_ms = t * 1000; + if (timeout_ms > accuracy * 255) { + WDT_ERROR("set wdt timeout too larger error.timeout_ms:%u\n", timeout_ms); + return -EINVAL; + } + + set_time_val = timeout_ms / accuracy; + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->timeout_cfg_reg, &set_time_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("set wdt timeout reg error, set_time_val:%u ret:%d\n", set_time_val, ret); + return ret; + } + wdd->timeout = t; + + return 0; +} + +static unsigned int wb_wdt_get_timeleft(struct watchdog_device *wdd) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + unsigned int time_left; + uint32_t accuracy; + uint8_t get_time_val; + int ret; + + accuracy = priv->timer_accuracy; + + ret = wb_wdt_read(priv->priv_func_mode, priv->config_dev_name, + priv->timeleft_cfg_reg, &get_time_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("get wdt timeout reg error.ret:%d\n", ret); + return ret; + } + time_left = get_time_val * accuracy / MS_TO_S; + + WDT_VERBOSE("get wdt timeleft %d get_time_val %d accuracy=%d\n", + time_left, get_time_val, accuracy); + return time_left; +} + +static const struct watchdog_info wb_wdt_ident = { + .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, + .firmware_version = 0, + .identity = "CPLD Watchdog", +}; + +static const struct watchdog_ops wb_wdt_ops = { + .owner = THIS_MODULE, + .start = wb_wdt_start, + .stop = wb_wdt_stop, + .ping = wb_wdt_ping, + .set_timeout = wb_wdt_set_timeout, + .get_timeleft = wb_wdt_get_timeleft, +}; + +static int watchdog_device_cfg(wb_wdt_priv_t *priv) +{ + int ret; + uint8_t set_time_val; + + ret = wb_wdt_enable_ctrl(priv, WDT_OFF); + if (ret < 0) { + dev_err(priv->dev, "probe disable wdt failed.\n"); + return -ENXIO; + } + + set_time_val = priv->hw_margin / priv->timer_accuracy; + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->timeout_cfg_reg, &set_time_val, ONE_BYTE); + if (ret < 0) { + dev_err(priv->dev, "set wdt time reg error.\n"); + return ret; + } + + watchdog_set_drvdata(&priv->wdd, priv); + + priv->wdd.info = &wb_wdt_ident; + priv->wdd.ops = &wb_wdt_ops; + priv->wdd.bootstatus = 0; + priv->wdd.timeout = priv->hw_margin / MS_TO_S; + priv->wdd.min_timeout = priv->timer_accuracy / MS_TO_S; + priv->wdd.max_timeout = priv->timer_accuracy * MAX_REG_VAL / MS_TO_S; + priv->wdd.parent = priv->dev; + + watchdog_stop_on_reboot(&priv->wdd); + + ret = devm_watchdog_register_device(priv->dev, &priv->wdd); + if (ret != 0) { + dev_err(priv->dev, "cannot register watchdog device (err=%d)\n", ret); + return -ENXIO; + } + + return 0; +} + +static int logic_wdt_init(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct device *dev; + logic_wdt_info_t *logic_wdt; + int ret; + + dev = priv->dev; + logic_wdt = &priv->logic_wdt; + + ret = 0; + if (dev->of_node) { + ret += of_property_read_string(dev->of_node, "feed_dev_name", &logic_wdt->feed_dev_name); + ret += of_property_read_u32(dev->of_node, "feed_reg", &logic_wdt->feed_reg); + ret += of_property_read_u8(dev->of_node, "active_val", &logic_wdt->active_val); + ret += of_property_read_u8(dev->of_node, "logic_func_mode", &logic_wdt->logic_func_mode); + if (ret != 0) { + dev_err(dev, "Failed to logic_wdt dts.\n"); + return -ENXIO; + } + } else { + logic_wdt->feed_dev_name = wb_wdt_device->wdt_config_mode.logic_wdt.feed_dev_name; + logic_wdt->feed_reg = wb_wdt_device->wdt_config_mode.logic_wdt.feed_reg; + logic_wdt->active_val = wb_wdt_device->wdt_config_mode.logic_wdt.active_val; + logic_wdt->logic_func_mode = wb_wdt_device->wdt_config_mode.logic_wdt.logic_func_mode; + } + + logic_wdt->state_val = logic_wdt->active_val; + + WDT_VERBOSE("feed_dev_name:%s, feed_reg:0x%x, active_val:%u, logic_func_mode:%u\n", + logic_wdt->feed_dev_name, logic_wdt->feed_reg, + logic_wdt->active_val, logic_wdt->logic_func_mode); + + return 0; +} + +static int gpio_wdt_init(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct device *dev; + gpio_wdt_info_t *gpio_wdt; + enum of_gpio_flags flags; + uint32_t f = 0; + int ret; + + dev = priv->dev; + gpio_wdt = &priv->gpio_wdt; + + if (dev->of_node) { + gpio_wdt->gpio = of_get_gpio_flags(dev->of_node, 0, &flags); + } else { + gpio_wdt->gpio = wb_wdt_device->wdt_config_mode.gpio_wdt.gpio; + flags = wb_wdt_device->wdt_config_mode.gpio_wdt.flags; + } + if (!gpio_is_valid(gpio_wdt->gpio)) { + dev_err(dev, "gpio is invalid.\n"); + return gpio_wdt->gpio; + } + + gpio_wdt->active_low = flags & OF_GPIO_ACTIVE_LOW; + + if(priv->hw_algo == HW_ALGO_TOGGLE) { + f = GPIOF_IN; + } else { + f = gpio_wdt->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; + } + + ret = devm_gpio_request_one(dev, gpio_wdt->gpio, f, + dev_name(dev)); + if (ret) { + dev_err(dev, "devm_gpio_request_one failed.\n"); + return ret; + } + + gpio_wdt->state = gpio_wdt->active_low; + gpio_direction_output(gpio_wdt->gpio, gpio_wdt->state); + + WDT_VERBOSE("active_low:%d\n", gpio_wdt->active_low); + return 0; +} + +static ssize_t set_wdt_sysfs_value(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + wb_wdt_priv_t *priv = dev_get_drvdata(dev); + int ret, val; + + val = 0; + sscanf(buf, "%d", &val); + WDT_VERBOSE("set wdt, val:%d.\n", val); + + if (val < 0 || val > 255) { + WDT_ERROR("set wdt val %d failed.\n", val); + return -EINVAL; + } + + mutex_lock(&priv->update_lock); + + ret = wb_wdt_enable_ctrl(priv, val); + if (ret < 0) { + WDT_ERROR("set wdt sysfs value:%u failed.\n", val); + goto fail; + } + + WDT_VERBOSE("set wdt sysfs value:%u successed.\n", val); + mutex_unlock(&priv->update_lock); + return count; + +fail: + mutex_unlock(&priv->update_lock); + return ret; +} + +static ssize_t show_wdt_sysfs_value(struct device *dev, + struct device_attribute *da, char *buf) +{ + wb_wdt_priv_t *priv = dev_get_drvdata(dev); + uint8_t val, status; + int ret; + + mutex_lock(&priv->update_lock); + + ret = wb_wdt_read(priv->priv_func_mode, priv->config_dev_name, + priv->enable_reg, &val, ONE_BYTE); + if (ret < 0) { + dev_err(priv->dev, "read wdt enable reg val error.\n"); + goto fail; + } + + val &= priv->enable_mask; + if (val == priv->enable_val) { + status = WDT_ON; + } else if(val == priv->disable_val) { + status = WDT_OFF; + } else { + WDT_ERROR("enable reg read val not match set val, read val:%u, mask:%u, enable_val:%u, disable_val:%u", + val, priv->enable_mask, priv->enable_val, priv->disable_val); + ret = -EIO; + goto fail; + } + + WDT_VERBOSE("read_val:%u, mask:%u, enable_val:%u, disable_val:%u, status:%u", + val, priv->enable_mask, priv->enable_val, priv->disable_val, status); + + mutex_unlock(&priv->update_lock); + return sprintf(buf, "%u\n", status); + +fail: + mutex_unlock(&priv->update_lock); + return ret; +} + +static SENSOR_DEVICE_ATTR(wdt_status, S_IRUGO | S_IWUSR, show_wdt_sysfs_value, set_wdt_sysfs_value, 0); + +static struct attribute *wdt_sysfs_attrs[] = { + &sensor_dev_attr_wdt_status.dev_attr.attr, + NULL +}; + +static const struct attribute_group wdt_sysfs_group = { + .attrs = wdt_sysfs_attrs, +}; + +struct wdt_attr_match_group { + uint8_t index; + const struct attribute_group *attr_group_ptr; +}; + +static struct wdt_attr_match_group g_wdt_attr_match[] = { + {0, &wdt_sysfs_group}, +}; + +static const struct attribute_group *wdt_get_attr_group(uint32_t index) +{ + int i; + struct wdt_attr_match_group *group; + + for (i = 0; i < ARRAY_SIZE(g_wdt_attr_match); i++) { + group = &g_wdt_attr_match[i]; + if (index == group->index) { + WDT_VERBOSE("get wdt attr, index:%u.\n", index); + return group->attr_group_ptr; + } + } + + return NULL; +} + +static int wb_wdt_probe(struct platform_device *pdev) +{ + wb_wdt_priv_t *priv; + int ret; + const char *algo; + wb_wdt_device_t *wb_wdt_device; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + platform_set_drvdata(pdev, priv); + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "config_dev_name", &priv->config_dev_name); + ret += of_property_read_string(pdev->dev.of_node, "hw_algo", &algo); + ret += of_property_read_u8(pdev->dev.of_node, "config_mode", &priv->config_mode); + ret += of_property_read_u8(pdev->dev.of_node, "priv_func_mode", &priv->priv_func_mode); + ret += of_property_read_u8(pdev->dev.of_node, "enable_val", &priv->enable_val); + ret += of_property_read_u8(pdev->dev.of_node, "disable_val", &priv->disable_val); + ret += of_property_read_u8(pdev->dev.of_node, "enable_mask", &priv->enable_mask); + ret += of_property_read_u32(pdev->dev.of_node, "enable_reg", &priv->enable_reg); + ret += of_property_read_u32(pdev->dev.of_node, "timeout_cfg_reg", &priv->timeout_cfg_reg); + ret += of_property_read_u32(pdev->dev.of_node,"hw_margin_ms", &priv->hw_margin); + ret += of_property_read_u8(pdev->dev.of_node,"feed_wdt_type", &priv->feed_wdt_type); + ret += of_property_read_u32(pdev->dev.of_node,"timer_accuracy", &priv->timer_accuracy); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to priv dts.\n"); + return -ENXIO; + } + + priv->sysfs_index = SYSFS_NO_CFG; + of_property_read_u8(pdev->dev.of_node,"sysfs_index", &priv->sysfs_index); + + priv->timeleft_cfg_reg = priv->timeout_cfg_reg; + of_property_read_u32(pdev->dev.of_node,"timeleft_cfg_reg", &priv->timeleft_cfg_reg); + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + wb_wdt_device = pdev->dev.platform_data; + priv->config_dev_name = wb_wdt_device->config_dev_name; + algo = wb_wdt_device->hw_algo; + priv->config_mode = wb_wdt_device->config_mode; + priv->priv_func_mode = wb_wdt_device->priv_func_mode; + priv->enable_val = wb_wdt_device->enable_val; + priv->disable_val = wb_wdt_device->disable_val; + priv->enable_mask = wb_wdt_device->enable_mask; + priv->enable_reg = wb_wdt_device->enable_reg; + priv->timeout_cfg_reg = wb_wdt_device->timeout_cfg_reg; + priv->hw_margin = wb_wdt_device->hw_margin; + priv->timer_accuracy = wb_wdt_device->timer_accuracy; + priv->feed_wdt_type = wb_wdt_device->feed_wdt_type; + priv->sysfs_index = wb_wdt_device->sysfs_index; + priv->timeleft_cfg_reg = wb_wdt_device->timeleft_cfg_reg; + } + + if (!strcmp(algo, "toggle")) { + priv->hw_algo = HW_ALGO_TOGGLE; + } else if (!strcmp(algo, "level")) { + priv->hw_algo = HW_ALGO_LEVEL; + } else { + dev_err(&pdev->dev, "hw_algo config error.must be toggle or level.\n"); + return -EINVAL; + } + + WDT_VERBOSE("config_dev_name:%s, config_mode:%u, priv_func_mode:%u, enable_reg:0x%x, timeout_cfg_reg:0x%x\n", + priv->config_dev_name, priv->config_mode, priv->priv_func_mode, priv->enable_reg, priv->timeout_cfg_reg); + WDT_VERBOSE("timeout_cfg_reg:0x%x, enable_val:%u, disable_val:%u, enable_mask:%u, hw_margin:%u, feed_wdt_type:%u\n", + priv->timeleft_cfg_reg, priv->enable_val, priv->disable_val, priv->enable_mask, priv->hw_margin, priv->feed_wdt_type); + + priv->dev = &pdev->dev; + if (priv->config_mode == GPIO_FEED_WDT_MODE) { + ret = gpio_wdt_init(priv, wb_wdt_device); + if (ret < 0) { + dev_err(&pdev->dev, "init gpio mode wdt failed.\n"); + return -ENXIO; + } + } else if (priv->config_mode == LOGIC_FEED_WDT_MODE) { + ret = logic_wdt_init(priv, wb_wdt_device); + if (ret < 0) { + dev_err(&pdev->dev, "init func mode wdt failed.\n"); + return -ENXIO; + } + } else { + dev_err(&pdev->dev, "unsupport %u config_mode, dts configure error.\n", + priv->config_mode); + return -ENXIO; + } + + switch (priv->feed_wdt_type) { + case WATCHDOG_DEVICE_TYPE: + ret = watchdog_device_cfg(priv); + break; + case HRTIMER_TYPE: + ret = hrtimer_cfg(priv, wb_wdt_device); + break; + case THREAD_TYPE: + ret = thread_timer_create(priv, wb_wdt_device); + break; + default: + dev_err(&pdev->dev, "timer type %u unsupport.\n", priv->feed_wdt_type); + return -EINVAL; + } + if (ret < 0) { + dev_err(&pdev->dev, "init timer feed_wdt_type %u failed.\n", priv->feed_wdt_type); + return -ENXIO; + } + + dev_info(&pdev->dev, "register %s mode, config_mode %u, func_mode %u, %u ms overtime wdt success\n", + algo, priv->config_mode, priv->priv_func_mode, priv->hw_margin); + + if (priv->sysfs_index != SYSFS_NO_CFG) { + + priv->sysfs_group = wdt_get_attr_group(priv->sysfs_index); + if (priv->sysfs_group) { + ret = sysfs_create_group(&pdev->dev.kobj, priv->sysfs_group); + if (ret != 0) { + dev_err(&pdev->dev, "sysfs_create_group failed. ret:%d.\n", ret); + return -ENOMEM; + } + dev_info(&pdev->dev, "sysfs create group success\n"); + } else { + dev_err(&pdev->dev, "failed to find %u index wdt, return NULL.\n", priv->sysfs_index); + return -ENOMEM; + } + + mutex_init(&priv->update_lock); + + dev_info(&pdev->dev, "register %u index wdt sysfs success." ,priv->sysfs_index); + } + + return 0; +} + +static void unregister_action(struct platform_device *pdev) +{ + wb_wdt_priv_t *priv = platform_get_drvdata(pdev); + gpio_wdt_info_t *gpio_wdt; + logic_wdt_info_t *logic_wdt; + int ret; + + ret = wb_wdt_enable_ctrl(priv, WDT_OFF); + if (ret < 0) { + dev_err(&pdev->dev, "remove disable wdt failed.\n"); + } + + if (priv->sysfs_index != SYSFS_NO_CFG) { + sysfs_remove_group(&pdev->dev.kobj, priv->sysfs_group); + } + + if (priv->feed_wdt_type == HRTIMER_TYPE) { + hrtimer_cancel(&priv->hrtimer); + } else if (priv->feed_wdt_type == THREAD_TYPE) { + kthread_stop(priv->thread); + priv->thread = NULL; + } else { + WDT_VERBOSE("wdd type, do nothing.\n"); + } + + if (priv->config_mode == GPIO_FEED_WDT_MODE) { + gpio_wdt = &priv->gpio_wdt; + gpio_set_value_cansleep(gpio_wdt->gpio, !gpio_wdt->active_low); + + if (priv->hw_algo == HW_ALGO_TOGGLE) { + gpio_direction_input(gpio_wdt->gpio); + } + } else { + logic_wdt = &priv->logic_wdt; + logic_wdt->state_val = !logic_wdt->state_val; + ret = wb_wdt_write(logic_wdt->logic_func_mode, logic_wdt->feed_dev_name, + logic_wdt->feed_reg, &logic_wdt->state_val, ONE_BYTE); + if (ret < 0) { + dev_err(&pdev->dev, "set wdt control reg error.\n"); + } + } + + return; +} + +static int wb_wdt_remove(struct platform_device *pdev) +{ + WDT_VERBOSE("enter remove wdt.\n"); + unregister_action(pdev); + dev_info(&pdev->dev, "remove wdt finish.\n"); + + return 0; +} + +static void wb_wdt_shutdown(struct platform_device *pdev) +{ + WDT_VERBOSE("enter shutdown wdt.\n"); + unregister_action(pdev); + dev_info(&pdev->dev, "shutdown wdt finish.\n"); + + return; +} + +static const struct of_device_id wb_wdt_dt_ids[] = { + { .compatible = "wb_wdt", }, + { } +}; +MODULE_DEVICE_TABLE(of, wb_wdt_dt_ids); + +static struct platform_driver wb_wdt_driver = { + .driver = { + .name = "wb_wdt", + .of_match_table = wb_wdt_dt_ids, + }, + .probe = wb_wdt_probe, + .remove = wb_wdt_remove, + .shutdown = wb_wdt_shutdown, +}; + +#ifdef CONFIG_GPIO_WATCHDOG_ARCH_INITCALL +static int __init wb_wdt_init(void) +{ + return platform_driver_register(&wb_wdt_driver); +} +arch_initcall(wb_wdt_init); +#else +module_platform_driver(wb_wdt_driver); +#endif + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("watchdog driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.h new file mode 100644 index 000000000000..10c30e13f94c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.h @@ -0,0 +1,46 @@ +#ifndef __WB_WDT_H__ +#define __WB_WDT_H__ + +#include + +#define SYSFS_NO_CFG (0xff) + +typedef struct gpio_wdt_info_s { + int gpio; + enum of_gpio_flags flags; + bool active_low; + bool state; +}gpio_wdt_info_t; + +typedef struct logic_wdt_info_s { + const char *feed_dev_name; + uint8_t logic_func_mode; + uint32_t feed_reg; + uint8_t active_val; + uint8_t state_val; +}logic_wdt_info_t; + +typedef struct wb_wdt_device_s { + int device_flag; + const char *config_dev_name; + uint8_t config_mode; + const char *hw_algo; + uint8_t enable_val; + uint8_t disable_val; + uint8_t enable_mask; + uint8_t priv_func_mode; + uint8_t feed_wdt_type; + uint32_t enable_reg; + uint32_t timeout_cfg_reg; + uint32_t timeleft_cfg_reg; + uint32_t hw_margin; + uint32_t feed_time; + uint32_t timer_accuracy; + union { + gpio_wdt_info_t gpio_wdt; + logic_wdt_info_t logic_wdt; + } wdt_config_mode; + uint8_t sysfs_index; +} wb_wdt_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_xdpe132g5c.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_xdpe132g5c.c new file mode 100644 index 000000000000..edc12d34b6e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_xdpe132g5c.c @@ -0,0 +1,574 @@ +/* + * xdpe132g5c_i2c_drv.c + * + * This module create sysfs to set AVS and create hwmon to get out power + * through xdpe132g5c I2C address. + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-09-17 Initial version + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WB_I2C_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define WB_I2C_RETRY_TIME (10) +#define WB_XDPE_I2C_PAGE_ADDR (0xff) +#define WB_XDPE_I2C_VOUT_MODE (0x40) +#define WB_XDPE_I2C_VOUT_COMMAND (0x42) +#define WB_XDPE_I2C_VOUT_PAGE (0x06) +#define WB_XDPE_VOUT_MAX_THRESHOLD ((0xFFFF * 1000L * 1000L) / (256)) +#define WB_XDPE_VOUT_MIN_THRESHOLD (0) + +static int g_wb_xdpe_debug = 0; +static int g_wb_xdpe_error = 0; + +module_param(g_wb_xdpe_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_xdpe_error, int, S_IRUGO | S_IWUSR); + +#define WB_XDPE_VERBOSE(fmt, args...) do { \ + if (g_wb_xdpe_debug) { \ + printk(KERN_INFO "[WB_XDPE][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_XDPE_ERROR(fmt, args...) do { \ + if (g_wb_xdpe_error) { \ + printk(KERN_ERR "[WB_XDPE][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct xdpe_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct mutex update_lock; + long vout_max; + long vout_min; +}; + +typedef struct xdpe_vout_data_s { + u8 vout_mode; + int vout_precision; +} xdpe_vout_data_t; + +static xdpe_vout_data_t g_xdpe_vout_group[] = { + {.vout_mode = 0x18, .vout_precision = 256}, + {.vout_mode = 0x17, .vout_precision = 512}, + {.vout_mode = 0x16, .vout_precision = 1024}, + {.vout_mode = 0x15, .vout_precision = 2048}, + {.vout_mode = 0x14, .vout_precision = 4096}, +}; + +static s32 wb_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_read_byte_data(client, command); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_write_byte_data(client, command, value); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_read_word_data(client, command); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, + u16 value) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_write_word_data(client, command, value); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static long calc_power_linear11_data(int data) +{ + s16 exponent; + s32 mantissa; + long val; + + exponent = ((s16)data) >> 11; + mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; + val = mantissa; + val = val * 1000L * 1000L; + + if (exponent >= 0) { + val <<= exponent; + } else { + val >>= -exponent; + } + return val; +} + +static int read_xdpe_power_value(const struct i2c_client *client, u8 page, u8 reg, long *value) +{ + int ret, data; + + ret = wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, page); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: set xdpe page%u failed, ret: %d\n", client->adapter->nr, + client->addr, page, ret); + return ret; + } + data = wb_i2c_smbus_read_word_data(client, reg); + if (data < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe page%u reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, page, reg, data); + return data; + } + *value = calc_power_linear11_data(data); + WB_XDPE_VERBOSE("%d-%04x: page%u reg: 0x%x rd_data: 0x%x, decode linear11 value: %ld\n", + client->adapter->nr, client->addr, page, reg, data, *value); + return 0; +} + +static ssize_t xdpe_power_value_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + int ret, ori_page; + u16 sensor_h, sensor_l; + u8 page, reg; + struct sensor_device_attribute *attr; + struct i2c_client *client; + struct xdpe_data *data; + long value1, value2; + + data = dev_get_drvdata(dev); + client = data->client; + attr = to_sensor_dev_attr(da); + sensor_h = ((attr->index) >> 16) & 0xffff; + sensor_l = (attr->index) & 0xffff; + + mutex_lock(&data->update_lock); + + ori_page = wb_i2c_smbus_read_byte_data(client, WB_XDPE_I2C_PAGE_ADDR); + if (ori_page < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe origin page failed, ret: %d\n", client->adapter->nr, + client->addr, ori_page); + mutex_unlock(&data->update_lock); + return ori_page; + } + value1 = 0; + value2 = 0; + + if (sensor_h) { + page = (sensor_h >> 8) & 0xff; + reg = sensor_h & 0xff; + ret = read_xdpe_power_value(client, page, reg, &value1); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe sensor high sensor page%u reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, page, reg, ret); + goto error; + } + WB_XDPE_VERBOSE("%d-%04x: read xdpe sensor high sensor page%u reg: 0x%x success, value: %ld\n", + client->adapter->nr, client->addr, page, reg, value1); + } + + page = (sensor_l >> 8) & 0xff; + reg = sensor_l & 0xff; + ret = read_xdpe_power_value(client, page, reg, &value2); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe sensor low sensor page%u reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, page, reg, ret); + goto error; + } + WB_XDPE_VERBOSE("%d-%04x: read xdpe sensor low sensor page%u reg: 0x%x success, value: %ld\n", + client->adapter->nr, client->addr, page, reg, value2); + + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + return snprintf(buf, PAGE_SIZE, "%ld\n", value1 + value2); +error: + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + return ret; +} + +static int xdpe_get_vout_precision(const struct i2c_client *client, int *vout_precision) +{ + int i, vout_mode, a_size; + + vout_mode = wb_i2c_smbus_read_byte_data(client, WB_XDPE_I2C_VOUT_MODE); + if (vout_mode < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe vout mode reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, WB_XDPE_I2C_VOUT_MODE, vout_mode); + return vout_mode; + } + + a_size = ARRAY_SIZE(g_xdpe_vout_group); + for (i = 0; i < a_size; i++) { + if (g_xdpe_vout_group[i].vout_mode == vout_mode) { + *vout_precision = g_xdpe_vout_group[i].vout_precision; + WB_XDPE_VERBOSE("%d-%04x: match, vout mode: 0x%x, precision: %d\n", + client->adapter->nr, client->addr, vout_mode, *vout_precision); + break; + } + } + if (i == a_size) { + WB_XDPE_ERROR("%d-%04x: invalid vout mode: 0x%x\n",client->adapter->nr, client->addr, + vout_mode); + return -EINVAL; + } + return 0; +} + +static ssize_t xdpe_avs_vout_show(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret, ori_page, vout_cmd, vout_precision; + struct i2c_client *client; + struct xdpe_data *data; + long vout; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + ori_page = wb_i2c_smbus_read_byte_data(client, WB_XDPE_I2C_PAGE_ADDR); + if (ori_page < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe origin page failed, ret: %d\n", client->adapter->nr, + client->addr, ori_page); + mutex_unlock(&data->update_lock); + return ori_page; + } + + ret = wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, WB_XDPE_I2C_VOUT_PAGE); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: set xdpe avs vout page%u failed, ret: %d\n", client->adapter->nr, + client->addr, WB_XDPE_I2C_VOUT_PAGE, ret); + goto error; + } + + ret = xdpe_get_vout_precision(client, &vout_precision); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: get xdpe avs vout precision failed, ret: %d\n", + client->adapter->nr, client->addr, ret); + goto error; + } + + vout_cmd = wb_i2c_smbus_read_word_data(client, WB_XDPE_I2C_VOUT_COMMAND); + if (vout_cmd < 0) { + ret = vout_cmd; + WB_XDPE_ERROR("%d-%04x: read xdpe vout command reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, WB_XDPE_I2C_VOUT_COMMAND, ret); + goto error; + } + + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + + vout = vout_cmd * 1000L * 1000L / vout_precision; + WB_XDPE_VERBOSE("%d-%04x: vout: %ld, vout_cmd: 0x%x, precision: %d\n", client->adapter->nr, + client->addr, vout, vout_cmd, vout_precision); + return snprintf(buf, PAGE_SIZE, "%ld\n", vout); +error: + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t xdpe_avs_vout_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int ret, ori_page, vout_cmd, vout_cmd_set, vout_precision; + struct i2c_client *client; + struct xdpe_data *data; + long vout, vout_max, vout_min; + + client = to_i2c_client(dev); + ret = kstrtol(buf, 10, &vout); + if (ret) { + WB_XDPE_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + + data = i2c_get_clientdata(client); + vout_max = data->vout_max; + vout_min = data->vout_min; + if ((vout > vout_max) || (vout < vout_min)) { + WB_XDPE_ERROR("%d-%04x: vout value: %ld, out of range [%ld, %ld] \n", client->adapter->nr, + client->addr, vout, vout_min, vout_max); + return -EINVAL; + } + + mutex_lock(&data->update_lock); + + ori_page = wb_i2c_smbus_read_byte_data(client, WB_XDPE_I2C_PAGE_ADDR); + if (ori_page < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe origin page failed, ret: %d\n", client->adapter->nr, + client->addr, ori_page); + mutex_unlock(&data->update_lock); + return ori_page; + } + + ret = wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, WB_XDPE_I2C_VOUT_PAGE); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: set xdpe avs vout page%u failed, ret: %d\n", client->adapter->nr, + client->addr, WB_XDPE_I2C_VOUT_PAGE, ret); + goto error; + } + + ret = xdpe_get_vout_precision(client, &vout_precision); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: get xdpe avs vout precision failed, ret: %d\n", + client->adapter->nr, client->addr, ret); + goto error; + } + + vout_cmd_set = (vout * vout_precision) / (1000L * 1000L); + if (vout_cmd_set > 0xffff) { + WB_XDPE_ERROR("%d-%04x: invalid value, vout %ld, vout_precision: %d, vout_cmd_set: 0x%x\n", + client->adapter->nr, client->addr, vout, vout_precision, vout_cmd_set); + ret = -EINVAL; + goto error; + } + ret = wb_i2c_smbus_write_word_data(client, WB_XDPE_I2C_VOUT_COMMAND, vout_cmd_set); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: set xdpe vout cmd reg: 0x%x, value: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, WB_XDPE_I2C_VOUT_COMMAND, vout_cmd_set, ret); + goto error; + } + + vout_cmd = wb_i2c_smbus_read_word_data(client, WB_XDPE_I2C_VOUT_COMMAND); + if (vout_cmd < 0) { + ret = vout_cmd; + WB_XDPE_ERROR("%d-%04x: read xdpe vout command reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, WB_XDPE_I2C_VOUT_COMMAND, ret); + goto error; + } + if (vout_cmd != vout_cmd_set) { + ret = -EIO; + WB_XDPE_ERROR("%d-%04x: vout cmd value check error, vout cmd read: 0x%x, vout cmd set: 0x%x\n", + client->adapter->nr, client->addr, vout_cmd, vout_cmd_set); + goto error; + + } + + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + WB_XDPE_VERBOSE("%d-%04x: set vout cmd success, vout %ld, vout_precision: %d, vout_cmd_set: 0x%x\n", + client->adapter->nr, client->addr, vout, vout_precision, vout_cmd_set); + return count; +error: + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t xdpe_avs_vout_max_show(struct device *dev, struct device_attribute *da, char *buf) +{ + struct i2c_client *client; + struct xdpe_data *data; + long vout_max; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + vout_max = data->vout_max; + return snprintf(buf, PAGE_SIZE, "%ld\n", vout_max); +} + +static ssize_t xdpe_avs_vout_max_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int ret; + struct i2c_client *client; + struct xdpe_data *data; + long vout_max; + + client = to_i2c_client(dev); + ret = kstrtol(buf, 10, &vout_max); + if (ret) { + WB_XDPE_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + WB_XDPE_VERBOSE("%d-%04x: vout max threshold: %ld", client->adapter->nr, client->addr, + vout_max); + data = i2c_get_clientdata(client); + data->vout_max = vout_max; + return count; +} + +static ssize_t xdpe_avs_vout_min_show(struct device *dev, struct device_attribute *da, char *buf) +{ + struct i2c_client *client; + struct xdpe_data *data; + long vout_min; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + vout_min = data->vout_min; + return snprintf(buf, PAGE_SIZE, "%ld\n", vout_min); +} + +static ssize_t xdpe_avs_vout_min_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int ret; + struct i2c_client *client; + struct xdpe_data *data; + long vout_min; + + client = to_i2c_client(dev); + ret = kstrtol(buf, 10, &vout_min); + if (ret) { + WB_XDPE_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + WB_XDPE_VERBOSE("%d-%04x: vout min threshold: %ld", client->adapter->nr, client->addr, + vout_min); + data = i2c_get_clientdata(client); + data->vout_min = vout_min; + return count; +} + +/* xdpe hwmon */ +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO ,xdpe_power_value_show, NULL, 0x072c); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO ,xdpe_power_value_show, NULL, 0x0b2c); +static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO ,xdpe_power_value_show, NULL, 0x072c0b2c); + +static struct attribute *xdpe_hwmon_attrs[] = { + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_power3_input.dev_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(xdpe_hwmon); + +/* xdpe sysfs */ +static SENSOR_DEVICE_ATTR(avs_vout, S_IRUGO | S_IWUSR, xdpe_avs_vout_show, xdpe_avs_vout_store, 0); +static SENSOR_DEVICE_ATTR(avs_vout_max, S_IRUGO | S_IWUSR, xdpe_avs_vout_max_show, xdpe_avs_vout_max_store, 0); +static SENSOR_DEVICE_ATTR(avs_vout_min, S_IRUGO | S_IWUSR, xdpe_avs_vout_min_show, xdpe_avs_vout_min_store, 0); + +static struct attribute *xdpe132g5c_sysfs_attrs[] = { + &sensor_dev_attr_avs_vout.dev_attr.attr, + &sensor_dev_attr_avs_vout_max.dev_attr.attr, + &sensor_dev_attr_avs_vout_min.dev_attr.attr, + NULL, +}; + +static const struct attribute_group xdpe132g5c_sysfs_attrs_group = { + .attrs = xdpe132g5c_sysfs_attrs, +}; + +static int xdpe132g5c_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct xdpe_data *data; + int ret; + + WB_XDPE_VERBOSE("bus: %d, addr: 0x%02x do probe.\n", client->adapter->nr, client->addr); + data = devm_kzalloc(&client->dev, sizeof(struct xdpe_data), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + ret = sysfs_create_group(&client->dev.kobj, &xdpe132g5c_sysfs_attrs_group); + if (ret != 0) { + dev_err(&client->dev, "Create xdpe132g5c sysfs failed, ret: %d\n", ret); + return ret; + } + data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, + xdpe_hwmon_groups); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &xdpe132g5c_sysfs_attrs_group); + dev_err(&client->dev, "Failed to register xdpe hwmon device, ret: %d\n", ret); + return ret; + } + data->vout_max = WB_XDPE_VOUT_MAX_THRESHOLD; + data->vout_min = WB_XDPE_VOUT_MIN_THRESHOLD; + dev_info(&client->dev, "xdpe132g5c probe success\n"); + return 0; +} + +static int xdpe132g5c_remove(struct i2c_client *client) +{ + struct xdpe_data *data; + + WB_XDPE_VERBOSE("bus: %d, addr: 0x%02x do remove\n", client->adapter->nr, client->addr); + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &xdpe132g5c_sysfs_attrs_group); + return 0; +} + +static const struct i2c_device_id xdpe132g5c_id[] = { + {"wb_xdpe132g5c", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, xdpe132g5c_id); + +static const struct of_device_id __maybe_unused xdpe132g5c_of_match[] = { + {.compatible = "infineon,wb_xdpe132g5c"}, + {} +}; +MODULE_DEVICE_TABLE(of, xdpe132g5c_of_match); + +static struct i2c_driver wb_xdpe132g5c_driver = { + .driver = { + .name = "wb_xdpe132g5c", + .of_match_table = of_match_ptr(xdpe132g5c_of_match), + }, + .probe = xdpe132g5c_probe, + .remove = xdpe132g5c_remove, + .id_table = xdpe132g5c_id, +}; + +module_i2c_driver(wb_xdpe132g5c_driver); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("I2C driver for Infineon XDPE132 family"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/auto_update.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/auto_update.py new file mode 100755 index 000000000000..838e64f6b417 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/auto_update.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python3 + +try: + import os + import json + import logging + import sys + from sonic_py_common import device_info + from sonic_platform.platform import Platform +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + +PLATFORM_COMPONENTS_FILE = "platform_components.json" +CHASSIS_KEY = "chassis" +COMPONENT_KEY = "component" +FIRMWARE_KEY = "firmware" +VERSION_KEY = "version" +chassis_component_map = {} +current_chassis_component_map = {} +current_chassis = Platform().get_chassis() + + +def parse_component_section(section, component): + if not isinstance(component, dict): + logging.error("dictionary is expected: key=%s", COMPONENT_KEY) + return False + + if not component: + return False + + missing_key = None + chassis_component_map[section] = {} + + for key1, value1 in component.items(): + if not isinstance(value1, dict): + logging.error("dictionary is expected: key=%s", key1) + return False + + if value1: + if len(value1) < 1 or len(value1) > 3: + logging.error("unexpected number of records: key=%s", key1) + return False + + if FIRMWARE_KEY not in value1: + missing_key = FIRMWARE_KEY + break + + for key2, value2 in value1.items(): + if not isinstance(value2, str): + logging.error("string is expected: key=%s", key2) + return False + + chassis_component_map[section][key1] = value1 + + if missing_key is not None: + logging.error("\"%s\" key hasn't been found", missing_key) + return False + + return True + + +def parse_chassis_section(chassis): + if not isinstance(chassis, dict): + logging.error("dictionary is expected: key=%s", CHASSIS_KEY) + return False + + if not chassis: + logging.error("dictionary is empty: key=%s", CHASSIS_KEY) + return False + + if len(chassis) != 1: + logging.error("unexpected number of records: key=%s", CHASSIS_KEY) + return False + + for key, value in chassis.items(): + if not isinstance(value, dict): + logging.error("dictionary is expected: key=%s", key) + return False + + if not value: + logging.error("dictionary is empty: key=%s", key) + return False + + if COMPONENT_KEY not in value: + logging.error("\"%s\" key hasn't been found", COMPONENT_KEY) + return False + + if len(value) != 1: + logging.error("unexpected number of records: key=%s", key) + return False + + return parse_component_section(key, value[COMPONENT_KEY]) + + return False + + +def get_platform_components_path(): + PLATFORM_COMPONENTS_PATH_TEMPLATE = "/usr/share/sonic/device/{}/{}" + PLATFORM_COMPONENTS_FILE_PATH = PLATFORM_COMPONENTS_PATH_TEMPLATE.format( + device_info.get_platform(), PLATFORM_COMPONENTS_FILE) + return PLATFORM_COMPONENTS_FILE_PATH + + +def parse_platform_components(): + platform_components_path = get_platform_components_path() + with open(platform_components_path) as platform_components: + data = json.load(platform_components) + + if not isinstance(data, dict): + logging.error("dictionary is expected: key=root") + return False + + if not data: + logging.error("dictionary is empty: key=root") + return False + + if CHASSIS_KEY not in data: + logging.error("\"%s\" key hasn't been found", CHASSIS_KEY) + return False + + return parse_chassis_section(data[CHASSIS_KEY]) + + +def get_current_chassis_component_map(): + chassis_name = current_chassis.get_name() + current_chassis_component_map[chassis_name] = {} + + component_list = current_chassis.get_all_components() + for component in component_list: + component_name = component.get_name() + current_chassis_component_map[chassis_name][component_name] = component + + return current_chassis_component_map + + +def get_upgrade_dict(): + upgrade_dict = {} + firmware_version_current = "" + firmware_version_available = "" + + if not parse_platform_components(): + logging.error("Reading platform_components.json i, ion exception") + sys.exit(1) + + if not get_current_chassis_component_map(): + logging.error("Reading firmware i, ion from the driver is abnormal") + sys.exit(1) + + chassis_name = current_chassis.get_name() + diff_keys = set(chassis_component_map.keys()) ^ set(current_chassis_component_map.keys()) + if diff_keys: + logging.error("%s names mismatch: keys=%s", chassis_name, str(list(diff_keys))) + return None + + for chassis_name, component_map in current_chassis_component_map.items(): + for component_name, component in component_map.items(): + firmware_version_current = component.get_firmware_version() + if component_name in chassis_component_map[chassis_name]: + firmware_version_available = chassis_component_map[chassis_name][component_name][VERSION_KEY] + else: + logging.warning("can't find %s in %s", component_name, PLATFORM_COMPONENTS_FILE) + break + + if not os.path.exists(chassis_component_map[chassis_name][component_name][FIRMWARE_KEY]): + logging.error("%s does not exist", chassis_component_map[chassis_name][component_name][FIRMWARE_KEY]) + break + + if firmware_version_available != firmware_version_current: + upgrade_dict[component_name] = chassis_component_map[chassis_name][component_name][FIRMWARE_KEY] + + return upgrade_dict + + +def auto_upgrade(): + upgrade_result_dict = {} + chassis_name = current_chassis.get_name() + + upgrade_dict = get_upgrade_dict() + if not upgrade_dict: + logging.info("No firmware found for automatic upgrade") + return None + + component_map = current_chassis_component_map[chassis_name] + for value, path in upgrade_dict.items(): + status = component_map[value].install_firmware(path) + if status: + upgrade_result_dict[value] = "success" + logging.info("%s Upgrade Success", value) + else: + upgrade_result_dict[value] = "failed" + logging.error("%s Upgrade Failed", value) + return upgrade_result_dict + + +if __name__ == '__main__': + auto_upgrade() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/avscontrol.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/avscontrol.py index 25874ddb8219..a0a2ccaac938 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/common/script/avscontrol.py +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/avscontrol.py @@ -1,18 +1,22 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- -import click +import sys +import os import time -import traceback -from ragileutil import wait_docker, STARTMODULE, AVSUTIL -from rgutil.logutil import Logger +import syslog +import glob +import click +from platform_config import MAC_DEFAULT_PARAM +from platform_util import getSdkReg, write_sysfs, get_value, get_format_value + + +AVSCTROL_DEBUG_FILE = "/etc/.avscontrol_debug_flag" -try: - from rest.rest import BMCMessage -except ImportError: - pass +AVSCTROLERROR = 1 +AVSCTROLDEBUG = 2 -CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) -logger = Logger("AVSCONTROL", syslog=True) +debuglevel = 0 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} class AliasedGroup(click.Group): @@ -20,72 +24,180 @@ def get_command(self, ctx, cmd_name): rv = click.Group.get_command(self, ctx, cmd_name) if rv is not None: return rv - matches = [x for x in self.list_commands(ctx) if x.startswith(cmd_name)] + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] if not matches: return None - elif len(matches) == 1: + if len(matches) == 1: return click.Group.get_command(self, ctx, matches[0]) - ctx.fail("Too many matches: %s" % ", ".join(sorted(matches))) - - -def do_avs_ctrl(): - index = 0 - url = "/xyz/openbmc_project/hostchannel/attr/MacRov" - while True: - if ( - "avscontrol_restful" in STARTMODULE - and STARTMODULE["avscontrol_restful"] == 1 - ): - try: - # for alibmc rest.py has define get_macrov_value function - get_macrov_value = getattr(BMCMessage(), "get_macrov_value", None) - if callable(get_macrov_value): - macrov_value = int(get_macrov_value()) - else: - macrov_value = int(BMCMessage().getBmcValue(url)) - if macrov_value >= 0: - break - except Exception as e: - time.sleep(2) - continue + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def avscontrol_debug(s): + if AVSCTROLDEBUG & debuglevel: + syslog.openlog("AVSCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def avscontrol_error(s): + if AVSCTROLERROR & debuglevel: + syslog.openlog("AVSCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def avserror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("AVSCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def avsinfo(s): + syslog.openlog("AVSCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_INFO, s) + + +def debug_init(): + global debuglevel + if os.path.exists(AVSCTROL_DEBUG_FILE): + debuglevel = debuglevel | AVSCTROLDEBUG | AVSCTROLERROR + else: + debuglevel = debuglevel & ~(AVSCTROLDEBUG | AVSCTROLERROR) + + +def set_avs_value_sysfs(conf, dcdc_value): + msg = "" + formula = conf.get("formula", None) + loc = conf.get("loc") + locations = glob.glob(loc) + if len(locations) == 0: + msg = "avs sysfs loc: %s not found" % loc + avscontrol_error(msg) + return False, msg + sysfs_loc = locations[0] + avscontrol_debug("set_avs_value_sysfs, loc: %s, origin dcdc value: %s, formula: %s" % + (sysfs_loc, dcdc_value, formula)) + if formula is not None: + dcdc_value = get_format_value(formula % (dcdc_value)) + wr_val = str(dcdc_value) + avscontrol_debug("set_avs_value_sysfs, write val: %s" % wr_val) + ret, log = write_sysfs(sysfs_loc, wr_val) + if ret is False: + msg = "set_avs_value_sysfs failed, msg: %s" % log + avscontrol_error(msg) + return ret, msg + + +def set_avs_value(avs_conf, dcdc_value): + set_avs_way = avs_conf.get("set_avs", {}).get("gettype") + if set_avs_way != "sysfs": + msg = "unsupport set avs value type: %s" % set_avs_way + avscontrol_error(msg) + return False, msg + ret, msg = set_avs_value_sysfs(avs_conf["set_avs"], dcdc_value) + return ret, msg + + +def get_dcdc_value(avs_conf, rov_value): + msg = "" + mac_avs_param = avs_conf.get("mac_avs_param", {}) + if rov_value not in mac_avs_param.keys(): + if avs_conf["type"] == 0: + msg = "VID:0x%x out of range, voltage regulate stop" % rov_value + avsinfo(msg) + return False, msg + dcdc_value = mac_avs_param[avs_conf["default"]] + avsinfo("VID:0x%x out of range, use default VID:0x%x" % (rov_value, dcdc_value)) + else: + dcdc_value = mac_avs_param[rov_value] + return True, dcdc_value + + +def get_rov_value_cpld(avs_conf): + cpld_avs_config = avs_conf["cpld_avs"] + return get_value(cpld_avs_config) + + +def get_rov_value_sdk(avs_conf): + name = avs_conf["sdkreg"] + ret, status = getSdkReg(name) + if ret is False: + return False, status + status = int(status, 16) + # shift operation + if avs_conf["sdktype"] != 0: + status = (status >> avs_conf["macregloc"]) & avs_conf["mask"] + macavs = status + return True, macavs + + +def doAvsCtrol_single(avs_conf): + try: + avs_name = avs_conf.get("name") + rov_source = avs_conf["rov_source"] + if rov_source == 0: + ret, rov_value = get_rov_value_cpld(avs_conf) # get rov from cpld reg else: - if AVSUTIL.mac_adj(): - break + ret, rov_value = get_rov_value_sdk(avs_conf) # get rov from sdk reg + if ret is False: + msg = "%s get rov_value failed, msg: %s" % (avs_name, rov_value) + avscontrol_error(msg) + return False, msg + avscontrol_debug("%s rov_value: 0x%x" % (avs_name, rov_value)) + ret, dcdc_value = get_dcdc_value(avs_conf, rov_value) + if ret is False: + msg = "%s get output voltage value failed, msg: %s" % (avs_name, dcdc_value) + avscontrol_error(msg) + return False, msg + ret, msg = set_avs_value(avs_conf, dcdc_value) + return ret, msg + except Exception as e: + msg = "%s avscontrol raise exception, msg: %s" % (avs_name, str(e)) + avscontrol_error(msg) + return False, msg + + +def doAvsCtrol(avs_conf): + retry_time = avs_conf.get("retry", 10) + for i in range(retry_time): + debug_init() + ret, log = doAvsCtrol_single(avs_conf) + if ret is True: + return True, log + time.sleep(1) + return False, log - index += 1 - if index >= 10: - logger.error("%%DEV_MONITOR-AVS: MAC Voltage adjust failed.") - exit(-1) - logger.info("%%AVSCONTROL success") - exit(0) +def run(): + # wait 30s for device steady + time.sleep(30) + errcnt = 0 + msg = "" + for item in MAC_DEFAULT_PARAM: + status, log = doAvsCtrol(item) + if status is False: + errcnt += 1 + msg += log -def run(interval): - while True: - try: - if wait_docker(timeout=0) == True: - time.sleep(10) # w10s - do_avs_ctrl() - time.sleep(interval) - except Exception as e: - traceback.print_exc() - print(e) + if errcnt == 0: + avsinfo("%%AVSCONTROL success") + sys.exit(0) + avserror("%%DEV_MONITOR-AVS: MAC Voltage adjust failed.") + avserror("%%DEV_MONITOR-AVS: errmsg: %s" % msg) + sys.exit(1) @click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) def main(): - """device operator""" - pass + '''device operator''' @main.command() def start(): - """start AVS control""" - logger.info("%%AVSCONTROL start") - interval = 5 - run(interval) + '''start AVS control''' + avsinfo("%%AVSCONTROL start") + run() -##device_i2c operation -if __name__ == "__main__": +if __name__ == '__main__': main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/dev_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/dev_monitor.py new file mode 100755 index 000000000000..e13377b80fe9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/dev_monitor.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python3 +import sys +import os +import time +import syslog +import traceback +import click +from platform_config import DEV_MONITOR_PARAM +from platform_util import io_rd, wbi2cget + + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +DEVMONITOR_DEBUG_FILE = "/etc/.devmonitor_debug_flag" + +debuglevel = 0 + + +def debug_init(): + global debuglevel + if os.path.exists(DEVMONITOR_DEBUG_FILE): + debuglevel = 1 + else: + debuglevel = 0 + + +def devwarninglog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def devcriticallog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def deverror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def devinfo(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_INFO, s) + + +def devdebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if debuglevel == 1: + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +class DevMonitor(): + + def getpresentstatus(self, param): + try: + ret = {} + ret["status"] = '' + gettype = param.get('gettype') + presentbit = param.get('presentbit') + okval = param.get('okval') + if gettype == "io": + io_addr = param.get('io_addr') + val = io_rd(io_addr) + if val is None: + ret["status"] = "NOT OK" + return ret + retval = val + else: + bus = param.get('bus') + loc = param.get('loc') + offset = param.get('offset') + ind, val = wbi2cget(bus, loc, offset) + if ind is not True: + ret["status"] = "NOT OK" + return ret + retval = val + val_t = (int(retval, 16) & (1 << presentbit)) >> presentbit + if val_t != okval: + ret["status"] = "ABSENT" + else: + ret["status"] = "PRESENT" + except Exception as e: + ret["status"] = "NOT OK" + deverror("getpresentstatus error") + deverror(str(e)) + return ret + + def removeDev(self, bus, loc): + cmd = "echo 0x%02x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (loc, bus) + devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc) + if os.path.exists(devpath): + os.system(cmd) + + def addDev(self, name, bus, loc): + if name == "lm75": + time.sleep(0.1) + cmd = "echo %s 0x%02x > /sys/bus/i2c/devices/i2c-%d/new_device" % (name, loc, bus) + devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc) + if os.path.exists(devpath) is False: + os.system(cmd) + + def checkattr(self, bus, loc, attr): + try: + attrpath = "/sys/bus/i2c/devices/%d-%04x/%s" % (bus, loc, attr) + if os.path.exists(attrpath): + return True + except Exception as e: + deverror("checkattr error") + deverror(str(e)) + return False + + def monitor(self, ret): + totalerr = 0 + for item in ret: + try: + name = item.get('name') + itemattr = '%sattr' % name + val_t = getattr(DevMonitor, itemattr, None) + if val_t == 'OK': + continue + present = item.get('present', None) + devices = item.get('device') + err_t = 0 + for item_dev in devices: + item_devattr = '%s' % (item_dev['id']) + val_t = getattr(DevMonitor, item_devattr, None) + if val_t == 'OK': + continue + devname = item_dev.get('name') + bus = item_dev.get('bus') + loc = item_dev.get('loc') + attr = item_dev.get('attr') + if self.checkattr(bus, loc, attr) is False: + err_t -= 1 + setattr(DevMonitor, item_devattr, 'NOT OK') + if present is not None: + presentstatus = self.getpresentstatus(present) + devdebuglog("%s present status:%s" % (name, presentstatus.get('status'))) + if presentstatus.get('status') == 'PRESENT': + self.removeDev(bus, loc) + time.sleep(0.1) + self.addDev(devname, bus, loc) + else: + self.removeDev(bus, loc) + time.sleep(0.1) + self.addDev(devname, bus, loc) + else: + setattr(DevMonitor, item_devattr, 'OK') + val_t = getattr(DevMonitor, item_devattr, None) + devdebuglog("%s status %s" % (item_devattr, val_t)) + if err_t == 0: + setattr(DevMonitor, itemattr, 'OK') + else: + totalerr -= 1 + setattr(DevMonitor, itemattr, 'NOT OK') + val_t = getattr(DevMonitor, itemattr, None) + devdebuglog("%s status %s" % (itemattr, val_t)) + except Exception as e: + totalerr -= 1 + deverror("monitor error") + deverror(str(e)) + return totalerr + + def psusmonitor(self): + psus_conf = DEV_MONITOR_PARAM.get('psus') + if psus_conf is None: + return 0 + psusattr = 'psusattr' + val_t = getattr(DevMonitor, psusattr, None) + if val_t == 'OK': + return 0 + ret = self.monitor(psus_conf) + if ret == 0: + setattr(DevMonitor, psusattr, 'OK') + else: + setattr(DevMonitor, psusattr, 'NOT OK') + val_t = getattr(DevMonitor, psusattr, None) + devdebuglog("psusattr:value:%s" % (val_t)) + return ret + + def fansmonitor(self): + fans_conf = DEV_MONITOR_PARAM.get('fans') + if fans_conf is None: + return 0 + fansattr = 'fansattr' + val_t = getattr(DevMonitor, fansattr, None) + if val_t == 'OK': + return 0 + ret = self.monitor(fans_conf) + if ret == 0: + setattr(DevMonitor, fansattr, 'OK') + else: + setattr(DevMonitor, fansattr, 'NOT OK') + val_t = getattr(DevMonitor, fansattr, None) + devdebuglog("fansattr:value:%s" % (val_t)) + return ret + + def slotsmonitor(self): + slots_conf = DEV_MONITOR_PARAM.get('slots') + if slots_conf is None: + return 0 + slotsattr = 'slotsattr' + val_t = getattr(DevMonitor, slotsattr, None) + if val_t == 'OK': + return 0 + ret = self.monitor(slots_conf) + if ret == 0: + setattr(DevMonitor, slotsattr, 'OK') + else: + setattr(DevMonitor, slotsattr, 'NOT OK') + val_t = getattr(DevMonitor, slotsattr, None) + devdebuglog("slotsattr:value:%s" % (val_t)) + return ret + + def othersmonitor(self): + others_conf = DEV_MONITOR_PARAM.get('others') + if others_conf is None: + return 0 + othersattr = 'othersattr' + val_t = getattr(DevMonitor, othersattr, None) + if val_t == 'OK': + return 0 + ret = self.monitor(others_conf) + if ret == 0: + setattr(DevMonitor, othersattr, 'OK') + else: + setattr(DevMonitor, othersattr, 'NOT OK') + val_t = getattr(DevMonitor, othersattr, None) + devdebuglog("othersattr:value:%s" % (val_t)) + return ret + + +def doDevMonitor(devMonitor): + ret_t = 0 + ret_t += devMonitor.psusmonitor() + ret_t += devMonitor.fansmonitor() + ret_t += devMonitor.slotsmonitor() + ret_t += devMonitor.othersmonitor() + return ret_t + + +def run(interval, devMonitor): + # devMonitor.devattrinit() + while True: + try: + debug_init() + ret = doDevMonitor(devMonitor) + except Exception as e: + traceback.print_exc() + deverror(str(e)) + ret = -1 + if ret == 0: + time.sleep(5) + devinfo("dev_monitor finished!") + sys.exit(0) + time.sleep(interval) + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''device operator''' + + +@main.command() +def start(): + '''start device monitor''' + devinfo("dev_monitor start") + devMonitor = DevMonitor() + interval = DEV_MONITOR_PARAM.get('polling_time', 10) + run(interval, devMonitor) + + +@main.command() +def stop(): + '''stop device monitor ''' + devinfo("stop") + + +# device_i2c operation +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/generate_airflow.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/generate_airflow.py new file mode 100755 index 000000000000..29d18e7b2688 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/generate_airflow.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- +''' +generate board air flow according to fan and psu air flow +write resulet to AIRFLOW_RESULT_FILE, file format: +{ + "FAN1": { + "model":"M1HFAN I-F", + "airflow":"intake", + }, + "PSU1": { + "model":"CSU550AP-3-500", + "airflow":"intake", + }, + "board":"intake" +} +''' +import os +import syslog +import json +from platform_config import AIR_FLOW_CONF, AIRFLOW_RESULT_FILE +from platform_util import dev_file_read, byteTostr +from eepromutil.fru import ipmifru +from eepromutil.fantlv import fan_tlv + + +AIRFLOW_DEBUG_FILE = "/etc/.airflow_debug_flag" + +AIRFLOWERROR = 1 +AIRFLOWDEBUG = 2 + +debuglevel = 0 + + +def airflow_info(s): + syslog.openlog("AIRFLOW", syslog.LOG_PID) + syslog.syslog(syslog.LOG_INFO, s) + + +def airflow_error(s): + syslog.openlog("AIRFLOW", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def airflow_debug(s): + if AIRFLOWDEBUG & debuglevel: + syslog.openlog("AIRFLOW", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def airflow_debug_error(s): + if AIRFLOWERROR & debuglevel: + syslog.openlog("AIRFLOW", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def debug_init(): + global debuglevel + try: + with open(AIRFLOW_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + +def get_model_fru(device, eeprom): + try: + fru = ipmifru() + fru.decodeBin(eeprom) + dev_name = device.get("name") + area = device.get("area") + field = device.get("field") + tmp_area = getattr(fru, area, None) + if tmp_area is None: + msg = "%s fru %s area config error" % (dev_name, area) + return False, msg + model = getattr(tmp_area, field, None) + if model is None: + msg = "%s get model error, area: %s, field: %s" % (dev_name, area, field) + return False, msg + airflow_debug("%s get model success, model: %s" % (dev_name, model)) + return True, model + except Exception as e: + return False, str(e) + + +def get_model_fantlv(device, eeprom): + try: + dev_name = device.get("name") + tlv = fan_tlv() + rets = tlv.decode(eeprom) + if len(rets) == 0: + msg = "%s decode fantlv eeprom info error" % dev_name + return False, msg + + field = device.get("field") + for fantlv_item in rets: + if fantlv_item.get("name") == field: + return True, fantlv_item["value"] + msg = "%s get model error, field: %s not found" % (dev_name, field) + return False, msg + except Exception as e: + return False, str(e) + + +def get_device_modele(device): + e2_type = device.get("e2_type") + dev_name = device.get("name") + support_e2_type = ("fru", "fantlv") + if e2_type not in support_e2_type: + msg = "%s unsupport e2_type: %s" % (dev_name, e2_type) + return False, msg + + e2_path = device.get("e2_path") + e2_size = device.get("e2_size", 256) + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + msg = "%s eeprom read error, eeprom path: %s, msg: %s" % (dev_name, e2_path, binval_bytes) + return False, msg + + binval = byteTostr(binval_bytes) + if e2_type == "fru": + return get_model_fru(device, binval) + return get_model_fantlv(device, binval) + + +def get_board_air_flow(fan_intake_num, fan_exhaust_num, psu_intake_num, psu_exhaust_num): + airflow_debug("fan_intake_num: %d, fan_exhaust_num: %d, psu_intake_num: %d, psu_exhaust_num: %d" % + (fan_intake_num, fan_exhaust_num, psu_intake_num, psu_exhaust_num)) + + if fan_intake_num == 0 and fan_exhaust_num == 0 and psu_intake_num == 0 and psu_exhaust_num == 0: + airflow_error("get all fans and psus air flow failed") + return "N/A" + + if fan_intake_num > fan_exhaust_num: + airflow_debug("fan intake number %d more than fan exhaust number %s, set board air flow: intake") + return "intake" + + if fan_intake_num < fan_exhaust_num: + airflow_debug("fan intake number less than fan exhaust number, set board air flow: exhaust") + return "exhaust" + + airflow_debug("fan intake number equal to exhaust number, check psu air flow") + + if psu_intake_num > psu_exhaust_num: + airflow_debug("psu intake number more than psu exhaust number, set board air flow: intake") + return "intake" + + if psu_intake_num < psu_exhaust_num: + airflow_debug("psu intake number less than psu exhaust number, set board air flow: exhaust") + return "exhaust" + + airflow_debug("fan and psu intake and exhaust number equal, return intake") + return "intake" + + +def generate_airflow(): + fan_intake_list = [] + fan_exhaust_list = [] + psu_intake_list = [] + psu_exhaust_list = [] + ret = {} + fans = AIR_FLOW_CONF.get("fans", []) + psus = AIR_FLOW_CONF.get("psus", []) + + for fan in fans: + dev_name = fan.get("name") + air_flow = "N/A" + status, model = get_device_modele(fan) + if status is False: + ret[dev_name] = {"model": "N/A", "airflow": "N/A"} + airflow_error(model) + continue + model = model.strip() + airflowconifg = AIR_FLOW_CONF[fan["decode"]] + for key, value in airflowconifg.items(): + if model in value: + air_flow = key + ret[dev_name] = {"model": model, "airflow": air_flow} + airflow_debug("%s model: %s, airflow: %s" % (dev_name, model, air_flow)) + if air_flow == "intake": + fan_intake_list.append(fan.get("name")) + elif air_flow == "exhaust": + fan_exhaust_list.append(fan.get("name")) + + airflow_debug("fan_intake_list: %s" % fan_intake_list) + airflow_debug("fan_exhaust_list: %s" % fan_exhaust_list) + + for psu in psus: + dev_name = psu.get("name") + air_flow = "N/A" + status, model = get_device_modele(psu) + if status is False: + ret[dev_name] = {"model": "N/A", "airflow": "N/A"} + airflow_error(model) + continue + model = model.strip() + airflowconifg = AIR_FLOW_CONF[psu["decode"]] + for key, value in airflowconifg.items(): + if model in value: + air_flow = key + ret[dev_name] = {"model": model, "airflow": air_flow} + airflow_debug("%s model: %s, airflow: %s" % (dev_name, model, air_flow)) + if air_flow == "intake": + psu_intake_list.append(psu.get("name")) + elif air_flow == "exhaust": + psu_exhaust_list.append(psu.get("name")) + + airflow_debug("psu_intake_list: %s" % psu_intake_list) + airflow_debug("psu_exhaust_list: %s" % psu_exhaust_list) + + fan_intake_num = len(fan_intake_list) + fan_exhaust_num = len(fan_exhaust_list) + psu_intake_num = len(psu_intake_list) + psu_exhaust_num = len(psu_exhaust_list) + + board_airflow = get_board_air_flow(fan_intake_num, fan_exhaust_num, psu_intake_num, psu_exhaust_num) + airflow_debug("board_airflow: %s" % board_airflow) + ret["board"] = board_airflow + ret_json = json.dumps(ret, ensure_ascii=False, indent=4) + + out_file_dir = os.path.dirname(AIRFLOW_RESULT_FILE) + if len(out_file_dir) != 0: + cmd = "mkdir -p %s" % out_file_dir + os.system(cmd) + os.system("sync") + with open(AIRFLOW_RESULT_FILE, "w") as fd: + fd.write(ret_json) + os.system("sync") + + +if __name__ == '__main__': + debug_init() + airflow_debug("enter main") + generate_airflow() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_fanctrl.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_fanctrl.py new file mode 100755 index 000000000000..7722b111f944 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_fanctrl.py @@ -0,0 +1,1135 @@ +#!/usr/bin/env python3 +import os +import subprocess +import time +import syslog +import traceback +from plat_hal.interface import interface +from plat_hal.baseutil import baseutil +from algorithm.pid import pid +from algorithm.openloop import openloop +from algorithm.hysteresis import hysteresis + + +SWITCH_TEMP = "SWITCH_TEMP" +INLET_TEMP = "INLET_TEMP" +BOARD_TEMP = "BOARD_TEMP" +OUTLET_TEMP = "OUTLET_TEMP" +CPU_TEMP = "CPU_TEMP" + +FANCTROL_DEBUG_FILE = "/etc/.fancontrol_debug_flag" +# coordination with REBOOT_CAUSE_PARA +OTP_SWITCH_REBOOT_JUDGE_FILE = "/etc/.otp_reboot_flag" +OTP_OTHER_REBOOT_JUDGE_FILE = OTP_SWITCH_REBOOT_JUDGE_FILE + +FANCTROLERROR = 1 +FANCTROLDEBUG = 2 +FANAIRFLOWDEBUG = 4 + +debuglevel = 0 + +F2B_AIR_FLOW = "intake" +B2F_AIR_FLOW = "exhaust" +ONIE_E2_NAME = "ONIE_E2" + +TEMP_REBOOT_CRIT_SWITCH_FLAG = 1 +TEMP_REBOOT_CRIT_OTHER_FLAG = 2 + + +def fancontrol_debug(s): + if FANCTROLDEBUG & debuglevel: + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def fancontrol_error(s): + if FANCTROLERROR & debuglevel: + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def fanairflow_debug(s): + if FANAIRFLOWDEBUG & debuglevel: + syslog.openlog("AIR_FLOW_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def fancontrol_warn(s): + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_WARNING, s) + + +def fancontrol_crit(s): + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_CRIT, s) + + +def fancontrol_alert(s): + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_ALERT, s) + + +def fancontrol_emerg(s): + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_EMERG, s) + + +def exec_os_cmd(cmd): + status, output = subprocess.getstatusoutput(cmd) + if status: + print(output) + return status, output + + +def debug_init(): + global debuglevel + try: + with open(FANCTROL_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + +error_temp = -9999 # get temp error +invalid_temp = -10000 # get temp invalid +PRE_FAN_NOK_UNKNOWN = "UNKNOWN" + + +class DevFan(object): + + def __init__(self, name, hal_interface): + self.__name = name + self.origin_name = None + self.display_name = None + self.air_flow = None + self.air_flow_inconsistent = False + self.int_case = hal_interface + + @property + def name(self): + return self.__name + + def get_fan_rotor_number(self): + return self.int_case.get_fan_rotor_number(self.name) + + def get_fan_presence(self): + return self.int_case.get_fan_presence(self.name) + + def get_fan_rotor_status(self, rotor_name): + return self.int_case.get_fan_rotor_status(self.name, rotor_name) + + def get_fan_fru_info(self): + return self.int_case.get_fan_fru_info(self.name) + + @property + def na_ret(self): + return self.int_case.na_ret + + def update_fru_info(self): + try: + dic = self.get_fan_fru_info() + self.origin_name = dic["PN"] + self.air_flow = dic["AirFlow"] + self.display_name = dic["DisplayName"] + except Exception as e: + fanairflow_debug("update %s fru info error, msg: %s" % (self.name, str(e))) + self.origin_name = self.na_ret + self.air_flow = self.na_ret + self.display_name = self.na_ret + + +class DevPsu(object): + + def __init__(self, name, hal_interface): + self.__name = name + self.origin_name = None + self.display_name = None + self.air_flow = None + self.air_flow_inconsistent = False + self.int_case = hal_interface + + @property + def name(self): + return self.__name + + def get_psu_fru_info(self): + return self.int_case.get_psu_fru_info(self.name) + + @property + def na_ret(self): + return self.int_case.na_ret + + def update_fru_info(self): + try: + dic = self.get_psu_fru_info() + self.origin_name = dic["PN"] + self.air_flow = dic["AirFlow"] + self.display_name = dic["DisplayName"] + except Exception as e: + fanairflow_debug("update %s fru info error, msg: %s" % (self.name, str(e))) + self.origin_name = self.na_ret + self.air_flow = self.na_ret + self.display_name = self.na_ret + + +class fancontrol(object): + __int_case = None + + __pwm = 0x80 + + def __init__(self): + self.int_case = interface() + self.__config = baseutil.get_monitor_config() + self.__pid_config = self.__config["pid"] + self.__hyst_config = self.__config.get("hyst", {}) + self.__temps_threshold_config = self.__config["temps_threshold"] + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['temp'] = 0 + temp_threshold['fail_num'] = 0 + temp_threshold['warning_num'] = 0 # temp warning times + temp_threshold['critical_num'] = 0 # temp critical times + temp_threshold['emergency_num'] = 0 # temp emergency times + temp_threshold.setdefault('ignore_threshold', 0) # default temp threshold on + temp_threshold.setdefault('invalid', invalid_temp) + temp_threshold.setdefault('error', error_temp) + + self.__otp_reboot_judge_file_config = self.__config.get("otp_reboot_judge_file", None) + if self.__otp_reboot_judge_file_config is None: + self.__otp_switch_reboot_judge_file = OTP_SWITCH_REBOOT_JUDGE_FILE + self.__otp_other_reboot_judge_file = OTP_OTHER_REBOOT_JUDGE_FILE + else: + self.__otp_switch_reboot_judge_file = self.__otp_reboot_judge_file_config.get( + "otp_switch_reboot_judge_file", OTP_SWITCH_REBOOT_JUDGE_FILE) + self.__otp_other_reboot_judge_file = self.__otp_reboot_judge_file_config.get( + "otp_other_reboot_judge_file", OTP_OTHER_REBOOT_JUDGE_FILE) + + self.__fan_rotor_error_num = {} + self.__fan_present_status = {} # {"FAN1":0, "FAN2":1...} 1:present, 0:absent + self.__fan_rotate_status = {} # {"FAN1":0, "FAN2":1...} 1:OK, 0:NOT OK + self.__fan_repair_flag = {} # {"FAN1":0, "FAN2":1...} 1:repair, 0:give up + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + self.__fan_present_status[fan_name] = 1 # present + self.__fan_rotate_status[fan_name] = 1 # OK + self.__fan_repair_flag[fan_name] = 1 # repair + rotor_num = self.get_rotor_number(fan_name) + tmp_fan = {} + for j in range(rotor_num): + rotor_name = "Rotor" + str(j + 1) + tmp_fan[rotor_name] = 0 # not error + self.__fan_rotor_error_num[fan_name] = tmp_fan + + self.__fancontrol_para = self.__config["fancontrol_para"] + self.__interval = self.__fancontrol_para.get("interval", 5) + self.__fan_status_interval = self.__fancontrol_para.get("fan_status_interval", 0) + self.__max_pwm = self.__fancontrol_para.get("max_pwm", 0xff) + self.__min_pwm = self.__fancontrol_para.get("min_pwm", 0x80) + self.__abnormal_pwm = self.__fancontrol_para.get("abnormal_pwm", 0xbb) + self.__warning_pwm = self.__fancontrol_para.get("warning_pwm", 0xff) + self.__temp_invalid_pid_pwm = self.__fancontrol_para.get("temp_invalid_pid_pwm", 0x80) + self.__temp_error_pid_pwm = self.__fancontrol_para.get("temp_error_pid_pwm", 0x80) + self.__temp_fail_num = self.__fancontrol_para.get("temp_fail_num", 3) + self.__check_temp_fail = self.__fancontrol_para.get("check_temp_fail", []) + self.__temp_warning_num = self.__fancontrol_para.get("temp_warning_num", 3) + self.__temp_critical_num = self.__fancontrol_para.get("temp_critical_num", 3) + self.__temp_emergency_num = self.__fancontrol_para.get("temp_emergency_num", 3) + self.__temp_warning_countdown = self.__fancontrol_para.get("temp_warning_countdown", 60) + self.__temp_critical_countdown = self.__fancontrol_para.get("temp_critical_countdown", 60) + self.__temp_emergency_countdown = self.__fancontrol_para.get("temp_emergency_countdown", 60) + self.__rotor_error_count = self.__fancontrol_para.get("rotor_error_count", 6) + self.__inlet_mac_diff = self.__fancontrol_para.get("inlet_mac_diff", 50) + self.__check_crit_reboot_flag = self.__fancontrol_para.get("check_crit_reboot_flag", 1) + self.__check_emerg_reboot_flag = self.__fancontrol_para.get("check_emerg_reboot_flag", 1) + self.__check_crit_reboot_num = self.__fancontrol_para.get("check_crit_reboot_num", 3) + self.__check_crit_sleep_time = self.__fancontrol_para.get("check_crit_sleep_time", 20) + self.__check_emerg_reboot_num = self.__fancontrol_para.get("check_emerg_reboot_num", 3) + self.__check_emerg_sleep_time = self.__fancontrol_para.get("check_emerg_sleep_time", 20) + self.__check_temp_emergency = self.__fancontrol_para.get("check_temp_emergency", 0) + self.__check_temp_critical = self.__fancontrol_para.get("check_temp_critical", 1) + self.__check_temp_warning = self.__fancontrol_para.get("check_temp_warning", 1) + self.__check_temp_emergency_reboot = self.__fancontrol_para.get("check_temp_emergency_reboot", []) + self.__psu_absent_fullspeed_num = self.__fancontrol_para.get("psu_absent_fullspeed_num", 1) + self.__fan_absent_fullspeed_num = self.__fancontrol_para.get("fan_absent_fullspeed_num", 1) + self.__rotor_error_fullspeed_num = self.__fancontrol_para.get("rotor_error_fullspeed_num", 1) + self.__psu_fan_control = self.__fancontrol_para.get("psu_fan_control", 1) # default control psu fan + self.__fan_plug_in_pwm = self.__fancontrol_para.get("fan_plug_in_pwm", 0x80) + self.__fan_plug_in_default_countdown = self.__fancontrol_para.get("fan_plug_in_default_countdown", 0) + self.__deal_fan_error_policy = self.__fancontrol_para.get("deal_fan_error", 0) + self.__deal_fan_error_conf = self.__fancontrol_para.get("deal_fan_error_conf", {}) + self.__deal_fan_error_default_countdown = self.__deal_fan_error_conf.get("countdown", 0) + + self.__warning_countdown = 0 # temp warning flag for normal fancontrol + self.__critical_countdown = 0 # temp critical flag for normal fancontrol + self.__emergency_countdown = 0 # temp emergency flag for normal fancontrol + self.__fan_plug_in_countdown = 0 # fan plug in flag for normal fancontrol + self.__deal_fan_error_countdown = 0 + self.__fan_absent_num = 0 + self.__fan_nok_num = 0 + self.__pre_fan_nok = PRE_FAN_NOK_UNKNOWN + self.openloop = openloop() + self.pid = pid() + self.hyst = hysteresis() + self.__pwm = self.__min_pwm + + self.__board_air_flow = "" + self.__fan_air_flow_monitor = self.__fancontrol_para.get("fan_air_flow_monitor", 0) + self.__psu_air_flow_monitor = self.__fancontrol_para.get("psu_air_flow_monitor", 0) + self.__air_flow_correct_fan_pwm = self.__fancontrol_para.get("air_flow_correct_fan_pwm", 0xff) + self.__air_flow_correct_psu_pwm = self.__fancontrol_para.get("air_flow_correct_psu_pwm", 0xff) + self.__air_flow_error_fan_pwm = self.__fancontrol_para.get("air_flow_error_fan_pwm", 0) + self.__air_flow_error_psu_pwm = self.__fancontrol_para.get("air_flow_error_psu_pwm", 0) + self.fan_air_flow_inconsistent_flag = False + self.psu_air_flow_inconsistent_flag = False + self.air_flow_inconsistent_flag = False + self.fan_obj_list = [] + self.psu_obj_list = [] + + @property + def na_ret(self): + return self.int_case.na_ret + + def get_onie_e2_obj(self, name): + return self.int_case.get_onie_e2_obj(name) + + @property + def board_air_flow(self): + air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) + if self.__board_air_flow not in air_flow_tuple: + self.__board_air_flow = self.int_case.get_device_airflow(ONIE_E2_NAME) + fanairflow_debug("board_air_flow: %s" % self.__board_air_flow) + return self.__board_air_flow + + @property + def fan_air_flow_monitor(self): + return self.__fan_air_flow_monitor + + @property + def psu_air_flow_monitor(self): + return self.__psu_air_flow_monitor + + @property + def air_flow_correct_fan_pwm(self): + return self.__air_flow_correct_fan_pwm + + @property + def air_flow_correct_psu_pwm(self): + return self.__air_flow_correct_psu_pwm + + @property + def air_flow_error_fan_pwm(self): + return self.__air_flow_error_fan_pwm + + @property + def air_flow_error_psu_pwm(self): + return self.__air_flow_error_psu_pwm + + def get_para(self, t): + para = self.__pid_config.get(t) + return para + + def update_over_temp_threshold_num(self): + for temp_threshold in self.__temps_threshold_config.values(): + if temp_threshold['ignore_threshold']: + continue + emergency_threshold = temp_threshold.get('emergency', None) + critical_threshold = temp_threshold.get('critical', None) + warning_threshold = temp_threshold.get('warning', None) + fancontrol_debug("%s warning = %s, critical = %s, emergency = %s" % + (temp_threshold['name'], warning_threshold, critical_threshold, emergency_threshold)) + + if emergency_threshold is not None and temp_threshold['temp'] >= emergency_threshold: + temp_threshold['emergency_num'] += 1 + else: + temp_threshold['emergency_num'] = 0 + + if critical_threshold is not None and temp_threshold['temp'] >= critical_threshold: + temp_threshold['critical_num'] += 1 + else: + temp_threshold['critical_num'] = 0 + + if warning_threshold is not None and temp_threshold['temp'] >= warning_threshold: + temp_threshold['warning_num'] += 1 + else: + temp_threshold['warning_num'] = 0 + + fancontrol_debug("%s warning_num = %d, critical_num = %d, emergency_num = %d" % + (temp_threshold['name'], temp_threshold['warning_num'], temp_threshold['critical_num'], temp_threshold.get("emergency_num"))) + + def get_monitor_temp(self): + sensorlist = self.int_case.get_temp_info() + + for temp_threshold in self.__temps_threshold_config.values(): + sensor = sensorlist.get(temp_threshold['name']) + if sensor["Value"] is None or int(sensor["Value"]) == self.int_case.error_ret: + temp_threshold['fail_num'] += 1 + fancontrol_error("get %s failed, fail_num = %d" % (temp_threshold['name'], temp_threshold['fail_num'])) + else: + temp_threshold['fail_num'] = 0 + temp_threshold.setdefault('fix', 0) + temp_threshold['temp'] = sensor["Value"] + temp_threshold['fix'] + fancontrol_debug("%s = %d" % (temp_threshold['name'], temp_threshold['temp'])) + self.update_over_temp_threshold_num() + + def is_temp_warning(self): + warning_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + if temp_threshold['ignore_threshold']: + continue + if temp_threshold['warning_num'] >= self.__temp_warning_num: + warning_flag = True + fancontrol_warn("%%FANCONTROL-4-TEMP_HIGH: %s temperature %sC is larger than warning threshold %sC." % + (temp_threshold['name'], temp_threshold['temp'], temp_threshold.get('warning'))) + return warning_flag + + def checkTempWarning(self): + try: + if self.is_temp_warning(): + self.__warning_countdown = self.__temp_warning_countdown + fancontrol_debug("temp is over warning") + return True + if self.__warning_countdown > 0: + self.__warning_countdown -= 1 + return False + except Exception as e: + fancontrol_error("%%policy: checkTempWarning failed") + fancontrol_error(str(e)) + return False + + def checkTempWarningCountdown(self): + if self.__warning_countdown > 0: + return True + return False + + def is_temp_critical(self): + critical_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['critical_flag'] = False + if temp_threshold['ignore_threshold']: + continue + if temp_threshold['critical_num'] >= self.__temp_critical_num: + critical_flag = True + temp_threshold['critical_flag'] = True + fancontrol_crit("%%FANCONTROL-2-TEMP_HIGH: %s temperature %sC is larger than critical threshold %sC." % + (temp_threshold['name'], temp_threshold['temp'], temp_threshold.get('critical'))) + return critical_flag + + def checkTempCritical(self): + try: + if self.is_temp_critical(): + self.__critical_countdown = self.__temp_critical_countdown + fancontrol_debug("temp is over critical") + return True + if self.__critical_countdown > 0: + self.__critical_countdown -= 1 + return False + except Exception as e: + fancontrol_error("%%policy: checkTempCrit failed") + fancontrol_error(str(e)) + return False + + def is_temp_emergency(self): + emergency_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['emergency_flag'] = False + if temp_threshold['ignore_threshold']: + continue + if temp_threshold['emergency_num'] >= self.__temp_emergency_num: + emergency_flag = True + temp_threshold['emergency_flag'] = True + fancontrol_alert("%%FANCONTROL-1-TEMP_HIGH: %s temperature %sC is larger than emergency threshold %sC." % + (temp_threshold['name'], temp_threshold['temp'], temp_threshold.get('emergency'))) + return emergency_flag + + def checkTempEmergency(self): + try: + if self.is_temp_emergency(): + self.__emergency_countdown = self.__temp_emergency_countdown + fancontrol_debug("temp is over emergency") + return True + if self.__emergency_countdown > 0: + self.__emergency_countdown -= 1 + return False + except Exception as e: + fancontrol_error("%%policy: checkTempEmergency failed") + fancontrol_error(str(e)) + return False + + def checkTempCriticalCountdown(self): + if self.__critical_countdown > 0: + return True + return False + + def checkTempEmergencyCountdown(self): + if self.__emergency_countdown > 0: + return True + return False + + def checkTempRebootCrit(self): + try: + if self.is_temp_critical(): + temp_dict = dict(self.__temps_threshold_config) + tmp = temp_dict.get(SWITCH_TEMP) + if tmp['critical_flag'] is True: + fancontrol_debug("switch temp is over reboot critical") + return TEMP_REBOOT_CRIT_SWITCH_FLAG + del temp_dict[SWITCH_TEMP] + for temp_items in temp_dict.values(): + if temp_items['ignore_threshold']: + continue + if temp_items['critical_flag'] is False: + return 0 + + fancontrol_debug("other temp is over reboot critical") + return TEMP_REBOOT_CRIT_OTHER_FLAG + except Exception as e: + fancontrol_error("%%policy: checkTempRebootCrit failed") + fancontrol_error(str(e)) + return 0 + + def checkCritReboot(self): + try: + reboot_flag = self.checkTempRebootCrit() + if reboot_flag > 0: + self.set_all_fan_speed_pwm(self.__max_pwm) + for i in range(self.__check_crit_reboot_num): + time.sleep(self.__check_crit_sleep_time) + self.get_monitor_temp() + reboot_flag = self.checkTempRebootCrit() + if reboot_flag > 0: + fancontrol_emerg("%%FANCONTROL-0-TEMP_EMERG: The temperature of device over reboot critical value lasts for %d seconds." % + (self.__check_crit_sleep_time * (i + 1))) + continue + fancontrol_debug("The temperature of device is not over reboot critical value.") + break + if reboot_flag > 0: + fancontrol_emerg( + "%%FANCONTROL-0-TEMP_EMERG: The temperature of device over reboot critical value, system is going to reboot now.") + for temp_threshold in self.__temps_threshold_config.values(): + fancontrol_emerg( + "%%FANCONTROL-TEMP_EMERG: %s temperature: %sC." % + (temp_threshold['name'], temp_threshold['temp'])) + if reboot_flag == TEMP_REBOOT_CRIT_SWITCH_FLAG: + create_judge_file = "touch %s" % self.__otp_switch_reboot_judge_file + else: + create_judge_file = "touch %s" % self.__otp_other_reboot_judge_file + exec_os_cmd(create_judge_file) + exec_os_cmd("sync") + time.sleep(3) + os.system("/sbin/reboot") + except Exception as e: + fancontrol_error("%%policy: checkCritReboot failed") + fancontrol_error(str(e)) + + def checkTempRebootEmerg(self): + try: + if self.is_temp_emergency(): + temp_emerg_reboot_flag = False + for temp_list in self.__check_temp_emergency_reboot: + for temp in temp_list: + tmp = self.__temps_threshold_config.get(temp) + if tmp['emergency_flag'] is False: + fancontrol_debug("temp_list %s, temp: %s not emergency" % (temp_list, temp)) + temp_emerg_reboot_flag = False + break + temp_emerg_reboot_flag = True + if temp_emerg_reboot_flag is True: + fancontrol_debug("temp_list %s, all temp is over emergency reboot" % temp_list) + return True + except Exception as e: + fancontrol_error("%%policy: checkTempRebootEmerg failed") + fancontrol_error(str(e)) + return False + + def checkEmergReboot(self): + try: + reboot_flag = False + if self.checkTempRebootEmerg() is True: + self.set_all_fan_speed_pwm(self.__max_pwm) + for i in range(self.__check_emerg_reboot_num): + time.sleep(self.__check_emerg_sleep_time) + self.get_monitor_temp() + if self.checkTempRebootEmerg() is True: + fancontrol_emerg("%%FANCONTROL-0-TEMP_EMERG: The temperature of device over reboot emergency value lasts for %d seconds." % + (self.__check_emerg_sleep_time * (i + 1))) + reboot_flag = True + continue + fancontrol_debug("The temperature of device is not over reboot emergency value.") + reboot_flag = False + break + if reboot_flag is True: + fancontrol_emerg( + "%%FANCONTROL-0-TEMP_EMERG: The temperature of device over reboot emergency value, system is going to reboot now.") + for temp_threshold in self.__temps_threshold_config.values(): + fancontrol_emerg( + "%%FANCONTROL-0-TEMP_EMERG: %s temperature: %sC." % + (temp_threshold['name'], temp_threshold['temp'])) + create_judge_file = "touch %s" % OTP_SWITCH_REBOOT_JUDGE_FILE + exec_os_cmd(create_judge_file) + exec_os_cmd("sync") + time.sleep(3) + os.system("/sbin/reboot") + except Exception as e: + fancontrol_error("%%policy: checkEmergReboot failed") + fancontrol_error(str(e)) + + def get_fan_total_number(self): + return self.int_case.get_fan_total_number() + + def get_rotor_number(self, fan_name): + return self.int_case.get_fan_rotor_number(fan_name) + + def get_fan_presence(self, fan_name): + return self.int_case.get_fan_presence(fan_name) + + def get_fan_rotor_status(self, fan_name, rotor_name): + return self.int_case.get_fan_rotor_status(fan_name, rotor_name) + + def get_psu_total_number(self): + return self.int_case.get_psu_total_number() + + def get_psu_presence(self, psu_name): + return self.int_case.get_psu_presence(psu_name) + + def get_psu_input_output_status(self, psu_name): + return self.int_case.get_psu_input_output_status(psu_name) + + def checkFanPresence(self): + absent_num = 0 + + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + rotor_num = self.get_rotor_number(fan_name) + tmp_fan = self.__fan_rotor_error_num.get(fan_name) + status = self.get_fan_presence(fan_name) + if status is False: + absent_num = absent_num + 1 + self.__fan_present_status[fan_name] = 0 + fancontrol_debug("%s absent" % fan_name) + else: + if self.__fan_present_status[fan_name] == 0: # absent -> present + self.__pre_fan_nok = PRE_FAN_NOK_UNKNOWN + self.__fan_plug_in_countdown = self.__fan_plug_in_default_countdown + self.__fan_repair_flag[fan_name] = 1 + for j in range(rotor_num): + rotor_name = "Rotor" + str(j + 1) + tmp_fan[rotor_name] = 0 + self.__fan_present_status[fan_name] = 1 + fancontrol_debug("%s presence" % fan_name) + return absent_num + + def checkFanRotorStatus(self): + err_num = 0 + self.__fan_nok_num = 0 + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + rotor_num = self.get_rotor_number(fan_name) + tmp_fan = self.__fan_rotor_error_num.get(fan_name) + fan_rotor_err_cnt = 0 + for j in range(rotor_num): + rotor_name = "Rotor" + str(j + 1) + status = self.get_fan_rotor_status(fan_name, rotor_name) + if status is True: + tmp_fan[rotor_name] = 0 + fancontrol_debug("%s %s ok" % (fan_name, rotor_name)) + else: + tmp_fan[rotor_name] += 1 + if tmp_fan[rotor_name] >= self.__rotor_error_count: + err_num = err_num + 1 + fan_rotor_err_cnt += 1 + fancontrol_debug("%s %s error" % (fan_name, rotor_name)) + fancontrol_debug("%s %s error %d times" % (fan_name, rotor_name, tmp_fan[rotor_name])) + if fan_rotor_err_cnt == 0: + self.__fan_rotate_status[fan_name] = 1 # FAN is ok + else: + self.__fan_rotate_status[fan_name] = 0 # FAN is not ok + self.__fan_nok_num += 1 + fancontrol_debug("fan not ok number:%d." % self.__fan_nok_num) + return err_num + + def checkPsuPresence(self): + absent_num = 0 + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + status = self.get_psu_presence(psu_name) + if status is False: + absent_num = absent_num + 1 + fancontrol_debug("%s absent" % psu_name) + else: + fancontrol_debug("%s presence" % psu_name) + return absent_num + + def checkPsuStatus(self): + err_num = 0 + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + status = self.get_psu_input_output_status(psu_name) + if status is False: + err_num = err_num + 1 + fancontrol_debug("%s error" % psu_name) + else: + fancontrol_debug("%s ok" % psu_name) + return err_num + + def checkDevError(self): + pwm = self.__min_pwm + switchtemp = self.__temps_threshold_config.get(SWITCH_TEMP)['temp'] + inlettemp = self.__temps_threshold_config.get(INLET_TEMP)['temp'] + temp_diff = abs(switchtemp - inlettemp) + fancontrol_debug("|switchtemp - inlettemp| = %d" % temp_diff) + if temp_diff >= self.__inlet_mac_diff: + fancontrol_debug("temp_diff is over than inlet_mac_diff(%d)" % self.__inlet_mac_diff) + if self.__pwm > self.__abnormal_pwm: + pwm = self.__max_pwm + else: + pwm = self.__abnormal_pwm + return pwm + + def checktempfail(self): + pwm = self.__min_pwm + for temp in self.__check_temp_fail: + temp_name = temp.get("temp_name") + temp_fail_num = self.__temps_threshold_config.get(temp_name)['fail_num'] + if temp_fail_num >= self.__temp_fail_num: + pwm = self.__abnormal_pwm + fancontrol_debug("%s temp_fail_num = %d" % (temp_name, temp_fail_num)) + fancontrol_debug("self.__temp_fail_num = %d" % self.__temp_fail_num) + return pwm + + def abnormal_check(self): + pwm_list = [] + pwm_min = self.__min_pwm + pwm_list.append(pwm_min) + + if self.__check_temp_emergency == 1: + status = self.checkTempEmergency() + if status is True: + over_emerg_pwm = self.__max_pwm + pwm_list.append(over_emerg_pwm) + fancontrol_debug("over_emerg_pwm = 0x%x" % over_emerg_pwm) + # do reset check + if self.__check_emerg_reboot_flag == 1: + self.checkEmergReboot() + else: + if self.checkTempEmergencyCountdown() is True: # temp lower than emergency in 5 min + over_emerg_countdown_pwm = self.__max_pwm + pwm_list.append(over_emerg_countdown_pwm) + fancontrol_debug("TempEmergencyCountdown: %d, over_emerg_countdown_pwm = 0x%x" % + (self.__emergency_countdown, over_emerg_countdown_pwm)) + + if self.__check_temp_critical == 1: + status = self.checkTempCritical() + if status is True: + over_crit_pwm = self.__max_pwm + pwm_list.append(over_crit_pwm) + fancontrol_debug("over_crit_pwm = 0x%x" % over_crit_pwm) + # do reset check + if self.__check_crit_reboot_flag == 1: + self.checkCritReboot() + else: + if self.checkTempCriticalCountdown() is True: # temp lower than critical in 5 min + over_crit_countdown_pwm = self.__max_pwm + pwm_list.append(over_crit_countdown_pwm) + fancontrol_debug("TempCriticalCountdown: %d, over_crit_countdown_pwm = 0x%x" % + (self.__critical_countdown, over_crit_countdown_pwm)) + + if self.__check_temp_warning == 1: + status = self.checkTempWarning() + if status is True: + over_warn_pwm = self.__warning_pwm + pwm_list.append(over_warn_pwm) + fancontrol_debug("over_warn_pwm = 0x%x" % over_warn_pwm) + else: + if self.checkTempWarningCountdown() is True: # temp lower than warning in 5 min + over_warn_countdown_pwm = self.__warning_pwm + pwm_list.append(over_warn_countdown_pwm) + fancontrol_debug("TempWarningCountdown: %d, over_warn_countdown_pwm = 0x%x" % + (self.__warning_countdown, over_warn_countdown_pwm)) + + self.__fan_absent_num = self.checkFanPresence() + if self.__fan_absent_num >= self.__fan_absent_fullspeed_num: + fan_absent_pwm = self.__max_pwm + pwm_list.append(fan_absent_pwm) + fancontrol_debug("fan_absent_pwm = 0x%x" % fan_absent_pwm) + + rotor_err_num = self.checkFanRotorStatus() + if rotor_err_num >= self.__rotor_error_fullspeed_num: + rotor_err_pwm = self.__max_pwm + pwm_list.append(rotor_err_pwm) + fancontrol_debug("rotor_err_pwm = 0x%x" % rotor_err_pwm) + + psu_absent_num = self.checkPsuPresence() + if psu_absent_num >= self.__psu_absent_fullspeed_num: + psu_absent_pwm = self.__max_pwm + pwm_list.append(psu_absent_pwm) + fancontrol_debug("psu_absent_pwm = 0x%x" % psu_absent_pwm) + + dev_err_pwm = self.checkDevError() + pwm_list.append(dev_err_pwm) + fancontrol_debug("dev_err_pwm = 0x%x" % dev_err_pwm) + + temp_fail_pwm = self.checktempfail() + pwm_list.append(temp_fail_pwm) + fancontrol_debug("temp_fail_pwm = 0x%x" % temp_fail_pwm) + + pwm = max(pwm_list) + return pwm + + def get_error_fan(self): + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + if self.__fan_rotate_status[fan_name] == 0: + return fan_name + return None + + def fan_error_update_pwm(self, fan_pwm_dict): + try: + fancontrol_debug("enter deal fan error policy") + ori_fan_pwm_dict = fan_pwm_dict.copy() + + err_fan_name = self.get_error_fan() + if err_fan_name is None: + fancontrol_debug("fan name is None, do nothing.") + return ori_fan_pwm_dict + + if self.__fan_repair_flag[err_fan_name] == 0: + fancontrol_debug("%s already repaired, do nothing." % err_fan_name) + return ori_fan_pwm_dict + + if self.__pre_fan_nok != err_fan_name: + fancontrol_debug( + "not ok fan change from %s to %s, update countdown." % + (self.__pre_fan_nok, err_fan_name)) + self.__deal_fan_error_countdown = self.__deal_fan_error_default_countdown + if self.__pre_fan_nok != PRE_FAN_NOK_UNKNOWN: + fancontrol_debug( + "%s repaire success, %s NOT OK, try to repaire." % + (self.__pre_fan_nok, err_fan_name)) + self.__fan_repair_flag[self.__pre_fan_nok] = 0 + self.__pre_fan_nok = err_fan_name + + if self.__deal_fan_error_countdown > 0: + self.__deal_fan_error_countdown -= 1 + fancontrol_debug("%s repaire, countdown %d." % (err_fan_name, self.__deal_fan_error_countdown)) + + if self.__deal_fan_error_countdown == 0: + self.__fan_repair_flag[err_fan_name] = 0 + fancontrol_debug("%s set repaire fail flag, use origin pwm." % err_fan_name) + return ori_fan_pwm_dict + + fan_err_pwm_conf_list = self.__deal_fan_error_conf[err_fan_name] + for item in fan_err_pwm_conf_list: + fan_pwm_dict[item["name"]] = item["pwm"] + fancontrol_debug("fan pwm update, fan pwm dict:%s" % fan_pwm_dict) + + return fan_pwm_dict + except Exception as e: + fancontrol_error("%%policy: deal_fan_error raise Exception:%s" % str(e)) + self.__pre_fan_nok = PRE_FAN_NOK_UNKNOWN + return ori_fan_pwm_dict + + def get_fan_pwm_dict(self, default_pwm): + fan_pwm_dict = {} + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_pwm_dict[fan_name] = default_pwm + if self.__deal_fan_error_policy: + if self.__fan_absent_num == 0 and self.__fan_nok_num == 1: + fan_pwm_dict = self.fan_error_update_pwm(fan_pwm_dict) + else: + if self.__pre_fan_nok != PRE_FAN_NOK_UNKNOWN and self.__fan_rotate_status[self.__pre_fan_nok] == 1: + fancontrol_debug("%s repaire success." % (self.__pre_fan_nok)) + self.__fan_repair_flag[self.__pre_fan_nok] = 0 + self.__pre_fan_nok = PRE_FAN_NOK_UNKNOWN + return fan_pwm_dict + + def get_psu_pwm_dict(self, default_pwm): + psu_pwm_dict = {} + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + psu_pwm_dict[psu_name] = default_pwm + return psu_pwm_dict + + def check_board_air_flow(self): + board_air_flow = self.board_air_flow + air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) + if board_air_flow not in air_flow_tuple: + fanairflow_debug("get board air flow error, value [%s]" % board_air_flow) + return False + fanairflow_debug("board air flow check ok: %s" % board_air_flow) + return True + + def check_fan_air_flow(self): + if self.fan_air_flow_monitor: + fanairflow_debug("open air flow monitor, check fan air flow") + ret = self.check_board_air_flow() + if ret is False: + fanairflow_debug("get board air flow error, set fan_air_flow_inconsistent_flag False") + self.fan_air_flow_inconsistent_flag = False + return + air_flow_inconsistent_flag_tmp = False + for fan_obj in self.fan_obj_list: + fan_obj.update_fru_info() + fanairflow_debug("%s origin name: [%s], display name: [%s] air flow [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow)) + if fan_obj.air_flow == self.na_ret: + fanairflow_debug("%s get air flow failed, set air_flow_inconsistent flag False" % fan_obj.name) + fan_obj.air_flow_inconsistent = False + continue + if fan_obj.air_flow != self.board_air_flow: + fanairflow_debug("%s air flow error, origin name: [%s], display name: [%s], fan air flow [%s], board air flow [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow)) + air_flow_inconsistent_flag_tmp = True + fan_obj.air_flow_inconsistent = True + else: + fanairflow_debug("%s air flow check ok, origin name: [%s], display name: [%s], fan air flow: [%s], board air flow: [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow)) + fan_obj.air_flow_inconsistent = False + self.fan_air_flow_inconsistent_flag = air_flow_inconsistent_flag_tmp + else: + fanairflow_debug("air flow monitor not open, set fan_air_flow_inconsistent_flag False") + self.fan_air_flow_inconsistent_flag = False + return + + def check_psu_air_flow(self): + if self.psu_air_flow_monitor: + fanairflow_debug("open air flow monitor, check psu air flow") + ret = self.check_board_air_flow() + if ret is False: + fanairflow_debug("get board air flow error, set psu_air_flow_inconsistent_flag False") + self.psu_air_flow_inconsistent_flag = False + return + air_flow_inconsistent_flag_tmp = False + for psu_obj in self.psu_obj_list: + psu_obj.update_fru_info() + fanairflow_debug("%s origin name: [%s], display name: [%s] air flow [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow)) + if psu_obj.air_flow == self.na_ret: + fanairflow_debug("%s get air flow failed, set air_flow_inconsistent flag False" % psu_obj.name) + psu_obj.air_flow_inconsistent = False + continue + if psu_obj.air_flow != self.board_air_flow: + fanairflow_debug("%s air flow error, origin name: [%s], display name: [%s], psu air flow [%s], board air flow [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow)) + air_flow_inconsistent_flag_tmp = True + psu_obj.air_flow_inconsistent = True + else: + fanairflow_debug("%s air flow check ok, origin name: [%s], display name: [%s], psu air flow: [%s], board air flow: [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow)) + psu_obj.air_flow_inconsistent = False + self.psu_air_flow_inconsistent_flag = air_flow_inconsistent_flag_tmp + else: + fanairflow_debug("air flow monitor not open, set psu_air_flow_inconsistent_flag False") + self.psu_air_flow_inconsistent_flag = False + return + + def do_fancontrol(self): + pwm_list = [] + pwm_min = self.__min_pwm + pwm_list.append(pwm_min) + + # first check air flow + self.check_fan_air_flow() + self.check_psu_air_flow() + if self.fan_air_flow_inconsistent_flag is True or self.psu_air_flow_inconsistent_flag is True: + self.air_flow_inconsistent_flag = True + else: + self.air_flow_inconsistent_flag = False + fanairflow_debug("check_air_flow, air_flow_inconsistent_flag: %s" % self.air_flow_inconsistent_flag) + # get_monitor_temp + self.get_monitor_temp() + fancontrol_debug("last_pwm = 0x%x" % self.__pwm) + # openloop + inlettemp = self.__temps_threshold_config.get(INLET_TEMP)['temp'] + linear_value = self.openloop.linear_cacl(inlettemp) + if linear_value is None: + linear_value = self.__min_pwm + pwm_list.append(linear_value) + fancontrol_debug("linear_value = 0x%x" % linear_value) + + curve_value = self.openloop.curve_cacl(inlettemp) + if curve_value is None: + curve_value = self.__min_pwm + pwm_list.append(curve_value) + fancontrol_debug("curve_value = 0x%x" % curve_value) + + # hyst + for hyst_index in self.__hyst_config.values(): + temp_name = hyst_index.get("name") + hyst_flag = hyst_index.get("flag", 0) + if hyst_flag == 0: + fancontrol_debug("%s hyst flag is 0, do nothing" % temp_name) + continue + tmp_temp = int(self.__temps_threshold_config.get(temp_name)['temp']) # make sure temp is int + hyst_value = self.hyst.cacl(temp_name, tmp_temp) + if hyst_value is None: + hyst_value = self.__min_pwm + pwm_list.append(hyst_value) + fancontrol_debug("%s hyst_value = 0x%x" % (temp_name, hyst_value)) + + # pid + for pid_index in self.__pid_config.values(): + temp_name = pid_index.get("name") + pid_flag = pid_index.get("flag", 0) + if pid_flag == 0: + fancontrol_debug("%s pid flag is 0, do nothing" % temp_name) + continue + tmp_temp = self.__temps_threshold_config.get(temp_name)['temp'] + if tmp_temp is not None: + tmp_temp = int(tmp_temp) # make sure temp is int + invalid_temp_val = self.__temps_threshold_config.get(temp_name)['invalid'] + error_temp_val = self.__temps_threshold_config.get(temp_name)['error'] + if tmp_temp == invalid_temp_val: # temp is invalid + temp = None + self.pid.cacl(self.__pwm, temp_name, temp) # temp invalid, PID need to record None + pid_value = self.__temp_invalid_pid_pwm + fancontrol_debug("%s is invalid, pid_value = 0x%x" % (temp_name, pid_value)) + fancontrol_debug("temp = %d, invalid_temp = %d" % (tmp_temp, invalid_temp_val)) + elif tmp_temp == error_temp_val: # temp is error + temp = None + self.pid.cacl(self.__pwm, temp_name, temp) # temp error, PID need to record None + pid_value = self.__temp_error_pid_pwm + fancontrol_debug("%s is error, pid_value = 0x%x" % (temp_name, pid_value)) + fancontrol_debug("temp = %d, error_temp = %d" % (tmp_temp, error_temp_val)) + else: + pid_value = self.pid.cacl(self.__pwm, temp_name, tmp_temp) + else: # temp get failed + pid_value = self.pid.cacl(self.__pwm, temp_name, tmp_temp) + if pid_value is None: + pid_value = self.__min_pwm + pwm_list.append(pid_value) + fancontrol_debug("%s pid_value = 0x%x" % (temp_name, pid_value)) + + # abnormal + abnormal_value = self.abnormal_check() + pwm_list.append(abnormal_value) + fancontrol_debug("abnormal_value = 0x%x" % abnormal_value) + + if self.__fan_plug_in_countdown > 0 and self.__fan_absent_num == 0: + fancontrol_debug("fan plug in countdown %d, set plug in pwm: 0x%x" % + (self.__fan_plug_in_countdown, self.__fan_plug_in_pwm)) + self.__pwm = self.__fan_plug_in_pwm + self.__fan_plug_in_countdown -= 1 + else: + self.__pwm = max(pwm_list) + fancontrol_debug("__pwm = 0x%x\n" % self.__pwm) + if self.air_flow_inconsistent_flag is True: + fanairflow_debug("air flow inconsistent, set all fan speed pwm") + self.set_all_fan_speed_pwm(self.__pwm) + else: + fanairflow_debug("air flow consistent, deal fan error policy") + fan_pwm_dict = self.get_fan_pwm_dict(self.__pwm) + psu_pwm_dict = self.get_psu_pwm_dict(self.__pwm) + self.set_fan_pwm_independent(fan_pwm_dict, psu_pwm_dict) + + def run(self): + start_time = time.time() + while True: + try: + debug_init() + if self.__fan_status_interval > 0 and self.__fan_status_interval < self.__interval: + delta_time = time.time() - start_time + if delta_time >= self.__interval or delta_time < 0: + self.do_fancontrol() + start_time = time.time() + else: + self.checkFanPresence() + time.sleep(self.__fan_status_interval) + else: + self.do_fancontrol() + time.sleep(self.__interval) + except Exception as e: + traceback.print_exc() + fancontrol_error(str(e)) + + def set_all_fan_speed_pwm(self, pwm): + fan_pwm_dict = {} + psu_pwm_dict = {} + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_pwm_dict[fan_name] = pwm + + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + psu_pwm_dict[psu_name] = pwm + self.set_fan_pwm_independent(fan_pwm_dict, psu_pwm_dict) + + def set_fan_pwm_independent(self, fan_pwm_dict, psu_pwm_dict): + if self.air_flow_inconsistent_flag is True: + for psu_obj in self.psu_obj_list: + if psu_obj.air_flow_inconsistent is True: + psu_pwm_dict[psu_obj.name] = self.air_flow_error_psu_pwm + fanairflow_debug("%s air flow error, origin name: [%s], display name: [%s], psu air flow: [%s], board air flow: [%s], set psu pwm: 0x%x" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow, self.air_flow_error_psu_pwm)) + else: + psu_pwm_dict[psu_obj.name] = self.air_flow_correct_psu_pwm + fanairflow_debug("%s air flow correct, origin name: [%s], display name: [%s], psu air flow: [%s], board air flow: [%s], set psu pwm: 0x%x" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow, self.air_flow_correct_psu_pwm)) + + for fan_obj in self.fan_obj_list: + if fan_obj.air_flow_inconsistent is True: + fan_pwm_dict[fan_obj.name] = self.air_flow_error_fan_pwm + fanairflow_debug("%s air flow error, origin name: [%s], display name: [%s], fan air flow: [%s], board air flow: [%s], set fan pwm: 0x%x" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow, self.air_flow_error_fan_pwm)) + else: + fan_pwm_dict[fan_obj.name] = self.air_flow_correct_fan_pwm + fanairflow_debug("%s air flow correct, origin name: [%s], display name: [%s], fan air flow: [%s], board air flow: [%s], set fan pwm: 0x%x" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow, self.air_flow_correct_fan_pwm)) + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + self.fan_set_speed_pwm_by_name(fan_name, fan_pwm_dict[fan_name]) + if self.__psu_fan_control == 1: + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + self.psu_set_speed_pwm_by_name(psu_name, psu_pwm_dict[psu_name]) + + def fan_set_speed_pwm_by_name(self, fan_name, pwm): + duty = round(pwm * 100 / 255) + rotor_len = self.get_rotor_number(fan_name) + for i in range(rotor_len): + val = self.int_case.set_fan_speed_pwm(fan_name, i + 1, duty) + if val != 0: + fancontrol_error("%s rotor%d: %d" % (fan_name, i + 1, val)) + + def psu_set_speed_pwm_by_name(self, psu_name, pwm): + duty = round(pwm * 100 / 255) + status = self.int_case.set_psu_fan_speed_pwm(psu_name, int(duty)) + if status is not True: + fancontrol_error("set %s speed fail" % psu_name) + + def fan_obj_init(self): + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_obj = DevFan(fan_name, self.int_case) + self.fan_obj_list.append(fan_obj) + fanairflow_debug("fan object initialize success") + + def psu_obj_init(self): + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + psu_obj = DevPsu(psu_name, self.int_case) + self.psu_obj_list.append(psu_obj) + fanairflow_debug("psu object initialize success") + + +if __name__ == '__main__': + debug_init() + fancontrol_debug("enter main") + fan_control = fancontrol() + fan_control.fan_obj_init() + fan_control.psu_obj_init() + fan_control.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_ledctrl.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_ledctrl.py new file mode 100755 index 000000000000..c21fd3c1f585 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_ledctrl.py @@ -0,0 +1,830 @@ +#!/usr/bin/env python3 +import time +import syslog +import traceback +from plat_hal.interface import interface +from plat_hal.baseutil import baseutil +try: + import abc +except ImportError as error: + raise ImportError(str(error) + " - required module not found") from error + +SWITCH_TEMP = "SWITCH_TEMP" +F2B_AIR_FLOW = "intake" +B2F_AIR_FLOW = "exhaust" +ONIE_E2_NAME = "ONIE_E2" + +# status +STATUS_PRESENT = "PRESENT" +STATUS_ABSENT = "ABSENT" +STATUS_OK = "OK" +STATUS_NOT_OK = "NOT OK" +STATUS_FAILED = "FAILED" +STATUS_UNKNOWN = "UNKNOWN" + +LEDCTROL_DEBUG_FILE = "/etc/.ledcontrol_debug_flag" + +LEDCTROLERROR = 1 +LEDCTROLDEBUG = 2 + +debuglevel = 0 +# led status defined +COLOR_GREEN = 1 +COLOR_AMBER = 2 +COLOR_RED = 3 +LED_STATUS_DICT = {COLOR_GREEN: "green", COLOR_AMBER: "amber", COLOR_RED: "red"} + + +def ledcontrol_debug(s): + if LEDCTROLDEBUG & debuglevel: + syslog.openlog("LEDCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def ledcontrol_error(s): + if LEDCTROLERROR & debuglevel: + syslog.openlog("LEDCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def air_flow_warn(s): + syslog.openlog("AIR_FLOW_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_WARNING, s) + + +def air_flow_error(s): + syslog.openlog("AIR_FLOW_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_ERR, s) + + +def air_flow_emerg(s): + syslog.openlog("AIR_FLOW_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_EMERG, s) + + +def debug_init(): + global debuglevel + try: + with open(LEDCTROL_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + +class DevBase(object): + __metaclass__ = abc.ABCMeta + + def __init__(self, name, air_flow_monitor): + self.__name = name + self.__air_flow_monitor = air_flow_monitor + self.present = STATUS_UNKNOWN + self.status = STATUS_UNKNOWN + self.status_summary = STATUS_UNKNOWN + self.origin_name = STATUS_UNKNOWN + self.display_name = STATUS_UNKNOWN + self.air_flow = STATUS_UNKNOWN + self.led_status = COLOR_GREEN + + @property + def name(self): + return self.__name + + @property + def air_flow_monitor(self): + return self.__air_flow_monitor + + @abc.abstractmethod + def get_present(self): + """ + Gets the present status of PSU/FAN + + Returns: + A string, e.g. 'PRESENT, ABSENT, FAILED' + """ + raise NotImplementedError + + @abc.abstractmethod + def get_status(self): + """ + Gets the status of PSU/FAN + + Returns: + A string, e.g. 'OK, NOT OK, FAILED' + """ + raise NotImplementedError + + @abc.abstractmethod + def update_dev_info(self): + """ + update status and fru info of PSU/FAN + + include present, status, status_summary, part_model_name, product_name, air_flow + """ + raise NotImplementedError + + @abc.abstractmethod + def set_module_led(self, color): + """ + set PSU/FAN module LED status + + Args: + color: A string representing the color with which to set the + PSU/FAN module LED status + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + +class DevPsu(DevBase): + + def __init__(self, name, air_flow_monitor, hal_interface): + super(DevPsu, self).__init__(name, air_flow_monitor) + self.int_case = hal_interface + + def get_psu_presence(self): + return self.int_case.get_psu_presence(self.name) + + def get_psu_input_output_status(self): + return self.int_case.get_psu_input_output_status(self.name) + + def get_psu_fru_info(self): + return self.int_case.get_psu_fru_info(self.name) + + @property + def na_ret(self): + return self.int_case.na_ret + + def get_present(self): + try: + status = self.get_psu_presence() + if status is True: + return STATUS_PRESENT + if status is False: + return STATUS_ABSENT + except Exception as e: + ledcontrol_error("get %s present status error, msg: %s" % (self.name, str(e))) + return STATUS_FAILED + + def get_status(self): + try: + status = self.get_psu_input_output_status() + if status is True: + return STATUS_OK + if status is False: + return STATUS_NOT_OK + except Exception as e: + ledcontrol_error("get %s status error, msg: %s" % (self.name, str(e))) + return STATUS_FAILED + + def update_dev_info(self): + try: + # update status + self.present = self.get_present() + if self.present != STATUS_PRESENT: + self.status = STATUS_UNKNOWN + self.status_summary = self.present + else: + self.status = self.get_status() + self.status_summary = self.status + # update fru info if need air flow monitor + if self.air_flow_monitor: + dic = self.get_psu_fru_info() + self.origin_name = dic["PN"] + self.air_flow = dic["AirFlow"] + self.display_name = dic["DisplayName"] + except Exception as e: + ledcontrol_error("update %s info error, msg: %s" % (self.name, str(e))) + self.present = STATUS_FAILED + self.status = STATUS_FAILED + self.status_summary = STATUS_FAILED + self.origin_name = self.na_ret + self.air_flow = self.na_ret + self.display_name = self.na_ret + + def set_module_led(self, color): + """ + set PSU module LED is not support, always return True + """ + return True + + +class DevFan(DevBase): + + def __init__(self, name, air_flow_monitor, hal_interface): + super(DevFan, self).__init__(name, air_flow_monitor) + self.int_case = hal_interface + + def get_fan_rotor_number(self): + return self.int_case.get_fan_rotor_number(self.name) + + def get_fan_presence(self): + return self.int_case.get_fan_presence(self.name) + + def get_fan_rotor_status(self, rotor_name): + return self.int_case.get_fan_rotor_status(self.name, rotor_name) + + def get_fan_fru_info(self): + return self.int_case.get_fan_fru_info(self.name) + + @property + def na_ret(self): + return self.int_case.na_ret + + def get_present(self): + try: + status = self.get_fan_presence() + if status is True: + return STATUS_PRESENT + if status is False: + return STATUS_ABSENT + except Exception as e: + ledcontrol_error("get %s present status error, msg: %s" % (self.name, str(e))) + return STATUS_FAILED + + def get_status(self): + try: + rotor_num = self.get_fan_rotor_number() + err_motor_num = 0 + for j in range(rotor_num): + rotor_name = "Rotor" + str(j + 1) + roll_status = self.get_fan_rotor_status(rotor_name) + if roll_status is not True: + err_motor_num += 1 + ledcontrol_debug("%s %s error, status %s" % (self.name, rotor_name, roll_status)) + else: + ledcontrol_debug("%s %s ok" % (self.name, rotor_name)) + if err_motor_num > 0: + return STATUS_NOT_OK + return STATUS_OK + except Exception as e: + ledcontrol_error("get %s status error, msg: %s" % (self.name, str(e))) + return STATUS_FAILED + + def update_dev_info(self): + try: + # update status + self.present = self.get_present() + if self.present != STATUS_PRESENT: + self.status = STATUS_UNKNOWN + self.status_summary = self.present + else: + self.status = self.get_status() + self.status_summary = self.status + # update fru info if need air flow monitor + if self.air_flow_monitor: + dic = self.get_fan_fru_info() + self.origin_name = dic["PN"] + self.air_flow = dic["AirFlow"] + self.display_name = dic["DisplayName"] + except Exception as e: + ledcontrol_error("update %s fru info error, msg: %s" % (self.name, str(e))) + self.present = STATUS_FAILED + self.status = STATUS_FAILED + self.status_summary = STATUS_FAILED + self.origin_name = self.na_ret + self.air_flow = self.na_ret + self.display_name = self.na_ret + + def set_module_led(self, color): + ret = self.int_case.set_fan_led(self.name, color) + if ret == 0: + return True + return False + + +class ledcontrol(object): + + def __init__(self): + self.fan_obj_list = [] + self.psu_obj_list = [] + self.board_psu_led_status = COLOR_GREEN + self.board_fan_led_status = COLOR_GREEN + self.__board_air_flow = "" + self.int_case = interface() + self.__config = baseutil.get_monitor_config() + self.__temps_threshold_config = self.__config["temps_threshold"] + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['temp'] = 0 + temp_threshold['fail_num'] = 0 + self.__ledcontrol_para = self.__config["ledcontrol_para"] + self.__interval = self.__ledcontrol_para.get("interval", 5) + self.__checkpsu = self.__ledcontrol_para.get("checkpsu", 0) + self.__checkfan = self.__ledcontrol_para.get("checkfan", 0) + self.__psu_amber_num = self.__ledcontrol_para.get("psu_amber_num") + self.__fan_amber_num = self.__ledcontrol_para.get("fan_amber_num") + self.__psu_air_flow_amber_num = self.__ledcontrol_para.get("psu_air_flow_amber_num", 0) + self.__fan_air_flow_amber_num = self.__ledcontrol_para.get("fan_air_flow_amber_num", 0) + self.__board_sys_led = self.__ledcontrol_para.get("board_sys_led", []) + self.__board_psu_led = self.__ledcontrol_para.get("board_psu_led", []) + self.__board_fan_led = self.__ledcontrol_para.get("board_fan_led", []) + self.__psu_air_flow_monitor = self.__ledcontrol_para.get("psu_air_flow_monitor", 0) + self.__fan_air_flow_monitor = self.__ledcontrol_para.get("fan_air_flow_monitor", 0) + self.__fan_mix_list = self.__ledcontrol_para.get("fan_mix_list", []) + + @property + def na_ret(self): + return self.int_case.na_ret + + @property + def checkpsu(self): + return self.__checkpsu + + @property + def checkfan(self): + return self.__checkfan + + @property + def psu_amber_num(self): + return self.__psu_amber_num + + @property + def fan_amber_num(self): + return self.__fan_amber_num + + @property + def psu_air_flow_amber_num(self): + return self.__psu_air_flow_amber_num + + @property + def fan_air_flow_amber_num(self): + return self.__fan_air_flow_amber_num + + @property + def psu_air_flow_monitor(self): + return self.__psu_air_flow_monitor + + @property + def fan_air_flow_monitor(self): + return self.__fan_air_flow_monitor + + @property + def board_sys_led(self): + return self.__board_sys_led + + @property + def board_psu_led(self): + return self.__board_psu_led + + @property + def board_fan_led(self): + return self.__board_fan_led + + @property + def fan_mix_list(self): + return self.__fan_mix_list + + @property + def interval(self): + return self.__interval + + def get_fan_total_number(self): + return self.int_case.get_fan_total_number() + + def get_psu_total_number(self): + return self.int_case.get_psu_total_number() + + def get_onie_e2_obj(self, name): + return self.int_case.get_onie_e2_obj(name) + + def set_led_color(self, led_name, color): + try: + ret = self.int_case.set_led_color(led_name, color) + except Exception as e: + ledcontrol_error("set %s led %s error, msg: %s" % (led_name, color, str(e))) + ret = False + return ret + + def set_sys_led(self, color): + for led in self.board_sys_led: + led_name = led.get("led_name") + ret = self.set_led_color(led_name, color) + if ret is True: + ledcontrol_debug("set %s success, color:%s," % (led_name, color)) + else: + ledcontrol_debug("set %s failed, color:%s," % (led_name, color)) + + def set_psu_led(self, color): + for led in self.board_psu_led: + led_name = led.get("led_name") + ret = self.set_led_color(led_name, color) + if ret is True: + ledcontrol_debug("set %s success, color:%s," % (led_name, color)) + else: + ledcontrol_debug("set %s failed, color:%s," % (led_name, color)) + + def set_fan_led(self, color): + for led in self.board_fan_led: + led_name = led.get("led_name") + ret = self.set_led_color(led_name, color) + if ret is True: + ledcontrol_debug("set %s success, color:%s," % (led_name, color)) + else: + ledcontrol_debug("set %s failed, color:%s," % (led_name, color)) + + def set_fan_module_led(self): + for fan_obj in self.fan_obj_list: + color = LED_STATUS_DICT.get(fan_obj.led_status) + ret = fan_obj.set_module_led(color) + if ret is True: + ledcontrol_debug("set %s module led success, color: %s," % (fan_obj.name, color)) + else: + ledcontrol_debug("set %s module led failed, color: %s," % (fan_obj.name, color)) + + @property + def board_air_flow(self): + air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) + if self.__board_air_flow not in air_flow_tuple: + self.__board_air_flow = self.int_case.get_device_airflow(ONIE_E2_NAME) + ledcontrol_debug("board_air_flow: %s" % self.__board_air_flow) + return self.__board_air_flow + + def update_psu_info(self): + for psu_obj in self.psu_obj_list: + psu_obj.update_dev_info() + ledcontrol_debug("%s present: [%s], status: [%s] status_summary [%s]" % + (psu_obj.name, psu_obj.present, psu_obj.status, psu_obj.status_summary)) + if psu_obj.air_flow_monitor: + ledcontrol_debug("%s origin name: [%s], display name: [%s] air flow [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow)) + + def update_fan_info(self): + for fan_obj in self.fan_obj_list: + fan_obj.update_dev_info() + ledcontrol_debug("%s present: [%s], status: [%s] status_summary [%s]" % + (fan_obj.name, fan_obj.present, fan_obj.status, fan_obj.status_summary)) + if fan_obj.air_flow_monitor: + ledcontrol_debug("%s origin name: [%s], display name: [%s] air flow [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow)) + + def get_monitor_temp(self): + sensorlist = self.int_case.get_temp_info() + + for temp_threshold in self.__temps_threshold_config.values(): + sensor = sensorlist.get(temp_threshold['name']) + if sensor["Value"] is None: + temp_threshold['fail_num'] += 1 + ledcontrol_error("get %s failed, fail_num = %d" % (temp_threshold['name'], temp_threshold['fail_num'])) + else: + temp_threshold['fail_num'] = 0 + temp_threshold.setdefault('fix', 0) + temp_threshold['temp'] = sensor["Value"] + temp_threshold['fix'] + ledcontrol_debug("%s = %d" % (temp_threshold['name'], temp_threshold['temp'])) + ledcontrol_debug("warning = %d, critical = %d" % (temp_threshold['warning'], temp_threshold['critical'])) + + def is_temp_warning(self): + warning_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + if temp_threshold['temp'] >= temp_threshold['warning']: + warning_flag = True + ledcontrol_debug("%s is over warning" % temp_threshold['name']) + ledcontrol_debug( + "%s = %d, warning = %d" % + (temp_threshold['name'], + temp_threshold['temp'], + temp_threshold['warning'])) + return warning_flag + + def checkTempWarning(self): + try: + if self.is_temp_warning(): + ledcontrol_debug("temp is over warning") + return True + except Exception as e: + ledcontrol_error("%%policy: checkTempWarning failed") + ledcontrol_error(str(e)) + return False + + def is_temp_critical(self): + critical_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['critical_flag'] = False + if temp_threshold['temp'] >= temp_threshold['critical']: + critical_flag = True + temp_threshold['critical_flag'] = True + ledcontrol_debug("%s is over critical" % temp_threshold['name']) + ledcontrol_debug( + "%s = %d, critical = %d" % + (temp_threshold['name'], + temp_threshold['temp'], + temp_threshold['critical'])) + return critical_flag + + def checkTempCrit(self): + try: + if self.is_temp_critical(): + temp_dict = dict(self.__temps_threshold_config) + tmp = temp_dict.get(SWITCH_TEMP) + if tmp['critical_flag'] is True: + ledcontrol_debug("temp is over critical") + return True + + del temp_dict[SWITCH_TEMP] + for temp_items in temp_dict.values(): + if temp_items['critical_flag'] is False: + return False + + ledcontrol_debug("temp is over critical") + return True + except Exception as e: + ledcontrol_error("%%policy: checkTempCrit failed") + ledcontrol_error(str(e)) + return False + + def check_board_air_flow(self): + board_air_flow = self.board_air_flow + air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) + if board_air_flow not in air_flow_tuple: + air_flow_error("%%AIR_FLOW_MONITOR-3-BOARD: Get board air flow failed, value: %s." % board_air_flow) + return False + ledcontrol_debug("board air flow check ok: %s" % board_air_flow) + return True + + def get_monitor_fan_status(self): + fanerrnum = 0 + for fan_obj in self.fan_obj_list: + status = fan_obj.status_summary + ledcontrol_debug("%s status: %s" % (fan_obj.name, status)) + if status != STATUS_OK: + fan_obj.led_status = COLOR_RED + fanerrnum += 1 + else: + fan_obj.led_status = COLOR_GREEN + ledcontrol_debug("fan error number: %d" % fanerrnum) + + if fanerrnum == 0: + fan_led_status = COLOR_GREEN + elif fanerrnum <= self.fan_amber_num: + fan_led_status = COLOR_AMBER + else: + fan_led_status = COLOR_RED + ledcontrol_debug("monitor fan status, set fan led: %s" % LED_STATUS_DICT.get(fan_led_status)) + return fan_led_status + + def get_monitor_psu_status(self): + psuerrnum = 0 + for psu_obj in self.psu_obj_list: + status = psu_obj.status_summary + ledcontrol_debug("%s status: %s" % (psu_obj.name, status)) + if status != STATUS_OK: + psu_obj.led_status = COLOR_RED + psuerrnum += 1 + else: + psu_obj.led_status = COLOR_GREEN + ledcontrol_debug("psu error number: %d" % psuerrnum) + + if psuerrnum == 0: + psu_led_status = COLOR_GREEN + elif psuerrnum <= self.psu_amber_num: + psu_led_status = COLOR_AMBER + else: + psu_led_status = COLOR_RED + ledcontrol_debug("monitor psu status, set psu led: %s" % LED_STATUS_DICT.get(psu_led_status)) + return psu_led_status + + def get_monitor_fan_air_flow(self): + if self.fan_air_flow_monitor == 0: + ledcontrol_debug("fan air flow monitor not open, default green") + return COLOR_GREEN + + ret = self.check_board_air_flow() + if ret is False: + ledcontrol_debug("check board air flow error, skip fan air flow monitor.") + return COLOR_GREEN + + fan_led_status_list = [] + fan_air_flow_ok_obj_list = [] + fan_air_flow_ok_set = set() + fan_module_led_list = [] + fan_air_flow_err_num = 0 + for fan_obj in self.fan_obj_list: + if fan_obj.present != STATUS_PRESENT: + fan_module_led_list.append(COLOR_GREEN) + continue + if fan_obj.air_flow == self.na_ret: + air_flow_warn("%%AIR_FLOW_MONITOR-4-FAN: %s get air flow failed, fan model: %s, air flow: %s." % + (fan_obj.name, fan_obj.display_name, fan_obj.air_flow)) + led_status = COLOR_AMBER + fan_module_led_list.append(led_status) + elif fan_obj.air_flow != self.board_air_flow: + air_flow_emerg("%%AIR_FLOW_MONITOR-0-FAN: %s air flow error, fan model: %s, fan air flow: %s, board air flow: %s." % + (fan_obj.name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow)) + led_status = COLOR_RED + fan_air_flow_err_num += 1 + else: + fan_air_flow_ok_obj_list.append(fan_obj) + fan_air_flow_ok_set.add(fan_obj.origin_name) + ledcontrol_debug("%s air flow check ok, origin name: [%s], display name: [%s], fan air flow: [%s], board air flow: [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow)) + led_status = COLOR_GREEN + fan_module_led_list.append(led_status) + if led_status > fan_obj.led_status: + fan_obj.led_status = led_status + if len(fan_module_led_list) != 0: + fan_led_status = max(fan_module_led_list) + fan_led_status_list.append(fan_led_status) + # check fan mixing + if len(fan_air_flow_ok_set) > 1 and fan_air_flow_ok_set not in self.fan_mix_list: + for fan_obj in fan_air_flow_ok_obj_list: + air_flow_warn("%%AIR_FLOW_MONITOR-4-FAN: %s mixing, fan model: %s, air flow: %s." % + (fan_obj.name, fan_obj.origin_name, fan_obj.air_flow)) + fan_led_status = COLOR_AMBER + fan_led_status_list.append(fan_led_status) + # check fan air flow error number + if fan_air_flow_err_num == 0: + fan_led_status = COLOR_GREEN + elif fan_air_flow_err_num <= self.fan_air_flow_amber_num: + fan_led_status = COLOR_AMBER + else: + fan_led_status = COLOR_RED + fan_led_status_list.append(fan_led_status) + + fan_led_status = max(fan_led_status_list) + ledcontrol_debug("monitor fan air flow, set fan led: %s" % LED_STATUS_DICT.get(fan_led_status)) + return fan_led_status + + def get_monitor_psu_air_flow(self): + if self.psu_air_flow_monitor == 0: + ledcontrol_debug("psu air flow monitor not open, default green") + return COLOR_GREEN + + ret = self.check_board_air_flow() + if ret is False: + ledcontrol_debug("check board air flow error, skip psu air flow monitor.") + return COLOR_GREEN + + psu_led_status_list = [] + psu_module_led_list = [] + psu_air_flow_err_num = 0 + for psu_obj in self.psu_obj_list: + if psu_obj.present != STATUS_PRESENT: + psu_module_led_list.append(COLOR_GREEN) + continue + if psu_obj.air_flow == self.na_ret: + air_flow_warn("%%AIR_FLOW_MONITOR-4-PSU: %s get air flow failed, psu model: %s, air flow: %s." % + (psu_obj.name, psu_obj.display_name, psu_obj.air_flow)) + led_status = COLOR_AMBER + psu_module_led_list.append(led_status) + elif psu_obj.air_flow != self.board_air_flow: + air_flow_emerg("%%AIR_FLOW_MONITOR-0-PSU: %s air flow error, psu model: %s, psu air flow: %s, board air flow: %s." % + (psu_obj.name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow)) + led_status = COLOR_RED + psu_air_flow_err_num += 1 + else: + ledcontrol_debug("%s psu air flow check ok, origin name: [%s], display name: [%s], psu air flow: [%s], board air flow: [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow)) + led_status = COLOR_GREEN + psu_module_led_list.append(led_status) + if led_status > psu_obj.led_status: + psu_obj.led_status = led_status + + if len(psu_module_led_list) != 0: + psu_led_status = max(psu_module_led_list) + psu_led_status_list.append(psu_led_status) + + # check fan air flow error number + if psu_air_flow_err_num == 0: + psu_led_status = COLOR_GREEN + elif psu_air_flow_err_num <= self.psu_air_flow_amber_num: + psu_led_status = COLOR_AMBER + else: + psu_led_status = COLOR_RED + psu_led_status_list.append(psu_led_status) + + psu_led_status = max(psu_led_status_list) + ledcontrol_debug("monitor psu air flow, set psu led: %s" % LED_STATUS_DICT.get(psu_led_status)) + return psu_led_status + + def get_temp_sys_led_status(self): + if self.checkTempCrit() is True: + sys_led_status = COLOR_RED + elif self.checkTempWarning() is True: + sys_led_status = COLOR_AMBER + else: + sys_led_status = COLOR_GREEN + ledcontrol_debug("monitor temperature, set sys led: %s" % LED_STATUS_DICT.get(sys_led_status)) + return sys_led_status + + def get_sys_led_follow_fan_status(self): + + if self.checkfan: + sys_led_status = self.board_fan_led_status + ledcontrol_debug("sys led follow fan led, set sys led: %s" % LED_STATUS_DICT.get(sys_led_status)) + else: + sys_led_status = COLOR_GREEN + ledcontrol_debug("sys led don't follow fan led, set default green") + return sys_led_status + + def get_sys_led_follow_psu_status(self): + if self.checkpsu: + sys_led_status = self.board_psu_led_status + ledcontrol_debug("sys led follow psu led, set sys led: %s" % LED_STATUS_DICT.get(sys_led_status)) + else: + sys_led_status = COLOR_GREEN + ledcontrol_debug("sys led don't follow psu led, set default green") + return sys_led_status + + def dealSysLedStatus(self): + sys_led_status_list = [] + # get_monitor_temp + self.get_monitor_temp() + + # monitor temp get sys led status + sys_led_status = self.get_temp_sys_led_status() + sys_led_status_list.append(sys_led_status) + + # check sys led follow fan led status + sys_led_status = self.get_sys_led_follow_fan_status() + sys_led_status_list.append(sys_led_status) + + # check sys led follow psu led status + sys_led_status = self.get_sys_led_follow_psu_status() + sys_led_status_list.append(sys_led_status) + + sys_led_status = max(sys_led_status_list) + sys_led_color = LED_STATUS_DICT.get(sys_led_status) + + # set sys led + self.set_sys_led(sys_led_color) + + def dealFanLedStatus(self): + fan_led_status_list = [] + # update fan info + self.update_fan_info() + + # monitor fan status first + fan_led_status = self.get_monitor_fan_status() + fan_led_status_list.append(fan_led_status) + + # monitor fan air flow + fan_led_status = self.get_monitor_fan_air_flow() + fan_led_status_list.append(fan_led_status) + + self.board_fan_led_status = max(fan_led_status_list) + fan_led_color = LED_STATUS_DICT.get(self.board_fan_led_status) + + # set fan led + self.set_fan_led(fan_led_color) + # set fan module led + self.set_fan_module_led() + + def dealPsuLedStatus(self): + psu_led_status_list = [] + # update psu info + self.update_psu_info() + + # monitor psu status first + psu_led_status = self.get_monitor_psu_status() + psu_led_status_list.append(psu_led_status) + + # monitor psu air flow + psu_led_status = self.get_monitor_psu_air_flow() + psu_led_status_list.append(psu_led_status) + + self.board_psu_led_status = max(psu_led_status_list) + psu_led_color = LED_STATUS_DICT.get(self.board_psu_led_status) + + # set psu led + self.set_psu_led(psu_led_color) + + def do_ledcontrol(self): + self.dealPsuLedStatus() + self.dealFanLedStatus() + self.dealSysLedStatus() + + def fan_obj_init(self): + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_obj = DevFan(fan_name, self.fan_air_flow_monitor, self.int_case) + self.fan_obj_list.append(fan_obj) + ledcontrol_debug("fan object initialize success") + + def psu_obj_init(self): + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + psu_obj = DevPsu(psu_name, self.psu_air_flow_monitor, self.int_case) + self.psu_obj_list.append(psu_obj) + ledcontrol_debug("psu object initialize success") + + def run(self): + while True: + try: + debug_init() + self.do_ledcontrol() + time.sleep(self.interval) + except Exception as e: + traceback.print_exc() + ledcontrol_error(str(e)) + + +if __name__ == '__main__': + debug_init() + ledcontrol_debug("enter main") + led_control = ledcontrol() + led_control.fan_obj_init() + led_control.psu_obj_init() + led_control.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_pltfm.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_pltfm.py new file mode 100755 index 000000000000..b724e77dcb1f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_pltfm.py @@ -0,0 +1,475 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import inspect +import sys +import json +import time +from plat_hal.interface import interface + + +class Command(): + def __init__(self, name, f): + self.name = name + self.f = f + self.paramcount = self.f.__code__.co_argcount + + def dofun(self, args): + fn = self.f.__call__ + fn(*args) + + +class Group(): + def __init__(self, name, f): + self.groups = [] + self.commands = [] + self.name = name + self.f = f + + def add_groups(self, command): + self.groups.append(command) + + def add_commands(self, commnad): + x = Command(commnad.__name__, commnad) + self.commands.append(x) + + def find_valuebyname(self, name): + for item in self.groups: + if name == item.name: + return item + for item in self.commands: + if name == item.name: + return item + return None + + def deal(self, args): + if len(args) <= 0: + return self.print_help() + funclevel = args[0] + val = self.find_valuebyname(funclevel) + if val is None: + return self.print_help() + if isinstance(val, Command): + if len(args) < (val.paramcount + 1): + return self.print_help() + inputargs = args[1: (1 + val.paramcount)] + return val.dofun(inputargs) + if isinstance(val, Group): + args = args[1:] + return val.deal(args) + return self.print_help() + + def get_max(self, arr): + lentmp = 0 + for ar in arr: + lentmp = len(ar) if (len(ar) > lentmp) else lentmp + return lentmp + + def print_help(self): + + namesize = [] + for item in self.groups: + namesize.append(item.name) + for item in self.commands: + namesize.append(item.name) + maxvalue = self.get_max(namesize) + + if len(self.groups) > 0: + print("Groups:") + for item in self.groups: + print(" %-*s %s" % (maxvalue, item.name, item.f.__doc__ or '')) + if len(self.commands) > 0: + print("Commands:") + for item in self.commands: + print(" %-*s %s" % (maxvalue, item.name, item.f.__doc__ or '')) + + +class clival(): + @staticmethod + def Fire(val=None): + group = Group("top", 'mainlevel') + clival.iterGroup(val, group) + # context = {} + # caller = inspect.stack()[1] + # caller_frame = caller[0] + # caller_globals = caller_frame.f_globals + # caller_locals = caller_frame.f_locals + # context.update(caller_globals) + # context.update(caller_locals) + args = sys.argv[1:] + group.deal(args) + + @staticmethod + def iterGroup(val, group): + for key, item in val.items(): + if item is None: # first level + if inspect.isfunction(key): + group.add_commands(key) + else: + group1 = Group(key.__name__, key) + clival.iterGroup(item, group1) + group.add_groups(group1) + + +def psu(): + r'''test psu ''' + + +def fan(): + r'''test fan ''' + + +def sensor(): + r'''test sensor ''' + + +def dcdc(): + r'''test dcdc ''' + + +def led(): + r'''test led ''' + + +def e2(): + r'''test onie eeprom ''' + + +def temps(): + r'''test temps sensor''' + + +int_case = interface() + + +def get_total_number(): + r'''psu get_total_number ''' + print("=================get_total_number======================") + print(int_case.get_psu_total_number()) + + +def get_presence(): + r'''psu get_presence ''' + print("=================get_presence======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(int_case.get_psu_presence(psu_item.name)) + + +def get_fru_info(): + r'''psu get_fru_info ''' + print("=================get_fru_info======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(json.dumps(int_case.get_psu_fru_info(psu_item.name), ensure_ascii=False, indent=4)) + + +def get_status(): + r'''psu get_status ''' + print("=================get_status======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(json.dumps(int_case.get_psu_status(psu_item.name), ensure_ascii=False, indent=4)) + + +def set_psu_fan_speed_pwm(realspeed): + r'''set_psu_fan_speed_pwm''' + print("=================set_psu_fan_speed_pwm======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(int_case.set_psu_fan_speed_pwm(psu_item.name, int(realspeed))) + + +def get_psu_fan_speed_pwm(): + r'''get_psu_fan_speed_pwm''' + print("=================get_psu_fan_speed_pwm======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(json.dumps(int_case.get_psu_fan_speed_pwm(psu_item.name))) + + +def get_psu_power_status(): + r'''psu get_psu_power_status ''' + print("=================get_psu_power_status======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(json.dumps(int_case.get_psu_power_status(psu_item.name), ensure_ascii=False, indent=4)) + + +def get_info_all(): + r'''psu get_info_all ''' + print("=================get_info_all======================") + print(json.dumps(int_case.get_psu_info_all(), ensure_ascii=False, indent=4)) + + +def fan_get_total_number(): + print("=================get_info_all======================") + print(json.dumps(int_case.get_fan_total_number(), ensure_ascii=False, indent=4)) + + +def fan_get_rotor_number(): + r'''fan_get_rotor_number''' + print("=================fan_get_rotor_number======================") + fans = int_case.get_fans() + for fan_item in fans: + print(fan_item.name, end=' ') + print(int_case.get_fan_rotor_number(fan_item.name)) + + +def fan_get_speed(): + r'''fan_get_speed''' + print("=================fan_get_speed======================") + fans = int_case.get_fans() + for fan_item in fans: + rotors = fan_item.rotor_list + for rotor in rotors: + index = rotors.index(rotor) + print("%s rotor%d" % (fan_item.name, index + 1), end=' ') + print(int_case.get_fan_speed(fan_item.name, index + 1)) + + +def fan_get_speed_pwm(): + r'''fan_get_speed_pwm''' + print("=================fan_get_speed_pwm======================") + fans = int_case.get_fans() + for fan_item in fans: + rotors = fan_item.rotor_list + for rotor in rotors: + index = rotors.index(rotor) + print("%s rotor%d" % (fan_item.name, index + 1), end=' ') + print(int_case.get_fan_speed_pwm(fan_item.name, index + 1)) + + +def fan_set_speed_pwm(pwm): + r'''fan_set_speed_pwm''' + print("=================fan_set_speed_pwm======================") + fans = int_case.get_fans() + for fan_item in fans: + rotors = fan_item.rotor_list + for rotor in rotors: + index = rotors.index(rotor) + print("%s %s" % (fan_item.name, rotor.name), end=' ') + val = int_case.set_fan_speed_pwm(fan_item.name, index + 1, pwm) + print(val) + + +def fan_get_watchdog_status(): + r'''fan_get_watchdog_status''' + print("=================fan_get_watchdog_status======================") + print(int_case.get_fan_watchdog_status()) + + +def fan_enable_watchdog(): + r'''fan_enable_watchdog''' + print("=================fan_enable_watchdog======================") + print('enable', int_case.enable_fan_watchdog()) + + +def fan_disable_watchdog(): + r'''fan_disable_watchdog''' + print("=================fan_disable_watchdog======================") + print('disable', int_case.enable_fan_watchdog(enable=False)) + + +def fan_get_speed1(): + r'''fan_get_speed''' + print("=================fan_get_speed======================") + fans = int_case.get_fans() + for fan_item in fans: + rotors = fan_item.rotor_list + for rotor in rotors: + print("%s %s" % (fan_item.name, rotor.name), end=' ') + print(int_case.get_fan_speed(fan_item.name, rotor.name)) + + +def fan_feed_watchdog(): + r'''fan_feed_watchdog''' + print("=================fan_feed_watchdog======================") + fan_get_speed() + print(int_case.feed_fan_watchdog()) + time.sleep(2) + fan_get_speed() + + +def fan_set_led(color): + r'''fan_set_led''' + print("=================fan_set_led======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(color, int_case.set_fan_led(fan_item.name, color)) + +def fan_get_led(): + r'''fan_get_led''' + print("=================fan_get_led======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(int_case.get_fan_led(fan_item.name)) + + +def fan_get_presence(): + r'''fan_get_presence''' + print("=================fan_get_presence======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(int_case.get_fan_presence(fan_item.name)) + + +def fan_get_fru_info(): + r'''fan_get_fru_info''' + print("=================fan_get_fru_info======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(json.dumps(int_case.get_fan_info(fan_item.name), ensure_ascii=False, indent=4)) + + +def fan_get_status(): + r'''fan_get_status''' + print("=================fan_get_status======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(json.dumps(int_case.get_fan_status(fan_item.name), ensure_ascii=False, indent=4)) + + +def fan_get_info_all(): + r'''fan_get_info_all''' + print("=================fan_get_info_all======================") + print(json.dumps(int_case.get_fan_info_all(), ensure_ascii=False, indent=4)) + + +def get_sensor_info(): + r'''get_sensor_info''' + print("=================get_sensor_info======================") + print(json.dumps(int_case.get_sensor_info(), ensure_ascii=False, indent=4)) + + +def get_dcdc_all_info(): + r'''get_dcdc_all_info''' + print("=================get_dcdc_all_info======================") + print(json.dumps(int_case.get_dcdc_all_info(), ensure_ascii=False, indent=4)) + + +def set_all_led_color(color): + r'''set_all_led_color color''' + print("=================set_all_led_color======================") + leds = int_case.get_leds() + for led_item in leds: + print("%s" % led_item.name) + print(color, int_case.set_led_color(led_item.name, color)) + + +def get_all_led_color(): + r'''get_all_led_color''' + print("=================get_all_led_color======================") + leds = int_case.get_leds() + for led_item in leds: + print("%s" % led_item.name) + print(int_case.get_led_color(led_item.name)) + + +def set_single_led_color(led_name, color): + r'''set_single_led_color led_name color''' + print("=================set_single_led_color======================") + leds = int_case.get_leds() + for led_item in leds: + if led_name == led_item.name: + print("%s" % led_item.name) + print(color, int_case.set_led_color(led_item.name, color)) + + +def get_single_led_color(led_name): + r'''get_single_led_color''' + print("=================get_single_led_color======================") + leds = int_case.get_leds() + for led_item in leds: + if led_name == led_item.name: + print("%s" % led_item.name) + print(int_case.get_led_color(led_item.name)) + + +def get_onie_e2_path(): + r'''get_onie_e2_path''' + print("=================get_onie_e2_path======================") + path = int_case.get_onie_e2_path("ONIE_E2") + print("%s" % path) + + +def get_device_airflow(): + r'''get_device_airflow''' + print("=================get_device_airflow======================") + airflow = int_case.get_device_airflow("ONIE_E2") + print("%s" % airflow) + + +def get_temps_sensor(): + r'''get_temps_sensor''' + print("=================get_temps_sensor======================") + temp_list = int_case.get_temps() + for temp in temp_list: + print("id: %s, name: %s, API name: %s, value: %s" % (temp.temp_id, temp.name, temp.api_name, temp.Value)) + + +def run_cli_man(): + clival.Fire( + { + psu: { + get_total_number: None, + get_presence: None, + get_fru_info: None, + set_psu_fan_speed_pwm: None, + get_psu_fan_speed_pwm: None, + get_status: None, + get_psu_power_status: None, + get_info_all: None + }, + fan: { + fan_get_total_number: None, + fan_get_rotor_number: None, + fan_get_speed: None, + fan_get_speed_pwm: None, + fan_set_speed_pwm: None, + fan_get_watchdog_status: None, + fan_enable_watchdog: None, + fan_disable_watchdog: None, + fan_feed_watchdog: None, + fan_set_led: None, + fan_get_led: None, + fan_get_presence: None, + fan_get_fru_info: None, + fan_get_status: None, + fan_get_info_all: None + }, + sensor: { + get_sensor_info: None + }, + dcdc: { + get_dcdc_all_info: None + }, + led: { + set_all_led_color: None, + set_single_led_color: None, + get_all_led_color: None, + get_single_led_color: None, + }, + e2: { + get_onie_e2_path: None, + get_device_airflow: None, + }, + temps: { + get_temps_sensor: None, + } + } + ) + + +if __name__ == '__main__': + run_cli_man() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor.py new file mode 100755 index 000000000000..33d5bfba64e6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor.py @@ -0,0 +1,144 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +import os +import time +import syslog +from plat_hal.interface import interface +from plat_hal.baseutil import baseutil +from platform_util import io_rd, wbi2cget + +INTELLIGENT_MONITOR_DEBUG_FILE = "/etc/.intelligent_monitor_debug" + +debuglevel = 0 + + +def monitor_syslog_debug(s): + if debuglevel: + syslog.openlog("INTELLIGENT_MONITOR_DEBUG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def monitor_syslog(s): + syslog.openlog("INTELLIGENT_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def pmon_syslog_notice(s): + syslog.openlog("PMON_SYSLOG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_NOTICE, s) + + +class IntelligentMonitor(): + def __init__(self): + self.dcdc_dict = {} + self.int_case = interface() + self.__config = baseutil.get_monitor_config() + self.__intelligent_monitor_para = self.__config.get('intelligent_monitor_para', {}) + self.__interval = self.__intelligent_monitor_para.get('interval', 60) + self.__dcdc_whitelist = self.__config.get('dcdc_monitor_whitelist', {}) + self.__error_ret = self.int_case.error_ret + + @property + def error_ret(self): + return self.__error_ret + + @property + def interval(self): + return self.__interval + + def debug_init(self): + global debuglevel + if os.path.exists(INTELLIGENT_MONITOR_DEBUG_FILE): + debuglevel = 1 + else: + debuglevel = 0 + + def dcdc_whitelist_check(self, dcdc_name): + try: + check_item = self.__dcdc_whitelist.get(dcdc_name, {}) + if len(check_item) == 0: + return False + gettype = check_item.get("gettype", None) + checkbit = check_item.get("checkbit", None) + okval = check_item.get("okval", None) + if gettype is None or checkbit is None or okval is None: + monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s config error. gettype:%s, checkbit:%s, okval:%s' % + (dcdc_name, gettype, checkbit, okval)) + return False + if gettype == "io": + io_addr = check_item.get('io_addr', None) + val = io_rd(io_addr) + if val is not None: + retval = val + else: + monitor_syslog( + '%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s io_rd error. io_addr:%s' % + (dcdc_name, io_addr)) + return False + elif gettype == "i2c": + bus = check_item.get('bus', None) + addr = check_item.get('addr', None) + offset = check_item.get('offset', None) + ind, val = wbi2cget(bus, addr, offset) + if ind is True: + retval = val + else: + monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s i2cget error. bus:%s, addr:%s, offset:%s' % + (dcdc_name, bus, addr, offset)) + return False + else: + monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s gettype not support' % dcdc_name) + return False + + val_t = (int(retval, 16) & (1 << checkbit)) >> checkbit + if val_t != okval: + return False + return True + except Exception as e: + monitor_syslog('%%WHITELIST_CHECK: %s check error, msg: %s.' % (dcdc_name, str(e))) + return False + + def update_dcdc_status(self): + try: + self.dcdc_dict = self.int_case.get_dcdc_all_info() + for dcdc_name, item in self.dcdc_dict.items(): + ret = self.dcdc_whitelist_check(dcdc_name) + if ret is False: + if item['Value'] == self.error_ret: + monitor_syslog( + '%%INTELLIGENT_MONITOR-3-DCDC_SENSOR_FAILED: The value of %s read failed.' % + (dcdc_name)) + elif float(item['Value']) > float(item['Max']): + pmon_syslog_notice('%%PMON-5-VOLTAGE_HIGH: %s voltage %.3f%s is larger than max threshold %.3f%s.' % + (dcdc_name, float(item['Value']), item['Unit'], float(item['Max']), item['Unit'])) + elif float(item['Value']) < float(item['Min']): + pmon_syslog_notice('%%PMON-5-VOLTAGE_LOW: %s voltage %.3f%s is lower than min threshold %.3f%s.' % + (dcdc_name, float(item['Value']), item['Unit'], float(item['Min']), item['Unit'])) + else: + monitor_syslog_debug('%%INTELLIGENT_MONITOR-6-DCDC_SENSOR_OK: %s normal, value is %.3f%s.' % + (dcdc_name, item['Value'], item['Unit'])) + else: + monitor_syslog_debug( + '%%INTELLIGENT_MONITOR-6-DCDC_WHITELIST_CHECK: %s is in dcdc whitelist, not monitor voltage' % + dcdc_name) + continue + except Exception as e: + monitor_syslog('%%INTELLIGENT_MONITOR-3-EXCEPTION: update dcdc sensors status error, msg: %s.' % (str(e))) + + def doWork(self): + self.update_dcdc_status() + + def run(self): + while True: + try: + self.debug_init() + self.doWork() + time.sleep(self.interval) + except Exception as e: + monitor_syslog('%%INTELLIGENT_MONITOR-3-EXCEPTION: %s.' % (str(e))) + + +if __name__ == '__main__': + intelligent_monitor = IntelligentMonitor() + intelligent_monitor.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor/monitor_fan.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor/monitor_fan.py new file mode 100755 index 000000000000..c84319f3b798 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor/monitor_fan.py @@ -0,0 +1,284 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +import os +import time +import logging +from logging.handlers import RotatingFileHandler + +from plat_hal.interface import interface +from plat_hal.baseutil import baseutil + + +DEBUG_FILE = "/etc/.monitor_fan_debug_flag" + +LOG_FILE = "/var/log/intelligent_monitor/monitor_fan_log" + +E2_NAME = "ONIE_E2" + + +def _init_logger(): + if not os.path.exists(LOG_FILE): + os.system("mkdir -p %s" % os.path.dirname(LOG_FILE)) + os.system("sync") + handler = RotatingFileHandler(filename=LOG_FILE, maxBytes=5 * 1024 * 1024, backupCount=1) + formatter = logging.Formatter("%(asctime)s %(levelname)s %(filename)s[%(funcName)s][%(lineno)s]: %(message)s") + handler.setFormatter(formatter) + logger = logging.getLogger(__name__) + logger.setLevel(logging.INFO) + logger.addHandler(handler) + return logger + + +class Fan(object): + + def __init__(self, name, hal_interface): + self.name = name + self.fan_dict = {} + self.int_case = hal_interface + self.update_time = 0 + self.pre_present = False + self.pre_status = True + self.plugin_cnt = 0 + self.plugout_cnt = 0 + self.status_normal_cnt = 0 + self.status_error_cnt = 0 + + def fan_dict_update(self): + local_time = time.time() + if not self.fan_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + self.fan_dict = self.int_case.get_fan_info(self.name) + + def get_model(self): + self.fan_dict_update() + return self.fan_dict["NAME"] + + def get_serial(self): + self.fan_dict_update() + return self.fan_dict["SN"] + + def get_presence(self): + return self.int_case.get_fan_presence(self.name) + + def get_rotor_speed(self, rotor_name): + """ + 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) + """ + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor pwm + value = fan_dir[rotor_name]["Speed"] + max_speed = fan_dir[rotor_name]["SpeedMax"] + + if isinstance(value, str) or value is None: + return 0 + pwm = value * 100 / max_speed + if pwm > 100: + pwm = 100 + elif pwm < 0: + pwm = 0 + return int(pwm) + + def get_rotor_speed_tolerance(self, rotor_name): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + # The default tolerance value is fixed as 30% + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor tolerance + tolerance = fan_dir[rotor_name]["Tolerance"] + + if isinstance(tolerance, str) or tolerance is None: + return 30 + return tolerance + + 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) + """ + pwm = self.int_case.get_fan_speed_pwm(self.name, 0) + return int(pwm) + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + if not self.get_presence(): + return False + + rotor_num = self.int_case.get_fan_rotor_number(self.name) + for i in range(rotor_num): + rotor_name = "Rotor" + str(i + 1) + speed = self.get_rotor_speed(rotor_name) + tolerance = self.get_rotor_speed_tolerance(rotor_name) + target = self.get_target_speed() + if (speed - target) > target * tolerance / 100: + return False + if (target - speed) > target * tolerance / 100: + return False + + return True + + def get_direction(self): + """ + Retrieves the fan airflow direction + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Notes: + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. + """ + self.fan_dict_update() + return self.fan_dict["AirFlow"] + + +class MonitorFan(object): + + def __init__(self): + self.int_case = interface() + self.logger = _init_logger() + self.fan_obj_list = [] + self.__config = baseutil.get_monitor_config() + self.__monitor_fan_config = self.__config.get("monitor_fan_para", {}) + self.__present_interval = self.__monitor_fan_config.get("present_interval", 0.5) + self.__status_interval = self.__monitor_fan_config.get("status_interval", 5) + self.__present_check_cnt = self.__monitor_fan_config.get("present_check_cnt", 3) + self.__status_check_cnt = self.__monitor_fan_config.get("status_check_cnt", 3) + + def debug_init(self): + if os.path.exists(DEBUG_FILE): + self.logger.setLevel(logging.DEBUG) + else: + self.logger.setLevel(logging.INFO) + + def get_fan_total_number(self): + return self.int_case.get_fan_total_number() + + def get_device_airflow(self): + return self.int_case.get_device_airflow(E2_NAME) + + def fan_obj_init(self): + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_obj = Fan(fan_name, self.int_case) + self.fan_obj_list.append(fan_obj) + self.logger.info("fan object initialize success") + + def fan_airflow_check(self, fan_obj): + fan_airflow = fan_obj.get_direction() + device_airflow = self.get_device_airflow() + if fan_airflow != device_airflow: + self.logger.error("%s airflow[%s] not match device airflow[%s]", fan_obj.name, fan_airflow, device_airflow) + else: + self.logger.debug("%s airflow[%s] match device airflow[%s]", fan_obj.name, fan_airflow, device_airflow) + + def fan_plug_in_out_check(self, fan_obj): + present = fan_obj.get_presence() + if present is True: + self.logger.debug("%s is present", fan_obj.name) + else: + self.logger.debug("%s is absent", fan_obj.name) + + if present != fan_obj.pre_present: + if present is True: + fan_obj.plugin_cnt += 1 + fan_obj.plugout_cnt = 0 + if fan_obj.plugin_cnt >= self.__present_check_cnt: + fan_obj.pre_present = True + self.logger.info("%s [serial:%s] is plugin", fan_obj.name, fan_obj.get_serial()) + self.fan_airflow_check(fan_obj) + else: + fan_obj.plugin_cnt = 0 + fan_obj.plugout_cnt += 1 + if fan_obj.plugout_cnt >= self.__present_check_cnt: + fan_obj.pre_present = False + self.logger.info("%s is plugout", fan_obj.name) + else: + fan_obj.plugin_cnt = 0 + fan_obj.plugout_cnt = 0 + self.logger.debug("%s present status is not change", fan_obj.name) + + def fan_status_check(self, fan_obj): + status = fan_obj.get_status() + if status is True: + self.logger.debug("%s is normal", fan_obj.name) + else: + self.logger.debug("%s is error", fan_obj.name) + + if status != fan_obj.pre_status: + if status is True: + fan_obj.status_normal_cnt += 1 + fan_obj.status_error_cnt = 0 + if fan_obj.status_normal_cnt >= self.__status_check_cnt: + fan_obj.pre_status = True + self.logger.info( + "%s [serial:%s] is form error change to normal", + fan_obj.name, + fan_obj.get_serial()) + else: + fan_obj.status_normal_cnt = 0 + fan_obj.status_error_cnt += 1 + if fan_obj.status_error_cnt >= self.__status_check_cnt: + fan_obj.pre_status = False + self.logger.info( + "%s [serial:%s] is form normal change to error", + fan_obj.name, + fan_obj.get_serial()) + else: + fan_obj.status_normal_cnt = 0 + fan_obj.status_error_cnt = 0 + self.logger.debug("%s status is not change", fan_obj.name) + + def checkFanPresence(self): + for fan_obj in self.fan_obj_list: + self.fan_plug_in_out_check(fan_obj) + + def checkFanStatus(self): + for fan_obj in self.fan_obj_list: + self.fan_status_check(fan_obj) + + def run(self): + start_time = time.time() + while True: + try: + self.debug_init() + delta_time = time.time() - start_time + if self.__present_interval <= self.__status_interval: + if delta_time >= self.__status_interval or delta_time < 0: + self.checkFanStatus() + start_time = time.time() + else: + self.checkFanPresence() + time.sleep(self.__present_interval) + else: + if delta_time >= self.__present_interval or delta_time < 0: + self.checkFanPresence() + start_time = time.time() + else: + self.checkFanStatus() + time.sleep(self.__status_interval) + except Exception as e: + self.logger.error('EXCEPTION: %s.', str(e)) + + +if __name__ == '__main__': + monitor_fan = MonitorFan() + monitor_fan.fan_obj_init() + monitor_fan.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_common.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_common.py new file mode 100755 index 000000000000..4fe0beec44d5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_common.py @@ -0,0 +1,178 @@ +#!/usr/bin/python3 + +__all__ = [ + "BLACKLIST_DRIVERS", + "DRIVERLISTS", + "DEVICE", + "STARTMODULE", + "MAC_LED_RESET", + "MAC_DEFAULT_PARAM", + "DEV_MONITOR_PARAM", + "SLOT_MONITOR_PARAM", + "MANUINFO_CONF", + "REBOOT_CTRL_PARAM", + "PMON_SYSLOG_STATUS", + "OPTOE", + "REBOOT_CAUSE_PARA", + "UPGRADE_SUMMARY", + "WARM_UPGRADE_PARAM", + "WARM_UPG_FLAG", + "WARM_UPGRADE_STARTED_FLAG", + "PLATFORM_E2_CONF", + "AIR_FLOW_CONF", + "AIRFLOW_RESULT_FILE", + "INIT_PARAM_PRE", + "INIT_COMMAND_PRE", + "INIT_PARAM", + "INIT_COMMAND", + "MONITOR_TEMP_MIN", + "MONITOR_K", + "MONITOR_MAC_IN", + "MONITOR_DEFAULT_SPEED", + "MONITOR_MAX_SPEED", + "MONITOR_MIN_SPEED", + "MONITOR_MAC_ERROR_SPEED", + "MONITOR_FAN_TOTAL_NUM", + "MONITOR_MAC_UP_TEMP", + "MONITOR_MAC_LOWER_TEMP", + "MONITOR_MAC_MAX_TEMP", + "MONITOR_FALL_TEMP", + "MONITOR_MAC_WARNING_THRESHOLD", + "MONITOR_OUTTEMP_WARNING_THRESHOLD", + "MONITOR_BOARDTEMP_WARNING_THRESHOLD", + "MONITOR_CPUTEMP_WARNING_THRESHOLD", + "MONITOR_INTEMP_WARNING_THRESHOLD", + "MONITOR_MAC_CRITICAL_THRESHOLD", + "MONITOR_OUTTEMP_CRITICAL_THRESHOLD", + "MONITOR_BOARDTEMP_CRITICAL_THRESHOLD", + "MONITOR_CPUTEMP_CRITICAL_THRESHOLD", + "MONITOR_INTEMP_CRITICAL_THRESHOLD", + "MONITOR_CRITICAL_NUM", + "MONITOR_SHAKE_TIME", + "MONITOR_INTERVAL", + "MONITOR_LED_INTERVAL", + "MONITOR_PID_FLAG", + "MONITOR_MAC_SOURCE_SYSFS", + "MONITOR_MAC_SOURCE_PATH", + "MONITOR_PID_MODULE", + "PSU_FAN_FOLLOW", + "MONITOR_SYS_LED", + "MONITOR_SYS_FAN_LED", + "MONITOR_FANS_LED", + "MONITOR_SYS_PSU_LED", + "MONITOR_FAN_STATUS", + "MONITOR_PSU_STATUS", + "MONITOR_DEV_STATUS", + "MONITOR_DEV_STATUS_DECODE", + "DEV_LEDS", + "fanloc" +] + +# driver blacklist parameter +BLACKLIST_DRIVERS = [] + +# driver list parameter +DRIVERLISTS = [] + +# device list parameter +DEVICE = [] + +# start module parameters +STARTMODULE = {} + +# mac led reset parameter +MAC_LED_RESET = {} + +# avscontrol parameter +MAC_DEFAULT_PARAM = [] + +# dev_monitor parameter +DEV_MONITOR_PARAM = {} + +# slot_monitor parameter +SLOT_MONITOR_PARAM = {} + +# platform_manufacturer parameter +MANUINFO_CONF = {} + +# reboot_ctrl parameter +REBOOT_CTRL_PARAM = {} + +# pmon_syslog parameter +PMON_SYSLOG_STATUS = {} + +# sfp optoe device parameter +OPTOE = [] + +# reboot_cause parameter +REBOOT_CAUSE_PARA = [] + +# upgrade parameter +UPGRADE_SUMMARY = {} + +# warm_uprade parameter +WARM_UPGRADE_PARAM = {} +WARM_UPG_FLAG = "/etc/sonic/.warm_upg_flag" +WARM_UPGRADE_STARTED_FLAG = "/etc/sonic/.doing_warm_upg" + +# platform_e2 parameter +PLATFORM_E2_CONF = {} + +# generate_airflow parameter +AIR_FLOW_CONF = {} +AIRFLOW_RESULT_FILE = "/etc/sonic/.airflow" + +# Initialization parameters +INIT_PARAM_PRE = [] +INIT_COMMAND_PRE = [] +INIT_PARAM = [] +INIT_COMMAND = [] + +################################ fancontrol parameter################################### +MONITOR_TEMP_MIN = 38 +MONITOR_K = 11 +MONITOR_MAC_IN = 35 +MONITOR_DEFAULT_SPEED = 0x60 +MONITOR_MAX_SPEED = 0xFF +MONITOR_MIN_SPEED = 0x60 +MONITOR_MAC_ERROR_SPEED = 0XBB +MONITOR_FAN_TOTAL_NUM = 4 +MONITOR_MAC_UP_TEMP = 50 +MONITOR_MAC_LOWER_TEMP = -50 +MONITOR_MAC_MAX_TEMP = 100 # + +MONITOR_FALL_TEMP = 4 +MONITOR_MAC_WARNING_THRESHOLD = 100 +MONITOR_OUTTEMP_WARNING_THRESHOLD = 85 +MONITOR_BOARDTEMP_WARNING_THRESHOLD = 85 +MONITOR_CPUTEMP_WARNING_THRESHOLD = 85 +MONITOR_INTEMP_WARNING_THRESHOLD = 70 + +MONITOR_MAC_CRITICAL_THRESHOLD = 105 +MONITOR_OUTTEMP_CRITICAL_THRESHOLD = 90 +MONITOR_BOARDTEMP_CRITICAL_THRESHOLD = 90 +MONITOR_CPUTEMP_CRITICAL_THRESHOLD = 100 +MONITOR_INTEMP_CRITICAL_THRESHOLD = 80 +MONITOR_CRITICAL_NUM = 3 +MONITOR_SHAKE_TIME = 20 +MONITOR_INTERVAL = 60 +MONITOR_LED_INTERVAL = 2 +MONITOR_PID_FLAG = 0 + +MONITOR_MAC_SOURCE_SYSFS = 0 +MONITOR_MAC_SOURCE_PATH = None + +MONITOR_PID_MODULE = {} + +PSU_FAN_FOLLOW = {} + +MONITOR_SYS_LED = [] +MONITOR_SYS_FAN_LED = [] +MONITOR_FANS_LED = [] +MONITOR_SYS_PSU_LED = [] +MONITOR_FAN_STATUS = [] +MONITOR_PSU_STATUS = [] +MONITOR_DEV_STATUS = {} +MONITOR_DEV_STATUS_DECODE = {} +DEV_LEDS = {} +fanloc = [] diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_config.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_config.py new file mode 100755 index 000000000000..004a64c72233 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_config.py @@ -0,0 +1,184 @@ +#!/usr/bin/python3 + +import sys +import os +from wbutil.baseutil import get_machine_info +from wbutil.baseutil import get_platform_info +from wbutil.baseutil import get_board_id + +__all__ = [ + "MAILBOX_DIR", + "PLATFORM_GLOBALCONFIG", + "GLOBALCONFIG", + "STARTMODULE", + "MAC_LED_RESET", + "MAC_DEFAULT_PARAM", + "DEV_MONITOR_PARAM", + "SLOT_MONITOR_PARAM", + "MANUINFO_CONF", + "REBOOT_CTRL_PARAM", + "PMON_SYSLOG_STATUS", + "REBOOT_CAUSE_PARA", + "UPGRADE_SUMMARY", + "WARM_UPGRADE_PARAM", + "WARM_UPG_FLAG", + "WARM_UPGRADE_STARTED_FLAG", + "PLATFORM_E2_CONF", + "AIR_FLOW_CONF", + "AIRFLOW_RESULT_FILE", + "GLOBALINITPARAM", + "GLOBALINITCOMMAND", + "GLOBALINITPARAM_PRE", + "GLOBALINITCOMMAND_PRE", + "MONITOR_CONST", + "PSU_FAN_FOLLOW", + "MONITOR_SYS_LED", + "MONITOR_FANS_LED", + "MONITOR_SYS_FAN_LED", + "MONITOR_SYS_PSU_LED", + "MONITOR_FAN_STATUS", + "MONITOR_PSU_STATUS", + "MONITOR_DEV_STATUS", + "MONITOR_DEV_STATUS_DECODE", + "DEV_LEDS", + "fanloc" +] + + +def getdeviceplatform(): + x = get_platform_info(get_machine_info()) + if x is not None: + filepath = "/usr/share/sonic/device/" + x + return filepath + return None + + +platform = get_platform_info(get_machine_info()) +board_id = get_board_id(get_machine_info()) +platformpath = getdeviceplatform() +MAILBOX_DIR = "/sys/bus/i2c/devices/" +grtd_productfile = (platform + "_config").replace("-", "_") +common_productfile = "platform_common" +platform_configfile = (platform + "_" + board_id + "_config").replace("-", "_") # platfrom + board_id +configfile_pre = "/usr/local/bin/" +sys.path.append(platformpath) +sys.path.append(configfile_pre) + +############################################################################################ +if os.path.exists(configfile_pre + platform_configfile + ".py"): + module_product = __import__(platform_configfile, globals(), locals(), [], 0) +elif os.path.exists(configfile_pre + grtd_productfile + ".py"): + module_product = __import__(grtd_productfile, globals(), locals(), [], 0) +elif os.path.exists(configfile_pre + common_productfile + ".py"): + module_product = __import__(common_productfile, globals(), locals(), [], 0) +else: + print("config file not exist") + sys.exit(-1) +############################################################################################ + +PLATFORM_GLOBALCONFIG = { + "DRIVERLISTS": module_product.DRIVERLISTS, + "OPTOE": module_product.OPTOE, + "DEVS": module_product.DEVICE, + "BLACKLIST_DRIVERS": module_product.BLACKLIST_DRIVERS +} +GLOBALCONFIG = PLATFORM_GLOBALCONFIG + +# start module parameters +STARTMODULE = module_product.STARTMODULE + +# mac led reset parameter +MAC_LED_RESET = module_product.MAC_LED_RESET + +# avscontrol parameter +MAC_DEFAULT_PARAM = module_product.MAC_DEFAULT_PARAM + +# dev_monitor parameter +DEV_MONITOR_PARAM = module_product.DEV_MONITOR_PARAM + +# slot_monitor parameter +SLOT_MONITOR_PARAM = module_product.SLOT_MONITOR_PARAM + +# platform_manufacturer parameter +MANUINFO_CONF = module_product.MANUINFO_CONF + +# reboot_ctrl parameter +REBOOT_CTRL_PARAM = module_product.REBOOT_CTRL_PARAM + +# pmon_syslog parameter +PMON_SYSLOG_STATUS = module_product.PMON_SYSLOG_STATUS + +# reboot_cause parameter +REBOOT_CAUSE_PARA = module_product.REBOOT_CAUSE_PARA + +# upgrade parameter +UPGRADE_SUMMARY = module_product.UPGRADE_SUMMARY + +# warm_uprade parameter +WARM_UPGRADE_PARAM = module_product.WARM_UPGRADE_PARAM +WARM_UPG_FLAG = module_product.WARM_UPG_FLAG +WARM_UPGRADE_STARTED_FLAG = module_product.WARM_UPGRADE_STARTED_FLAG + +# platform_e2 parameter +PLATFORM_E2_CONF = module_product.PLATFORM_E2_CONF + +# generate_airflow parameter +AIR_FLOW_CONF = module_product.AIR_FLOW_CONF +AIRFLOW_RESULT_FILE = module_product.AIRFLOW_RESULT_FILE + +# Initialization parameters +GLOBALINITPARAM = module_product.INIT_PARAM +GLOBALINITCOMMAND = module_product.INIT_COMMAND +GLOBALINITPARAM_PRE = module_product.INIT_PARAM_PRE +GLOBALINITCOMMAND_PRE = module_product.INIT_COMMAND_PRE + +################################ fancontrol parameter################################### + + +class MONITOR_CONST: + TEMP_MIN = module_product.MONITOR_TEMP_MIN + K = module_product.MONITOR_K + MAC_IN = module_product.MONITOR_MAC_IN + DEFAULT_SPEED = module_product.MONITOR_DEFAULT_SPEED + MAX_SPEED = module_product.MONITOR_MAX_SPEED + MIN_SPEED = module_product.MONITOR_MIN_SPEED + MAC_ERROR_SPEED = module_product.MONITOR_MAC_ERROR_SPEED + FAN_TOTAL_NUM = module_product.MONITOR_FAN_TOTAL_NUM + MAC_UP_TEMP = module_product.MONITOR_MAC_UP_TEMP + MAC_LOWER_TEMP = module_product.MONITOR_MAC_LOWER_TEMP + MAC_MAX_TEMP = module_product.MONITOR_MAC_MAX_TEMP + + MAC_WARNING_THRESHOLD = module_product.MONITOR_MAC_WARNING_THRESHOLD + OUTTEMP_WARNING_THRESHOLD = module_product.MONITOR_OUTTEMP_WARNING_THRESHOLD + BOARDTEMP_WARNING_THRESHOLD = module_product.MONITOR_BOARDTEMP_WARNING_THRESHOLD + CPUTEMP_WARNING_THRESHOLD = module_product.MONITOR_CPUTEMP_WARNING_THRESHOLD + INTEMP_WARNING_THRESHOLD = module_product.MONITOR_INTEMP_WARNING_THRESHOLD + + MAC_CRITICAL_THRESHOLD = module_product.MONITOR_MAC_CRITICAL_THRESHOLD + OUTTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_OUTTEMP_CRITICAL_THRESHOLD + BOARDTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_BOARDTEMP_CRITICAL_THRESHOLD + CPUTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_CPUTEMP_CRITICAL_THRESHOLD + INTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_INTEMP_CRITICAL_THRESHOLD + CRITICAL_NUM = module_product.MONITOR_CRITICAL_NUM + SHAKE_TIME = module_product.MONITOR_SHAKE_TIME + MONITOR_INTERVAL = module_product.MONITOR_INTERVAL + MONITOR_LED_INTERVAL = module_product.MONITOR_LED_INTERVAL + MONITOR_FALL_TEMP = module_product.MONITOR_FALL_TEMP + MONITOR_PID_FLAG = module_product.MONITOR_PID_FLAG + MONITOR_PID_MODULE = module_product.MONITOR_PID_MODULE + + MONITOR_MAC_SOURCE_SYSFS = module_product.MONITOR_MAC_SOURCE_SYSFS + MONITOR_MAC_SOURCE_PATH = module_product.MONITOR_MAC_SOURCE_PATH + + +PSU_FAN_FOLLOW = module_product.PSU_FAN_FOLLOW +MONITOR_SYS_LED = module_product.MONITOR_SYS_LED +MONITOR_FANS_LED = module_product.MONITOR_FANS_LED +MONITOR_SYS_FAN_LED = module_product.MONITOR_SYS_FAN_LED +MONITOR_SYS_PSU_LED = module_product.MONITOR_SYS_PSU_LED +MONITOR_FAN_STATUS = module_product.MONITOR_FAN_STATUS +MONITOR_PSU_STATUS = module_product.MONITOR_PSU_STATUS +MONITOR_DEV_STATUS = module_product.MONITOR_DEV_STATUS +MONITOR_DEV_STATUS_DECODE = module_product.MONITOR_DEV_STATUS_DECODE +DEV_LEDS = module_product.DEV_LEDS +fanloc = module_product.fanloc diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_driver.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_driver.py new file mode 100755 index 000000000000..6d2c6de653d9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_driver.py @@ -0,0 +1,258 @@ +#!/usr/bin/env python3 +import os +import subprocess +import time +import click +from platform_config import GLOBALCONFIG, WARM_UPGRADE_STARTED_FLAG, WARM_UPG_FLAG + + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def log_os_system(cmd): + status, output = subprocess.getstatusoutput(cmd) + if status: + print(output) + return status, output + + +def platform_process_file_check(): + # WARM_UPGRADE_STARTED_FLAG is used as warm_upgrade.py process start flag + if os.path.exists(WARM_UPGRADE_STARTED_FLAG): + os.remove(WARM_UPGRADE_STARTED_FLAG) + + # WARM_UPG_FLAG is used as port related service judgment flag + if os.path.exists(WARM_UPG_FLAG): + os.remove(WARM_UPG_FLAG) + + +def startCommon_operation(): + platform_process_file_check() + + +def check_driver(): + status, output = log_os_system("lsmod | grep wb | wc -l") + if status: + return False + if output.isdigit() and int(output) > 0: + return True + return False + + +def removeDev(bus, loc): + cmd = "echo 0x%02x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (loc, bus) + devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc) + if os.path.exists(devpath): + log_os_system(cmd) + + +def addDev(name, bus, loc): + if name == "lm75": + time.sleep(0.1) + pdevpath = "/sys/bus/i2c/devices/i2c-%d/" % (bus) + for i in range(1, 100): + if os.path.exists(pdevpath) is True: + break + time.sleep(0.1) + if i % 10 == 0: + click.echo("%%WB_PLATFORM_DRIVER-INIT: %s not found, wait 0.1 second ! i %d " % (pdevpath, i)) + + cmd = "echo %s 0x%02x > /sys/bus/i2c/devices/i2c-%d/new_device" % (name, loc, bus) + devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc) + if os.path.exists(devpath) is False: + os.system(cmd) + + +def removeOPTOE(startbus, endbus): + for bus in range(endbus, startbus - 1, -1): + removeDev(bus, 0x50) + + +def addOPTOE(name, startbus, endbus): + for bus in range(startbus, endbus + 1): + addDev(name, bus, 0x50) + + +def removeoptoes(): + optoes = GLOBALCONFIG["OPTOE"] + for index in range(len(optoes) - 1, -1, -1): + removeOPTOE(optoes[index]["startbus"], optoes[index]["endbus"]) + + +def addoptoes(): + optoes = GLOBALCONFIG["OPTOE"] + for optoe in optoes: + addOPTOE(optoe["name"], optoe["startbus"], optoe["endbus"]) + + +def removedevs(): + devs = GLOBALCONFIG["DEVS"] + for index in range(len(devs) - 1, -1, -1): + removeDev(devs[index]["bus"], devs[index]["loc"]) + + +def adddevs(): + devs = GLOBALCONFIG["DEVS"] + for dev in devs: + addDev(dev["name"], dev["bus"], dev["loc"]) + + +def checksignaldriver(name): + modisexistcmd = "lsmod | grep -w %s | wc -l" % name + status, output = log_os_system(modisexistcmd) + if status: + return False + if output.isdigit() and int(output) > 0: + return True + return False + + +def adddriver(name, delay): + cmd = "modprobe %s" % name + if delay != 0: + time.sleep(delay) + if checksignaldriver(name) is not True: + log_os_system(cmd) + + +def removedriver(name, delay, removeable=1): + realname = name.lstrip().split(" ")[0] + cmd = "rmmod -f %s" % realname + if checksignaldriver(realname) and removeable: + log_os_system(cmd) + if delay > 0: + time.sleep(delay) + + +def removedrivers(): + if GLOBALCONFIG is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load global config failed.") + return + drivers = GLOBALCONFIG.get("DRIVERLISTS", None) + if drivers is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load driver list failed.") + return + for index in range(len(drivers) - 1, -1, -1): + delay = 0 + name = "" + removeable = drivers[index].get("removable", 1) + if isinstance(drivers[index], dict) and "delay" in drivers[index]: + name = drivers[index].get("name") + delay = drivers[index]["delay"] + else: + name = drivers[index] + removedriver(name, delay, removeable) + + +def adddrivers(): + if GLOBALCONFIG is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load global config failed.") + return + drivers = GLOBALCONFIG.get("DRIVERLISTS", None) + if drivers is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load driver list failed.") + return + for driver in drivers: + delay = 0 + name = "" + if isinstance(driver, dict) and "delay" in driver: + name = driver.get("name") + delay = driver["delay"] + else: + name = driver + adddriver(name, delay) + + +def blacklist_driver_remove(): + if GLOBALCONFIG is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load global config failed.") + return + blacklist_drivers = GLOBALCONFIG.get("BLACKLIST_DRIVERS", []) + for driver in blacklist_drivers: + delay = 0 + name = "" + if isinstance(driver, dict) and "delay" in driver: + name = driver.get("name") + delay = driver["delay"] + else: + name = driver + removedriver(name, delay) + + +def unload_driver(): + removeoptoes() + removedevs() + removedrivers() + + +def reload_driver(): + removedevs() + removedrivers() + time.sleep(1) + adddrivers() + adddevs() + + +def i2c_check(bus, retrytime=6): + try: + i2cpath = "/sys/bus/i2c/devices/" + bus + while retrytime and not os.path.exists(i2cpath): + click.echo("%%WB_PLATFORM_DRIVER-HA: i2c bus abnormal, last bus %s is not exist." % i2cpath) + reload_driver() + retrytime -= 1 + time.sleep(1) + except Exception as e: + click.echo("%%WB_PLATFORM_DRIVER-HA: %s" % str(e)) + + +def load_driver(): + startCommon_operation() + adddrivers() + adddevs() + addoptoes() + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''device operator''' + + +@main.command() +def start(): + '''load drivers and device ''' + blacklist_driver_remove() + if check_driver(): + unload_driver() + load_driver() + + +@main.command() +def stop(): + '''stop drivers device ''' + unload_driver() + + +@main.command() +def restart(): + '''restart drivers and device''' + unload_driver() + load_driver() + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_e2.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_e2.py new file mode 100755 index 000000000000..808d93216210 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_e2.py @@ -0,0 +1,434 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import click + +from eepromutil.fru import ipmifru +from eepromutil.fantlv import fan_tlv +import eepromutil.onietlv as ot +from platform_config import PLATFORM_E2_CONF +from platform_util import byteTostr, dev_file_read + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +class ExtraFunc(object): + @staticmethod + def decode_mac(encodedata): + if encodedata is None: + return None + ret = ":".join("%02x" % ord(data) for data in encodedata) + return ret.upper() + + @staticmethod + def decode_mac_number(encodedata): + if encodedata is None: + return None + return (ord(encodedata[0]) << 8) | (ord(encodedata[1]) & 0x00ff) + + @staticmethod + @staticmethod + def fru_decode_mac_number(params): + ipmi_fru = params.get("fru") + area = params.get("area") + field = params.get("field") + area_info = getattr(ipmi_fru, area, None) + if area_info is not None: + raw_mac_number = getattr(area_info, field, None) + mac_number = decode_mac_number(raw_mac_number) + ipmi_fru.setValue(area, field, mac_number) + + @staticmethod + def fru_decode_mac(params): + ipmi_fru = params.get("fru") + area = params.get("area") + field = params.get("field") + area_info = getattr(ipmi_fru, area, None) + if area_info is not None: + raw_mac = getattr(area_info, field, None) + decoded_mac = decode_mac(raw_mac) + ipmi_fru.setValue(area, field, decoded_mac) + + @staticmethod + def fru_decode_hw(params): + ipmi_fru = params.get("fru") + area = params.get("area") + field = params.get("field") + area_info = getattr(ipmi_fru, area, None) + if area_info is not None: + raw_hw = getattr(area_info, field, None) + decode_hw = str(int(raw_hw, 16)) + ipmi_fru.setValue(area, field, decode_hw) + + +def set_onie_value(params): + onie = params.get("onie") + field = params.get("field") + config_value = params.get("config_value") + for index, onie_item in enumerate(onie): + if onie_item.get("name") == field: + if "value" in onie_item.keys(): + onie[index]["value"] = config_value + + +def onie_eeprom_decode(onie, e2_decode): + for e2_decode_item in e2_decode: + field = e2_decode_item.get("field") + decode_type = e2_decode_item.get("decode_type") + if decode_type == 'func': + params = { + "onie": onie, + "field": field + } + func_name = e2_decode_item.get("func_name") + if func_name is not None: + run_func(func_name, params) + elif decode_type == 'config': + config_value = e2_decode_item.get("config_value") + if config_value is not None: + params = { + "onie": onie, + "field": field, + "config_value": config_value + } + set_onie_value(params) + else: + print("unsupport decode type") + continue + + +def onie_eeprom_show(eeprom, e2_decode=None): + try: + onietlv = ot.onie_tlv() + rets = onietlv.decode(eeprom) + if e2_decode is not None: + onie_eeprom_decode(rets, e2_decode) + print("%-20s %-5s %-5s %-20s" % ("TLV name", "Code", "lens", "Value")) + for item in rets: + if item["code"] == 0xfd: + print("%-20s 0x%-02X %-5s" % (item["name"], item["code"], item["lens"])) + else: + print("%-20s 0x%-02X %-5s %-20s" % (item["name"], item["code"], item["lens"], item["value"])) + except Exception as e: + print(str(e)) + + +def set_fantlv_value(params): + fantlv_dict = params.get("fantlv") + field = params.get("field") + config_value = params.get("config_value") + for index, fantlv_item in enumerate(fantlv_dict): + if fantlv_item.get("name") == field: + if "value" in fantlv_item.keys(): + fantlv_dict[index]["value"] = config_value + + +def fantlv_eeprom_decode(fantlv_dict, e2_decode): + for e2_decode_item in e2_decode: + field = e2_decode_item.get("field") + decode_type = e2_decode_item.get("decode_type") + if decode_type == 'func': + params = { + "fantlv": fantlv_dict, + "field": field + } + func_name = e2_decode_item.get("func_name") + if func_name is not None: + run_func(func_name, params) + elif decode_type == 'config': + config_value = e2_decode_item.get("config_value") + if config_value is not None: + params = { + "fantlv": fantlv_dict, + "field": field, + "config_value": config_value + } + set_fantlv_value(params) + else: + print("unsupport decode type") + continue + + +def fantlv_eeprom_show(eeprom, e2_decode=None): + try: + tlv = fan_tlv() + rets = tlv.decode(eeprom) + if len(rets) == 0: + print("fan tlv eeprom info error.!") + return + if e2_decode is not None: + fantlv_eeprom_decode(rets, e2_decode) + print("%-15s %-5s %-5s %-20s" % ("TLV name", "Code", "lens", "Value")) + for item in rets: + print("%-15s 0x%-02X %-5s %-20s" % (item["name"], item["code"], item["lens"], item["value"])) + except Exception as e: + print(str(e)) + return + + +def run_func(funcname, params): + try: + func = getattr(ExtraFunc, funcname) + func(params) + except Exception as e: + print(str(e)) + +def set_fru_value(params): + ipmi_fru = params.get("fru") + area = params.get("area") + field = params.get("field") + config_value = params.get("config_value") + ipmi_fru.setValue(area, field, config_value) + + +def fru_eeprom_decode(ipmi_fru, e2_decode): + for e2_decode_item in e2_decode: + area = e2_decode_item.get("area") + field = e2_decode_item.get("field") + decode_type = e2_decode_item.get("decode_type") + if decode_type == 'func': + params = { + "fru": ipmi_fru, + "area": area, + "field": field + } + func_name = e2_decode_item.get("func_name") + if func_name is not None: + run_func(func_name, params) + elif decode_type == 'config': + config_value = e2_decode_item.get("config_value") + if config_value is not None: + params = { + "fru": ipmi_fru, + "area": area, + "field": field, + "config_value": config_value + } + set_fru_value(params) + else: + print("unsupport decode type") + continue + + +def fru_eeprom_show(eeprom, e2_decode=None): + try: + ipmi_fru = ipmifru() + ipmi_fru.decodeBin(eeprom) + if e2_decode is not None: + fru_eeprom_decode(ipmi_fru, e2_decode) + print("=================board=================") + print(ipmi_fru.boardInfoArea) + print("=================product=================") + print(ipmi_fru.productInfoArea) + except Exception as e: + print(str(e)) + + +def eeprom_parase(eeprom_conf): + name = eeprom_conf.get("name") + e2_type = eeprom_conf.get("e2_type") + e2_path = eeprom_conf.get("e2_path") + e2_size = eeprom_conf.get("e2_size", 256) + e2_decode = eeprom_conf.get("e2_decode") + print("===================%s===================" % name) + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + print("eeprom read error, eeprom path: %s, msg: %s" % (e2_path, binval_bytes)) + return + binval = byteTostr(binval_bytes) + if e2_type == "onie_tlv": + onie_eeprom_show(binval, e2_decode) + elif e2_type == "fru": + fru_eeprom_show(binval, e2_decode) + elif e2_type == "fantlv": + fantlv_eeprom_show(binval, e2_decode) + else: + print("Unknow eeprom type: %s" % e2_type) + return + + +def get_fans_eeprom_info(param): + fan_eeprom_conf = PLATFORM_E2_CONF.get("fan", []) + fan_num = len(fan_eeprom_conf) + if fan_num == 0: + print("fan number is 0, can't get fan eeprom info") + return + if param == 'all': + for conf in fan_eeprom_conf: + eeprom_parase(conf) + return + if not param.isdigit(): + print("param error, %s is not digital or 'all'" % param) + return + fan_index = int(param, 10) - 1 + if fan_index < 0 or fan_index >= fan_num: + print("param error, total fan number: %d, fan index: %d" % (fan_num, fan_index + 1)) + return + eeprom_parase(fan_eeprom_conf[fan_index]) + return + + +def get_psus_eeprom_info(param): + psu_eeprom_conf = PLATFORM_E2_CONF.get("psu", []) + psu_num = len(psu_eeprom_conf) + if psu_num == 0: + print("psu number is 0, can't get psu eeprom info") + return + if param == 'all': + for conf in psu_eeprom_conf: + eeprom_parase(conf) + return + if not param.isdigit(): + print("param error, %s is not digital or 'all'" % param) + return + psu_index = int(param, 10) - 1 + if psu_index < 0 or psu_index >= psu_num: + print("param error, total psu number: %d, psu index: %d" % (psu_num, psu_index + 1)) + return + eeprom_parase(psu_eeprom_conf[psu_index]) + return + + +def get_slots_eeprom_info(param): + slot_eeprom_conf = PLATFORM_E2_CONF.get("slot", []) + slot_num = len(slot_eeprom_conf) + if slot_num == 0: + print("slot number is 0, can't get slot eeprom info") + return + if param == 'all': + for conf in slot_eeprom_conf: + eeprom_parase(conf) + return + if not param.isdigit(): + print("param error, %s is not digital or 'all'" % param) + return + slot_index = int(param, 10) - 1 + if slot_index < 0 or slot_index >= slot_num: + print("param error, total slot number: %d, slot index: %d" % (slot_num, slot_index + 1)) + return + eeprom_parase(slot_eeprom_conf[slot_index]) + return + + +def get_syseeprom_info(param): + syseeprom_conf = PLATFORM_E2_CONF.get("syseeprom", []) + syseeprom_num = len(syseeprom_conf) + if syseeprom_num == 0: + print("syseeprom number is 0, can't get syseeprom info") + return + if param == 'all': + for conf in syseeprom_conf: + eeprom_parase(conf) + return + if not param.isdigit(): + print("param error, %s is not digital or 'all'" % param) + return + syseeprom_index = int(param, 10) - 1 + if syseeprom_index < 0 or syseeprom_index >= syseeprom_num: + print("param error, total syseeprom number: %d, syseeprom index: %d" % (syseeprom_num, syseeprom_index + 1)) + return + eeprom_parase(syseeprom_conf[syseeprom_index]) + return + + +def decode_eeprom_info(e2_type, e2_path, e2_size): + if not e2_size.isdigit(): + print("param error, e2_size %s is not digital" % e2_size) + return + e2_size = int(e2_size, 10) + eeprom_conf = {} + eeprom_conf["name"] = e2_type + eeprom_conf["e2_type"] = e2_type + eeprom_conf["e2_path"] = e2_path + eeprom_conf["e2_size"] = e2_size + eeprom_parase(eeprom_conf) + return + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''platform eeprom display script''' + +# fan eeprom info display + + +@main.command() +@click.argument('fan_index', required=True) +def fan(fan_index): + '''fan_index(1, 2, 3...)/all''' + get_fans_eeprom_info(fan_index) + +# psu eeprom info display + + +@main.command() +@click.argument('psu_index', required=True) +def psu(psu_index): + '''psu_index(1, 2, 3...)/all''' + get_psus_eeprom_info(psu_index) + +# slot eeprom info display + + +@main.command() +@click.argument('slot_index', required=True) +def slot(slot_index): + '''slot_index(1, 2, 3...)/all''' + get_slots_eeprom_info(slot_index) + +# syseeprom info display + + +@main.command() +@click.argument('syseeprom_index', required=True) +def syseeprom(syseeprom_index): + '''syseeprom_index(1, 2, 3...)/all''' + get_syseeprom_info(syseeprom_index) + +# fru eeprom info decode + + +@main.command() +@click.argument('e2_path', required=True) +@click.argument('e2_size', required=False, default="256") +def fru(e2_path, e2_size): + '''e2_path''' + decode_eeprom_info("fru", e2_path, e2_size) + +# fantlv eeprom info decode + + +@main.command() +@click.argument('e2_path', required=True) +@click.argument('e2_size', required=False, default="256") +def fantlv(e2_path, e2_size): + '''e2_path''' + decode_eeprom_info("fantlv", e2_path, e2_size) + +# onie_tlv eeprom info decode + + +@main.command() +@click.argument('e2_path', required=True) +@click.argument('e2_size', required=False, default="256") +def onie_tlv(e2_path, e2_size): + '''e2_path''' + decode_eeprom_info("onie_tlv", e2_path, e2_size) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_intf.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_intf.py new file mode 100755 index 000000000000..2143b9420cd3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_intf.py @@ -0,0 +1,367 @@ +#!/usr/bin/env python3 +import os +import syslog +import importlib.machinery +from platform_util import getplatform_name, dev_file_read, dev_file_write, write_sysfs, read_sysfs + +__all__ = [ + "platform_reg_read", + "platform_reg_write", + "platform_set_optoe_type", + "platform_get_optoe_type", + "platform_sfp_read", + "platform_sfp_write", +] + +CPLD = 0 +FPGA = 1 +CPLD_PATH = "/dev/cpld%d" +FPGA_PATH = "/dev/fpga%d" + + +OPTOE_PATH = "/sys/bus/i2c/devices/%d-0050/" +OPTOE_DEV_CLASS = "dev_class" +OPTOE_EEPROM = "eeprom" + + +PLATFORM_INTF_DEBUG_FILE = "/etc/.platform_intf_debug_flag" + + +CONFIG_FILE_LIST = [ + "/usr/local/bin/", + "/usr/local/lib/python3/dist-packages/config/", + "/usr/local/lib/python3.7/dist-packages/config/", + "/usr/local/lib/python3.9/dist-packages/config/"] + + +def platform_intf_debug(s): + if os.path.exists(PLATFORM_INTF_DEBUG_FILE): + syslog.openlog("PLATFORM_INTF_DEBUG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def platform_intf_error(s): + if os.path.exists(PLATFORM_INTF_DEBUG_FILE): + syslog.openlog("PLATFORM_INTF_ERROR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +class IntfPlatform: + CONFIG_NAME = 'PLATFORM_INTF_OPTOE' + __port_optoe_dict = {} + + def __init__(self): + real_path = None + platform_name = (getplatform_name()).replace("-", "_") + for configfile_path in CONFIG_FILE_LIST: + configfile = configfile_path + platform_name + "_port_config.py" + if os.path.exists(configfile): + real_path = configfile + break + if real_path is None: + raise Exception("get port config error") + config = importlib.machinery.SourceFileLoader(self.CONFIG_NAME, real_path).load_module() + self.__port_optoe_dict = config.PLATFORM_INTF_OPTOE + + def get_dev_path(self, dev_type, dev_id): + if dev_type == CPLD: + path = CPLD_PATH % dev_id + elif dev_type == FPGA: + path = FPGA_PATH % dev_id + else: + msg = "dev_type error!" + return False, msg + platform_intf_debug("path:%s" % path) + return True, path + + def get_port_path(self, port): + port_num = self.__port_optoe_dict.get("port_num", 0) + optoe_start_bus = self.__port_optoe_dict.get("optoe_start_bus", 0) + if port_num <= 0 or optoe_start_bus <= 0: + msg = "PLATFORM_INTF_OPTOE config error!" + return False, msg + if port <= 0 or port > port_num: + msg = "port out of range !" + return False, msg + path = OPTOE_PATH % (port + optoe_start_bus - 1) + platform_intf_debug("path:%s" % path) + return True, path + + ########################################### + # reg_read - read logic device register + # @dev_type: 0: CPLD, 1: FPGA + # @dev_id: device ID, start from 0 + # @offset: register offset + # @size: read length + # return: + # @ret: True if read success, False if not + # @info: The read value list if read success, otherwise the detail error message + ########################################### + def reg_read(self, dev_type, dev_id, offset, size): + ret, path = self.get_dev_path(dev_type, dev_id) + if ret is False: + return False, path + ret, info = dev_file_read(path, offset, size) + return ret, info + + ########################################### + # platform_reg_write - write logic device register + # @dev_type: 0: CPLD, 1: FPGA + # @dev_id: device ID, start from 0 + # @offset: register offset + # @val_list: The write value list + # return: + # @ret: True if write success, False if not + # @info: The write value length if write success, otherwise the detail error message + ########################################### + def reg_write(self, dev_type, dev_id, offset, val_list): + ret, path = self.get_dev_path(dev_type, dev_id) + if ret is False: + return False, path + ret, info = dev_file_write(path, offset, val_list) + return ret, info + + ########################################### + # set_optoe_type - set port optoe type + # @port: port index start from 1 + # @optoe_type: optoe type, including the following values + # 1: OPTOE1 + # 2: OPTOE2 + # 3: OPTOE3 + # return: + # @ret: True if set optoe type success, False if not + # @info: None if set optoe type success, otherwise the detail error message + ########################################### + def set_optoe_type(self, port, optoe_type): + ret, path = self.get_port_path(port) + if ret is False: + return False, path + optoe_type_path = path + OPTOE_DEV_CLASS + ret, info = write_sysfs(optoe_type_path, "%d" % optoe_type) + if ret is False: + return False, info + return True, None + + ########################################### + # get_optoe_type - get port optoe type + # @port: port index start from 1 + # return: + # @ret: True if set optoe type success, False if not + # @info: Optoe type value if get optoe type success, otherwise the detail error message + # optoe type including the following values + # 1: OPTOE1 + # 2: OPTOE2 + # 3: OPTOE3 + ########################################### + def get_optoe_type(self, port): + ret, path = self.get_port_path(port) + if ret is False: + return False, path + optoe_type_path = path + OPTOE_DEV_CLASS + ret, info = read_sysfs(optoe_type_path) + if ret is False: + return False, info + return True, int(info) + + ########################################### + # sfp_read -read sfp eeprom + # @port_id: port index start from 1 + # @offset: sfp eeprom offset + # @size: read sfp eeprom length + # return: + # @ret: True if read success, False if not + # @info: The read value list if read success, otherwise the detail error message + ########################################### + def sfp_read(self, port_id, offset, size): + ret, path = self.get_port_path(port_id) + if ret is False: + return False, path + optoe_eeprom_path = path + OPTOE_EEPROM + ret, info = dev_file_read(optoe_eeprom_path, offset, size) + return ret, info + + ########################################### + # sfp_write -write sfp eeprom + # @port_id: port index start from 1 + # @offset: sfp eeprom offset + # @val_list: The write value list + # return: + # @ret: True if read success, False if not + # @info: The write value length if write success, otherwise the detail error message + ########################################### + def sfp_write(self, port_id, offset, val_list): + ret, path = self.get_port_path(port_id) + if ret is False: + return False, path + optoe_eeprom_path = path + OPTOE_EEPROM + ret, info = dev_file_write(optoe_eeprom_path, offset, val_list) + return ret, info + + +platform = IntfPlatform() + + +########################################### +# platform_reg_read - read logic device register +# @dev_type: 0: CPLD, 1: FPGA +# @dev_id: device ID, start from 0 +# @offset: register offset +# @size: read length +# return: +# @ret: True if read success, False if not +# @info: The read value list if read success, otherwise the detail error message +########################################### +def platform_reg_read(dev_type, dev_id, offset, size): + ret = False + info = None + + # params check + if (isinstance(dev_type, int) is False or isinstance(dev_id, int) is False or + isinstance(offset, int) is False or isinstance(size, int) is False): + info = "params type check fail in platform_reg_read" + return ret, info + if dev_id < 0 or offset < 0 or size <= 0: + info = "params value check fail in platform_reg_read" + return ret, info + support_dev_type = (CPLD, FPGA) + if dev_type not in support_dev_type: + info = "dev_type match erro, fail in platform_reg_read" + return ret, info + + # call the solve func + return platform.reg_read(dev_type, dev_id, offset, size) + + +########################################### +# platform_reg_write - write logic device register +# @dev_type: 0: CPLD, 1: FPGA +# @dev_id: device ID, start from 0 +# @offset: register offset +# @val_list: The write value list +# return: +# @ret: True if write success, False if not +# @info: The write value length if write success, otherwise the detail error message +########################################### +def platform_reg_write(dev_type, dev_id, offset, val_list): + ret = False + info = None + + # params check + if (isinstance(dev_type, int) is False or isinstance(dev_id, int) is False or + isinstance(offset, int) is False or isinstance(val_list, list) is False): + info = "params type check fail in platform_reg_write" + return ret, info + if dev_id < 0 or offset < 0 or len(val_list) <= 0: + info = "params value check fail in platform_reg_write" + return ret, info + support_dev_type = (CPLD, FPGA) + if dev_type not in support_dev_type: + info = "dev_type match erro, fail in platform_reg_write" + return ret, info + + # call the solve func + return platform.reg_write(dev_type, dev_id, offset, val_list) + + +########################################### +# platform_set_optoe_type - set port optoe type +# @port: port index start from 1 +# @optoe_type: optoe type, including the following values +# 1: OPTOE1 +# 2: OPTOE2 +# 3: OPTOE3 +# return: +# @ret: True if set optoe type success, False if not +# @info: None if set optoe type success, otherwise the detail error message +########################################### +def platform_set_optoe_type(port, optoe_type): + ret = False + info = None + + # params check + if isinstance(port, int) is False or isinstance(optoe_type, int) is False: + info = "params type check fail in platform_set_optoe_type" + return ret, info + if port < 0 or optoe_type < 1 or optoe_type > 3: + info = "params value check fail in platform_set_optoe_type" + return ret, info + + # call the solve func + return platform.set_optoe_type(port, optoe_type) + + +########################################### +# platform_get_optoe_type - get port optoe type +# @port: port index start from 1 +# return: +# @ret: True if set optoe type success, False if not +# @info: Optoe type value if get optoe type success, otherwise the detail error message +# optoe type including the following values +# 1: OPTOE1 +# 2: OPTOE2 +# 3: OPTOE3 +########################################### +def platform_get_optoe_type(port): + ret = False + info = None + + # params check + if isinstance(port, int) is False: + info = "params type check fail in platform_get_optoe_type" + return ret, info + if port < 0: + info = "params value check fail in platform_get_optoe_type" + return ret, info + + # call the solve func + return platform.get_optoe_type(port) + + +########################################### +# platform_sfp_read -read sfp eeprom +# @port_id: port index start from 1 +# @offset: sfp eeprom offset +# @size: read sfp eeprom length +# return: +# @ret: True if read success, False if not +# @info: The read value list if read success, otherwise the detail error message +########################################### +def platform_sfp_read(port_id, offset, size): + ret = False + info = None + + # params check + if isinstance(port_id, int) is False or isinstance(offset, int) is False or isinstance(size, int) is False: + info = "params type check fail in platform_sfp_read" + return ret, info + if port_id < 0 or offset < 0 or size <= 0: + info = "params value check fail in platform_sfp_read" + return ret, info + + # call the solve func + return platform.sfp_read(port_id, offset, size) + + +########################################### +# platform_sfp_write -write sfp eeprom +# @port_id: port index start from 1 +# @offset: sfp eeprom offset +# @val_list: The write value list +# return: +# @ret: True if read success, False if not +# @info: The write value length if write success, otherwise the detail error message +########################################### +def platform_sfp_write(port_id, offset, val_list): + ret = False + info = None + + # params check + if isinstance(port_id, int) is False or isinstance(offset, int) is False or isinstance(val_list, list) is False: + info = "params type check fail in platform_sfp_write" + return ret, info + if port_id < 0 or offset < 0 or len(val_list) <= 0: + info = "params value check fail in platform_sfp_write" + return ret, info + + # call the solve func + return platform.sfp_write(port_id, offset, val_list) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_ipmi.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_ipmi.py new file mode 100755 index 000000000000..c9b72c99cca9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_ipmi.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import sys +import os +import syslog +import click +from platform_util import exec_os_cmd + + +IPMITOOL_CMD = "ipmitool raw 0x32 0x04" # All products are the same command + +PLATFORM_IPMI_DEBUG_FILE = "/etc/.platform_ipmi_debug_flag" +UPGRADEDEBUG = 1 +debuglevel = 0 + + +def debug_init(): + global debuglevel + if os.path.exists(PLATFORM_IPMI_DEBUG_FILE): + debuglevel = debuglevel | UPGRADEDEBUG + else: + debuglevel = debuglevel & ~(UPGRADEDEBUG) + + +def ipmidebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if UPGRADEDEBUG & debuglevel: + syslog.openlog("PLATFORM_IPMI", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def ipmierror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("PLATFORM_IPMI", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +@click.command() +@click.argument('cmd', required=True) +def platform_ipmi_main(cmd): + '''Send command to BMC through ipmi''' + try: + # Convert string command to ASCII + user_cmd = "" + for ch in cmd: + user_cmd += " " + str(ord(ch)) + + final_cmd = IPMITOOL_CMD + user_cmd + ipmidebuglog("final cmd:%s" % final_cmd) + + # exec ipmitool cmd + status, output = exec_os_cmd(final_cmd) + if status: + ipmierror("exec ipmitool_cmd:%s user_cmd:%s failed" % (IPMITOOL_CMD, cmd)) + ipmierror("failed log: %s" % output) + return False, "exec final_cmd failed" + + # the data read by ipmitool is hex value, needs transformation + data_list = output.replace("\n", "").strip(' ').split(' ') + ipmidebuglog("data_list: %s" % data_list) + result = "" + for data in data_list: + result += chr(int(data, 16)) + + # 'result' string include ret and log, separated by , + result_list = result.split(',', 2) + if len(result_list) != 2: + log = "split failed. len(result) != 2. result:%s" % result + ipmierror(log) + return False, log + if int(result_list[0]) != 0: + ipmierror("finally analy ipmitool_cmd:%s user_cmd:%s exec failed" % (IPMITOOL_CMD, cmd)) + ipmierror("failed return log: %s" % result_list[1]) + print(result_list[1]) + return False, result_list[1] + + ipmidebuglog("finally exec ipmitool_cmd:%s user_cmd:%s success" % (IPMITOOL_CMD, cmd)) + print(result_list[1]) + return True, result_list[1] + + except Exception as e: + log = "An exception occurred, exception log:%s" % str(e) + ipmierror(log) + return False, log + + +if __name__ == '__main__': + debug_init() + ret, msg = platform_ipmi_main() + if ret is False: + sys.exit(1) + sys.exit(0) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_manufacturer.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_manufacturer.py new file mode 100755 index 000000000000..1404692bc93b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_manufacturer.py @@ -0,0 +1,591 @@ +#!/usr/bin/env python3 + +import re +import mmap +import fcntl +import subprocess +import shlex +import signal +import os +import time +import sys +from platform_config import MANUINFO_CONF +from monitor import status + + +INDENT = 4 + + +def printerr(vchar): + sys.stderr.write(vchar + '\n') + + +g_extra_cache = {} +g_meminfo_cache = {} +g_exphy_cache = {} + + +def exec_os_cmd(cmd, timeout = None): + status, output = subprocess.getstatusoutput(cmd) + return status, output + + +def exphyfwsplit(): + # improve performance + global g_exphy_cache + if g_exphy_cache: + return + cmd = "bcmcmd -t 1 \"phy control xe,ce fw_get\" |grep fw_version" + ret, output = exec_os_cmd(cmd) + if ret or len(output) == 0: + raise Exception("run cmd: {} error, status: {}, msg: {}".format(cmd, ret, output)) + exphyfwstr = output.strip() + portlist = exphyfwstr.split("\n") + for port in portlist: + phy_addr_str = get_regular_val(port, r"phy_addr\s*=\s*\w+", 0) + if phy_addr_str.startswith("ERR"): + continue + phy_addr_key = phy_addr_str.replace(" ", "") + if phy_addr_key in g_exphy_cache: + continue + + g_exphy_cache[phy_addr_key] = {} + + fw_version_str = get_regular_val(port, r"fw_version\s*=\s*\w+", 0) + if fw_version_str.startswith("ERR"): + del g_exphy_cache[phy_addr_key] + continue + + fw_version = fw_version_str.split("=")[1].strip() + g_exphy_cache[phy_addr_key]["fw_version"] = fw_version + + if "success" in port: + ret = "OK" + else: + ret = "Unexpected" + g_exphy_cache[phy_addr_key]["status"] = ret + return + + +def lshwmemorysplit(): + # improve performance + global g_meminfo_cache + if g_meminfo_cache: + return + cmd = "lshw -c memory" + ret, output = exec_os_cmd(cmd) + if ret or len(output) == 0: + raise Exception("run cmd: {} error, status: {}, msg: {}".format(cmd, ret, output)) + memstr = output.strip() + memlist = memstr.split("*-") + for item in memlist: + if item.strip().startswith("memory") and "System Memory" not in item: + continue + line_index = 0 + for line in item.splitlines(): + line_index += 1 + if line_index == 1: + memdict_key = line + g_meminfo_cache[memdict_key] = {} + else: + if ":" not in line: + continue + key = line.split(":", 1)[0].strip() + value = line.split(":", 1)[1].strip() + g_meminfo_cache[memdict_key][key] = value + if "empty" in item: + break + return + + +def run_extra_func(funcname): + # improve performance + if funcname in g_extra_cache: + return g_extra_cache.get(funcname) + func = getattr(status, funcname) + ret = [] + func(ret) + if ret: + g_extra_cache[funcname] = ret + return ret + + +def get_extra_value(funcname, itemid, key): + for item in run_extra_func(funcname): + if item.get("id") == itemid: + return item.get(key, "NA") + return "NA" + + +def io_wr(reg_addr, reg_data): + try: + regdata = 0 + regaddr = 0 + if isinstance(reg_addr, int): + regaddr = reg_addr + else: + regaddr = int(reg_addr, 16) + if isinstance(reg_data, int): + regdata = reg_data + else: + regdata = int(reg_data, 16) + devfile = "/dev/port" + fd = os.open(devfile, os.O_RDWR | os.O_CREAT) + os.lseek(fd, regaddr, os.SEEK_SET) + os.write(fd, regdata.to_bytes(1, 'little')) + return True + except ValueError as e: + print(e) + return False + except Exception as e: + print(e) + return False + finally: + os.close(fd) + + +def checksignaldriver(name): + modisexistcmd = "lsmod | grep -w %s | wc -l" % name + ret, output = exec_os_cmd(modisexistcmd) + if ret: + return False + if output.isdigit() and int(output) > 0: + return True + return False + + +def adddriver(name): + cmd = "modprobe %s" % name + if checksignaldriver(name) is not True: + ret, log = exec_os_cmd(cmd) + if ret != 0 or len(log) > 0: + return False + return True + return True + + +def removedriver(name): + cmd = "rmmod %s" % name + if checksignaldriver(name): + exec_os_cmd(cmd) + + +def add_5387_driver(): + errmsg = "" + spi_gpio = "wb_spi_gpio" + ret = adddriver(spi_gpio) + if ret is False: + errmsg = "modprobe wb_spi_gpio driver failed." + return False, errmsg + spi_5387_device = "wb_spi_93xx46 spi_bus_num=0" + ret = adddriver(spi_5387_device) + if ret is False: + errmsg = "modprobe wb_spi_93xx46 driver failed." + return ret, errmsg + return True, "" + + +def remove_5387_driver(): + spi_5387_device = "wb_spi_93xx46" + removedriver(spi_5387_device) + spi_gpio = "wb_spi_gpio" + removedriver(spi_gpio) + + +def deal_itmes(item_list): + for item in item_list: + dealtype = item.get("dealtype") + if dealtype == "shell": + cmd = item.get("cmd") + timeout = item.get("timeout", 10) + exec_os_cmd(cmd, timeout) + elif dealtype == "io_wr": + io_addr = item.get("io_addr") + wr_value = item.get("value") + io_wr(io_addr, wr_value) + + +def get_func_value(funcname, params): + func = getattr(ExtraFunc, funcname) + ret = func(params) + return ret + + +def read_pci_reg(pcibus, slot, fn, resource, offset): + '''read pci register''' + if offset % 4 != 0: + return "ERR offset: %d not 4 bytes align" + filename = "/sys/bus/pci/devices/0000:%02x:%02x.%x/resource%d" % (int(pcibus), int(slot), int(fn), int(resource)) + size = os.path.getsize(filename) + with open(filename, "r+") as file: + data = mmap.mmap(file.fileno(), size) + result = data[offset: offset + 4] + s = result[::-1] + val = 0 + for value in s: + val = val << 8 | value + data.close() + return "%08x" % val + + +def devfileread(path, offset, length, bit_width): + ret = "" + val_str = '' + val_list = [] + fd = -1 + if not os.path.exists(path): + return "%s not found !" % path + if length % bit_width != 0: + return "only support read by bit_width" + if length < bit_width: + return "len needs to greater than or equal to bit_width" + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, length) + for item in ret: + val_list.append(item) + + for i in range(0, length, bit_width): + val_str += " 0x" + for j in range(0, bit_width): + val_str += "%02x" % val_list[i + bit_width - j - 1] + except Exception as e: + return str(e) + finally: + if fd > 0: + os.close(fd) + return val_str + + +def read_reg(loc, offset, size): + with open(loc, 'rb') as file: + file.seek(offset) + return ' '.join(["%02x" % item for item in file.read(size)]) + + +def std_match(stdout, pattern): + if pattern is None: + return stdout.strip() + for line in stdout.splitlines(): + if re.match(pattern, line): + return line.strip() + raise EOFError("pattern: {} does not match anything in stdout {}".format( + pattern, stdout)) + + +def i2c_rd(bus, loc, offset): + ''' + read i2c with i2cget command + ''' + cmd = "i2cget -f -y {} {} {}".format(bus, loc, offset) + retrytime = 6 + for i in range(retrytime): + ret, stdout = subprocess.getstatusoutput(cmd) + if ret == 0: + return stdout + time.sleep(0.1) + raise RuntimeError("run cmd: {} error, status {}".format(cmd, ret)) + + +def i2c_rd_bytes(bus, loc, offset, size): + blist = [] + for i in range(size): + ret = i2c_rd(bus, loc, offset + i) + blist.append(ret) + + return blist + + +def get_pair_val(source, separator): + try: + value = source.split(separator, 1)[1] + except (ValueError, IndexError): + return "ERR separator: {} does not match in source: {}".format(separator, source) + return value.strip() + + +def get_regular_val(source, pattern, group): + try: + value = re.findall(pattern, source)[group] + except Exception: + return "ERR pattern: {} does not match in source: {} with group: {}".format(pattern, source, group) + return value.strip() + + +def find_match(file2read, pattern): + with open(file2read, 'r') as file: + for line in file: + if not re.match(pattern, line): + continue + return line.strip() + return "ERR pattern %s not match in %s" % (pattern, file2read) + + +def readaline(file2read): + with open(file2read, 'r') as file: + return file.readline() + + +def sort_key(e): + return e.arrt_index + + +class ExtraFunc(object): + @staticmethod + def get_bcm5387_version(params): + version = "" + try: + ret, msg = add_5387_driver() + if ret is False: + raise Exception(msg) + + before_deal_list = params.get("before", []) + deal_itmes(before_deal_list) + + ret, version = exec_os_cmd(params["get_version"]) + if ret != 0: + version = "ERR " + version + + after_deal_list = params.get("after", []) + deal_itmes(after_deal_list) + + except Exception as e: + version = "ERR %s" % (str(e)) + finally: + finally_deal_list = params.get("finally", []) + deal_itmes(finally_deal_list) + remove_5387_driver() + return version + + @staticmethod + def get_memory_value(params): + root_key = params.get("root_key") + sub_key = params.get("sub_key") + lshwmemorysplit() + return g_meminfo_cache.get(root_key, {}).get(sub_key, "NA") + + @staticmethod + def get_memory_bank_value(params): + lshwmemorysplit() + bank = params.get("bankid") + if g_meminfo_cache.get(bank, {}): + return True + return False + + @staticmethod + def get_exphy_fw(phyid): + exphyfwsplit() + if phyid not in g_exphy_cache: + return "ERR %s not found." % phyid + fw_version = g_exphy_cache.get(phyid).get("fw_version") + ret = g_exphy_cache.get(phyid).get("status") + msg = "%s %s" % (fw_version, ret) + return msg + +class CallbackSet: + def cpld_format(self, blist): + if isinstance(blist, str): + blist = blist.split() + elif not isinstance(blist, list) or len(blist) != 4: + raise ValueError("cpld format: wrong parameter: {}".format(blist)) + + return "{}{}{}{}".format(*blist).replace("0x", "") + + +class VersionHunter: + call = CallbackSet() + + def __init__(self, entires): + self.head = None + self.next = None + self.key = None + self.cmd = None + self.file = None + self.reg = None + self.i2c = None + self.extra = None + self.pattern = None + self.separator = None + self.parent = None + self.ignore = False + self.children = [] + self.level = 0 + self.callback = None + self.delspace = None + self.arrt_index = None + self.config = None + self.precheck = None + self.func = None + self.regular = None + self.group = 0 + self.pci = None + self.devfile = None + self.decode = None + self.timeout = 10 + self.__dict__.update(entires) + + def check_para(self): + if self.pattern is None: + return False + if self.cmd is None or self.file is None: + return False + return True + + def get_version(self): + ret = "NA" + try: + if self.cmd is not None: + ret, output = exec_os_cmd(self.cmd, self.timeout) + if ret or len(output) == 0: + raise RuntimeError("run cmd: {} error, status: {}, msg: {}".format(self.cmd, ret, output)) + ret = std_match(output, self.pattern) + elif self.file is not None: + ret = self.read_file() + elif self.reg is not None: + ret = read_reg(self.reg.get("loc"), self.reg.get("offset"), + self.reg.get("size")) + elif self.extra: + ret = get_extra_value(self.extra.get("funcname"), + self.extra.get("id"), + self.extra.get("key")) + elif self.i2c: + ret = i2c_rd_bytes(self.i2c.get("bus"), self.i2c.get("loc"), + self.i2c.get("offset"), + self.i2c.get("size")) + elif self.config: + ret = self.config + elif self.func: + ret = get_func_value(self.func.get("funcname"), + self.func.get("params")) + elif self.pci: + ret = read_pci_reg(self.pci.get("bus"), self.pci.get("slot"), + self.pci.get("fn"), self.pci.get("bar"), self.pci.get("offset")) + elif self.devfile: + ret = devfileread(self.devfile.get("loc"), self.devfile.get("offset"), + self.devfile.get("len"), self.devfile.get("bit_width")) + + except Exception as e: + # printerr(e.message) + return "ERR %s" % str(e) + return self.exe_callback(ret) + + def exe_callback(self, data): + try: + if self.callback: + method = getattr(self.call, self.callback) + return method(data) + except Exception: + return "ERR run callback method: {} error, data: {}".format(self.callback, data) + return data + + def read_file(self): + if self.pattern is not None: + return find_match(self.file, self.pattern) + return readaline(self.file) + + def hunt(self): + if self.ignore: + return + indent = self.level * INDENT * " " + + if self.precheck: + try: + ret = get_func_value(self.precheck.get("funcname"), self.precheck.get("params")) + if ret is not True: + return + except Exception as e: + err_msg = "ERR %s" % str(e) + format_str = "{}{:<{}}{}".format(indent, self.key + ':', + (30 - len(indent)), err_msg) + print(format_str) + return + # has children + if self.children: + self.children.sort(key=sort_key) + format_str = "{}{}:".format(indent, self.key) + print(format_str) + for child in self.children: + if not isinstance(child, VersionHunter): + continue + child.level = self.level + 1 + child.hunt() + else: + version = self.get_version() or "" + if not version.startswith("ERR"): + version = version.replace("\x00", "").strip() + if self.separator is not None: + version = get_pair_val(version, self.separator) + if self.delspace is not None: + version = version.replace(" ", "") + if self.regular is not None: + version = get_regular_val(version, self.regular, self.group) + if self.decode is not None: + tmp_version = self.decode.get(version) + if tmp_version is None: + version = "ERR decode %s failed" % version + else: + version = tmp_version + format_str = "{}{:<{}}{}".format(indent, self.key + ':', + (30 - len(indent)), version) + print(format_str) + + if self.next: + print("") + self.next.hunt() + + +pidfile = 0 + + +def ApplicationInstance(): + global pidfile + pidfile = open(os.path.realpath(__file__), "r") + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + return True + except Exception: + return False + + +def run(): + if os.geteuid() != 0: + print("Root privileges are required for this operation") + sys.exit(1) + + start_time = time.time() + while True: + ret = ApplicationInstance() + if ret is True: + break + if time.time() - start_time > 10: + printerr("manufacturer is running.") + sys.exit(1) + time.sleep(0.5) + + objmap = {} + + try: + target = {} + target.update(MANUINFO_CONF) + for objname, value in target.items(): + objmap[objname] = VersionHunter(value) + except Exception as e: + printerr(str(e)) + sys.exit(1) + + head = None + for objname, obj in objmap.items(): + if head is None and obj.head: + head = obj + if obj.parent: + objmap.get(obj.parent).children.append(obj) + if obj.next: + obj.next = objmap.get(obj.next) + + head.hunt() + + +if __name__ == "__main__": + run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_process.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_process.py new file mode 100755 index 000000000000..75bc95975520 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_process.py @@ -0,0 +1,396 @@ +#!/usr/bin/env python3 +import os +import subprocess +import glob +import time +import click +from platform_config import STARTMODULE, MAC_LED_RESET, AIRFLOW_RESULT_FILE +from platform_config import GLOBALINITPARAM, GLOBALINITCOMMAND, GLOBALINITPARAM_PRE, GLOBALINITCOMMAND_PRE +from platform_util import wbpciwr + + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def log_os_system(cmd): + status, output = subprocess.getstatusoutput(cmd) + if status: + print(output) + return status, output + + +def write_sysfs_value(reg_name, value): + mb_reg_file = "/sys/bus/i2c/devices/" + reg_name + locations = glob.glob(mb_reg_file) + if len(locations) == 0: + print("%s not found" % mb_reg_file) + return False + sysfs_loc = locations[0] + try: + with open(sysfs_loc, 'w') as fd: + fd.write(value) + except Exception: + return False + return True + + +def getPid(name): + ret = [] + for dirname in os.listdir('/proc'): + if dirname == 'curproc': + continue + try: + with open('/proc/{}/cmdline'.format(dirname), mode='r') as fd: + content = fd.read() + except Exception: + continue + if name in content: + ret.append(dirname) + return ret + + +def startAvscontrol(): + if STARTMODULE.get('avscontrol', 0) == 1: + cmd = "nohup avscontrol.py start >/dev/null 2>&1 &" + rets = getPid("avscontrol.py") + if len(rets) == 0: + os.system(cmd) + + +def startFanctrol(): + if STARTMODULE.get('fancontrol', 0) == 1: + cmd = "nohup fancontrol.py start >/dev/null 2>&1 &" + rets = getPid("fancontrol.py") + if len(rets) == 0: + os.system(cmd) + + +def starthal_fanctrl(): + if STARTMODULE.get('hal_fanctrl', 0) == 1: + cmd = "nohup hal_fanctrl.py start >/dev/null 2>&1 &" + rets = getPid("hal_fanctrl.py") + if len(rets) == 0: + os.system(cmd) + + +def starthal_ledctrl(): + if STARTMODULE.get('hal_ledctrl', 0) == 1: + cmd = "nohup hal_ledctrl.py start >/dev/null 2>&1 &" + rets = getPid("hal_ledctrl.py") + if len(rets) == 0: + os.system(cmd) + + +def startDevmonitor(): + if STARTMODULE.get('dev_monitor', 0) == 1: + cmd = "nohup dev_monitor.py start >/dev/null 2>&1 &" + rets = getPid("dev_monitor.py") + if len(rets) == 0: + os.system(cmd) + + +def startSlotmonitor(): + if STARTMODULE.get('slot_monitor', 0) == 1: + cmd = "nohup slot_monitor.py start >/dev/null 2>&1 &" + rets = getPid("slot_monitor.py") + if len(rets) == 0: + os.system(cmd) + + +def startIntelligentmonitor(): + if STARTMODULE.get('intelligent_monitor', 0) == 1: + cmd = "nohup intelligent_monitor.py >/dev/null 2>&1 &" + rets = getPid("intelligent_monitor.py") + if len(rets) == 0: + os.system(cmd) + + +def startSignalmonitor(): + if STARTMODULE.get('signal_monitor', 0) == 1: + cmd = "nohup signal_monitor.py start >/dev/null 2>&1 &" + rets = getPid("signal_monitor.py") + if len(rets) == 0: + os.system(cmd) + + +def startSff_temp_polling(): + if STARTMODULE.get('sff_temp_polling', 0) == 1: + cmd = "nohup sfp_highest_temperatue.py >/dev/null 2>&1 &" + rets = getPid("sfp_highest_temperatue.py") + if len(rets) == 0: + os.system(cmd) + + +def startRebootCause(): + if STARTMODULE.get('reboot_cause', 0) == 1: + cmd = "nohup reboot_cause.py >/dev/null 2>&1 &" + rets = getPid("reboot_cause.py") + if len(rets) == 0: + os.system(cmd) + + +def startPMON_sys(): + if STARTMODULE.get('pmon_syslog', 0) == 1: + cmd = "nohup pmon_syslog.py >/dev/null 2>&1 &" + rets = getPid("pmon_syslog.py") + if len(rets) == 0: + os.system(cmd) + + +def startSff_polling(): + if STARTMODULE.get('sff_polling', 0) == 1: + cmd = "nohup sff_polling.py start > /dev/null 2>&1 &" + rets = getPid("sff_polling.py") + if len(rets) == 0: + os.system(cmd) + + +def generate_air_flow(): + cmd = "nohup generate_airflow.py > /dev/null 2>&1 &" + rets = getPid("generate_airflow.py") + if len(rets) == 0: + os.system(cmd) + time.sleep(1) + + +def startGenerate_air_flow(): + if STARTMODULE.get('generate_airflow', 0) == 1: + for i in range(10): + generate_air_flow() + if os.path.exists(AIRFLOW_RESULT_FILE): + click.echo("%%WB_PLATFORM_PROCESS: generate air flow success") + return + time.sleep(1) + click.echo("%%WB_PLATFORM_PROCESS: generate air flow,failed, %s not exits" % AIRFLOW_RESULT_FILE) + return + + +def start_tty_console(): + if STARTMODULE.get('tty_console', 0) == 1: + cmd = "nohup tty_console.py > /dev/null 2>&1 &" + rets = getPid("tty_console.py") + if len(rets) == 0: + os.system(cmd) + + +def stopAvscontrol(): + if STARTMODULE.get('avscontrol', 0) == 1: + rets = getPid("avscontrol.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopFanctrol(): + if STARTMODULE.get('fancontrol', 0) == 1: + rets = getPid("fancontrol.py") # + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stophal_fanctrl(): + if STARTMODULE.get('hal_fanctrl', 0) == 1: + rets = getPid("hal_fanctrl.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stophal_ledctrl(): + if STARTMODULE.get('hal_ledctrl', 0) == 1: + rets = getPid("hal_ledctrl.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopDevmonitor(): + if STARTMODULE.get('dev_monitor', 0) == 1: + rets = getPid("dev_monitor.py") # + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopSlotmonitor(): + if STARTMODULE.get('slot_monitor', 0) == 1: + rets = getPid("slot_monitor.py") # + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopIntelligentmonitor(): + if STARTMODULE.get('intelligent_monitor', 0) == 1: + rets = getPid("intelligent_monitor.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopSignalmonitor(): + if STARTMODULE.get('signal_monitor', 0) == 1: + rets = getPid("signal_monitor.py") # + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopSff_temp_polling(): + if STARTMODULE.get('sff_temp_polling', 0) == 1: + rets = getPid("sfp_highest_temperatue.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopPMON_sys(): + if STARTMODULE.get('pmon_syslog', 0) == 1: + rets = getPid("pmon_syslog.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopRebootCause(): + if STARTMODULE.get('reboot_cause', 0) == 1: + rets = getPid("reboot_cause.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopSff_polling(): + if STARTMODULE.get('sff_polling', 0) == 1: + rets = getPid("sff_polling.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopGenerate_air_flow(): + if STARTMODULE.get('generate_airflow', 0) == 1: + rets = getPid("generate_airflow.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stop_tty_console(): + if STARTMODULE.get('tty_console', 0) == 1: + rets = getPid("tty_console.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def otherinit(): + for index in GLOBALINITPARAM: + write_sysfs_value(index["loc"], index["value"]) + + for index in GLOBALINITCOMMAND: + log_os_system(index) + + +def otherinit_pre(): + for index in GLOBALINITPARAM_PRE: + write_sysfs_value(index["loc"], index["value"]) + + for index in GLOBALINITCOMMAND_PRE: + log_os_system(index) + + +def unload_apps(): + stopSff_polling() + stopPMON_sys() + stopSignalmonitor() + stopIntelligentmonitor() + stopSlotmonitor() + stopDevmonitor() + stopAvscontrol() + stophal_ledctrl() + stophal_fanctrl() + stopFanctrol() + stopSff_temp_polling() + stopRebootCause() + stop_tty_console() + stopGenerate_air_flow() + + +def MacLedSet(data): + '''write pci register''' + pcibus = MAC_LED_RESET.get("pcibus") + slot = MAC_LED_RESET.get("slot") + fn = MAC_LED_RESET.get("fn") + resource = MAC_LED_RESET.get("bar") + offset = MAC_LED_RESET.get("offset") + val = MAC_LED_RESET.get(data, None) + if val is None: + click.echo("%%WB_PLATFORM_PROCESS-INIT: MacLedSet wrong input") + return + wbpciwr(pcibus, slot, fn, resource, offset, val) + + +def load_apps(): + otherinit_pre() + startGenerate_air_flow() + start_tty_console() + startRebootCause() + startSff_temp_polling() + startFanctrol() + starthal_fanctrl() + starthal_ledctrl() + startAvscontrol() + startDevmonitor() + startSlotmonitor() + startIntelligentmonitor() + startSignalmonitor() + startPMON_sys() + startSff_polling() + otherinit() + if STARTMODULE.get("macledreset", 0) == 1: + MacLedSet("reset") + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''device operator''' + + +@main.command() +def start(): + '''load process ''' + load_apps() + + +@main.command() +def stop(): + '''stop process ''' + unload_apps() + + +@main.command() +def restart(): + '''restart process''' + unload_apps() + load_apps() + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_sensors.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_sensors.py new file mode 100755 index 000000000000..1727242b74b9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_sensors.py @@ -0,0 +1,253 @@ +#!/usr/bin/python3 + +import os +import sys +import importlib.machinery + + +def get_machine_info(): + if not os.path.isfile('/host/machine.conf'): + return None + machine_vars = {} + with open('/host/machine.conf') as machine_file: + for line in machine_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + machine_vars[tokens[0]] = tokens[1].strip() + return machine_vars + + +def get_platform_info(machine_info): + if machine_info is not None: + if 'onie_platform' in machine_info: + return machine_info['onie_platform'] + if 'aboot_platform' in machine_info: + return machine_info['aboot_platform'] + return None + + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +PLATFORM_SPECIFIC_MODULE_NAME = 'monitor' +PLATFORM_SPECIFIC_CLASS_NAME = 'status' +platform_status_class = None +platform = None + + +def get_platform_name(): + global platform + platform = get_platform_info(get_machine_info()) + return platform + + +val = get_platform_name() +sys.path.append("/".join([PLATFORM_ROOT_PATH, platform])) + +# Loads platform specific sfputil module from source + + +def load_platform_monitor(): + global platform_status_class + platform_name = get_platform_info(get_machine_info()) + platform_path = "/".join([PLATFORM_ROOT_PATH, platform_name]) + try: + module_file = "/".join([platform_path, PLATFORM_SPECIFIC_MODULE_NAME + ".py"]) + module = importlib.machinery.SourceFileLoader(PLATFORM_SPECIFIC_MODULE_NAME, module_file).load_module() + except IOError: + return -1 + try: + platform_status_class = getattr(module, PLATFORM_SPECIFIC_CLASS_NAME) + except AttributeError: + return -2 + return 0 + + +def printerr(msg): + print("\033[0;31m%s\033[0m" % msg) + + +def print_console(msg): + print(msg) + + +val_t = load_platform_monitor() +if val_t != 0: + raise Exception("load monitor.py error") + + +def print_platform(): + platform_info = get_platform_name() + print_console(platform_info) + print_console("") + + +def print_cputemp_sensors(): + val_ret = get_call_value_by_function("getcputemp") + print_info_str = "" + toptile = "Onboard coretemp Sensors:" + formatstr = " {name:<20} : {temp} C (high = {max} C , crit = {crit} C )" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + print_info_str += formatstr.format(**item) + '\n' + print_console(print_info_str) + + +def print_boardtemp(): + val_ret = get_call_value_by_function("getTemp") + print_info_str = "" + toptile = "Onboard Temperature Sensors:" + errformat = " {id:<20} : {errmsg}" + formatstr = " {id:<20} : {temp1_input} C (high = {temp1_max} C, hyst = {temp1_max_hyst} C)" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + realformat = formatstr if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + '\n' + print_console(print_info_str) + + +def print_mactemp_sensors(): + val_ret = get_call_value_by_function("getmactemp") + print_info_str = "" + toptile = "Onboard MAC Temperature Sensors:" + errformat = " {id:<20} : {errmsg}" + formatstr = " {id:<20} : {temp_input} C" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + realformat = formatstr if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + '\n' + print_console(print_info_str) + + +def print_macpower_sensors(): + val_ret = get_call_value_by_function("getmacpower") + print_info_str = "" + toptile = "Onboard MAC Power Sensors:" + errformat = " {id:<20} : {errmsg}" + formatstr = " {id:<20} : {power_input} W" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + realformat = formatstr if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + '\n' + print_console(print_info_str) + + +def print_fan_sensor(): + val_ret = get_call_value_by_function("checkFan") + print_info_str = "" + toptile = "Onboard fan Sensors:" + errformat = " {id} : {errmsg}\n" # " {id:<20} : {errmsg}" + fan_signle_rotor_format = " {id} : \n" \ + " fan_type :{fan_type}\n" \ + " sn :{sn}\n" \ + " hw_version:{hw_version}\n" \ + " Speed :{Speed} RPM\n" \ + " status :{errmsg} \n" + fan_double_rotor_format = " {id} : \n" \ + " fan_type :{fan_type}\n" \ + " sn :{sn}\n" \ + " hw_version:{hw_version}\n" \ + " Speed :\n" \ + " speed_front :{rotor1_speed:<5} RPM\n" \ + " speed_rear :{rotor2_speed:<5} RPM\n" \ + " status :{errmsg} \n" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + if item.get('Speed', None) is None: + realformat = fan_double_rotor_format if item.get('errcode', 0) == 0 else errformat + else: + realformat = fan_signle_rotor_format if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + print_console(print_info_str) + + +def print_psu_sensor(): + val_ret = get_call_value_by_function("getPsu") + print_info_str = "" + toptile = "Onboard Power Supply Unit Sensors:" + errformat = " {id} : {errmsg}\n" # " {id:<20} : {errmsg}" + psuformat = " {id} : \n" \ + " type :{type1}\n" \ + " sn :{sn}\n" \ + " in_current :{in_current} A\n" \ + " in_voltage :{in_voltage} V\n" \ + " out_current:{out_current} A\n" \ + " out_voltage:{out_voltage} V\n" \ + " temp :{temp} C \n" \ + " fan_speed :{fan_speed} RPM\n" \ + " in_power :{in_power} W\n" \ + " out_power :{out_power} W\n" + + if len(val_ret) != 0: + print_info_str += toptile + '\r\n' + for item in val_ret: + realformat = psuformat if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + print_console(print_info_str) + + +def print_slot_sensor(): + val_ret = get_call_value_by_function("checkSlot") + print_info_str = "" + toptile = "Onboard slot Sensors:" + errformat = " {id} : {errmsg}\n" # " {id:<20} : {errmsg}" + psuformat = " {id} : \n" \ + " slot_type :{slot_type}\n" \ + " sn :{sn}\n" \ + " hw_version :{hw_version} \n" \ + " status :{errmsg}\n" + + if len(val_ret) != 0: + print_info_str += toptile + '\r\n' + for item in val_ret: + realformat = psuformat if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + print_console(print_info_str) + + +def print_boarddcdc(): + val_ret = get_call_value_by_function("getDcdc") + print_info_str = "" + toptile = "Onboard DCDC Sensors:" + errformat = " {id:<26} : {errmsg}" + formatstr = " {id:<26} : {dcdc_input:<6} {dcdc_unit:<1} (Min = {dcdc_min:<6} {dcdc_unit:<1}, Max = {dcdc_max:<6} {dcdc_unit:<1})" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + realformat = formatstr if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + '\n' + print_console(print_info_str) + + +def get_call_value_by_function(function_name): + valtemp = [] + if hasattr(platform_status_class, function_name): + test2_func = getattr(platform_status_class, function_name) + test2_func(valtemp) + return valtemp + + +def getsensors(): + print_platform() + print_cputemp_sensors() + print_boardtemp() + print_mactemp_sensors() + print_macpower_sensors() + print_fan_sensor() + print_psu_sensor() + print_slot_sensor() + print_boarddcdc() + + +if __name__ == "__main__": + getsensors() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_test.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_test.py new file mode 100755 index 000000000000..da7119a9ce49 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_test.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- + +try: + import click + from platform_intf import platform_reg_read, platform_reg_write, platform_get_optoe_type + from platform_intf import platform_set_optoe_type, platform_sfp_read, platform_sfp_write +except ImportError as error: + raise ImportError('%s - required module not found' % str(error)) from error + + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def print_reg(info, offset): + try: + size = len(info) + j = offset % 16 + tmp = j + offset -= j + print_buf = "\n " + + for i in range(16): + print_buf = print_buf + "%2x " % i + print(print_buf) + + print_buf = None + for i in range(size + j): + if i % 16 == 0: + print_buf = "" + print_buf = "0x%08x " % offset + offset = offset + 16 + if tmp: + print_buf = print_buf + " " + tmp = tmp - 1 + else: + print_buf = print_buf + "%02x " % info[i - j] + if (i + 1) % 16 == 0 or i == size + j - 1: + print(print_buf) + except Exception as e: + msg = str(e) + print("i = %d, j = %d," % (i, j)) + print(msg) + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''platform_test main''' + + +@main.command() +@click.argument('dev_type', required=True) +@click.argument('dev_id', required=True) +@click.argument('offset', required=True) +@click.argument('size', required=True) +def reg_rd(dev_type, dev_id, offset, size): + '''read cpld/fpga reg''' + ret, info = platform_reg_read(int(dev_type), int(dev_id), int(offset), int(size)) + print(ret) + if ret is True: + print_reg(info, int(offset)) + else: + print(info) + + +@main.command() +@click.argument('dev_type', required=True) +@click.argument('dev_id', required=True) +@click.argument('offset', required=True) +@click.argument('value', required=True) +def reg_wr(dev_type, dev_id, offset, value): + '''write cpld/fpga reg''' + value_list = [] + value_list.append(int(value)) + ret, info = platform_reg_write(int(dev_type), int(dev_id), int(offset), value_list) + print(ret) + print(info) + + +@main.command() +@click.argument('port', required=True) +def get_optoe_type(port): + '''get optoe type''' + ret, info = platform_get_optoe_type(int(port)) + print(ret) + print(info) + + +@main.command() +@click.argument('port', required=True) +@click.argument('optoe_type', required=True) +def set_optoe_type(port, optoe_type): + '''set optoe type''' + ret, info = platform_set_optoe_type(int(port), int(optoe_type)) + print(ret) + print(info) + + +@main.command() +@click.argument('port_id', required=True) +@click.argument('offset', required=True) +@click.argument('size', required=True) +def sfp_rd(port_id, offset, size): + '''read sfp''' + ret, info = platform_sfp_read(int(port_id), int(offset), int(size)) + print(ret) + if ret is True: + print_reg(info, int(offset)) + else: + print(info) + + +@main.command() +@click.argument('port_id', required=True) +@click.argument('offset', required=True) +@click.argument('value', required=True) +def sfp_wr(port_id, offset, value): + '''write sfp''' + value_list = [] + value_list.append(int(value)) + ret, info = platform_sfp_write(int(port_id), int(offset), value_list) + print(ret) + print(info) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_util.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_util.py new file mode 100755 index 000000000000..e7e6c8b1d6eb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_util.py @@ -0,0 +1,845 @@ +#!/usr/bin/python3 + +import sys +import os +import re +import subprocess +import shlex +import time +import mmap +import glob +import logging.handlers +import shutil +import gzip +import ast + + +CONFIG_DB_PATH = "/etc/sonic/config_db.json" +MAILBOX_DIR = "/sys/bus/i2c/devices/" + + +__all__ = [ + "strtoint", + "byteTostr", + "getplatform_name", + "wbi2cget", + "wbi2cset", + "wbpcird", + "wbpciwr", + "wbi2cgetWord", + "wbi2csetWord", + "wbi2cset_pec", + "wbi2cset_wordpec", + "wbsysset", + "dev_file_read", + "dev_file_write", + "wb_os_system", + "io_rd", + "io_wr", + "exec_os_cmd", + "exec_os_cmd_log", + "write_sysfs", + "read_sysfs", + "get_sysfs_value", + "write_sysfs_value", + "get_value", + "set_value", + "getSdkReg", + "getMacTemp", + "getMacTemp_sysfs", + "get_format_value" +] + +class CodeVisitor(ast.NodeVisitor): + + def __init__(self): + self.value = None + + def get_value(self): + return self.value + + def get_op_value(self, node): + if isinstance(node, ast.Call): # node is func call + value = self.visit_Call(node) + elif isinstance(node, ast.BinOp): # node is BinOp + value = self.visit_BinOp(node) + elif isinstance(node, ast.UnaryOp): # node is UnaryOp + value = self.visit_UnaryOp(node) + elif isinstance(node, ast.Num): # node is Num Constant + value = node.n + elif isinstance(node, ast.Str): # node is Str Constant + value = node.s + else: + raise NotImplementedError("Unsupport operand type: %s" % type(node)) + return value + + def visit_UnaryOp(self, node): + ''' + node.op: operand type, only support ast.UAdd/ast.USub + node.operand: only support ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp/ast.UnaryOp + ''' + + operand_value = self.get_op_value(node.operand) + if isinstance(node.op, ast.UAdd): + self.value = operand_value + elif isinstance(node.op, ast.USub): + self.value = 0 - operand_value + else: + raise NotImplementedError("Unsupport arithmetic methods %s" % type(node.op)) + return self.value + + def visit_BinOp(self, node): + ''' + node.left: left operand, only support ast.Call/ast.Constant(ast.Num)/ast.BinOp + node.op: operand type, only support ast.Add/ast.Sub/ast.Mult/ast.Div + node.right: right operan, only support ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp + ''' + left_value = self.get_op_value(node.left) + right_value = self.get_op_value(node.right) + + if isinstance(node.op, ast.Add): + self.value = left_value + right_value + elif isinstance(node.op, ast.Sub): + self.value = left_value - right_value + elif isinstance(node.op, ast.Mult): + self.value = left_value * right_value + elif isinstance(node.op, ast.Div): + self.value = left_value / right_value + else: + raise NotImplementedError("Unsupport arithmetic methods %s" % type(node.op)) + return self.value + + def visit_Call(self, node): + ''' + node.func.id: func name, only support 'float', 'int', 'str' + node.args: func args list,only support ast.Constant(ast.Num/ast.Str)/ast.BinOp/ast.Call + str/float only support one parameter, eg: float(XXX), str(xxx) + int support one or two parameters, eg: int(xxx) or int(xxx, 16) + xxx can be ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp + ''' + calc_tuple = ("float", "int", "str") + + if node.func.id not in calc_tuple: + raise NotImplementedError("Unsupport function call type: %s" % node.func.id) + + args_val_list = [] + for item in node.args: + ret = self.get_op_value(item) + args_val_list.append(ret) + + if node.func.id == "str": + if len(args_val_list) != 1: + raise TypeError("str() takes 1 positional argument but %s were given" % len(args_val_list)) + value = str(args_val_list[0]) + self.value = value + return value + + if node.func.id == "float": + if len(args_val_list) != 1: + raise TypeError("float() takes 1 positional argument but %s were given" % len(args_val_list)) + value = float(args_val_list[0]) + self.value = value + return value + # int + if len(args_val_list) == 1: + value = int(args_val_list[0]) + self.value = value + return value + if len(args_val_list) == 2: + value = int(args_val_list[0], args_val_list[1]) + self.value = value + return value + raise TypeError("int() takes 1 or 2 arguments (%s given)" % len(args_val_list)) + +def inttostr(vl, length): + if not isinstance(vl, int): + raise Exception(" type error") + index = 0 + ret_t = "" + while index < length: + ret = 0xff & (vl >> index * 8) + ret_t += chr(ret) + index += 1 + return ret_t + + +def strtoint(str_tmp): + value = 0 + rest_v = str_tmp.replace("0X", "").replace("0x", "") + str_len = len(rest_v) + for index, val in enumerate(rest_v): + value |= int(val, 16) << ((str_len - index - 1) * 4) + return value + + +def inttobytes(val, length): + if not isinstance(val, int): + raise Exception("type error") + data_array = bytearray() + index = 0 + while index < length: + ret = 0xff & (val >> index * 8) + data_array.append(ret) + index += 1 + return data_array + + +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + strtmp = '' + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + + +def getonieplatform(path): + if not os.path.isfile(path): + return "" + machine_vars = {} + with open(path) as machine_file: + for line in machine_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + machine_vars[tokens[0]] = tokens[1].strip() + return machine_vars.get("onie_platform") + + +def getplatform_config_db(): + if not os.path.isfile(CONFIG_DB_PATH): + return "" + val = os.popen("sonic-cfggen -j %s -v DEVICE_METADATA.localhost.platform" % CONFIG_DB_PATH).read().strip() + if len(val) <= 0: + return "" + return val + + +def getplatform_name(): + if os.path.isfile('/host/machine.conf'): + return getonieplatform('/host/machine.conf') + if os.path.isfile('/usr/share/sonic/hwsku/machine.conf'): + return getonieplatform('/usr/share/sonic/hwsku/machine.conf') + return getplatform_config_db() + + +def wbi2cget(bus, devno, address, word=None): + if word is None: + command_line = "i2cget -f -y %d 0x%02x 0x%02x " % (bus, devno, address) + else: + command_line = "i2cget -f -y %d 0x%02x 0x%02x %s" % (bus, devno, address, word) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + time.sleep(0.1) + return False, ret_t + + +def wbi2cset(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbpcird(pcibus, slot, fn, resource, offset): + '''read pci register''' + if offset % 4 != 0: + return "ERR offset: %d not 4 bytes align" + filename = "/sys/bus/pci/devices/0000:%02x:%02x.%x/resource%d" % (int(pcibus), int(slot), int(fn), int(resource)) + with open(filename, "r+") as file: + size = os.path.getsize(filename) + data = mmap.mmap(file.fileno(), size) + result = data[offset: offset + 4] + s = result[::-1] + val = 0 + for value in s: + val = val << 8 | value + data.close() + return "0x%08x" % val + + +def wbpciwr(pcibus, slot, fn, resource, offset, data): + '''write pci register''' + ret = inttobytes(data, 4) + filename = "/sys/bus/pci/devices/0000:%02x:%02x.%x/resource%d" % (int(pcibus), int(slot), int(fn), int(resource)) + with open(filename, "r+") as file: + size = os.path.getsize(filename) + data = mmap.mmap(file.fileno(), size) + data[offset: offset + 4] = ret + result = data[offset: offset + 4] + s = result[::-1] + val = 0 + for value in s: + val = val << 8 | value + data.close() + + +def wbi2cgetWord(bus, devno, address): + command_line = "i2cget -f -y %d 0x%02x 0x%02x w" % (bus, devno, address) + retrytime = 3 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbi2csetWord(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%x w" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbi2cset_pec(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x bp" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbi2cset_wordpec(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x wp" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbsysset(location, value): + command_line = "echo 0x%02x > %s" % (value, location) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def dev_file_read(path, offset, read_len): + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + return True, val_list + + +def dev_file_write(path, offset, buf_list): + msg = "" + fd = -1 + + if not isinstance(buf_list, list) or len(buf_list) == 0: + msg = "buf:%s is not list type or is NONE !" % buf_list + return False, msg + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + try: + fd = os.open(path, os.O_WRONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.write(fd, bytes(buf_list)) + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + + return True, ret + + +def wb_os_system(cmd): + status, output = subprocess.getstatusoutput(cmd) + return status, output + + +def io_rd(reg_addr, read_len=1): + try: + regaddr = 0 + if isinstance(reg_addr, int): + regaddr = reg_addr + else: + regaddr = int(reg_addr, 16) + devfile = "/dev/port" + fd = os.open(devfile, os.O_RDWR | os.O_CREAT) + os.lseek(fd, regaddr, os.SEEK_SET) + val = os.read(fd, read_len) + return "".join(["%02x" % item for item in val]) + except ValueError: + return None + except Exception as e: + print(e) + return None + finally: + os.close(fd) + + +def io_wr(reg_addr, reg_data): + try: + regdata = 0 + regaddr = 0 + if isinstance(reg_addr, int): + regaddr = reg_addr + else: + regaddr = int(reg_addr, 16) + if isinstance(reg_data, int): + regdata = reg_data + else: + regdata = int(reg_data, 16) + devfile = "/dev/port" + fd = os.open(devfile, os.O_RDWR | os.O_CREAT) + os.lseek(fd, regaddr, os.SEEK_SET) + os.write(fd, regdata.to_bytes(1, 'little')) + return True + except ValueError as e: + print(e) + return False + except Exception as e: + print(e) + return False + finally: + os.close(fd) + + +def exec_os_cmd(cmd): + cmds = cmd.split('|') + procs = [] + for i, c in enumerate(cmds): + stdin = None if i == 0 else procs[i-1].stdout + p = subprocess.Popen(shlex.split(c), stdin=stdin, stdout=subprocess.PIPE, shell=False, stderr=subprocess.STDOUT) + procs.append(p) + for proc in procs: + proc.wait() + return procs[-1].returncode, typeTostr(procs[-1].communicate()[0]) + + +def exec_os_cmd_log(cmd): + proc = subprocess.Popen(shlex.split(cmd), stdin=subprocess.PIPE, shell=False, stderr=sys.stderr, close_fds=True, + stdout=sys.stdout, universal_newlines=True, bufsize=1) + proc.wait() + stdout = proc.communicate()[0] + stdout = typeTostr(stdout) + return proc.returncode, stdout + + +def write_sysfs(location, value): + try: + if not os.path.isfile(location): + return False, ("location[%s] not found !" % location) + with open(location, 'w') as fd1: + fd1.write(value) + except Exception as e: + return False, (str(e) + " location[%s]" % location) + return True, ("set location[%s] %s success !" % (location, value)) + + +def read_sysfs(location): + try: + locations = glob.glob(location) + with open(locations[0], 'rb') as fd1: + retval = fd1.read() + retval = typeTostr(retval) + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + except Exception as e: + return False, (str(e) + "location[%s]" % location) + return True, retval + + +def get_pmc_register(reg_name): + retval = 'ERR' + mb_reg_file = MAILBOX_DIR + reg_name + filepath = glob.glob(mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) + mb_reg_file = filepath[0] + if not os.path.isfile(mb_reg_file): + return "%s %s notfound" % (retval, mb_reg_file) + try: + with open(mb_reg_file, 'r') as fd: + retval = fd.read() + except Exception as error: + retval = retval + str(error) + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +def get_sysfs_value(location): + pos_t = str(location) + name = get_pmc_register(pos_t) + return name + + +def write_sysfs_value(reg_name, value): + fileLoc = MAILBOX_DIR + reg_name + try: + if not os.path.isfile(fileLoc): + print(fileLoc, 'not found !') + return False + with open(fileLoc, 'w') as fd: + fd.write(value) + except Exception: + print("Unable to open " + fileLoc + "file !") + return False + return True + + +def get_value_once(config): + try: + way = config.get("gettype") + int_decode = config.get("int_decode", 16) + if way == 'sysfs': + loc = config.get("loc") + ret, val = read_sysfs(loc) + if ret is True: + return True, int(val, int_decode) + return False, ("sysfs read %s failed. log:%s" % (loc, val)) + if way == "i2c": + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset", 0) + ret, val = wbi2cget(bus, addr, offset) + if ret is True: + return True, int(val, int_decode) + return False, ("i2c read failed. bus:%d , addr:0x%x, offset:0x%x" % (bus, addr, offset)) + if way == "io": + io_addr = config.get('io_addr') + val = io_rd(io_addr) + if len(val) != 0: + return True, int(val, int_decode) + return False, ("io_addr read 0x%x failed" % io_addr) + if way == "i2cword": + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + ret, val = wbi2cgetWord(bus, addr, offset) + if ret is True: + return True, int(val, int_decode) + return False, ("i2cword read failed. bus:%d, addr:0x%x, offset:0x%x" % (bus, addr, offset)) + if way == "devfile": + path = config.get("path") + offset = config.get("offset") + read_len = config.get("read_len") + ret, val_list = dev_file_read(path, offset, read_len) + if ret is True: + return True, val_list + return False, ("devfile read failed. path:%s, offset:0x%x, read_len:%d" % (path, offset, read_len)) + if way == 'cmd': + cmd = config.get("cmd") + ret, val = exec_os_cmd(cmd) + if ret: + return False, ("cmd read exec %s failed, log: %s" % (cmd, val)) + return True, int(val, int_decode) + if way == 'file_exist': + judge_file = config.get('judge_file', None) + if os.path.exists(judge_file): + return True, True + return True, False + return False, "not support read type" + except Exception as e: + return False, ("get_value_once exception:%s happen" % str(e)) + + +def set_value_once(config): + try: + delay_time = config.get("delay", None) + if delay_time is not None: + time.sleep(delay_time) + + way = config.get("gettype") + if way == 'sysfs': + loc = config.get("loc") + value = config.get("value") + mask = config.get("mask", 0xff) + mask_tuple = (0xff, 0) + if mask not in mask_tuple: + ret, read_value = read_sysfs(loc) + if ret is True: + read_value = int(read_value, base=16) + value = (read_value & mask) | value + else: + return False, ("sysfs read %s failed. log:%s" % (loc, read_value)) + ret, log = write_sysfs(loc, "0x%02x" % value) + if ret is not True: + return False, ("sysfs %s write 0x%x failed" % (loc, value)) + return True, ("sysfs write 0x%x success" % value) + if way == "i2c": + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + value = config.get("value") + mask = config.get("mask", 0xff) + mask_tuple = (0xff, 0) + if mask not in mask_tuple: + ret, read_value = wbi2cget(bus, addr, offset) + if ret is True: + read_value = int(read_value, base=16) + value = (read_value & mask) | value + else: + return False, ("i2c read failed. bus:%d , addr:0x%x, offset:0x%x" % (bus, addr, offset)) + ret, log = wbi2cset(bus, addr, offset, value) + if ret is not True: + return False, ("i2c write bus:%d, addr:0x%x, offset:0x%x, value:0x%x failed" % + (bus, addr, offset, value)) + return True, ("i2c write bus:%d, addr:0x%x, offset:0x%x, value:0x%x success" % + (bus, addr, offset, value)) + if way == "io": + io_addr = config.get('io_addr') + value = config.get('value') + mask = config.get("mask", 0xff) + mask_tuple = (0xff, 0) + if mask not in mask_tuple: + read_value = io_rd(io_addr) + if read_value is None: + return False, ("io_addr 0x%x read failed" % (io_addr)) + read_value = int(read_value, base=16) + value = (read_value & mask) | value + ret = io_wr(io_addr, value) + if ret is not True: + return False, ("io_addr 0x%x write 0x%x failed" % (io_addr, value)) + return True, ("io_addr 0x%x write 0x%x success" % (io_addr, value)) + if way == 'i2cword': + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + value = config.get("value") + mask = config.get("mask", 0xff) + mask_tuple = (0xff, 0) + if mask not in mask_tuple: + ret, read_value = wbi2cgetWord(bus, addr, offset) + if ret is True: + read_value = int(read_value, base=16) + value = (read_value & mask) | value + else: + return False, ("i2c read word failed. bus:%d , addr:0x%x, offset:0x%x" % (bus, addr, offset)) + ret, log = wbi2csetWord(bus, addr, offset, value) + if ret is not True: + return False, ("i2cword write bus:%d, addr:0x%x, offset:0x%x, value:0x%x failed" % + (bus, addr, offset, value)) + return True, ("i2cword write bus:%d, addr:0x%x, offset:0x%x, value:0x%x success" % + (bus, addr, offset, value)) + if way == "devfile": + path = config.get("path") + offset = config.get("offset") + buf_list = config.get("value") + ret, log = dev_file_write(path, offset, buf_list) + if ret is True: + return True, ("devfile write path:%s, offset:0x%x, buf_list:%s success." % (path, offset, buf_list)) + return False, ("devfile read path:%s, offset:0x%x, buf_list:%s failed.log:%s" % + (path, offset, buf_list, log)) + if way == 'cmd': + cmd = config.get("cmd") + ret, log = exec_os_cmd(cmd) + if ret: + return False, ("cmd write exec %s failed, log: %s" % (cmd, log)) + return True, ("cmd write exec %s success" % cmd) + if way == 'bit_wr': + mask = config.get("mask") + bit_val = config.get("value") + val_config = config.get("val_config") + ret, rd_value = get_value_once(val_config) + if ret is False: + return False, ("bit_wr read failed, log: %s" % rd_value) + wr_val = (rd_value & mask) | bit_val + val_config["value"] = wr_val + ret, log = set_value_once(val_config) + if ret is False: + return False, ("bit_wr failed, log: %s" % log) + return True, ("bit_wr success, log: %s" % log) + if way == 'creat_file': + file_name = config.get("file") + ret, log = exec_os_cmd("touch %s" % file_name) + if ret: + return False, ("creat file %s failed, log: %s" % (file_name, log)) + exec_os_cmd("sync") + return True, ("creat file %s success" % file_name) + if way == 'remove_file': + file_name = config.get("file") + ret, log = exec_os_cmd("rm -rf %s" % file_name) + if ret: + return False, ("remove file %s failed, log: %s" % (file_name, log)) + exec_os_cmd("sync") + return True, ("remove file %s success" % file_name) + return False, "not support write type" + except Exception as e: + return False, ("set_value_once exception:%s happen" % str(e)) + + +def get_value(config): + retrytime = 6 + for i in range(retrytime): + ret, val = get_value_once(config) + if ret is True: + return True, val + time.sleep(0.1) + return False, val + + +def set_value(config): + retrytime = 6 + ignore_result_flag = config.get("ignore_result", 0) + for i in range(retrytime): + ret, log = set_value_once(config) + if ret is True: + return True, log + if ignore_result_flag == 1: + return True, log + time.sleep(0.1) + return False, log + + +class CompressedRotatingFileHandler(logging.handlers.RotatingFileHandler): + def doRollover(self): + """ + Do a rollover, as described in __init__(). + """ + if self.stream: + self.stream.close() + self.stream = None + if self.backupCount > 0: + for i in range(self.backupCount - 1, 0, -1): + sfn = "%s.%d.gz" % (self.baseFilename, i) + dfn = "%s.%d.gz" % (self.baseFilename, i + 1) + if os.path.exists(sfn): + if os.path.exists(dfn): + os.remove(dfn) + os.rename(sfn, dfn) + dfn = self.baseFilename + ".1.gz" + if os.path.exists(dfn): + os.remove(dfn) + # These two lines below are the only new lines. I commented out the os.rename(self.baseFilename, dfn) and + # replaced it with these two lines. + with open(self.baseFilename, 'rb') as f_in, gzip.open(dfn, 'wb') as f_out: + shutil.copyfileobj(f_in, f_out) + self.mode = 'w' + self.stream = self._open() + + +def getSdkReg(reg): + try: + cmd = "bcmcmd -t 1 'getr %s ' < /dev/null" % reg + ret, result = wb_os_system(cmd) + result_t = result.strip().replace("\r", "").replace("\n", "") + if ret != 0 or "Error:" in result_t: + return False, result + patt = r"%s.(.*):(.*)>drivshell" % reg + rt = re.findall(patt, result_t, re.S) + test = re.findall("=(.*)", rt[0][0])[0] + except Exception: + return False, 'getsdk register error' + return True, test + + +def getMacTemp(): + result = {} + wb_os_system("bcmcmd -t 1 \"show temp\" < /dev/null") + ret, log = wb_os_system("bcmcmd -t 1 \"show temp\" < /dev/null") + if ret: + return False, result + logs = log.splitlines() + for line in logs: + if "average" in line: + b = re.findall(r'\d+.\d+', line) + result["average"] = b[0] + elif "maximum" in line: + b = re.findall(r'\d+.\d+', line) + result["maximum"] = b[0] + return True, result + + +def getMacTemp_sysfs(mactempconf): + temp = -1000000 + try: + temp_list = [] + mac_temp_loc = mactempconf.get("loc", []) + mac_temp_flag = mactempconf.get("flag", None) + if mac_temp_flag is not None: + gettype = mac_temp_flag.get('gettype') + okbit = mac_temp_flag.get('okbit') + okval = mac_temp_flag.get('okval') + if gettype == "io": + io_addr = mac_temp_flag.get('io_addr') + val = io_rd(io_addr) + if val is None: + raise Exception("get mac_flag by io failed.") + else: + bus = mac_temp_flag.get('bus') + loc = mac_temp_flag.get('loc') + offset = mac_temp_flag.get('offset') + ind, val = wbi2cget(bus, loc, offset) + if ind is not True: + raise Exception("get mac_flag by i2c failed.") + val_t = (int(val, 16) & (1 << okbit)) >> okbit + if val_t != okval: + raise Exception("mac_flag invalid, val_t:%d." % val_t) + for loc in mac_temp_loc: + temp_s = get_sysfs_value(loc) + if isinstance(temp_s, str) and temp_s.startswith("ERR"): + raise Exception("get mac temp error. loc:%s" % loc) + temp_t = int(temp_s) + if temp_t == -1000000: + raise Exception("mac temp invalid.loc:%s" % loc) + temp_list.append(temp_t) + temp_list.sort(reverse=True) + temp = temp_list[0] + except Exception: + return False, temp + return True, temp + +def get_format_value(format_str): + ast_obj = ast.parse(format_str, mode='eval') + visitor = CodeVisitor() + visitor.visit(ast_obj) + ret = visitor.get_value() + return ret + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/pmon_syslog.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/pmon_syslog.py new file mode 100755 index 000000000000..8bdceef8c1b5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/pmon_syslog.py @@ -0,0 +1,519 @@ +#!/usr/bin/python3 +# * onboard interval check +# * FAN trays +# * PSU +# * SFF +import time +import syslog +import traceback +import glob +from platform_config import PMON_SYSLOG_STATUS + +PMON_DEBUG_FILE = "/etc/.pmon_syslog_debug_flag" +debuglevel = 0 +PMONERROR = 1 +PMONDEBUG = 2 + + +def pmon_debug(s): + if PMONDEBUG & debuglevel: + syslog.openlog("PMON_SYSLOG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def pmon_error(s): + if PMONERROR & debuglevel: + syslog.openlog("PMON_SYSLOG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def dev_syslog(s): + syslog.openlog("PMON_SYSLOG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_NOTICE, s) + + +# status +STATUS_PRESENT = 'PRESENT' +STATUS_ABSENT = 'ABSENT' +STATUS_OK = 'OK' +STATUS_NOT_OK = 'NOT OK' +STATUS_FAILED = 'FAILED' + + +class checkBase(object): + def __init__(self, path, dev_name, display_name, obj_type, config): + self._peroid_syslog = None + self._peroid_failed_syslog = None # exception + self._preDevStatus = None + self._path = path + self._name = dev_name + self._display_name = display_name + self._type = obj_type + self._config = config + + def getCurstatus(self): + # get ok/not ok/absent status + status, log = self.getPresent() + if status == STATUS_PRESENT: + # check status + property_status, log = self.getStatus() + if property_status is not None: + status = property_status + return status, log + + def getPresent(self): + presentFilepath = self.getPath() + try: + # get ok/not ok/absent status + presentConfig = self._config["present"] + mask = presentConfig.get("mask", 0xff) + absent_val = presentConfig.get("ABSENT", None) + absent_val = absent_val & mask + with open(presentFilepath, "r") as fd: + retval = fd.read() + if int(retval) == absent_val: + return STATUS_ABSENT, None + return STATUS_PRESENT, None + except Exception as e: + return STATUS_FAILED, (str(e) + " location[%s]" % presentFilepath) + + def getStatus(self): + if "status" in self._config: + statusConfig = self._config["status"] + for itemConfig in statusConfig: + mask = itemConfig.get("mask", 0xff) + ok_val = itemConfig.get("okval", None) + ok_val = ok_val & mask + Filepath = itemConfig["path"] % self._name + try: + with open(Filepath, "r") as fd1: + retval = fd1.read() + if int(retval) != ok_val: + return STATUS_NOT_OK, None + except Exception as e: + return STATUS_FAILED, (str(e) + " location[%s]" % Filepath) + return STATUS_OK, None + return None, None + + def getPath(self): + return self._path + + def getName(self): + return self._name + + def getType(self): + return self._type + + def getDisplayName(self): + return self._display_name + + def getnochangedMsgFlag(self): + return self._config["nochangedmsgflag"] + + def getnochangedMsgTime(self): + return self._config["nochangedmsgtime"] + + def getnoprintFirstTimeFlag(self): + return self._config["noprintfirsttimeflag"] + + def checkStatus(self): + # syslog msg + dev_type = self.getType() + display_name = self.getDisplayName() + nochangedMsgTime = self.getnochangedMsgTime() + getnochangedMsgFlag = self.getnochangedMsgFlag() + noprintFirstTimeFlag = self.getnoprintFirstTimeFlag() + MSG_IN = '%%PMON-5-' + dev_type + '_PLUG_IN: %s is PRESENT.' + MSG_OUT = '%%PMON-5-' + dev_type + '_PLUG_OUT: %s is ABSENT.' + MSG_OK = '%%PMON-5-' + dev_type + '_OK: %s is OK.' + MSG_NOT_OK = '%%PMON-5-' + dev_type + '_FAILED: %s is NOT OK.' + MSG_ABSENT = '%%PMON-5-' + dev_type + '_ABSENT: %s is ABSENT.' + MSG_UNKNOWN = '%%PMON-5-' + dev_type + '_UNKNOWN: %s is UNKNOWN.%s' + MSG_RECOVER = '%%PMON-5-' + dev_type + '_OK: %s is OK. Recover from ' + dev_type + ' FAILED.' + + curStatus, log = self.getCurstatus() + pmon_debug("%s: current status %s" % (display_name, curStatus)) + pmon_debug("%s: pre status %s" % (display_name, self._preDevStatus)) + pmon_debug("%s: peroid_syslog %s" % (display_name, self._peroid_syslog)) + + if curStatus == STATUS_FAILED: + # get status failed + if self._peroid_failed_syslog is not None: + if getnochangedMsgFlag and time.time() - self._peroid_failed_syslog >= nochangedMsgTime: + # absent as before for some time, notice + dev_syslog(MSG_UNKNOWN % (display_name, log)) + self._peroid_failed_syslog = time.time() + else: # first time failed + dev_syslog(MSG_UNKNOWN % (display_name, log)) + self._peroid_failed_syslog = time.time() + return + self._peroid_failed_syslog = time.time() + + if self._preDevStatus is None: + # 1st time + if noprintFirstTimeFlag == 1: + self._peroid_syslog = time.time() + else: + if curStatus == STATUS_PRESENT: + # present + dev_syslog(MSG_IN % display_name) + elif curStatus == STATUS_OK: + # ok + dev_syslog(MSG_OK % display_name) + elif curStatus == STATUS_NOT_OK: + # not ok + dev_syslog(MSG_NOT_OK % display_name) + self._peroid_syslog = time.time() + else: + # absent + dev_syslog(MSG_ABSENT % display_name) + self._peroid_syslog = time.time() + else: + # from 2nd time... + if self._preDevStatus == curStatus: + # status not changed + if self._preDevStatus == STATUS_ABSENT: + if self._peroid_syslog is not None: + if getnochangedMsgFlag and time.time() - self._peroid_syslog >= nochangedMsgTime: + # absent as before for some time, notice + dev_syslog(MSG_ABSENT % display_name) + self._peroid_syslog = time.time() + elif self._preDevStatus == STATUS_NOT_OK: + if self._peroid_syslog is not None: + if getnochangedMsgFlag and time.time() - self._peroid_syslog >= nochangedMsgTime: + # not ok as before for some time, notice + dev_syslog(MSG_NOT_OK % display_name) + self._peroid_syslog = time.time() + else: + # status changed + if self._preDevStatus == STATUS_ABSENT: + if curStatus == STATUS_NOT_OK: + # absent -> not ok + dev_syslog(MSG_IN % display_name) + dev_syslog(MSG_NOT_OK % display_name) + self._peroid_syslog = time.time() + elif curStatus == STATUS_OK: + # absent -> ok + dev_syslog(MSG_IN % display_name) + dev_syslog(MSG_OK % display_name) + else: + # absent -> prsent + dev_syslog(MSG_IN % display_name) + + elif self._preDevStatus == STATUS_OK: + if curStatus == STATUS_NOT_OK: + # ok -> not ok + dev_syslog(MSG_NOT_OK % display_name) + self._peroid_syslog = time.time() + elif curStatus == STATUS_ABSENT: + # ok -> absent + dev_syslog(MSG_OUT % display_name) + self._peroid_syslog = time.time() + elif self._preDevStatus == STATUS_PRESENT: + # present -> absent + dev_syslog(MSG_OUT % display_name) + self._peroid_syslog = time.time() + else: # not ok + if curStatus == STATUS_OK: + # not ok -> ok + dev_syslog(MSG_RECOVER % display_name) + dev_syslog(MSG_OK % display_name) + else: + # not ok -> absent + dev_syslog(MSG_OUT % display_name) + self._peroid_syslog = time.time() + self._preDevStatus = curStatus + + +class checkSfp(checkBase): + def __init__(self, path, dev_name, display_name, config): + super(checkSfp, self).__init__(path, dev_name, display_name, 'XCVR', config) + + def getPath(self): + super(checkSfp, self).getPath() + return self._path + + def getName(self): + super(checkSfp, self).getName() + return self._name + + def getType(self): + super(checkSfp, self).getType() + return self._type + + +class checkSlot(checkBase): + def __init__(self, path, dev_name, display_name, config): + super(checkSlot, self).__init__(path, dev_name, display_name, 'SLOT', config) + + def getPath(self): + super(checkSlot, self).getPath() + return self._path + + def getName(self): + super(checkSlot, self).getName() + return self._name + + def getType(self): + super(checkSlot, self).getType() + return self._type + + +class checkPSU(checkBase): + def __init__(self, path, dev_name, display_name, config): + super(checkPSU, self).__init__(path, dev_name, display_name, 'PSU', config) + + def getPath(self): + super(checkPSU, self).getPath() + return self._path + + def getName(self): + super(checkPSU, self).getName() + return self._name + + def getType(self): + super(checkPSU, self).getType() + return self._type + + +class checkFAN(checkBase): + def __init__(self, path, dev_name, display_name, config): + super(checkFAN, self).__init__(path, dev_name, display_name, 'FAN', config) + + def getPath(self): + super(checkFAN, self).getPath() + return self._path + + def getName(self): + super(checkFAN, self).getName() + return self._name + + def getType(self): + super(checkFAN, self).getType() + return self._type + + +class platformSyslog(): + def __init__(self): + self.__sfp_checklist = [] + self.__fan_checklist = [] + self.__psu_checklist = [] + self.__slot_checklist = [] + self.__temp_checklist = [] + self.temps_peroid_syslog = {} + self.normal_status = 0 + self.warning_status = 1 + self.critical_status = 2 + self.poweron_flag = 0 + + self.pmon_syslog_config = PMON_SYSLOG_STATUS.copy() + self.__pollingtime = self.pmon_syslog_config.get('polling_time', 3) + + tmpconfig = self.pmon_syslog_config.get('sffs', None) + if tmpconfig is not None: + preset_item = tmpconfig.get("present", {}) + path = preset_item.get("path", []) + for location in path: + if '*' not in location: + pmon_error("sff location config error: %s" % location) + continue + dev_name_index = 0 + loc_split_list = location.split('/') + for i, item in enumerate(loc_split_list): + if '*' in item: + dev_name_index = i + break + locations = glob.glob(location) + for dev_path in locations: + dev_name_list = dev_path.split('/') + # explame:get eth1 from /sys_switch/transceiver/eth1/present + dev_name = dev_name_list[dev_name_index] + dev_name_alias = tmpconfig.get("alias", {}) + display_name = dev_name_alias.get(dev_name, dev_name) + dev = checkSfp(dev_path, dev_name, display_name, tmpconfig) + self.__sfp_checklist.append(dev) + + tmpconfig = self.pmon_syslog_config.get('fans', None) + if tmpconfig is not None: + preset_item = tmpconfig.get("present", {}) + path = preset_item.get("path", []) + for location in path: + if '*' not in location: + pmon_error("fan location config error: %s" % location) + continue + dev_name_index = 0 + loc_split_list = location.split('/') + for i, item in enumerate(loc_split_list): + if '*' in item: + dev_name_index = i + break + locations = glob.glob(location) + for dev_path in locations: + dev_name_list = dev_path.split('/') + dev_name = dev_name_list[dev_name_index] + dev_name_alias = tmpconfig.get("alias", {}) + display_name = dev_name_alias.get(dev_name, dev_name) + dev = checkFAN(dev_path, dev_name, display_name, tmpconfig) + self.__fan_checklist.append(dev) + + tmpconfig = self.pmon_syslog_config.get('psus', None) + if tmpconfig is not None: + preset_item = tmpconfig.get("present", {}) + path = preset_item.get("path", []) + for location in path: + if '*' not in location: + pmon_error("psu location config error: %s" % location) + continue + dev_name_index = 0 + loc_split_list = location.split('/') + for i, item in enumerate(loc_split_list): + if '*' in item: + dev_name_index = i + break + locations = glob.glob(location) + for dev_path in locations: + dev_name_list = dev_path.split('/') + dev_name = dev_name_list[dev_name_index] + dev_name_alias = tmpconfig.get("alias", {}) + display_name = dev_name_alias.get(dev_name, dev_name) + dev = checkPSU(dev_path, dev_name, display_name, tmpconfig) + self.__psu_checklist.append(dev) + + tmpconfig = self.pmon_syslog_config.get('slots', None) + if tmpconfig is not None: + preset_item = tmpconfig.get("present", {}) + path = preset_item.get("path", []) + for location in path: + if '*' not in location: + pmon_error("slot location config error: %s" % location) + continue + dev_name_index = 0 + loc_split_list = location.split('/') + for i, item in enumerate(loc_split_list): + if '*' in item: + dev_name_index = i + break + locations = glob.glob(location) + for dev_path in locations: + dev_name_list = dev_path.split('/') + dev_name = dev_name_list[dev_name_index] + dev_name_alias = tmpconfig.get("alias", {}) + display_name = dev_name_alias.get(dev_name, dev_name) + dev = checkSlot(dev_path, dev_name, display_name, tmpconfig) + self.__slot_checklist.append(dev) + + tmpconfig = self.pmon_syslog_config.get('temps', None) + if tmpconfig is not None: + self.__temp_checklist = tmpconfig.get('temps_list', []) + self.__temps_pollingseconds = tmpconfig.get('over_temps_polling_seconds', None) + + def checkTempStaus(self, temp_item): + temp_name = temp_item.get('name', None) + input_path = temp_item.get('input_path', None) + warning_temp = temp_item.get('warning', None) + critical_temp = temp_item.get('critical', None) + input_accuracy = temp_item.get('input_accuracy', None) + if temp_name is None or input_path is None or warning_temp is None or critical_temp is None: + dev_syslog('%%PMON-5-TEMP_NOTICE: get temperature config parament failed.') + return + try: + locations = glob.glob(input_path) + with open(locations[0], "r") as fd: + input_temp = fd.read() + input_temp = float(input_temp) / float(input_accuracy) + + if 'time' not in temp_item: + temp_item['time'] = time.time() + temp_item['status'] = self.normal_status + if float(input_temp) >= float(warning_temp): + if float(input_temp) >= float(critical_temp): + if time.time() - \ + temp_item['time'] >= self.__temps_pollingseconds or temp_item['status'] != self.critical_status: + dev_syslog('%%PMON-5-TEMP_HIGH: %s temperature %sC is larger than max critical threshold %sC.' + % (temp_name, input_temp, critical_temp)) + temp_item['status'] = self.critical_status + temp_item['time'] = time.time() + else: + if time.time() - \ + temp_item['time'] >= self.__temps_pollingseconds or temp_item['status'] != self.warning_status: + dev_syslog('%%PMON-5-TEMP_HIGH: %s temperature %sC is larger than max warning threshold %sC.' + % (temp_name, input_temp, warning_temp)) + temp_item['status'] = self.warning_status + temp_item['time'] = time.time() + else: + pmon_debug( + "%s temperature %sC is in range [%s, %s]" % + (temp_name, input_temp, warning_temp, critical_temp)) + temp_item['status'] = self.normal_status + temp_item['time'] = time.time() + except Exception as e: + dev_syslog('%%PMON-5-TEMP_NOTICE: Cannot get %s temperature. Exception log: %s' % (temp_name, str(e))) + return + + def sysfs_precondition_check(self, check_module, check_project): + try: + tmpconfig = self.pmon_syslog_config.get(check_module, None) + if tmpconfig is not None: + check_list = tmpconfig.get(check_project, []) + for check_item in check_list: + location = check_item.get("path", None) + ok_val = check_item.get("ok_val", None) + mask = check_item.get("mask", 0xff) + ok_val = ok_val & mask + locations = glob.glob(location) + for power_path in locations: + with open(power_path, "r") as fd: + retval = fd.read() + if int(retval) != ok_val: + return + self.poweron_flag = 1 + except Exception as e: + dev_syslog('%%PMON-5-TEMP_NOTICE: Cannot check power status. Exception log: %s' % str(e)) + return + + def updateSysDeviceStatus(self): + if self.poweron_flag == 1: + for dev in self.__sfp_checklist: + dev.checkStatus() + else: + self.sysfs_precondition_check('sffs', 'power') + + for dev in self.__fan_checklist: + dev.checkStatus() + for dev in self.__psu_checklist: + dev.checkStatus() + for dev in self.__slot_checklist: + dev.checkStatus() + for temp_item in self.__temp_checklist: + self.checkTempStaus(temp_item) + + def getPollingtime(self): + return self.__pollingtime + + def debug_init(self): + global debuglevel + try: + with open(PMON_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + def doWork(self): + try: + self.debug_init() + self.updateSysDeviceStatus() + except Exception as e: + MSG_EXCEPTION = '%%PMON-5-NOTICE: Exception happened! info:%s' % str(e) + pmon_error(MSG_EXCEPTION % traceback.format_exc()) + + +def run(): + platform = platformSyslog() + while True: + platform.doWork() + time.sleep(platform.getPollingtime()) + + +if __name__ == '__main__': + run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_cause.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_cause.py new file mode 100755 index 000000000000..2f125c5084c2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_cause.py @@ -0,0 +1,183 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- +import sys +import os +import time +import syslog +from platform_util import get_value, set_value, exec_os_cmd, wb_os_system +from platform_config import REBOOT_CAUSE_PARA + +REBOOT_CAUSE_DEBUG_FILE = "/etc/.reboot_cause_debug" +REBOOT_CAUSE_STARTED_FLAG = "/tmp/.reboot_cause_started_flag" + +debuglevel = 0 + + +def record_syslog_debug(s): + if debuglevel: + syslog.openlog("REBOOT_CAUSE_DEBUG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def record_syslog(s): + syslog.openlog("REBOOT_CAUSE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +class RebootCause(): + def __init__(self): + self.reboot_cause_para = REBOOT_CAUSE_PARA.copy() + self.reboot_cause_list = self.reboot_cause_para.get('reboot_cause_list', None) + self.other_reboot_cause_record = self.reboot_cause_para.get('other_reboot_cause_record', None) + + def debug_init(self): + global debuglevel + if os.path.exists(REBOOT_CAUSE_DEBUG_FILE): + debuglevel = 1 + else: + debuglevel = 0 + + def monitor_point_check(self, item): + try: + gettype = item.get('gettype', None) + okval = item.get('okval', None) + compare_mode = item.get('compare_mode', "equal") + ret, value = get_value(item) + if ret is True: + if compare_mode == "equal": + if value == okval: + return True + elif compare_mode == "great": + if value > okval: + return True + elif compare_mode == "ignore": + return True + else: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: compare_mode %s not match error.' % (compare_mode)) + else: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: base point check type:%s not support.' % gettype) + except Exception as e: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: base point check error. msg: %s.' % (str(e))) + return False + + def reboot_cause_record(self, item_list): + RET = {"RETURN_KEY1": 0} + try: + for item in item_list: + record_type = item.get('record_type', None) + if record_type == 'file': + file_mode = item.get('mode', None) + file_log = item.get('log', None) + file_path = item.get('path', None) + file_max_size = item.get('file_max_size', 0) + + if file_path is None: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: record type is file, but path is none.') + continue + + if file_max_size > 0: + file_size = 0 + if os.path.exists(file_path): + file_size = os.path.getsize(file_path) // file_max_size + if file_size >= 1: + reocrd_cmd = "mv %s %s_bak" % (file_path, file_path) + status, output = exec_os_cmd(reocrd_cmd) + if status: + record_syslog( + '%%REBOOT_CAUSE-3-EXCEPTION: exec cmd %s failed, %s' % + (reocrd_cmd, output)) + + if file_mode == 'cover': + operate_cmd = ">" + elif file_mode == 'add': + operate_cmd = ">>" + else: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: file record mode:%s not support.' % file_mode) + continue + + create_dir = "mkdir -p %s" % os.path.dirname(file_path) + status, ret_t = wb_os_system(create_dir) + if status != 0: + RET["RETURN_KEY1"] = -1 + record_syslog( + '%%REBOOT_CAUSE-3-EXCEPTION: create %s failed, msg: %s' % + (os.path.dirname(file_path), ret_t)) + continue + + status, date = wb_os_system("date") + if status != 0 or len(date) == 0: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: get date failed.') + continue + + reocrd_cmd = "echo %s %s %s %s" % (file_log, date, operate_cmd, file_path) + status, ret_t = wb_os_system(reocrd_cmd) + if status != 0: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: get date failed, msg: %s' % ret_t) + continue + wb_os_system('sync') + else: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: record_type:%s not support.' % record_type) + continue + except Exception as e: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: reboot cause record error. msg: %s.' % (str(e))) + if RET["RETURN_KEY1"] == 0: + return True + return False + + def reboot_cause_check(self): + try: + reboot_cause_flag = False + if self.reboot_cause_list is None: + record_syslog_debug('%%REBOOT_CAUSE-6-DEBUG: reboot cause check config not found') + return + for item in self.reboot_cause_list: + name = item.get('name', None) + monitor_point = item.get('monitor_point', None) + record = item.get('record', None) + finish_operation_list = item.get('finish_operation', []) + if name is None or monitor_point is None or record is None: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: reboot cause check get config failed.name:%s, monitor_point:%s, record:%s' % + (name, monitor_point, record)) + return + ret = self.monitor_point_check(monitor_point) + if ret is True: + record_syslog_debug('%%REBOOT_CAUSE-6-DEBUG: %s reboot cause is happen' % name) + self.reboot_cause_record(record) + reboot_cause_flag = True + for finish_operation_item in finish_operation_list: + ret, log = set_value(finish_operation_item) + if ret is False: + log = "%%REBOOT_CAUSE-3-EXCEPTION: " + log + record_syslog(log) + + if reboot_cause_flag is False and self.other_reboot_cause_record is not None: + record_syslog_debug('%%REBOOT_CAUSE-6-DEBUG: other reboot cause is happen') + self.reboot_cause_record(self.other_reboot_cause_record) + except Exception as e: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: reboot cause check error. msg: %s.' % (str(e))) + return + + def run(self): + try: + self.debug_init() + if os.path.exists(REBOOT_CAUSE_STARTED_FLAG): + record_syslog_debug( + '%%REBOOT_CAUSE-6-DEBUG: Reboot cause has been started and will not be started again') + sys.exit(0) + self.reboot_cause_check() + wb_os_system("touch %s" % REBOOT_CAUSE_STARTED_FLAG) + wb_os_system("sync") + time.sleep(5) + sys.exit(0) + except Exception as e: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: %s.' % (str(e))) + + +if __name__ == '__main__': + reboot_cause = RebootCause() + reboot_cause.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_ctrl.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_ctrl.py new file mode 100755 index 000000000000..17d3f5902b9d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_ctrl.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import time +import syslog +import click +from platform_util import write_sysfs, wbi2cset, io_wr, wbi2csetWord +from platform_config import REBOOT_CTRL_PARAM + + +REBOOTCTLDEBUG = 0 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def rebootctrlwarning(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("REBOOTCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def rebootctrlcritical(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("REBOOTCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def rebootctrlerror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("REBOOTCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def rebootctrldebug(s): + # s = s.decode('utf-8').encode('gb2312') + if REBOOTCTLDEBUG == 1: + syslog.openlog("REBOOTCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +class RebootCtrl(): + def __init__(self): + self.config = REBOOT_CTRL_PARAM.copy() + + def set_value(self, config, val): + way = config.get("gettype") + if way == 'sysfs': + loc = config.get("loc") + value = config.get(val) + rebootctrldebug("sysfs type.loc:0x%x, value:0x%x" % (loc, value)) + return write_sysfs(loc, "0x%02x" % value) + if way == "i2c": + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + value = config.get(val) + rebootctrldebug("i2c type.bus:0x%x, addr:0x%x, offset:0x%x, value:0x%x" % (bus, addr, offset, value)) + return wbi2cset(bus, addr, offset, value) + if way == "io": + io_addr = config.get('io_addr') + value = config.get(val) + rebootctrldebug("io type.io_addr:0x%x, value:0x%x" % (io_addr, value)) + ret = io_wr(io_addr, value) + if ret is not True: + return False, ("write 0x%x failed" % io_addr) + return True, ("write 0x%x success" % io_addr) + if way == 'i2cword': + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + value = config.get(val) + rebootctrldebug("i2cword type.bus:0x%x, addr:0x%x, offset:0x%x, value:0x%x" % (bus, addr, offset, value)) + return wbi2csetWord(bus, addr, offset, value) + return False, "unsupport way: %s" % way + + def reset_operate(self, config): + ret, log = self.set_value(config, "rst_val") + rst_delay = config.get("rst_delay", 0) + time.sleep(rst_delay) + return ret, log + + def unlock_reset_operate(self, config): + ret, log = self.set_value(config, "unlock_rst_val") + unlock_rst_delay = config.get("unlock_rst_delay", 0) + time.sleep(unlock_rst_delay) + return ret, log + + def do_rebootctrl(self, option): + if self.config is None: + rebootctrlerror("Reset failed, REBOOT_CTRL_PARAM cfg get failed.") + return + try: + name_conf = self.config.get(option, None) + if name_conf is None: + print("Reset %s not support" % option) + return + try: + click.confirm("Are you sure you want to reset " + option + "?", + default=False, abort=True, show_default=True) + except Exception as e: + print("Aborted, msg: %s" % str(e)) + return + print("Reset %s start" % option) + ret, log = self.reset_operate(name_conf) + if ret is False: + rebootctrlerror(log) + print("Reset %s failed" % option) + return + if "unlock_rst_val" in name_conf: + ret, log = self.unlock_reset_operate(name_conf) + if ret is False: + rebootctrlerror(log) + print("%s unlock reset failed" % option) + return + print("Reset %s success" % option) + except Exception: + rebootctrlerror("do_rebootctrl Exception error") + return + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''reboot_ctrl reset [option]''' + + +@main.command() +@click.argument('option', required=True) +def reset(option): + '''reset device''' + rebootctrldebug("reboot ctrl option %s" % option) + rebootctrl = RebootCtrl() + rebootctrl.do_rebootctrl(option) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/sensors b/platform/broadcom/sonic-platform-modules-ragile/common/script/sensors new file mode 100755 index 000000000000..a2c72b123a43 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +#docker exec -i pmon sensors "$@" + + +#To probe sensors not part of lm-sensors +if [ -r /usr/local/bin/platform_sensors.py ]; then + python /usr/local/bin/platform_sensors.py +fi diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/sfp_highest_temperatue.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/sfp_highest_temperatue.py new file mode 100755 index 000000000000..4dd98f3a36b3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/sfp_highest_temperatue.py @@ -0,0 +1,148 @@ +#!/usr/bin/python3 +import os +import importlib.machinery +import time +import syslog +import subprocess +import fcntl + +sfp_temperature_file = "/tmp/highest_sff_temp" + +SFP_TEMP_DEBUG_FILE = "/etc/.sfp_temp_debug_flag" +SFP_TEMP_RECORD_DEBUG = 1 +SFP_TEMP_RECORD_ERROR = 2 +debuglevel = 0 + + +def sfp_temp_debug(s): + if SFP_TEMP_RECORD_DEBUG & debuglevel: + syslog.openlog("SFP_TEMP_DEBUG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def sfp_temp_error(s): + if SFP_TEMP_RECORD_ERROR & debuglevel: + syslog.openlog("SFP_TEMP_ERROR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +pidfile = None + + +def file_rw_lock(): + global pidfile + pidfile = open(sfp_temperature_file, "r") + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + sfp_temp_debug("file lock success") + return True + except Exception: + if pidfile is not None: + pidfile.close() + pidfile = None + return False + + +def file_rw_unlock(): + try: + global pidfile + + if pidfile is not None: + fcntl.flock(pidfile, fcntl.LOCK_UN) + pidfile.close() + pidfile = None + sfp_temp_debug("file unlock success") + else: + sfp_temp_debug("pidfile is invalid, do nothing") + return True + except Exception as e: + sfp_temp_error("file unlock err, msg:%s" % (str(e))) + return False + + +def get_sfp_highest_temperature(): + highest_temperature = 0 + platform_sfputil = None + + sfputil_dir = "/usr/share/sonic/device/" + try: + if not os.path.exists(sfputil_dir): + sfputil_dir = "/usr/share/sonic/platform/" + sfputil_path = sfputil_dir + "/plugins/sfputil.py" + else: + cmd = "cat /host/machine.conf | grep onie_build_platform" + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) + + onie_platform = output.split("=")[1] + sfputil_path = sfputil_dir + onie_platform + "/plugins/sfputil.py" + + module = importlib.machinery.SourceFileLoader("sfputil", sfputil_path).load_module() + platform_sfputil_class = getattr(module, "SfpUtil") + platform_sfputil = platform_sfputil_class() + + temperature = platform_sfputil.get_highest_temperature() + highest_temperature = int(temperature) * 1000 + except Exception as e: + sfp_temp_error("get sfp temperature error, msg:%s" % str(e)) + highest_temperature = -9999000 + + return highest_temperature + + +def write_sfp_highest_temperature(temperature): + + loop = 1000 + ret = False + try: + if os.path.exists(sfp_temperature_file) is False: + with open(sfp_temperature_file, 'w') as sfp_f: + pass + for i in range(0, loop): + ret = file_rw_lock() + if ret is True: + break + time.sleep(0.001) + + if ret is False: + sfp_temp_error("take file lock timeout") + return + + with open(sfp_temperature_file, 'w') as sfp_f: + sfp_f.write("%s\n" % str(temperature)) + + file_rw_unlock() + return + except Exception as e: + sfp_temp_error("write sfp temperature error, msg:%s" % str(e)) + file_rw_unlock() + return + + +def debug_init(): + global debuglevel + + try: + with open(SFP_TEMP_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + +def main(): + while True: + debug_init() + temperature = 0 + try: + temperature = get_sfp_highest_temperature() + write_sfp_highest_temperature(temperature) + except Exception as e: + sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) + write_sfp_highest_temperature(-9999000) + time.sleep(5) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/slot_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/slot_monitor.py new file mode 100755 index 000000000000..b8b774c8b726 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/slot_monitor.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import time +import syslog +import traceback +import operator +import click +from platform_config import SLOT_MONITOR_PARAM, MONITOR_DEV_STATUS_DECODE +from platform_util import io_rd, io_wr, wbi2cget, wbi2cset + + +SLOTMONITORDEBUG = 0 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def slotwarninglog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def slotcriticallog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def sloterror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def slotinfo(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_INFO, s) + + +def slotdebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if SLOTMONITORDEBUG == 1: + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +class SlotMonitor(): + def __init__(self): + self.preSlotStatus = [] + + def checkslot(self, ret): + slots_conf = SLOT_MONITOR_PARAM.get('slots', None) + slotpresent = MONITOR_DEV_STATUS_DECODE.get('slotpresent', None) + + if slots_conf is None or slotpresent is None: + return False + for item_slot in slots_conf: + totalerr = 0 + try: + ret_t = {} + ret_t["id"] = item_slot.get('name') + ret_t["status"] = "" + presentattr = item_slot.get('present') + gettype = presentattr.get('gettype') + presentbit = presentattr.get('presentbit') + if gettype == "io": + io_addr = presentattr.get('io_addr') + val = io_rd(io_addr) + if val is not None: + retval = val + else: + totalerr -= 1 + sloterror(" %s %s" % (item_slot.get('name'), "lpc read failed")) + else: + bus = presentattr.get('bus') + loc = presentattr.get('loc') + offset = presentattr.get('offset') + ind, val = wbi2cget(bus, loc, offset) + if ind is True: + retval = val + else: + totalerr -= 1 + sloterror(" %s %s" % (item_slot.get('name'), "i2c read failed")) + if totalerr < 0: + ret_t["status"] = "NOT OK" + ret.append(ret_t) + continue + val_t = (int(retval, 16) & (1 << presentbit)) >> presentbit + slotdebuglog("%s present:%s" % (item_slot.get('name'), slotpresent.get(val_t))) + if val_t != slotpresent.get('okval'): + ret_t["status"] = "ABSENT" + else: + ret_t["status"] = "PRESENT" + except Exception as e: + ret_t["status"] = "NOT OK" + totalerr -= 1 + sloterror("checkslot error") + sloterror(str(e)) + ret.append(ret_t) + return True + + def dealslotplugin(self, name): + slotdebuglog("enter dealslotplugin %s" % name) + # wait for slot stable + time.sleep(5) + slots_conf = SLOT_MONITOR_PARAM.get('slots', None) + if slots_conf is None: + return False + for item_slot in slots_conf: + try: + slotdebuglog("name %s, item_slot.get('name') %s" % (name, item_slot.get('name'))) + if name == item_slot.get('name'): + actattr = item_slot.get('act') + for item_act in actattr: + gettype = item_act.get('gettype') + if gettype == "io": + io_addr = item_act.get('io_addr') + value = item_act.get('value') + mask = item_act.get('mask') + val = io_rd(io_addr) + if val is None: + sloterror(" %s %s" % (name, "lpc read failed")) + continue + set_val = (int(val, 16) & mask) | value + ret = io_wr(io_addr, set_val) + if ret is not True: + sloterror(" %s %s" % (name, "lpc write failed")) + continue + slotdebuglog("io set io_addr:0x%x value:0x%x success" % (io_addr, set_val)) + elif gettype == "i2c": + bus = item_act.get('bus') + loc = item_act.get('loc') + offset = item_act.get('offset') + value = item_act.get('value') + ret, log = wbi2cset(bus, loc, offset, value) + if ret is not True: + sloterror(" %s %s %s" % (name, "i2c write failed", log)) + continue + slotdebuglog( + "i2c set bus:%d loc:0x%x offset:0x%x value:0x%x success" % + (bus, loc, offset, value)) + else: + sloterror("gettype error") + break + except Exception as e: + sloterror("dealslotplugin failed") + sloterror(str(e)) + return False + return True + + def updateSlotStatus(self): + ''' + Only two status: PRESENT and ABSENT + ''' + curSlotStatus = [] + self.checkslot(curSlotStatus) + slotdebuglog('curSlotStatus: {}\n preSlotStatus: {}'.format(curSlotStatus, self.preSlotStatus)) + if operator.eq(self.preSlotStatus, curSlotStatus) is False: + if len(self.preSlotStatus) == 0: + # first time + for i, item in enumerate(curSlotStatus): + if item['status'] == 'PRESENT': + slotdebuglog('SLOT_PLUG_IN: %s' % (item['id'])) + elif item['status'] == 'ABSENT': + slotdebuglog('SLOT_ABSENT: %s' % (item['id'])) + else: + slotdebuglog('SLOT_FAILED: %s status %s not support yet' % (item['id'], item['status'])) + self.preSlotStatus.append(item) + else: + for i, item in enumerate(curSlotStatus): + if item['status'] == self.preSlotStatus[i]['status']: + continue + if item['status'] == 'PRESENT' and self.preSlotStatus[i]['status'] == 'ABSENT': + self.dealslotplugin(item['id']) + slotinfo('SLOT_PLUG_IN: %s' % (item['id'])) + elif item['status'] == 'ABSENT' and self.preSlotStatus[i]['status'] == 'PRESENT': + slotwarninglog('SLOT_PLUG_OUT: %s' % (item['id'])) + else: + slotwarninglog('SLOT_PLUG_OUT: %s status change from %s to %s not support' % + (item['id'], self.preSlotStatus[i]['status'], item['status'])) + self.preSlotStatus.remove(self.preSlotStatus[i]) + self.preSlotStatus.insert(i, item) + + def slotmonitor(self): + self.updateSlotStatus() + return 0 + + +def doSlotMonitor(slotMonitor): + slotMonitor.slotmonitor() + + +def run(interval, slotMonitor): + # slotMonitor.devattrinit() + while True: + try: + doSlotMonitor(slotMonitor) + except Exception as e: + traceback.print_exc() + sloterror(str(e)) + time.sleep(interval) + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''slot monitor operator''' + + +@main.command() +def start(): + '''start slot monitor''' + slotinfo("slot_monitor start") + slotMonitor = SlotMonitor() + interval = SLOT_MONITOR_PARAM.get('polling_time', 1) + run(interval, slotMonitor) + + +@main.command() +def stop(): + '''stop slot monitor ''' + slotinfo("stop") + + +# device_i2c operation +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/ssdmon b/platform/broadcom/sonic-platform-modules-ragile/common/script/ssdmon new file mode 100755 index 000000000000..4290b0a68725 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/ssdmon @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +# +# ssdmon +# +# Command-line utility to check SSD health and parameters +# + +try: + import argparse + import os + import sys + + from sonic_py_common import device_info, logger +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +DEFAULT_DEVICE = "/dev/sda" +SYSLOG_IDENTIFIER = "ssdmon" + +# Global logger instance +log = logger.Logger(SYSLOG_IDENTIFIER) + +def import_ssd_api(diskdev): + """ + Loads platform specific or generic ssd_mon module from source + Raises an ImportError exception if none of above available + + Returns: + Instance of the class with SSD API implementation (vendor or generic) + """ + + # try to load platform specific module + try: + platform_path, _ = device_info.get_paths_to_platform_and_hwsku_dirs() + platform_plugins_path = os.path.join(platform_path, "plugins") + sys.path.append(os.path.abspath(platform_plugins_path)) + from ssd_util import SsdUtil + except ImportError as e: + log.log_warning("Platform specific SsdMon module not found.") + + return SsdUtil(diskdev) + +def is_number(s): + try: + float(s) + return True + except ValueError: + return False + +# ==================== Entry point ==================== +def ssdmon(): + if os.geteuid() != 0: + print("Root privileges are required for this operation") + sys.exit(1) + + parser = argparse.ArgumentParser() + parser.add_argument("-d", "--device", help="Device name to show health info", default=DEFAULT_DEVICE) + parser.add_argument("-t", "--temperature", action="store_true", default=False, help="Show only temperature") + parser.add_argument("-j", "--health", action="store_true", default=False, help="Show only health") + + args = parser.parse_args() + + ssd = import_ssd_api(args.device) + + if args.temperature: + print(ssd.get_temperature()) + return + + if args.health: + print(ssd.get_health()) + return + + print("Device Model : {}".format(ssd.get_model())) + print("Firmware : {}".format(ssd.get_firmware())) + print("Serial : {}".format(ssd.get_serial())) + print("Health : {}{}".format(ssd.get_health(), "%" if is_number(ssd.get_health()) else "")) + print("Remain Life : {}{}".format(ssd.get_remaining_life(), "%" if is_number(ssd.get_remaining_life()) else "")) + print("Temperature : {}{}".format(ssd.get_temperature(), "C" if is_number(ssd.get_temperature()) else "")) + print("SATA Rate : {}".format(ssd.get_sata_rate())) + +if __name__ == '__main__': + ssdmon() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/tty_console.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/tty_console.py new file mode 100755 index 000000000000..4fae02f5128e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/tty_console.py @@ -0,0 +1,91 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +import logging.handlers +import subprocess +import shlex +import time +import sys +import os +from platform_util import CompressedRotatingFileHandler, exec_os_cmd + +console_file = "/dev/ttyS1" +console_logfile = "/var/log/bmc-console.log" +MAX_LOG_BYTES = 20 * 1024 * 1024 +BACKUP_COUNT = 9 + +READ_SIZE = 1024 + +logger = logging.getLogger("cpu_monitor_bmc") +logger.setLevel(logging.DEBUG) +fh = CompressedRotatingFileHandler( + console_logfile, + mode='a', + maxBytes=MAX_LOG_BYTES, + backupCount=BACKUP_COUNT, + encoding=None, + delay=0) +fh.setLevel(logging.DEBUG) + +formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") +fh.setFormatter(formatter) +logger.addHandler(fh) + + +def tty_system_cmd(cmd, print_log=True): + if print_log: + logger.debug("command: %s", cmd) + status, output = exec_os_cmd(cmd) + logger.debug("command status %s", status) + logger.debug("command output:\n%s", output) + else: + status, output = exec_os_cmd(cmd) + return status, output + + +if __name__ == '__main__': + try_times = 0 + while try_times < 3: + try_times = try_times + 1 + ret, log = tty_system_cmd("stty -F /dev/ttyS1 | grep 115200", True) + if len(log) != 0 and "115200" in log: + break + tty_system_cmd("stty -F /dev/ttyS1 115200", True) + if try_times > 1: + logger.error("The %d time try to set SONiC /dev/ttyS1 115200", try_times) + + if not os.path.exists(console_file): + logger.error("device %s not exist", console_file) + sys.exit(1) + + nopen = 3 + while nopen > 0: + try: + console_fd = os.open(console_file, os.O_RDONLY) + break + except Exception as e: + logger.error(e) + logger.error("open %s failed", console_file) + nopen = nopen - 1 + time.sleep(1) + if nopen == 0: + sys.exit(1) + + try: + tmp_read = "" + while True: + dev_read = os.read(console_fd, READ_SIZE) + dev_read = str(dev_read, encoding='utf-8') + if len(dev_read) == 1 and dev_read == "\n": + continue + if dev_read[len(dev_read) - 1] == '\n': + tmp_read = tmp_read + dev_read[0:(len(dev_read) - 1)] + logger.info(tmp_read) + tmp_read = "" + else: + tmp_read = tmp_read + dev_read + + except Exception as e: + if console_fd is not None: + os.close(console_fd) + logger.error(e) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/upgrade.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/upgrade.py new file mode 100755 index 000000000000..f56712e471b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/upgrade.py @@ -0,0 +1,991 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import sys +import os +import time +import syslog +import signal +import click +from platform_util import get_value, set_value, exec_os_cmd, exec_os_cmd_log +from platform_config import UPGRADE_SUMMARY, WARM_UPGRADE_STARTED_FLAG +from warm_upgrade import WarmBasePlatform + + +############################# Error code defined ############################# +ERR_FW_CHECK_CPLD_UPGRADE = -601 # "Failed to check the device CPLD information" +ERR_FW_CHECK_FPGA_UPGRADE = -602 # "Failed to check the device FPGA information" +ERR_FW_MATCH_CPLD_UPGRADE = -603 # "Not found upgrade CPLD file." +ERR_FW_MATCH_FPGA_UPGRADE = -604 # "Not found upgrade FPGA file." +ERR_FW_SAMEVER_CPLD_UPGRADE = -605 # "The CPLD version in device is same" +ERR_FW_SAMEVER_FPGA_UPGRADE = -606 # "The FPGA version in device is same" +ERR_FW_DO_CPLD_UPGRADE = -607 # "Doing upgrade CPLD is failed." +ERR_FW_DO_FPGA_UPGRADE = -608 # "Doing upgrade FPGA is failed." +ERR_FW_UPGRADE = -609 # "Failed to upgrade firmware" +FIRMWARE_PROGRAM_EXEC_ERR = -610 # "Firmware program run error!" +ERR_FW_FILE_FOUND = -701 # "Failed to find upgrade file" +ERR_FW_HEAD_PARSE = -702 # "Failed to parse upgrade firmware head info" +ERR_FW_CONFIG_FOUND = -703 # "Failed to find config item" +ERR_FW_NOSUPPORT_HOT = -704 # "No support hot upgrade" +ERR_FW_CHECK_SIZE = -705 # "Failed to check file size" +ERR_FW_DEVICE_ACCESS = -706 # "Failed to access device" +ERR_FW_NO_FILE_SUCCESS = -707 # "No files were successfully upgraded" +ERR_FW_CARD_ABSENT = -708 # "The subcard not present" +ERR_FW_HEAD_CHECK = -709 # "Failed to check head info" +ERR_FW_FOOL_PROOF = -710 # "Failed to fool proof verification" +ERR_FW_RAISE_EXCEPTION = -711 # Code raise exception +ERR_FW_INVALID_PARAM = -712 # Invalid parameter +ERR_FW_UNZIP_FAILED = -713 # Unzip firmware failed + +FIRMWARE_SUCCESS = 0 +CHECK_OK = 0 + + +UPGRADE_DEBUG_FILE = "/etc/.upgrade_debug_flag" +UPGRADE_FILE_DIR = "/tmp/firmware/" + +UPGRADEDEBUG = 1 + +debuglevel = 0 + +COLD_UPGRADE = 1 +WARM_UPGRADE = 2 +TEST_UPGRADE = 3 +BMC_UPGRADE = 4 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def debug_init(): + global debuglevel + if os.path.exists(UPGRADE_DEBUG_FILE): + debuglevel = debuglevel | UPGRADEDEBUG + else: + debuglevel = debuglevel & ~(UPGRADEDEBUG) + + +def upgradewarninglog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("UPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def upgradecriticallog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("UPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def upgradeerror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("UPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def upgradedebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if UPGRADEDEBUG & debuglevel: + syslog.openlog("UPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def signal_init(): + signal.signal(signal.SIGINT, signal.SIG_IGN) # ignore ctrl+c signal + signal.signal(signal.SIGTERM, signal.SIG_IGN) # ignore kill signal + signal.signal(signal.SIGTSTP, signal.SIG_IGN) # ignore ctrl+z signal + + +class BasePlatform(): + + def __init__(self): + self.upgrade_param = UPGRADE_SUMMARY.copy() + self.devtype = self.upgrade_param.get('devtype', None) + self.max_slot_num = self.upgrade_param.get("max_slot_num", 0) + self.head_info_config = {} + self.slot_config = {} + self.cold_chain_config = {} + self.subtype = None + self.chain = None + self.filetype = None + self.DEVTYPE = None + self.SUBTYPE = '0' + self.TYPE = None + self.CHAIN = None + self.CHIPNAME = None + self.VERSION = None + self.FILETYPE = None + self.CRC = None + self.SUBTYPE_LIST = None + + def save_and_set_value(self, cfg_list): + for config in cfg_list: + ret, val = get_value(config) + if ret: + config["save_value"] = val + else: + upgradeerror(val) + return False, "get save value fail" + + set_val = config.get("set_value", None) + if set_val is None: + log = "save_and_set_value lack of set_val config" + upgradeerror(log) + return log + + gettype = config.get("gettype", None) + set_cmd = config.get("set_cmd", None) + if gettype == "cmd": + if set_cmd is None: + log = "save_and_set_value lack of set_cmd config" + upgradeerror(log) + return False, log + config["cmd"] = set_cmd % set_val + upgradedebuglog("save_and_set_value modify set cmd to %s" % config["cmd"]) + else: + config["value"] = set_val + upgradedebuglog("save_and_set_value modify set val to %s" % config["value"]) + + ret, log = set_value(config) + if ret is False: + upgradeerror(log) + return False, log + return True, "save and set value success" + + def recover_save_value(self, cfg_list): + total_err = 0 + for config in cfg_list: + upgradedebuglog("config: %s, recover save value" % config) + val = config.get("save_value", None) + if val is None: + upgradeerror("recover_save_value lack of save_value config") + total_err -= 1 + continue + gettype = config.get("gettype", None) + set_cmd = config.get("set_cmd", None) + if gettype == "cmd": + config["cmd"] = set_cmd % val + upgradedebuglog("recover_save_value modify set cmd to %s" % config["cmd"]) + else: + config["value"] = val + upgradedebuglog("recover_save_value modify set val to %s" % config["value"]) + + ret, log = set_value(config) + if ret is False: + upgradeerror("recover save value write failed, log: %s" % log) + total_err -= 1 + else: + upgradedebuglog("recover save value success") + if total_err < 0: + return False, "recover save value failed" + return True, "recover save value success" + + def check_slot_present(self, slot_present_config): + presentbit = slot_present_config.get('presentbit') + ret, value = get_value(slot_present_config) + if ret is False: + return "NOT OK" + if isinstance(value, str): + val_t = int(value, 16) + else: + val_t = value + val_t = (val_t & (1 << presentbit)) >> presentbit + if val_t != slot_present_config.get('okval'): + status = "ABSENT" + else: + status = "PRESENT" + return status + + def linecard_present_check(self, slot_present_config): + present_status = self.check_slot_present(slot_present_config) + if present_status == "NOT OK": + return ERR_FW_DEVICE_ACCESS, "get slot present status failed." + if present_status == "ABSENT": + return ERR_FW_CARD_ABSENT, "slot absent" + return CHECK_OK, "slot present" + + def subprocess_warm_upgrade(self, config, file, main_type, sub_type, slot): + dev_name = config.get("name", None) + status, output = self.subprocess_firmware_upgrade(config, file, main_type, sub_type, slot) + if status is False: + upgradeerror("%s warm upgrade failed" % dev_name) + return False, output + command = "warm_upgrade.py %s 0x%x 0x%x %s %s %s" % (file, main_type, sub_type, slot, self.filetype, self.chain) + upgradedebuglog("warm upgrade cmd: %s" % command) + if os.path.exists(UPGRADE_DEBUG_FILE): + status, output = exec_os_cmd_log(command) + else: + status, output = exec_os_cmd(command) + if status: + upgradeerror("%s warm upgrade failed" % dev_name) + return False, output + upgradedebuglog("%s warm upgrade success" % dev_name) + return True, "upgrade success" + + def do_fw_upg_init_cmd(self, dev_name, init_cmd_list): + # pre operation + try: + for init_cmd_config in init_cmd_list: + ret, log = set_value(init_cmd_config) + if ret is False: + upgradeerror("%s do init cmd: %s failed, msg: %s" % (dev_name, init_cmd_config, log)) + return False, log + msg = "%s firmware init cmd all set success" % dev_name + upgradedebuglog(msg) + return True, msg + except Exception as e: + return False, str(e) + + def do_fw_upg_finish_cmd(self, dev_name, finish_cmd_list): + # end operation + ret = 0 + for finish_cmd_config in finish_cmd_list: + ret_t, log = set_value(finish_cmd_config) + if ret_t is False: + upgradeerror("%s do finish cmd: %s failed, msg: %s" % (dev_name, finish_cmd_config, log)) + ret = -1 + if ret != 0: + msg = "%s firmware finish cmd exec failed" % dev_name + upgradeerror(msg) + return False, msg + msg = "%s firmware finish cmd all set success" % dev_name + upgradedebuglog(msg) + return True, msg + + def subprocess_firmware_upgrade(self, config, file, main_type, sub_type, slot): + dev_name = config.get("name", None) + init_cmd_list = config.get("init_cmd", []) + finish_cmd_list = config.get("finish_cmd", []) + try: + ret, log = self.do_fw_upg_init_cmd(dev_name, init_cmd_list) + if ret is False: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, log + time.sleep(0.5) # delay 0.5s after execute init_cmd + command = "firmware_upgrade %s 0x%x 0x%x %s" % (file, main_type, sub_type, slot) + upgradedebuglog("firmware upgrade cmd: %s" % command) + if os.path.exists(UPGRADE_DEBUG_FILE): + status, output = exec_os_cmd_log(command) + else: + status, output = exec_os_cmd(command) + if status: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + upgradeerror("%s firmware upgrade failed, msg: %s" % (dev_name, output)) + return False, output + upgradedebuglog("%s firmware upgrade success" % dev_name) + ret, log = self.do_fw_upg_finish_cmd(dev_name, init_cmd_list) + if ret is False: + return False, log + return True, "upgrade success" + except Exception as e: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, str(e) + + def subprocess_test_upgrade(self, config, file, main_type, sub_type, slot): + dev_name = config.get("name", None) + init_cmd_list = config.get("init_cmd", []) + finish_cmd_list = config.get("finish_cmd", []) + try: + ret, log = self.do_fw_upg_init_cmd(dev_name, init_cmd_list) + if ret is False: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, log + time.sleep(0.5) # delay 0.5s after execute init_cmd + command = "firmware_upgrade test %s 0x%x 0x%x %s" % (file, main_type, sub_type, slot) + upgradedebuglog("firmware upgrade cmd: %s" % command) + if os.path.exists(UPGRADE_DEBUG_FILE): + status, output = exec_os_cmd_log(command) + else: + status, output = exec_os_cmd(command) + if status: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + upgradeerror("%s test upgrade failed, msg: %s" % (dev_name, output)) + return False, output + upgradedebuglog("%s test upgrade success" % dev_name) + ret, log = self.do_fw_upg_finish_cmd(dev_name, init_cmd_list) + if ret is False: + return False, log + return True, "upgrade success" + except Exception as e: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, str(e) + + def subprocess_bmc_upgrade(self, config, file, chip_select, erase_type): + dev_name = config.get("name", None) + init_cmd_list = config.get("init_cmd", []) + finish_cmd_list = config.get("finish_cmd", []) + save_set_reg_list = config.get("save_set_reg", []) + try: + # save and set reg + ret, log = self.save_and_set_value(save_set_reg_list) + if ret is False: + upgradeerror(log) + self.recover_save_value(save_set_reg_list) + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, log + upgradedebuglog("%s save and set cmd all set success" % dev_name) + time.sleep(0.5) # delay 0.5s after execute save and set reg + + # pre operation + ret, log = self.do_fw_upg_init_cmd(dev_name, init_cmd_list) + if ret is False: + self.recover_save_value(save_set_reg_list) + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, log + + upgradedebuglog("%s bmc init cmd all set success" % dev_name) + time.sleep(0.5) # delay 0.5s after execute init_cmd + + command = "fw_upgrade upgrade %s %s %s" % (file, chip_select, erase_type) + upgradedebuglog("fw_upgrade upgrade cmd: %s" % command) + status, output = exec_os_cmd_log(command) + if status: + upgradeerror("%s bmc upgrade failed" % dev_name) + self.recover_save_value(save_set_reg_list) + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, output + upgradedebuglog("%s bmc upgrade success" % dev_name) + + ret1, log1 = self.recover_save_value(save_set_reg_list) + if ret1 is False: + upgradeerror("bmc upgrade recover save value failed, msg: %s" % log1) + ret2, log2 = self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + if ret2 is False: + upgradeerror("bmc upgrade do finish command failed, msg: %s" % log2) + if ret1 is False or ret2 is False: + return False, "bmc upgrade do recover save value or finish command failed" + return True, "upgrade success" + + except Exception as e: + self.recover_save_value(save_set_reg_list) + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, str(e) + + def file_head_param_check(self, head_info_config): + try: + self.DEVTYPE = head_info_config.get('DEVTYPE', None) + self.SUBTYPE = head_info_config.get('SUBTYPE', '0') + self.TYPE = head_info_config.get('TYPE', None) + self.CHAIN = head_info_config.get('CHAIN', None) + self.CHIPNAME = head_info_config.get('CHIPNAME', None) + self.VERSION = head_info_config.get('VERSION', None) + self.FILETYPE = head_info_config.get('FILETYPE', None) + self.CRC = head_info_config.get('CRC', None) + + if self.devtype != int(self.DEVTYPE, 16): + return ERR_FW_HEAD_CHECK, ("no support %s devtype" % self.DEVTYPE) + + if self.SUBTYPE is not None: + self.SUBTYPE_LIST = self.SUBTYPE.split(',') + self.SUBTYPE_LIST = [int(tmp_subtype, base=16) for tmp_subtype in self.SUBTYPE_LIST] + if len(self.SUBTYPE) != 0 and self.subtype not in self.SUBTYPE_LIST: + return ERR_FW_HEAD_CHECK, ("no support %s SUBTYPE" % self.SUBTYPE) + + if len(self.CHAIN) == 0 or len(self.FILETYPE) == 0: + return ERR_FW_HEAD_CHECK, ("CHAIN:%s, FILETYPE:%s get failed" % (self.CHAIN, self.FILETYPE)) + self.chain = int(self.CHAIN) + self.filetype = self.FILETYPE + upgradedebuglog("file head param: devtype:0x%x, subtype:0x%x, chain:%s, filetype:%s" + % (self.devtype, self.subtype, self.chain, self.filetype)) + return CHECK_OK, "SUCCESS" + except Exception as e: + return ERR_FW_RAISE_EXCEPTION, str(e) + + def parse_file_head(self, file): + try: + self.head_info_config = {} + with open(file, 'r', errors='ignore') as fd: + rdbuf = fd.read() + upgradedebuglog("start parse upgrade file head") + file_head_start = rdbuf.index('FILEHEADER(\n') # ponit to F + file_head_start += rdbuf[file_head_start:].index('\n') # ponit to \n + file_head_end = rdbuf.index(')\n') + header_buf = rdbuf[file_head_start + 1: file_head_end - 1] + upgradedebuglog("upgrade file head find FILEHEADER") + for line in header_buf.split('\n'): + head_list = line.split('=', 1) + head_key = head_list[0] + head_val = head_list[1] + self.head_info_config[head_key] = head_val + upgradedebuglog("file: %s head_info_config: %s" % (file, self.head_info_config)) + return CHECK_OK, "SUCCESS" + except Exception as e: + msg = "parse %s head failed, msg: %s" % (file, str(e)) + upgradeerror(msg) + return ERR_FW_RAISE_EXCEPTION, msg + + def get_file_size_k(self, file): + fsize = os.path.getsize(file) + fsize = fsize / float(1024) + return round(fsize, 2) + + def get_device_model(self, conf): + ret, val = get_value(conf) + if ret is False: + msg = "get device model failed, msg: %s" % val + return False, msg + decode_val = conf.get("decode") + if decode_val is None: + return True, val + for k, v in decode_val.items(): + if val == v: + return True, k + msg = "device model decode error, val: %s" % val + return False, msg + + def upgrade_fool_proofing(self, conf): + try: + status, dev_model = self.get_device_model(conf) + if status is False: + msg = "upgrade fool proofing get device model failed, msg: %s" % dev_model + upgradeerror(msg) + return False, msg + upgradedebuglog("get device model success, device model: %s" % dev_model) + if dev_model != self.VERSION: + msg = "upgrade fool proofing failed, device model: %s, upgrade file version: %s" % ( + dev_model, self.VERSION) + upgradedebuglog(msg) + return False, msg + msg = "upgrade fool proofing pass, device model: %s, upgrade file version: %s" % (dev_model, self.VERSION) + upgradedebuglog(msg) + return True, msg + except Exception as e: + upgradeerror(str(e)) + return False, str(e) + + def upgrading(self, config, file, devtype, subtype, slot, option_flag, erase_type=None): + dev_name = config.get("name", None) + if option_flag == COLD_UPGRADE: + status, output = self.subprocess_firmware_upgrade(config, file, devtype, subtype, slot) + elif option_flag == WARM_UPGRADE: + status, output = self.subprocess_warm_upgrade(config, file, devtype, subtype, slot) + elif option_flag == TEST_UPGRADE: + status, output = self.subprocess_test_upgrade(config, file, devtype, subtype, slot) + elif option_flag == BMC_UPGRADE: + status, output = self.subprocess_bmc_upgrade(config, file, slot, erase_type) + else: + log = "%s set error option flag" % dev_name + upgradeerror(log) + return False, log + + if status is False: + upgradeerror("%s upgrade failed" % dev_name) + return False, output + upgradedebuglog("%s upgrade success" % dev_name) + return True, "upgrade success" + + def initial_check(self, file, slot, upg_type): + try: + upgradedebuglog("BasePlatform initial_check, file: %s, slot: %s, upg_type: %s" % + (file, slot, upg_type)) + + upgradedebuglog("do file exist check...") + if not os.path.isfile(file): + msg = "%s not found" % file + upgradedebuglog(msg) + return ERR_FW_FILE_FOUND, msg + upgradedebuglog("file exist check ok") + + slot_name = "slot%d" % slot + slot_config = self.upgrade_param.get(slot_name, {}) + slot_present_config = slot_config.get("present", {}) + if len(slot_present_config) != 0: + upgradedebuglog("do %s present check..." % slot_name) + ret, log = self.linecard_present_check(slot_present_config) + if ret != CHECK_OK: + msg = "check %s present error, msg: %s" % (slot_name, log) + upgradedebuglog(msg) + return ret, msg + upgradedebuglog("%s present check ok" % slot_name) + + upgradedebuglog("do file head parse...") + self.subtype = slot_config.get("subtype", 0) + ret, log = self.parse_file_head(file) + if ret != CHECK_OK: + return ret, log + upgradedebuglog("file head parse success") + + upgradedebuglog("do file head check...") + ret, log = self.file_head_param_check(self.head_info_config) + if ret != CHECK_OK: + msg = "file: %s, head check failed, msg: %s" % (file, log) + upgradedebuglog(msg) + return ret, msg + upgradedebuglog("file head check ok") + + upgradedebuglog("get upgrade chain config...") + filetype_config = slot_config.get(self.filetype, {}) + if len(filetype_config) == 0: + msg = "file: %s filetype: %s no support" % (file, self.filetype) + upgradedebuglog(msg) + return ERR_FW_CONFIG_FOUND, msg + chain_num = "chain%s" % self.chain + chain_config = filetype_config.get(chain_num, {}) + if len(chain_config) == 0: + msg = "file: %s get %s config failed" % (file, chain_num) + upgradedebuglog(msg) + return ERR_FW_CONFIG_FOUND, msg + self.cold_chain_config = chain_config + upgradedebuglog("get %s filetype: %s %s config success" % (slot_name, self.filetype, chain_num)) + + fool_proofing = chain_config.get("fool_proofing") + if fool_proofing is not None: + upgradedebuglog("do fool proofing check...") + status, log = self.upgrade_fool_proofing(fool_proofing) + if status is False: + msg = "upgrade fool proofing check failed, msg: %s" % log + upgradedebuglog(msg) + return ERR_FW_FOOL_PROOF, msg + upgradedebuglog("do fool proofing check ok") + + if upg_type == WARM_UPGRADE: + upgradedebuglog("do support warm upgrade check...") + if chain_config.get("is_support_warm_upg", 0) != 1: + msg = "file: %s %s chain config not support warm upgrade" % (file, slot_name) + upgradedebuglog(msg) + return ERR_FW_NOSUPPORT_HOT, msg + upgradedebuglog("file: %s %s chain config support warm upgrade" % (file, slot_name)) + + filesizecheck = chain_config.get("filesizecheck", 0) + if filesizecheck != 0: + upgradedebuglog("do file size check...") + file_size = self.get_file_size_k(file) + if file_size > filesizecheck: + msg = "file: %s size: %s exceed %s" % (file, file_size, filesizecheck) + upgradedebuglog(msg) + return ERR_FW_CHECK_SIZE, msg + msg = "file: %s size: %s check ok" % (file, file_size) + upgradedebuglog(msg) + + msg = "file: %s slot: %s upgrade type: %s check ok" % (file, slot, upg_type) + upgradedebuglog(msg) + return CHECK_OK, msg + except Exception as e: + return ERR_FW_RAISE_EXCEPTION, str(e) + + def do_upgrade(self, file, slot, upg_type): + try: + ret, log = self.initial_check(file, slot, upg_type) + if ret != CHECK_OK: + return ret, log + + # start upgrading + upgradedebuglog("start upgrading") + ret, log = self.upgrading(self.cold_chain_config, file, self.devtype, self.subtype, slot, upg_type) + if ret is False: + upgradeerror("upgrade failed") + return ERR_FW_UPGRADE, log + upgradedebuglog("upgrade success") + return FIRMWARE_SUCCESS, "SUCCESS" + except Exception as e: + return ERR_FW_RAISE_EXCEPTION, str(e) + + def do_pre_check(self, conf): + ret, val = get_value(conf) + if ret is False: + msg = "pre check get value failed, msg: %s" % val + return False, msg + ok_val = conf.get("ok_val") + if val == ok_val: + msg = "pre check success, ok_val: %s, get value: %s" % (ok_val, val) + return True, msg + msg = "pre check failed, ok_val: %s, get value: %s" % (ok_val, val) + return False, msg + + def do_test(self, device, slot): + try: + # slot present check + slot_name = "slot%d" % slot + slot_config = self.upgrade_param.get(slot_name, {}) + slot_present_config = slot_config.get("present", {}) + if len(slot_present_config) != 0: + ret, log = self.linecard_present_check(slot_present_config) + if ret != CHECK_OK: + msg = "check %s present error, msg: %s" % (slot_name, log) + upgradedebuglog(msg) + return ret, msg + upgradedebuglog("%s present" % slot_name) + + # get list of devices to be tested + test_config = slot_config.get("TEST", {}) + if len(test_config) == 0: + return ERR_FW_CONFIG_FOUND, "test config no found" + device_list = test_config.get(device, []) + if len(device_list) == 0: + return ERR_FW_CONFIG_FOUND, ("logic device %s test config list not found" % device) + + # test_file existence check + for test_config in device_list: + chain_num = test_config.get("chain", None) + test_file = test_config.get("file", None) + display_name = test_config.get("display_name", None) + if chain_num is None or test_file is None or display_name is None: + log = "test_config:%s lack of config" % test_config + upgradeerror(log) + return ERR_FW_CONFIG_FOUND, log + if not os.path.isfile(test_file): + return ERR_FW_FILE_FOUND, ("%s not found" % test_file) + + # start testing + RET = 0 + pre_check_failed = 0 + pre_check_failed_summary = "" + failed_summary = "chain test failed.\ntest fail chain:" + success_summary = "test success chain:" + for test_config in device_list: + chain_num = test_config.get("chain", None) + test_file = test_config.get("file", None) + display_name = test_config.get("display_name", None) + pre_check_conf = test_config.get("pre_check", None) + if pre_check_conf is not None: + status, msg = self.do_pre_check(pre_check_conf) + if status is False: + pre_check_failed += 1 + log = "\nchain:%d, name:%s, pre check failed, msg: %s" % (chain_num, display_name, msg) + upgradedebuglog(log) + pre_check_failed_summary += log + continue + upgradedebuglog("chain:%d, name:%s, pre check ok, msg: %s" % (chain_num, display_name, msg)) + ret, log = self.do_upgrade(test_file, slot, TEST_UPGRADE) + if ret != FIRMWARE_SUCCESS: + RET = -1 + upgradeerror("chain:%d, name:%s test failed" % (chain_num, display_name)) + failed_summary += "\n chain:%d, name:%s;" % (chain_num, display_name) + else: + upgradedebuglog("chain:%d, name:%s test success" % (chain_num, display_name)) + success_summary += "\n chain:%d, name:%s;" % (chain_num, display_name) + if RET != 0: + return ERR_FW_UPGRADE, failed_summary + if pre_check_failed == len(device_list): + return ERR_FW_NO_FILE_SUCCESS, failed_summary + pre_check_failed_summary + return FIRMWARE_SUCCESS, success_summary + except Exception as e: + return ERR_FW_RAISE_EXCEPTION, str(e) + + def do_test_main(self, device, slot): + print("+================================+") + print("|Doing upgrade test, please wait.|") + ret, log = self.do_test(device, slot) + if ret == FIRMWARE_SUCCESS: + print("| test succeeded! |") + print("+================================+") + print(log) + sys.exit(0) + else: + print("| test failed! |") + print("+================================+") + print("FAILED REASON:") + print(log) + sys.exit(1) + + def do_bmc_upgrade_main(self, file, chip_select, erase_type): + bmc_upgrade_config = self.upgrade_param.get("BMC", {}) + ret, log = self.upgrading(bmc_upgrade_config, file, self.devtype, + self.subtype, chip_select, BMC_UPGRADE, erase_type) + if ret is True: + print("===========upgrade succeeded!============") + sys.exit(0) + else: + print("============upgrade failed!==============") + print("FAILED REASON:") + print("%s" % log) + sys.exit(1) + + +class FileUpg(object): + def __init__(self, config, file, devtype, subtype, slot, filetype, chain, upg_type): + self.config = config + self.file = file + self.devtype = devtype + self.subtype = subtype + self.slot = slot + self.filetype = filetype + self.chain = chain + self.upg_type = upg_type + + def __repr__(self): + return "file:%s slot:%d" % (self.file, self.slot) + + +class FwUpg(object): + def __init__(self): + self.upg_platform = BasePlatform() + self.warm_upg_platform = WarmBasePlatform() + self.max_slot_num = self.upg_platform.max_slot_num + self.file_list = [] + + def do_file_refresh(self, fw_upg_instance): + fw_upg_config = fw_upg_instance.config + fw_upg_file = fw_upg_instance.file + fw_upg_devtype = fw_upg_instance.devtype + fw_upg_subype = fw_upg_instance.subtype + fw_upg_slot = fw_upg_instance.slot + fw_upg_filetype = fw_upg_instance.filetype + fw_upg_chain = fw_upg_instance.chain + dev_name = fw_upg_config.get("name", None) + upgradedebuglog("%s start warm upgrade, file: %s, devtype:0x%x, subype: 0x%x, slot: %d, filetype: %s, chain: %d" % + (dev_name, fw_upg_file, fw_upg_devtype, fw_upg_subype, fw_upg_slot, fw_upg_filetype, fw_upg_chain)) + status, output = self.warm_upg_platform.do_warmupgrade(fw_upg_file, fw_upg_devtype, fw_upg_subype, fw_upg_slot, + fw_upg_filetype, fw_upg_chain) + if status is False: + upgradeerror("%s warm upgrade failed, msg: %s" % (dev_name, output)) + return False, output + upgradedebuglog("%s warm upgrade success" % dev_name) + return True, "upgrade success" + + def do_refresh(self): + try: + exec_os_cmd("touch %s" % WARM_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") + + # stop upper layer services access + ret, log = self.warm_upg_platform.stop_services_access() + if ret is False: + upgradeerror("stop upper layer services access failed") + upgradeerror(log) + return ERR_FW_UPGRADE, log + upgradedebuglog("stop upper layer services access success") + + for file_instance in self.file_list: + file_info = repr(file_instance) + ret, log = self.do_file_refresh(file_instance) + if ret is False: + msg = "%s refresh failed, ret:%s, \n log:%s." % (file_info, ret, log) + upgradeerror(msg) + return ERR_FW_UPGRADE, msg + upgradedebuglog("%s refresh success." % file_info) + msg = "all files refresh success." + return FIRMWARE_SUCCESS, msg + except Exception as e: + msg = "do warm upg exception happend. log:%s" % str(e) + upgradeerror(msg) + return ERR_FW_UPGRADE, msg + finally: + self.warm_upg_platform.start_services_access() + if os.path.isfile(WARM_UPGRADE_STARTED_FLAG): + exec_os_cmd("rm -rf %s" % WARM_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") + + def do_file_cold_upg(self, fw_upg_instance): + try: + upgradedebuglog("start cold upgrade") + fw_upg_config = fw_upg_instance.config + fw_upg_file = fw_upg_instance.file + fw_upg_devtype = fw_upg_instance.devtype + fw_upg_subype = fw_upg_instance.subtype + fw_upg_slot = fw_upg_instance.slot + ret, log = self.upg_platform.upgrading( + fw_upg_config, fw_upg_file, fw_upg_devtype, fw_upg_subype, fw_upg_slot, COLD_UPGRADE) + if ret is False: + upgradeerror("cold upgrade %s slot%d failed, log:%s" % (fw_upg_file, fw_upg_slot, log)) + return ERR_FW_UPGRADE, log + log = "cold upgrade %s slot%d success" % (fw_upg_file, fw_upg_slot) + upgradedebuglog(log) + return FIRMWARE_SUCCESS, log + except Exception as e: + msg = "do cold upg exception happend. log:%s" % str(e) + upgradeerror(msg) + return ERR_FW_UPGRADE, msg + + def do_file_init_check(self, file_path, slot, upg_type): + upgradedebuglog("do_file_init_check, file_path: %s, slot: %s, upg_type: %s" % (file_path, slot, upg_type)) + + if slot is None: # traverse all slots + for i in range(0, self.max_slot_num + 1): + ret, log = self.upg_platform.initial_check(file_path, i, upg_type) + if ret != CHECK_OK: + upgradedebuglog( + "file: %s, slot%d initial check not ok, ret: %d, msg: %s" % + (file_path, i, ret, log)) + accept_error = (ERR_FW_CARD_ABSENT, ERR_FW_HEAD_CHECK, ERR_FW_FOOL_PROOF) + if ret in accept_error: + msg = "file: %s, slot%d initial check ret: %d, acceptable error." % (file_path, i, ret) + upgradedebuglog(msg) + continue + return ret, log + file_instance = FileUpg(self.upg_platform.cold_chain_config, file_path, self.upg_platform.devtype, + self.upg_platform.subtype, i, self.upg_platform.filetype, self.upg_platform.chain, upg_type) + self.file_list.append(file_instance) + else: + slot = int(slot, 10) + ret, log = self.upg_platform.initial_check(file_path, slot, upg_type) + if ret != CHECK_OK: + msg = "file: %s, slot%d initial check not ok, ret: %d, msg: %s" % (file_path, slot, ret, log) + return ret, msg + file_instance = FileUpg(self.upg_platform.cold_chain_config, file_path, self.upg_platform.devtype, + self.upg_platform.subtype, slot, self.upg_platform.filetype, self.upg_platform.chain, upg_type) + self.file_list.append(file_instance) + msg = "file: %s all slots init check ok" % file_path + return CHECK_OK, msg + + def do_dir_init_check(self, path, slot, upg_type): + for root, dirs, names in os.walk(path): + # root: directory absolute path + # dirs: folder path collection under directory + # names: file path collection under directory + for filename in names: + # file_path is file absolute path + file_path = os.path.join(root, filename) + ret, log = self.do_file_init_check(file_path, slot, upg_type) + if ret != CHECK_OK: + return ret, log + msg = "all files in dir have been check ok" + upgradedebuglog(msg) + return CHECK_OK, msg + + def do_fw_upg(self, path, slot, upg_type): + match_zip_file_flag = False + try: + upgradedebuglog("do_fw_upg, path: %s, slot: %s, upg_type: %s" % (path, slot, upg_type)) + if slot is not None and not slot.isdigit(): + msg = "invalid slot param: %s" % slot + upgradeerror(msg) + return ERR_FW_INVALID_PARAM, msg + + upgradedebuglog("start init check") + if os.path.isfile(path) and path.endswith(".zip"): + upgradedebuglog("firmware upgrade via compressed package: %s" % path) + # remove origin firmware upgrade file + exec_os_cmd("rm -rf %s" % UPGRADE_FILE_DIR) + cmd = "unzip -o %s -d /tmp/" % path + if os.path.exists(UPGRADE_DEBUG_FILE): + status, output = exec_os_cmd_log(cmd) + else: + status, output = exec_os_cmd(cmd) + if status: + msg = "unzip %s failed, log: %s" % (path, output) + upgradeerror(msg) + return ERR_FW_UNZIP_FAILED, msg + match_zip_file_flag = True + path = UPGRADE_FILE_DIR + + if os.path.isdir(path): + ret, msg = self.do_dir_init_check(path, slot, upg_type) + elif os.path.isfile(path): + ret, msg = self.do_file_init_check(path, slot, upg_type) + else: + ret = ERR_FW_FILE_FOUND + msg = "path: %s not found" % path + upgradeerror(msg) + + if ret != CHECK_OK: + return ret, msg + + # self.file_list is a collection of all check ok files + if len(self.file_list) == 0: + msg = "all file upgrade check not be satisfied." + upgradeerror(msg) + return ERR_FW_NO_FILE_SUCCESS, msg + + SUCCUSS_FILE_SUMMARY = "SUCCESS FILE: \n" + # file cold upgrade + upgradedebuglog("start all files cold upgrade") + for file_instance in self.file_list: + file_info = repr(file_instance) + ret, log = self.do_file_cold_upg(file_instance) + if ret != FIRMWARE_SUCCESS: + msg = "%s cold upgrade failed, ret:%d, \n log:\n%s." % (file_info, ret, log) + upgradeerror(msg) + return ret, msg + SUCCUSS_FILE_SUMMARY += "%s \n" % file_info + upgradedebuglog("%s cold upgrade success." % file_info) + + # file refresh upgrade + if upg_type == WARM_UPGRADE: + upgradedebuglog("start all files refresh upgrade") + ret, log = self.do_refresh() + if ret != FIRMWARE_SUCCESS: + return ret, log + + msg = "all file upgrade success" + upgradedebuglog(msg) + return FIRMWARE_SUCCESS, SUCCUSS_FILE_SUMMARY + except Exception as e: + msg = "do dir upgrade exception happend. log: %s" % str(e) + upgradeerror(msg) + return ERR_FW_UPGRADE, msg + finally: + if match_zip_file_flag is True: + exec_os_cmd("rm -rf %s" % UPGRADE_FILE_DIR) + + def fw_upg(self, path, slot, upg_type): + print("+================================+") + print("| Doing upgrade, please wait... |") + ret, log = self.do_fw_upg(path, slot, upg_type) + if ret == FIRMWARE_SUCCESS: + print("| upgrade succeeded! |") + print("+================================+") + print(log) + sys.exit(0) + else: + print("| upgrade failed! |") + print("+================================+") + print("FAILED REASON:") + print("%s" % log) + sys.exit(1) + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''upgrade script''' + + +# cold upgrade +@main.command() +@click.argument('file_name', required=True) +@click.argument('slot_num', required=False, default=None) +def cold(file_name, slot_num): + '''cold upgrade''' + fwupg = FwUpg() + fwupg.fw_upg(file_name, slot_num, COLD_UPGRADE) + + +# warm upgrade +@main.command() +@click.argument('file_name', required=True) +@click.argument('slot_num', required=False, default=None) +def warm(file_name, slot_num): + '''warm upgrade''' + fwupg = FwUpg() + fwupg.fw_upg(file_name, slot_num, WARM_UPGRADE) + + +# test upgrade +@main.command() +@click.argument('device', required=True) +@click.argument('slot_num', required=True) +def test(device, slot_num): + '''upgrade test''' + platform = BasePlatform() + platform.do_test_main(device, int(slot_num)) + + +# BMC upgrade +@main.command() +@click.argument('file_name', required=True) +@click.argument('chip_select', required=False, default="2") +@click.argument('erase_type', required=False, default="full") +def bmc(file_name, chip_select, erase_type): + '''BMC upgrade''' + platform = BasePlatform() + platform.do_bmc_upgrade_main(file_name, chip_select, erase_type) + + +if __name__ == '__main__': + signal_init() + debug_init() + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/warm_upgrade.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/warm_upgrade.py new file mode 100755 index 000000000000..69a310faa606 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/warm_upgrade.py @@ -0,0 +1,514 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import sys +import os +import time +import syslog +import signal +import click +from platform_util import get_value, set_value, exec_os_cmd, exec_os_cmd_log +from platform_config import WARM_UPGRADE_PARAM + + +WARM_UPGRADE_DEBUG_FILE = "/etc/.warm_upgrade_debug_flag" + +WARMUPGRADEDEBUG = 1 + +debuglevel = 0 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def debug_init(): + global debuglevel + if os.path.exists(WARM_UPGRADE_DEBUG_FILE): + debuglevel = debuglevel | WARMUPGRADEDEBUG + else: + debuglevel = debuglevel & ~(WARMUPGRADEDEBUG) + + +def warmupgradewarninglog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("WARMUPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def warmupgradecriticallog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("WARMUPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def warmupgradeerror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("WARMUPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def warmupgradedebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if WARMUPGRADEDEBUG & debuglevel: + syslog.openlog("WARMUPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def subprocess_warm_upgrade(file, main_type, sub_type, slot): + command = "firmware_upgrade %s 0x%x 0x%x %s" % (file, main_type, sub_type, slot) + warmupgradedebuglog("warm upgrade firmware cmd:%s" % command) + if os.path.exists(WARM_UPGRADE_DEBUG_FILE): + return exec_os_cmd_log(command) + return exec_os_cmd(command) + + +def signal_init(): + signal.signal(signal.SIGINT, signal.SIG_IGN) # ignore ctrl+c signal + signal.signal(signal.SIGTERM, signal.SIG_IGN) # ignore kill signal + signal.signal(signal.SIGTSTP, signal.SIG_IGN) # ignore ctrl+z signal + + +class RefreshUpgradeBase(object): + + def __init__(self, config, slot_num, devtype, subtype): + self._config = config + self._slot_num = slot_num + self._devtype = devtype + self._subtype = subtype + self.device_name = self._config.get("name", None) + self.refresh_file = self._config.get("refresh_file", None) + self.init_cmd_list = self._config.get("init_cmd", []) + self.save_set_reg_list = self._config.get("save_set_reg", []) + self.rw_recover_reg_list = self._config.get("rw_recover_reg", []) + self.after_upgrade_delay = self._config.get("after_upgrade_delay", None) + self.after_upgrade_delay_timeout = self._config.get("after_upgrade_delay_timeout", None) + self.refresh_finish_flag_check_config = self._config.get("refresh_finish_flag_check", None) + self.access_check_reg_config = self._config.get("access_check_reg", {}) + self.time_delay = 0 + self.finish_cmd_list = self._config.get("finish_cmd", []) + + def get_config(self): + pass + + def get_slot_num(self): + pass + + def save_value(self, cfg_list): + for config in cfg_list: + ret, val = get_value(config) + if ret: + config["value"] = val + else: + warmupgradeerror(val) + return False, val + return True, "save value success" + + def save_and_set_value(self, cfg_list): + for config in cfg_list: + ret, val = get_value(config) + if ret: + config["save_value"] = val + else: + warmupgradeerror(val) + return False, "get save value fail" + set_val = config.get("set_value", None) + if set_val is not None: + config["value"] = set_val + else: + warmupgradeerror("save_and_set_value lack of set_val config") + return False, "set value is not config" + ret, log = set_value(config) + if ret is False: + warmupgradeerror(log) + return False, log + return True, "save value success" + + def recover_value(self, cfg_list): + fail_flag = 0 + for config in cfg_list: + ret, log = set_value(config) + if ret is False: + fail_flag = -1 + warmupgradeerror("recover_value set_value failed, log: %s" % log) + if fail_flag != 0: + warmupgradeerror("recover_value write failed") + return False, "recover write failed" + return True, "recover write success" + + def recover_save_value(self, cfg_list): + total_err = 0 + for config in cfg_list: + val = config.get("save_value", None) + if val is None: + warmupgradeerror("recover_save_value lack of save_value config") + total_err -= 1 + continue + config["value"] = val + ret, log = set_value(config) + if ret is False: + total_err -= 1 + warmupgradeerror("recover save value write failed, log: %s" % log) + else: + warmupgradedebuglog("recover save value success") + if total_err < 0: + return False, "recover save value failed" + return True, "recover save value success" + + def do_fw_upg_init_cmd(self, init_cmd_list): + # pre operation + try: + for init_cmd_config in init_cmd_list: + ret, log = set_value(init_cmd_config) + if ret is False: + warmupgradeerror("%s do init cmd: %s failed, msg: %s" % (self.device_name, init_cmd_config, log)) + return False, log + msg = "%s warm upgrade init cmd all set success" % self.device_name + warmupgradedebuglog(msg) + return True, msg + except Exception as e: + return False, str(e) + + def do_fw_upg_finish_cmd(self, finish_cmd_list): + # end operation + total_err = 0 + for finish_cmd_config in finish_cmd_list: + ret_t, log = set_value(finish_cmd_config) + if ret_t is False: + warmupgradeerror("%s do finish cmd: %s failed, msg: %s" % (self.device_name, finish_cmd_config, log)) + total_err -= 1 + if total_err < 0: + msg = "%s warm upgrade finish cmd exec failed" % self.device_name + warmupgradeerror(msg) + return False, msg + msg = "%s warm upgrade finish cmd all set success" % self.device_name + warmupgradedebuglog(msg) + return True, msg + + def access_test(self, config): + # polling execute command + polling_cmd_list = config.get("polling_cmd", []) + for polling_cmd_config in polling_cmd_list: + ret, log = set_value(polling_cmd_config) + if ret is False: + warmupgradeerror(log) + return False + polling_delay = config.get("polling_delay", None) + if polling_delay is not None: + time.sleep(polling_delay) + + # record check val + check_val = config.get("value", None) + # write value + ret, log = set_value(config) + if ret is False: + warmupgradeerror(log) + return False + # read value + ret, val = get_value(config) + if ret is False: + warmupgradeerror(val) + return False + + # compare write and read val + warmupgradedebuglog("check_val:%s" % check_val) + warmupgradedebuglog("get_value:%s" % val) + if val != check_val: + warmupgradeerror("check_val:%s != get_value:%s" % (check_val, val)) + return False + return True + + def check_value(self, config): + # record check val + check_val = config.get("value", None) + ret, val = get_value(config) + if ret is False: + warmupgradeerror(val) + return False + # compare write and read val + warmupgradedebuglog("check_val:%s" % check_val) + warmupgradedebuglog("get_value:%s" % val) + if val != check_val: + warmupgradeerror("check_val:%s != get_value:%s" % (check_val, val)) + return False + return True + + def refresh_file_upgrade(self): + try: + warmupgradedebuglog("start %s warm upgrading" % self.device_name) + + # save and set reg + ret, log = self.save_and_set_value(self.save_set_reg_list) + if ret is False: + warmupgradeerror(log) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("%s save and set reg cmd all set success" % self.device_name) + time.sleep(0.5) # delay 0.5s after execute save and set reg + + # pre operation + ret, log = self.do_fw_upg_init_cmd(self.init_cmd_list) + if ret is False: + warmupgradeerror(log) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + time.sleep(0.5) # delay 0.5s after execute init_cmd + + # save reg + ret, log = self.save_value(self.rw_recover_reg_list) + if ret is False: + warmupgradeerror("%s save reg failed" % self.device_name) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("%s all reg save success" % self.device_name) + + # upgrade refresh file + if self.refresh_file is not None: + status, output = subprocess_warm_upgrade( + self.refresh_file, self._devtype, self._subtype, self._slot_num) + if status: + log = "%s refresh file upg failed, msg: %s" % (self.device_name, output) + warmupgradeerror(log) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("%s refresh file upg success" % self.device_name) + + # delay the preset time after the upgrade is complete + if self.after_upgrade_delay is not None: + time.sleep(self.after_upgrade_delay) + + # check something in the timeout period + if self.after_upgrade_delay_timeout is not None: + while self.time_delay < self.after_upgrade_delay_timeout: + + # check refresh finish flag + if self.refresh_finish_flag_check_config is not None: + ret = self.check_value(self.refresh_finish_flag_check_config) + if ret is False: + time.sleep(1) + self.time_delay = self.time_delay + 1 + warmupgradedebuglog("doing refresh_finish_flag_check, time_delay:%s" % self.time_delay) + continue + warmupgradedebuglog("%s upgrade_finish_flag_check success. self.time_delay:%d" + % (self.device_name, self.time_delay)) + + # doing logic device rw access test + ret = self.access_test(self.access_check_reg_config) + if ret: + warmupgradedebuglog( + "%s rw test success. self.time_delay:%d" % + (self.device_name, self.time_delay)) + break + time.sleep(1) + self.time_delay = self.time_delay + 1 + warmupgradedebuglog("doing access_test, self.time_delay:%s" % self.time_delay) + + if self.time_delay >= self.after_upgrade_delay_timeout: + log = "wait %s access test timeout" % self.device_name + warmupgradeerror(log) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("%s access test success" % self.device_name) + + # recover reg + ret, log = self.recover_value(self.rw_recover_reg_list) + if ret is False: + warmupgradeerror("recover %s reg failed" % self.device_name) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("recover %s reg success" % self.device_name) + # finally + ret1, log1 = self.recover_save_value(self.save_set_reg_list) + if ret1 is False: + warmupgradeerror("bmc upgrade recover save value failed, msg: %s" % log1) + ret2, log2 = self.do_fw_upg_finish_cmd(self.finish_cmd_list) + if ret2 is False: + warmupgradeerror("bmc upgrade do finish command failed, msg: %s" % log2) + if ret1 is False or ret2 is False: + return False, "upgrading %s recover save value or finish command failed" % self.device_name + return True, "upgrading %s success" % self.device_name + + except Exception as e: + log = "refresh file upgrade Exception happend, error log : %s" % str(e) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + + +class RefreshUpgrade(RefreshUpgradeBase): + + def __init__(self, config, slot_num, devtype, subtype): + super(RefreshUpgrade, self).__init__(config, slot_num, devtype, subtype) + + def get_config(self): + super(RefreshUpgrade, self).get_config() + return self._config + + def get_slot_num(self): + super(RefreshUpgrade, self).get_slot_num() + return self._slot_num + + +class WarmBasePlatform(): + + def __init__(self): + signal_init() + debug_init() + self.warm_upgrade_param = WARM_UPGRADE_PARAM.copy() + self.stop_services_cmd_list = self.warm_upgrade_param.get("stop_services_cmd", []) + self.start_services_cmd_list = self.warm_upgrade_param.get("start_services_cmd", []) + self.__warm_upgrade_config_list = [] + + def execute_command_list(self, cmd_list): + for cmd_item in cmd_list: + warmupgradedebuglog("execute cmd: %s" % cmd_item) + status, output = exec_os_cmd(cmd_item) + if status: + log = "execute %s failed, msg: %s" % (cmd_item, output) + warmupgradeerror(log) + return False, log + return True, "execute success" + + def stop_services_access(self): + return self.execute_command_list(self.stop_services_cmd_list) + + def start_services_access(self): + return self.execute_command_list(self.start_services_cmd_list) + + def check_slot_present(self, slot_present_config): + totalerr = 0 + presentbit = slot_present_config.get('presentbit') + ret, value = get_value(slot_present_config) + if ret is False: + return "NOT OK" + if isinstance(value, str): + val_t = int(value, 16) + else: + val_t = value + val_t = (val_t & (1 << presentbit)) >> presentbit + if val_t != slot_present_config.get('okval'): + status = "ABSENT" + else: + status = "PRESENT" + return status + + def linecard_present_check(self, slot_name, slot_present_config): + present_status = self.check_slot_present(slot_present_config) + present_status_tuple = ("ABSENT", "NOT OK") + if present_status in present_status_tuple: + return False, ("%s not present, warm upgrade exit" % slot_name) + warmupgradedebuglog("%s present" % slot_name) + return True, ("%s present" % slot_name) + + def start_warmupgrade(self): + try: + # start refresh file upgrade process + for dev in self.__warm_upgrade_config_list: + ret, log = dev.refresh_file_upgrade() + if ret is False: + return ret, log + return True, "all success" + except Exception as e: + log = "Exception happend, error log : %s" % str(e) + return False, log + + def do_warmupgrade(self, file, main_type, sub_type, slot, file_type, chain): + try: + # upgrade file existence check + if not os.path.isfile(file): + return False, "%s not found" % file + + # get slot config + slot_name = "slot%d" % slot + slot_config = self.warm_upgrade_param.get(slot_name, {}) + if len(slot_config) == 0: + return False, ("%s config not found" % slot_name) + + # linecard present check + slot_present_config = slot_config.get("present", {}) + if len(slot_present_config) != 0: + ret, log = self.linecard_present_check(slot_name, slot_present_config) + if ret is False: + return False, log + + # match file_type and chain_num get chain_config + file_type_config = slot_config.get(file_type, {}) + chain_name = "chain%d" % chain + chain_list = file_type_config.get(chain_name, []) + self.__warm_upgrade_config_list = [] + for refresh_config in chain_list: + # refresh_file existence check + refresh_file_judge_flag = refresh_config.get("refresh_file_judge_flag", 0) + if refresh_file_judge_flag == 1: + refresh_file = refresh_config.get("refresh_file", None) + if not os.path.isfile(refresh_file): + log = "%s not found" % refresh_file + return False, log + # each refresh_config add as an instance of RefreshUpgrade Class + refresh_instance = RefreshUpgrade(refresh_config, slot, main_type, sub_type) + self.__warm_upgrade_config_list.append(refresh_instance) + + ret, log = self.start_warmupgrade() + if ret is False: + warmupgradeerror("doing warm upgrade failed") + warmupgradeerror(log) + return ret, log + + except Exception as e: + log = "Exception happend, error log : %s" % str(e) + return False, log + return True, "all success" + + def do_warm_upgrade(self, file, main_type, sub_type, slot, file_type, chain): + print("+================================+") + print("|Begin warm upgrade, please wait..|") + ret, log = self.do_warmupgrade(file, main_type, sub_type, slot, file_type, chain) + if ret: + print("| warm upgrade succeeded! |") + print("+================================+") + sys.exit(0) + else: + print("| warm upgrade failed! |") + print("+================================+") + print("FAILED REASON:") + print("%s" % log) + sys.exit(1) + + +@click.group(invoke_without_command=True, context_settings=CONTEXT_SETTINGS) +@click.argument('file', required=True) +@click.argument('main_type', required=True) +@click.argument('sub_type', required=True) +@click.argument('slot', required=True) +@click.argument('file_type', required=True) +@click.argument('chain', required=True) +def main(file, main_type, sub_type, slot, file_type, chain): + '''warm upgrade''' + signal_init() + debug_init() + platform = WarmBasePlatform() + platform.do_warm_upgrade(file, int(main_type, 16), int(sub_type, 16), int(slot), file_type, int(chain)) + + +# warm upgrade +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_driver.service b/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_driver.service new file mode 100644 index 000000000000..08a49d695c92 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_driver.service @@ -0,0 +1,15 @@ +[Unit] +Description= Global Initialize platform drivers. +After=local-fs.target +Before=pmon.service platform_process.service +#DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/platform_driver.py start +ExecStop=/usr/local/bin/platform_driver.py stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_process.service b/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_process.service new file mode 100644 index 000000000000..7bd853152752 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_process.service @@ -0,0 +1,15 @@ +[Unit] +Description= Global Load process. +After=platform_driver.service +Requires=platform_driver.service +#DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/platform_process.py start +ExecStop=/usr/local/bin/platform_process.py stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/__init__.py new file mode 100644 index 000000000000..b70995a582fc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "thermal", "psu", "fan", "fan_drawer", "watchdog"] +from . import platform diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/chassis.py new file mode 100644 index 000000000000..adbd4e746c36 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/chassis.py @@ -0,0 +1,520 @@ +#!/usr/bin/env python3 + +############################################################################# +# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import time + import sys + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.psu import Psu + # from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer + from sonic_platform.thermal import Thermal + # from sonic_platform.watchdog import Watchdog + from sonic_platform.component import Component + from sonic_platform.eeprom import Eeprom + from sonic_platform.dcdc import Dcdc + from plat_hal.baseutil import baseutil + + from plat_hal.interface import interface + +except ImportError as error: + raise ImportError(str(error) + "- required module not found")from error + + +class Chassis(ChassisBase): + """ + Platform-specific Chassis class + """ + # List of Dcdc objects representing all dcdc + # available on the chassis + _dcdc_list = None + + STATUS_INSERTED = "1" + STATUS_REMOVED = "0" + STATUS_NORMAL = "0" + STATUS_ABNORMAL = "1" + sfp_present_dict = {} + fan_present_dict = {} + voltage_status_dict = {} + + def __init__(self): + ChassisBase.__init__(self) + self._dcdc_list = [] + self.int_case = interface() + # Initialize SFP list + + # sfp.py will read eeprom contents and retrive the eeprom data. + # It will also provide support sfp controls like reset and setting + # low power mode. + # We pass the eeprom path and sfp control path from chassis.py + # So that sfp.py implementation can be generic to all platforms + try: + self._sfp_list = [] + self.port_num = baseutil.get_config().get("sfps", None).get("port_num", 0) + self.port_start_index = baseutil.get_config().get("sfps", None).get("port_index_start", 0) + # fix problem with first index is 1, we add a fake sfp node + if self.port_start_index == 1: + self._sfp_list.append(Sfp(1)) + + # sfp id always start at 1 + for index in range(1, self.port_num + 1): + self._sfp_list.append(Sfp(index)) + + for i in range(self.port_start_index, self.port_start_index + self.port_num): + self.sfp_present_dict[i] = self.STATUS_REMOVED + + except Exception as err: + print("SFP init error: %s" % str(err)) + + try: + self._eeprom = Eeprom(self.int_case) + except Exception as err: + print("EEPROM INIT ERROR %s" % str(err)) + + # Initialize watchdog + # self._watchdog = Watchdog() + fantray_num = self.int_case.get_fan_total_number() + for index in range(fantray_num): + fandrawer = FanDrawer(self.int_case, index + 1) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + + psu_num = self.int_case.get_psu_total_number() + for index in range(psu_num): + psuobj = Psu(self.int_case, index + 1) + self._psu_list.append(psuobj) + + thermal_num = self.int_case.get_temp_id_number() + for index in range(thermal_num): + thermalobj = Thermal(self.int_case, index + 1) + self._thermal_list.append(thermalobj) + + component_num = self.int_case.get_cpld_total_number() + for index in range(component_num): + componentobj = Component(self.int_case, index + 1) + self._component_list.append(componentobj) + + dcdc_num = self.int_case.get_dcdc_total_number() + for index in range(dcdc_num): + dcdcobj = Dcdc(self.int_case, index + 1) + self._dcdc_list.append(dcdcobj) + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + name = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + name = sys_eeprom.modelstr(e) + if name is None: + return '' + return name + + 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 chassis + Returns: + string: Model/part number of chassis + """ + model = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + model = sys_eeprom.modelnumber(e) + if model is None: + return '' + return model + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + serial_number = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + serial_number = sys_eeprom.serial_number_str(e) + if serial_number is None: + return '' + + return serial_number + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + device_version = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + device_version = sys_eeprom.deviceversion(e) + if device_version is None: + return '' + + return device_version + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self.get_serial_number() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis 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 initizalize_system_led(self): + return True + + def set_status_led(self, color): + return False + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + ret, color = self.int_case.get_led_color_by_type('SYS_LED') + if ret is True: + return color + return 'N/A' + + 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' + """ + base_mac = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + base_mac = sys_eeprom.base_mac_addr(e) + if base_mac is None: + return '' + + return base_mac.upper() + + 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. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return {} + return sys_eeprom.system_eeprom_info() + + def get_thermal_manager(self): + """ + Retrieves thermal manager class on this chassis + :return: A class derived from ThermalManagerBase representing the + specified thermal manager. ThermalManagerBase is returned as default + """ + return False + + 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. + """ + reset_num = self.int_case.get_cpu_reset_num() + # cold reboot + if reset_num == 0: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + def get_module(self, index): + """ + Retrieves module represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the module to + retrieve + + Returns: + An object dervied from ModuleBase representing the specified + module + """ + module = None + + try: + if self.get_num_modules(): + module = self._module_list[index] + except IndexError: + sys.stderr.write("Module index {} out of range (0-{})\n".format( + index, len(self._module_list) - 1)) + + return module + + def get_fan_drawer(self, index): + """ + Retrieves fan drawers represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the fan drawer to + retrieve + + Returns: + An object dervied from FanDrawerBase representing the specified fan + drawer + """ + fan_drawer = None + + try: + if self.get_num_fan_drawers(): + fan_drawer = self._fan_drawer_list[index] + except IndexError: + sys.stderr.write("Fan drawer index {} out of range (0-{})\n".format( + index, len(self._fan_drawer_list) - 1)) + + return fan_drawer + + 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. + """ + + change_event_dict = {"fan": {}, "sfp": {}, "voltage": {}} + + start_time = time.time() + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print("get_change_event:Invalid timeout value: %s" % timeout) + return False, change_event_dict + + end_time = start_time + timeout + if start_time > end_time: + print("get_change_event:time wrap / invalid timeout value: %s" % timeout) + return False, change_event_dict # Time wrap or possibly incorrect timeout + try: + while timeout >= 0: + # check for sfp + sfp_change_dict = self.get_transceiver_change_event() + # check for fan + fan_change_dict = self.get_fan_change_event() + # check for voltage + voltage_change_dict = self.get_voltage_change_event() + + if sfp_change_dict or fan_change_dict or voltage_change_dict: + change_event_dict["sfp"] = sfp_change_dict + change_event_dict["fan"] = fan_change_dict + change_event_dict["voltage"] = voltage_change_dict + return True, change_event_dict + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, change_event_dict + except Exception as e: + print(e) + print("get_change_event: Should not reach here.") + return False, change_event_dict + + def get_transceiver_change_event(self): + current_sfp_present_dict = {} + ret_dict = {} + + # Check for OIR events and return ret_dict + for i in range(self.port_start_index, self.port_start_index + self.port_num): + sfp = self._sfp_list[i] + if sfp.get_presence(): + current_sfp_present_dict[i] = self.STATUS_INSERTED + + else: + current_sfp_present_dict[i] = self.STATUS_REMOVED + + # Update reg value + if current_sfp_present_dict == self.sfp_present_dict: + return ret_dict + + for index, status in current_sfp_present_dict.items(): + if self.sfp_present_dict[index] != status: + ret_dict[index] = status + + self.sfp_present_dict = current_sfp_present_dict + + return ret_dict + + def get_fan_change_event(self): + current_fan_present_dict = {} + ret_dict = {} + + # Check for OIR events and return ret_dict + for index, fan in enumerate(self._fan_list): + if fan.get_presence() is True: + current_fan_present_dict[index] = self.STATUS_INSERTED + else: + current_fan_present_dict[index] = self.STATUS_REMOVED + + if len(self.fan_present_dict) == 0: # first time + self.fan_present_dict = current_fan_present_dict + return {} + + if current_fan_present_dict == self.fan_present_dict: + return {} + + # updated fan_present_dict + for index, status in current_fan_present_dict.items(): + if self.fan_present_dict[index] != status: + ret_dict[str(index)] = status + self.fan_present_dict = current_fan_present_dict + return ret_dict + + def get_voltage_change_event(self): + current_voltage_status_dict = {} + ret_dict = {} + + # Check for OIR events and return ret_dict + for index, dcdc in enumerate(self._dcdc_list): + name = dcdc.get_name() + value = dcdc.get_value() + high = dcdc.get_high_threshold() + low = dcdc.get_low_threshold() + if (value is None) or (value > high) or (value < low): + current_voltage_status_dict[name] = self.STATUS_ABNORMAL + else: + current_voltage_status_dict[name] = self.STATUS_NORMAL + + if len(self.voltage_status_dict) == 0: # first time + self.voltage_status_dict = current_voltage_status_dict + return {} + + if current_voltage_status_dict == self.voltage_status_dict: + return {} + + # updated voltage_status_dict + for name, status in current_voltage_status_dict.items(): + if self.voltage_status_dict[name] != status: + ret_dict[name] = status + self.voltage_status_dict = current_voltage_status_dict + return ret_dict + + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/component.py new file mode 100644 index 000000000000..3181d0508d45 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/component.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python3 + +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import time + import subprocess + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Component(ComponentBase): + """Platform-specific Component class""" + + def __init__(self, interface_obj, index): + self.cpld_dict = {} + self.int_case = interface_obj + self.index = index + self.update_time = 0 + self.cpld_id = "CPLD" + str(index) + + def cpld_dict_update(self): + local_time = time.time() + if not self.cpld_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + self.cpld_dict = self.int_case.get_cpld_version_by_id(self.cpld_id) + + def get_slot(self): + self.cpld_dict_update() + return self.cpld_dict["Slot"] + + def get_warm_upgrade_flag(self): + self.cpld_dict_update() + return self.cpld_dict["Warm"] + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + self.cpld_dict_update() + return self.cpld_dict["Name"] + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + self.cpld_dict_update() + return self.cpld_dict["Desc"] + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Note: the firmware version will be read from HW + + Returns: + A string containing the firmware version of the component + """ + self.cpld_dict_update() + return self.cpld_dict["Version"] + + def get_available_firmware_version(self, image_path): + """ + Retrieves the available firmware version of the component + + Note: the firmware version will be read from image + + Args: + image_path: A string, path to firmware image + + Returns: + A string containing the available firmware version of the component + """ + raise NotImplementedError + + def get_firmware_update_notification(self, image_path): + """ + Retrieves a notification on what should be done in order to complete + the component firmware update + + Args: + image_path: A string, path to firmware image + + Returns: + A string containing the component firmware update notification if required. + By default 'None' value will be used, which indicates that no actions are required + """ + return None + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + This API performs firmware installation only: this may/may not be the same as firmware update. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this must be done manually by user + + Note: in case immediate actions are required to complete the component firmware update + (e.g., reboot, power cycle, etc.) - will be done automatically by API and no return value provided + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + cmdstr = "upgrade.py cold %s %d" % (image_path, self.get_slot()) + status, output = subprocess.getstatusoutput(cmdstr) + if status == 0: + print("INFO: %s firmware upgrade succeeded" % self.get_name()) + return True + print("%s upgrade failed. status:%d, output:\n%s" % (self.get_name(), status, output)) + return False + + def update_firmware(self, image_path): + """ + Updates firmware of the component + + This API performs firmware update: it assumes firmware installation and loading in a single call. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically by API + + Args: + image_path: A string, path to firmware image + + Raises: + RuntimeError: update failed + """ + if self.get_warm_upgrade_flag() == 1: # use warm upgrade + cmdstr = "upgrade.py warm %s %d" % (image_path, self.get_slot()) + else: + cmdstr = "upgrade.py cold %s %d" % (image_path, self.get_slot()) + status, output = subprocess.getstatusoutput(cmdstr) + if status == 0: + if self.get_warm_upgrade_flag() != 1: # not support warm upgrade, need to reboot + reboot_log = "update %s firmware %s, the system is going to reboot now." % (self.get_name(), image_path) + reboot_log_cmd = "echo '%s' > /dev/ttyS0" % reboot_log + print(reboot_log) + subprocess.call(reboot_log_cmd) + subprocess.call("sync") + time.sleep(3) + subprocess.call("reboot") + print("INFO: %s firmware version up-to-date" % self.get_name()) + return None + raise RuntimeError(output) + + def auto_update_firmware(self, image_path, boot_type): + """ + Updates firmware of the component + + This API performs firmware update automatically based on boot_type: it assumes firmware installation + and/or creating a loading task during the reboot, if needed, in a single call. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically during the reboot. + The loading task will be created by API. + + Args: + image_path: A string, path to firmware image + boot_type: A string, reboot type following the upgrade + - none/fast/warm/cold + + Returns: + Output: A return code + return_code: An integer number, status of component firmware auto-update + - return code of a positive number indicates successful auto-update + - status_installed = 1 + - status_updated = 2 + - status_scheduled = 3 + - return_code of a negative number indicates failed auto-update + - status_err_boot_type = -1 + - status_err_image = -2 + - status_err_unknown = -3 + + Raises: + RuntimeError: auto-update failure cause + """ + if self.get_warm_upgrade_flag() == 1: # use warm upgrade + cmdstr = "upgrade.py warm %s %d" % (image_path, self.get_slot()) + else: + cmdstr = "upgrade.py cold %s %d" % (image_path, self.get_slot()) + status, output = subprocess.getstatusoutput(cmdstr) + if status == 0: + reboot_log = "update %s firmware %s, the system is going to reboot now." % (self.get_name(), image_path) + reboot_log_cmd = "echo '%s' > /dev/ttyS0" % reboot_log + print(reboot_log) + subprocess.call(reboot_log_cmd) + subprocess.call("sync") + time.sleep(3) + if boot_type == "none": + subprocess.call("sync") + elif boot_type == "cold": + subprocess.call("reboot_ctrl.py reset power") + else: + subprocess.call("reboot") + print("INFO: %s firmware version up-to-date" % self.get_name()) + return 2 + print("%s upgrade failed. status:%d, output:\n%s" % (self.get_name(), status, output)) + return -3 diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/dcdc.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/dcdc.py new file mode 100644 index 000000000000..494d4aa610dc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/dcdc.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## +import time + + +class Dcdc(object): + + def __init__(self, interface_obj, index): + self.dcdc_dict = {} + self.int_case = interface_obj + self.index = index + self.update_time = 0 + self.dcdc_id = "DCDC" + str(index) + + def dcdc_dict_update(self): + local_time = time.time() + if not self.dcdc_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + self.dcdc_dict = self.int_case.get_dcdc_by_id(self.dcdc_id) + + def get_name(self): + """ + Retrieves the name of the sensor + + Returns: + string: The name of the sensor + """ + self.dcdc_dict_update() + return self.dcdc_dict["Name"] + + def get_value(self): + """ + Retrieves current value reading from sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["Value"] + if value is None: + value = 0 + return round(float(value), 3) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["High"] + if value is None: + value = 0 + return round(float(value), 3) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["Low"] + if value is None: + value = 0 + return round(float(value), 3) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["Max"] + if value is None: + value = 0 + return round(float(value), 3) + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["Min"] + if value is None: + value = 0 + return round(float(value), 3) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/eeprom.py new file mode 100644 index 000000000000..05fcc3c25678 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/eeprom.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +######################################################################## +# +# Module contains platform specific implementation of SONiC Platform +# Base API and provides the EEPROMs' information. +# +# The different EEPROMs available are as follows: +# - System EEPROM : Contains Serial number, Service tag, Base MA +# address, etc. in ONIE TlvInfo EEPROM format. +# - PSU EEPROM : Contains Serial number, Part number, Service Tag, +# PSU type, Revision. +# - Fan EEPROM : Contains Serial number, Part number, Service Tag, +# Fan type, Number of Fans in Fantray, Revision. +######################################################################## + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as error: + raise ImportError(str(error) + "- required module not found") from error + + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, interface_obj): + self.int_case = interface_obj + self.name = "ONIE_E2" + + eeprom_path = self.int_case.get_onie_e2_path(self.name) + if eeprom_path is None: + raise ValueError("get eeprom path failed") + + super().__init__(eeprom_path, 0, "", True) + + def modelnumber(self, e): + ''' + Returns the value field of the model(part) number TLV as a string + ''' + (is_valid, t) = self.get_tlv_field(e, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return super().part_number_str(e) + + return t[2].decode("ascii") + + def deviceversion(self, e): + ''' + Returns the value field of the Device Version as a string + ''' + (is_valid, t) = self.get_tlv_field(e, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return str(ord(t[2])) + + def 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. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + ''' + sys_eeprom_dict = {} + e = self.read_eeprom() + if self._TLV_HDR_ENABLED: + if not self.is_valid_tlvinfo_header(e): + return {} + total_len = (e[9] << 8) | e[10] + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_len + else: + tlv_index = self.eeprom_start + tlv_end = self._TLV_INFO_MAX_LEN + + while (tlv_index + 2) < len(e) and tlv_index < tlv_end: + if not self.is_valid_tlv(e[tlv_index:]): + break + + tlv = e[tlv_index:tlv_index + 2 + e[tlv_index + 1]] + code = "0x%02X" % tlv[0] + name, value = self.decoder(None, tlv) + sys_eeprom_dict[code] = value + + if e[tlv_index] == self._TLV_CODE_QUANTA_CRC or \ + e[tlv_index] == self._TLV_CODE_CRC_32: + break + tlv_index += e[tlv_index + 1] + 2 + + return sys_eeprom_dict diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan.py new file mode 100644 index 000000000000..9499e721a0f9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python3 +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform. +# +######################################################################## + +try: + import time + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, interface_obj, fantray_index, fan_index, psu_fan=False, psu_index=0): + self.fan_dict = {} + self.int_case = interface_obj + self.fantray_index = fantray_index + self.fan_index = fan_index + self.psu_index = psu_index + self.is_psu_fan = psu_fan + self.update_time = 0 + if not self.is_psu_fan: + self.name = "FAN" + str(fantray_index) + else: + self.name = "PSU" + str(psu_index) + + def fan_dict_update(self): + local_time = time.time() + if not self.fan_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + if not self.is_psu_fan: + self.fan_dict = self.int_case.get_fan_info(self.name) + else: + self.fan_dict = self.int_case.get_psu_fru_info(self.name) + + def get_name(self): + """ + Retrieves the fan name + Returns: + string: The name of the device + """ + if not self.is_psu_fan: + return "Fantray{}_{}".format(self.fantray_index, self.fan_index) + return "PSU{}_FAN{}".format(self.psu_index, self.fan_index) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + string: Part number of FAN + """ + if not self.is_psu_fan: + self.fan_dict_update() + return self.fan_dict["NAME"] + return 'N/A' + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + string: Serial number of FAN + """ + if not self.is_psu_fan: + self.fan_dict_update() + return self.fan_dict["SN"] + return 'N/A' + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + if not self.is_psu_fan: + return self.int_case.get_fan_presence(self.name) + return self.int_case.get_psu_presence(self.name) + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + if not self.get_presence(): + return False + + if not self.is_psu_fan: + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor pwm + rotor_name = "Rotor" + str(self.fan_index) + value = fan_dir[rotor_name]["Speed"] + min_speed = fan_dir[rotor_name]["SpeedMin"] + max_speed = fan_dir[rotor_name]["SpeedMax"] + tolerance = fan_dir[rotor_name]["Tolerance"] + else: + psu_status_dict = self.int_case.get_psu_status(self.name) + value = psu_status_dict["FanSpeed"]["Value"] + min_speed = psu_status_dict["FanSpeed"]["Min"] + max_speed = psu_status_dict["FanSpeed"]["Max"] + tolerance = psu_status_dict["FanSpeed"]["Tolerance"] + + if isinstance(tolerance, str) or tolerance is None: + tolerance = 30 + + if isinstance(value, str) or value is None: + return False + + if value < min_speed: + return False + + speed = int(value * 100 / max_speed) + if speed > 100: + speed = 100 + elif speed < 0: + speed = 0 + target = self.get_target_speed() + + if (speed - target) > target * tolerance / 100: + return False + if (target - speed) > target * tolerance / 100: + return False + + 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 True + + def get_direction(self): + """ + Retrieves the fan airflow direction + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Notes: + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. + """ + self.fan_dict_update() + air_flow = self.fan_dict["AirFlow"] + if air_flow is not None: + return air_flow + return self.FAN_DIRECTION_NOT_APPLICABLE + + 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 not self.get_presence(): + return 0 + + if not self.is_psu_fan: + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor pwm + rotor_name = "Rotor" + str(self.fan_index) + value = fan_dir[rotor_name]["Speed"] + max_speed = fan_dir[rotor_name]["SpeedMax"] + else: + psu_status_dict = self.int_case.get_psu_status(self.name) + value = psu_status_dict["FanSpeed"]["Value"] + max_speed = psu_status_dict["FanSpeed"]["Max"] + + if isinstance(value, str) or value is None: + return 0 + pwm = value * 100 / max_speed + if pwm > 100: + pwm = 100 + elif pwm < 0: + pwm = 0 + return int(pwm) + + 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 + """ + # The default tolerance value is fixed as 30% + if not self.is_psu_fan: + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor tolerance + rotor_name = "Rotor" + str(self.fan_index) + tolerance = fan_dir[rotor_name]["Tolerance"] + else: + psu_status_dict = self.int_case.get_psu_status(self.name) + tolerance = psu_status_dict["FanSpeed"]["Tolerance"] + + if isinstance(tolerance, str) or tolerance is None: + return 30 + return tolerance + + def fan_set_speed_pwm(self, pwm): + status = self.int_case.set_fan_speed_pwm(self.name, self.fan_index, pwm) + if status == -1: + return False + return True + + def set_speed(self, speed): + """ + Set fan speed to expected value + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + bool: True if set success, False if fail. + """ + if not self.is_psu_fan: + return self.fan_set_speed_pwm(speed) + return self.int_case.set_psu_fan_speed_pwm(self.name, int(speed)) + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if set success, False if fail. + """ + # not supported + return False + + def get_status_led(self): + """ + Gets the state of the Fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.is_psu_fan: + # No LED available for PSU Fan + return 'N/A' + + if not self.get_presence(): + return 'N/A' + + ret, color = self.int_case.get_fan_led(self.name) + if ret is True: + return color + return 'N/A' + + 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) + """ + if not self.is_psu_fan: + # get fan rotor pwm + pwm = int(self.int_case.get_fan_speed_pwm(self.name, self.fan_index)) + else: + psu_status_dict = self.int_case.get_psu_status(self.name) + if psu_status_dict["InputStatus"] is False: + pwm = 0 + else: + pwm = self.get_speed() # target equal to real pwm, to avoid alarm + return int(pwm) + + def get_vendor(self): + """ + Retrieves the vendor name of the fan + + Returns: + string: Vendor name of fan + """ + if not self.is_psu_fan: + return "WB" + return 'N/A' + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + if not self.is_psu_fan: + self.fan_dict_update() + return self.fan_dict["HW"] + return 'N/A' diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..f0b039648158 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan_drawer.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +# +# fan_drawer_base.py +# +# Abstract base class for implementing a platform-specific class with which +# to interact with a fan drawer module in SONiC +# + +try: + import time + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class FanDrawer(FanDrawerBase): + """ + Abstract base class for interfacing with a fan drawer + """ + # Device type definition. Note, this is a constant. + DEVICE_TYPE = "fan_drawer" + + def __init__(self, interface_obj, fantray_index): + FanDrawerBase.__init__(self) + self.fantray_dict = {} + self.fantray_update_time = 0 + self.fantray_index = fantray_index + self.int_case = interface_obj + self.fantrayname = "FAN" + str(fantray_index) + self.num_fans_per_fantray = self.int_case.get_fan_rotor_number(self.fantrayname) + for i in range(self.num_fans_per_fantray): + self._fan_list.append(Fan(interface_obj, fantray_index, i + 1)) + + def fantray_dict_update(self): + local_time = time.time() + # update data every 1 seconds + if not self.fantray_dict or (local_time - self.fantray_update_time) >= 1: + self.fantray_update_time = local_time + self.fantray_dict = self.int_case.get_fan_info(self.fantrayname) + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return "Fantray{}".format(self.fantray_index) + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + return self.int_case.get_fan_presence(self.fantrayname) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + string: Part number of FAN + """ + self.fantray_dict_update() + return self.fantray_dict["NAME"] + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + string: Serial number of FAN + """ + self.fantray_dict_update() + return self.fantray_dict["SN"] + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + self.fantray_dict_update() + return self.fantray_dict["HW"] + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + for i in range(self.num_fans_per_fantray): + if self._fan_list[i].get_status() is False: + return False + 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 True + + def get_num_fans(self): + """ + Retrieves the number of fans available on this fan drawer + Returns: + An integer, the number of fan modules available on this fan drawer + """ + return len(self._fan_list) + + def get_all_fans(self): + """ + Retrieves all fan modules available on this fan drawer + Returns: + A list of objects derived from FanBase representing all fan + modules available on this fan drawer + """ + return self._fan_list + + 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 + """ + # not supported + return False + + def get_status_led(self): + """ + Gets the state of the Fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if not self.get_presence(): + return 'N/A' + + ret, color = self.int_case.get_fan_led(self.fantrayname) + if ret is True: + return color + return 'N/A' + + def get_maximum_consumed_power(self): + """ + Retrives the maximum power drawn by Fan Drawer + + Returns: + A float, with value of the maximum consumable power of the + component. + """ + self.fantray_dict_update() + return self.fantray_dict["PowerMax"] diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/pcie.py new file mode 100644 index 000000000000..8ea66f339e96 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/pcie.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +######################################################################## +# +# Module contains a platform specific implementation of SONiC Platform +# Base PCIe class +# +######################################################################## + +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Pcie(PcieUtil): + """Platform-specific Pcie class""" + + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/platform.py new file mode 100644 index 000000000000..4d6fe03d93ac --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/platform.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +############################################################################# +# +# 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") from e + + +class Platform(PlatformBase): + """ + Platform-specific class + """ + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/psu.py new file mode 100644 index 000000000000..a9f7e87d2027 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/psu.py @@ -0,0 +1,359 @@ +#!/usr/bin/env python3 +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + + +try: + import time + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Psu(PsuBase): + """Platform-specific PSU class""" + + def __init__(self, interface_obj, index): + self.psu_dict = {} + self.psu_status_dict = {} + self.psu_power_dict = {} + self._fan_list = [] + self._thermal_list = [] + self.int_case = interface_obj + self.index = index + self.name = "PSU" + str(index) + + self.psu_dict_update_time = 0 + self.psu_status_dict_update_time = 0 + self.psu_power_dict_update_time = 0 + + self._fan_list.append(Fan(self.int_case, 1, 1, psu_fan=True, psu_index=index)) + + def psu_dict_update(self): + local_time = time.time() + if not self.psu_dict or (local_time - self.psu_dict_update_time) >= 1: # update data every 1 seconds + self.psu_dict_update_time = local_time + self.psu_dict = self.int_case.get_psu_fru_info(self.name) + + def psu_status_dict_update(self): + local_time = time.time() + if not self.psu_status_dict or ( + local_time - self.psu_status_dict_update_time) >= 1: # update data every 1 seconds + self.psu_status_dict_update_time = local_time + self.psu_status_dict = self.int_case.get_psu_status(self.name) + + def psu_power_dict_update(self): + local_time = time.time() + if not self.psu_power_dict or ( + local_time - self.psu_power_dict_update_time) >= 1: # update data every 1 seconds + self.psu_power_dict_update_time = local_time + self.psu_power_dict = self.int_case.get_psu_power_status(self.name) + + 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 Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + return self.int_case.get_psu_presence(self.name) + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + self.psu_dict_update() + return self.psu_dict["DisplayName"] + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + self.psu_dict_update() + return self.psu_dict["SN"] + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + return self.int_case.get_psu_input_output_status(self.name) + + 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 True + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Voltage"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Current"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Power"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + 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.int_case.get_psu_input_output_status(self.name) + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if not self.get_presence(): + return "N/A" + if self.int_case.get_psu_input_output_status(self.name): + return self.STATUS_LED_COLOR_GREEN + return self.STATUS_LED_COLOR_RED + + 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 + Returns: + bool: True if status LED state is set successfully, False if + not + """ + # not supported + return False + + 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 + """ + self.psu_status_dict_update() + value = self.psu_status_dict["Temperature"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + 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 + """ + self.psu_status_dict_update() + value = self.psu_status_dict["Temperature"]["Max"] + if value is None: + value = 0 + return round(float(value), 1) + + 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 + """ + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Voltage"]["HighAlarm"] + if value is None: + value = 0 + return round(float(value), 1) + + 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 + """ + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Voltage"]["LowAlarm"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_input_voltage(self): + """ + Get the input voltage of the PSU + + Returns: + A float number, the input voltage in volts, + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Inputs"]["Voltage"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_input_current(self): + """ + Get the input electric current of the PSU + + Returns: + A float number, the input current in amperes, e.g 220.3 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Inputs"]["Current"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_input_power(self): + """ + Get the input current energy of the PSU + + Returns: + A float number, the input power in watts, e.g. 302.6 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Inputs"]["Power"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + self.psu_dict_update() + return self.psu_dict["HW"] + + def get_vendor(self): + """ + Retrieves the vendor name of the psu + + Returns: + string: Vendor name of psu + """ + self.psu_dict_update() + return self.psu_dict["VENDOR"] + + 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 False + + def get_thermal(self, index): + """ + Retrieves thermal unit represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the thermal to + retrieve + + Returns: + An object dervied from ThermalBase representing the specified thermal + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/sfp.py new file mode 100644 index 000000000000..4667d3efcd7c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/sfp.py @@ -0,0 +1,480 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +# +# *_device.py config version instruction: +# ver 1.0 - platform api: +# "presence_cpld": { +# "dev_id": { +# [dev_id]: { +# "offset": { +# [offset]: [port_id] +# } +# } +# } +# } +# "reset_cpld": { +# "dev_id": { +# [dev_id]: { +# "offset": { +# [offset]: [port_id] +# } +# } +# } +# } +# ver 2.0 - wb_plat: +# "presence_path": "/xx/wb_plat/xx[port_id]/present" +# "eeprom_path": "/sys/bus/i2c/devices/i2c-[bus]/[bus]-0050/eeprom" +# "reset_path": "/xx/wb_plat/xx[port_id]/reset" +############################################################################# +import sys +import time +import syslog +import traceback +from abc import abstractmethod + +configfile_pre = "/usr/local/bin/" +sys.path.append(configfile_pre) + +try: + from platform_intf import * + from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase + from plat_hal.baseutil import baseutil + +except ImportError as error: + raise ImportError(str(error) + "- required module not found") from error + +LOG_DEBUG_LEVEL = 1 +LOG_WARNING_LEVEL = 2 +LOG_ERROR_LEVEL = 3 + + +class Sfp(SfpOptoeBase): + + OPTOE_DRV_TYPE1 = 1 + OPTOE_DRV_TYPE2 = 2 + OPTOE_DRV_TYPE3 = 3 + + # index must start at 1 + def __init__(self, index): + SfpOptoeBase.__init__(self) + self.sfp_type = None + sfp_config = baseutil.get_config().get("sfps", None) + self.log_level_config = sfp_config.get("log_level", LOG_WARNING_LEVEL) + # Init instance of SfpCust + ver = sfp_config.get("ver", None) + if ver is None: + self._sfplog(LOG_ERROR_LEVEL, "Get Ver Config Error!") + vers = int(float(ver)) + if vers == 1: + self._sfp_api = SfpV1(index) + elif vers == 2: + self._sfp_api = SfpV2(index) + else: + self._sfplog(LOG_ERROR_LEVEL, "Get SfpVer Error!") + + def get_eeprom_path(self): + return self._sfp_api._get_eeprom_path() + + def read_eeprom(self, offset, num_bytes): + return self._sfp_api.read_eeprom(offset, num_bytes) + + def write_eeprom(self, offset, num_bytes, write_buffer): + return self._sfp_api.write_eeprom(offset, num_bytes, write_buffer) + + def get_presence(self): + return self._sfp_api.get_presence() + + def get_transceiver_info(self): + # temporary solution for a sonic202111 bug + transceiver_info = super().get_transceiver_info() + try: + if transceiver_info["vendor_rev"] is not None: + transceiver_info["hardware_rev"] = transceiver_info["vendor_rev"] + except BaseException: + print(traceback.format_exc()) + return None + return transceiver_info + + def reset(self): + if self.get_presence() is False: + return False + + if self.sfp_type is None: + self.refresh_xcvr_api() + + if self.sfp_type == 'SFP': + self._sfplog(LOG_ERROR_LEVEL, 'SFP does not support reset') + return False + + self._sfplog(LOG_DEBUG_LEVEL, 'resetting...') + ret = self._sfp_api.set_reset(True) + if ret: + time.sleep(0.5) + ret = self._sfp_api.set_reset(False) + + return ret + + def get_lpmode(self): + if self.get_presence() is False: + return False + + if self.sfp_type is None: + self.refresh_xcvr_api() + + if self.sfp_type == 'SFP': + self._sfplog(LOG_WARNING_LEVEL, 'SFP does not support lpmode') + return False + + # implement in future + + return False + + def set_lpmode(self, lpmode): + if self.get_presence() is False: + return False + + if self.sfp_type is None or self._xcvr_api is None: + self.refresh_xcvr_api() + + if self.sfp_type == 'QSFP-DD': + return SfpOptoeBase.set_lpmode(self, lpmode) + if self.sfp_type == 'QSFP': + if lpmode: + return self._xcvr_api.set_power_override(True, lpmode) + return self._xcvr_api.set_power_override(False, lpmode) + self._sfplog(LOG_WARNING_LEVEL, 'SFP does not support lpmode') + return False + + def set_optoe_write_max(self, write_max): + """ + This func is declared and implemented by SONiC but we're not supported + so override it as NotImplemented + """ + self._sfplog(LOG_DEBUG_LEVEL, "set_optoe_write_max NotImplemented") + + def refresh_xcvr_api(self): + """ + Updates the XcvrApi associated with this SFP + """ + self._xcvr_api = self._xcvr_api_factory.create_xcvr_api() + class_name = self._xcvr_api.__class__.__name__ + optoe_type = None + # set sfp_type + if 'CmisApi' in class_name: + self.sfp_type = 'QSFP-DD' + optoe_type = self.OPTOE_DRV_TYPE3 + elif 'Sff8472Api' in class_name: + self.sfp_type = 'SFP' + optoe_type = self.OPTOE_DRV_TYPE2 + elif ('Sff8636Api' in class_name or 'Sff8436Api' in class_name): + self.sfp_type = 'QSFP' + optoe_type = self.OPTOE_DRV_TYPE1 + # set optoe driver + if optoe_type is not None: + self._sfp_api.set_optoe_type(optoe_type) + + def _sfplog(self, log_level, msg): + if log_level >= self.log_level_config: + try: + syslog.openlog("Sfp") + if log_level == LOG_DEBUG_LEVEL: + syslog.syslog(syslog.LOG_DEBUG, msg) + elif log_level == LOG_WARNING_LEVEL: + syslog.syslog(syslog.LOG_DEBUG, msg) + elif log_level == LOG_ERROR_LEVEL: + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + + except BaseException: + print(traceback.format_exc()) + + +class SfpCust(): + def __init__(self, index): + self.eeprom_path = None + self._init_config(index) + + def _init_config(self, index): + sfp_config = baseutil.get_config().get("sfps", None) + self.log_level_config = sfp_config.get("log_level", LOG_WARNING_LEVEL) + self._port_id = index + self.eeprom_retry_times = sfp_config.get("eeprom_retry_times", 0) + self.eeprom_retry_break_sec = sfp_config.get("eeprom_retry_break_sec", 0) + + def _get_eeprom_path(self): + return self.eeprom_path or None + + @abstractmethod + def get_presence(self): + pass + + def read_eeprom(self, offset, num_bytes): + try: + for i in range(self.eeprom_retry_times): + with open(self._get_eeprom_path(), mode='rb', buffering=0) as f: + f.seek(offset) + result = f.read(num_bytes) + # temporary solution for a sonic202111 bug + if len(result) < num_bytes: + result = result[::-1].zfill(num_bytes)[::-1] + if result is not None: + return bytearray(result) + time.sleep(self.eeprom_retry_break_sec) + continue + + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return None + + def write_eeprom(self, offset, num_bytes, write_buffer): + try: + for i in range(self.eeprom_retry_times): + ret = SfpOptoeBase.write_eeprom(self, offset, num_bytes, write_buffer) + if ret is False: + time.sleep(self.eeprom_retry_break_sec) + continue + break + + return ret + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + + @abstractmethod + def set_optoe_type(self, optoe_type): + pass + + @abstractmethod + def set_reset(self, reset): + pass + + def _convert_str_range_to_int_arr(self, range_str): + if not range_str: + return [] + + int_range_strs = range_str.split(',') + range_res = [] + for int_range_str in int_range_strs: + if '-' in int_range_str: + range_s = int(int_range_str.split('-')[0]) + range_e = int(int_range_str.split('-')[1]) + 1 + else: + range_s = int(int_range_str) + range_e = int(int_range_str) + 1 + + range_res = range_res + list(range(range_s, range_e)) + + return range_res + + def _sfplog(self, log_level, msg): + if log_level >= self.log_level_config: + try: + syslog.openlog("SfpCust") + if log_level == LOG_DEBUG_LEVEL: + syslog.syslog(syslog.LOG_DEBUG, msg) + elif log_level == LOG_WARNING_LEVEL: + syslog.syslog(syslog.LOG_DEBUG, msg) + elif log_level == LOG_ERROR_LEVEL: + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + + except BaseException: + print(traceback.format_exc()) + + +class SfpV1(SfpCust): + def _init_config(self, index): + super()._init_config(index) + # init presence path + sfp_config = baseutil.get_config().get("sfps", None) + self.presence_cpld = sfp_config.get("presence_cpld", None) + self.presence_val_is_present = sfp_config.get("presence_val_is_present", 0) + self._sfplog(LOG_DEBUG_LEVEL, "Done init presence path") + + # init reset path + self.reset_cpld = sfp_config.get("reset_cpld", None) + self.reset_val_is_reset = sfp_config.get("reset_val_is_reset", 0) + self._sfplog(LOG_DEBUG_LEVEL, "Done init cpld path") + + def get_presence(self): + if self.presence_cpld is None: + self._sfplog(LOG_ERROR_LEVEL, "presence_cpld is None!") + return False + try: + dev_id, offset, offset_bit = self._get_sfp_cpld_info(self.presence_cpld) + ret, info = platform_reg_read(0, dev_id, offset, 1) + if (ret is False + or info is None): + return False + return info[0] & (1 << offset_bit) == self.presence_val_is_present + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + + def read_eeprom(self, offset, num_bytes): + try: + for i in range(self.eeprom_retry_times): + ret, info = platform_sfp_read(self._port_id, offset, num_bytes) + if (ret is False + or info is None): + time.sleep(self.eeprom_retry_break_sec) + continue + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + for n in range(0, len(info)): + eeprom_raw[n] = info[n] + # temporary solution for a sonic202111 bug + if len(eeprom_raw) < num_bytes: + eeprom_raw = eeprom_raw[::-1].zfill(num_bytes)[::-1] + return bytearray(eeprom_raw) + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return None + + def write_eeprom(self, offset, num_bytes, write_buffer): + try: + for i in range(self.eeprom_retry_times): + # TODO: write_buffer is bytearray, need to convert to int array + val_list = [] + if isinstance(write_buffer, list): + val_list = write_buffer + else: + val_list.append(write_buffer) + ret, info = platform_sfp_write(self._port_id, offset, val_list) + if (ret is False + or info is None): + time.sleep(self.eeprom_retry_break_sec) + continue + return True + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + + return False + + def set_optoe_type(self, optoe_type): + ret, info = platform_get_optoe_type(self._port_id) + if ret is True and info != optoe_type: + try: + ret, _ = platform_set_optoe_type(self._port_id, optoe_type) + except Exception as err: + self._sfplog(LOG_ERROR_LEVEL, "Set optoe err %s" % err) + + def set_reset(self, reset): + if self.reset_cpld is None: + self._sfplog(LOG_ERROR_LEVEL, "reset_cpld is None!") + return False + try: + val = [] + dev_id, offset, offset_bit = self._get_sfp_cpld_info(self.reset_cpld) + ret, info = platform_reg_read(0, dev_id, offset, 1) + if self.reset_val_is_reset == 0: + if reset: + val.append(info[0] & (~(1 << offset_bit))) + else: + val.append(info[0] | (1 << offset_bit)) + else: + if reset: + val.append(info[0] | (1 << offset_bit)) + else: + val.append(info[0] & (~(1 << offset_bit))) + + ret, info = platform_reg_write(0, dev_id, offset, val) + if ret is False: + self._sfplog(LOG_ERROR_LEVEL, "platform_reg_write error!") + return False + + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + + return True + + def _get_sfp_cpld_info(self, cpld_config): + dev_id = 0 + offset = 0 + + for dev_id_temp in cpld_config["dev_id"]: + for offset_temp in cpld_config["dev_id"][dev_id_temp]["offset"]: + port_range_str = cpld_config["dev_id"][dev_id_temp]["offset"][offset_temp] + port_range_int = self._convert_str_range_to_int_arr(port_range_str) + if self._port_id in port_range_int: + dev_id = dev_id_temp + offset = offset_temp + offset_bit = port_range_int.index(self._port_id) + break + + return dev_id, offset, offset_bit + + +class SfpV2(SfpCust): + def _init_config(self, index): + super()._init_config(index) + # init eeprom path + sfp_config = baseutil.get_config().get("sfps", None) + eeprom_path_config = sfp_config.get("eeprom_path", None) + eeprom_path_key = sfp_config.get("eeprom_path_key")[self._port_id - 1] + self.eeprom_path = None if eeprom_path_config is None else eeprom_path_config % ( + eeprom_path_key, eeprom_path_key) + self._sfplog(LOG_DEBUG_LEVEL, "Done init eeprom path: %s" % self.eeprom_path) + + # init presence path + self.presence_path = None if sfp_config.get("presence_path", + None) is None else sfp_config.get("presence_path") % self._port_id + self.presence_val_is_present = sfp_config.get("presence_val_is_present", 0) + self._sfplog(LOG_DEBUG_LEVEL, "Done init presence path: %s" % self.presence_path) + + # init optoe driver path + optoe_driver_path = sfp_config.get("optoe_driver_path", None) + optoe_driver_key = sfp_config.get("optoe_driver_key")[self._port_id - 1] + self.dev_class_path = None if optoe_driver_path is None else optoe_driver_path % ( + optoe_driver_key, optoe_driver_key) + self._sfplog(LOG_DEBUG_LEVEL, "Done init optoe driver path: %s" % self.dev_class_path) + + # init reset path + self.reset_path = None if sfp_config.get( + "reset_path", + None) is None else sfp_config.get( + "reset_path", + None) % self._port_id + self.reset_val_is_reset = sfp_config.get("reset_val_is_reset", 0) + self._sfplog(LOG_DEBUG_LEVEL, "Done init reset path: %s" % self.reset_path) + + def get_presence(self): + if self.presence_path is None: + self._sfplog(LOG_ERROR_LEVEL, "presence_path is None!") + return False + try: + with open(self.presence_path, "rb") as data: + sysfs_data = data.read(1) + if sysfs_data != "": + result = int(sysfs_data, 16) + return result == self.presence_val_is_present + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + + def set_reset(self, reset): + return True + + def set_optoe_type(self, optoe_type): + if self.dev_class_path is None: + self._sfplog(LOG_ERROR_LEVEL, "dev_class_path is None!") + return False + try: + with open(self.dev_class_path, "r+") as dc_file: + dc_file_val = dc_file.read(1) + if int(dc_file_val) != optoe_type: + dc_str = "%s" % str(optoe_type) + dc_file.write(dc_str) + # dc_file.close() + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + return True diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/thermal.py new file mode 100644 index 000000000000..4632de3bc1e4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/thermal.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 + +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + import time + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Thermal(ThermalBase): + + def __init__(self, interface_obj, index): + self.temp_dict = {} + self.temperature_list = [] + self.int_case = interface_obj + self.index = index + self.update_time = 0 + self.temp_id = "TEMP" + str(index) + + def temp_dict_update(self): + local_time = time.time() + if not self.temp_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + self.temp_dict = self.int_case.get_monitor_temp_by_id(self.temp_id) + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + self.temp_dict_update() + return self.temp_dict["Api_name"] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + 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 Thermal + + Returns: + string: Model/part number of Thermal + """ + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return "N/A" + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + return "N/A" + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + self.temp_dict_update() + if (self.temp_dict["Value"] >= self.temp_dict["High"]) or (self.temp_dict["Value"] <= self.temp_dict["Low"]): + return False + + 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 get_temperature(self): + """ + 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 + """ + self.temp_dict_update() + value = self.temp_dict["Value"] + if value is None or value == self.int_case.error_ret: + return "N/A" + if len(self.temperature_list) >= 1000: + del self.temperature_list[0] + self.temperature_list.append(float(value)) + return round(float(value), 1) + + 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 + """ + self.temp_dict_update() + value = self.temp_dict["High"] + if value is None or value == self.int_case.error_ret: + return "N/A" + return round(float(value), 1) + + 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 + """ + self.temp_dict_update() + value = self.temp_dict["Low"] + if value is None or value == self.int_case.error_ret: + return "N/A" + return round(float(value), 1) + + 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 + """ + # not supported + return False + + 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 + """ + # not supported + 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 + """ + self.temp_dict_update() + value = self.temp_dict["Max"] + if value is None or value == self.int_case.error_ret: + return "N/A" + return round(float(value), 1) + + 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 + """ + self.temp_dict_update() + value = self.temp_dict["Min"] + if value is None or value == self.int_case.error_ret: + return "N/A" + return round(float(value), 1) + + 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 + """ + if len(self.temperature_list) == 0: + return "N/A" + return round(float(min(self.temperature_list)), 1) + + 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 + """ + if len(self.temperature_list) == 0: + return "N/A" + return round(float(max(self.temperature_list)), 1) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/watchdog.py new file mode 100644 index 000000000000..948337f47a9a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/watchdog.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 + +######################################################################## +# +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +import fcntl +import os +import array + +try: + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as error: + raise ImportError(str(error) + "- required module not found") from error + + +# ioctl constants +IO_WRITE = 0x40000000 +IO_READ = 0x80000000 +IO_READ_WRITE = 0xC0000000 +IO_SIZE_INT = 0x00040000 +IO_SIZE_40 = 0x00280000 +IO_TYPE_WATCHDOG = ord('W') << 8 + +WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG +WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG +WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG + +# Watchdog ioctl command +WDIOC_GETSUPPORT = 0 | WDR_40 +WDIOC_GETSTATUS = 1 | WDR_INT +WDIOC_GETBOOTSTATUS = 2 | WDR_INT +WDIOC_GETTEMP = 3 | WDR_INT +WDIOC_SETOPTIONS = 4 | WDR_INT +WDIOC_KEEPALIVE = 5 | WDR_INT +WDIOC_SETTIMEOUT = 6 | WDWR_INT +WDIOC_GETTIMEOUT = 7 | WDR_INT +WDIOC_SETPRETIMEOUT = 8 | WDWR_INT +WDIOC_GETPRETIMEOUT = 9 | WDR_INT +WDIOC_GETTIMELEFT = 10 | WDR_INT + +# Watchdog status constants +WDIOS_DISABLECARD = 0x0001 +WDIOS_ENABLECARD = 0x0002 + +WDT_COMMON_ERROR = -1 +WDT_IDENTITY = "CPLD Watchdog" +WDT_SYSFS_PATH = "/sys/class/watchdog/" + +DEFAULT_TIMEOUT = 180 + + +class Watchdog(WatchdogBase): + """ + Abstract base class for interfacing with a hardware watchdog module + """ + + def __init__(self): + self.watchdog, self.wdt_main_dev_name = self._get_wdt() + self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name + self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name + self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name + # Set default value + self._disable() + self.armed = False + self.timeout = self._gettimeout() + + def _is_wd_main(self, dev): + """ + Checks watchdog identity + """ + identity = self._read_file( + "{}/{}/identity".format(WDT_SYSFS_PATH, dev)) + return identity == WDT_IDENTITY + + def _get_wdt(self): + """ + Retrieves watchdog device + """ + wdt_main_dev_list = [dev for dev in os.listdir( + "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] + if not wdt_main_dev_list: + return None + wdt_main_dev_name = wdt_main_dev_list[0] + watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) + watchdog = os.open(watchdog_device_path, os.O_RDWR) + return watchdog, wdt_main_dev_name + + def _read_file(self, file_path): + """ + Read text file + """ + try: + with open(file_path, "r") as fd: + txt = fd.read() + except IOError: + return WDT_COMMON_ERROR + return txt.strip() + + def _enable(self): + """ + Turn on the watchdog timer + """ + req = array.array('h', [WDIOS_ENABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _disable(self): + """ + Turn off the watchdog timer + """ + req = array.array('h', [WDIOS_DISABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE) + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + req = array.array('I', [seconds]) + fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True) + return int(req[0]) + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True) + + return int(req[0]) + + def _gettimeleft(self): + """ + Get time left before watchdog timer expires + @return time left in seconds + """ + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True) + + return int(req[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: + self._settimeout(seconds) + self._enable() + 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: + 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 + + def __del__(self): + """ + Close watchdog + """ + os.close(self.watchdog) diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/compat b/platform/broadcom/sonic-platform-modules-ragile/debian/compat index 45a4fb75db86..f599e28b8ab0 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/compat +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/compat @@ -1 +1 @@ -8 +10 diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/control b/platform/broadcom/sonic-platform-modules-ragile/debian/control index 795c8219a61e..ae30aee8c0b5 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/control +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/control @@ -1,18 +1,18 @@ Source: sonic-ragile-platform-modules Section: main Priority: extra -Maintainer: support +Maintainer: support Standards-Version: 3.9.3 Package: platform-modules-ragile-ra-b6510-48v8c Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp -Package: platform-modules-ragile-ra-b6910-64c +Package: platform-modules-ragile-ra-b6510-32c Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp -Package: platform-modules-ragile-ra-b6510-32c +Package: platform-modules-ragile-ra-b6910-64c Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/copyright b/platform/broadcom/sonic-platform-modules-ragile/debian/copyright index 1e4fc20a1672..676cdeec726b 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/copyright +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/copyright @@ -1,5 +1,4 @@ Copyright (C) 2016 Microsoft, Inc -Copyright (C) 2018 Ragile Network Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.install b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.install index 568190dca044..a63d409ace41 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.install +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.install @@ -1 +1 @@ -ra-b6510-48v8c/scripts/pddf_post_driver_install.sh /usr/local/bin +ra-b6510-48v8c/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-ragile_ra-b6510-48v8c-r0 diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.postinst b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.postinst index 0d9d6a34d2a5..a8132f4f65a9 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.postinst +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.postinst @@ -7,11 +7,4 @@ if [ -e /boot/System.map-${kernel_version} ]; then depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true fi -# enable platform-service -depmod -a -# systemctl enable platform-modules-ra-b6510-48v8c.service -# systemctl start platform-modules-ra-b6510-48v8c.service -systemctl enable pddf-platform-init.service -systemctl start pddf-platform-init.service - #DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.install b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.install index 0034aa70603d..8de43ed4ed66 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.install +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.install @@ -1 +1 @@ -ra-b6920-4s/scripts/pddf_post_device_create.sh /usr/local/bin +ra-b6920-4s/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-ragile_ra-b6920-4s-r0 diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/rules b/platform/broadcom/sonic-platform-modules-ragile/debian/rules index e32da1faa711..0177d5072684 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/rules +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/rules @@ -6,17 +6,12 @@ KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) KBUILD_OUTPUT=$(KERNEL_SRC)/build -LIB_DIR = usr/lib/python3.7/dist-packages +LIB_DIR = usr/lib/python3/dist-packages CUSTOM_RULES_DIR := $(shell pwd)/debian -PLATFORM_PREFIX = "x86_64-ragile" -PLATFORM_VER = "r0" -BDIST_DIR = "dist" -BDIST_TARGET = "bdist_t" +export INSTALL_MOD_DIR top_srcdir KVERSION KERNEL_SRC CC KBUILD_OUTPUT CUSTOM_RULES_DIR -export INSTALL_MOD_DIR top_srcdir KVERSION KERNEL_SRC CC KBUILD_OUTPUT - -include $(CUSTOM_RULES_DIR)/rule-ragile.mk +include $(CUSTOM_RULES_DIR)/rule.mk #all product need common COMPILE_DIRS = $(MODULE_DIRS) @@ -24,15 +19,14 @@ COMPILE_DIRS = $(MODULE_DIRS) clean_dirs = $(MODULE_DIRS) clean_dirs += common -custom_clean_dirs := $(addprefix _clean_,$(clean_dirs) ) - +complie_clean_dirs := $(addprefix _clean_,$(clean_dirs) ) %: dh $@ -build: $(COMPILE_DIRS) +build: COMPILE_WHL @echo "build success" -$(custom_clean_dirs): +$(complie_clean_dirs): $(MAKE) -C $(patsubst _clean_%,%,$@) clean common_build : @@ -42,26 +36,29 @@ $(COMPILE_DIRS): common_build $(MAKE) -C $(MOD_SRC_DIR)/$@ dh_testdir dh_installdirs - # - # wheel pcakage - @cp -r \ - $(MOD_SRC_DIR)/common/lib/rgutil \ - $(MOD_SRC_DIR)/common/lib/eepromutil \ - $(MOD_SRC_DIR)/$@/; \ - cd $(MOD_SRC_DIR)/$@; \ - python3 setup.py bdist_wheel --bdist-dir $(BDIST_DIR) -d $(BDIST_TARGET); \ - mkdir -p build/usr/share/sonic/device/$(PLATFORM_PREFIX)_$@-$(PLATFORM_VER); \ - mkdir -p build/usr/share/sonic/device/$(PLATFORM_PREFIX)_$@-$(PLATFORM_VER)/pddf; \ - cp $(BDIST_TARGET)/*.whl build/usr/share/sonic/device/$(PLATFORM_PREFIX)_$@-$(PLATFORM_VER); \ - cp $(BDIST_TARGET)/*.whl build/usr/share/sonic/device/$(PLATFORM_PREFIX)_$@-$(PLATFORM_VER)/pddf/; \ - cd $(MOD_SRC_DIR); \ - rm -rf \ - $(MOD_SRC_DIR)/$@/rgutil \ - $(MOD_SRC_DIR)/$@/eepromutil \ - $(MOD_SRC_DIR)/$@/$(BDIST_TARGET) - - cp -r $(MOD_SRC_DIR)/common/build/* debian/platform-modules-ragile-$@/ - cp -r $(MOD_SRC_DIR)/$@/build/* debian/platform-modules-ragile-$@/ + cp -r $(MOD_SRC_DIR)/common/build/* debian/platform-modules-ragile-$@/; \ + cp -r $(MOD_SRC_DIR)/$@/build/* debian/platform-modules-ragile-$@/; \ + +COMPILE_WHL: $(COMPILE_DIRS) + @(for mod in $(MODULE_DIRS); do \ + cd $(MOD_SRC_DIR)/$${mod}; \ + cp -r $(MOD_SRC_DIR)/common/lib/plat_hal $(MOD_SRC_DIR)/$${mod}/; \ + cp -r $(MOD_SRC_DIR)/common/lib/wbutil $(MOD_SRC_DIR)/$${mod}/; \ + cp -r $(MOD_SRC_DIR)/common/lib/eepromutil $(MOD_SRC_DIR)/$${mod}/; \ + cp -r $(MOD_SRC_DIR)/common/sonic_platform $(MOD_SRC_DIR)/$${mod}/; \ + cp $(MOD_SRC_DIR)/common/script/hal_pltfm.py $(MOD_SRC_DIR)/$${mod}/hal_pltfm.py; \ + cp $(MOD_SRC_DIR)/common/script/platform_util.py $(MOD_SRC_DIR)/$${mod}/platform_util.py; \ + cp $(MOD_SRC_DIR)/common/script/platform_intf.py $(MOD_SRC_DIR)/$${mod}/platform_intf.py; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/plat_hal; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/wbutil; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/eepromutil; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/sonic_platform; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/hal_pltfm.py; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/platform_intf.py; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/platform_util.py; \ + cd $(MOD_SRC_DIR); \ + done) binary: binary-indep @echo "=======================================================" @@ -87,7 +84,7 @@ override_dh_usrlocal: override_dh_pysupport: -clean: $(custom_clean_dirs) +clean: $(complie_clean_dirs) dh_testdir dh_testroot dh_clean diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/.upgrade_test/cpld_test_header.vme b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/.upgrade_test/cpld_test_header.vme new file mode 100644 index 0000000000000000000000000000000000000000..7b149c47b31018f8b5f6818f4336f8b3a17c6811 GIT binary patch literal 413 zcmaiu!A^rf5QZ0MSXg6HMH9VkJn4n7P_?PyK+0-KEH+3;JQ0L7Z9>aNvC)$^AIxX) zA-wtoxZndYmzhky@1MzeS)?_4snaFP3ifPn*9=_;w{%85pGK$1r%C*C6j4mxvxLLT^spZky2PKDZ0rt<|M;crvGG8co}Xr!2GV;u4)9c6E}9BDP6> z^BaGat*cFeea6e`ea$vCj;pG~j!DFYh?!2$T%{r)_Zn*rD4mLCe9>yj9u dW;DE4YDu*v^;U +#include +#include +#include +#include +#include + +static int g_wb_firmware_upgrade_debug = 0; +static int g_wb_firmware_upgrade_error = 0; + +module_param(g_wb_firmware_upgrade_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_firmware_upgrade_error, int, S_IRUGO | S_IWUSR); + +#define WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_firmware_upgrade_debug) { \ + printk(KERN_INFO "[WB_FIRMWARE_UPGRADE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FIRMWARE_UPGRADE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_firmware_upgrade_error) { \ + printk(KERN_ERR "[WB_FIRMWARE_UPGRADE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 48, + .en_level[1] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* fpga */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "SPI_LOGIC", + .chain = 3, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x1A0000, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "SPI_LOGIC", + .chain = 4, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x0, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* bios */ +static firmware_upgrade_device_t firmware_upgrade_device_data3 = { + .type = "MTD_DEV", + .chain = 2, + .chip_index = 1, + .upg_type.sysfs = { + .mtd_name = "BIOS", + .flash_base = 0x800000, + }, + + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 4, + .dev = { + .platform_data = &firmware_upgrade_device_data3, + .release = firmware_device_release, + }, + }, + }; + + static int __init firmware_upgrade_device_init(void) + { + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; + } + + static void __exit firmware_upgrade_device_exit(void) + { + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&firmware_upgrade_device[i]); + } + } + } + + module_init(firmware_upgrade_device_init); + module_exit(firmware_upgrade_device_exit); + MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_dev_device.c new file mode 100644 index 000000000000..9a5173142e95 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_dev_device.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_dev_device_debug = 0; +static int g_wb_i2c_dev_device_error = 0; + +module_param(g_wb_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_dev_device_t i2c_dev_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x0d, + .i2c_name = "cpld2", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data1 = { + .i2c_bus = 8, + .i2c_addr = 0x30, + .i2c_name = "cpld3", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data2 = { + .i2c_bus = 8, + .i2c_addr = 0x31, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +struct i2c_board_info i2c_dev_device_info[] = { + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data0, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data1, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data2, + }, +}; + +static int __init wb_i2c_dev_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_dev_device_info); i++) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + i2c_dev_device_info[i].addr = i2c_dev_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_dev_device_data->i2c_bus); + if (adap == NULL) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_dev_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); + if (!client) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", + i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); + } else { + i2c_dev_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_dev_device_exit(void) +{ + int i; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_dev_device_info) - 1; i >= 0; i--) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + if (i2c_dev_device_data->client) { + i2c_unregister_device(i2c_dev_device_data->client); + i2c_dev_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_dev_device_init); +module_exit(wb_i2c_dev_device_exit); +MODULE_DESCRIPTION("I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 000000000000..0a2a8b203b3c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,224 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca954x_device_debug = 0; +static int g_wb_i2c_mux_pca954x_device_error = 0; + +module_param(g_wb_i2c_mux_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 16, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/cpld1", + .file_attr.offset = 0x60, + .file_attr.mask = 0x02, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data1 = { + .i2c_bus = 4, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 24, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/cpld1", + .file_attr.offset = 0x60, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data2 = { + .i2c_bus = 12, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 32, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data3 = { + .i2c_bus = 12, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 40, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data4 = { + .i2c_bus = 12, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 48, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data5 = { + .i2c_bus = 12, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 56, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data1, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data2, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data3, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data4, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data5, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (!client) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_ocores_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_ocores_device.c new file mode 100644 index 000000000000..ff7ba9d26fbc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_ocores_device.c @@ -0,0 +1,423 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_ocores_device_debug = 0; +static int g_wb_i2c_ocores_device_error = 0; + +module_param(g_wb_i2c_ocores_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_ocores_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_debug) { \ + printk(KERN_INFO "[WB_I2C_OCORE_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_OCORE_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_error) { \ + printk(KERN_ERR "[WB_I2C_OCORE_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_ocores_device_t i2c_ocores_device_data0 = { + .adap_nr = 2, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0800, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 0, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data1 = { + .adap_nr = 3, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0820, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 1, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data2 = { + .adap_nr = 4, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0840, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 2, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data3 = { + .adap_nr = 5, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0860, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 3, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data4 = { + .adap_nr = 6, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0880, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 4, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data5 = { + .adap_nr = 7, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08a0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 5, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data6 = { + .adap_nr = 8, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08c0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 6, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data7 = { + .adap_nr = 9, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08e0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 7, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data8 = { + .adap_nr = 10, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0900, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 8, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data9 = { + .adap_nr = 11, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0920, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 9, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data10 = { + .adap_nr = 12, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0940, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 10, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data11 = { + .adap_nr = 13, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0960, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 11, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data12 = { + .adap_nr = 14, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0980, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 12, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data13 = { + .adap_nr = 15, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x09a0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 13, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static void wb_i2c_ocores_device_release(struct device *dev) +{ + return; +} + +static struct platform_device i2c_ocores_device[] = { + { + .name = "wb-ocores-i2c", + .id = 1, + .dev = { + .platform_data = &i2c_ocores_device_data0, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 2, + .dev = { + .platform_data = &i2c_ocores_device_data1, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 3, + .dev = { + .platform_data = &i2c_ocores_device_data2, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 4, + .dev = { + .platform_data = &i2c_ocores_device_data3, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 5, + .dev = { + .platform_data = &i2c_ocores_device_data4, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 6, + .dev = { + .platform_data = &i2c_ocores_device_data5, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 7, + .dev = { + .platform_data = &i2c_ocores_device_data6, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 8, + .dev = { + .platform_data = &i2c_ocores_device_data7, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 9, + .dev = { + .platform_data = &i2c_ocores_device_data8, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 10, + .dev = { + .platform_data = &i2c_ocores_device_data9, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 11, + .dev = { + .platform_data = &i2c_ocores_device_data10, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 12, + .dev = { + .platform_data = &i2c_ocores_device_data11, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 13, + .dev = { + .platform_data = &i2c_ocores_device_data12, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 14, + .dev = { + .platform_data = &i2c_ocores_device_data13, + .release = wb_i2c_ocores_device_release, + }, + }, +}; + +static int __init wb_i2c_ocores_device_init(void) +{ + int i; + int ret = 0; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_ocores_device); i++) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + ret = platform_device_register(&i2c_ocores_device[i]); + if (ret < 0) { + i2c_ocores_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-ocores-i2c.%d register failed!\n", i + 1); + } else { + i2c_ocores_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_i2c_ocores_device_exit(void) +{ + int i; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_ocores_device) - 1; i >= 0; i--) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + if (i2c_ocores_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&i2c_ocores_device[i]); + } + } +} + +module_init(wb_i2c_ocores_device_init); +module_exit(wb_i2c_ocores_device_exit); +MODULE_DESCRIPTION("I2C OCORES Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..cc84938fff0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_io_dev_device.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data1 = { + .io_dev_name = "cpld1", + .io_base = 0x900, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 2, + .dev = { + .platform_data = &io_dev_device_data1, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..9b6b61a51735 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static lpc_drv_device_t lpc_drv_device_data_1 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x900, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x88, +}; + +static lpc_drv_device_t lpc_drv_device_data_2 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0xb00, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x90, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 2, + .dev = { + .platform_data = &lpc_drv_device_data_1, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 3, + .dev = { + .platform_data = &lpc_drv_device_data_2, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_pcie_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_pcie_dev_device.c new file mode 100644 index 000000000000..f79b29770d29 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_pcie_dev_device.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_pcie_dev_device_debug = 0; +static int g_wb_pcie_dev_device_error = 0; + +module_param(g_wb_pcie_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_pcie_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_pcie_dev_device_debug) { \ + printk(KERN_INFO "[WB_PCIE_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PCIE_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_pcie_dev_device_error) { \ + printk(KERN_ERR "[WB_PCIE_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static pci_dev_device_t pcie_dev_device_data0 = { + .pci_dev_name = "fpga0", + .pci_domain = 0x0000, + .pci_bus = 0x08, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .upg_ctrl_base = 0xa00, + .upg_flash_base = 0x1a0000, +}; + +static void wb_pcie_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device pcie_dev_device[] = { + { + .name = "wb-pci-dev", + .id = 1, + .dev = { + .platform_data = &pcie_dev_device_data0, + .release = wb_pcie_dev_device_release, + }, + }, +}; + +static int __init wb_pcie_dev_device_init(void) +{ + int i; + int ret = 0; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(pcie_dev_device); i++) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + ret = platform_device_register(&pcie_dev_device[i]); + if (ret < 0) { + pcie_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-pci-dev.%d register failed!\n", i + 1); + } else { + pcie_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_pcie_dev_device_exit(void) +{ + int i; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(pcie_dev_device) - 1; i >= 0; i--) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + if (pcie_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&pcie_dev_device[i]); + } + } +} + +module_init(wb_pcie_dev_device_init); +module_exit(wb_pcie_dev_device_exit); +MODULE_DESCRIPTION("PCIE DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..927521a384ff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,38 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_0_2=2 +cpld_i2c_dev.addr_0_2=0x0d +cpld_i2c_dev.bus_0_3=8 +cpld_i2c_dev.addr_0_3=0x30 +cpld_i2c_dev.bus_0_4=8 +cpld_i2c_dev.addr_0_4=0x31 + + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_0=0x700 +cpld_lpc_dev_0_1=0x900 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=lpc +mode_cpld_0_1=lpc +mode_cpld_0_2=i2c +mode_cpld_0_3=i2c +mode_cpld_0_4=i2c + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=5 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..e46f690f317a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,372 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=5 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=2 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x00020030 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x00020030 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=1 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x00020030 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=2 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=cpld +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.addr_1_4=0x00020030 +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=3 + +dev_present_status.mode_1_5=config +dev_present_status.src_1_5=cpld +dev_present_status.frmt_1_5=bit +dev_present_status.pola_1_5=negative +dev_present_status.addr_1_5=0x00020030 +dev_present_status.len_1_5=1 +dev_present_status.bit_offset_1_5=4 + + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x00020031 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=0 + +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=cpld +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1= +fan_roll_status.addr_1_1=0x00020034 +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=0 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x00020031 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=1 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=cpld +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1= +fan_roll_status.addr_2_1=0x00020034 +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=1 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x00020031 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=2 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=cpld +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1= +fan_roll_status.addr_3_1=0x00020034 +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=2 + +fan_roll_status.mode_4_0=config +fan_roll_status.int_cons_4_0= +fan_roll_status.src_4_0=cpld +fan_roll_status.frmt_4_0=bit +fan_roll_status.pola_4_0=positive +fan_roll_status.fpath_4_0= +fan_roll_status.addr_4_0=0x00020031 +fan_roll_status.len_4_0=1 +fan_roll_status.bit_offset_4_0=3 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=cpld +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1= +fan_roll_status.addr_4_1=0x00020034 +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=3 + +fan_roll_status.mode_5_0=config +fan_roll_status.int_cons_5_0= +fan_roll_status.src_5_0=cpld +fan_roll_status.frmt_5_0=bit +fan_roll_status.pola_5_0=positive +fan_roll_status.fpath_5_0= +fan_roll_status.addr_5_0=0x00020031 +fan_roll_status.len_5_0=1 +fan_roll_status.bit_offset_5_0=4 + +fan_roll_status.mode_5_1=config +fan_roll_status.int_cons_5_1= +fan_roll_status.src_5_1=cpld +fan_roll_status.frmt_5_1=bit +fan_roll_status.pola_5_1=positive +fan_roll_status.fpath_5_1= +fan_roll_status.addr_5_1=0x00020034 +fan_roll_status.len_5_1=1 +fan_roll_status.bit_offset_5_1=4 + + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x0002001b +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=cpld +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1=negative +fan_speed.fpath_1_1= +fan_speed.addr_1_1=0x00020025 +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0002001d +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=cpld +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1=negative +fan_speed.fpath_2_1= +fan_speed.addr_2_1=0x00020027 +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0002001f +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=cpld +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1=negative +fan_speed.fpath_3_1= +fan_speed.addr_3_1=0x00020029 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_4_0=config +fan_speed.int_cons_4_0= +fan_speed.src_4_0=cpld +fan_speed.frmt_4_0=num_bytes +fan_speed.pola_4_0=negative +fan_speed.fpath_4_0= +fan_speed.addr_4_0=0x00020021 +fan_speed.len_4_0=2 +fan_speed.bit_offset_4_0= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=cpld +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1=negative +fan_speed.fpath_4_1= +fan_speed.addr_4_1=0x0002002b +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + +fan_speed.mode_5_0=config +fan_speed.int_cons_5_0= +fan_speed.src_5_0=cpld +fan_speed.frmt_5_0=num_bytes +fan_speed.pola_5_0=negative +fan_speed.fpath_5_0= +fan_speed.addr_5_0=0x00020023 +fan_speed.len_5_0=2 +fan_speed.bit_offset_5_0= + +fan_speed.mode_5_1=config +fan_speed.int_cons_5_1= +fan_speed.src_5_1=cpld +fan_speed.frmt_5_1=num_bytes +fan_speed.pola_5_1=negative +fan_speed.fpath_5_1= +fan_speed.addr_5_1=0x0002002d +fan_speed.len_5_1=2 +fan_speed.bit_offset_5_1= + + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x00020014 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_1_1=config +fan_ratio.int_cons_1_1= +fan_ratio.src_1_1=cpld +fan_ratio.frmt_1_1=byte +fan_ratio.pola_1_1= +fan_ratio.fpath_1_1= +fan_ratio.addr_1_1=0x00020014 +fan_ratio.len_1_1=1 +fan_ratio.bit_offset_1_1= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x00020015 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_2_1=config +fan_ratio.int_cons_2_1= +fan_ratio.src_2_1=cpld +fan_ratio.frmt_2_1=byte +fan_ratio.pola_2_1= +fan_ratio.fpath_2_1= +fan_ratio.addr_2_1=0x00020015 +fan_ratio.len_2_1=1 +fan_ratio.bit_offset_2_1= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x00020016 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= + +fan_ratio.mode_3_1=config +fan_ratio.int_cons_3_1= +fan_ratio.src_3_1=cpld +fan_ratio.frmt_3_1=byte +fan_ratio.pola_3_1= +fan_ratio.fpath_3_1= +fan_ratio.addr_3_1=0x00020016 +fan_ratio.len_3_1=1 +fan_ratio.bit_offset_3_1= + +fan_ratio.mode_4_0=config +fan_ratio.int_cons_4_0= +fan_ratio.src_4_0=cpld +fan_ratio.frmt_4_0=byte +fan_ratio.pola_4_0= +fan_ratio.fpath_4_0= +fan_ratio.addr_4_0=0x00020017 +fan_ratio.len_4_0=1 +fan_ratio.bit_offset_4_0= + +fan_ratio.mode_4_1=config +fan_ratio.int_cons_4_1= +fan_ratio.src_4_1=cpld +fan_ratio.frmt_4_1=byte +fan_ratio.pola_4_1= +fan_ratio.fpath_4_1= +fan_ratio.addr_4_1=0x00020017 +fan_ratio.len_4_1=1 +fan_ratio.bit_offset_4_1= + +fan_ratio.mode_5_0=config +fan_ratio.int_cons_5_0= +fan_ratio.src_5_0=cpld +fan_ratio.frmt_5_0=byte +fan_ratio.pola_5_0= +fan_ratio.fpath_5_0= +fan_ratio.addr_5_0=0x00020018 +fan_ratio.len_5_0=1 +fan_ratio.bit_offset_5_0= + +fan_ratio.mode_5_1=config +fan_ratio.int_cons_5_1= +fan_ratio.src_5_1=cpld +fan_ratio.frmt_5_1=byte +fan_ratio.pola_5_1= +fan_ratio.fpath_5_1= +fan_ratio.addr_5_1=0x00020018 +fan_ratio.len_5_1=1 +fan_ratio.bit_offset_5_1= diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..cc4a6dae1db3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,64 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=2 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00010051 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00010051 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00010051 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00010051 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=4 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00010051 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=5 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00010051 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=6 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..ceafe3e9c17b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,306 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=32 + + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x00030010 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x00030010 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x00030010 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x00030010 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x00030010 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x00030010 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x00030010 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x00030010 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x00030011 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x00030011 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x00030011 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x00030011 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x00030011 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x00030011 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x00030011 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x00030011 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x00040010 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x00040010 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x00040010 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x00040010 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x00040010 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x00040010 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x00040010 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x00040010 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x00040011 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x00040011 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x00040011 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x00040011 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x00040011 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x00040011 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x00040011 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x00040011 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/cfg_file_name new file mode 100644 index 000000000000..5f49420441a5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,4 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/setup.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/setup.py index f36055fb4e6d..6c3916921abb 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/setup.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/setup.py @@ -3,18 +3,25 @@ setup( name='sonic-platform', version='1.0', - description='SONiC platform API implementation on RAGILE Platforms', + description='SONiC platform API implementation', license='Apache 2.0', author='SONiC Team', - author_email='support@ragile.com', + author_email='support', url='', - maintainer='RAGILE SUPPORT TEAM', + maintainer='support', maintainer_email='', packages=[ 'sonic_platform', - 'rgutil', + 'plat_hal', + 'wbutil', 'eepromutil', - 'sonic_pcie', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', ], classifiers=[ 'Development Status :: 3 - Alpha', @@ -30,4 +37,3 @@ ], keywords='sonic SONiC platform PLATFORM', ) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/cpld_test_header.vme b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/cpld_test_header.vme new file mode 100644 index 0000000000000000000000000000000000000000..083fd78f3ea1919d9d3737fe0d8d0c7b8b2ce881 GIT binary patch literal 406 zcmaiu!AgWc7{^Cl9GwWZEU4QY>mrW2O9%#{v#rqDVj^@}T%AMUt^?Upr*1u1&(K43 z?FnqO2k^UmA0NNppMS~gYSXfp);#POTEzEsNrQ-{S16)+_OzzH_2yb`frh&jGzynN zocKiSc%1|*>JQ(XrjPMM;vcLbWx(?lMPV9>2xnduTlc0w*NEL#8!^N-$!~cVJr}!X zU*U-Hx_RHReT%cEsj*`cOSm-1L@17ejCweGWq851n7EkCz1hsO3AQcUK?q#pT+$Q+ zaP`9Ix{m7r0$EYyqaQexPBa5Reu@nVOwPd9@%QJs+)cP9_xx1wT$jWNHKXIBQctQq VsrNb@^ic_@K=0eZ|8`^i#~;mYW4-_Y literal 0 HcmV?d00001 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/fpga_test_header.bin b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/fpga_test_header.bin new file mode 100644 index 000000000000..bdf9ae2139e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/fpga_test_header.bin @@ -0,0 +1,10 @@ +fpga_test_header.bin +FILEHEADER( +DEVTYPE=0x404a +TYPE=fpga +CHAIN=3 +CHIPNAME=fpga +VERSION=v0 +FILETYPE=SPI-LOGIC-DEV +CRC=0x00000000 +) diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile old mode 100755 new mode 100644 index 9e262d7c095e..1b84abef410a --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile @@ -5,10 +5,9 @@ EXTRA_CFLAGS+= -Wall SUB_BUILD_DIR = $(PWD)/build INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin -INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system/ - -KBUILD_EXTRA_SYMBOLS += $(DIR_KERNEL_SRC)/Module.symvers -export KBUILD_EXTRA_SYMBOLS +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_SYSFS_CFG_DIR = $(SUB_BUILD_DIR)/etc/plat_sysfs_cfg +INSTALL_UPGRADE_TEST_DIR = $(SUB_BUILD_DIR)/etc/.upgrade_test all: $(MAKE) -C $(KBUILD_OUTPUT) M=$(DIR_KERNEL_SRC) modules @@ -16,8 +15,12 @@ all: cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_DIR) @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi cp -r $(PWD)/config/* $(INSTALL_SCRIPT_DIR) - @if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi - cp $(PWD)/systemd/*.service $(INSTALL_SERVICE_DIR) + @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi + @if [ -d $(PWD)/hal-config/ ]; then cp -r $(PWD)/hal-config/* ${INSTALL_LIB_DIR} ;fi + @if [ ! -d ${INSTALL_SYSFS_CFG_DIR} ]; then mkdir -p ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ -d $(PWD)/plat_sysfs_cfg/ ]; then cp -r $(PWD)/plat_sysfs_cfg/* ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ ! -d ${INSTALL_UPGRADE_TEST_DIR} ]; then mkdir -p ${INSTALL_UPGRADE_TEST_DIR} ;fi + @if [ -d $(PWD)/.upgrade_test/ ]; then cp -r $(PWD)/.upgrade_test/* ${INSTALL_UPGRADE_TEST_DIR} ;fi clean: rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_config.py index 5fe30ea12848..b40926068f60 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_config.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_config.py @@ -1,484 +1,1097 @@ #!/usr/bin/python # -*- coding: UTF-8 -*- -from ragilecommon import * -PCA9548START = -1 -PCA9548BUSEND = -2 +from platform_common import * +STARTMODULE = { + "hal_fanctrl": 1, + "hal_ledctrl": 1, + "avscontrol": 1, + "dev_monitor": 1, + "pmon_syslog": 1, + "tty_console": 1, + "macledreset": 1, + "sff_temp_polling": 1, + "generate_airflow": 1, +} + +MAC_LED_RESET = {"pcibus": 8, "slot": 0, "fn": 0, "bar": 0, "offset": 64, "reset": 0x98} + +MANUINFO_CONF = { + "bios": { + "key": "BIOS", + "head": True, + "next": "onie" + }, + "bios_vendor": { + "parent": "bios", + "key": "Vendor", + "cmd": "dmidecode -t 0 |grep Vendor", + "pattern": r".*Vendor", + "separator": ":", + "arrt_index": 1, + }, + "bios_version": { + "parent": "bios", + "key": "Version", + "cmd": "dmidecode -t 0 |grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "bios_date": { + "parent": "bios", + "key": "Release Date", + "cmd": "dmidecode -t 0 |grep Release", + "pattern": r".*Release Date", + "separator": ":", + "arrt_index": 3, + }, + "onie": { + "key": "ONIE", + "next": "cpu" + }, + "onie_date": { + "parent": "onie", + "key": "Build Date", + "file": "/host/machine.conf", + "pattern": r"^onie_build_date", + "separator": "=", + "arrt_index": 1, + }, + "onie_version": { + "parent": "onie", + "key": "Version", + "file": "/host/machine.conf", + "pattern": r"^onie_version", + "separator": "=", + "arrt_index": 2, + }, + + "cpu": { + "key": "CPU", + "next": "ssd" + }, + "cpu_vendor": { + "parent": "cpu", + "key": "Vendor", + "cmd": "dmidecode --type processor |grep Manufacturer", + "pattern": r".*Manufacturer", + "separator": ":", + "arrt_index": 1, + }, + "cpu_model": { + "parent": "cpu", + "key": "Device Model", + "cmd": "dmidecode --type processor | grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "cpu_core": { + "parent": "cpu", + "key": "Core Count", + "cmd": "dmidecode --type processor | grep \"Core Count\"", + "pattern": r".*Core Count", + "separator": ":", + "arrt_index": 3, + }, + "cpu_thread": { + "parent": "cpu", + "key": "Thread Count", + "cmd": "dmidecode --type processor | grep \"Thread Count\"", + "pattern": r".*Thread Count", + "separator": ":", + "arrt_index": 4, + }, + "ssd": { + "key": "SSD", + "next": "cpld" + }, + "ssd_model": { + "parent": "ssd", + "key": "Device Model", + "cmd": "smartctl -i /dev/sda |grep \"Device Model\"", + "pattern": r".*Device Model", + "separator": ":", + "arrt_index": 1, + }, + "ssd_fw": { + "parent": "ssd", + "key": "Firmware Version", + "cmd": "smartctl -i /dev/sda |grep \"Firmware Version\"", + "pattern": r".*Firmware Version", + "separator": ":", + "arrt_index": 2, + }, + "ssd_user_cap": { + "parent": "ssd", + "key": "User Capacity", + "cmd": "smartctl -i /dev/sda |grep \"User Capacity\"", + "pattern": r".*User Capacity", + "separator": ":", + "arrt_index": 3, + }, + + "cpld": { + "key": "CPLD", + "next": "psu" + }, + + "cpld1": { + "key": "CPLD1", + "parent": "cpld", + "arrt_index": 1, + }, + "cpld1_model": { + "key": "Device Model", + "parent": "cpld1", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld1_vender": { + "key": "Vendor", + "parent": "cpld1", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld1_desc": { + "key": "Description", + "parent": "cpld1", + "config": "CPU_CPLD", + "arrt_index": 3, + }, + "cpld1_version": { + "key": "Firmware Version", + "parent": "cpld1", + "reg": { + "loc": "/dev/port", + "offset": 0x700, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld2": { + "key": "CPLD2", + "parent": "cpld", + "arrt_index": 2, + }, + "cpld2_model": { + "key": "Device Model", + "parent": "cpld2", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld2_vender": { + "key": "Vendor", + "parent": "cpld2", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld2_desc": { + "key": "Description", + "parent": "cpld2", + "config": "CONNECT_CPLD", + "arrt_index": 3, + }, + "cpld2_version": { + "key": "Firmware Version", + "parent": "cpld2", + "reg": { + "loc": "/dev/port", + "offset": 0x900, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld3": { + "key": "CPLD3", + "parent": "cpld", + "arrt_index": 3, + }, + "cpld3_model": { + "key": "Device Model", + "parent": "cpld3", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld3_vender": { + "key": "Vendor", + "parent": "cpld3", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld3_desc": { + "key": "Description", + "parent": "cpld3", + "config": "CONNECT_CPLD-FAN", + "arrt_index": 3, + }, + "cpld3_version": { + "key": "Firmware Version", + "parent": "cpld3", + "i2c": { + "bus": "2", + "loc": "0x0d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld4": { + "key": "CPLD4", + "parent": "cpld", + "arrt_index": 4, + }, + "cpld4_model": { + "key": "Device Model", + "parent": "cpld4", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld4_vender": { + "key": "Vendor", + "parent": "cpld4", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld4_desc": { + "key": "Description", + "parent": "cpld4", + "config": "MAC_CPLD1", + "arrt_index": 3, + }, + "cpld4_version": { + "key": "Firmware Version", + "parent": "cpld4", + "i2c": { + "bus": "8", + "loc": "0x30", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld5": { + "key": "CPLD5", + "parent": "cpld", + "arrt_index": 5, + }, + "cpld5_model": { + "key": "Device Model", + "parent": "cpld5", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld5_vender": { + "key": "Vendor", + "parent": "cpld5", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld5_desc": { + "key": "Description", + "parent": "cpld5", + "config": "MAC_CPLD2", + "arrt_index": 3, + }, + "cpld5_version": { + "key": "Firmware Version", + "parent": "cpld5", + "i2c": { + "bus": "8", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "psu": { + "key": "PSU", + "next": "fan" + }, + + "psu1": { + "parent": "psu", + "key": "PSU1", + "arrt_index": 1, + }, + "psu1_hw_version": { + "key": "Hardware Version", + "parent": "psu1", + "extra": { + "funcname": "getPsu", + "id": "psu1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu1_fw_version": { + "key": "Firmware Version", + "parent": "psu1", + "config": "NA", + "arrt_index": 2, + }, + + "psu2": { + "parent": "psu", + "key": "PSU2", + "arrt_index": 2, + }, + "psu2_hw_version": { + "key": "Hardware Version", + "parent": "psu2", + "extra": { + "funcname": "getPsu", + "id": "psu2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu2_fw_version": { + "key": "Firmware Version", + "parent": "psu2", + "config": "NA", + "arrt_index": 2, + }, + + "fan": { + "key": "FAN", + "next": "i210" + }, -RAGILE_CARDID = 0x0000404a -RAGILE_PRODUCTNAME = "RA-B6510-48V8C" + "fan1": { + "key": "FAN1", + "parent": "fan", + "arrt_index": 1, + }, + "fan1_hw_version": { + "key": "Hardware Version", + "parent": "fan1", + "extra": { + "funcname": "checkFan", + "id": "fan1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan1_fw_version": { + "key": "Firmware Version", + "parent": "fan1", + "config": "NA", + "arrt_index": 2, + }, + + "fan2": { + "key": "FAN2", + "parent": "fan", + "arrt_index": 2, + }, + "fan2_hw_version": { + "key": "Hardware Version", + "parent": "fan2", + "extra": { + "funcname": "checkFan", + "id": "fan2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan2_fw_version": { + "key": "Firmware Version", + "parent": "fan2", + "config": "NA", + "arrt_index": 2, + }, + + "fan3": { + "key": "FAN3", + "parent": "fan", + "arrt_index": 3, + }, + "fan3_hw_version": { + "key": "Hardware Version", + "parent": "fan3", + "extra": { + "funcname": "checkFan", + "id": "fan3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan3_fw_version": { + "key": "Firmware Version", + "parent": "fan3", + "config": "NA", + "arrt_index": 2, + }, + + "fan4": { + "key": "FAN4", + "parent": "fan", + "arrt_index": 4, + }, + "fan4_hw_version": { + "key": "Hardware Version", + "parent": "fan4", + "extra": { + "funcname": "checkFan", + "id": "fan4", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan4_fw_version": { + "key": "Firmware Version", + "parent": "fan4", + "config": "NA", + "arrt_index": 2, + }, -STARTMODULE = { - "fancontrol":1, - "avscontrol":1, - "dev_monitor":1 + "i210": { + "key": "NIC", + "next": "fpga" + }, + "i210_model": { + "parent": "i210", + "config": "NA", + "key": "Device Model", + "arrt_index": 1, + }, + "i210_vendor": { + "parent": "i210", + "config": "INTEL", + "key": "Vendor", + "arrt_index": 2, + }, + "i210_version": { + "parent": "i210", + "cmd": "ethtool -i eth0", + "pattern": r"firmware-version", + "separator": ":", + "key": "Firmware Version", + "arrt_index": 3, + }, + + "fpga": { + "key": "FPGA", + "next": "asic" + }, + "fpga_model": { + "parent": "fpga", + "config": "XC7A15T-2FGG484C", + "key": "Device Model", + "arrt_index": 1, + }, + "fpga_vendor": { + "parent": "fpga", + "config": "XILINX", + "key": "Vendor", + "arrt_index": 2, + }, + "fpga_desc": { + "parent": "fpga", + "config": "NA", + "key": "Description", + "arrt_index": 3, + }, + "fpga_hw_version": { + "parent": "fpga", + "config": "NA", + "key": "Hardware Version", + "arrt_index": 4, + }, + "fpga_fw_version": { + "parent": "fpga", + "pci": { + "bus": 8, + "slot": 0, + "fn": 0, + "bar": 0, + "offset": 0 + }, + "key": "Firmware Version", + "arrt_index": 5, + }, + "fpga_date": { + "parent": "fpga", + "pci": { + "bus": 8, + "slot": 0, + "fn": 0, + "bar": 0, + "offset": 4 + }, + "key": "Build Date", + "arrt_index": 6, + }, + "asic": { + "key": "ASIC", + }, + "sdk_model": { + "parent": "asic", + "cmd": "bcmcmd -t 1 att", + "pattern": r"^Attach", + "regular": r"(?<=\()[^)]*(?=\))", + "key": "Device Model", + "arrt_index": 1, + }, + "sdk_version": { + "parent": "asic", + "cmd": "bcmcmd -t 1 version | grep Release", + "pattern": r".*Release", + "separator": ":", + "key": "SDK Version", + "arrt_index": 2, + }, + "pci_version": { + "parent": "asic", + "cmd": "bcmcmd -t 1 \"pciephy fw version\" |grep \"PCIe FW version\"", + "pattern": r".*PCIe FW version", + "separator": ":", + "key": "PCIe Firmware Version", + "arrt_index": 3, + }, } -i2ccheck_params = {"busend":"i2c-66","retrytime":6} +PMON_SYSLOG_STATUS = { + "polling_time": 3, + "sffs": { + "present": {"path": ["/sys/wb_plat/sff/*/present"], "ABSENT": 0}, + "nochangedmsgflag": 0, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 1, + "alias": { + "sff1": "Ethernet1", + "sff2": "Ethernet2", + "sff3": "Ethernet3", + "sff4": "Ethernet4", + "sff5": "Ethernet5", + "sff6": "Ethernet6", + "sff7": "Ethernet7", + "sff8": "Ethernet8", + "sff9": "Ethernet9", + "sff10": "Ethernet10", + "sff11": "Ethernet11", + "sff12": "Ethernet12", + "sff13": "Ethernet13", + "sff14": "Ethernet14", + "sff15": "Ethernet15", + "sff16": "Ethernet16", + "sff17": "Ethernet17", + "sff18": "Ethernet18", + "sff19": "Ethernet19", + "sff20": "Ethernet20", + "sff21": "Ethernet21", + "sff22": "Ethernet22", + "sff23": "Ethernet23", + "sff24": "Ethernet24", + "sff25": "Ethernet25", + "sff26": "Ethernet26", + "sff27": "Ethernet27", + "sff28": "Ethernet28", + "sff29": "Ethernet29", + "sff30": "Ethernet30", + "sff31": "Ethernet31", + "sff32": "Ethernet32", + "sff33": "Ethernet33", + "sff34": "Ethernet34", + "sff35": "Ethernet35", + "sff36": "Ethernet36", + "sff37": "Ethernet37", + "sff38": "Ethernet38", + "sff39": "Ethernet39", + "sff40": "Ethernet40", + "sff41": "Ethernet41", + "sff42": "Ethernet42", + "sff43": "Ethernet43", + "sff44": "Ethernet44", + "sff45": "Ethernet45", + "sff46": "Ethernet46", + "sff47": "Ethernet47", + "sff48": "Ethernet48", + "sff49": "Ethernet49", + "sff50": "Ethernet50", + "sff51": "Ethernet51", + "sff52": "Ethernet52", + "sff53": "Ethernet53", + "sff54": "Ethernet54", + "sff55": "Ethernet55", + "sff56": "Ethernet56", + } + }, + "fans": { + "present": {"path": ["/sys/wb_plat/fan/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/wb_plat/fan/%s/motor0/status", 'okval': 1}, + {"path": "/sys/wb_plat/fan/%s/motor1/status", 'okval': 1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "fan1": "FAN1", + "fan2": "FAN2", + "fan3": "FAN3", + "fan4": "FAN4" + } + }, + "psus": { + "present": {"path": ["/sys/wb_plat/psu/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/wb_plat/psu/%s/output", "okval": 1}, + {"path": "/sys/wb_plat/psu/%s/alert", "okval": 0}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "psu1": "PSU1", + "psu2": "PSU2" + } + } +} + +##################### MAC Voltage adjust#################################### +MAC_DEFAULT_PARAM = [ + { + "name": "mac_core", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default": 0x74, # default value, if rov value not in range + "sdkreg": "TOP_AVS_SEL_REG", # SDK register name + "sdktype": 0, # 0: No shift operation required, 1: shift operation required + "macregloc": 24, # Shift right 24 bits + "mask": 0xff, # Use with macregloc + "rov_source": 1, # 0:get rov value from cpld, 1: get rov value from SDK + "cpld_avs": {"bus": 6, "loc": 0x0d, "offset": 0xc3, "gettype": "i2c"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x08: 0.888, + 0x72: 0.900, + 0x73: 0.894, + 0x74: 0.888, + 0x75: 0.882, + 0x76: 0.875, + 0x77: 0.869, + 0x78: 0.863, + 0x79: 0.857, + 0x7a: 0.850, + 0x7b: 0.844, + 0x7c: 0.838, + 0x7d: 0.832, + 0x7e: 0.825, + 0x7f: 0.819, + 0x80: 0.813, + 0x81: 0.807, + 0x82: 0.800, + 0x83: 0.794, + 0x84: 0.788, + 0x85: 0.782, + 0x86: 0.775, + 0x87: 0.769, + 0x88: 0.763, + 0x89: 0.757, + 0x8A: 0.750 + } + } +] + +BLACKLIST_DRIVERS = [ + {"name": "i2c_i801", "delay": 0}, +] + +DRIVERLISTS = [ + {"name": "wb_i2c_i801", "delay": 0}, + {"name": "wb_gpio_d1500", "delay": 0}, + {"name": "i2c_dev", "delay": 0}, + {"name": "wb_i2c_algo_bit", "delay": 0}, + {"name": "wb_i2c_gpio", "delay": 0}, + {"name": "i2c_mux", "delay": 0}, + {"name": "wb_gpio_device", "delay": 0}, + {"name": "wb_i2c_gpio_device gpio_sda=17 gpio_scl=1 gpio_udelay=2", "delay": 0}, + {"name": "platform_common dfd_my_type=0x404a", "delay": 0}, + {"name": "wb_lpc_drv", "delay": 0}, + {"name": "wb_lpc_drv_device", "delay": 0}, + {"name": "wb_io_dev", "delay": 0}, + {"name": "wb_io_dev_device", "delay": 0}, + {"name": "wb_fpga_pcie", "delay": 0}, + {"name": "wb_pcie_dev", "delay": 0}, + {"name": "wb_pcie_dev_device", "delay": 0}, + {"name": "wb_i2c_dev", "delay": 0}, + {"name": "wb_i2c_ocores", "delay": 0}, + {"name": "wb_i2c_ocores_device", "delay": 0}, + {"name": "wb_i2c_mux_pca9641", "delay": 0}, + {"name": "wb_i2c_mux_pca954x", "delay": 0}, + {"name": "wb_i2c_mux_pca954x_device", "delay": 0}, + {"name": "wb_i2c_dev_device", "delay": 0}, + {"name": "wb_lm75", "delay": 0}, + {"name": "wb_optoe", "delay": 0}, + {"name": "wb_at24", "delay": 0}, + {"name": "wb_mac_bsc", "delay": 0}, + {"name": "wb_pmbus_core", "delay": 0}, + {"name": "wb_isl68137", "delay": 0}, + {"name": "wb_csu550", "delay": 0}, + {"name": "wb_ina3221", "delay": 0}, + {"name": "wb_tps53622", "delay": 0}, + {"name": "firmware_driver_cpld", "delay": 0}, + {"name": "firmware_driver_ispvme", "delay": 0}, + {"name": "firmware_driver_sysfs", "delay": 0}, + {"name": "wb_firmware_upgrade_device", "delay": 0}, + {"name": "plat_dfd", "delay": 0}, + {"name": "plat_switch", "delay": 0}, + {"name": "plat_fan", "delay": 0}, + {"name": "plat_psu", "delay": 0}, + {"name": "plat_sff", "delay": 0}, +] + +DEVICE = [ + {"name": "wb_24c02", "bus": 0, "loc": 0x56}, + {"name": "wb_mac_bsc_td3", "bus": 3, "loc": 0x44}, + # fan + {"name": "wb_24c02", "bus": 16, "loc": 0x50}, + {"name": "wb_24c02", "bus": 17, "loc": 0x50}, + {"name": "wb_24c02", "bus": 18, "loc": 0x50}, + {"name": "wb_24c02", "bus": 19, "loc": 0x50}, + # psu + {"name": "wb_24c02", "bus": 24, "loc": 0x50}, + {"name": "wb_dps550", "bus": 24, "loc": 0x58}, + {"name": "wb_24c02", "bus": 25, "loc": 0x50}, + {"name": "wb_dps550", "bus": 25, "loc": 0x58}, + # temp + {"name": "wb_lm75", "bus": 3, "loc": 0x48}, + {"name": "wb_lm75", "bus": 3, "loc": 0x49}, + {"name": "wb_lm75", "bus": 3, "loc": 0x4a}, + {"name": "wb_lm75", "bus": 3, "loc": 0x4b}, + {"name": "wb_lm75", "bus": 3, "loc": 0x4c}, + # dcdc + {"name": "wb_ina3221", "bus": 7, "loc": 0x40}, + {"name": "wb_ina3221", "bus": 7, "loc": 0x41}, + {"name": "wb_ina3221", "bus": 7, "loc": 0x42}, + {"name": "wb_ina3221", "bus": 7, "loc": 0x43}, + {"name": "wb_tps53622", "bus": 7, "loc": 0x60}, + {"name": "wb_tps53622", "bus": 7, "loc": 0x6c}, + {"name": "wb_isl68127", "bus": 7, "loc": 0x64}, +] + +OPTOE = [ + {"name": "wb_optoe2", "startbus": 32, "endbus": 79}, + {"name": "wb_optoe1", "startbus": 80, "endbus": 87}, +] DEV_MONITOR_PARAM = { "polling_time": 10, "psus": [ { "name": "psu1", - "present": { - "gettype": "i2c", - "bus": 2, - "loc": 0x37, - "offset": 0x51, - "presentbit": 0, - "okval": 0, - }, + "present": {"gettype": "i2c", "bus": 6, "loc": 0x0d, "offset": 0x51, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu1pmbus", - "name": "dps550", - "bus": 7, - "loc": 0x58, - "attr": "hwmon", - }, + {"id": "psu1pmbus", "name": "wb_dps550", "bus": 24, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu1frue2", "name": "wb_24c02", "bus": 24, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "psu2", - "present": { - "gettype": "i2c", - "bus": 2, - "loc": 0x37, - "offset": 0x51, - "presentbit": 4, - "okval": 0, - }, + "present": {"gettype": "i2c", "bus": 6, "loc": 0x0d, "offset": 0x51, "presentbit": 4, "okval": 0}, "device": [ - { - "id": "psu2pmbus", - "name": "dps550", - "bus": 8, - "loc": 0x5B, - "attr": "hwmon", - }, + {"id": "psu2pmbus", "name": "wb_dps550", "bus": 25, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu2frue2", "name": "wb_24c02", "bus": 25, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "fans": [ + { + "name": "fan1", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x0d, "offset": 0x30, "presentbit": 0, "okval": 0}, + "device": [ + {"id": "fan1frue2", "name": "24c02", "bus": 16, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan2", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x0d, "offset": 0x30, "presentbit": 1, "okval": 0}, + "device": [ + {"id": "fan2frue2", "name": "24c02", "bus": 17, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan3", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x0d, "offset": 0x30, "presentbit": 2, "okval": 0}, + "device": [ + {"id": "fan3frue2", "name": "24c02", "bus": 18, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan4", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x0d, "offset": 0x30, "presentbit": 3, "okval": 0}, + "device": [ + {"id": "fan4frue2", "name": "24c02", "bus": 19, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "others": [ + { + "name": "eeprom", + "device": [ + {"id": "eeprom_1", "name": "wb_24c02", "bus": 0, "loc": 0x56, "attr": "eeprom"}, + ], + }, + { + "name": "lm75", + "device": [ + {"id": "lm75_1", "name": "wb_lm75", "bus": 3, "loc": 0x48, "attr": "hwmon"}, + {"id": "lm75_2", "name": "wb_lm75", "bus": 3, "loc": 0x49, "attr": "hwmon"}, + {"id": "lm75_3", "name": "wb_lm75", "bus": 3, "loc": 0x4a, "attr": "hwmon"}, + {"id": "lm75_4", "name": "wb_lm75", "bus": 3, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_5", "name": "wb_lm75", "bus": 3, "loc": 0x4c, "attr": "hwmon"}, ], }, + { + "name": "mac_bsc", + "device": [ + {"id": "mac_bsc_1", "name": "wb_mac_bsc_td3", "bus": 3, "loc": 0x44, "attr": "hwmon"}, + ], + }, + { + "name": "ina3221", + "device": [ + {"id": "ina3221_1", "name": "wb_ina3221", "bus": 7, "loc": 0x40, "attr": "hwmon"}, + {"id": "ina3221_2", "name": "wb_ina3221", "bus": 7, "loc": 0x41, "attr": "hwmon"}, + {"id": "ina3221_3", "name": "wb_ina3221", "bus": 7, "loc": 0x42, "attr": "hwmon"}, + {"id": "ina3221_4", "name": "wb_ina3221", "bus": 7, "loc": 0x43, "attr": "hwmon"}, + ], + }, + { + "name": "tps53622", + "device": [ + {"id": "tps53622_1", "name": "wb_tps53622", "bus": 7, "loc": 0x60, "attr": "hwmon"}, + {"id": "tps53622_2", "name": "wb_tps53622", "bus": 7, "loc": 0x6c, "attr": "hwmon"}, + ], + }, + { + "name": "isl68127", + "device": [ + {"id": "isl68127_1", "name": "wb_isl68127", "bus": 7, "loc": 0x64, "attr": "hwmon"}, + ], + } ], } -fanlevel = { - "tips":["LOW","MEDIUM","HIGH"], - "level":[51,150,255], - "low_speed":[500,7500,17000], - "high_speed":[11000,22500,28500] -} +INIT_PARAM_PRE = [ + {"loc": "7-0064/hwmon/hwmon*/avs0_vout_max", "value": "900000"}, + {"loc": "7-0064/hwmon/hwmon*/avs0_vout_min", "value": "750000"}, +] +INIT_COMMAND_PRE = [] + +INIT_PARAM = [] -# fit with pddf -fanloc = [ +INIT_COMMAND = [ + "i2cset -y -f 6 0x0d 0x91 0x48", + "i2cset -y -f 6 0x0d 0x92 0x01", # MAC_PWR_EN + "i2cset -y -f 6 0x0d 0x94 0x01", # SFF_PWR_EN + "i2cset -y -f 6 0x0d 0xbf 0x01", # enbale tty_console monitor + "i2cset -y -f 8 0x30 0x60 0x00", # enable txdis[1~8] + "i2cset -y -f 8 0x30 0x61 0x00", # enable txdis[9~16] + "i2cset -y -f 8 0x30 0x62 0x00", # enable txdis[17~24] + "i2cset -y -f 8 0x31 0x60 0x00", # enable txdis[24~32] + "i2cset -y -f 8 0x31 0x61 0x00", # enable txdis[33~40] + "i2cset -y -f 8 0x31 0x62 0x00", # enable txdis[41~48] +] + +REBOOT_CAUSE_PARA = [ { - "name": "FAN1/FAN2/FAN3/FAN4", - "location": "2-0066/fan1_pwm", - "childfans": [ - {"name": "FAN1", "location": "2-0066/fan1_input"}, - {"name": "FAN2", "location": "2-0066/fan2_input"}, - {"name": "FAN3", "location": "2-0066/fan3_input"}, - {"name": "FAN4", "location": "2-0066/fan4_input"}, - ], + "name": "cold_reboot", + "monitor_point": {"gettype": "i2c", "bus": 8, "addr": 0x30, "offset": 0x42, "okval": 0x0}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Cold reboot, ", + "path": "/var/cache/sonic/previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Cold reboot, ", "path": "/host/misc/history-reboot-cause.txt"} + ] }, + { + "name": "otp_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_reboot_flag"}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "OTP reboot, ", + "path": "/var/cache/sonic/previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "OTP reboot, ", "path": "/host/misc/history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_reboot_flag"}, + ] + } ] +UPGRADE_SUMMARY = { + "devtype": 0x404a, + "slot0": { + "subtype": 0, + "VME": { + "chain1": { + "name": "VME_CPLD", + "is_support_warm_upg": 0, + }, + }, -MONITOR_TEMP_MIN = 38 -MONITOR_K = 11 -MONITOR_MAC_IN = 35 -MONITOR_DEFAULT_SPEED = 0x60 -MONITOR_MAX_SPEED = 0xFF -MONITOR_MIN_SPEED = 0x33 -MONITOR_MAC_ERROR_SPEED = 0XBB -MONITOR_FAN_TOTAL_NUM = 4 -MONITOR_MAC_UP_TEMP = 50 -MONITOR_MAC_LOWER_TEMP = -50 -MONITOR_MAC_MAX_TEMP = 100 - -MONITOR_FALL_TEMP = 4 -MONITOR_MAC_WARNING_THRESHOLD = 100 -MONITOR_OUTTEMP_WARNING_THRESHOLD = 85 -MONITOR_BOARDTEMP_WARNING_THRESHOLD = 85 -MONITOR_CPUTEMP_WARNING_THRESHOLD = 85 -MONITOR_INTEMP_WARNING_THRESHOLD = 70 - -MONITOR_MAC_CRITICAL_THRESHOLD = 105 -MONITOR_OUTTEMP_CRITICAL_THRESHOLD = 90 -MONITOR_BOARDTEMP_CRITICAL_THRESHOLD = 90 -MONITOR_CPUTEMP_CRITICAL_THRESHOLD = 100 -MONITOR_INTEMP_CRITICAL_THRESHOLD = 80 -MONITOR_CRITICAL_NUM = 3 -MONITOR_SHAKE_TIME = 20 -MONITOR_INTERVAL = 60 - -MONITOR_SYS_LED = [ - {"bus":2,"devno":0x33, "addr":0xb2, "yellow":0x03, "red":0x02,"green":0x01}, - {"bus":2,"devno":0x37, "addr":0xb2, "yellow":0x03, "red":0x02,"green":0x01}] - -MONITOR_SYS_FAN_LED =[ - {"bus":2,"devno":0x33, "addr":0xb4, "yellow":0x06, "red":0x02,"green":0x04}, - ] -MONITOR_FANS_LED = [ - {"bus":2,"devno":0x32, "addr":0x23, "green":0x09, "red":0x0a}, - {"bus":2,"devno":0x32, "addr":0x24, "green":0x09, "red":0x0a}, - {"bus":2,"devno":0x32, "addr":0x25, "green":0x09, "red":0x0a}, - {"bus":2,"devno":0x32, "addr":0x26, "green":0x09, "red":0x0a}] - - -CPLDVERSIONS = [ - {"bus":2, "devno":0x33, "name":"MAC BOARD CPLD-A"}, - {"bus":2, "devno":0x35, "name":"MAC BOARD CPLD-B"}, - {"bus":2, "devno":0x37, "name":"CONNECT BOARD CPLD-A"}, - {"bus":0, "devno":0x0d, "name":"CPU BOARD CPLD"}, -] + "SPI-LOGIC-DEV": { + "chain3": { + "name": "FPGA", + "is_support_warm_upg": 0, + }, + }, -MONITOR_SYS_PSU_LED =[ - {"bus":2,"devno":0x33, "addr":0xb3, "yellow":0x06, "red":0x02,"green":0x04}, - ] + "MTD": { + "chain2": { + "name": "BIOS", + "is_support_warm_upg": 0, + "filesizecheck": 10240, # bios check file size, Unit: K + "init_cmd": [ + {"io_addr": 0x722, "value": 0x02, "gettype": "io"}, + {"cmd": "modprobe mtd", "gettype": "cmd"}, + {"cmd": "modprobe spi_nor", "gettype": "cmd"}, + {"cmd": "modprobe ofpart", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi writeable=1", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi_platform writeable=1", "gettype": "cmd"}, + ], + "finish_cmd": [ + {"cmd": "rmmod intel_spi_platform", "gettype": "cmd"}, + {"cmd": "rmmod intel_spi", "gettype": "cmd"}, + {"cmd": "rmmod ofpart", "gettype": "cmd"}, + {"cmd": "rmmod spi_nor", "gettype": "cmd"}, + {"cmd": "rmmod mtd", "gettype": "cmd"}, + ], + }, + }, -MONITOR_FAN_STATUS = [ - {'status':'green' , 'minOkNum':4,'maxOkNum':4}, - {'status':'yellow', 'minOkNum':3,'maxOkNum':3}, - {'status':'red' , 'minOkNum':0,'maxOkNum':2}, - ] + "TEST": { + "cpld": [ + {"chain": 1, "file": "/etc/.upgrade_test/cpld_test_header.vme", "display_name": "CPLD"}, + ], + "fpga": [ + { + "chain": 3, + "file": "/etc/.upgrade_test/fpga_test_header.bin", + "display_name": "FPGA", + }, + ], + }, + }, -MONITOR_PSU_STATUS = [ - {'status':'green' , 'minOkNum':2,'maxOkNum':2}, - {'status':'yellow', 'minOkNum':1,'maxOkNum':1}, - {'status':'red' , 'minOkNum':0,'maxOkNum':0}, - ] + "BMC": { + "name": "BMC", + "init_cmd": [ + ], + "finish_cmd": [], + }, +} -MONITOR_DEV_STATUS = { - "temperature": [ - {"name":"lm75in", "location":"/sys/bus/i2c/devices/2-0048/hwmon/*/temp1_input"}, - {"name":"lm75out", "location":"/sys/bus/i2c/devices/2-0049/hwmon/*/temp1_input"}, - {"name":"lm75hot", "location":"/sys/bus/i2c/devices/2-004a/hwmon/*/temp1_input"}, - {"name":"cpu", "location":"/sys/class/hwmon/hwmon0"}, - ], - "fans": [ +PLATFORM_E2_CONF = { + "fan": [ { - "name":"fan1", - "presentstatus":{"bus":2, "loc":0x37, "offset":0x30, 'bit':0}, - "rollstatus": [ - {"name":"motor1","bus":2, "loc":0x37, "offset":0x31, 'bit':0}, - ] + "name": "fan1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/16-0050/eeprom", + "e2_decode": [ + { + "area": "productInfoArea", "field": "productVersion", "decode_type": "func", "func_name": "fru_decode_hw" + }, + { + "area": "boardInfoArea", "field": "boardextra1", "decode_type": "func", "func_name": "fru_decode_hw" + }, + ], }, { - "name":"fan2", - "presentstatus":{"bus":2, "loc":0x37, "offset":0x30, 'bit':1}, - "rollstatus":[ - {"name":"motor1","bus":2, "loc":0x37, "offset":0x31, 'bit':1}, - ] + "name": "fan2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/17-0050/eeprom", + "e2_decode": [ + { + "area": "productInfoArea", "field": "productVersion", "decode_type": "func", "func_name": "fru_decode_hw" + }, + { + "area": "boardInfoArea", "field": "boardextra1", "decode_type": "func", "func_name": "fru_decode_hw" + }, + ], }, { - "name":"fan3", - "presentstatus":{"bus":2, "loc":0x37, "offset":0x30, 'bit':2}, - "rollstatus":[ - {"name":"motor1","bus":2, "loc":0x37, "offset":0x31, 'bit':2}, - ] + "name": "fan3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/18-0050/eeprom", + "e2_decode": [ + { + "area": "productInfoArea", "field": "productVersion", "decode_type": "func", "func_name": "fru_decode_hw" + }, + { + "area": "boardInfoArea", "field": "boardextra1", "decode_type": "func", "func_name": "fru_decode_hw" + }, + ], }, { - "name":"fan4", - "presentstatus":{"bus":2, "loc":0x37, "offset":0x30, 'bit':3}, - "rollstatus":[ - {"name":"motor1","bus":2, "loc":0x37, "offset":0x31, 'bit':3}, - ] + "name": "fan4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/19-0050/eeprom", + "e2_decode": [ + { + "area": "productInfoArea", "field": "productVersion", "decode_type": "func", "func_name": "fru_decode_hw" + }, + { + "area": "boardInfoArea", "field": "boardextra1", "decode_type": "func", "func_name": "fru_decode_hw" + }, + ], }, ], - "psus": [ - {"name":"psu1", "bus":2, "loc":0x37, "offset":0x51, "gettype":"i2c", 'presentbit': 0, 'statusbit':1,'alertbit':2}, - {"name":"psu2", "bus":2, "loc":0x37, "offset":0x51, "gettype":"i2c", 'presentbit': 4, 'statusbit':5,'alertbit':6}, - ], - "mac_temp" : { - "flag" : {"bus":2, "loc":0x33, "offset":0xd4, "gettype":"i2c", 'okbit': 0, 'okval':1}, - "loc" : [ - "2-0035/mac_temp_input", - ], - "try_bcmcmd" : 0, - }, -} - -MONITOR_DEV_STATUS_DECODE = { - 'fanpresent': {0:'PRESENT', 1:'ABSENT', 'okval':0}, - 'fanroll' : {0:'STALL' , 1:'ROLL', 'okval':1}, - 'psupresent': {0:'PRESENT', 1:'ABSENT', 'okval':0}, - 'psuoutput' : {0:'FAULT' , 1:'NORMAL', 'okval':1}, - 'psualert' : {0:'FAULT' , 1:'NORMAL', 'okval':1}, -} -################################################################### - - - -MAC_AVS_PARAM ={ - 0x72:0x0384, - 0x73:0x037e, - 0x74:0x0378, - 0x75:0x0372, - 0x76:0x036b, - 0x77:0x0365, - 0x78:0x035f, - 0x79:0x0359, - 0x7a:0x0352, - 0x7b:0x034c, - 0x7c:0x0346, - 0x7d:0x0340, - 0x7e:0x0339, - 0x7f:0x0333, - 0x80:0x032d, - 0x81:0x0327, - 0x82:0x0320, - 0x83:0x031a, - 0x84:0x0314, - 0x85:0x030e, - 0x86:0x0307, - 0x87:0x0301, - 0x88:0x02fb, - 0x89:0x02f5, - 0x8A:0x02ee -} - -MAC_DEFAULT_PARAM = { - "type": 1, - "default":0x74, - "loopaddr":0x00, - "loop":0x00, - "open":0x00, - "close":0x40, - "bus":2, - "devno":0x60, - "addr":0x21, - "protectaddr":0x10, - "sdkreg":"TOP_AVS_SEL_REG", - "sdkcmd": "scdcmd", - "sdkcmdargs": ["-t", 5], - "sdktype": 0, - "macregloc":24 , - "mask": 0xff + "psu": [ + {"name": "psu1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/24-0050/eeprom"}, + {"name": "psu2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/25-0050/eeprom"}, + ], + "syseeprom": [ + {"name": "syseeprom", "e2_type": "onie_tlv", "e2_path": "/sys/bus/i2c/devices/0-0056/eeprom"}, + ], } +AIR_FLOW_CONF = { + "psu_fan_airflow": { + "intake": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "exhaust": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] + }, + "fanairflow": { + "intake": ['M1HFAN I-F'], + "exhaust": ['M1HFAN I-R'] + }, -DEVICE = [] -DRIVERLISTS = [] - -""" -## -DRIVERLISTS = [ - {"name":"i2c_dev", "delay":0}, - {"name":"i2c_algo_bit","delay":0}, - {"name":"i2c_gpio", "delay":0}, - {"name":"i2c_mux", "delay":0}, - {"name":"i2c_mux_pca9641", "delay":0}, - {"name":"i2c_mux_pca954x force_create_bus=1", "delay":0},# force_deselect_on_exit=1 - {"name":"lm75", "delay":0}, - {"name":"optoe", "delay":0}, - {"name":"at24", "delay":0}, - {"name":"rg_sff", "delay":0}, - {"name":"ragile_b6510_platform", "delay":0}, - {"name":"ragile_platform", "delay":0}, - {"name":"rg_avs", "delay":0}, - {"name":"rg_cpld", "delay":0}, - {"name":"rg_fan", "delay":0}, - {"name":"rg_psu", "delay":0}, - {"name":"pmbus_core", "delay":0}, - {"name":"csu550", "delay":0}, - {"name":"rg_gpio_xeon", "delay":0}, - {"name":"firmware_driver", "delay":0}, - {"name":"firmware_bin", "delay":0}, - {"name":"ragile_b6510_sfputil", "delay":0}, - {"name":"ragile_common dfd_my_type=0x404a", "delay":0}, - {"name":"lpc_dbg", "delay":0}, -] - -DEVICE = [ - {"name":"pca9641","bus":0 ,"loc":0x10 }, - {"name":"pca9548","bus":2 ,"loc":0x70 }, - {"name":"lm75","bus": 2, "loc":0x48 }, - {"name":"lm75","bus": 2, "loc":0x49 }, - {"name":"lm75","bus": 2, "loc":0x4a }, - {"name":"24c02","bus":2 , "loc":0x57 }, - {"name":"rg_cpld","bus":0 ,"loc":0x32 }, - {"name":"rg_cpld","bus":1 ,"loc":0x34 }, - {"name":"rg_cpld","bus":1 ,"loc":0x36 }, - {"name":"rg_cpld","bus":2 ,"loc":0x33 }, - {"name":"rg_cpld","bus":2 ,"loc":0x35 }, - {"name":"rg_cpld","bus":2 ,"loc":0x37 }, - {"name":"rg_avs","bus": 2 ,"loc":0x60 }, - {"name":"pca9548","bus":1,"loc":0x70 }, - {"name":"pca9548","bus":1,"loc":0x71 }, - {"name":"pca9548","bus":1,"loc":0x72 }, - {"name":"pca9548","bus":1,"loc":0x73 }, - {"name":"pca9548","bus":1,"loc":0x74 }, - {"name":"pca9548","bus":1,"loc":0x75 }, - {"name":"pca9548","bus":1,"loc":0x76 }, - {"name":"rg_fan","bus":3,"loc":0x53 }, - {"name":"rg_fan","bus":4,"loc":0x53 }, - {"name":"rg_fan","bus":5,"loc":0x53 }, - {"name":"rg_fan","bus":6,"loc":0x53 }, - {"name":"rg_psu","bus":7 ,"loc":0x50 }, - {"name":"dps550","bus":7 ,"loc":0x58 }, - {"name":"rg_psu","bus":8 ,"loc":0x53 }, - {"name":"dps550","bus":8 ,"loc":0x5b }, - {"name": "optoe2", "bus": 11, "loc": 0x50}, - {"name": "optoe2", "bus": 12, "loc": 0x50}, - {"name": "optoe2", "bus": 13, "loc": 0x50}, - {"name": "optoe2", "bus": 14, "loc": 0x50}, - {"name": "optoe2", "bus": 15, "loc": 0x50}, - {"name": "optoe2", "bus": 16, "loc": 0x50}, - {"name": "optoe2", "bus": 17, "loc": 0x50}, - {"name": "optoe2", "bus": 18, "loc": 0x50}, - {"name": "optoe2", "bus": 19, "loc": 0x50}, - {"name": "optoe2", "bus": 20, "loc": 0x50}, - {"name": "optoe2", "bus": 21, "loc": 0x50}, - {"name": "optoe2", "bus": 22, "loc": 0x50}, - {"name": "optoe2", "bus": 23, "loc": 0x50}, - {"name": "optoe2", "bus": 24, "loc": 0x50}, - {"name": "optoe2", "bus": 25, "loc": 0x50}, - {"name": "optoe2", "bus": 26, "loc": 0x50}, - {"name": "optoe2", "bus": 27, "loc": 0x50}, - {"name": "optoe2", "bus": 28, "loc": 0x50}, - {"name": "optoe2", "bus": 29, "loc": 0x50}, - {"name": "optoe2", "bus": 30, "loc": 0x50}, - {"name": "optoe2", "bus": 31, "loc": 0x50}, - {"name": "optoe2", "bus": 32, "loc": 0x50}, - {"name": "optoe2", "bus": 33, "loc": 0x50}, - {"name": "optoe2", "bus": 34, "loc": 0x50}, - {"name": "optoe2", "bus": 35, "loc": 0x50}, - {"name": "optoe2", "bus": 36, "loc": 0x50}, - {"name": "optoe2", "bus": 37, "loc": 0x50}, - {"name": "optoe2", "bus": 38, "loc": 0x50}, - {"name": "optoe2", "bus": 39, "loc": 0x50}, - {"name": "optoe2", "bus": 40, "loc": 0x50}, - {"name": "optoe2", "bus": 41, "loc": 0x50}, - {"name": "optoe2", "bus": 42, "loc": 0x50}, - {"name": "optoe2", "bus": 43, "loc": 0x50}, - {"name": "optoe2", "bus": 44, "loc": 0x50}, - {"name": "optoe2", "bus": 45, "loc": 0x50}, - {"name": "optoe2", "bus": 46, "loc": 0x50}, - {"name": "optoe2", "bus": 47, "loc": 0x50}, - {"name": "optoe2", "bus": 48, "loc": 0x50}, - {"name": "optoe2", "bus": 49, "loc": 0x50}, - {"name": "optoe2", "bus": 50, "loc": 0x50}, - {"name": "optoe2", "bus": 51, "loc": 0x50}, - {"name": "optoe2", "bus": 52, "loc": 0x50}, - {"name": "optoe2", "bus": 53, "loc": 0x50}, - {"name": "optoe2", "bus": 54, "loc": 0x50}, - {"name": "optoe2", "bus": 55, "loc": 0x50}, - {"name": "optoe2", "bus": 56, "loc": 0x50}, - {"name": "optoe2", "bus": 57, "loc": 0x50}, - {"name": "optoe2", "bus": 58, "loc": 0x50}, - {"name": "optoe1", "bus": 59, "loc": 0x50}, - {"name": "optoe1", "bus": 60, "loc": 0x50}, - {"name": "optoe1", "bus": 61, "loc": 0x50}, - {"name": "optoe1", "bus": 62, "loc": 0x50}, - {"name": "optoe1", "bus": 63, "loc": 0x50}, - {"name": "optoe1", "bus": 64, "loc": 0x50}, - {"name": "optoe1", "bus": 65, "loc": 0x50}, - {"name": "optoe1", "bus": 66, "loc": 0x50}, -] - -INIT_PARAM = [ - {"loc":"1-0034/sfp_enable","value": "01"}, - {"loc":"2-0035/sfp_enable2","value":"ff"}, - {"loc":"2-0033/mac_led", "value":"ff"}, - {"loc":"1-0034/sfp_txdis1","value":"00"}, - {"loc":"1-0034/sfp_txdis2","value":"00"}, - {"loc":"1-0034/sfp_txdis3","value":"00"}, - {"loc":"1-0036/sfp_txdis4","value":"00"}, - {"loc":"1-0036/sfp_txdis5","value":"00"}, - {"loc":"1-0036/sfp_txdis6","value":"00"}, - {"loc":fanloc[0]["location"], "value":"80"}, - {"loc":"2-0033/sfp_led1_yellow","value":"ad"}, - {"loc":"2-0035/sfp_led2_yellow","value":"ad"}, -] -""" + "fans": [ + { + "name": "FAN1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/16-0050/eeprom", + "area": "productInfoArea", "field": "productName", "decode": "fanairflow" + }, + { + "name": "FAN2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/17-0050/eeprom", + "area": "productInfoArea", "field": "productName", "decode": "fanairflow" + }, + { + "name": "FAN3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/18-0050/eeprom", + "area": "productInfoArea", "field": "productName", "decode": "fanairflow" + }, + { + "name": "FAN4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/19-0050/eeprom", + "area": "productInfoArea", "field": "productName", "decode": "fanairflow" + } + ], -INIT_PARAM = [ - { - "name": "sfp_enable", - "bus": 1, - "devaddr": 0x34, - "offset": 0xa1, - "val": 0x01, - }, - { - "name": "sfp_eanble2", - "bus": 2, - "devaddr": 0x35, - "offset": 0xa0, - "val": 0xff, - }, - { - "name": "mac_led", - "bus": 2, - "devaddr": 0x33, - "offset": 0xa0, - "val": 0xff, - }, - { - "name": "sfp_txdis1", - "bus": 1, - "devaddr": 0x34, - "offset": 0x60, - "val": 0x00, - }, - { - "name": "sfp_txdis2", - "bus": 1, - "devaddr": 0x34, - "offset": 0x61, - "val": 0x00, - }, - { - "name": "sfp_txdis3", - "bus": 1, - "devaddr": 0x34, - "offset": 0x62, - "val": 0x00, - }, - { - "name": "sfp_txdis4", - "bus": 1, - "devaddr": 0x36, - "offset": 0x60, - "val": 0x00, - }, - { - "name": "sfp_txdis5", - "bus": 1, - "devaddr": 0x36, - "offset": 0x61, - "val": 0x00, - }, - { - "name": "sfp_txdis6", - "bus": 1, - "devaddr": 0x36, - "offset": 0x62, - "val": 0x00, - }, - { - "name": "sfp_led1_yellow", - "bus": 2, - "devaddr": 0x33, - "offset": 0xad, - "val": 0xad, - }, - { - "name": "sfp_led2_yellow", - "bus": 2, - "devaddr": 0x35, - "offset": 0xad, - "val": 0xad, - }, - { - "name": "fan_speed_set", - "bus": 0, - "devaddr": 0x32, - "offset": 0x15, - "val": 0x80, - }, -] + "psus": [ + { + "name": "PSU1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/24-0050/eeprom", + "area": "productInfoArea", "field": "productPartModelName", "decode": "psu_fan_airflow" + }, + { + "name": "PSU2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/25-0050/eeprom", + "area": "productInfoArea", "field": "productPartModelName", "decode": "psu_fan_airflow" + } + ] +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_port_config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_port_config.py new file mode 100644 index 000000000000..26f92a77a020 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_port_config.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +PLATFORM_INTF_OPTOE = { + "port_num": 56, + "optoe_start_bus": 32, +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_device.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_device.py new file mode 100644 index 000000000000..34257080c150 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_device.py @@ -0,0 +1,1212 @@ +#!/usr/bin/python3 + +psu_fan_airflow = { + "intake": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "exhaust": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] +} + +fanairflow = { + "intake": ['M1HFAN I-F'], + "exhaust": ['M1HFAN I-R'], +} + +psu_display_name = { + "PA550II-F": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "PA550II-R": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] +} + +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + + +PSU_NOT_PRESENT_PWM = 100 + + +class threshold: + PSU_TEMP_MIN = -20 * 1000 + PSU_TEMP_MAX = 60 * 1000 + + PSU_FAN_SPEED_MIN = 2000 + PSU_FAN_SPEED_MAX = 18000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 560 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 625 * 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 1 * 1000 + PSU_OUTPUT_CURRENT_MAX = 45 * 1000 + + PSU_INPUT_CURRENT_MIN = 0 * 1000 + PSU_INPUT_CURRENT_MAX = 7 * 1000 + + FRONT_FAN_SPEED_MAX = 24000 + REAR_FAN_SPEED_MAX = 22500 + FAN_SPEED_MIN = 5000 + + +class Description: + CPLD = "Used for managing IO modules, SFP+ modules and system LEDs" + BIOS = "Performs initialization of hardware components during booting" + FPGA = "Platform management controller for on-board temperature monitoring, in-chassis power" + + +devices = { + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/0-0056/eeprom", "way": "sysfs"}, + "airflow": "intake" + }, + ], + "psus": [ + { + "e2loc": {"loc": "/sys/bus/i2c/devices/24-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 24, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 24, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/25-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 25, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 25, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + } + ], + "temps": [ + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP1", + "api_name": "ASIC_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0044/hwmon/hwmon*/temp99_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 105000, + "Max": 110000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "CPU_TEMP", + "temp_id": "TEMP2", + "Temperature": { + "value": {"loc": "/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -15000, + "Low": 0, + "High": 100000, + "Max": 102000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP3", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "fix_value": { + "fix_type": "config", + "addend": -3, + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP4", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-004c/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "BOARD_TEMP", + "temp_id": "TEMP5", + "api_name": "MAC_OUT_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-004a/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "MAC_IN_TEMP", + "temp_id": "TEMP6", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU1_TEMP", + "temp_id": "TEMP7", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -20000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU2_TEMP", + "temp_id": "TEMP8", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -20000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "Temperature": { + "value": {"loc": "/tmp/highest_sff_temp", "way": "sysfs", "flock_path": "/tmp/highest_sff_temp"}, + "Min": -30000, + "Low": 0, + "High": 90000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "invalid": -10000, + "error": -9999, + } + ], + "leds": [ + { + "name": "FRONT_SYS_LED", + "led_type": "SYS_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x72, "way": "i2c"}, + "led_attrs": { + "off": 0x00, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + }, + { + "name": "FRONT_PSU_LED", + "led_type": "PSU_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x73, "way": "i2c"}, + "led_attrs": { + "off": 0x10, "red_flash": 0x11, "red": 0x12, + "green_flash": 0x13, "green": 0x14, "amber_flash": 0x15, + "amber": 0x16, "mask": 0x17 + }, + }, + { + "name": "FRONT_FAN_LED", + "led_type": "FAN_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x74, "way": "i2c"}, + "led_attrs": { + "off": 0x10, "red_flash": 0x11, "red": 0x12, + "green_flash": 0x13, "green": 0x14, "amber_flash": 0x15, + "amber": 0x16, "mask": 0x17 + }, + }, + ], + "fans": [ + { + "name": "FAN1", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-16/16-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3b, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-17/17-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-18/18-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + + { + "name": "FAN4", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-19/19-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3e, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x17, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x17, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + }, + { + "name": "CONNECT_CPLD", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + }, + { + "name": "CONNECT_CPLD-FAN", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld2", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for fan modules", + "slot": 0, + }, + { + "name": "MAC_CPLD1", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld3", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + }, + { + "name": "MAC_CPLD2", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld4", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + }, + { + "name": "FPGA", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/fpga0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + }, + ], + "dcdc": [ + { + "name": "Switch_ZSFP1_3v3_C", + "dcdc_id": "DCDC1", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 22000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_QSFP1_3v3_C", + "dcdc_id": "DCDC2", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 22000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_5v0_C", + "dcdc_id": "DCDC3", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ZSFP1_3v3_V", + "dcdc_id": "DCDC4", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_QSFP1_3v3_V", + "dcdc_id": "DCDC5", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_5v0_V", + "dcdc_id": "DCDC6", + "Min": 4000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 6000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_1v2_C", + "dcdc_id": "DCDC7", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_3v3_C", + "dcdc_id": "DCDC8", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_Cpld_3v3_C", + "dcdc_id": "DCDC9", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_1v2_V", + "dcdc_id": "DCDC10", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_3v3_V", + "dcdc_id": "DCDC11", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_Cpld_3v3_V", + "dcdc_id": "DCDC12", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_1v2_C", + "dcdc_id": "DCDC13", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1300, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_3v3_C", + "dcdc_id": "DCDC14", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2800, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_SSD_3v3_C", + "dcdc_id": "DCDC15", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 4500, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_1v2_V", + "dcdc_id": "DCDC16", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_3v3_V", + "dcdc_id": "DCDC17", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_SSD_3v3_V", + "dcdc_id": "DCDC18", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_3v3_C", + "dcdc_id": "DCDC19", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 4686, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_5v_C", + "dcdc_id": "DCDC20", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v7_C", + "dcdc_id": "DCDC21", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_3v3_V", + "dcdc_id": "DCDC22", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_5v_V", + "dcdc_id": "DCDC23", + "Min": 4000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 6000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v7_V", + "dcdc_id": "DCDC24", + "Min": 1360, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2040, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_CORE_C", + "dcdc_id": "DCDC25", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 47300, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v05_C", + "dcdc_id": "DCDC26", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 15400, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_CORE_V", + "dcdc_id": "DCDC27", + "Min": 1456, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2184, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v05_V", + "dcdc_id": "DCDC28", + "Min": 840, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1260, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_CORE_C", + "dcdc_id": "DCDC29", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 220000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ANALOG_C", + "dcdc_id": "DCDC30", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 18000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_CORE_V", + "dcdc_id": "DCDC31", + "Min": 600, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ANALOG_V", + "dcdc_id": "DCDC32", + "Min": 640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v2_C", + "dcdc_id": "DCDC33", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 9900, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_2v23_C", + "dcdc_id": "DCDC34", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v2_V", + "dcdc_id": "DCDC35", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_2v23_V", + "dcdc_id": "DCDC36", + "Min": 1784, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2676, + "format": "float(float(%s)/1000)", + }, + ], + "sfps": { + "ver": '1.0', + "port_index_start": 1, + "port_num": 56, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_cpld": { + "dev_id": { + 3: { + "offset": { + 0x30: "1-8", + 0x31: "9-16", + 0x32: "17-24", + }, + }, + 4: { + "offset": { + 0x30: "25-32", + 0x31: "33-40", + 0x32: "41-48", + 0x33: "49-56", + }, + }, + }, + }, + "presence_val_is_present": 0, + "eeprom_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/eeprom", + "eeprom_path_key": list(range(32, 88)), + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(32, 88)), + "txdis_cpld": { + "dev_id": { + 3: { + "offset": { + 0x60: "1-8", + 0x61: "9-16", + 0x62: "17-24", + }, + }, + 4: { + "offset": { + 0x60: "25-32", + 0x61: "33-40", + 0x62: "41-48", + }, + }, + }, + }, + "txdisable_val_is_on": 0, + "reset_cpld": { + "dev_id": { + 4: { + "offset": { + 0xb9: "49-56", + }, + }, + }, + }, + "reset_val_is_reset": 0, + } +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_exhaust_device.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_exhaust_device.py new file mode 100644 index 000000000000..caa7dd08d7cf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_exhaust_device.py @@ -0,0 +1,1211 @@ +#!/usr/bin/python3 + +psu_fan_airflow = { + "intake": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "exhaust": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] +} + +fanairflow = { + "intake": ['M1HFAN I-F'], + "exhaust": ['M1HFAN I-R'], +} + +psu_display_name = { + "PA550II-F": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "PA550II-R": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] +} + +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + + +PSU_NOT_PRESENT_PWM = 100 + + +class threshold: + PSU_TEMP_MIN = -20 * 1000 + PSU_TEMP_MAX = 60 * 1000 + + PSU_FAN_SPEED_MIN = 2000 + PSU_FAN_SPEED_MAX = 18000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 560 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 625 * 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 1 * 1000 + PSU_OUTPUT_CURRENT_MAX = 45 * 1000 + + PSU_INPUT_CURRENT_MIN = 0 * 1000 + PSU_INPUT_CURRENT_MAX = 7 * 1000 + + FRONT_FAN_SPEED_MAX = 24000 + REAR_FAN_SPEED_MAX = 22500 + FAN_SPEED_MIN = 5000 + + +class Description: + CPLD = "Used for managing IO modules, SFP+ modules and system LEDs" + BIOS = "Performs initialization of hardware components during booting" + FPGA = "Platform management controller for on-board temperature monitoring, in-chassis power" + + +devices = { + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/0-0056/eeprom", "way": "sysfs"}, + "airflow": "exhaust" + }, + ], + "psus": [ + { + "e2loc": {"loc": "/sys/bus/i2c/devices/24-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 24, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 24, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/25-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 25, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 25, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + } + ], + "temps": [ + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP1", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0044/hwmon/hwmon*/temp99_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 105000, + "Max": 110000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "CPU_TEMP", + "temp_id": "TEMP2", + "Temperature": { + "value": {"loc": "/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -15000, + "Low": 0, + "High": 100000, + "Max": 102000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP3", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-004c/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "fix_value": { + "fix_type": "config", + "addend": -3, + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP4", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "BOARD_TEMP", + "temp_id": "TEMP5", + "api_name": "MAC_OUT_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "MAC_IN_TEMP", + "temp_id": "TEMP6", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-004a/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU1_TEMP", + "temp_id": "TEMP7", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -20000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU2_TEMP", + "temp_id": "TEMP8", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -20000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "Temperature": { + "value": {"loc": "/tmp/highest_sff_temp", "way": "sysfs", "flock_path": "/tmp/highest_sff_temp"}, + "Min": -30000, + "Low": 0, + "High": 90000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "invalid": -10000, + "error": -9999, + } + ], + "leds": [ + { + "name": "FRONT_SYS_LED", + "led_type": "SYS_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x72, "way": "i2c"}, + "led_attrs": { + "off": 0x00, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + }, + { + "name": "FRONT_PSU_LED", + "led_type": "PSU_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x73, "way": "i2c"}, + "led_attrs": { + "off": 0x10, "red_flash": 0x11, "red": 0x12, + "green_flash": 0x13, "green": 0x14, "amber_flash": 0x15, + "amber": 0x16, "mask": 0x17 + }, + }, + { + "name": "FRONT_FAN_LED", + "led_type": "FAN_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x74, "way": "i2c"}, + "led_attrs": { + "off": 0x10, "red_flash": 0x11, "red": 0x12, + "green_flash": 0x13, "green": 0x14, "amber_flash": 0x15, + "amber": 0x16, "mask": 0x17 + }, + }, + ], + "fans": [ + { + "name": "FAN1", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-16/16-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3b, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-17/17-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-18/18-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + + { + "name": "FAN4", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-19/19-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3e, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x17, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x17, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + }, + { + "name": "CONNECT_CPLD", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + }, + { + "name": "CONNECT_CPLD-FAN", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld2", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for fan modules", + "slot": 0, + }, + { + "name": "MAC_CPLD1", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld3", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + }, + { + "name": "MAC_CPLD2", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld4", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + }, + { + "name": "FPGA", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/fpga0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + }, + ], + "dcdc": [ + { + "name": "Switch_ZSFP1_3v3_C", + "dcdc_id": "DCDC1", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 22000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_QSFP1_3v3_C", + "dcdc_id": "DCDC2", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 22000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_5v0_C", + "dcdc_id": "DCDC3", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ZSFP1_3v3_V", + "dcdc_id": "DCDC4", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_QSFP1_3v3_V", + "dcdc_id": "DCDC5", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_5v0_V", + "dcdc_id": "DCDC6", + "Min": 4000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 6000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_1v2_C", + "dcdc_id": "DCDC7", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_3v3_C", + "dcdc_id": "DCDC8", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_Cpld_3v3_C", + "dcdc_id": "DCDC9", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_1v2_V", + "dcdc_id": "DCDC10", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_3v3_V", + "dcdc_id": "DCDC11", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_Cpld_3v3_V", + "dcdc_id": "DCDC12", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_1v2_C", + "dcdc_id": "DCDC13", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1300, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_3v3_C", + "dcdc_id": "DCDC14", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2800, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_SSD_3v3_C", + "dcdc_id": "DCDC15", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 4500, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_1v2_V", + "dcdc_id": "DCDC16", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_3v3_V", + "dcdc_id": "DCDC17", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_SSD_3v3_V", + "dcdc_id": "DCDC18", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_3v3_C", + "dcdc_id": "DCDC19", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 4686, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_5v_C", + "dcdc_id": "DCDC20", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v7_C", + "dcdc_id": "DCDC21", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_3v3_V", + "dcdc_id": "DCDC22", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_5v_V", + "dcdc_id": "DCDC23", + "Min": 4000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 6000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v7_V", + "dcdc_id": "DCDC24", + "Min": 1360, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2040, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_CORE_C", + "dcdc_id": "DCDC25", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 47300, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v05_C", + "dcdc_id": "DCDC26", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 15400, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_CORE_V", + "dcdc_id": "DCDC27", + "Min": 1456, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2184, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v05_V", + "dcdc_id": "DCDC28", + "Min": 840, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1260, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_CORE_C", + "dcdc_id": "DCDC29", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 220000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ANALOG_C", + "dcdc_id": "DCDC30", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 18000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_CORE_V", + "dcdc_id": "DCDC31", + "Min": 600, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ANALOG_V", + "dcdc_id": "DCDC32", + "Min": 640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v2_C", + "dcdc_id": "DCDC33", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 9900, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_2v23_C", + "dcdc_id": "DCDC34", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v2_V", + "dcdc_id": "DCDC35", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_2v23_V", + "dcdc_id": "DCDC36", + "Min": 1784, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2676, + "format": "float(float(%s)/1000)", + }, + ], + "sfps": { + "ver": '1.0', + "port_index_start": 1, + "port_num": 56, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_cpld": { + "dev_id": { + 3: { + "offset": { + 0x30: "1-8", + 0x31: "9-16", + 0x32: "17-24", + }, + }, + 4: { + "offset": { + 0x30: "25-32", + 0x31: "33-40", + 0x32: "41-48", + 0x33: "49-56", + }, + }, + }, + }, + "presence_val_is_present": 0, + "eeprom_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/eeprom", + "eeprom_path_key": list(range(32, 88)), + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(32, 88)), + "txdis_cpld": { + "dev_id": { + 3: { + "offset": { + 0x60: "1-8", + 0x61: "9-16", + 0x62: "17-24", + }, + }, + 4: { + "offset": { + 0x60: "25-32", + 0x61: "33-40", + 0x62: "41-48", + }, + }, + }, + }, + "txdisable_val_is_on": 0, + "reset_cpld": { + "dev_id": { + 4: { + "offset": { + 0xb9: "49-56", + }, + }, + }, + }, + "reset_val_is_reset": 0, + } +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_monitor.py new file mode 100644 index 000000000000..3a9eef34d880 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_monitor.py @@ -0,0 +1,204 @@ +# coding:utf-8 + + +monitor = { + "openloop": { + "linear": { + "name": "linear", + "flag": 0, + "pwm_min": 0x80, + "pwm_max": 0xff, + "K": 11, + "tin_min": 38, + }, + "curve": { + "name": "curve", + "flag": 0, + "pwm_min": 0x5a, + "pwm_max": 0xff, + "a": 0.086, + "b": 0.318, + "c": 28, + "tin_min": 25, + }, + }, + + "pid": { + "CPU_TEMP": { + "name": "CPU_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 3, + "Ki": 0.5, + "Kd": 0.5, + "target": 89, + "value": [None, None, None], + }, + "SWITCH_TEMP": { + "name": "SWITCH_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 3, + "Ki": 0.4, + "Kd": 0.4, + "target": 82, + "value": [None, None, None], + }, + "OUTLET_TEMP": { + "name": "OUTLET_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "BOARD_TEMP": { + "name": "BOARD_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "SFF_TEMP": { + "name": "SFF_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 0.1, + "Ki": 0.4, + "Kd": 0, + "target": 60, + "value": [None, None, None], + }, + }, + + "hyst": { + "INLET_TEMP": { + "name": "INLET_TEMP", + "flag": 1, + "type": "duty", + "hyst_min": 50, # duty + "hyst_max": 100, # duty + "last_hyst_value": 50, # duty + "temp_min": 23, + "temp_max": 40, + "value": [None, None], + "rising": { + 23: 50, + 24: 50, + 25: 50, + 26: 53, + 27: 56, + 28: 59, + 29: 62, + 30: 65, + 31: 68, + 32: 71, + 33: 74, + 34: 77, + 35: 80, + 36: 84, + 37: 88, + 38: 92, + 39: 96, + 40: 100, + }, + "descending": { + 23: 50, + 24: 53, + 25: 56, + 26: 59, + 27: 62, + 28: 65, + 29: 68, + 30: 71, + 31: 74, + 32: 77, + 33: 80, + 34: 84, + 35: 88, + 36: 92, + 37: 96, + 38: 100, + 39: 100, + 40: 100, + }, + } + }, + + "temps_threshold": { + "SWITCH_TEMP": {"name": "SWITCH_TEMP", "warning": 100, "critical": 105}, + "INLET_TEMP": {"name": "INLET_TEMP", "warning": 40, "critical": 50}, + "BOARD_TEMP": {"name": "BOARD_TEMP", "warning": 70, "critical": 80}, + "OUTLET_TEMP": {"name": "OUTLET_TEMP", "warning": 70, "critical": 80}, + "CPU_TEMP": {"name": "CPU_TEMP", "warning": 100, "critical": 102}, + "SFF_TEMP": {"name": "SFF_TEMP", "warning": 999, "critical": 1000, "ignore_threshold": 1, "invalid": -10000, "error": -9999}, + }, + + "fancontrol_para": { + "interval": 5, + "fan_air_flow_monitor": 1, + "psu_air_flow_monitor": 1, + "max_pwm": 0xff, + "min_pwm": 0x80, + "abnormal_pwm": 0xff, + "warning_pwm": 0xff, + "temp_invalid_pid_pwm": 0x80, + "temp_error_pid_pwm": 0x80, + "temp_fail_num": 3, + "check_temp_fail": [ + {"temp_name": "INLET_TEMP"}, + {"temp_name": "SWITCH_TEMP"}, + {"temp_name": "CPU_TEMP"}, + ], + "temp_warning_num": 3, # temp over warning 3 times continuously + "temp_critical_num": 3, # temp over critical 3 times continuously + "temp_warning_countdown": 60, # 5 min warning speed after not warning + "temp_critical_countdown": 60, # 5 min full speed after not critical + "rotor_error_count": 6, # fan rotor error 6 times continuously + "inlet_mac_diff": 999, + "check_crit_reboot_flag": 1, + "check_crit_reboot_num": 3, + "check_crit_sleep_time": 20, + "psu_absent_fullspeed_num": 0xFF, + "fan_absent_fullspeed_num": 1, + "rotor_error_fullspeed_num": 1, + }, + + "ledcontrol_para": { + "interval": 5, + "checkpsu": 0, # 0: sys led don't follow psu led + "checkfan": 0, # 0: sys led don't follow fan led + "psu_amber_num": 1, + "fan_amber_num": 1, + "board_sys_led": [ + {"led_name": "FRONT_SYS_LED"}, + ], + "board_psu_led": [ + {"led_name": "FRONT_PSU_LED"}, + ], + "board_fan_led": [ + {"led_name": "FRONT_FAN_LED"}, + ], + "psu_air_flow_monitor": 1, + "fan_air_flow_monitor": 1, + "psu_air_flow_amber_num": 1, + "fan_air_flow_amber_num": 1, + }, + + +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/Makefile index f10216ec4d5a..e59ffd7ee67d 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/Makefile @@ -1 +1,15 @@ -obj-m := rg_cpld.o +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/app/firmware_upgrade/firmware_driver/include) + +EXTRA_CFLAGS+= -I$(MODULES_DIR) +EXTRA_CFLAGS+= -I$(MODULES_DIR)/linux-5.10 +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) + +obj-m := wb_pcie_dev_device.o +obj-m += wb_i2c_mux_pca954x_device.o +obj-m += wb_i2c_ocores_device.o +obj-m += wb_lpc_drv_device.o +obj-m += wb_i2c_dev_device.o +obj-m += wb_io_dev_device.o +obj-m += wb_firmware_upgrade_device.o diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_firmware_upgrade_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_firmware_upgrade_device.c new file mode 100644 index 000000000000..5fcaa8da1963 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_firmware_upgrade_device.c @@ -0,0 +1,178 @@ +/* + * wb_firmware_upgrade.c + * Original Author: support 2021-03-17 + * + * ko for firmware device + * History + * [Version] [Author] [Date] [Description] + * v1.0 support 2021-05-07 Initial version + */ +#include +#include +#include +#include +#include +#include + +static int g_wb_firmware_upgrade_debug = 0; +static int g_wb_firmware_upgrade_error = 0; + +module_param(g_wb_firmware_upgrade_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_firmware_upgrade_error, int, S_IRUGO | S_IWUSR); + +#define WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_firmware_upgrade_debug) { \ + printk(KERN_INFO "[WB_FIRMWARE_UPGRADE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FIRMWARE_UPGRADE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_firmware_upgrade_error) { \ + printk(KERN_ERR "[WB_FIRMWARE_UPGRADE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 48, + .en_level[1] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* fpga */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "SPI_LOGIC", + .chain = 3, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x1A0000, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "SPI_LOGIC", + .chain = 4, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x0, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* bios */ +static firmware_upgrade_device_t firmware_upgrade_device_data3 = { + .type = "MTD_DEV", + .chain = 2, + .chip_index = 1, + .upg_type.sysfs = { + .mtd_name = "BIOS", + .flash_base = 0x800000, + }, + + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 4, + .dev = { + .platform_data = &firmware_upgrade_device_data3, + .release = firmware_device_release, + }, + }, + }; + + static int __init firmware_upgrade_device_init(void) + { + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; + } + + static void __exit firmware_upgrade_device_exit(void) + { + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&firmware_upgrade_device[i]); + } + } + } + + module_init(firmware_upgrade_device_init); + module_exit(firmware_upgrade_device_exit); + MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_dev_device.c new file mode 100644 index 000000000000..865e7afea44c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_dev_device.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_dev_device_debug = 0; +static int g_wb_i2c_dev_device_error = 0; + +module_param(g_wb_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_dev_device_t i2c_dev_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x0d, + .i2c_name = "cpld2", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data1 = { + .i2c_bus = 8, + .i2c_addr = 0x30, + .i2c_name = "cpld3", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data2 = { + .i2c_bus = 8, + .i2c_addr = 0x31, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data3 = { + .i2c_bus = 6, + .i2c_addr = 0x0d, + .i2c_name = "cpld5", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +struct i2c_board_info i2c_dev_device_info[] = { + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data0, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data1, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data2, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data3, + }, +}; + +static int __init wb_i2c_dev_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_dev_device_info); i++) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + i2c_dev_device_info[i].addr = i2c_dev_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_dev_device_data->i2c_bus); + if (adap == NULL) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_dev_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); + if (!client) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", + i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); + } else { + i2c_dev_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_dev_device_exit(void) +{ + int i; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_dev_device_info) - 1; i >= 0; i--) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + if (i2c_dev_device_data->client) { + i2c_unregister_device(i2c_dev_device_data->client); + i2c_dev_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_dev_device_init); +module_exit(wb_i2c_dev_device_exit); +MODULE_DESCRIPTION("I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 000000000000..f12a71013451 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,296 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca954x_device_debug = 0; +static int g_wb_i2c_mux_pca954x_device_error = 0; + +module_param(g_wb_i2c_mux_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 16, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/cpld5", + .file_attr.offset = 0x60, + .file_attr.mask = 0x02, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data1 = { + .i2c_bus = 4, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 24, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/cpld5", + .file_attr.offset = 0x60, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data2 = { + .i2c_bus = 12, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 32, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data3 = { + .i2c_bus = 12, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 40, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data4 = { + .i2c_bus = 12, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 48, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data5 = { + .i2c_bus = 12, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 56, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data6 = { + .i2c_bus = 13, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 64, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data7 = { + .i2c_bus = 13, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 72, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data8 = { + .i2c_bus = 13, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 80, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data1, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data2, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data3, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data4, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data5, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data6, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data7, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data8, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (!client) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_ocores_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_ocores_device.c new file mode 100644 index 000000000000..ff7ba9d26fbc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_ocores_device.c @@ -0,0 +1,423 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_ocores_device_debug = 0; +static int g_wb_i2c_ocores_device_error = 0; + +module_param(g_wb_i2c_ocores_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_ocores_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_debug) { \ + printk(KERN_INFO "[WB_I2C_OCORE_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_OCORE_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_error) { \ + printk(KERN_ERR "[WB_I2C_OCORE_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_ocores_device_t i2c_ocores_device_data0 = { + .adap_nr = 2, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0800, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 0, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data1 = { + .adap_nr = 3, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0820, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 1, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data2 = { + .adap_nr = 4, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0840, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 2, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data3 = { + .adap_nr = 5, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0860, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 3, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data4 = { + .adap_nr = 6, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0880, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 4, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data5 = { + .adap_nr = 7, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08a0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 5, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data6 = { + .adap_nr = 8, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08c0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 6, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data7 = { + .adap_nr = 9, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08e0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 7, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data8 = { + .adap_nr = 10, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0900, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 8, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data9 = { + .adap_nr = 11, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0920, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 9, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data10 = { + .adap_nr = 12, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0940, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 10, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data11 = { + .adap_nr = 13, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0960, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 11, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data12 = { + .adap_nr = 14, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0980, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 12, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data13 = { + .adap_nr = 15, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x09a0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 13, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static void wb_i2c_ocores_device_release(struct device *dev) +{ + return; +} + +static struct platform_device i2c_ocores_device[] = { + { + .name = "wb-ocores-i2c", + .id = 1, + .dev = { + .platform_data = &i2c_ocores_device_data0, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 2, + .dev = { + .platform_data = &i2c_ocores_device_data1, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 3, + .dev = { + .platform_data = &i2c_ocores_device_data2, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 4, + .dev = { + .platform_data = &i2c_ocores_device_data3, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 5, + .dev = { + .platform_data = &i2c_ocores_device_data4, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 6, + .dev = { + .platform_data = &i2c_ocores_device_data5, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 7, + .dev = { + .platform_data = &i2c_ocores_device_data6, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 8, + .dev = { + .platform_data = &i2c_ocores_device_data7, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 9, + .dev = { + .platform_data = &i2c_ocores_device_data8, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 10, + .dev = { + .platform_data = &i2c_ocores_device_data9, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 11, + .dev = { + .platform_data = &i2c_ocores_device_data10, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 12, + .dev = { + .platform_data = &i2c_ocores_device_data11, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 13, + .dev = { + .platform_data = &i2c_ocores_device_data12, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 14, + .dev = { + .platform_data = &i2c_ocores_device_data13, + .release = wb_i2c_ocores_device_release, + }, + }, +}; + +static int __init wb_i2c_ocores_device_init(void) +{ + int i; + int ret = 0; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_ocores_device); i++) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + ret = platform_device_register(&i2c_ocores_device[i]); + if (ret < 0) { + i2c_ocores_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-ocores-i2c.%d register failed!\n", i + 1); + } else { + i2c_ocores_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_i2c_ocores_device_exit(void) +{ + int i; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_ocores_device) - 1; i >= 0; i--) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + if (i2c_ocores_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&i2c_ocores_device[i]); + } + } +} + +module_init(wb_i2c_ocores_device_init); +module_exit(wb_i2c_ocores_device_exit); +MODULE_DESCRIPTION("I2C OCORES Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..cc84938fff0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_io_dev_device.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data1 = { + .io_dev_name = "cpld1", + .io_base = 0x900, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 2, + .dev = { + .platform_data = &io_dev_device_data1, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..9b6b61a51735 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static lpc_drv_device_t lpc_drv_device_data_1 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x900, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x88, +}; + +static lpc_drv_device_t lpc_drv_device_data_2 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0xb00, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x90, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 2, + .dev = { + .platform_data = &lpc_drv_device_data_1, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 3, + .dev = { + .platform_data = &lpc_drv_device_data_2, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_pcie_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_pcie_dev_device.c new file mode 100644 index 000000000000..f79b29770d29 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_pcie_dev_device.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_pcie_dev_device_debug = 0; +static int g_wb_pcie_dev_device_error = 0; + +module_param(g_wb_pcie_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_pcie_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_pcie_dev_device_debug) { \ + printk(KERN_INFO "[WB_PCIE_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PCIE_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_pcie_dev_device_error) { \ + printk(KERN_ERR "[WB_PCIE_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static pci_dev_device_t pcie_dev_device_data0 = { + .pci_dev_name = "fpga0", + .pci_domain = 0x0000, + .pci_bus = 0x08, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .upg_ctrl_base = 0xa00, + .upg_flash_base = 0x1a0000, +}; + +static void wb_pcie_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device pcie_dev_device[] = { + { + .name = "wb-pci-dev", + .id = 1, + .dev = { + .platform_data = &pcie_dev_device_data0, + .release = wb_pcie_dev_device_release, + }, + }, +}; + +static int __init wb_pcie_dev_device_init(void) +{ + int i; + int ret = 0; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(pcie_dev_device); i++) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + ret = platform_device_register(&pcie_dev_device[i]); + if (ret < 0) { + pcie_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-pci-dev.%d register failed!\n", i + 1); + } else { + pcie_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_pcie_dev_device_exit(void) +{ + int i; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(pcie_dev_device) - 1; i >= 0; i--) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + if (pcie_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&pcie_dev_device[i]); + } + } +} + +module_init(wb_pcie_dev_device_init); +module_exit(wb_pcie_dev_device_exit); +MODULE_DESCRIPTION("PCIE DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..98d1da1750c3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,41 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_0_2=2 +cpld_i2c_dev.addr_0_2=0x0d +cpld_i2c_dev.bus_0_3=8 +cpld_i2c_dev.addr_0_3=0x30 +cpld_i2c_dev.bus_0_4=8 +cpld_i2c_dev.addr_0_4=0x31 +cpld_i2c_dev.bus_0_5=6 +cpld_i2c_dev.addr_0_5=0x0d + + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_0=0x700 +cpld_lpc_dev_0_1=0x900 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=lpc +mode_cpld_0_1=lpc +mode_cpld_0_2=i2c +mode_cpld_0_3=i2c +mode_cpld_0_4=i2c +mode_cpld_0_5=i2c + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=6 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..2350b74eb8bc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,304 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=4 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=2 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x00020030 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x00020030 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=1 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x00020030 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=2 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=cpld +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.addr_1_4=0x00020030 +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=3 + + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x00020031 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=0 + +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=cpld +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1= +fan_roll_status.addr_1_1=0x00020034 +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=0 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x00020031 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=1 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=cpld +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1= +fan_roll_status.addr_2_1=0x00020034 +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=1 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x00020031 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=2 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=cpld +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1= +fan_roll_status.addr_3_1=0x00020034 +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=2 + +fan_roll_status.mode_4_0=config +fan_roll_status.int_cons_4_0= +fan_roll_status.src_4_0=cpld +fan_roll_status.frmt_4_0=bit +fan_roll_status.pola_4_0=positive +fan_roll_status.fpath_4_0= +fan_roll_status.addr_4_0=0x00020031 +fan_roll_status.len_4_0=1 +fan_roll_status.bit_offset_4_0=3 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=cpld +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1= +fan_roll_status.addr_4_1=0x00020034 +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=3 + + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x0002001b +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=cpld +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1=negative +fan_speed.fpath_1_1= +fan_speed.addr_1_1=0x00020025 +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0002001d +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=cpld +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1=negative +fan_speed.fpath_2_1= +fan_speed.addr_2_1=0x00020027 +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0002001f +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=cpld +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1=negative +fan_speed.fpath_3_1= +fan_speed.addr_3_1=0x00020029 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_4_0=config +fan_speed.int_cons_4_0= +fan_speed.src_4_0=cpld +fan_speed.frmt_4_0=num_bytes +fan_speed.pola_4_0=negative +fan_speed.fpath_4_0= +fan_speed.addr_4_0=0x00020021 +fan_speed.len_4_0=2 +fan_speed.bit_offset_4_0= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=cpld +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1=negative +fan_speed.fpath_4_1= +fan_speed.addr_4_1=0x0002002b +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x00020014 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_1_1=config +fan_ratio.int_cons_1_1= +fan_ratio.src_1_1=cpld +fan_ratio.frmt_1_1=byte +fan_ratio.pola_1_1= +fan_ratio.fpath_1_1= +fan_ratio.addr_1_1=0x00020014 +fan_ratio.len_1_1=1 +fan_ratio.bit_offset_1_1= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x00020015 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_2_1=config +fan_ratio.int_cons_2_1= +fan_ratio.src_2_1=cpld +fan_ratio.frmt_2_1=byte +fan_ratio.pola_2_1= +fan_ratio.fpath_2_1= +fan_ratio.addr_2_1=0x00020015 +fan_ratio.len_2_1=1 +fan_ratio.bit_offset_2_1= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x00020016 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= + +fan_ratio.mode_3_1=config +fan_ratio.int_cons_3_1= +fan_ratio.src_3_1=cpld +fan_ratio.frmt_3_1=byte +fan_ratio.pola_3_1= +fan_ratio.fpath_3_1= +fan_ratio.addr_3_1=0x00020016 +fan_ratio.len_3_1=1 +fan_ratio.bit_offset_3_1= + +fan_ratio.mode_4_0=config +fan_ratio.int_cons_4_0= +fan_ratio.src_4_0=cpld +fan_ratio.frmt_4_0=byte +fan_ratio.pola_4_0= +fan_ratio.fpath_4_0= +fan_ratio.addr_4_0=0x00020017 +fan_ratio.len_4_0=1 +fan_ratio.bit_offset_4_0= + +fan_ratio.mode_4_1=config +fan_ratio.int_cons_4_1= +fan_ratio.src_4_1=cpld +fan_ratio.frmt_4_1=byte +fan_ratio.pola_4_1= +fan_ratio.fpath_4_1= +fan_ratio.addr_4_1=0x00020017 +fan_ratio.len_4_1=1 +fan_ratio.bit_offset_4_1= diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..082ef20fe97f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,64 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=2 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00050051 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00050051 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00050051 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00050051 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=4 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00050051 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=5 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00050051 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=6 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..7f57dfd93c5b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,521 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=56 + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 +sff_dir_name_33 =sff33 +sff_dir_name_34 =sff34 +sff_dir_name_35 =sff35 +sff_dir_name_36 =sff36 +sff_dir_name_37 =sff37 +sff_dir_name_38 =sff38 +sff_dir_name_39 =sff39 +sff_dir_name_40 =sff40 +sff_dir_name_41 =sff41 +sff_dir_name_42 =sff42 +sff_dir_name_43 =sff43 +sff_dir_name_44 =sff44 +sff_dir_name_45 =sff45 +sff_dir_name_46 =sff46 +sff_dir_name_47 =sff47 +sff_dir_name_48 =sff48 +sff_dir_name_49 =sff49 +sff_dir_name_50 =sff50 +sff_dir_name_51 =sff51 +sff_dir_name_52 =sff52 +sff_dir_name_53 =sff53 +sff_dir_name_54 =sff54 +sff_dir_name_55 =sff55 +sff_dir_name_56 =sff56 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x00030030 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x00030030 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x00030030 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x00030030 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x00030030 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x00030030 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x00030030 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x00030030 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x00030031 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x00030031 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x00030031 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x00030031 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x00030031 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x00030031 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x00030031 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x00030031 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x00030032 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x00030032 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x00030032 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x00030032 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x00030032 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x00030032 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x00030032 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x00030032 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x00040030 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x00040030 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x00040030 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x00040030 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x00040030 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x00040030 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x00040030 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x00040030 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +sff_cpld_reg.mode_33_8=config +sff_cpld_reg.src_33_8=cpld +sff_cpld_reg.frmt_33_8=bit +sff_cpld_reg.pola_33_8=negative +sff_cpld_reg.addr_33_8=0x00040031 +sff_cpld_reg.len_33_8=1 +sff_cpld_reg.bit_offset_33_8=0 + +sff_cpld_reg.mode_34_8=config +sff_cpld_reg.src_34_8=cpld +sff_cpld_reg.frmt_34_8=bit +sff_cpld_reg.pola_34_8=negative +sff_cpld_reg.addr_34_8=0x00040031 +sff_cpld_reg.len_34_8=1 +sff_cpld_reg.bit_offset_34_8=1 + +sff_cpld_reg.mode_35_8=config +sff_cpld_reg.src_35_8=cpld +sff_cpld_reg.frmt_35_8=bit +sff_cpld_reg.pola_35_8=negative +sff_cpld_reg.addr_35_8=0x00040031 +sff_cpld_reg.len_35_8=1 +sff_cpld_reg.bit_offset_35_8=2 + +sff_cpld_reg.mode_36_8=config +sff_cpld_reg.src_36_8=cpld +sff_cpld_reg.frmt_36_8=bit +sff_cpld_reg.pola_36_8=negative +sff_cpld_reg.addr_36_8=0x00040031 +sff_cpld_reg.len_36_8=1 +sff_cpld_reg.bit_offset_36_8=3 + +sff_cpld_reg.mode_37_8=config +sff_cpld_reg.src_37_8=cpld +sff_cpld_reg.frmt_37_8=bit +sff_cpld_reg.pola_37_8=negative +sff_cpld_reg.addr_37_8=0x00040031 +sff_cpld_reg.len_37_8=1 +sff_cpld_reg.bit_offset_37_8=4 + +sff_cpld_reg.mode_38_8=config +sff_cpld_reg.src_38_8=cpld +sff_cpld_reg.frmt_38_8=bit +sff_cpld_reg.pola_38_8=negative +sff_cpld_reg.addr_38_8=0x00040031 +sff_cpld_reg.len_38_8=1 +sff_cpld_reg.bit_offset_38_8=5 + +sff_cpld_reg.mode_39_8=config +sff_cpld_reg.src_39_8=cpld +sff_cpld_reg.frmt_39_8=bit +sff_cpld_reg.pola_39_8=negative +sff_cpld_reg.addr_39_8=0x00040031 +sff_cpld_reg.len_39_8=1 +sff_cpld_reg.bit_offset_39_8=6 + +sff_cpld_reg.mode_40_8=config +sff_cpld_reg.src_40_8=cpld +sff_cpld_reg.frmt_40_8=bit +sff_cpld_reg.pola_40_8=negative +sff_cpld_reg.addr_40_8=0x00040031 +sff_cpld_reg.len_40_8=1 +sff_cpld_reg.bit_offset_40_8=7 + +sff_cpld_reg.mode_41_8=config +sff_cpld_reg.src_41_8=cpld +sff_cpld_reg.frmt_41_8=bit +sff_cpld_reg.pola_41_8=negative +sff_cpld_reg.addr_41_8=0x00040032 +sff_cpld_reg.len_41_8=1 +sff_cpld_reg.bit_offset_41_8=0 + +sff_cpld_reg.mode_42_8=config +sff_cpld_reg.src_42_8=cpld +sff_cpld_reg.frmt_42_8=bit +sff_cpld_reg.pola_42_8=negative +sff_cpld_reg.addr_42_8=0x00040032 +sff_cpld_reg.len_42_8=1 +sff_cpld_reg.bit_offset_42_8=1 + +sff_cpld_reg.mode_43_8=config +sff_cpld_reg.src_43_8=cpld +sff_cpld_reg.frmt_43_8=bit +sff_cpld_reg.pola_43_8=negative +sff_cpld_reg.addr_43_8=0x00040032 +sff_cpld_reg.len_43_8=1 +sff_cpld_reg.bit_offset_43_8=2 + +sff_cpld_reg.mode_44_8=config +sff_cpld_reg.src_44_8=cpld +sff_cpld_reg.frmt_44_8=bit +sff_cpld_reg.pola_44_8=negative +sff_cpld_reg.addr_44_8=0x00040032 +sff_cpld_reg.len_44_8=1 +sff_cpld_reg.bit_offset_44_8=3 + +sff_cpld_reg.mode_45_8=config +sff_cpld_reg.src_45_8=cpld +sff_cpld_reg.frmt_45_8=bit +sff_cpld_reg.pola_45_8=negative +sff_cpld_reg.addr_45_8=0x00040032 +sff_cpld_reg.len_45_8=1 +sff_cpld_reg.bit_offset_45_8=4 + +sff_cpld_reg.mode_46_8=config +sff_cpld_reg.src_46_8=cpld +sff_cpld_reg.frmt_46_8=bit +sff_cpld_reg.pola_46_8=negative +sff_cpld_reg.addr_46_8=0x00040032 +sff_cpld_reg.len_46_8=1 +sff_cpld_reg.bit_offset_46_8=5 + +sff_cpld_reg.mode_47_8=config +sff_cpld_reg.src_47_8=cpld +sff_cpld_reg.frmt_47_8=bit +sff_cpld_reg.pola_47_8=negative +sff_cpld_reg.addr_47_8=0x00040032 +sff_cpld_reg.len_47_8=1 +sff_cpld_reg.bit_offset_47_8=6 + +sff_cpld_reg.mode_48_8=config +sff_cpld_reg.src_48_8=cpld +sff_cpld_reg.frmt_48_8=bit +sff_cpld_reg.pola_48_8=negative +sff_cpld_reg.addr_48_8=0x00040032 +sff_cpld_reg.len_48_8=1 +sff_cpld_reg.bit_offset_48_8=7 + +sff_cpld_reg.mode_49_8=config +sff_cpld_reg.src_49_8=cpld +sff_cpld_reg.frmt_49_8=bit +sff_cpld_reg.pola_49_8=negative +sff_cpld_reg.addr_49_8=0x00040033 +sff_cpld_reg.len_49_8=1 +sff_cpld_reg.bit_offset_49_8=0 + +sff_cpld_reg.mode_50_8=config +sff_cpld_reg.src_50_8=cpld +sff_cpld_reg.frmt_50_8=bit +sff_cpld_reg.pola_50_8=negative +sff_cpld_reg.addr_50_8=0x00040033 +sff_cpld_reg.len_50_8=1 +sff_cpld_reg.bit_offset_50_8=1 + +sff_cpld_reg.mode_51_8=config +sff_cpld_reg.src_51_8=cpld +sff_cpld_reg.frmt_51_8=bit +sff_cpld_reg.pola_51_8=negative +sff_cpld_reg.addr_51_8=0x00040033 +sff_cpld_reg.len_51_8=1 +sff_cpld_reg.bit_offset_51_8=2 + +sff_cpld_reg.mode_52_8=config +sff_cpld_reg.src_52_8=cpld +sff_cpld_reg.frmt_52_8=bit +sff_cpld_reg.pola_52_8=negative +sff_cpld_reg.addr_52_8=0x00040033 +sff_cpld_reg.len_52_8=1 +sff_cpld_reg.bit_offset_52_8=3 + +sff_cpld_reg.mode_53_8=config +sff_cpld_reg.src_53_8=cpld +sff_cpld_reg.frmt_53_8=bit +sff_cpld_reg.pola_53_8=negative +sff_cpld_reg.addr_53_8=0x00040033 +sff_cpld_reg.len_53_8=1 +sff_cpld_reg.bit_offset_53_8=4 + +sff_cpld_reg.mode_54_8=config +sff_cpld_reg.src_54_8=cpld +sff_cpld_reg.frmt_54_8=bit +sff_cpld_reg.pola_54_8=negative +sff_cpld_reg.addr_54_8=0x00040033 +sff_cpld_reg.len_54_8=1 +sff_cpld_reg.bit_offset_54_8=5 + +sff_cpld_reg.mode_55_8=config +sff_cpld_reg.src_55_8=cpld +sff_cpld_reg.frmt_55_8=bit +sff_cpld_reg.pola_55_8=negative +sff_cpld_reg.addr_55_8=0x00040033 +sff_cpld_reg.len_55_8=1 +sff_cpld_reg.bit_offset_55_8=6 + +sff_cpld_reg.mode_56_8=config +sff_cpld_reg.src_56_8=cpld +sff_cpld_reg.frmt_56_8=bit +sff_cpld_reg.pola_56_8=negative +sff_cpld_reg.addr_56_8=0x00040033 +sff_cpld_reg.len_56_8=1 +sff_cpld_reg.bit_offset_56_8=7 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/cfg_file_name new file mode 100644 index 000000000000..5f49420441a5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,4 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/setup.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/setup.py index f36055fb4e6d..6c3916921abb 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/setup.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/setup.py @@ -3,18 +3,25 @@ setup( name='sonic-platform', version='1.0', - description='SONiC platform API implementation on RAGILE Platforms', + description='SONiC platform API implementation', license='Apache 2.0', author='SONiC Team', - author_email='support@ragile.com', + author_email='support', url='', - maintainer='RAGILE SUPPORT TEAM', + maintainer='support', maintainer_email='', packages=[ 'sonic_platform', - 'rgutil', + 'plat_hal', + 'wbutil', 'eepromutil', - 'sonic_pcie', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', ], classifiers=[ 'Development Status :: 3 - Alpha', @@ -30,4 +37,3 @@ ], keywords='sonic SONiC platform PLATFORM', ) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/.upgrade_test/cpld_test_header.vme b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/.upgrade_test/cpld_test_header.vme new file mode 100644 index 0000000000000000000000000000000000000000..0fdca91f1d2fc2a072bb0a17b4398834eaff68a6 GIT binary patch literal 357 zcmYc;$VrJWNi8mk&qz&7NiEVV%T48S^Yn4`aCLNX4btFpaSaQJ3~;qIs4y`wN#+8x zlYyGJoIM;p{cH_^v}b^yqpzziSTxKvDA?2A&$i3}YzkO;n6E3BbC5I82tz~jWJA+5 zQ!Y)e)P-g7KwxO3XZSJM-6bzV+hbt z1sBH +#include + +typedef enum { + DBG_START, + DBG_VERBOSE, + DBG_KEY, + DBG_WARN, + DBG_ERROR, + DBG_END, +} dbg_level_t; + +typedef enum dfd_cpld_id { + BCM_CPLD0 = 0, + BCM_CPLD1, + CPLD0_MAC0, + CPLD0_MAC1, + CPLD1_MAC0, + CPLD2_MAC1, +} dfd_cpld_id_t; + + typedef enum dfd_cpld_bus { + SMBUS_BUS = 0 , + PCA9641_BUS = 1, + GPIO_BUS = 2, +} dfd_cpld_bus_t; + + typedef struct dfd_i2c_dev_s { + int bus; + int addr; + } dfd_i2c_dev_t; + + typedef enum dfd_cpld_addr { + CPLD_ADDR_MIN = 0x31, + BCM_CPLD0_ADDR = 0x32, + CPLD0_MAC0_ADDR = 0x33, + CPLD0_MAC1_ADDR = 0x34, + CPLD1_MAC0_ADDR = 0x35, + CPLD2_MAC1_ADDR = 0x36, + BCM_CPLD1_ADDR = 0x37, + CPLD_ADDR_MAX, +} dfd_cpld_addr_t; + +typedef struct dfd_dev_head_info_s { + uint8_t ver; + uint8_t flag; + uint8_t hw_ver; + uint8_t type; + int16_t tlv_len; +} dfd_dev_head_info_t; + +typedef enum dfd_intf_e{ + DFD_INTF_GET_FAN_HW_VERSION, + DFD_INTF_GET_FAN_STATUS, + DFD_INTF_GET_FAN_SPEED_LEVEL, + DFD_INTF_GET_FAN_SPEED, + DFD_INTF_GET_FAN_ATTRIBUTE, + DFD_INTF_GET_FAN_SN, + DFD_INTF_GET_FAN_TYPE, + DFD_INTF_SET_FAN_SPEED_LEVEL, + DFD_INTF_GET_FAN_SUB_NUM, + DFD_INTF_GET_FAN_FAIL_BITMAP, +}dfd_intf_t; + +typedef struct dfd_dev_tlv_info_s { + uint8_t type; + uint8_t len; + uint8_t data[0]; +} dfd_dev_tlv_info_t; + +typedef enum dfd_dev_info_type_e { + DFD_DEV_INFO_TYPE_MAC = 1, + DFD_DEV_INFO_TYPE_NAME = 2, + DFD_DEV_INFO_TYPE_SN = 3, + DFD_DEV_INFO_TYPE_PWR_CONS = 4, + DFD_DEV_INFO_TYPE_HW_INFO = 5, + DFD_DEV_INFO_TYPE_DEV_TYPE = 6, +} dfd_dev_tlv_type_t; + +typedef struct i2c_muxs_struct_flag +{ + int nr; + char name[48]; + struct mutex update_lock; + int flag; +}i2c_mux_flag; + +extern int setpca9641_muxflag(i2c_mux_flag i2c); +extern i2c_mux_flag getpca9641_muxflag(void) ; + +extern int debuglevel; +extern int dfd_cpld_read_chipid(int cpldid , uint32_t addr, int32_t size, unsigned char *buf); +extern int dfd_cpld_read(int32_t addr, uint8_t *val); +extern int dfd_cpld_write(int32_t addr, uint8_t val); + +#define DBG_DEBUG(fmt, arg...) do { \ + if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ + printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else if ( debuglevel >= DBG_ERROR ) { \ + printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else { } \ +} while (0) + +#define DBG_ERROR(fmt, arg...) do { \ + if ( debuglevel > DBG_START) { \ + printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_firmware_upgrade_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_firmware_upgrade_device.c new file mode 100644 index 000000000000..e203d569d897 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_firmware_upgrade_device.c @@ -0,0 +1,155 @@ +/* + * wb_firmware_upgrade.c + * Original Author: support 2021-03-17 + * + * ko for firmware device + * History + * [Version] [Author] [Date] [Description] + * v1.0 support 2021-05-07 Initial version + */ +#include +#include +#include +#include +#include +#include + +static int g_wb_firmware_upgrade_debug = 0; +static int g_wb_firmware_upgrade_error = 0; + +module_param(g_wb_firmware_upgrade_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_firmware_upgrade_error, int, S_IRUGO | S_IWUSR); + +#define WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_firmware_upgrade_debug) { \ + printk(KERN_INFO "[WB_FIRMWARE_UPGRADE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FIRMWARE_UPGRADE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_firmware_upgrade_error) { \ + printk(KERN_ERR "[WB_FIRMWARE_UPGRADE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* vme cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 32, + .tck = 65, + .tms = 6, + .tdo = 67, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 1, + .en_logic_num = 0, +}; + +/* isc cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "ISC", + .upg_type.jtag = { + .tdi = 32, + .tck = 65, + .tms = 6, + .tdo = 67, + }, + .en_gpio[0] = 26, + .en_level[0] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 1, + .en_logic_num = 0, +}; + +/* bios */ +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "MTD_DEV", + .chain = 1, + .chip_index = 1, + .upg_type.sysfs = { + .mtd_name = "BIOS", + .flash_base = 0x800000, + }, + + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, +}; + + static int __init firmware_upgrade_device_init(void) + { + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; + } + + static void __exit firmware_upgrade_device_exit(void) + { + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&firmware_upgrade_device[i]); + } + } + } + + module_init(firmware_upgrade_device_init); + module_exit(firmware_upgrade_device_exit); + MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 000000000000..3ba64250b7e0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,278 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca954x_device_debug = 0; +static int g_wb_i2c_mux_pca954x_device_error = 0; + +module_param(g_wb_i2c_mux_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 3, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 7, + .gpio_attr.reset_on = 1, + .gpio_attr.reset_off = 0, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data1 = { + .i2c_bus = 1, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 11, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data2 = { + .i2c_bus = 1, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 19, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data3 = { + .i2c_bus = 1, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 27, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data4 = { + .i2c_bus = 1, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 35, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data5 = { + .i2c_bus = 1, + .i2c_addr = 0x74, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 43, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data6 = { + .i2c_bus = 1, + .i2c_addr = 0x75, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 51, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data7 = { + .i2c_bus = 1, + .i2c_addr = 0x76, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 59, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data8 = { + .i2c_bus = 1, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 67, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data1, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data2, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data3, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data4, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data5, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data6, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data7, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data8, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (!client) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca9641_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca9641_device.c new file mode 100644 index 000000000000..5044fb2bb79d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca9641_device.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca9641_device_debug = 0; +static int g_wb_i2c_mux_pca9641_device_error = 0; + +module_param(g_wb_i2c_mux_pca9641_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca9641_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA9641_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca9641_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA9641_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA9641_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca9641_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA9641_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca9641_device_t i2c_mux_pca9641_device_data0 = { + .i2c_bus = 0, + .i2c_addr = 0x10, + .pca9641_nr = 2, + .pca9641_reset_type = PCA9641_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 68, + .gpio_attr.reset_on = 1, + .gpio_attr.reset_off = 0, + }, +}; + +struct i2c_board_info i2c_mux_pca9641_device_info[] = { + { + .type = "wb_pca9641", + .platform_data = &i2c_mux_pca9641_device_data0, + }, +}; + +static int __init wb_i2c_mux_pca9641_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca9641_device_t *i2c_mux_pca9641_device_data; + + WB_I2C_MUX_PCA9641_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca9641_device_info); i++) { + i2c_mux_pca9641_device_data = i2c_mux_pca9641_device_info[i].platform_data; + i2c_mux_pca9641_device_info[i].addr = i2c_mux_pca9641_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca9641_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca9641_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca9641_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca9641_device_info[i]); + if (!client) { + i2c_mux_pca9641_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca9641 device %d at bus %d!\n", + i2c_mux_pca9641_device_data->i2c_addr, i2c_mux_pca9641_device_data->i2c_bus); + } else { + i2c_mux_pca9641_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca9641_device_exit(void) +{ + int i; + i2c_mux_pca9641_device_t *i2c_mux_pca9641_device_data; + + WB_I2C_MUX_PCA9641_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca9641_device_info) - 1; i >= 0; i--) { + i2c_mux_pca9641_device_data = i2c_mux_pca9641_device_info[i].platform_data; + if (i2c_mux_pca9641_device_data->client) { + i2c_unregister_device(i2c_mux_pca9641_device_data->client); + i2c_mux_pca9641_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca9641_device_init); +module_exit(wb_i2c_mux_pca9641_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA9641 Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..b05efeb70dd1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_io_dev_device.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..8371b1ce0ea4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_platform_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_platform_i2c_dev_device.c new file mode 100644 index 000000000000..fa02ca22aad5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_platform_i2c_dev_device.c @@ -0,0 +1,199 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_platform_i2c_dev_device_debug = 0; +static int g_wb_platform_i2c_dev_device_error = 0; + +module_param(g_wb_platform_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_platform_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_platform_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_PLATFORM_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_platform_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_PLATFORM_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static platform_i2c_dev_device_t platform_i2c_dev_device_data0 = { + .i2c_bus = 0, + .i2c_addr = 0x0d, + .i2c_name = "cpld1", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data1 = { + .i2c_bus = 0, + .i2c_addr = 0x32, + .i2c_name = "cpld2", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data2 = { + .i2c_bus = 2, + .i2c_addr = 0x37, + .i2c_name = "cpld3", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data3 = { + .i2c_bus = 2, + .i2c_addr = 0x33, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data4 = { + .i2c_bus = 1, + .i2c_addr = 0x34, + .i2c_name = "cpld5", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data5 = { + .i2c_bus = 1, + .i2c_addr = 0x36, + .i2c_name = "cpld6", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data6 = { + .i2c_bus = 2, + .i2c_addr = 0x35, + .i2c_name = "cpld7", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static void wb_platform_i2c_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device platform_i2c_dev_device[] = { + { + .name = "wb-platform-i2c-dev", + .id = 1, + .dev = { + .platform_data = &platform_i2c_dev_device_data0, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 2, + .dev = { + .platform_data = &platform_i2c_dev_device_data1, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 3, + .dev = { + .platform_data = &platform_i2c_dev_device_data2, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 4, + .dev = { + .platform_data = &platform_i2c_dev_device_data3, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 5, + .dev = { + .platform_data = &platform_i2c_dev_device_data4, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 6, + .dev = { + .platform_data = &platform_i2c_dev_device_data5, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 7, + .dev = { + .platform_data = &platform_i2c_dev_device_data6, + .release = wb_platform_i2c_dev_device_release, + }, + }, +}; + +static int __init wb_platform_i2c_dev_device_init(void) +{ + int i; + int ret = 0; + platform_i2c_dev_device_t *platform_i2c_dev_device_data; + + WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(platform_i2c_dev_device); i++) { + platform_i2c_dev_device_data = platform_i2c_dev_device[i].dev.platform_data; + ret = platform_device_register(&platform_i2c_dev_device[i]); + if (ret < 0) { + platform_i2c_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-platform-i2c-dev.%d register failed!\n", i + 1); + } else { + platform_i2c_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_platform_i2c_dev_device_exit(void) +{ + int i; + platform_i2c_dev_device_t *platform_i2c_dev_device_data; + + WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(platform_i2c_dev_device) - 1; i >= 0; i--) { + platform_i2c_dev_device_data = platform_i2c_dev_device[i].dev.platform_data; + if (platform_i2c_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&platform_i2c_dev_device[i]); + } + } +} + +module_init(wb_platform_i2c_dev_device_init); +module_exit(wb_platform_i2c_dev_device_exit); +MODULE_DESCRIPTION("PLATFORM I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..4078bf2684d1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,48 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_0_0=0 +cpld_i2c_dev.addr_0_0=0x32 +cpld_i2c_dev.bus_0_1=2 +cpld_i2c_dev.addr_0_1=0x37 +cpld_i2c_dev.bus_0_2=2 +cpld_i2c_dev.addr_0_2=0x33 +cpld_i2c_dev.bus_0_3=1 +cpld_i2c_dev.addr_0_3=0x34 +cpld_i2c_dev.bus_0_4=2 +cpld_i2c_dev.addr_0_4=0x35 +cpld_i2c_dev.bus_0_5=1 +cpld_i2c_dev.addr_0_5=0x36 +cpld_i2c_dev.bus_0_6=0 +cpld_i2c_dev.addr_0_6=0x0d + + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_7=0x700 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=i2c +mode_cpld_0_1=i2c +mode_cpld_0_2=i2c +mode_cpld_0_3=i2c +mode_cpld_0_4=i2c +mode_cpld_0_5=i2c +mode_cpld_0_6=i2c +mode_cpld_0_7=lpc + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=8 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..89966d9897bf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,145 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=3 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=1 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x00010030 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x00010030 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=1 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x00010030 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=2 + + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x00010031 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=0 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x00010031 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=1 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x00010031 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=2 + + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x0001001b +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0001001d +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0001001f +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x00000015 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x00000015 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x00000015 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..cc4a6dae1db3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,64 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=2 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00010051 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00010051 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00010051 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00010051 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=4 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00010051 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=5 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00010051 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=6 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg new file mode 100755 index 000000000000..98136f07651e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg @@ -0,0 +1,225 @@ +# Number of temperature sensors on the mainboard +dev_num_0_1=0 + +# Number of voltage sensors on the mainboard +dev_num_0_2=10 + +# in1 +hwmon_in.mode_0x0001_0x00=config +hwmon_in.int_cons_0x0001_0x00=0 +hwmon_in.src_0x0001_0x00=cpld +hwmon_in.frmt_0x0001_0x00=num_bytes +hwmon_in.addr_0x0001_0x00=0x00020080 +hwmon_in.len_0x0001_0x00=2 +hwmon_in.int_extra1_0x0001_0x00=0x0002008e +hwmon_in.int_extra2_0x0001_0x00=2480 + +hwmon_in.mode_0x0001_0x01=str_constant +hwmon_in.str_cons_0x0001_0x01=MAC_BOARD_VDD3V3 + +hwmon_in.mode_0x0001_0x02=str_constant +hwmon_in.str_cons_0x0001_0x02=cpld + +hwmon_in.mode_0x0001_0x03=str_constant +hwmon_in.str_cons_0x0001_0x03=3542 + +hwmon_in.mode_0x0001_0x05=str_constant +hwmon_in.str_cons_0x0001_0x05=3135 + +# in2 +hwmon_in.mode_0x0002_0x00=config +hwmon_in.int_cons_0x0002_0x00=0 +hwmon_in.src_0x0002_0x00=cpld +hwmon_in.frmt_0x0002_0x00=num_bytes +hwmon_in.addr_0x0002_0x00=0x00020082 +hwmon_in.len_0x0002_0x00=2 +hwmon_in.int_extra1_0x0002_0x00=0x0002008e +hwmon_in.int_extra2_0x0002_0x00=1240 + +hwmon_in.mode_0x0002_0x01=str_constant +hwmon_in.str_cons_0x0002_0x01=MAC_BOARD_VDD1V2_MAC + +hwmon_in.mode_0x0002_0x02=str_constant +hwmon_in.str_cons_0x0002_0x02=cpld + +hwmon_in.mode_0x0002_0x03=str_constant +hwmon_in.str_cons_0x0002_0x03=126 + +hwmon_in.mode_0x0002_0x05=str_constant +hwmon_in.str_cons_0x0002_0x05=114 + +# in3 +hwmon_in.mode_0x0003_0x00=config +hwmon_in.int_cons_0x0003_0x00=0 +hwmon_in.src_0x0003_0x00=cpld +hwmon_in.frmt_0x0003_0x00=num_bytes +hwmon_in.addr_0x0003_0x00=0x00020084 +hwmon_in.len_0x0003_0x00=2 +hwmon_in.int_extra1_0x0003_0x00=0x0002008e +hwmon_in.int_extra2_0x0003_0x00=1240 + +hwmon_in.mode_0x0003_0x01=str_constant +hwmon_in.str_cons_0x0003_0x01=MAC_BOARD_VDD_CORE + +hwmon_in.mode_0x0003_0x02=str_constant +hwmon_in.str_cons_0x0003_0x02=cpld + +hwmon_in.mode_0x0003_0x03=str_constant +hwmon_in.str_cons_0x0003_0x03=945 + +hwmon_in.mode_0x0003_0x05=str_constant +hwmon_in.str_cons_0x0003_0x05=712 + +# in4 +hwmon_in.mode_0x0004_0x00=config +hwmon_in.int_cons_0x0004_0x00=0 +hwmon_in.src_0x0004_0x00=cpld +hwmon_in.frmt_0x0004_0x00=num_bytes +hwmon_in.addr_0x0004_0x00=0x00020086 +hwmon_in.len_0x0004_0x00=2 +hwmon_in.int_extra1_0x0004_0x00=0x0002008e +hwmon_in.int_extra2_0x0004_0x00=1240 + +hwmon_in.mode_0x0004_0x01=str_constant +hwmon_in.str_cons_0x0004_0x01=MAC_BOARD_VDD_ANALOG + +hwmon_in.mode_0x0004_0x02=str_constant +hwmon_in.str_cons_0x0004_0x02=cpld + +hwmon_in.mode_0x0004_0x03=str_constant +hwmon_in.str_cons_0x0004_0x03=856 + +hwmon_in.mode_0x0004_0x05=str_constant +hwmon_in.str_cons_0x0004_0x05=760 + +# in5 +hwmon_in.mode_0x0005_0x00=config +hwmon_in.int_cons_0x0005_0x00=0 +hwmon_in.src_0x0005_0x00=cpld +hwmon_in.frmt_0x0005_0x00=num_bytes +hwmon_in.addr_0x0005_0x00=0x00020088 +hwmon_in.len_0x0005_0x00=2 +hwmon_in.int_extra1_0x0005_0x00=0x0002008e +hwmon_in.int_extra2_0x0005_0x00=2480 + +hwmon_in.mode_0x0005_0x01=str_constant +hwmon_in.str_cons_0x0005_0x01=MAC_BOARD_QSFP_3V3 + +hwmon_in.mode_0x0005_0x02=str_constant +hwmon_in.str_cons_0x0005_0x02=cpld + +hwmon_in.mode_0x0005_0x03=str_constant +hwmon_in.str_cons_0x0005_0x03=3500 + +hwmon_in.mode_0x0005_0x05=str_constant +hwmon_in.str_cons_0x0005_0x05=3135 + +# in6 +hwmon_in.mode_0x0006_0x00=config +hwmon_in.int_cons_0x0006_0x00=0 +hwmon_in.src_0x0006_0x00=cpld +hwmon_in.frmt_0x0006_0x00=num_bytes +hwmon_in.addr_0x0006_0x00=0x0002008a +hwmon_in.len_0x0006_0x00=2 +hwmon_in.int_extra1_0x0006_0x00=0x0002008e +hwmon_in.int_extra2_0x0006_0x00=2480 + +hwmon_in.mode_0x0006_0x01=str_constant +hwmon_in.str_cons_0x0006_0x01=MAC_BOARD_VDD5.0V + +hwmon_in.mode_0x0006_0x02=str_constant +hwmon_in.str_cons_0x0006_0x02=cpld + +hwmon_in.mode_0x0006_0x03=str_constant +hwmon_in.str_cons_0x0006_0x03=5331 + +hwmon_in.mode_0x0006_0x05=str_constant +hwmon_in.str_cons_0x0006_0x05=4750 + +# in7 +hwmon_in.mode_0x0007_0x00=config +hwmon_in.int_cons_0x0007_0x00=0 +hwmon_in.src_0x0007_0x00=cpld +hwmon_in.frmt_0x0007_0x00=num_bytes +hwmon_in.addr_0x0007_0x00=0x0002008c +hwmon_in.len_0x0007_0x00=2 +hwmon_in.int_extra1_0x0007_0x00=0x0002008e +hwmon_in.int_extra2_0x0007_0x00=1240 + +hwmon_in.mode_0x0007_0x01=str_constant +hwmon_in.str_cons_0x0007_0x01=MAC_BOARD_VDD1.8V + +hwmon_in.mode_0x0007_0x02=str_constant +hwmon_in.str_cons_0x0007_0x02=cpld + +hwmon_in.mode_0x0007_0x03=str_constant +hwmon_in.str_cons_0x0007_0x03=1909 + +hwmon_in.mode_0x0007_0x05=str_constant +hwmon_in.str_cons_0x0007_0x05=1710 + +# in8 +hwmon_in.mode_0x0008_0x00=config +hwmon_in.int_cons_0x0008_0x00=0 +hwmon_in.src_0x0008_0x00=cpld +hwmon_in.frmt_0x0008_0x00=num_bytes +hwmon_in.addr_0x0008_0x00=0x0002008e +hwmon_in.len_0x0008_0x00=2 +hwmon_in.int_extra1_0x0008_0x00=0x0002008e +hwmon_in.int_extra2_0x0008_0x00=1000 + +hwmon_in.mode_0x0008_0x01=str_constant +hwmon_in.str_cons_0x0008_0x01=MAC_BOARD_TEST1.24V + +hwmon_in.mode_0x0008_0x02=str_constant +hwmon_in.str_cons_0x0008_0x02=cpld + +hwmon_in.mode_0x0008_0x03=str_constant +hwmon_in.str_cons_0x0008_0x03=1302 + +hwmon_in.mode_0x0008_0x05=str_constant +hwmon_in.str_cons_0x0008_0x05=1178 + +# in9 +hwmon_in.mode_0x0009_0x00=config +hwmon_in.int_cons_0x0009_0x00=0 +hwmon_in.src_0x0009_0x00=cpld +hwmon_in.frmt_0x0009_0x00=num_bytes +hwmon_in.addr_0x0009_0x00=0x0002009a +hwmon_in.len_0x0009_0x00=2 +hwmon_in.int_extra1_0x0009_0x00=0x0002008e +hwmon_in.int_extra2_0x0009_0x00=2480 + +hwmon_in.mode_0x0009_0x01=str_constant +hwmon_in.str_cons_0x0009_0x01=MAC_BOARD_ZSFP3.3V + +hwmon_in.mode_0x0009_0x02=str_constant +hwmon_in.str_cons_0x0009_0x02=cpld + +hwmon_in.mode_0x0009_0x03=str_constant +hwmon_in.str_cons_0x0009_0x03=3542 + +hwmon_in.mode_0x0009_0x05=str_constant +hwmon_in.str_cons_0x0009_0x05=3135 + +# in10 +hwmon_in.mode_0x000a_0x00=config +hwmon_in.int_cons_0x000a_0x00=0 +hwmon_in.src_0x000a_0x00=cpld +hwmon_in.frmt_0x000a_0x00=num_bytes +hwmon_in.addr_0x000a_0x00=0x0002009c +hwmon_in.len_0x000a_0x00=2 +hwmon_in.int_extra1_0x000a_0x00=0x0002008e +hwmon_in.int_extra2_0x000a_0x00=2480 + +hwmon_in.mode_0x000a_0x01=str_constant +hwmon_in.str_cons_0x000a_0x01=MAC_BOARD_VDD3V3_CLK_MCU + +hwmon_in.mode_0x000a_0x02=str_constant +hwmon_in.str_cons_0x000a_0x02=cpld + +hwmon_in.mode_0x000a_0x03=str_constant +hwmon_in.str_cons_0x000a_0x03=3542 + +hwmon_in.mode_0x000a_0x05=str_constant +hwmon_in.str_cons_0x000a_0x05=3135 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..67bec1920049 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,592 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=64 + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 +sff_dir_name_33 =sff33 +sff_dir_name_34 =sff34 +sff_dir_name_35 =sff35 +sff_dir_name_36 =sff36 +sff_dir_name_37 =sff37 +sff_dir_name_38 =sff38 +sff_dir_name_39 =sff39 +sff_dir_name_40 =sff40 +sff_dir_name_41 =sff41 +sff_dir_name_42 =sff42 +sff_dir_name_43 =sff43 +sff_dir_name_44 =sff44 +sff_dir_name_45 =sff45 +sff_dir_name_46 =sff46 +sff_dir_name_47 =sff47 +sff_dir_name_48 =sff48 +sff_dir_name_49 =sff49 +sff_dir_name_50 =sff50 +sff_dir_name_51 =sff51 +sff_dir_name_52 =sff52 +sff_dir_name_53 =sff53 +sff_dir_name_54 =sff54 +sff_dir_name_55 =sff55 +sff_dir_name_56 =sff56 +sff_dir_name_57 =sff57 +sff_dir_name_58 =sff58 +sff_dir_name_59 =sff59 +sff_dir_name_60 =sff60 +sff_dir_name_61 =sff61 +sff_dir_name_62 =sff62 +sff_dir_name_63 =sff63 +sff_dir_name_64 =sff64 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x00030030 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x00030030 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x00030030 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x00030030 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x00030030 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x00030030 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x00030030 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x00030030 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x00030031 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x00030031 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x00030031 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x00030031 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x00030031 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x00030031 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x00030031 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x00030031 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x00050030 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x00050030 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x00050030 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x00050030 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x00050030 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x00050030 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x00050030 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x00050030 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x00050031 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x00050031 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x00050031 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x00050031 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x00050031 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x00050031 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x00050031 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x00050031 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +sff_cpld_reg.mode_33_8=config +sff_cpld_reg.src_33_8=cpld +sff_cpld_reg.frmt_33_8=bit +sff_cpld_reg.pola_33_8=negative +sff_cpld_reg.addr_33_8=0x00030032 +sff_cpld_reg.len_33_8=1 +sff_cpld_reg.bit_offset_33_8=0 + +sff_cpld_reg.mode_34_8=config +sff_cpld_reg.src_34_8=cpld +sff_cpld_reg.frmt_34_8=bit +sff_cpld_reg.pola_34_8=negative +sff_cpld_reg.addr_34_8=0x00030032 +sff_cpld_reg.len_34_8=1 +sff_cpld_reg.bit_offset_34_8=1 + +sff_cpld_reg.mode_35_8=config +sff_cpld_reg.src_35_8=cpld +sff_cpld_reg.frmt_35_8=bit +sff_cpld_reg.pola_35_8=negative +sff_cpld_reg.addr_35_8=0x00030032 +sff_cpld_reg.len_35_8=1 +sff_cpld_reg.bit_offset_35_8=2 + +sff_cpld_reg.mode_36_8=config +sff_cpld_reg.src_36_8=cpld +sff_cpld_reg.frmt_36_8=bit +sff_cpld_reg.pola_36_8=negative +sff_cpld_reg.addr_36_8=0x00030032 +sff_cpld_reg.len_36_8=1 +sff_cpld_reg.bit_offset_36_8=3 + +sff_cpld_reg.mode_37_8=config +sff_cpld_reg.src_37_8=cpld +sff_cpld_reg.frmt_37_8=bit +sff_cpld_reg.pola_37_8=negative +sff_cpld_reg.addr_37_8=0x00030032 +sff_cpld_reg.len_37_8=1 +sff_cpld_reg.bit_offset_37_8=4 + +sff_cpld_reg.mode_38_8=config +sff_cpld_reg.src_38_8=cpld +sff_cpld_reg.frmt_38_8=bit +sff_cpld_reg.pola_38_8=negative +sff_cpld_reg.addr_38_8=0x00030032 +sff_cpld_reg.len_38_8=1 +sff_cpld_reg.bit_offset_38_8=5 + +sff_cpld_reg.mode_39_8=config +sff_cpld_reg.src_39_8=cpld +sff_cpld_reg.frmt_39_8=bit +sff_cpld_reg.pola_39_8=negative +sff_cpld_reg.addr_39_8=0x00030032 +sff_cpld_reg.len_39_8=1 +sff_cpld_reg.bit_offset_39_8=6 + +sff_cpld_reg.mode_40_8=config +sff_cpld_reg.src_40_8=cpld +sff_cpld_reg.frmt_40_8=bit +sff_cpld_reg.pola_40_8=negative +sff_cpld_reg.addr_40_8=0x00030032 +sff_cpld_reg.len_40_8=1 +sff_cpld_reg.bit_offset_40_8=7 + +sff_cpld_reg.mode_41_8=config +sff_cpld_reg.src_41_8=cpld +sff_cpld_reg.frmt_41_8=bit +sff_cpld_reg.pola_41_8=negative +sff_cpld_reg.addr_41_8=0x00030033 +sff_cpld_reg.len_41_8=1 +sff_cpld_reg.bit_offset_41_8=0 + +sff_cpld_reg.mode_42_8=config +sff_cpld_reg.src_42_8=cpld +sff_cpld_reg.frmt_42_8=bit +sff_cpld_reg.pola_42_8=negative +sff_cpld_reg.addr_42_8=0x00030033 +sff_cpld_reg.len_42_8=1 +sff_cpld_reg.bit_offset_42_8=1 + +sff_cpld_reg.mode_43_8=config +sff_cpld_reg.src_43_8=cpld +sff_cpld_reg.frmt_43_8=bit +sff_cpld_reg.pola_43_8=negative +sff_cpld_reg.addr_43_8=0x00030033 +sff_cpld_reg.len_43_8=1 +sff_cpld_reg.bit_offset_43_8=2 + +sff_cpld_reg.mode_44_8=config +sff_cpld_reg.src_44_8=cpld +sff_cpld_reg.frmt_44_8=bit +sff_cpld_reg.pola_44_8=negative +sff_cpld_reg.addr_44_8=0x00030033 +sff_cpld_reg.len_44_8=1 +sff_cpld_reg.bit_offset_44_8=3 + +sff_cpld_reg.mode_45_8=config +sff_cpld_reg.src_45_8=cpld +sff_cpld_reg.frmt_45_8=bit +sff_cpld_reg.pola_45_8=negative +sff_cpld_reg.addr_45_8=0x00030033 +sff_cpld_reg.len_45_8=1 +sff_cpld_reg.bit_offset_45_8=4 + +sff_cpld_reg.mode_46_8=config +sff_cpld_reg.src_46_8=cpld +sff_cpld_reg.frmt_46_8=bit +sff_cpld_reg.pola_46_8=negative +sff_cpld_reg.addr_46_8=0x00030033 +sff_cpld_reg.len_46_8=1 +sff_cpld_reg.bit_offset_46_8=5 + +sff_cpld_reg.mode_47_8=config +sff_cpld_reg.src_47_8=cpld +sff_cpld_reg.frmt_47_8=bit +sff_cpld_reg.pola_47_8=negative +sff_cpld_reg.addr_47_8=0x00030033 +sff_cpld_reg.len_47_8=1 +sff_cpld_reg.bit_offset_47_8=6 + +sff_cpld_reg.mode_48_8=config +sff_cpld_reg.src_48_8=cpld +sff_cpld_reg.frmt_48_8=bit +sff_cpld_reg.pola_48_8=negative +sff_cpld_reg.addr_48_8=0x00030033 +sff_cpld_reg.len_48_8=1 +sff_cpld_reg.bit_offset_48_8=7 + +sff_cpld_reg.mode_49_8=config +sff_cpld_reg.src_49_8=cpld +sff_cpld_reg.frmt_49_8=bit +sff_cpld_reg.pola_49_8=negative +sff_cpld_reg.addr_49_8=0x00050032 +sff_cpld_reg.len_49_8=1 +sff_cpld_reg.bit_offset_49_8=0 + +sff_cpld_reg.mode_50_8=config +sff_cpld_reg.src_50_8=cpld +sff_cpld_reg.frmt_50_8=bit +sff_cpld_reg.pola_50_8=negative +sff_cpld_reg.addr_50_8=0x00050032 +sff_cpld_reg.len_50_8=1 +sff_cpld_reg.bit_offset_50_8=1 + +sff_cpld_reg.mode_51_8=config +sff_cpld_reg.src_51_8=cpld +sff_cpld_reg.frmt_51_8=bit +sff_cpld_reg.pola_51_8=negative +sff_cpld_reg.addr_51_8=0x00050032 +sff_cpld_reg.len_51_8=1 +sff_cpld_reg.bit_offset_51_8=2 + +sff_cpld_reg.mode_52_8=config +sff_cpld_reg.src_52_8=cpld +sff_cpld_reg.frmt_52_8=bit +sff_cpld_reg.pola_52_8=negative +sff_cpld_reg.addr_52_8=0x00050032 +sff_cpld_reg.len_52_8=1 +sff_cpld_reg.bit_offset_52_8=3 + +sff_cpld_reg.mode_53_8=config +sff_cpld_reg.src_53_8=cpld +sff_cpld_reg.frmt_53_8=bit +sff_cpld_reg.pola_53_8=negative +sff_cpld_reg.addr_53_8=0x00050032 +sff_cpld_reg.len_53_8=1 +sff_cpld_reg.bit_offset_53_8=4 + +sff_cpld_reg.mode_54_8=config +sff_cpld_reg.src_54_8=cpld +sff_cpld_reg.frmt_54_8=bit +sff_cpld_reg.pola_54_8=negative +sff_cpld_reg.addr_54_8=0x00050032 +sff_cpld_reg.len_54_8=1 +sff_cpld_reg.bit_offset_54_8=5 + +sff_cpld_reg.mode_55_8=config +sff_cpld_reg.src_55_8=cpld +sff_cpld_reg.frmt_55_8=bit +sff_cpld_reg.pola_55_8=negative +sff_cpld_reg.addr_55_8=0x00050032 +sff_cpld_reg.len_55_8=1 +sff_cpld_reg.bit_offset_55_8=6 + +sff_cpld_reg.mode_56_8=config +sff_cpld_reg.src_56_8=cpld +sff_cpld_reg.frmt_56_8=bit +sff_cpld_reg.pola_56_8=negative +sff_cpld_reg.addr_56_8=0x00050032 +sff_cpld_reg.len_56_8=1 +sff_cpld_reg.bit_offset_56_8=7 +sff_cpld_reg.mode_57_8=config +sff_cpld_reg.src_57_8=cpld +sff_cpld_reg.frmt_57_8=bit +sff_cpld_reg.pola_57_8=negative +sff_cpld_reg.addr_57_8=0x00050033 +sff_cpld_reg.len_57_8=1 +sff_cpld_reg.bit_offset_57_8=0 + +sff_cpld_reg.mode_58_8=config +sff_cpld_reg.src_58_8=cpld +sff_cpld_reg.frmt_58_8=bit +sff_cpld_reg.pola_58_8=negative +sff_cpld_reg.addr_58_8=0x00050033 +sff_cpld_reg.len_58_8=1 +sff_cpld_reg.bit_offset_58_8=1 + +sff_cpld_reg.mode_59_8=config +sff_cpld_reg.src_59_8=cpld +sff_cpld_reg.frmt_59_8=bit +sff_cpld_reg.pola_59_8=negative +sff_cpld_reg.addr_59_8=0x00050033 +sff_cpld_reg.len_59_8=1 +sff_cpld_reg.bit_offset_59_8=2 + +sff_cpld_reg.mode_60_8=config +sff_cpld_reg.src_60_8=cpld +sff_cpld_reg.frmt_60_8=bit +sff_cpld_reg.pola_60_8=negative +sff_cpld_reg.addr_60_8=0x00050033 +sff_cpld_reg.len_60_8=1 +sff_cpld_reg.bit_offset_60_8=3 + +sff_cpld_reg.mode_61_8=config +sff_cpld_reg.src_61_8=cpld +sff_cpld_reg.frmt_61_8=bit +sff_cpld_reg.pola_61_8=negative +sff_cpld_reg.addr_61_8=0x00050033 +sff_cpld_reg.len_61_8=1 +sff_cpld_reg.bit_offset_61_8=4 + +sff_cpld_reg.mode_62_8=config +sff_cpld_reg.src_62_8=cpld +sff_cpld_reg.frmt_62_8=bit +sff_cpld_reg.pola_62_8=negative +sff_cpld_reg.addr_62_8=0x00050033 +sff_cpld_reg.len_62_8=1 +sff_cpld_reg.bit_offset_62_8=5 + +sff_cpld_reg.mode_63_8=config +sff_cpld_reg.src_63_8=cpld +sff_cpld_reg.frmt_63_8=bit +sff_cpld_reg.pola_63_8=negative +sff_cpld_reg.addr_63_8=0x00050033 +sff_cpld_reg.len_63_8=1 +sff_cpld_reg.bit_offset_63_8=6 + +sff_cpld_reg.mode_64_8=config +sff_cpld_reg.src_64_8=cpld +sff_cpld_reg.frmt_64_8=bit +sff_cpld_reg.pola_64_8=negative +sff_cpld_reg.addr_64_8=0x00050033 +sff_cpld_reg.len_64_8=1 +sff_cpld_reg.bit_offset_64_8=7 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/cfg_file_name new file mode 100755 index 000000000000..c3ea65365c78 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,5 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF +WB_PLAT_SENSOR diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py old mode 100644 new mode 100755 index 0ed22d770626..6c3916921abb --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py @@ -3,17 +3,25 @@ setup( name='sonic-platform', version='1.0', - description='SONiC platform API implementation on RAGILE Platforms', + description='SONiC platform API implementation', license='Apache 2.0', author='SONiC Team', - author_email='support@ragile.com', + author_email='support', url='', - maintainer='RAGILE SUPPORT TEAM', + maintainer='support', maintainer_email='', packages=[ 'sonic_platform', - 'rgutil', - 'eepromutil' + 'plat_hal', + 'wbutil', + 'eepromutil', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', ], classifiers=[ 'Development Status :: 3 - Alpha', @@ -29,4 +37,3 @@ ], keywords='sonic SONiC platform PLATFORM', ) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/.upgrade_test/board_cpld_test_header.vme b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/.upgrade_test/board_cpld_test_header.vme new file mode 100644 index 0000000000000000000000000000000000000000..2c364e44b9eea15e4541783bd3269c90d12b3b25 GIT binary patch literal 470 zcmaivK}&={7=}k(9GwWZEU4QY>#{hm!XkK(b!vsy789Y9?5;+EyAGR4o$AyN>o@cx z>ew&XX56mfcbS*rd!CnXQO!4bwq#|V)x~2yXjTQf2(Rdb`T>p4P(ah*_pQ0yq%>(;LyXAehDKU)JJ?HS)5EvTi8GcN5cgal5&Cg3wa7iu5$*;^!%_~s|$l}a%uv9_A^g99 zlYyOqiJ6&+`vtoIqacSc1ABpxf-oZkiwMIZ-YadQO#fL5I2hO%I6*qtK{^Pjt_J{6 Ct5Adh literal 0 HcmV?d00001 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/Makefile b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/Makefile index 46415e74ab7d..1b84abef410a 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/Makefile @@ -5,10 +5,9 @@ EXTRA_CFLAGS+= -Wall SUB_BUILD_DIR = $(PWD)/build INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin -INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system/ - -KBUILD_EXTRA_SYMBOLS += $(DIR_KERNEL_SRC)/Module.symvers -export KBUILD_EXTRA_SYMBOLS +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_SYSFS_CFG_DIR = $(SUB_BUILD_DIR)/etc/plat_sysfs_cfg +INSTALL_UPGRADE_TEST_DIR = $(SUB_BUILD_DIR)/etc/.upgrade_test all: $(MAKE) -C $(KBUILD_OUTPUT) M=$(DIR_KERNEL_SRC) modules @@ -16,11 +15,14 @@ all: cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_DIR) @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi cp -r $(PWD)/config/* $(INSTALL_SCRIPT_DIR) - @if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi - cp $(PWD)/systemd/*.service $(INSTALL_SERVICE_DIR) + @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi + @if [ -d $(PWD)/hal-config/ ]; then cp -r $(PWD)/hal-config/* ${INSTALL_LIB_DIR} ;fi + @if [ ! -d ${INSTALL_SYSFS_CFG_DIR} ]; then mkdir -p ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ -d $(PWD)/plat_sysfs_cfg/ ]; then cp -r $(PWD)/plat_sysfs_cfg/* ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ ! -d ${INSTALL_UPGRADE_TEST_DIR} ]; then mkdir -p ${INSTALL_UPGRADE_TEST_DIR} ;fi + @if [ -d $(PWD)/.upgrade_test/ ]; then cp -r $(PWD)/.upgrade_test/* ${INSTALL_UPGRADE_TEST_DIR} ;fi clean: rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order rm -rf ${DIR_KERNEL_SRC}/.tmp_versions rm -rf $(SUB_BUILD_DIR) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_config.py index 51cb6992a0a0..31638b4e8caf 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_config.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_config.py @@ -1,625 +1,1676 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: UTF-8 -*- -from ragilecommon import * -PCA9548START = -1 -PCA9548BUSEND = -2 - -RAGILE_CARDID = 0x0000404d -RAGILE_PRODUCTNAME = "RA-B6920-4S" +from platform_common import * STARTMODULE = { - "fancontrol": 1, + "fancontrol": 0, + "hal_fanctrl": 1, + "hal_ledctrl": 1, "avscontrol": 1, - "sfptempmodule": 0, - "sfptempmodule_interval": 3, "slot_monitor": 1, "dev_monitor": 1, + "pmon_syslog": 1, + "sff_temp_polling": 1, + "reboot_cause": 1, } DEV_MONITOR_PARAM = { - "polling_time": 5, + "polling_time": 10, "psus": [ { "name": "psu1", - "present": {"gettype": "io", "io_addr": 0xB27, "presentbit": 0, "okval": 0}, + "present": {"gettype": "io", "io_addr": 0xb27, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu1pmbus", - "name": "fsp1200", - "bus": 23, - "loc": 0x58, - "attr": "hwmon", - }, + {"id": "psu1pmbus", "name": "wb_fsp1200", "bus": 23, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu1frue2", "name": "wb_24c02", "bus": 23, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "psu2", - "present": {"gettype": "io", "io_addr": 0xB28, "presentbit": 0, "okval": 0}, + "present": {"gettype": "io", "io_addr": 0xb28, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu2pmbus", - "name": "fsp1200", - "bus": 25, - "loc": 0x58, - "attr": "hwmon", - }, + {"id": "psu2pmbus", "name": "wb_fsp1200", "bus": 25, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu2frue2", "name": "wb_24c02", "bus": 25, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "psu3", - "present": {"gettype": "io", "io_addr": 0xB29, "presentbit": 0, "okval": 0}, + "present": {"gettype": "io", "io_addr": 0xb29, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu3pmbus", - "name": "fsp1200", - "bus": 24, - "loc": 0x58, - "attr": "hwmon", - }, + {"id": "psu3pmbus", "name": "wb_fsp1200", "bus": 24, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu3frue2", "name": "wb_24c02", "bus": 24, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "psu4", - "present": {"gettype": "io", "io_addr": 0xB2A, "presentbit": 0, "okval": 0}, + "present": {"gettype": "io", "io_addr": 0xb2a, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu4pmbus", - "name": "fsp1200", - "bus": 26, - "loc": 0x58, - "attr": "hwmon", - }, - ], + {"id": "psu4pmbus", "name": "wb_fsp1200", "bus": 26, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu4frue2", "name": "wb_24c02", "bus": 26, "loc": 0x50, "attr": "eeprom"}, + ], }, ], "fans": [ { "name": "fan1", - "present": { - "gettype": "i2c", - "bus": 14, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 0, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 14, "loc": 0x0d, "offset": 0x30, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "fan1frue2", - "name": "24c02", - "bus": 63, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan1frue2", "name": "wb_24c02", "bus": 63, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan2", - "present": { - "gettype": "i2c", - "bus": 13, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 0, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 13, "loc": 0x0d, "offset": 0x30, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "fan2frue2", - "name": "24c02", - "bus": 55, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan2frue2", "name": "wb_24c02", "bus": 55, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan3", - "present": { - "gettype": "i2c", - "bus": 14, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 1, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 14, "loc": 0x0d, "offset": 0x30, "presentbit": 1, "okval": 0}, "device": [ - { - "id": "fan3frue2", - "name": "24c02", - "bus": 64, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan3frue2", "name": "wb_24c02", "bus": 64, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan4", - "present": { - "gettype": "i2c", - "bus": 13, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 1, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 13, "loc": 0x0d, "offset": 0x30, "presentbit": 1, "okval": 0}, "device": [ - { - "id": "fan4frue2", - "name": "24c02", - "bus": 56, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan4frue2", "name": "wb_24c02", "bus": 56, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan5", - "present": { - "gettype": "i2c", - "bus": 14, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 2, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 14, "loc": 0x0d, "offset": 0x30, "presentbit": 2, "okval": 0}, "device": [ - { - "id": "fan5frue2", - "name": "24c02", - "bus": 65, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan5frue2", "name": "wb_24c02", "bus": 65, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan6", - "present": { - "gettype": "i2c", - "bus": 13, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 2, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 13, "loc": 0x0d, "offset": 0x30, "presentbit": 2, "okval": 0}, + "device": [ + {"id": "fan6frue2", "name": "wb_24c02", "bus": 57, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "slots": [ + { + "name": "slot1", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 4, "okval": 0}, + "device": [ + {"id": "slot1frue2", "name": "wb_24c02", "bus": 3, "loc": 0x56, "attr": "eeprom"}, + {"id": "slot1tlve2", "name": "wb_24c02", "bus": 3, "loc": 0x57, "attr": "eeprom"}, + {"id": "slot1lm75a1", "name": "wb_lm75", "bus": 32, "loc": 0x48, "attr": "hwmon"}, + {"id": "slot1lm75a2", "name": "wb_lm75", "bus": 32, "loc": 0x49, "attr": "hwmon"}, + {"id": "slot1lm75a3", "name": "wb_lm75", "bus": 32, "loc": 0x4D, "attr": "hwmon"}, + ], + }, + { + "name": "slot2", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 5, "okval": 0}, + "device": [ + {"id": "slot2frue2", "name": "wb_24c02", "bus": 4, "loc": 0x56, "attr": "eeprom"}, + {"id": "slot2tlve2", "name": "wb_24c02", "bus": 4, "loc": 0x57, "attr": "eeprom"}, + {"id": "slot2lm75a1", "name": "wb_lm75", "bus": 48, "loc": 0x48, "attr": "hwmon"}, + {"id": "slot2lm75a2", "name": "wb_lm75", "bus": 48, "loc": 0x49, "attr": "hwmon"}, + {"id": "slot2lm75a3", "name": "wb_lm75", "bus": 48, "loc": 0x4D, "attr": "hwmon"}, + ], + }, + { + "name": "slot3", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 6, "okval": 0}, + "device": [ + {"id": "slot3frue2", "name": "wb_24c02", "bus": 5, "loc": 0x56, "attr": "eeprom"}, + {"id": "slot3tlve2", "name": "wb_24c02", "bus": 5, "loc": 0x57, "attr": "eeprom"}, + {"id": "slot3lm75a1", "name": "wb_lm75", "bus": 40, "loc": 0x48, "attr": "hwmon"}, + {"id": "slot3lm75a2", "name": "wb_lm75", "bus": 40, "loc": 0x49, "attr": "hwmon"}, + {"id": "slot3lm75a3", "name": "wb_lm75", "bus": 40, "loc": 0x4D, "attr": "hwmon"}, + ], + }, + { + "name": "slot4", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 7, "okval": 0}, + "device": [ + {"id": "slot4frue2", "name": "wb_24c02", "bus": 6, "loc": 0x56, "attr": "eeprom"}, + {"id": "slot4tlve2", "name": "wb_24c02", "bus": 6, "loc": 0x57, "attr": "eeprom"}, + {"id": "slot4lm75a1", "name": "wb_lm75", "bus": 16, "loc": 0x48, "attr": "hwmon"}, + {"id": "slot4lm75a2", "name": "wb_lm75", "bus": 16, "loc": 0x49, "attr": "hwmon"}, + {"id": "slot4lm75a3", "name": "wb_lm75", "bus": 16, "loc": 0x4D, "attr": "hwmon"}, + ], + }, + ], + "others": [ + { + "name": "eeprom", + "device": [ + {"id": "eeprom_1", "name": "wb_24c02", "bus": 1, "loc": 0x56, "attr": "eeprom"}, + ], + }, + { + "name": "lm75", + "device": [ + {"id": "lm75_1", "name": "wb_lm75", "bus": 28, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_2", "name": "wb_lm75", "bus": 29, "loc": 0x4f, "attr": "hwmon"}, + {"id": "lm75_3", "name": "wb_lm75", "bus": 60, "loc": 0x48, "attr": "hwmon"}, + {"id": "lm75_4", "name": "wb_lm75", "bus": 60, "loc": 0x49, "attr": "hwmon"}, + {"id": "lm75_5", "name": "wb_lm75", "bus": 68, "loc": 0x48, "attr": "hwmon"}, + {"id": "lm75_6", "name": "wb_lm75", "bus": 68, "loc": 0x49, "attr": "hwmon"}, + ], + }, + { + "name": "mac_bsc", + "device": [ + {"id": "mac_bsc_1", "name": "wb_mac_bsc_th3", "bus": 27, "loc": 0x44, "attr": "hwmon"}, + ], + }, + { + "name": "tps53622", + "device": [ + {"id": "tps53622_1", "name": "wb_tps53622", "bus": 10, "loc": 0x60, "attr": "hwmon"}, + {"id": "tps53622_2", "name": "wb_tps53622", "bus": 10, "loc": 0x6c, "attr": "hwmon"}, + ], + }, + { + "name": "tmp411", "device": [ - { - "id": "fan6frue2", - "name": "24c02", - "bus": 57, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "tmp411_1", "name": "wb_tmp411", "bus": 28, "loc": 0x4c, "attr": "hwmon"}, + {"id": "tmp411_2", "name": "wb_tmp411", "bus": 29, "loc": 0x4c, "attr": "hwmon"}, ], }, - ] + ], } +MANUINFO_CONF = { + "bios": { + "key": "BIOS", + "head": True, + "next": "onie" + }, + "bios_vendor": { + "parent": "bios", + "key": "Vendor", + "cmd": "dmidecode -t 0 |grep Vendor", + "pattern": r".*Vendor", + "separator": ":", + "arrt_index": 1, + }, + "bios_version": { + "parent": "bios", + "key": "Version", + "cmd": "dmidecode -t 0 |grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "bios_date": { + "parent": "bios", + "key": "Release Date", + "cmd": "dmidecode -t 0 |grep Release", + "pattern": r".*Release Date", + "separator": ":", + "arrt_index": 3, + }, -FRULISTS = { - "fans":[ - {"name":"fan1","bus":63,"loc":0x50, }, - {"name":"fan2","bus":55,"loc":0x50, }, - {"name":"fan3","bus":64,"loc":0x50, }, - {"name":"fan4","bus":56,"loc":0x50, }, - {"name":"fan5","bus":65,"loc":0x50, }, - {"name":"fan6","bus":57,"loc":0x50, } - ] , - "psus": [ - {"name":"psu1","bus":23,"loc":0x50}, - {"name":"psu2","bus":25,"loc":0x50 }, - {"name":"psu2","bus":24,"loc":0x50 }, - {"name":"psu2","bus":26,"loc":0x50 } - ] -} + "onie": { + "key": "ONIE", + "next": "cpu" + }, + "onie_date": { + "parent": "onie", + "key": "Build Date", + "file": "/host/machine.conf", + "pattern": r"^onie_build_date", + "separator": "=", + "arrt_index": 1, + }, + "onie_version": { + "parent": "onie", + "key": "Version", + "file": "/host/machine.conf", + "pattern": r"^onie_version", + "separator": "=", + "arrt_index": 2, + }, -# INIT_PARAM = [ -# {"loc":"3-0030/sfp_led_reset","value": "ff"}, -# {"loc":"3-0031/sfp_led_reset","value": "ff"}, -# {"loc":"4-0030/sfp_led_reset","value": "ff"}, -# {"loc":"4-0031/sfp_led_reset","value": "ff"}, -# {"loc":"5-0030/sfp_led_reset","value": "ff"}, -# {"loc":"5-0031/sfp_led_reset","value": "ff"}, -# {"loc":"6-0030/sfp_led_reset","value": "ff"}, -# {"loc":"6-0031/sfp_led_reset","value": "ff"}, -# ] -# INIT_COMMAND = [ -# "grtd_test.py io wr 0xb19 0xff", -# ] - -INIT_PARAM = [ - { - "name": "sfp_led_reset1", - "bus": 3, - "devaddr": 0x30, - "offset": 0xa0, - "val": 0xff, + "cpu": { + "key": "CPU", + "next": "ssd" }, - { - "name": "sfp_led_reset2", - "bus": 3, - "devaddr": 0x31, - "offset": 0xa0, - "val": 0xff, + "cpu_vendor": { + "parent": "cpu", + "key": "Vendor", + "cmd": "dmidecode --type processor |grep Manufacturer", + "pattern": r".*Manufacturer", + "separator": ":", + "arrt_index": 1, }, - { - "name": "sfp_led_reset3", - "bus": 4, - "devaddr": 0x30, - "offset": 0xa0, - "val": 0xff, + "cpu_model": { + "parent": "cpu", + "key": "Device Model", + "cmd": "dmidecode --type processor | grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, }, - { - "name": "sfp_led_reset4", - "bus": 4, - "devaddr": 0x31, - "offset": 0xa0, - "val": 0xff, + "cpu_core": { + "parent": "cpu", + "key": "Core Count", + "cmd": "dmidecode --type processor | grep \"Core Count\"", + "pattern": r".*Core Count", + "separator": ":", + "arrt_index": 3, }, - { - "name": "sfp_led_reset5", - "bus": 5, - "devaddr": 0x30, - "offset": 0xa0, - "val": 0xff, + "cpu_thread": { + "parent": "cpu", + "key": "Thread Count", + "cmd": "dmidecode --type processor | grep \"Thread Count\"", + "pattern": r".*Thread Count", + "separator": ":", + "arrt_index": 4, }, - { - "name": "sfp_led_reset6", - "bus": 5, - "devaddr": 0x31, - "offset": 0xa0, - "val": 0xff, + + "ssd": { + "key": "SSD", + "next": "slot" }, - { - "name": "sfp_led_reset7", - "bus": 6, - "devaddr": 0x30, - "offset": 0xa0, - "val": 0xff, + "ssd_model": { + "parent": "ssd", + "key": "Device Model", + "cmd": "smartctl -i /dev/sda |grep \"Device Model\"", + "pattern": r".*Device Model", + "separator": ":", + "arrt_index": 1, }, - { - "name": "sfp_led_reset8", - "bus": 6, - "devaddr": 0x31, - "offset": 0xa0, - "val": 0xff, + "ssd_fw": { + "parent": "ssd", + "key": "Firmware Version", + "cmd": "smartctl -i /dev/sda |grep \"Firmware Version\"", + "pattern": r".*Firmware Version", + "separator": ":", + "arrt_index": 2, + }, + "ssd_user_cap": { + "parent": "ssd", + "key": "User Capacity", + "cmd": "smartctl -i /dev/sda |grep \"User Capacity\"", + "pattern": r".*User Capacity", + "separator": ":", + "arrt_index": 3, }, - { - "name": "mac_power_on", - "type": "io", - "offset": 0xb19, - "val": 0xff - } -] -#rg_eeprom = "0-0054/eeprom" -E2_LOC = {"bus":1, "devno":0x56} -E2_PROTECT = {"io_addr":0xb45, "gettype":"io", "open":0, "close":1} - -CPLDVERSIONS = [ - {"bus":13, "devno":0x0d, "name":"FAN_CPLD_B"}, - {"bus":14, "devno":0x0d, "name":"FAN_CPLD_A"}, - {"bus":3, "devno":0x30, "name":"LC1_CPLD_1"}, - {"bus":3, "devno":0x31, "name":"LC1_CPLD_2"}, - {"bus":4, "devno":0x30, "name":"LC2_CPLD_1"}, - {"bus":4, "devno":0x31, "name":"LC2_CPLD_2"}, - {"bus":5, "devno":0x30, "name":"LC3_CPLD_1"}, - {"bus":5, "devno":0x31, "name":"LC3_CPLD_2"}, - {"bus":6, "devno":0x30, "name":"LC4_CPLD_1"}, - {"bus":6, "devno":0x31, "name":"LC4_CPLD_2"}, - {"io_addr":0x700, "name":"X86_CPLD", "gettype":"io"}, - {"io_addr":0x900, "name":"MAC_CPLD_B", "gettype":"io"}, - {"io_addr":0xb00, "name":"MAC_CPLD_A", "gettype":"io"}, -] -DRIVERLISTS = [] - - -TEMPIDCHANGE = { - "lm75in": "inlet", - "lm75out": "outlet", - "lm75hot": "hot-point", - "slot1lm75a1": "LINE CARD1 lm751", - "slot1lm75a2": "LINE CARD1 lm752", - "slot1lm75a3": "LINE CARD1 lm753", - "slot2lm75a1": "LINE CARD2 lm751", - "slot2lm75a2": "LINE CARD2 lm752", - "slot2lm75a3": "LINE CARD2 lm753", - "slot3lm75a1": "LINE CARD3 lm751", - "slot3lm75a2": "LINE CARD3 lm752", - "slot3lm75a3": "LINE CARD3 lm753", - "slot4lm75a1": "LINE CARD4 lm751", - "slot4lm75a2": "LINE CARD4 lm752", - "slot4lm75a3": "LINE CARD4 lm753", - "inlet": "lm75in", - "outlet": "lm75out", - "hot-point": "lm75hot", -} + "slot": { + "key": "SLOT", + "next": "cpld" + }, + "slot1": { + "key": "SLOT1", + "parent": "slot", + "arrt_index": 1, + }, + "slot1_hw_version": { + "key": "Hardware Version", + "parent": "slot1", + "extra": { + "funcname": "checkSlot", + "id": "slot1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "slot2": { + "key": "SLOT2", + "parent": "slot", + "arrt_index": 2, + }, + "slot2_hw_version": { + "key": "Hardware Version", + "parent": "slot2", + "extra": { + "funcname": "checkSlot", + "id": "slot2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "slot3": { + "key": "SLOT3", + "parent": "slot", + "arrt_index": 3, + }, + "slot3_hw_version": { + "key": "Hardware Version", + "parent": "slot3", + "extra": { + "funcname": "checkSlot", + "id": "slot3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "slot4": { + "key": "SLOT4", + "parent": "slot", + "arrt_index": 4, + }, + "slot4_hw_version": { + "key": "Hardware Version", + "parent": "slot4", + "extra": { + "funcname": "checkSlot", + "id": "slot4", + "key": "hw_version" + }, + "arrt_index": 1, + }, -DEVICE = [] + "cpld": { + "key": "CPLD", + "next": "psu" + }, + "cpld1": { + "key": "CPLD1", + "parent": "cpld", + "arrt_index": 1, + }, + "cpld1_model": { + "key": "Device Model", + "parent": "cpld1", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld1_vender": { + "key": "Vendor", + "parent": "cpld1", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld1_desc": { + "key": "Description", + "parent": "cpld1", + "config": "CPU_CPLD", + "arrt_index": 3, + }, + "cpld1_version": { + "key": "Firmware Version", + "parent": "cpld1", + "reg": { + "loc": "/dev/port", + "offset": 0x700, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -fanlevel = { - "tips":["LOW","MIDDLE","HIGH"], - "level":[51,128,255], - "low_speed":[1500,4500,9500], - "high_speed":[3000,7000,14000] -} + "cpld2": { + "key": "CPLD2", + "parent": "cpld", + "arrt_index": 2, + }, + "cpld2_model": { + "key": "Device Model", + "parent": "cpld2", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld2_vender": { + "key": "Vendor", + "parent": "cpld2", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld2_desc": { + "key": "Description", + "parent": "cpld2", + "config": "MAC_CPLD_A", + "arrt_index": 3, + }, + "cpld2_version": { + "key": "Firmware Version", + "parent": "cpld2", + "reg": { + "loc": "/dev/port", + "offset": 0xb00, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -fanloc =[ {"name":"FAN1", "location":"2-0020/fan1_pwm" , - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan1_input"},{"name":"BACK ROTOR", "location":"2-0020/fan2_input"} ]}, - {"name":"FAN2", "location":"2-0020/fan3_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan3_input"},{"name":"BACK ROTOR", "location":"2-0020/fan4_input"} ]}, - {"name":"FAN3", "location":"2-0020/fan5_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan5_input"},{"name":"BACK ROTOR", "location":"2-0020/fan6_input"} ]}, - {"name":"FAN4", "location":"2-0020/fan7_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan7_input"},{"name":"BACK ROTOR", "location":"2-0020/fan8_input"} ]}, - {"name":"FAN5", "location":"2-0020/fan9_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan9_input"},{"name":"BACK ROTOR", "location":"2-0020/fan10_input"} ]}, - {"name":"FAN6", "location":"2-0020/fan11_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan11_input"},{"name":"BACK ROTOR", "location":"2-0020/fan12_input"} ]}, - ] - - -#################FAN speed args ############################## -MONITOR_TEMP_MIN = 30 -MONITOR_K = 14 -MONITOR_MAC_IN = 35 -MONITOR_DEFAULT_SPEED = 0x80 -MONITOR_MAX_SPEED = 0xFF -MONITOR_MIN_SPEED = 0x33 -MONITOR_MAC_ERROR_SPEED = 0XBB -MONITOR_FAN_TOTAL_NUM = 6 -MONITOR_MAC_UP_TEMP = 40 -MONITOR_MAC_LOWER_TEMP = -40 -MONITOR_MAC_MAX_TEMP = 100 - -MONITOR_FALL_TEMP = 2 -MONITOR_MAC_WARNING_THRESHOLD = 100 -MONITOR_OUTTEMP_WARNING_THRESHOLD = 85 -MONITOR_BOARDTEMP_WARNING_THRESHOLD = 85 -MONITOR_CPUTEMP_WARNING_THRESHOLD = 85 -MONITOR_INTEMP_WARNING_THRESHOLD = 70 - -MONITOR_MAC_CRITICAL_THRESHOLD = 105 -MONITOR_OUTTEMP_CRITICAL_THRESHOLD = 90 -MONITOR_BOARDTEMP_CRITICAL_THRESHOLD = 90 -MONITOR_CPUTEMP_CRITICAL_THRESHOLD = 100 -MONITOR_INTEMP_CRITICAL_THRESHOLD = 80 -MONITOR_CRITICAL_NUM = 2 -MONITOR_SHAKE_TIME = 10 -MONITOR_INTERVAL = 60 - -MONITOR_SYS_LED = [ -{ - "cmdstr":"/sys/devices/pci0000:00/0000:00:1f.0/broad_front_sys", - "yellow":0x06, - "red":0x02, - "green":0x04, - "type":"sysfs", -}, -] + "cpld3": { + "key": "CPLD3", + "parent": "cpld", + "arrt_index": 3, + }, + "cpld3_model": { + "key": "Device Model", + "parent": "cpld3", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld3_vender": { + "key": "Vendor", + "parent": "cpld3", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld3_desc": { + "key": "Description", + "parent": "cpld3", + "config": "MAC_CPLD_B", + "arrt_index": 3, + }, + "cpld3_version": { + "key": "Firmware Version", + "parent": "cpld3", + "reg": { + "loc": "/dev/port", + "offset": 0x900, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -MONITOR_SYS_FAN_LED =[ -{ - "cmdstr":"/sys/devices/pci0000:00/0000:00:1f.0/broad_front_fan", - "yellow":0x06, - "red":0x02, - "green":0x04, - "type":"sysfs", -}, -] + "cpld4": { + "key": "CPLD4", + "parent": "cpld", + "arrt_index": 4, + }, + "cpld4_model": { + "key": "Device Model", + "parent": "cpld4", + "config": "LCMXO2-2000HC-4MG132C", + "arrt_index": 1, + }, + "cpld4_vender": { + "key": "Vendor", + "parent": "cpld4", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld4_desc": { + "key": "Description", + "parent": "cpld4", + "config": "FAN_CPLD_A", + "arrt_index": 3, + }, + "cpld4_version": { + "key": "Firmware Version", + "parent": "cpld4", + "i2c": { + "bus": "14", + "loc": "0x0d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -MONITOR_FANS_LED = [ - {"bus":14,"devno":0x0d, "addr":0x3b, "green":0x04, "red":0x02}, - {"bus":13,"devno":0x0d, "addr":0x3b, "green":0x04, "red":0x02}, - {"bus":14,"devno":0x0d, "addr":0x3c, "green":0x04, "red":0x02}, - {"bus":13,"devno":0x0d, "addr":0x3c, "green":0x04, "red":0x02}, - {"bus":14,"devno":0x0d, "addr":0x3d, "green":0x04, "red":0x02}, - {"bus":13,"devno":0x0d, "addr":0x3d, "green":0x04, "red":0x02}, - ] - -DEV_LEDS = { - "SLOTLED":[ - {"name":'slot1',"bus":3,"devno":0x30, "addr":0x1a, "green":0x04, "red":0x02}, - {"name":'slot2',"bus":4,"devno":0x30, "addr":0x1a, "green":0x04, "red":0x02}, - {"name":'slot3',"bus":5,"devno":0x30, "addr":0x1a, "green":0x04, "red":0x02}, - {"name":'slot4',"bus":6,"devno":0x30, "addr":0x1a, "green":0x04, "red":0x02}, - ] -} + "cpld5": { + "key": "CPLD5", + "parent": "cpld", + "arrt_index": 5, + }, + "cpld5_model": { + "key": "Device Model", + "parent": "cpld5", + "config": "LCMXO2-2000HC-4MG132C", + "arrt_index": 1, + }, + "cpld5_vender": { + "key": "Vendor", + "parent": "cpld5", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld5_desc": { + "key": "Description", + "parent": "cpld5", + "config": "FAN_CPLD_B", + "arrt_index": 3, + }, + "cpld5_version": { + "key": "Firmware Version", + "parent": "cpld5", + "i2c": { + "bus": "13", + "loc": "0x0d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -MONITOR_SYS_PSU_LED =[ -{ - "cmdstr":"/sys/devices/pci0000:00/0000:00:1f.0/broad_front_pwr", - "yellow":0x06, - "red":0x02, - "green":0x04, - "type":"sysfs", -}, -] + "cpld6": { + "key": "CPLD6", + "parent": "cpld", + "arrt_index": 6, + }, + "cpld6_model": { + "key": "Device Model", + "parent": "cpld6", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld6_vender": { + "key": "Vendor", + "parent": "cpld6", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld6_desc": { + "key": "Description", + "parent": "cpld6", + "config": "LC1_CPLD_2", + "arrt_index": 3, + }, + "cpld6_version": { + "key": "Firmware Version", + "parent": "cpld6", + "i2c": { + "bus": "3", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -MONITOR_FAN_STATUS = [ - {'status':'green' , 'minOkNum':6,'maxOkNum':6}, - {'status':'yellow', 'minOkNum':5,'maxOkNum':5}, - {'status':'red' , 'minOkNum':0,'maxOkNum':4}, - ] - -MONITOR_PSU_STATUS = [ - {'status':'green' , 'minOkNum':4,'maxOkNum':4}, - {'status':'yellow', 'minOkNum':3,'maxOkNum':3}, - {'status':'red' , 'minOkNum':0,'maxOkNum':2}, - ] - -MONITOR_DEV_STATUS = { - "temperature": [ - {"name":"lm75in", "location":"/sys/bus/i2c/devices/29-004f/hwmon/*/temp1_input"}, - {"name":"lm75out", "location":"/sys/bus/i2c/devices/28-004b/hwmon/*/temp1_input"}, - {"name":"lm75hot", "location":"/sys/bus/i2c/devices/28-004c/hwmon/*/temp1_input"}, - {"name":"cpu", "location":"/sys/class/hwmon/hwmon0"}, - ], - "fans": [ - { - "name":"fan1", - "presentstatus":{"bus":14, "loc":0x0d, "offset":0x30, 'bit':0}, - "rollstatus": [ - {"name":"motor1","bus":14, "loc":0x0d, "offset":0x31, 'bit':0}, - {"name":"motor2","bus":14, "loc":0x0d, "offset":0x34, 'bit':0}, - ] + "cpld7": { + "key": "CPLD7", + "parent": "cpld", + "arrt_index": 7, + }, + "cpld7_model": { + "key": "Device Model", + "parent": "cpld7", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld7_vender": { + "key": "Vendor", + "parent": "cpld7", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld7_desc": { + "key": "Description", + "parent": "cpld7", + "config": "LC1_CPLD_1", + "arrt_index": 3, + }, + "cpld7_version": { + "key": "Firmware Version", + "parent": "cpld7", + "i2c": { + "bus": "3", + "loc": "0x30", + "offset": 0, + "size": 4 }, - { - "name":"fan2", - "presentstatus":{"bus":13, "loc":0x0d, "offset":0x30, 'bit':0}, - "rollstatus": [ - {"name":"motor1","bus":13, "loc":0x0d, "offset":0x31, 'bit':0}, - {"name":"motor2","bus":13, "loc":0x0d, "offset":0x34, 'bit':0}, - ] + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld8": { + "key": "CPLD8", + "parent": "cpld", + "arrt_index": 8, + }, + "cpld8_model": { + "key": "Device Model", + "parent": "cpld8", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld8_vender": { + "key": "Vendor", + "parent": "cpld8", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld8_desc": { + "key": "Description", + "parent": "cpld8", + "config": "LC2_CPLD_2", + "arrt_index": 3, + }, + "cpld8_version": { + "key": "Firmware Version", + "parent": "cpld8", + "i2c": { + "bus": "4", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld9": { + "key": "CPLD9", + "parent": "cpld", + "arrt_index": 9, + }, + "cpld9_model": { + "key": "Device Model", + "parent": "cpld9", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld9_vender": { + "key": "Vendor", + "parent": "cpld9", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld9_desc": { + "key": "Description", + "parent": "cpld9", + "config": "LC2_CPLD_1", + "arrt_index": 3, + }, + "cpld9_version": { + "key": "Firmware Version", + "parent": "cpld9", + "i2c": { + "bus": "4", + "loc": "0x30", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld10": { + "key": "CPLD10", + "parent": "cpld", + "arrt_index": 10, + }, + "cpld10_model": { + "key": "Device Model", + "parent": "cpld10", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld10_vender": { + "key": "Vendor", + "parent": "cpld10", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld10_desc": { + "key": "Description", + "parent": "cpld10", + "config": "LC3_CPLD_2", + "arrt_index": 3, + }, + "cpld10_version": { + "key": "Firmware Version", + "parent": "cpld10", + "i2c": { + "bus": "5", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld11": { + "key": "CPLD11", + "parent": "cpld", + "arrt_index": 11, + }, + "cpld11_model": { + "key": "Device Model", + "parent": "cpld11", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld11_vender": { + "key": "Vendor", + "parent": "cpld11", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld11_desc": { + "key": "Description", + "parent": "cpld11", + "config": "LC3_CPLD_1", + "arrt_index": 3, + }, + "cpld11_version": { + "key": "Firmware Version", + "parent": "cpld11", + "i2c": { + "bus": "5", + "loc": "0x30", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld12": { + "key": "CPLD12", + "parent": "cpld", + "arrt_index": 12, + }, + "cpld12_model": { + "key": "Device Model", + "parent": "cpld12", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld12_vender": { + "key": "Vendor", + "parent": "cpld12", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld12_desc": { + "key": "Description", + "parent": "cpld12", + "config": "LC4_CPLD_2", + "arrt_index": 3, + }, + "cpld12_version": { + "key": "Firmware Version", + "parent": "cpld12", + "i2c": { + "bus": "6", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld13": { + "key": "CPLD13", + "parent": "cpld", + "arrt_index": 13, + }, + "cpld13_model": { + "key": "Device Model", + "parent": "cpld13", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld13_vender": { + "key": "Vendor", + "parent": "cpld13", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld13_desc": { + "key": "Description", + "parent": "cpld13", + "config": "LC4_CPLD_1", + "arrt_index": 3, + }, + "cpld13_version": { + "key": "Firmware Version", + "parent": "cpld13", + "i2c": { + "bus": "6", + "loc": "0x30", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "psu": { + "key": "PSU", + "next": "fan" + }, + + "psu1": { + "parent": "psu", + "key": "PSU1", + "arrt_index": 1, + }, + "psu1_hw_version": { + "key": "Hardware Version", + "parent": "psu1", + "extra": { + "funcname": "getPsu", + "id": "psu1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu1_fw_version": { + "key": "Firmware Version", + "parent": "psu1", + "config": "NA", + "arrt_index": 2, + }, + + "psu2": { + "parent": "psu", + "key": "PSU2", + "arrt_index": 2, + }, + "psu2_hw_version": { + "key": "Hardware Version", + "parent": "psu2", + "extra": { + "funcname": "getPsu", + "id": "psu2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu2_fw_version": { + "key": "Firmware Version", + "parent": "psu2", + "config": "NA", + "arrt_index": 2, + }, + + "psu3": { + "parent": "psu", + "key": "PSU3", + "arrt_index": 3, + }, + "psu3_hw_version": { + "key": "Hardware Version", + "parent": "psu3", + "extra": { + "funcname": "getPsu", + "id": "psu3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu3_fw_version": { + "key": "Firmware Version", + "parent": "psu3", + "config": "NA", + "arrt_index": 2, + }, + + "psu4": { + "parent": "psu", + "key": "PSU4", + "arrt_index": 4, + }, + "psu4_hw_version": { + "key": "Hardware Version", + "parent": "psu4", + "extra": { + "funcname": "getPsu", + "id": "psu4", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu4_fw_version": { + "key": "Firmware Version", + "parent": "psu4", + "config": "NA", + "arrt_index": 2, + }, + + "fan": { + "key": "FAN", + "next": "i210" + }, + + "fan1": { + "key": "FAN1", + "parent": "fan", + "arrt_index": 1, + }, + "fan1_hw_version": { + "key": "Hardware Version", + "parent": "fan1", + "extra": { + "funcname": "checkFan", + "id": "fan1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan1_fw_version": { + "key": "Firmware Version", + "parent": "fan1", + "config": "NA", + "arrt_index": 2, + }, + + "fan2": { + "key": "FAN2", + "parent": "fan", + "arrt_index": 2, + }, + "fan2_hw_version": { + "key": "Hardware Version", + "parent": "fan2", + "extra": { + "funcname": "checkFan", + "id": "fan2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan2_fw_version": { + "key": "Firmware Version", + "parent": "fan2", + "config": "NA", + "arrt_index": 2, + }, + + "fan3": { + "key": "FAN3", + "parent": "fan", + "arrt_index": 3, + }, + "fan3_hw_version": { + "key": "Hardware Version", + "parent": "fan3", + "extra": { + "funcname": "checkFan", + "id": "fan3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan3_fw_version": { + "key": "Firmware Version", + "parent": "fan3", + "config": "NA", + "arrt_index": 2, + }, + + "fan4": { + "key": "FAN4", + "parent": "fan", + "arrt_index": 4, + }, + "fan4_hw_version": { + "key": "Hardware Version", + "parent": "fan4", + "extra": { + "funcname": "checkFan", + "id": "fan4", + "key": "hw_version" }, + "arrt_index": 1, + }, + "fan4_fw_version": { + "key": "Firmware Version", + "parent": "fan4", + "config": "NA", + "arrt_index": 2, + }, + + "fan5": { + "key": "FAN5", + "parent": "fan", + "arrt_index": 5, + }, + "fan5_hw_version": { + "key": "Hardware Version", + "parent": "fan5", + "extra": { + "funcname": "checkFan", + "id": "fan5", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan5_fw_version": { + "key": "Firmware Version", + "parent": "fan5", + "config": "NA", + "arrt_index": 2, + }, + + "fan6": { + "key": "FAN6", + "parent": "fan", + "arrt_index": 6, + }, + "fan6_hw_version": { + "key": "Hardware Version", + "parent": "fan6", + "extra": { + "funcname": "checkFan", + "id": "fan6", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan6_fw_version": { + "key": "Firmware Version", + "parent": "fan6", + "config": "NA", + "arrt_index": 2, + }, + + "i210": { + "key": "NIC", + }, + "i210_model": { + "parent": "i210", + "config": "NA", + "key": "Device Model", + "arrt_index": 1, + }, + "i210_vendor": { + "parent": "i210", + "config": "INTEL", + "key": "Vendor", + "arrt_index": 2, + }, + "i210_version": { + "parent": "i210", + "cmd": "ethtool -i eth0", + "pattern": r"firmware-version", + "separator": ":", + "key": "Firmware Version", + "arrt_index": 3, + }, +} + +PMON_SYSLOG_STATUS = { + "polling_time": 3, + "sffs": { + "present": {"path": ["/sys/wb_plat/sff/*/present"], "ABSENT":0}, + "nochangedmsgflag": 0, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 1, + "alias": { + "eth1": "Eth100GE1-1", + "eth2": "Eth100GE1-2", + "eth3": "Eth100GE1-3", + "eth4": "Eth100GE1-4", + "eth5": "Eth100GE1-5", + "eth6": "Eth100GE1-6", + "eth7": "Eth100GE1-7", + "eth8": "Eth100GE1-8", + "eth9": "Eth100GE1-9", + "eth10": "Eth100GE1-10", + "eth11": "Eth100GE1-11", + "eth12": "Eth100GE1-12", + "eth13": "Eth100GE1-13", + "eth14": "Eth100GE1-14", + "eth15": "Eth100GE1-15", + "eth16": "Eth100GE1-16", + "eth17": "Eth100GE1-17", + "eth18": "Eth100GE1-18", + "eth19": "Eth100GE1-19", + "eth20": "Eth100GE1-20", + "eth21": "Eth100GE1-21", + "eth22": "Eth100GE1-22", + "eth23": "Eth100GE1-23", + "eth24": "Eth100GE1-24", + "eth25": "Eth100GE1-25", + "eth26": "Eth100GE1-26", + "eth27": "Eth100GE1-27", + "eth28": "Eth100GE1-28", + "eth29": "Eth100GE1-29", + "eth30": "Eth100GE1-30", + "eth31": "Eth100GE1-31", + "eth32": "Eth100GE1-32", + "eth33": "Eth100GE2-1", + "eth34": "Eth100GE2-2", + "eth35": "Eth100GE2-3", + "eth36": "Eth100GE2-4", + "eth37": "Eth100GE2-5", + "eth38": "Eth100GE2-6", + "eth39": "Eth100GE2-7", + "eth40": "Eth100GE2-8", + "eth41": "Eth100GE2-9", + "eth42": "Eth100GE2-10", + "eth43": "Eth100GE2-11", + "eth44": "Eth100GE2-12", + "eth45": "Eth100GE2-13", + "eth46": "Eth100GE2-14", + "eth47": "Eth100GE2-15", + "eth48": "Eth100GE2-16", + "eth49": "Eth100GE2-17", + "eth50": "Eth100GE2-18", + "eth51": "Eth100GE2-19", + "eth52": "Eth100GE2-20", + "eth53": "Eth100GE2-21", + "eth54": "Eth100GE2-22", + "eth55": "Eth100GE2-23", + "eth56": "Eth100GE2-24", + "eth57": "Eth100GE2-25", + "eth58": "Eth100GE2-26", + "eth59": "Eth100GE2-27", + "eth60": "Eth100GE2-28", + "eth61": "Eth100GE2-29", + "eth62": "Eth100GE2-30", + "eth63": "Eth100GE2-31", + "eth64": "Eth100GE2-32", + "eth65": "Eth100GE3-1", + "eth66": "Eth100GE3-2", + "eth67": "Eth100GE3-3", + "eth68": "Eth100GE3-4", + "eth69": "Eth100GE3-5", + "eth70": "Eth100GE3-6", + "eth71": "Eth100GE3-7", + "eth72": "Eth100GE3-8", + "eth73": "Eth100GE3-9", + "eth74": "Eth100GE3-10", + "eth75": "Eth100GE3-11", + "eth76": "Eth100GE3-12", + "eth77": "Eth100GE3-13", + "eth78": "Eth100GE3-14", + "eth79": "Eth100GE3-15", + "eth80": "Eth100GE3-16", + "eth81": "Eth100GE3-17", + "eth82": "Eth100GE3-18", + "eth83": "Eth100GE3-19", + "eth84": "Eth100GE3-20", + "eth85": "Eth100GE3-21", + "eth86": "Eth100GE3-22", + "eth87": "Eth100GE3-23", + "eth88": "Eth100GE3-24", + "eth89": "Eth100GE3-25", + "eth90": "Eth100GE3-26", + "eth91": "Eth100GE3-27", + "eth92": "Eth100GE3-28", + "eth93": "Eth100GE3-29", + "eth94": "Eth100GE3-30", + "eth95": "Eth100GE3-31", + "eth96": "Eth100GE3-32", + "eth97": "Eth100GE4-1", + "eth98": "Eth100GE4-2", + "eth99": "Eth100GE4-3", + "eth100": "Eth100GE4-4", + "eth101": "Eth100GE4-5", + "eth102": "Eth100GE4-6", + "eth103": "Eth100GE4-7", + "eth104": "Eth100GE4-8", + "eth105": "Eth100GE4-9", + "eth106": "Eth100GE4-10", + "eth107": "Eth100GE4-11", + "eth108": "Eth100GE4-12", + "eth109": "Eth100GE4-13", + "eth110": "Eth100GE4-14", + "eth111": "Eth100GE4-15", + "eth112": "Eth100GE4-16", + "eth113": "Eth100GE4-17", + "eth114": "Eth100GE4-18", + "eth115": "Eth100GE4-19", + "eth116": "Eth100GE4-20", + "eth117": "Eth100GE4-21", + "eth118": "Eth100GE4-22", + "eth119": "Eth100GE4-23", + "eth120": "Eth100GE4-24", + "eth121": "Eth100GE4-25", + "eth122": "Eth100GE4-26", + "eth123": "Eth100GE4-27", + "eth124": "Eth100GE4-28", + "eth125": "Eth100GE4-29", + "eth126": "Eth100GE4-30", + "eth127": "Eth100GE4-31", + "eth128": "Eth100GE4-32", + } + }, + "slots": { + "present": {"path": ["/sys/wb_plat/slot/*/status"], "ABSENT":0}, + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "slot1": "SLOT1", + "slot2": "SLOT2", + "slot3": "SLOT3", + "slot4": "SLOT4", + } + }, + "fans": { + "present": {"path": ["/sys/wb_plat/fan/*/present"], "ABSENT":0}, + "status": [ + {"path": "/sys/wb_plat/fan/%s/motor0/status", 'okval': 1}, + {"path": "/sys/wb_plat/fan/%s/motor1/status", 'okval': 1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "fan1": "FAN1", + "fan2": "FAN2", + "fan3": "FAN3", + "fan4": "FAN4", + "fan5": "FAN5", + "fan6": "FAN6" + } + }, + "psus": { + "present" : {"path": ["/sys/wb_plat/psu/*/present"], "ABSENT":0}, + "status" : [ + {"path": "/sys/wb_plat/psu/%s/output", "okval":1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "psu1": "PSU1", + "psu2": "PSU2", + "psu3": "PSU3", + "psu4": "PSU4", + } + } +} + +REBOOT_CAUSE_PARA = { + "reboot_cause_list": [ { - "name":"fan3", - "presentstatus":{"bus":14, "loc":0x0d, "offset":0x30, 'bit':1}, - "rollstatus": [ - {"name":"motor1","bus":14, "loc":0x0d, "offset":0x31, 'bit':1}, - {"name":"motor2","bus":14, "loc":0x0d, "offset":0x34, 'bit':1}, + "name": "cold_reboot", + "monitor_point": {"gettype": "io", "io_addr": 0xb88, "okval": 0}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Power Loss, ", + "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Power Loss, ", + "path": "/etc/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} ] }, { - "name":"fan4", - "presentstatus":{"bus":13, "loc":0x0d, "offset":0x30, 'bit':1}, - "rollstatus": [ - {"name":"motor1","bus":13, "loc":0x0d, "offset":0x31, 'bit':1}, - {"name":"motor2","bus":13, "loc":0x0d, "offset":0x34, 'bit':1}, - ] + "name": "reboot", + "monitor_point": {"gettype": "io", "io_addr": 0xb88, "okval": 0, "compare_mode": "great"}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Reboot, ", + "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Reboot, ", + "path": "/etc/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], }, { - "name":"fan5", - "presentstatus":{"bus":14, "loc":0x0d, "offset":0x30, 'bit':2}, - "rollstatus": [ - {"name":"motor1","bus":14, "loc":0x0d, "offset":0x31, 'bit':2}, - {"name":"motor2","bus":14, "loc":0x0d, "offset":0x34, 'bit':2}, + "name": "otp_switch_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_switch_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: ASIC, ", + "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: ASIC, ", + "path": "/etc/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_switch_reboot_flag"}, ] }, { - "name":"fan6", - "presentstatus":{"bus":13, "loc":0x0d, "offset":0x30, 'bit':2}, - "rollstatus": [ - {"name":"motor1","bus":13, "loc":0x0d, "offset":0x31, 'bit':2}, - {"name":"motor2","bus":13, "loc":0x0d, "offset":0x34, 'bit':2}, + "name": "otp_other_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_other_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: Other, ", + "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: Other, ", + "path": "/etc/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_other_reboot_flag"}, ] }, ], - "psus": [ - {"name":"psu1", "io_addr":0xb27, "gettype":"io", 'presentbit': 0, 'statusbit':1, 'alertbit':2}, - {"name":"psu2", "io_addr":0xb28, "gettype":"io", 'presentbit': 0, 'statusbit':1, 'alertbit':2}, - {"name":"psu3", "io_addr":0xb29, "gettype":"io", 'presentbit': 0, 'statusbit':1, 'alertbit':2}, - {"name":"psu4", "io_addr":0xb2a, "gettype":"io", 'presentbit': 0, 'statusbit':1, 'alertbit':2} - ], - "slots": [ - {"name":"slot1", "io_addr":0xb2c, "gettype":"io", 'presentbit': 4}, - {"name":"slot2", "io_addr":0xb2c, "gettype":"io", 'presentbit': 5}, - {"name":"slot3", "io_addr":0xb2c, "gettype":"io", 'presentbit': 6}, - {"name":"slot4", "io_addr":0xb2c, "gettype":"io", 'presentbit': 7} + "other_reboot_cause_record": [ + {"record_type": "file", "mode": "cover", "log": "Other, ", "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Other, ", "path": "/etc/.reboot/.history-reboot-cause.txt"} ], - "mac_temp" : { - "loc" : [ - "28-004c/hwmon/*/temp2_input", - "29-004c/hwmon/*/temp2_input", - ], - }, } -MONITOR_DEV_STATUS_DECODE = { - 'fanpresent' : {0:'PRESENT', 1:'ABSENT', 'okval':0}, - 'fanroll' : {0:'STALL' , 1:'ROLL', 'okval':1}, - 'psupresent' : {0:'PRESENT', 1:'ABSENT', 'okval':0}, - 'psuoutput' : {0:'FAULT' , 1:'NORMAL', 'okval':1}, - 'psualert' : {0:'FAULT' , 1:'NORMAL', 'okval':1}, - 'slotpresent': {0:'PRESENT', 1:'ABSENT', 'okval':0}, -} +INIT_PARAM_PRE = [ + {"loc": "30-0064/hwmon/hwmon*/avs1_vout_max", "value": "900000"}, + {"loc": "30-0064/hwmon/hwmon*/avs1_vout_min", "value": "750000"}, +] + +INIT_COMMAND_PRE = [] + +INIT_PARAM = [] + +INIT_COMMAND = [ + "dfd_debug io_wr 0xb19 0xff", + "i2cset -y -f 3 0x30 0xa0 0xff", + "i2cset -y -f 3 0x31 0xa0 0xff", + "i2cset -y -f 4 0x30 0xa0 0xff", + "i2cset -y -f 4 0x31 0xa0 0xff", + "i2cset -y -f 5 0x30 0xa0 0xff", + "i2cset -y -f 5 0x31 0xa0 0xff", + "i2cset -y -f 6 0x30 0xa0 0xff", + "i2cset -y -f 6 0x31 0xa0 0xff", +] + +BLACKLIST_DRIVERS = [ + {"name": "i2c_i801", "delay": 0}, +] + +DRIVERLISTS = [ + {"name": "wb_i2c_i801", "delay": 0}, + {"name": "wb_gpio_d1500", "delay": 0}, + {"name": "i2c_dev", "delay": 0}, + {"name": "wb_i2c_algo_bit", "delay": 0}, + {"name": "wb_i2c_gpio", "delay": 0}, + {"name": "i2c_mux", "delay": 0}, + {"name": "wb_gpio_device", "delay": 0}, + {"name": "wb_i2c_gpio_device gpio_sda=17 gpio_scl=1 gpio_udelay=2", "delay": 0}, + {"name": "platform_common dfd_my_type_i2c_bus=1 dfd_my_type_i2c_addr=0x56", "delay": 0}, + {"name": "wb_lpc_drv", "delay": 0}, + {"name": "wb_lpc_drv_device", "delay": 0}, + {"name": "wb_io_dev", "delay": 0}, + {"name": "wb_io_dev_device", "delay": 0}, + {"name": "wb_i2c_dev", "delay": 0}, + {"name": "wb_i2c_ocores", "delay": 0}, + {"name": "wb_i2c_ocores_device", "delay": 0}, + {"name": "wb_i2c_mux_pca9641", "delay": 0}, + {"name": "wb_i2c_mux_pca954x", "delay": 0}, + {"name": "wb_i2c_mux_pca954x_device", "delay": 0}, + {"name": "wb_platform_i2c_dev", "delay": 0}, + {"name": "wb_platform_i2c_dev_device", "delay": 0}, + {"name": "wb_lm75", "delay": 0}, + {"name": "wb_tmp401", "delay": 0}, + {"name": "wb_optoe", "delay": 0}, + {"name": "wb_at24", "delay": 0}, + {"name": "wb_pmbus_core", "delay": 0}, + {"name": "wb_csu550", "delay": 0}, + {"name": "wb_isl68137", "delay": 0}, + {"name": "wb_mac_bsc", "delay": 0}, + {"name": "wb_tps53622", "delay": 0}, + {"name": "firmware_driver_cpld", "delay": 0}, + {"name": "firmware_driver_ispvme", "delay": 0}, + {"name": "firmware_driver_sysfs", "delay": 0}, + {"name": "wb_firmware_upgrade_device", "delay": 0}, + {"name": "plat_dfd", "delay": 0}, + {"name": "plat_switch", "delay": 0}, + {"name": "plat_fan", "delay": 0}, + {"name": "plat_psu", "delay": 0}, + {"name": "plat_sff", "delay": 0}, + {"name": "plat_sensor", "delay": 0}, + {"name": "plat_slot", "delay": 0}, +] + +DEVICE = [ + {"name": "wb_lm75", "bus": 28, "loc": 0x4B}, + {"name": "wb_tmp411", "bus": 28, "loc": 0x4C}, + {"name": "wb_tmp411", "bus": 29, "loc": 0x4C}, + {"name": "wb_lm75", "bus": 29, "loc": 0x4F}, + {"name": "wb_lm75", "bus": 68, "loc": 0x48}, + {"name": "wb_lm75", "bus": 68, "loc": 0x49}, + {"name": "wb_lm75", "bus": 60, "loc": 0x48}, + {"name": "wb_lm75", "bus": 60, "loc": 0x49}, + {"name": "wb_lm75", "bus": 32, "loc": 0x48}, + {"name": "wb_lm75", "bus": 32, "loc": 0x49}, + {"name": "wb_lm75", "bus": 32, "loc": 0x4D}, + {"name": "wb_lm75", "bus": 48, "loc": 0x48}, + {"name": "wb_lm75", "bus": 48, "loc": 0x49}, + {"name": "wb_lm75", "bus": 48, "loc": 0x4D}, + {"name": "wb_lm75", "bus": 40, "loc": 0x48}, + {"name": "wb_lm75", "bus": 40, "loc": 0x49}, + {"name": "wb_lm75", "bus": 40, "loc": 0x4D}, + {"name": "wb_lm75", "bus": 16, "loc": 0x48}, + {"name": "wb_lm75", "bus": 16, "loc": 0x49}, + {"name": "wb_lm75", "bus": 16, "loc": 0x4D}, + {"name": "wb_24c02", "bus": 1, "loc": 0x56}, + # fan + {"name": "wb_24c02", "bus": 63, "loc": 0x50}, + {"name": "wb_24c02", "bus": 55, "loc": 0x50}, + {"name": "wb_24c02", "bus": 64, "loc": 0x50}, + {"name": "wb_24c02", "bus": 56, "loc": 0x50}, + {"name": "wb_24c02", "bus": 65, "loc": 0x50}, + {"name": "wb_24c02", "bus": 57, "loc": 0x50}, + # slot + {"name": "wb_24c02", "bus": 3, "loc": 0x57}, + {"name": "wb_24c02", "bus": 4, "loc": 0x57}, + {"name": "wb_24c02", "bus": 5, "loc": 0x57}, + {"name": "wb_24c02", "bus": 6, "loc": 0x57}, + {"name": "wb_24c02", "bus": 3, "loc": 0x56}, + {"name": "wb_24c02", "bus": 4, "loc": 0x56}, + {"name": "wb_24c02", "bus": 5, "loc": 0x56}, + {"name": "wb_24c02", "bus": 6, "loc": 0x56}, + # psu + {"name": "wb_24c02", "bus": 23, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 23, "loc": 0x58}, + {"name": "wb_24c02", "bus": 25, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 25, "loc": 0x58}, + {"name": "wb_24c02", "bus": 24, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 24, "loc": 0x58}, + {"name": "wb_24c02", "bus": 26, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 26, "loc": 0x58}, + {"name": "wb_isl68127", "bus": 30, "loc": 0x64}, + #mac bsc + {"name": "wb_mac_bsc_th3", "bus": 27, "loc": 0x44}, + {"name": "wb_tps53622", "bus": 10, "loc": 0x60}, + {"name": "wb_tps53622", "bus": 10, "loc": 0x6c}, +] + +OPTOE = [ + {"name": "wb_optoe1", "startbus": 71, "endbus": 198}, +] SLOT_MONITOR_PARAM = { - "polling_time" : 0.5, + "polling_time": 0.5, "slots": [ - {"name":"slot1", - "present":{"gettype":"io", "io_addr":0xb2c,"presentbit": 4,"okval":0}, - "act":[ - {"io_addr":0xb19, "value":0x01, "mask":0xfe, "gettype":"io"}, - {"bus":3, "loc":0x30, "offset":0xa0, "value":0xff,"gettype":"i2c"}, - {"bus":3, "loc":0x31, "offset":0xa0, "value":0xff,"gettype":"i2c"}, + {"name": "slot1", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 4, "okval": 0}, + "act": [ + {"io_addr": 0xb19, "value": 0x01, "mask": 0xfe, "gettype": "io"}, + {"bus": 3, "loc": 0x30, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, + {"bus": 3, "loc": 0x31, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, ], - }, - {"name":"slot2", - "present":{"gettype":"io", "io_addr":0xb2c,"presentbit": 5,"okval":0}, - "act":[ - {"io_addr":0xb19, "value":0x02, "mask":0xfd, "gettype":"io"}, - {"bus":4, "loc":0x30, "offset":0xa0, "value":0xff,"gettype":"i2c"}, - {"bus":4, "loc":0x31, "offset":0xa0, "value":0xff,"gettype":"i2c"}, + }, + {"name": "slot2", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 5, "okval": 0}, + "act": [ + {"io_addr": 0xb19, "value": 0x02, "mask": 0xfd, "gettype": "io"}, + {"bus": 4, "loc": 0x30, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, + {"bus": 4, "loc": 0x31, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, ], - }, - {"name":"slot3", - "present":{"gettype":"io", "io_addr":0xb2c,"presentbit": 6,"okval":0}, - "act":[ - {"io_addr":0xb19, "value":0x04, "mask":0xfb, "gettype":"io"}, - {"bus":5, "loc":0x30, "offset":0xa0, "value":0xff,"gettype":"i2c"}, - {"bus":5, "loc":0x31, "offset":0xa0, "value":0xff,"gettype":"i2c"}, + }, + {"name": "slot3", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 6, "okval": 0}, + "act": [ + {"io_addr": 0xb19, "value": 0x04, "mask": 0xfb, "gettype": "io"}, + {"bus": 5, "loc": 0x30, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, + {"bus": 5, "loc": 0x31, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, ], - }, - {"name":"slot4", - "present":{"gettype":"io", "io_addr":0xb2c,"presentbit": 7,"okval":0}, - "act":[ - {"io_addr":0xb19, "value":0x08, "mask":0xf7, "gettype":"io"}, - {"bus":6, "loc":0x30, "offset":0xa0, "value":0xff,"gettype":"i2c"}, - {"bus":6, "loc":0x31, "offset":0xa0, "value":0xff,"gettype":"i2c"}, + }, + {"name": "slot4", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 7, "okval": 0}, + "act": [ + {"io_addr": 0xb19, "value": 0x08, "mask": 0xf7, "gettype": "io"}, + {"bus": 6, "loc": 0x30, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, + {"bus": 6, "loc": 0x31, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, ], - }, + }, ], } -#####################MAC AVS ARGS (B6920-4S) #################################### -MAC_AVS_PARAM ={ - 0x72:0x0384 , - 0x73:0x037e , - 0x74:0x0378 , - 0x75:0x0372 , - 0x76:0x036b , - 0x77:0x0365 , - 0x78:0x035f , - 0x79:0x0359 , - 0x7a:0x0352 , - 0x7b:0x034c , - 0x7c:0x0346 , - 0x7d:0x0340 , - 0x7e:0x0339 , - 0x7f:0x0333 , - 0x80:0x032d , - 0x81:0x0327 , - 0x82:0x0320 , - 0x83:0x031a , - 0x84:0x0314 , - 0x85:0x030e , - 0x86:0x0307 , - 0x87:0x0301 , - 0x88:0x02fb , - 0x89:0x02f5 , - 0x8A:0x02ee -} +##################### MAC Voltage adjust#################################### +MAC_DEFAULT_PARAM = [ + { + "name": "mac_core", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default": 0x73, # default value, if rov value not in range + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + "cpld_avs": {"io_addr": 0x932, "gettype": "io"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/30-0064/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x72: 0.900, + 0x73: 0.894, + 0x74: 0.888, + 0x75: 0.882, + 0x76: 0.875, + 0x77: 0.869, + 0x78: 0.863, + 0x79: 0.857, + 0x7a: 0.850, + 0x7b: 0.844, + 0x7c: 0.838, + 0x7d: 0.832, + 0x7e: 0.825, + 0x7f: 0.819, + 0x80: 0.813, + 0x81: 0.807, + 0x82: 0.800, + 0x83: 0.794, + 0x84: 0.788, + 0x85: 0.782, + 0x86: 0.775, + 0x87: 0.769, + 0x88: 0.763, + 0x89: 0.757, + 0x8A: 0.750 + } + } +] + +UPGRADE_SUMMARY = { + "devtype": 0x404d, + + "slot0": { + "subtype": 0, + "VME": { + "chain1": { + "name": "BOARD_CPLD", + "is_support_warm_upg": 0, + }, + }, + + "MTD": { + "chain1": { + "name": "BIOS", + "is_support_warm_upg": 0, + "filesizecheck": 10240, # bios check file size, Unit: K + "init_cmd": [ + {"io_addr": 0x722, "value": 0x02, "gettype": "io"}, + {"cmd": "modprobe mtd", "gettype": "cmd"}, + {"cmd": "modprobe spi_nor", "gettype": "cmd"}, + {"cmd": "modprobe ofpart", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi writeable=1", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi_platform writeable=1", "gettype": "cmd"}, + ], + "finish_cmd": [ + {"io_addr": 0x722, "value": 0x02, "gettype": "io"}, + {"cmd": "rmmod intel_spi_platform", "gettype": "cmd"}, + {"cmd": "rmmod intel_spi", "gettype": "cmd"}, + {"cmd": "rmmod ofpart", "gettype": "cmd"}, + {"cmd": "rmmod spi_nor", "gettype": "cmd"}, + {"cmd": "rmmod mtd", "gettype": "cmd"}, + ], + }, + }, + + "TEST": { + "cpld": [ + {"chain": 1, "file": "/etc/.upgrade_test/board_cpld_test_header.vme", "display_name": "BOARD_CPLD"}, + ], + }, + }, + + "slot1": { + "subtype": 0x4045, + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 4, "okval": 0}, + "VME": { + "chain0": { + "name": "SLOT1_CPLD", + "is_support_warm_upg": 0, + }, + }, + + "TEST": { + "cpld": [ + {"chain": 0, "file": "/etc/.upgrade_test/slot_cpld_test_header.vme", "display_name": "SLOT1_CPLD"}, + ], + }, + }, + + "slot2": { + "subtype": 0x4045, + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 5, "okval": 0}, + "VME": { + "chain0": { + "name": "SLOT2_CPLD", + "is_support_warm_upg": 0, + }, + }, + + "TEST": { + "cpld": [ + {"chain": 0, "file": "/etc/.upgrade_test/slot_cpld_test_header.vme", "display_name": "SLOT2_CPLD"}, + ], + }, + }, + + "slot3": { + "subtype": 0x4045, + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 6, "okval": 0}, + "VME": { + "chain0": { + "name": "SLOT3_CPLD", + "is_support_warm_upg": 0, + }, + }, + + "TEST": { + "cpld": [ + {"chain": 0, "file": "/etc/.upgrade_test/slot_cpld_test_header.vme", "display_name": "SLOT3_CPLD"}, + ], + }, + }, + + "slot4": { + "subtype": 0x4045, + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 7, "okval": 0}, + "VME": { + "chain0": { + "name": "SLOT4_CPLD", + "is_support_warm_upg": 0, + }, + }, + "TEST": { + "cpld": [ + {"chain": 0, "file": "/etc/.upgrade_test/slot_cpld_test_header.vme", "display_name": "SLOT4_CPLD"}, + ], + }, + }, +} -MAC_DEFAULT_PARAM = { - "type": 1, - "default":0x73, - "loopaddr":0x00, - "loop":0x01, - "open":0x00, - "close":0x40, - "bus":30, - "devno":0x64, - "addr":0x21, - "protectaddr":0x10, - "sdkreg":"DMU_PCU_OTP_CONFIG_4", - "sdkcmd": "scdcmd", - "sdkcmdargs": ["-t", 5], - "sdktype": 1, - "macregloc":8, - "mask": 0xff +PLATFORM_E2_CONF = { + "fan": [ + {"name": "fan1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/63-0050/eeprom"}, + {"name": "fan2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/55-0050/eeprom"}, + {"name": "fan3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/64-0050/eeprom"}, + {"name": "fan4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/56-0050/eeprom"}, + {"name": "fan5", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/65-0050/eeprom"}, + {"name": "fan6", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/57-0050/eeprom"}, + ], + "psu": [ + {"name": "psu1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/23-0050/eeprom"}, + {"name": "psu2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/25-0050/eeprom"}, + {"name": "psu3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/24-0050/eeprom"}, + {"name": "psu4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/26-0050/eeprom"}, + ], + "syseeprom": [ + {"name": "syseeprom", "e2_type": "onie_tlv", "e2_path": "/sys/bus/i2c/devices/1-0056/eeprom"}, + ], + "slot": [ + {"name": "slot1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/3-0056/eeprom"}, + {"name": "slot2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/4-0056/eeprom"}, + {"name": "slot3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/5-0056/eeprom"}, + {"name": "slot4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/6-0056/eeprom"}, + ], } diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_port_config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_port_config.py new file mode 100755 index 000000000000..6ff11529ec9b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_port_config.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +PLATFORM_INTF_OPTOE = { + "port_num": 128, + "optoe_start_bus": 71, +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_device.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_device.py new file mode 100755 index 000000000000..046af4e0dd60 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_device.py @@ -0,0 +1,1247 @@ +# coding:utf-8 + +psu_fan_airflow = { + "intake": ['DPS-1300AB-6 S', 'GW-CRPS1300D'], +} + +fanairflow = { + "intake": ['P2EFAN I-F'], +} + +psu_display_name = { + "PA1300I-F": ['GW-CRPS1300D', 'DPS-1300AB-6 S'], +} + +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + + +class threshold: + PSU_TEMP_MIN = -10 * 1000 + PSU_TEMP_MAX = 60 * 1000 + + PSU_FAN_SPEED_MIN = 150 + PSU_FAN_SPEED_MAX = 12000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 1300 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 1444 * 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 2 * 1000 + PSU_OUTPUT_CURRENT_MAX = 107 * 1000 + + PSU_INPUT_CURRENT_MIN = 0.2 * 1000 + PSU_INPUT_CURRENT_MAX = 7 * 1000 + + FRONT_FAN_SPEED_MAX = 11000 + REAR_FAN_SPEED_MAX = 9500 + FAN_SPEED_MIN = 1500 + + +class Description: + CPLD = "Used for managing IO modules, SFP+ modules and system LEDs" + BIOS = "Performs initialization of hardware components during booting" + FPGA = "Platform management controller for on-board temperature monitoring, in-chassis power" + + +devices = { + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/1-0056/eeprom", "way": "sysfs"}, + }, + ], + "psus": [ + { + "e2loc": {"loc": "/sys/bus/i2c/devices/23-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 23, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 23, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 23, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "InputsStatus": {"bus": 23, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 23, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 23, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/25-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 25, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "InputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 25, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/24-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 24, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU3", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "InputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 24, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/26-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 26, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU4", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 26, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 26, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "InputsStatus": {"bus": 26, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 26, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 26, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + ], + "temps": [ + { + "name": "BOARD_TEMP", + "temp_id": "TEMP1", + "Temperature": { + "value": [ + {"loc": "/sys/bus/i2c/devices/32-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/32-004d/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/48-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/48-004d/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/40-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/40-004d/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/16-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/16-004d/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + ], + "Min": -10000, + "Low": 0, + "High": 85000, + "Max": 90000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "CPU_TEMP", + "temp_id": "TEMP2", + "Temperature": { + "value": {"loc": "/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": 2000, + "Low": 10000, + "High": 85000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP3", + "Temperature": { + "value": [ + {"loc": "/sys/bus/i2c/devices/32-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/48-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/40-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/16-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"} + ], + "Min": -10000, + "Low": 0, + "High": 50000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP4", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/28-004b/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 85000, + "Max": 90000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP5", + "api_name": "ASIC_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/28-004c/hwmon/hwmon*/temp2_input", "way": "sysfs"}, + "Min": 2000, + "Low": 10000, + "High": 100000, + "Max": 105000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "Temperature": { + "value": {"loc": "/tmp/highest_sff_temp", "way": "sysfs", "flock_path": "/tmp/highest_sff_temp"}, + "Min": -15000, + "Low": 0, + "High": 80000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + ], + "leds": [ + { + "name": "BOARD_SYS_LED", + "led_type": "SYS_LED", + "led": {"loc": "/dev/cpld1", "offset": 0x21, "len": 1, "way": "devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0, "mask": 0xff + }, + }, + { + "name": "BOARD_PSU_LED", + "led_type": "PSU_LED", + "led": {"loc": "/dev/cpld1", "offset": 0x22, "len": 1, "way": "devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0, "mask": 0xff + }, + }, + { + "name": "BOARD_FAN_LED", + "led_type": "FAN_LED", + "led": {"loc": "/dev/cpld1", "offset": 0x23, "len": 1, "way": "devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0, "mask": 0xff + }, + }, + ], + "fans": [ + { + "name": "FAN1", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/63-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 14, "addr": 0x0d, "offset": 0x3b, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/55-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 13, "addr": 0x0d, "offset": 0x3b, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/64-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 14, "addr": 0x0d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN4", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/56-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 13, "addr": 0x0d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN5", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/65-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan5/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 14, "addr": 0x0d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan5/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan5/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan5/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan5/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN6", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/57-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan6/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 13, "addr": 0x0d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan6/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan6/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan6/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan6/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + }, + { + "name": "MAC_CPLD_A", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + }, + { + "name": "MAC_CPLD_B", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld2", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + }, + { + "name": "FAN_CPLD_A", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld3", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system LEDs and FANs", + "slot": 0, + }, + { + "name": "FAN_CPLD_B", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld4", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system LEDs and FANs", + "slot": 0, + }, + { + "name": "LC1_CPLD_2", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/cpld5", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 1, + }, + { + "name": "LC1_CPLD_1", + "cpld_id": "CPLD7", + "VersionFile": {"loc": "/dev/cpld6", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 1, + }, + { + "name": "LC2_CPLD_2", + "cpld_id": "CPLD8", + "VersionFile": {"loc": "/dev/cpld7", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 2, + }, + { + "name": "LC2_CPLD_1", + "cpld_id": "CPLD9", + "VersionFile": {"loc": "/dev/cpld8", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 2, + }, + { + "name": "LC3_CPLD_2", + "cpld_id": "CPLD10", + "VersionFile": {"loc": "/dev/cpld9", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 3, + }, + { + "name": "LC3_CPLD_1", + "cpld_id": "CPLD11", + "VersionFile": {"loc": "/dev/cpld10", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 3, + }, + { + "name": "LC4_CPLD_2", + "cpld_id": "CPLD12", + "VersionFile": {"loc": "/dev/cpld11", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 4, + }, + { + "name": "LC4_CPLD_1", + "cpld_id": "CPLD13", + "VersionFile": {"loc": "/dev/cpld12", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 4, + }, + ], + "dcdc": [ + { + "name": "X86_BOARD_P5V_AUX_IN", + "dcdc_id": "DCDC1", + "Min": 4721, + "value": { + "loc": "/sys/wb_plat/sensor/in1/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 5250, + "format": "float(float(%s)/1000)", + }, + { + "name": "X86_BOARD_P1V7_IN", + "dcdc_id": "DCDC2", + "Min": 1615, + "value": { + "loc": "/sys/wb_plat/sensor/in2/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1792, + "format": "float(float(%s)/1000)", + }, + { + "name": "X86_BOARD_TEST1v24", + "dcdc_id": "DCDC3", + "Min": 1178, + "value": { + "loc": "/sys/wb_plat/sensor/in3/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1302, + "format": "float(float(%s)/1000)", + }, + { + "name": "X86_BOARD_P3V3_STBY_IN", + "dcdc_id": "DCDC4", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in4/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3500, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD1v8", + "dcdc_id": "DCDC5", + "Min": 1710, + "value": { + "loc": "/sys/wb_plat/sensor/in5/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1909, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_SW_VDD1v2", + "dcdc_id": "DCDC6", + "Min": 1140, + "value": { + "loc": "/sys/wb_plat/sensor/in6/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1286, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_TEST1v24", + "dcdc_id": "DCDC7", + "Min": 1178, + "value": { + "loc": "/sys/wb_plat/sensor/in7/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1302, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD1v2_MAC", + "dcdc_id": "DCDC8", + "Min": 1140, + "value": { + "loc": "/sys/wb_plat/sensor/in8/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1260, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD_CORE", + "dcdc_id": "DCDC9", + "Min": 712, + "value": { + "loc": "/sys/wb_plat/sensor/in9/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 945, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD3v3_MCU", + "dcdc_id": "DCDC10", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in10/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3556, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD3v3_CLK", + "dcdc_id": "DCDC11", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in11/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3556, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD5V_CLK_MCU", + "dcdc_id": "DCDC12", + "Min": 4750, + "value": { + "loc": "/sys/wb_plat/sensor/in12/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 5331, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD2v5", + "dcdc_id": "DCDC13", + "Min": 2375, + "value": { + "loc": "/sys/wb_plat/sensor/in13/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2688, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDDO", + "dcdc_id": "DCDC14", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in14/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3542, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_BC_PVDD", + "dcdc_id": "DCDC15", + "Min": 760, + "value": { + "loc": "/sys/wb_plat/sensor/in15/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 867, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD3v3", + "dcdc_id": "DCDC16", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in16/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3542, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_ANLGOUT", + "dcdc_id": "DCDC17", + "Min": 760, + "value": { + "loc": "/sys/wb_plat/sensor/in17/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 856, + "format": "float(float(%s)/1000)", + }, + ], + "cpu": [ + { + "name": "cpu", + "CpuResetCntReg": {"io_addr": 0xb88, "way": "io"}, + } + ], + "sfps": { + "ver": '1.0', + "port_index_start": 0, + "port_num": 128, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_cpld": { + "dev_id": { + 6: { + "offset": { + 0x10: "1-8", + 0x11: "9-16", + }, + }, + 5: { + "offset": { + 0x10: "17-24", + 0x11: "25-32", + }, + }, + 8: { + "offset": { + 0x10: "33-40", + 0x11: "41-48", + }, + }, + 7: { + "offset": { + 0x10: "49-56", + 0x11: "57-64", + }, + }, + 10: { + "offset": { + 0x10: "65-72", + 0x11: "73-80", + }, + }, + 9: { + "offset": { + 0x10: "81-88", + 0x11: "89-96", + }, + }, + 12: { + "offset": { + 0x10: "97-104", + 0x11: "105-112", + }, + }, + 11: { + "offset": { + 0x10: "113-120", + 0x11: "121-128", + }, + }, + }, + }, + "presence_val_is_present": 0, + "eeprom_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/eeprom", + "eeprom_path_key": list(range(71, 199)), + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(71, 199)), + "reset_cpld": { + "dev_id": { + 6: { + "offset": { + 0x14: "1-8", + 0x15: "9-16", + }, + }, + 5: { + "offset": { + 0x14: "17-24", + 0x15: "25-32", + }, + }, + 8: { + "offset": { + 0x14: "33-40", + 0x15: "41-48", + }, + }, + 7: { + "offset": { + 0x14: "49-56", + 0x15: "57-64", + }, + }, + 10: { + "offset": { + 0x14: "65-72", + 0x15: "73-80", + }, + }, + 9: { + "offset": { + 0x14: "81-88", + 0x15: "89-96", + }, + }, + 12: { + "offset": { + 0x14: "97-104", + 0x15: "105-112", + }, + }, + 11: { + "offset": { + 0x14: "113-120", + 0x15: "121-128", + }, + }, + } + }, + "reset_val_is_reset": 0, + } +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_monitor.py new file mode 100755 index 000000000000..6ab176708c27 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_monitor.py @@ -0,0 +1,113 @@ +# coding:utf-8 + + +monitor = { + "openloop": { + "linear": { + "name": "linear", + "flag": 1, + "pwm_min": 0x80, + "pwm_max": 0xff, + "K": 11, + "tin_min": 28, + }, + "curve": { + "name": "curve", + "flag": 0, + "pwm_min": 0x80, + "pwm_max": 0xff, + "a": 0.183, + "b": -6.88, + "c": 120, + "tin_min": 25, + }, + }, + + "pid": { + "CPU_TEMP": { + "name": "CPU_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 1.5, + "Ki": 1, + "Kd": 0.3, + "target": 90, + "value": [None, None, None], + }, + "SWITCH_TEMP": { + "name": "SWITCH_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 1.5, + "Ki": 1, + "Kd": 0.3, + "target": 90, + "value": [None, None, None], + }, + "SFF_TEMP": { + "name": "SFF_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 0.1, + "Ki": 0.4, + "Kd": 0, + "target": 68, + "value": [None, None, None], + }, + }, + + "temps_threshold": { + "SWITCH_TEMP": {"name": "SWITCH_TEMP", "warning": 100, "critical": 105}, + "INLET_TEMP": {"name": "INLET_TEMP", "warning": 50, "critical": 60}, + "BOARD_TEMP": {"name": "BOARD_TEMP", "warning": 85, "critical": 90}, + "OUTLET_TEMP": {"name": "OUTLET_TEMP", "warning": 85, "critical": 90}, + "CPU_TEMP": {"name": "CPU_TEMP", "warning": 85, "critical": 100}, + "SFF_TEMP": {"name": "SFF_TEMP", "warning": 999, "critical": 1000, "ignore_threshold": 1, "invalid": -10000, "error": -9999}, + }, + + "fancontrol_para": { + "interval": 5, + "max_pwm": 0xff, + "min_pwm": 0x80, + "abnormal_pwm": 0xff, + "temp_fail_num": 3, + "check_temp_fail": [ + {"temp_name": "INLET_TEMP"}, + ], + "inlet_mac_diff": 50, + "check_crit_reboot_num": 3, + "check_crit_sleep_time": 20, + "psu_absent_fullspeed_num": 0xFF, + "fan_absent_fullspeed_num": 1, + "rotor_error_fullspeed_num": 1, + "psu_fan_control": 0, + }, + + "ledcontrol_para": { + "interval": 5, + "checkpsu": 0, # 0: sys led don't follow psu led + "checkfan": 0, # 0: sys led don't follow fan led + "psu_amber_num": 1, + "fan_amber_num": 1, + "board_sys_led": [ + {"led_name": "BOARD_SYS_LED"}, + ], + "board_psu_led": [ + {"led_name": "BOARD_PSU_LED"}, + ], + "board_fan_led": [ + {"led_name": "BOARD_FAN_LED"}, + ], + }, + + "otp_reboot_judge_file": { + "otp_switch_reboot_judge_file": "/etc/.otp_switch_reboot_flag", + "otp_other_reboot_judge_file": "/etc/.otp_other_reboot_flag", + }, +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/Makefile index 2b5ac6c5aadb..dda2e92069fb 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/Makefile @@ -1,8 +1,14 @@ -obj-m := rg_cpld.o - -obj-m += lpc_cpld_i2c.o -obj-m += rg_lpc_cpld.o -obj-m += pddf_custom_fan.o -obj-m += pddf_custom_psu.o -obj-m += pddf_custom_xcvr.o -obj-m += pddf_custom_led_module.o +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/app/firmware_upgrade/firmware_driver/include) + +EXTRA_CFLAGS+= -I$(MODULES_DIR) +EXTRA_CFLAGS+= -I$(MODULES_DIR)/linux-5.10 +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) + +obj-m += wb_lpc_drv_device.o +obj-m += wb_io_dev_device.o +obj-m += wb_platform_i2c_dev_device.o +obj-m += wb_i2c_ocores_device.o +obj-m += wb_i2c_mux_pca954x_device.o +obj-m += wb_firmware_upgrade_device.o diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/platform_common.h b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/platform_common.h new file mode 100644 index 000000000000..e910b7fa15f6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/platform_common.h @@ -0,0 +1,113 @@ +#ifndef __PLATFORM_COMMON_H__ +#define __PLATFORM_COMMON_H__ + +#include +#include + +typedef enum { + DBG_START, + DBG_VERBOSE, + DBG_KEY, + DBG_WARN, + DBG_ERROR, + DBG_END, +} dbg_level_t; + +typedef enum dfd_cpld_id { + BCM_CPLD0 = 0, + BCM_CPLD1, + CPLD0_MAC0, + CPLD0_MAC1, + CPLD1_MAC0, + CPLD2_MAC1, +} dfd_cpld_id_t; + + typedef enum dfd_cpld_bus { + SMBUS_BUS = 0 , + PCA9641_BUS = 1, + GPIO_BUS = 2, +} dfd_cpld_bus_t; + + typedef struct dfd_i2c_dev_s { + int bus; + int addr; + } dfd_i2c_dev_t; + + typedef enum dfd_cpld_addr { + CPLD_ADDR_MIN = 0x31, + BCM_CPLD0_ADDR = 0x32, + CPLD0_MAC0_ADDR = 0x33, + CPLD0_MAC1_ADDR = 0x34, + CPLD1_MAC0_ADDR = 0x35, + CPLD2_MAC1_ADDR = 0x36, + BCM_CPLD1_ADDR = 0x37, + CPLD_ADDR_MAX, +} dfd_cpld_addr_t; + +typedef struct dfd_dev_head_info_s { + uint8_t ver; + uint8_t flag; + uint8_t hw_ver; + uint8_t type; + int16_t tlv_len; +} dfd_dev_head_info_t; + +typedef enum dfd_intf_e{ + DFD_INTF_GET_FAN_HW_VERSION, + DFD_INTF_GET_FAN_STATUS, + DFD_INTF_GET_FAN_SPEED_LEVEL, + DFD_INTF_GET_FAN_SPEED, + DFD_INTF_GET_FAN_ATTRIBUTE, + DFD_INTF_GET_FAN_SN, + DFD_INTF_GET_FAN_TYPE, + DFD_INTF_SET_FAN_SPEED_LEVEL, + DFD_INTF_GET_FAN_SUB_NUM, + DFD_INTF_GET_FAN_FAIL_BITMAP, +}dfd_intf_t; + +typedef struct dfd_dev_tlv_info_s { + uint8_t type; + uint8_t len; + uint8_t data[0]; +} dfd_dev_tlv_info_t; + +typedef enum dfd_dev_info_type_e { + DFD_DEV_INFO_TYPE_MAC = 1, + DFD_DEV_INFO_TYPE_NAME = 2, + DFD_DEV_INFO_TYPE_SN = 3, + DFD_DEV_INFO_TYPE_PWR_CONS = 4, + DFD_DEV_INFO_TYPE_HW_INFO = 5, + DFD_DEV_INFO_TYPE_DEV_TYPE = 6, +} dfd_dev_tlv_type_t; + +typedef struct i2c_muxs_struct_flag +{ + int nr; + char name[48]; + struct mutex update_lock; + int flag; +}i2c_mux_flag; + +extern int setpca9641_muxflag(i2c_mux_flag i2c); +extern i2c_mux_flag getpca9641_muxflag(void) ; + +extern int debuglevel; +extern int dfd_cpld_read_chipid(int cpldid , uint32_t addr, int32_t size, unsigned char *buf); +extern int dfd_cpld_read(int32_t addr, uint8_t *val); +extern int dfd_cpld_write(int32_t addr, uint8_t val); + +#define DBG_DEBUG(fmt, arg...) do { \ + if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ + printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else if ( debuglevel >= DBG_ERROR ) { \ + printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else { } \ +} while (0) + +#define DBG_ERROR(fmt, arg...) do { \ + if ( debuglevel > DBG_START) { \ + printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_firmware_upgrade_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_firmware_upgrade_device.c new file mode 100644 index 000000000000..9713f42c6634 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_firmware_upgrade_device.c @@ -0,0 +1,243 @@ +/* + * wb_firmware_upgrade.c + * Original Author: support 2021-03-17 + * + * ko for firmware device + * History + * [Version] [Author] [Date] [Description] + * v1.0 support 2021-05-07 Initial version + */ +#include +#include +#include +#include +#include +#include + +static int g_wb_firmware_upgrade_debug = 0; +static int g_wb_firmware_upgrade_error = 0; + +module_param(g_wb_firmware_upgrade_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_firmware_upgrade_error, int, S_IRUGO | S_IWUSR); + +#define WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_firmware_upgrade_debug) { \ + printk(KERN_INFO "[WB_FIRMWARE_UPGRADE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FIRMWARE_UPGRADE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_firmware_upgrade_error) { \ + printk(KERN_ERR "[WB_FIRMWARE_UPGRADE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 48, + .en_level[1] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* slot1 */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 39, + .en_level[1] = 1, + .chain = 16, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* slot2 */ +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 69, + .en_level[1] = 1, + .chain = 32, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* slot3 */ +static firmware_upgrade_device_t firmware_upgrade_device_data3 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 70, + .en_level[1] = 1, + .chain = 48, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* slot4 */ +static firmware_upgrade_device_t firmware_upgrade_device_data4 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 71, + .en_level[1] = 1, + .chain = 64, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* bios */ +static firmware_upgrade_device_t firmware_upgrade_device_data5 = { + .type = "MTD_DEV", + .chain = 1, + .chip_index = 1, + .upg_type.sysfs = { + .mtd_name = "BIOS", + .flash_base = 0x800000, + }, + + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 4, + .dev = { + .platform_data = &firmware_upgrade_device_data3, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 5, + .dev = { + .platform_data = &firmware_upgrade_device_data4, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 6, + .dev = { + .platform_data = &firmware_upgrade_device_data5, + .release = firmware_device_release, + }, + }, +}; + +static int __init firmware_upgrade_device_init(void) +{ + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit firmware_upgrade_device_exit(void) +{ + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&firmware_upgrade_device[i]); + } + } +} + +module_init(firmware_upgrade_device_init); +module_exit(firmware_upgrade_device_exit); +MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 000000000000..f9fb5f815eb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,632 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca954x_device_debug = 0; +static int g_wb_i2c_mux_pca954x_device_error = 0; + +module_param(g_wb_i2c_mux_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x76, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 7, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x936, + .io_attr.mask = 0x10, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x10, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data1 = { + .i2c_bus = 7, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 15, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data2 = { + .i2c_bus = 8, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 23, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x10, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x10, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data3 = { + .i2c_bus = 9, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 31, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data4 = { + .i2c_bus = 11, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 39, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data5 = { + .i2c_bus = 12, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 47, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data6 = { + .i2c_bus = 13, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 55, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb10, + .io_attr.mask = 0x80, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x80, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data7 = { + .i2c_bus = 14, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 63, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb10, + .io_attr.mask = 0x20, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x20, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data8 = { + .i2c_bus = 3, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 71, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data9 = { + .i2c_bus = 3, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 79, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data10 = { + .i2c_bus = 3, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 87, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data11 = { + .i2c_bus = 3, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 95, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data12 = { + .i2c_bus = 4, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 103, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data13 = { + .i2c_bus = 4, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 111, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data14 = { + .i2c_bus = 4, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 119, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data15 = { + .i2c_bus = 4, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 127, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data16 = { + .i2c_bus = 5, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 135, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data17 = { + .i2c_bus = 5, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 143, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data18 = { + .i2c_bus = 5, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 151, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data19 = { + .i2c_bus = 5, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 159, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data20 = { + .i2c_bus = 6, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 167, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data21 = { + .i2c_bus = 6, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 175, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data22 = { + .i2c_bus = 6, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 183, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data23 = { + .i2c_bus = 6, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 191, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data1, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data2, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data3, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data4, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data5, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data6, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data7, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data8, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data9, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data10, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data11, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data12, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data13, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data14, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data15, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data16, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data17, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data18, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data19, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data20, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data21, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data22, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data23, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (!client) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_ocores_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_ocores_device.c new file mode 100644 index 000000000000..961e8edeaaff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_ocores_device.c @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_ocores_device_debug = 0; +static int g_wb_i2c_ocores_device_error = 0; + +module_param(g_wb_i2c_ocores_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_ocores_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_debug) { \ + printk(KERN_INFO "[WB_I2C_OCORE_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_OCORE_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_error) { \ + printk(KERN_ERR "[WB_I2C_OCORE_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_ocores_device_t i2c_ocores_device_data0 = { + .adap_nr = 2, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0xa0, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data1 = { + .adap_nr = 3, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0x80, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data2 = { + .adap_nr = 4, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0x88, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data3 = { + .adap_nr = 5, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0x90, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data4 = { + .adap_nr = 6, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0x98, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static void wb_i2c_ocores_device_release(struct device *dev) +{ + return; +} + +static struct platform_device i2c_ocores_device[] = { + { + .name = "wb-ocores-i2c", + .id = 1, + .dev = { + .platform_data = &i2c_ocores_device_data0, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 2, + .dev = { + .platform_data = &i2c_ocores_device_data1, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 3, + .dev = { + .platform_data = &i2c_ocores_device_data2, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 4, + .dev = { + .platform_data = &i2c_ocores_device_data3, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 5, + .dev = { + .platform_data = &i2c_ocores_device_data4, + .release = wb_i2c_ocores_device_release, + }, + }, +}; + +static int __init wb_i2c_ocores_device_init(void) +{ + int i; + int ret = 0; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_ocores_device); i++) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + ret = platform_device_register(&i2c_ocores_device[i]); + if (ret < 0) { + i2c_ocores_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-ocores-i2c.%d register failed!\n", i + 1); + } else { + i2c_ocores_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_i2c_ocores_device_exit(void) +{ + int i; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_ocores_device) - 1; i >= 0; i--) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + if (i2c_ocores_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&i2c_ocores_device[i]); + } + } +} + +module_init(wb_i2c_ocores_device_init); +module_exit(wb_i2c_ocores_device_exit); +MODULE_DESCRIPTION("I2C OCORES Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..454815c23369 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_io_dev_device.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data1 = { + .io_dev_name = "cpld1", + .io_base = 0xb00, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data2 = { + .io_dev_name = "cpld2", + .io_base = 0x900, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 2, + .dev = { + .platform_data = &io_dev_device_data1, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 3, + .dev = { + .platform_data = &io_dev_device_data2, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..9b6b61a51735 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static lpc_drv_device_t lpc_drv_device_data_1 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x900, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x88, +}; + +static lpc_drv_device_t lpc_drv_device_data_2 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0xb00, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x90, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 2, + .dev = { + .platform_data = &lpc_drv_device_data_1, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 3, + .dev = { + .platform_data = &lpc_drv_device_data_2, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_platform_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_platform_i2c_dev_device.c new file mode 100644 index 000000000000..42a945dc8ba2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_platform_i2c_dev_device.c @@ -0,0 +1,263 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_platform_i2c_dev_device_debug = 0; +static int g_wb_platform_i2c_dev_device_error = 0; + +module_param(g_wb_platform_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_platform_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_platform_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_PLATFORM_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_platform_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_PLATFORM_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* FAN CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data0 = { + .i2c_bus = 14, + .i2c_addr = 0x0d, + .i2c_name = "cpld3", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* FAN CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data1 = { + .i2c_bus = 13, + .i2c_addr = 0x0d, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT1 CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data2 = { + .i2c_bus = 3, + .i2c_addr = 0x31, + .i2c_name = "cpld5", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT1 CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data3 = { + .i2c_bus = 3, + .i2c_addr = 0x30, + .i2c_name = "cpld6", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT2 CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data4 = { + .i2c_bus = 4, + .i2c_addr = 0x31, + .i2c_name = "cpld7", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT2 CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data5 = { + .i2c_bus = 4, + .i2c_addr = 0x30, + .i2c_name = "cpld8", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT3 CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data6 = { + .i2c_bus = 5, + .i2c_addr = 0x31, + .i2c_name = "cpld9", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT3 CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data7 = { + .i2c_bus = 5, + .i2c_addr = 0x30, + .i2c_name = "cpld10", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT4 CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data8 = { + .i2c_bus = 6, + .i2c_addr = 0x31, + .i2c_name = "cpld11", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT4 CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data9 = { + .i2c_bus = 6, + .i2c_addr = 0x30, + .i2c_name = "cpld12", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static void wb_platform_i2c_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device platform_i2c_dev_device[] = { + { + .name = "wb-platform-i2c-dev", + .id = 1, + .dev = { + .platform_data = &platform_i2c_dev_device_data0, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 2, + .dev = { + .platform_data = &platform_i2c_dev_device_data1, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 3, + .dev = { + .platform_data = &platform_i2c_dev_device_data2, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 4, + .dev = { + .platform_data = &platform_i2c_dev_device_data3, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 5, + .dev = { + .platform_data = &platform_i2c_dev_device_data4, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 6, + .dev = { + .platform_data = &platform_i2c_dev_device_data5, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 7, + .dev = { + .platform_data = &platform_i2c_dev_device_data6, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 8, + .dev = { + .platform_data = &platform_i2c_dev_device_data7, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 9, + .dev = { + .platform_data = &platform_i2c_dev_device_data8, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 10, + .dev = { + .platform_data = &platform_i2c_dev_device_data9, + .release = wb_platform_i2c_dev_device_release, + }, + }, +}; + +static int __init wb_platform_i2c_dev_device_init(void) +{ + int i; + int ret = 0; + platform_i2c_dev_device_t *platform_i2c_dev_device_data; + + WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(platform_i2c_dev_device); i++) { + platform_i2c_dev_device_data = platform_i2c_dev_device[i].dev.platform_data; + ret = platform_device_register(&platform_i2c_dev_device[i]); + if (ret < 0) { + platform_i2c_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-platform-i2c-dev.%d register failed!\n", i + 1); + } else { + platform_i2c_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_platform_i2c_dev_device_exit(void) +{ + int i; + platform_i2c_dev_device_t *platform_i2c_dev_device_data; + + WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(platform_i2c_dev_device) - 1; i >= 0; i--) { + platform_i2c_dev_device_data = platform_i2c_dev_device[i].dev.platform_data; + if (platform_i2c_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&platform_i2c_dev_device[i]); + } + } +} + +module_init(wb_platform_i2c_dev_device_init); +module_exit(wb_platform_i2c_dev_device_exit); +MODULE_DESCRIPTION("PLATFORM I2C DEV Devices"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..ad8cc36f7145 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,61 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_1_0=3 +cpld_i2c_dev.addr_1_0=0x31 +cpld_i2c_dev.bus_1_1=3 +cpld_i2c_dev.addr_1_1=0x30 +cpld_i2c_dev.bus_2_0=4 +cpld_i2c_dev.addr_2_0=0x31 +cpld_i2c_dev.bus_2_1=4 +cpld_i2c_dev.addr_2_1=0x30 +cpld_i2c_dev.bus_3_0=5 +cpld_i2c_dev.addr_3_0=0x31 +cpld_i2c_dev.bus_3_1=5 +cpld_i2c_dev.addr_3_1=0x30 +cpld_i2c_dev.bus_4_0=6 +cpld_i2c_dev.addr_4_0=0x31 +cpld_i2c_dev.bus_4_1=6 +cpld_i2c_dev.addr_4_1=0x30 +cpld_i2c_dev.bus_5_0=14 +cpld_i2c_dev.addr_5_0=0x0d +cpld_i2c_dev.bus_5_1=13 +cpld_i2c_dev.addr_5_1=0x0d + + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_0=0x700 +cpld_lpc_dev_0_1=0xb00 +cpld_lpc_dev_0_2=0x900 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=lpc +mode_cpld_0_1=lpc +mode_cpld_0_2=lpc +mode_cpld_1_0=i2c +mode_cpld_1_1=i2c +mode_cpld_2_0=i2c +mode_cpld_2_1=i2c +mode_cpld_3_0=i2c +mode_cpld_3_1=i2c +mode_cpld_4_0=i2c +mode_cpld_4_1=i2c +mode_cpld_5_0=i2c +mode_cpld_5_1=i2c + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=13 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..2d07cec07ff3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,440 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=6 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=2 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x05000030 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x05010030 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=0 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x05000030 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=1 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=cpld +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.addr_1_4=0x05010030 +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=1 + +dev_present_status.mode_1_5=config +dev_present_status.src_1_5=cpld +dev_present_status.frmt_1_5=bit +dev_present_status.pola_1_5=negative +dev_present_status.addr_1_5=0x05000030 +dev_present_status.len_1_5=1 +dev_present_status.bit_offset_1_5=2 + +dev_present_status.mode_1_6=config +dev_present_status.src_1_6=cpld +dev_present_status.frmt_1_6=bit +dev_present_status.pola_1_6=negative +dev_present_status.addr_1_6=0x05010030 +dev_present_status.len_1_6=1 +dev_present_status.bit_offset_1_6=2 + + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x05000014 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_1_1=config +fan_ratio.int_cons_1_1= +fan_ratio.src_1_1=cpld +fan_ratio.frmt_1_1=byte +fan_ratio.pola_1_1= +fan_ratio.fpath_1_1= +fan_ratio.addr_1_1=0x05000014 +fan_ratio.len_1_1=1 +fan_ratio.bit_offset_1_1= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x05010014 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_2_1=config +fan_ratio.int_cons_2_1= +fan_ratio.src_2_1=cpld +fan_ratio.frmt_2_1=byte +fan_ratio.pola_2_1= +fan_ratio.fpath_2_1= +fan_ratio.addr_2_1=0x05010014 +fan_ratio.len_2_1=1 +fan_ratio.bit_offset_2_1= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x05000015 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= + +fan_ratio.mode_3_1=config +fan_ratio.int_cons_3_1= +fan_ratio.src_3_1=cpld +fan_ratio.frmt_3_1=byte +fan_ratio.pola_3_1= +fan_ratio.fpath_3_1= +fan_ratio.addr_3_1=0x05000015 +fan_ratio.len_3_1=1 +fan_ratio.bit_offset_3_1= + +fan_ratio.mode_4_0=config +fan_ratio.int_cons_4_0= +fan_ratio.src_4_0=cpld +fan_ratio.frmt_4_0=byte +fan_ratio.pola_4_0= +fan_ratio.fpath_4_0= +fan_ratio.addr_4_0=0x05010015 +fan_ratio.len_4_0=1 +fan_ratio.bit_offset_4_0= + +fan_ratio.mode_4_1=config +fan_ratio.int_cons_4_1= +fan_ratio.src_4_1=cpld +fan_ratio.frmt_4_1=byte +fan_ratio.pola_4_1= +fan_ratio.fpath_4_1= +fan_ratio.addr_4_1=0x05010015 +fan_ratio.len_4_1=1 +fan_ratio.bit_offset_4_1= + +fan_ratio.mode_5_0=config +fan_ratio.int_cons_5_0= +fan_ratio.src_5_0=cpld +fan_ratio.frmt_5_0=byte +fan_ratio.pola_5_0= +fan_ratio.fpath_5_0= +fan_ratio.addr_5_0=0x05000016 +fan_ratio.len_5_0=1 +fan_ratio.bit_offset_5_0= + +fan_ratio.mode_5_1=config +fan_ratio.int_cons_5_1= +fan_ratio.src_5_1=cpld +fan_ratio.frmt_5_1=byte +fan_ratio.pola_5_1= +fan_ratio.fpath_5_1= +fan_ratio.addr_5_1=0x05000016 +fan_ratio.len_5_1=1 +fan_ratio.bit_offset_5_1= + +fan_ratio.mode_6_0=config +fan_ratio.int_cons_6_0= +fan_ratio.src_6_0=cpld +fan_ratio.frmt_6_0=byte +fan_ratio.pola_6_0= +fan_ratio.fpath_6_0= +fan_ratio.addr_6_0=0x05010016 +fan_ratio.len_6_0=1 +fan_ratio.bit_offset_6_0= + +fan_ratio.mode_6_1=config +fan_ratio.int_cons_6_1= +fan_ratio.src_6_1=cpld +fan_ratio.frmt_6_1=byte +fan_ratio.pola_6_1= +fan_ratio.fpath_6_1= +fan_ratio.addr_6_1=0x05010016 +fan_ratio.len_6_1=1 +fan_ratio.bit_offset_6_1= + + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x05000031 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=0 + +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=cpld +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1= +fan_roll_status.addr_1_1=0x05000034 +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=0 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x05010031 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=0 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=cpld +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1= +fan_roll_status.addr_2_1=0x05010034 +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=0 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x05000031 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=1 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=cpld +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1= +fan_roll_status.addr_3_1=0x05000034 +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=1 + +fan_roll_status.mode_4_0=config +fan_roll_status.int_cons_4_0= +fan_roll_status.src_4_0=cpld +fan_roll_status.frmt_4_0=bit +fan_roll_status.pola_4_0=positive +fan_roll_status.fpath_4_0= +fan_roll_status.addr_4_0=0x05010031 +fan_roll_status.len_4_0=1 +fan_roll_status.bit_offset_4_0=1 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=cpld +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1= +fan_roll_status.addr_4_1=0x05010034 +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=1 + +fan_roll_status.mode_5_0=config +fan_roll_status.int_cons_5_0= +fan_roll_status.src_5_0=cpld +fan_roll_status.frmt_5_0=bit +fan_roll_status.pola_5_0=positive +fan_roll_status.fpath_5_0= +fan_roll_status.addr_5_0=0x05000031 +fan_roll_status.len_5_0=1 +fan_roll_status.bit_offset_5_0=2 + +fan_roll_status.mode_5_1=config +fan_roll_status.int_cons_5_1= +fan_roll_status.src_5_1=cpld +fan_roll_status.frmt_5_1=bit +fan_roll_status.pola_5_1=positive +fan_roll_status.fpath_5_1= +fan_roll_status.addr_5_1=0x05000034 +fan_roll_status.len_5_1=1 +fan_roll_status.bit_offset_5_1=2 + +fan_roll_status.mode_6_0=config +fan_roll_status.int_cons_6_0= +fan_roll_status.src_6_0=cpld +fan_roll_status.frmt_6_0=bit +fan_roll_status.pola_6_0=positive +fan_roll_status.fpath_6_0= +fan_roll_status.addr_6_0=0x05010031 +fan_roll_status.len_6_0=1 +fan_roll_status.bit_offset_6_0=2 + +fan_roll_status.mode_6_1=config +fan_roll_status.int_cons_6_1= +fan_roll_status.src_6_1=cpld +fan_roll_status.frmt_6_1=bit +fan_roll_status.pola_6_1=positive +fan_roll_status.fpath_6_1= +fan_roll_status.addr_6_1=0x05010034 +fan_roll_status.len_6_1=1 +fan_roll_status.bit_offset_6_1=2 + + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x0500001b +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=cpld +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1=negative +fan_speed.fpath_1_1= +fan_speed.addr_1_1=0x05000025 +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0501001b +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=cpld +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1=negative +fan_speed.fpath_2_1= +fan_speed.addr_2_1=0x05010025 +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0500001d +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=cpld +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1=negative +fan_speed.fpath_3_1= +fan_speed.addr_3_1=0x05000027 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_4_0=config +fan_speed.int_cons_4_0= +fan_speed.src_4_0=cpld +fan_speed.frmt_4_0=num_bytes +fan_speed.pola_4_0=negative +fan_speed.fpath_4_0= +fan_speed.addr_4_0=0x0501001d +fan_speed.len_4_0=2 +fan_speed.bit_offset_4_0= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=cpld +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1=negative +fan_speed.fpath_4_1= +fan_speed.addr_4_1=0x05010027 +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + +fan_speed.mode_5_0=config +fan_speed.int_cons_5_0= +fan_speed.src_5_0=cpld +fan_speed.frmt_5_0=num_bytes +fan_speed.pola_5_0=negative +fan_speed.fpath_5_0= +fan_speed.addr_5_0=0x0500001f +fan_speed.len_5_0=2 +fan_speed.bit_offset_5_0= + +fan_speed.mode_5_1=config +fan_speed.int_cons_5_1= +fan_speed.src_5_1=cpld +fan_speed.frmt_5_1=num_bytes +fan_speed.pola_5_1=negative +fan_speed.fpath_5_1= +fan_speed.addr_5_1=0x05000029 +fan_speed.len_5_1=2 +fan_speed.bit_offset_5_1= + +fan_speed.mode_6_0=config +fan_speed.int_cons_6_0= +fan_speed.src_6_0=cpld +fan_speed.frmt_6_0=num_bytes +fan_speed.pola_6_0=negative +fan_speed.fpath_6_0= +fan_speed.addr_6_0=0x0501001f +fan_speed.len_6_0=2 +fan_speed.bit_offset_6_0= + +fan_speed.mode_6_1=config +fan_speed.int_cons_6_1= +fan_speed.src_6_1=cpld +fan_speed.frmt_6_1=num_bytes +fan_speed.pola_6_1=negative +fan_speed.fpath_6_1= +fan_speed.addr_6_1=0x05010029 +fan_speed.len_6_1=2 +fan_speed.bit_offset_6_1= diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..ee060135ad6c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,118 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=4 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00010027 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00010027 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00010027 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00010028 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=0 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00010028 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=1 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00010028 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=2 + +# psu3 presence status +psu_status.mode_3_0=config +psu_status.src_3_0=cpld +psu_status.frmt_3_0=bit +psu_status.pola_3_0=negative +psu_status.addr_3_0=0x00010029 +psu_status.len_3_0=1 +psu_status.bit_offset_3_0=0 + +# psu3 output status +psu_status.mode_3_1=config +psu_status.src_3_1=cpld +psu_status.frmt_3_1=bit +psu_status.pola_3_1=positive +psu_status.addr_3_1=0x00010029 +psu_status.len_3_1=1 +psu_status.bit_offset_3_1=1 + +# psu3 alert status +psu_status.mode_3_2=config +psu_status.src_3_2=cpld +psu_status.frmt_3_2=bit +psu_status.pola_3_2=negative +psu_status.addr_3_2=0x00010029 +psu_status.len_3_2=1 +psu_status.bit_offset_3_2=2 + +# psu4 presence status +psu_status.mode_4_0=config +psu_status.src_4_0=cpld +psu_status.frmt_4_0=bit +psu_status.pola_4_0=negative +psu_status.addr_4_0=0x0001002a +psu_status.len_4_0=1 +psu_status.bit_offset_4_0=0 + +# psu4 output status +psu_status.mode_4_1=config +psu_status.src_4_1=cpld +psu_status.frmt_4_1=bit +psu_status.pola_4_1=positive +psu_status.addr_4_1=0x0001002a +psu_status.len_4_1=1 +psu_status.bit_offset_4_1=1 + +# psu4 alert status +psu_status.mode_4_2=config +psu_status.src_4_2=cpld +psu_status.frmt_4_2=bit +psu_status.pola_4_2=negative +psu_status.addr_4_2=0x0001002a +psu_status.len_4_2=1 +psu_status.bit_offset_4_2=2 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg new file mode 100755 index 000000000000..d16cafec6bc0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg @@ -0,0 +1,365 @@ +# Number of temperature sensors on the mainboard +dev_num_0_1=0 + +# Number of voltage sensors on the mainboard +dev_num_0_2=17 + +# Number of current sensors on the mainboard +dev_num_0_3=0 +#sensor in1 +hwmon_in.mode_0x0001_0x00=config +hwmon_in.int_cons_0x0001_0x00=0 +hwmon_in.src_0x0001_0x00=cpld +hwmon_in.frmt_0x0001_0x00=num_bytes +hwmon_in.addr_0x0001_0x00=0x000000a0 +hwmon_in.len_0x0001_0x00=2 +hwmon_in.int_extra1_0x0001_0x00=0x000000a4 +hwmon_in.int_extra2_0x0001_0x00=1240 + +hwmon_in.mode_0x0001_0x01=str_constant +hwmon_in.str_cons_0x0001_0x01=X86_BOARD_P5V_AUX_IN + +hwmon_in.mode_0x0001_0x02=str_constant +hwmon_in.str_cons_0x0001_0x02=cpld + +hwmon_in.mode_0x0001_0x03=str_constant +hwmon_in.str_cons_0x0001_0x03=5250 + +hwmon_in.mode_0x0001_0x05=str_constant +hwmon_in.str_cons_0x0001_0x05=4721 + +hwmon_in.mode_0x0002_0x00=config +hwmon_in.int_cons_0x0002_0x00=0 +hwmon_in.src_0x0002_0x00=cpld +hwmon_in.frmt_0x0002_0x00=num_bytes +hwmon_in.addr_0x0002_0x00=0x000000a2 +hwmon_in.len_0x0002_0x00=2 +hwmon_in.int_extra1_0x0002_0x00=0x000000a4 +hwmon_in.int_extra2_0x0002_0x00=1240 + +hwmon_in.mode_0x0002_0x01=str_constant +hwmon_in.str_cons_0x0002_0x01=X86_BOARD_P1V7_IN + +hwmon_in.mode_0x0002_0x02=str_constant +hwmon_in.str_cons_0x0002_0x02=cpld + +hwmon_in.mode_0x0002_0x03=str_constant +hwmon_in.str_cons_0x0002_0x03=1792 + +hwmon_in.mode_0x0002_0x05=str_constant +hwmon_in.str_cons_0x0002_0x05=1615 + +hwmon_in.mode_0x0003_0x00=config +hwmon_in.int_cons_0x0003_0x00=0 +hwmon_in.src_0x0003_0x00=cpld +hwmon_in.frmt_0x0003_0x00=num_bytes +hwmon_in.addr_0x0003_0x00=0x000000a4 +hwmon_in.len_0x0003_0x00=2 +hwmon_in.int_extra1_0x0003_0x00=0x000000a4 +hwmon_in.int_extra2_0x0003_0x00=2000 + +hwmon_in.mode_0x0003_0x01=str_constant +hwmon_in.str_cons_0x0003_0x01=X86_BOARD_TEST1v24 + +hwmon_in.mode_0x0003_0x02=str_constant +hwmon_in.str_cons_0x0003_0x02=cpld + +hwmon_in.mode_0x0003_0x03=str_constant +hwmon_in.str_cons_0x0003_0x03=1302 + +hwmon_in.mode_0x0003_0x05=str_constant +hwmon_in.str_cons_0x0003_0x05=1178 + +hwmon_in.mode_0x0004_0x00=config +hwmon_in.int_cons_0x0004_0x00=0 +hwmon_in.src_0x0004_0x00=cpld +hwmon_in.frmt_0x0004_0x00=num_bytes +hwmon_in.addr_0x0004_0x00=0x000000a6 +hwmon_in.len_0x0004_0x00=2 +hwmon_in.int_extra1_0x0004_0x00=0x000000a4 +hwmon_in.int_extra2_0x0004_0x00=1240 + +hwmon_in.mode_0x0004_0x01=str_constant +hwmon_in.str_cons_0x0004_0x01=X86_BOARD_P3V3_STBY_IN + +hwmon_in.mode_0x0004_0x02=str_constant +hwmon_in.str_cons_0x0004_0x02=cpld + +hwmon_in.mode_0x0004_0x03=str_constant +hwmon_in.str_cons_0x0004_0x03=3500 + +hwmon_in.mode_0x0004_0x05=str_constant +hwmon_in.str_cons_0x0004_0x05=3135 + +hwmon_in.mode_0x0005_0x00=config +hwmon_in.int_cons_0x0005_0x00=0 +hwmon_in.src_0x0005_0x00=cpld +hwmon_in.frmt_0x0005_0x00=num_bytes +hwmon_in.addr_0x0005_0x00=0x00020018 +hwmon_in.len_0x0005_0x00=2 +hwmon_in.int_extra1_0x0005_0x00=0x0002001c +hwmon_in.int_extra2_0x0005_0x00=1240 + +hwmon_in.mode_0x0005_0x01=str_constant +hwmon_in.str_cons_0x0005_0x01=MAC_BOARD_VDD1v8 + +hwmon_in.mode_0x0005_0x02=str_constant +hwmon_in.str_cons_0x0005_0x02=cpld + +hwmon_in.mode_0x0005_0x03=str_constant +hwmon_in.str_cons_0x0005_0x03=1909 + +hwmon_in.mode_0x0005_0x05=str_constant +hwmon_in.str_cons_0x0005_0x05=1710 + +hwmon_in.mode_0x0006_0x00=config +hwmon_in.int_cons_0x0006_0x00=0 +hwmon_in.src_0x0006_0x00=cpld +hwmon_in.frmt_0x0006_0x00=num_bytes +hwmon_in.addr_0x0006_0x00=0x0002001a +hwmon_in.len_0x0006_0x00=2 +hwmon_in.int_extra1_0x0006_0x00=0x0002001c +hwmon_in.int_extra2_0x0006_0x00=1240 + +hwmon_in.mode_0x0006_0x01=str_constant +hwmon_in.str_cons_0x0006_0x01=MAC_BOARD_SW_VDD1v2 + +hwmon_in.mode_0x0006_0x02=str_constant +hwmon_in.str_cons_0x0006_0x02=cpld + +hwmon_in.mode_0x0006_0x03=str_constant +hwmon_in.str_cons_0x0006_0x03=1286 + +hwmon_in.mode_0x0006_0x05=str_constant +hwmon_in.str_cons_0x0006_0x05=1140 + +hwmon_in.mode_0x0007_0x00=config +hwmon_in.int_cons_0x0007_0x00=0 +hwmon_in.src_0x0007_0x00=cpld +hwmon_in.frmt_0x0007_0x00=num_bytes +hwmon_in.addr_0x0007_0x00=0x0002001c +hwmon_in.len_0x0007_0x00=2 +hwmon_in.int_extra1_0x0007_0x00=0x0002001c +hwmon_in.int_extra2_0x0007_0x00=1000 + +hwmon_in.mode_0x0007_0x01=str_constant +hwmon_in.str_cons_0x0007_0x01=MAC_BOARD_TEST1v24 + +hwmon_in.mode_0x0007_0x02=str_constant +hwmon_in.str_cons_0x0007_0x02=cpld + +hwmon_in.mode_0x0007_0x03=str_constant +hwmon_in.str_cons_0x0007_0x03=1302 + +hwmon_in.mode_0x0007_0x05=str_constant +hwmon_in.str_cons_0x0007_0x05=1178 + +hwmon_in.mode_0x0008_0x00=config +hwmon_in.int_cons_0x0008_0x00=0 +hwmon_in.src_0x0008_0x00=cpld +hwmon_in.frmt_0x0008_0x00=num_bytes +hwmon_in.addr_0x0008_0x00=0x0002001e +hwmon_in.len_0x0008_0x00=2 +hwmon_in.int_extra1_0x0008_0x00=0x0002001c +hwmon_in.int_extra2_0x0008_0x00=1240 + +hwmon_in.mode_0x0008_0x01=str_constant +hwmon_in.str_cons_0x0008_0x01=MAC_BOARD_VDD1v2_MAC + +hwmon_in.mode_0x0008_0x02=str_constant +hwmon_in.str_cons_0x0008_0x02=cpld + +hwmon_in.mode_0x0008_0x03=str_constant +hwmon_in.str_cons_0x0008_0x03=1260 + +hwmon_in.mode_0x0008_0x05=str_constant +hwmon_in.str_cons_0x0008_0x05=1140 + +hwmon_in.mode_0x0009_0x00=config +hwmon_in.int_cons_0x0009_0x00=0 +hwmon_in.src_0x0009_0x00=cpld +hwmon_in.frmt_0x0009_0x00=num_bytes +hwmon_in.addr_0x0009_0x00=0x00020020 +hwmon_in.len_0x0009_0x00=2 +hwmon_in.int_extra1_0x0009_0x00=0x0002001c +hwmon_in.int_extra2_0x0009_0x00=1240 + +hwmon_in.mode_0x0009_0x01=str_constant +hwmon_in.str_cons_0x0009_0x01=MAC_BOARD_VDD_CORE + +hwmon_in.mode_0x0009_0x02=str_constant +hwmon_in.str_cons_0x0009_0x02=cpld + +hwmon_in.mode_0x0009_0x03=str_constant +hwmon_in.str_cons_0x0009_0x03=945 + +hwmon_in.mode_0x0009_0x05=str_constant +hwmon_in.str_cons_0x0009_0x05=712 + +hwmon_in.mode_0x000a_0x00=config +hwmon_in.int_cons_0x000a_0x00=0 +hwmon_in.src_0x000a_0x00=cpld +hwmon_in.frmt_0x000a_0x00=num_bytes +hwmon_in.addr_0x000a_0x00=0x00020022 +hwmon_in.len_0x000a_0x00=2 +hwmon_in.int_extra1_0x000a_0x00=0x0002001c +hwmon_in.int_extra2_0x000a_0x00=2480 + +hwmon_in.mode_0x000a_0x01=str_constant +hwmon_in.str_cons_0x000a_0x01=MAC_BOARD_VDD3v3_MCU + +hwmon_in.mode_0x000a_0x02=str_constant +hwmon_in.str_cons_0x000a_0x02=cpld + +hwmon_in.mode_0x000a_0x03=str_constant +hwmon_in.str_cons_0x000a_0x03=3556 + +hwmon_in.mode_0x000a_0x05=str_constant +hwmon_in.str_cons_0x000a_0x05=3135 + +hwmon_in.mode_0x000b_0x00=config +hwmon_in.int_cons_0x000b_0x00=0 +hwmon_in.src_0x000b_0x00=cpld +hwmon_in.frmt_0x000b_0x00=num_bytes +hwmon_in.addr_0x000b_0x00=0x00020024 +hwmon_in.len_0x000b_0x00=2 +hwmon_in.int_extra1_0x000b_0x00=0x0002001c +hwmon_in.int_extra2_0x000b_0x00=2480 + +hwmon_in.mode_0x000b_0x01=str_constant +hwmon_in.str_cons_0x000b_0x01=MAC_BOARD_VDD3v3_CLK + +hwmon_in.mode_0x000b_0x02=str_constant +hwmon_in.str_cons_0x000b_0x02=cpld + +hwmon_in.mode_0x000b_0x03=str_constant +hwmon_in.str_cons_0x000b_0x03=3556 + +hwmon_in.mode_0x000b_0x05=str_constant +hwmon_in.str_cons_0x000b_0x05=3135 + +hwmon_in.mode_0x000c_0x00=config +hwmon_in.int_cons_0x000c_0x00=0 +hwmon_in.src_0x000c_0x00=cpld +hwmon_in.frmt_0x000c_0x00=num_bytes +hwmon_in.addr_0x000c_0x00=0x00020026 +hwmon_in.len_0x000c_0x00=2 +hwmon_in.int_extra1_0x000c_0x00=0x0002001c +hwmon_in.int_extra2_0x000c_0x00=2480 + +hwmon_in.mode_0x000c_0x01=str_constant +hwmon_in.str_cons_0x000c_0x01=MAC_BOARD_VDD5V_CLK_MCU + +hwmon_in.mode_0x000c_0x02=str_constant +hwmon_in.str_cons_0x000c_0x02=cpld + +hwmon_in.mode_0x000c_0x03=str_constant +hwmon_in.str_cons_0x000c_0x03=5331 + +hwmon_in.mode_0x000c_0x05=str_constant +hwmon_in.str_cons_0x000c_0x05=4750 + +hwmon_in.mode_0x000d_0x00=config +hwmon_in.int_cons_0x000d_0x00=0 +hwmon_in.src_0x000d_0x00=cpld +hwmon_in.frmt_0x000d_0x00=num_bytes +hwmon_in.addr_0x000d_0x00=0x00020028 +hwmon_in.len_0x000d_0x00=2 +hwmon_in.int_extra1_0x000d_0x00=0x0002001c +hwmon_in.int_extra2_0x000d_0x00=2480 + +hwmon_in.mode_0x000d_0x01=str_constant +hwmon_in.str_cons_0x000d_0x01=MAC_BOARD_VDD2v5 + +hwmon_in.mode_0x000d_0x02=str_constant +hwmon_in.str_cons_0x000d_0x02=cpld + +hwmon_in.mode_0x000d_0x03=str_constant +hwmon_in.str_cons_0x000d_0x03=2688 + +hwmon_in.mode_0x000d_0x05=str_constant +hwmon_in.str_cons_0x000d_0x05=2375 + +hwmon_in.mode_0x000e_0x00=config +hwmon_in.int_cons_0x000e_0x00=0 +hwmon_in.src_0x000e_0x00=cpld +hwmon_in.frmt_0x000e_0x00=num_bytes +hwmon_in.addr_0x000e_0x00=0x0002002a +hwmon_in.len_0x000e_0x00=2 +hwmon_in.int_extra1_0x000e_0x00=0x0002001c +hwmon_in.int_extra2_0x000e_0x00=2480 + +hwmon_in.mode_0x000e_0x01=str_constant +hwmon_in.str_cons_0x000e_0x01=MAC_BOARD_VDDO + +hwmon_in.mode_0x000e_0x02=str_constant +hwmon_in.str_cons_0x000e_0x02=cpld + +hwmon_in.mode_0x000e_0x03=str_constant +hwmon_in.str_cons_0x000e_0x03=3542 + +hwmon_in.mode_0x000e_0x05=str_constant +hwmon_in.str_cons_0x000e_0x05=3135 + +hwmon_in.mode_0x000f_0x00=config +hwmon_in.int_cons_0x000f_0x00=0 +hwmon_in.src_0x000f_0x00=cpld +hwmon_in.frmt_0x000f_0x00=num_bytes +hwmon_in.addr_0x000f_0x00=0x0002002c +hwmon_in.len_0x000f_0x00=2 +hwmon_in.int_extra1_0x000f_0x00=0x0002001c +hwmon_in.int_extra2_0x000f_0x00=1240 + +hwmon_in.mode_0x000f_0x01=str_constant +hwmon_in.str_cons_0x000f_0x01=MAC_BOARD_BC_PVDD + +hwmon_in.mode_0x000f_0x02=str_constant +hwmon_in.str_cons_0x000f_0x02=cpld + +hwmon_in.mode_0x000f_0x03=str_constant +hwmon_in.str_cons_0x000f_0x03=867 + +hwmon_in.mode_0x000f_0x05=str_constant +hwmon_in.str_cons_0x000f_0x05=760 + +hwmon_in.mode_0x0010_0x00=config +hwmon_in.int_cons_0x0010_0x00=0 +hwmon_in.src_0x0010_0x00=cpld +hwmon_in.frmt_0x0010_0x00=num_bytes +hwmon_in.addr_0x0010_0x00=0x0002002e +hwmon_in.len_0x0010_0x00=2 +hwmon_in.int_extra1_0x0010_0x00=0x0002001c +hwmon_in.int_extra2_0x0010_0x00=2480 + +hwmon_in.mode_0x0010_0x01=str_constant +hwmon_in.str_cons_0x0010_0x01=MAC_BOARD_VDD3v3 + +hwmon_in.mode_0x0010_0x02=str_constant +hwmon_in.str_cons_0x0010_0x02=cpld + +hwmon_in.mode_0x0010_0x03=str_constant +hwmon_in.str_cons_0x0010_0x03=3542 + +hwmon_in.mode_0x0010_0x05=str_constant +hwmon_in.str_cons_0x0010_0x05=3135 + +hwmon_in.mode_0x0011_0x00=config +hwmon_in.int_cons_0x0011_0x00=0 +hwmon_in.src_0x0011_0x00=cpld +hwmon_in.frmt_0x0011_0x00=num_bytes +hwmon_in.addr_0x0011_0x00=0x00020030 +hwmon_in.len_0x0011_0x00=2 +hwmon_in.int_extra1_0x0011_0x00=0x0002001c +hwmon_in.int_extra2_0x0011_0x00=1240 + +hwmon_in.mode_0x0011_0x01=str_constant +hwmon_in.str_cons_0x0011_0x01=MAC_BOARD_ANLGOUT + +hwmon_in.mode_0x0011_0x02=str_constant +hwmon_in.str_cons_0x0011_0x02=cpld + +hwmon_in.mode_0x0011_0x03=str_constant +hwmon_in.str_cons_0x0011_0x03=856 + +hwmon_in.mode_0x0011_0x05=str_constant +hwmon_in.str_cons_0x0011_0x05=760 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..7fa47c217e89 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,1169 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=128 + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 +sff_dir_name_33 =sff33 +sff_dir_name_34 =sff34 +sff_dir_name_35 =sff35 +sff_dir_name_36 =sff36 +sff_dir_name_37 =sff37 +sff_dir_name_38 =sff38 +sff_dir_name_39 =sff39 +sff_dir_name_40 =sff40 +sff_dir_name_41 =sff41 +sff_dir_name_42 =sff42 +sff_dir_name_43 =sff43 +sff_dir_name_44 =sff44 +sff_dir_name_45 =sff45 +sff_dir_name_46 =sff46 +sff_dir_name_47 =sff47 +sff_dir_name_48 =sff48 +sff_dir_name_49 =sff49 +sff_dir_name_50 =sff50 +sff_dir_name_51 =sff51 +sff_dir_name_52 =sff52 +sff_dir_name_53 =sff53 +sff_dir_name_54 =sff54 +sff_dir_name_55 =sff55 +sff_dir_name_56 =sff56 +sff_dir_name_57 =sff57 +sff_dir_name_58 =sff58 +sff_dir_name_59 =sff59 +sff_dir_name_60 =sff60 +sff_dir_name_61 =sff61 +sff_dir_name_62 =sff62 +sff_dir_name_63 =sff63 +sff_dir_name_64 =sff64 +sff_dir_name_65 =sff65 +sff_dir_name_66 =sff66 +sff_dir_name_67 =sff67 +sff_dir_name_68 =sff68 +sff_dir_name_69 =sff69 +sff_dir_name_70 =sff70 +sff_dir_name_71 =sff71 +sff_dir_name_72 =sff72 +sff_dir_name_73 =sff73 +sff_dir_name_74 =sff74 +sff_dir_name_75 =sff75 +sff_dir_name_76 =sff76 +sff_dir_name_77 =sff77 +sff_dir_name_78 =sff78 +sff_dir_name_79 =sff79 +sff_dir_name_80 =sff80 +sff_dir_name_81 =sff81 +sff_dir_name_82 =sff82 +sff_dir_name_83 =sff83 +sff_dir_name_84 =sff84 +sff_dir_name_85 =sff85 +sff_dir_name_86 =sff86 +sff_dir_name_87 =sff87 +sff_dir_name_88 =sff88 +sff_dir_name_89 =sff89 +sff_dir_name_90 =sff90 +sff_dir_name_91 =sff91 +sff_dir_name_92 =sff92 +sff_dir_name_93 =sff93 +sff_dir_name_94 =sff94 +sff_dir_name_95 =sff95 +sff_dir_name_96 =sff96 +sff_dir_name_97 =sff97 +sff_dir_name_98 =sff98 +sff_dir_name_99 =sff99 +sff_dir_name_100 =sff100 +sff_dir_name_101 =sff101 +sff_dir_name_102 =sff102 +sff_dir_name_103 =sff103 +sff_dir_name_104 =sff104 +sff_dir_name_105 =sff105 +sff_dir_name_106 =sff106 +sff_dir_name_107 =sff107 +sff_dir_name_108 =sff108 +sff_dir_name_109 =sff109 +sff_dir_name_110 =sff110 +sff_dir_name_111 =sff111 +sff_dir_name_112 =sff112 +sff_dir_name_113 =sff113 +sff_dir_name_114 =sff114 +sff_dir_name_115 =sff115 +sff_dir_name_116 =sff116 +sff_dir_name_117 =sff117 +sff_dir_name_118 =sff118 +sff_dir_name_119 =sff119 +sff_dir_name_120 =sff120 +sff_dir_name_121 =sff121 +sff_dir_name_122 =sff122 +sff_dir_name_123 =sff123 +sff_dir_name_124 =sff124 +sff_dir_name_125 =sff125 +sff_dir_name_126 =sff126 +sff_dir_name_127 =sff127 +sff_dir_name_128 =sff128 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x01010010 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x01010010 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x01010010 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x01010010 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x01010010 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x01010010 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x01010010 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x01010010 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x01010011 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x01010011 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x01010011 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x01010011 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x01010011 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x01010011 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x01010011 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x01010011 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x01000010 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x01000010 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x01000010 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x01000010 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x01000010 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x01000010 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x01000010 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x01000010 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x01000011 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x01000011 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x01000011 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x01000011 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x01000011 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x01000011 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x01000011 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x01000011 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +sff_cpld_reg.mode_33_8=config +sff_cpld_reg.src_33_8=cpld +sff_cpld_reg.frmt_33_8=bit +sff_cpld_reg.pola_33_8=negative +sff_cpld_reg.addr_33_8=0x02010010 +sff_cpld_reg.len_33_8=1 +sff_cpld_reg.bit_offset_33_8=0 + +sff_cpld_reg.mode_34_8=config +sff_cpld_reg.src_34_8=cpld +sff_cpld_reg.frmt_34_8=bit +sff_cpld_reg.pola_34_8=negative +sff_cpld_reg.addr_34_8=0x02010010 +sff_cpld_reg.len_34_8=1 +sff_cpld_reg.bit_offset_34_8=1 + +sff_cpld_reg.mode_35_8=config +sff_cpld_reg.src_35_8=cpld +sff_cpld_reg.frmt_35_8=bit +sff_cpld_reg.pola_35_8=negative +sff_cpld_reg.addr_35_8=0x02010010 +sff_cpld_reg.len_35_8=1 +sff_cpld_reg.bit_offset_35_8=2 + +sff_cpld_reg.mode_36_8=config +sff_cpld_reg.src_36_8=cpld +sff_cpld_reg.frmt_36_8=bit +sff_cpld_reg.pola_36_8=negative +sff_cpld_reg.addr_36_8=0x02010010 +sff_cpld_reg.len_36_8=1 +sff_cpld_reg.bit_offset_36_8=3 + +sff_cpld_reg.mode_37_8=config +sff_cpld_reg.src_37_8=cpld +sff_cpld_reg.frmt_37_8=bit +sff_cpld_reg.pola_37_8=negative +sff_cpld_reg.addr_37_8=0x02010010 +sff_cpld_reg.len_37_8=1 +sff_cpld_reg.bit_offset_37_8=4 + +sff_cpld_reg.mode_38_8=config +sff_cpld_reg.src_38_8=cpld +sff_cpld_reg.frmt_38_8=bit +sff_cpld_reg.pola_38_8=negative +sff_cpld_reg.addr_38_8=0x02010010 +sff_cpld_reg.len_38_8=1 +sff_cpld_reg.bit_offset_38_8=5 + +sff_cpld_reg.mode_39_8=config +sff_cpld_reg.src_39_8=cpld +sff_cpld_reg.frmt_39_8=bit +sff_cpld_reg.pola_39_8=negative +sff_cpld_reg.addr_39_8=0x02010010 +sff_cpld_reg.len_39_8=1 +sff_cpld_reg.bit_offset_39_8=6 + +sff_cpld_reg.mode_40_8=config +sff_cpld_reg.src_40_8=cpld +sff_cpld_reg.frmt_40_8=bit +sff_cpld_reg.pola_40_8=negative +sff_cpld_reg.addr_40_8=0x02010010 +sff_cpld_reg.len_40_8=1 +sff_cpld_reg.bit_offset_40_8=7 + +sff_cpld_reg.mode_41_8=config +sff_cpld_reg.src_41_8=cpld +sff_cpld_reg.frmt_41_8=bit +sff_cpld_reg.pola_41_8=negative +sff_cpld_reg.addr_41_8=0x02010011 +sff_cpld_reg.len_41_8=1 +sff_cpld_reg.bit_offset_41_8=0 + +sff_cpld_reg.mode_42_8=config +sff_cpld_reg.src_42_8=cpld +sff_cpld_reg.frmt_42_8=bit +sff_cpld_reg.pola_42_8=negative +sff_cpld_reg.addr_42_8=0x02010011 +sff_cpld_reg.len_42_8=1 +sff_cpld_reg.bit_offset_42_8=1 + +sff_cpld_reg.mode_43_8=config +sff_cpld_reg.src_43_8=cpld +sff_cpld_reg.frmt_43_8=bit +sff_cpld_reg.pola_43_8=negative +sff_cpld_reg.addr_43_8=0x02010011 +sff_cpld_reg.len_43_8=1 +sff_cpld_reg.bit_offset_43_8=2 + +sff_cpld_reg.mode_44_8=config +sff_cpld_reg.src_44_8=cpld +sff_cpld_reg.frmt_44_8=bit +sff_cpld_reg.pola_44_8=negative +sff_cpld_reg.addr_44_8=0x02010011 +sff_cpld_reg.len_44_8=1 +sff_cpld_reg.bit_offset_44_8=3 + +sff_cpld_reg.mode_45_8=config +sff_cpld_reg.src_45_8=cpld +sff_cpld_reg.frmt_45_8=bit +sff_cpld_reg.pola_45_8=negative +sff_cpld_reg.addr_45_8=0x02010011 +sff_cpld_reg.len_45_8=1 +sff_cpld_reg.bit_offset_45_8=4 + +sff_cpld_reg.mode_46_8=config +sff_cpld_reg.src_46_8=cpld +sff_cpld_reg.frmt_46_8=bit +sff_cpld_reg.pola_46_8=negative +sff_cpld_reg.addr_46_8=0x02010011 +sff_cpld_reg.len_46_8=1 +sff_cpld_reg.bit_offset_46_8=5 + +sff_cpld_reg.mode_47_8=config +sff_cpld_reg.src_47_8=cpld +sff_cpld_reg.frmt_47_8=bit +sff_cpld_reg.pola_47_8=negative +sff_cpld_reg.addr_47_8=0x02010011 +sff_cpld_reg.len_47_8=1 +sff_cpld_reg.bit_offset_47_8=6 + +sff_cpld_reg.mode_48_8=config +sff_cpld_reg.src_48_8=cpld +sff_cpld_reg.frmt_48_8=bit +sff_cpld_reg.pola_48_8=negative +sff_cpld_reg.addr_48_8=0x02010011 +sff_cpld_reg.len_48_8=1 +sff_cpld_reg.bit_offset_48_8=7 + +sff_cpld_reg.mode_49_8=config +sff_cpld_reg.src_49_8=cpld +sff_cpld_reg.frmt_49_8=bit +sff_cpld_reg.pola_49_8=negative +sff_cpld_reg.addr_49_8=0x02000010 +sff_cpld_reg.len_49_8=1 +sff_cpld_reg.bit_offset_49_8=0 + +sff_cpld_reg.mode_50_8=config +sff_cpld_reg.src_50_8=cpld +sff_cpld_reg.frmt_50_8=bit +sff_cpld_reg.pola_50_8=negative +sff_cpld_reg.addr_50_8=0x02000010 +sff_cpld_reg.len_50_8=1 +sff_cpld_reg.bit_offset_50_8=1 + +sff_cpld_reg.mode_51_8=config +sff_cpld_reg.src_51_8=cpld +sff_cpld_reg.frmt_51_8=bit +sff_cpld_reg.pola_51_8=negative +sff_cpld_reg.addr_51_8=0x02000010 +sff_cpld_reg.len_51_8=1 +sff_cpld_reg.bit_offset_51_8=2 + +sff_cpld_reg.mode_52_8=config +sff_cpld_reg.src_52_8=cpld +sff_cpld_reg.frmt_52_8=bit +sff_cpld_reg.pola_52_8=negative +sff_cpld_reg.addr_52_8=0x02000010 +sff_cpld_reg.len_52_8=1 +sff_cpld_reg.bit_offset_52_8=3 + +sff_cpld_reg.mode_53_8=config +sff_cpld_reg.src_53_8=cpld +sff_cpld_reg.frmt_53_8=bit +sff_cpld_reg.pola_53_8=negative +sff_cpld_reg.addr_53_8=0x02000010 +sff_cpld_reg.len_53_8=1 +sff_cpld_reg.bit_offset_53_8=4 + +sff_cpld_reg.mode_54_8=config +sff_cpld_reg.src_54_8=cpld +sff_cpld_reg.frmt_54_8=bit +sff_cpld_reg.pola_54_8=negative +sff_cpld_reg.addr_54_8=0x02000010 +sff_cpld_reg.len_54_8=1 +sff_cpld_reg.bit_offset_54_8=5 + +sff_cpld_reg.mode_55_8=config +sff_cpld_reg.src_55_8=cpld +sff_cpld_reg.frmt_55_8=bit +sff_cpld_reg.pola_55_8=negative +sff_cpld_reg.addr_55_8=0x02000010 +sff_cpld_reg.len_55_8=1 +sff_cpld_reg.bit_offset_55_8=6 + +sff_cpld_reg.mode_56_8=config +sff_cpld_reg.src_56_8=cpld +sff_cpld_reg.frmt_56_8=bit +sff_cpld_reg.pola_56_8=negative +sff_cpld_reg.addr_56_8=0x02000010 +sff_cpld_reg.len_56_8=1 +sff_cpld_reg.bit_offset_56_8=7 + +sff_cpld_reg.mode_57_8=config +sff_cpld_reg.src_57_8=cpld +sff_cpld_reg.frmt_57_8=bit +sff_cpld_reg.pola_57_8=negative +sff_cpld_reg.addr_57_8=0x02000011 +sff_cpld_reg.len_57_8=1 +sff_cpld_reg.bit_offset_57_8=0 + +sff_cpld_reg.mode_58_8=config +sff_cpld_reg.src_58_8=cpld +sff_cpld_reg.frmt_58_8=bit +sff_cpld_reg.pola_58_8=negative +sff_cpld_reg.addr_58_8=0x02000011 +sff_cpld_reg.len_58_8=1 +sff_cpld_reg.bit_offset_58_8=1 + +sff_cpld_reg.mode_59_8=config +sff_cpld_reg.src_59_8=cpld +sff_cpld_reg.frmt_59_8=bit +sff_cpld_reg.pola_59_8=negative +sff_cpld_reg.addr_59_8=0x02000011 +sff_cpld_reg.len_59_8=1 +sff_cpld_reg.bit_offset_59_8=2 + +sff_cpld_reg.mode_60_8=config +sff_cpld_reg.src_60_8=cpld +sff_cpld_reg.frmt_60_8=bit +sff_cpld_reg.pola_60_8=negative +sff_cpld_reg.addr_60_8=0x02000011 +sff_cpld_reg.len_60_8=1 +sff_cpld_reg.bit_offset_60_8=3 + +sff_cpld_reg.mode_61_8=config +sff_cpld_reg.src_61_8=cpld +sff_cpld_reg.frmt_61_8=bit +sff_cpld_reg.pola_61_8=negative +sff_cpld_reg.addr_61_8=0x02000011 +sff_cpld_reg.len_61_8=1 +sff_cpld_reg.bit_offset_61_8=4 + +sff_cpld_reg.mode_62_8=config +sff_cpld_reg.src_62_8=cpld +sff_cpld_reg.frmt_62_8=bit +sff_cpld_reg.pola_62_8=negative +sff_cpld_reg.addr_62_8=0x02000011 +sff_cpld_reg.len_62_8=1 +sff_cpld_reg.bit_offset_62_8=5 + +sff_cpld_reg.mode_63_8=config +sff_cpld_reg.src_63_8=cpld +sff_cpld_reg.frmt_63_8=bit +sff_cpld_reg.pola_63_8=negative +sff_cpld_reg.addr_63_8=0x02000011 +sff_cpld_reg.len_63_8=1 +sff_cpld_reg.bit_offset_63_8=6 + +sff_cpld_reg.mode_64_8=config +sff_cpld_reg.src_64_8=cpld +sff_cpld_reg.frmt_64_8=bit +sff_cpld_reg.pola_64_8=negative +sff_cpld_reg.addr_64_8=0x02000011 +sff_cpld_reg.len_64_8=1 +sff_cpld_reg.bit_offset_64_8=7 + +sff_cpld_reg.mode_65_8=config +sff_cpld_reg.src_65_8=cpld +sff_cpld_reg.frmt_65_8=bit +sff_cpld_reg.pola_65_8=negative +sff_cpld_reg.addr_65_8=0x03010010 +sff_cpld_reg.len_65_8=1 +sff_cpld_reg.bit_offset_65_8=0 + +sff_cpld_reg.mode_66_8=config +sff_cpld_reg.src_66_8=cpld +sff_cpld_reg.frmt_66_8=bit +sff_cpld_reg.pola_66_8=negative +sff_cpld_reg.addr_66_8=0x03010010 +sff_cpld_reg.len_66_8=1 +sff_cpld_reg.bit_offset_66_8=1 + +sff_cpld_reg.mode_67_8=config +sff_cpld_reg.src_67_8=cpld +sff_cpld_reg.frmt_67_8=bit +sff_cpld_reg.pola_67_8=negative +sff_cpld_reg.addr_67_8=0x03010010 +sff_cpld_reg.len_67_8=1 +sff_cpld_reg.bit_offset_67_8=2 + +sff_cpld_reg.mode_68_8=config +sff_cpld_reg.src_68_8=cpld +sff_cpld_reg.frmt_68_8=bit +sff_cpld_reg.pola_68_8=negative +sff_cpld_reg.addr_68_8=0x03010010 +sff_cpld_reg.len_68_8=1 +sff_cpld_reg.bit_offset_68_8=3 + +sff_cpld_reg.mode_69_8=config +sff_cpld_reg.src_69_8=cpld +sff_cpld_reg.frmt_69_8=bit +sff_cpld_reg.pola_69_8=negative +sff_cpld_reg.addr_69_8=0x03010010 +sff_cpld_reg.len_69_8=1 +sff_cpld_reg.bit_offset_69_8=4 + +sff_cpld_reg.mode_70_8=config +sff_cpld_reg.src_70_8=cpld +sff_cpld_reg.frmt_70_8=bit +sff_cpld_reg.pola_70_8=negative +sff_cpld_reg.addr_70_8=0x03010010 +sff_cpld_reg.len_70_8=1 +sff_cpld_reg.bit_offset_70_8=5 + +sff_cpld_reg.mode_71_8=config +sff_cpld_reg.src_71_8=cpld +sff_cpld_reg.frmt_71_8=bit +sff_cpld_reg.pola_71_8=negative +sff_cpld_reg.addr_71_8=0x03010010 +sff_cpld_reg.len_71_8=1 +sff_cpld_reg.bit_offset_71_8=6 + +sff_cpld_reg.mode_72_8=config +sff_cpld_reg.src_72_8=cpld +sff_cpld_reg.frmt_72_8=bit +sff_cpld_reg.pola_72_8=negative +sff_cpld_reg.addr_72_8=0x03010010 +sff_cpld_reg.len_72_8=1 +sff_cpld_reg.bit_offset_72_8=7 + +sff_cpld_reg.mode_73_8=config +sff_cpld_reg.src_73_8=cpld +sff_cpld_reg.frmt_73_8=bit +sff_cpld_reg.pola_73_8=negative +sff_cpld_reg.addr_73_8=0x03010011 +sff_cpld_reg.len_73_8=1 +sff_cpld_reg.bit_offset_73_8=0 + +sff_cpld_reg.mode_74_8=config +sff_cpld_reg.src_74_8=cpld +sff_cpld_reg.frmt_74_8=bit +sff_cpld_reg.pola_74_8=negative +sff_cpld_reg.addr_74_8=0x03010011 +sff_cpld_reg.len_74_8=1 +sff_cpld_reg.bit_offset_74_8=1 + +sff_cpld_reg.mode_75_8=config +sff_cpld_reg.src_75_8=cpld +sff_cpld_reg.frmt_75_8=bit +sff_cpld_reg.pola_75_8=negative +sff_cpld_reg.addr_75_8=0x03010011 +sff_cpld_reg.len_75_8=1 +sff_cpld_reg.bit_offset_75_8=2 + +sff_cpld_reg.mode_76_8=config +sff_cpld_reg.src_76_8=cpld +sff_cpld_reg.frmt_76_8=bit +sff_cpld_reg.pola_76_8=negative +sff_cpld_reg.addr_76_8=0x03010011 +sff_cpld_reg.len_76_8=1 +sff_cpld_reg.bit_offset_76_8=3 + +sff_cpld_reg.mode_77_8=config +sff_cpld_reg.src_77_8=cpld +sff_cpld_reg.frmt_77_8=bit +sff_cpld_reg.pola_77_8=negative +sff_cpld_reg.addr_77_8=0x03010011 +sff_cpld_reg.len_77_8=1 +sff_cpld_reg.bit_offset_77_8=4 + +sff_cpld_reg.mode_78_8=config +sff_cpld_reg.src_78_8=cpld +sff_cpld_reg.frmt_78_8=bit +sff_cpld_reg.pola_78_8=negative +sff_cpld_reg.addr_78_8=0x03010011 +sff_cpld_reg.len_78_8=1 +sff_cpld_reg.bit_offset_78_8=5 + +sff_cpld_reg.mode_79_8=config +sff_cpld_reg.src_79_8=cpld +sff_cpld_reg.frmt_79_8=bit +sff_cpld_reg.pola_79_8=negative +sff_cpld_reg.addr_79_8=0x03010011 +sff_cpld_reg.len_79_8=1 +sff_cpld_reg.bit_offset_79_8=6 + +sff_cpld_reg.mode_80_8=config +sff_cpld_reg.src_80_8=cpld +sff_cpld_reg.frmt_80_8=bit +sff_cpld_reg.pola_80_8=negative +sff_cpld_reg.addr_80_8=0x03010011 +sff_cpld_reg.len_80_8=1 +sff_cpld_reg.bit_offset_80_8=7 + +sff_cpld_reg.mode_81_8=config +sff_cpld_reg.src_81_8=cpld +sff_cpld_reg.frmt_81_8=bit +sff_cpld_reg.pola_81_8=negative +sff_cpld_reg.addr_81_8=0x03000010 +sff_cpld_reg.len_81_8=1 +sff_cpld_reg.bit_offset_81_8=0 + +sff_cpld_reg.mode_82_8=config +sff_cpld_reg.src_82_8=cpld +sff_cpld_reg.frmt_82_8=bit +sff_cpld_reg.pola_82_8=negative +sff_cpld_reg.addr_82_8=0x03000010 +sff_cpld_reg.len_82_8=1 +sff_cpld_reg.bit_offset_82_8=1 + +sff_cpld_reg.mode_83_8=config +sff_cpld_reg.src_83_8=cpld +sff_cpld_reg.frmt_83_8=bit +sff_cpld_reg.pola_83_8=negative +sff_cpld_reg.addr_83_8=0x03000010 +sff_cpld_reg.len_83_8=1 +sff_cpld_reg.bit_offset_83_8=2 + +sff_cpld_reg.mode_84_8=config +sff_cpld_reg.src_84_8=cpld +sff_cpld_reg.frmt_84_8=bit +sff_cpld_reg.pola_84_8=negative +sff_cpld_reg.addr_84_8=0x03000010 +sff_cpld_reg.len_84_8=1 +sff_cpld_reg.bit_offset_84_8=3 + +sff_cpld_reg.mode_85_8=config +sff_cpld_reg.src_85_8=cpld +sff_cpld_reg.frmt_85_8=bit +sff_cpld_reg.pola_85_8=negative +sff_cpld_reg.addr_85_8=0x03000010 +sff_cpld_reg.len_85_8=1 +sff_cpld_reg.bit_offset_85_8=4 + +sff_cpld_reg.mode_86_8=config +sff_cpld_reg.src_86_8=cpld +sff_cpld_reg.frmt_86_8=bit +sff_cpld_reg.pola_86_8=negative +sff_cpld_reg.addr_86_8=0x03000010 +sff_cpld_reg.len_86_8=1 +sff_cpld_reg.bit_offset_86_8=5 + +sff_cpld_reg.mode_87_8=config +sff_cpld_reg.src_87_8=cpld +sff_cpld_reg.frmt_87_8=bit +sff_cpld_reg.pola_87_8=negative +sff_cpld_reg.addr_87_8=0x03000010 +sff_cpld_reg.len_87_8=1 +sff_cpld_reg.bit_offset_87_8=6 + +sff_cpld_reg.mode_88_8=config +sff_cpld_reg.src_88_8=cpld +sff_cpld_reg.frmt_88_8=bit +sff_cpld_reg.pola_88_8=negative +sff_cpld_reg.addr_88_8=0x03000010 +sff_cpld_reg.len_88_8=1 +sff_cpld_reg.bit_offset_88_8=7 + +sff_cpld_reg.mode_89_8=config +sff_cpld_reg.src_89_8=cpld +sff_cpld_reg.frmt_89_8=bit +sff_cpld_reg.pola_89_8=negative +sff_cpld_reg.addr_89_8=0x03000011 +sff_cpld_reg.len_89_8=1 +sff_cpld_reg.bit_offset_89_8=0 + +sff_cpld_reg.mode_90_8=config +sff_cpld_reg.src_90_8=cpld +sff_cpld_reg.frmt_90_8=bit +sff_cpld_reg.pola_90_8=negative +sff_cpld_reg.addr_90_8=0x03000011 +sff_cpld_reg.len_90_8=1 +sff_cpld_reg.bit_offset_90_8=1 + +sff_cpld_reg.mode_91_8=config +sff_cpld_reg.src_91_8=cpld +sff_cpld_reg.frmt_91_8=bit +sff_cpld_reg.pola_91_8=negative +sff_cpld_reg.addr_91_8=0x03000011 +sff_cpld_reg.len_91_8=1 +sff_cpld_reg.bit_offset_91_8=2 + +sff_cpld_reg.mode_92_8=config +sff_cpld_reg.src_92_8=cpld +sff_cpld_reg.frmt_92_8=bit +sff_cpld_reg.pola_92_8=negative +sff_cpld_reg.addr_92_8=0x03000011 +sff_cpld_reg.len_92_8=1 +sff_cpld_reg.bit_offset_92_8=3 + +sff_cpld_reg.mode_93_8=config +sff_cpld_reg.src_93_8=cpld +sff_cpld_reg.frmt_93_8=bit +sff_cpld_reg.pola_93_8=negative +sff_cpld_reg.addr_93_8=0x03000011 +sff_cpld_reg.len_93_8=1 +sff_cpld_reg.bit_offset_93_8=4 + +sff_cpld_reg.mode_94_8=config +sff_cpld_reg.src_94_8=cpld +sff_cpld_reg.frmt_94_8=bit +sff_cpld_reg.pola_94_8=negative +sff_cpld_reg.addr_94_8=0x03000011 +sff_cpld_reg.len_94_8=1 +sff_cpld_reg.bit_offset_94_8=5 + +sff_cpld_reg.mode_95_8=config +sff_cpld_reg.src_95_8=cpld +sff_cpld_reg.frmt_95_8=bit +sff_cpld_reg.pola_95_8=negative +sff_cpld_reg.addr_95_8=0x03000011 +sff_cpld_reg.len_95_8=1 +sff_cpld_reg.bit_offset_95_8=6 + +sff_cpld_reg.mode_96_8=config +sff_cpld_reg.src_96_8=cpld +sff_cpld_reg.frmt_96_8=bit +sff_cpld_reg.pola_96_8=negative +sff_cpld_reg.addr_96_8=0x03000011 +sff_cpld_reg.len_96_8=1 +sff_cpld_reg.bit_offset_96_8=7 + +sff_cpld_reg.mode_97_8=config +sff_cpld_reg.src_97_8=cpld +sff_cpld_reg.frmt_97_8=bit +sff_cpld_reg.pola_97_8=negative +sff_cpld_reg.addr_97_8=0x04010010 +sff_cpld_reg.len_97_8=1 +sff_cpld_reg.bit_offset_97_8=0 + +sff_cpld_reg.mode_98_8=config +sff_cpld_reg.src_98_8=cpld +sff_cpld_reg.frmt_98_8=bit +sff_cpld_reg.pola_98_8=negative +sff_cpld_reg.addr_98_8=0x04010010 +sff_cpld_reg.len_98_8=1 +sff_cpld_reg.bit_offset_98_8=1 + +sff_cpld_reg.mode_99_8=config +sff_cpld_reg.src_99_8=cpld +sff_cpld_reg.frmt_99_8=bit +sff_cpld_reg.pola_99_8=negative +sff_cpld_reg.addr_99_8=0x04010010 +sff_cpld_reg.len_99_8=1 +sff_cpld_reg.bit_offset_99_8=2 + +sff_cpld_reg.mode_100_8=config +sff_cpld_reg.src_100_8=cpld +sff_cpld_reg.frmt_100_8=bit +sff_cpld_reg.pola_100_8=negative +sff_cpld_reg.addr_100_8=0x04010010 +sff_cpld_reg.len_100_8=1 +sff_cpld_reg.bit_offset_100_8=3 + +sff_cpld_reg.mode_101_8=config +sff_cpld_reg.src_101_8=cpld +sff_cpld_reg.frmt_101_8=bit +sff_cpld_reg.pola_101_8=negative +sff_cpld_reg.addr_101_8=0x04010010 +sff_cpld_reg.len_101_8=1 +sff_cpld_reg.bit_offset_101_8=4 + +sff_cpld_reg.mode_102_8=config +sff_cpld_reg.src_102_8=cpld +sff_cpld_reg.frmt_102_8=bit +sff_cpld_reg.pola_102_8=negative +sff_cpld_reg.addr_102_8=0x04010010 +sff_cpld_reg.len_102_8=1 +sff_cpld_reg.bit_offset_102_8=5 + +sff_cpld_reg.mode_103_8=config +sff_cpld_reg.src_103_8=cpld +sff_cpld_reg.frmt_103_8=bit +sff_cpld_reg.pola_103_8=negative +sff_cpld_reg.addr_103_8=0x04010010 +sff_cpld_reg.len_103_8=1 +sff_cpld_reg.bit_offset_103_8=6 + +sff_cpld_reg.mode_104_8=config +sff_cpld_reg.src_104_8=cpld +sff_cpld_reg.frmt_104_8=bit +sff_cpld_reg.pola_104_8=negative +sff_cpld_reg.addr_104_8=0x04010010 +sff_cpld_reg.len_104_8=1 +sff_cpld_reg.bit_offset_104_8=7 + +sff_cpld_reg.mode_105_8=config +sff_cpld_reg.src_105_8=cpld +sff_cpld_reg.frmt_105_8=bit +sff_cpld_reg.pola_105_8=negative +sff_cpld_reg.addr_105_8=0x04010011 +sff_cpld_reg.len_105_8=1 +sff_cpld_reg.bit_offset_105_8=0 + +sff_cpld_reg.mode_106_8=config +sff_cpld_reg.src_106_8=cpld +sff_cpld_reg.frmt_106_8=bit +sff_cpld_reg.pola_106_8=negative +sff_cpld_reg.addr_106_8=0x04010011 +sff_cpld_reg.len_106_8=1 +sff_cpld_reg.bit_offset_106_8=1 + +sff_cpld_reg.mode_107_8=config +sff_cpld_reg.src_107_8=cpld +sff_cpld_reg.frmt_107_8=bit +sff_cpld_reg.pola_107_8=negative +sff_cpld_reg.addr_107_8=0x04010011 +sff_cpld_reg.len_107_8=1 +sff_cpld_reg.bit_offset_107_8=2 + +sff_cpld_reg.mode_108_8=config +sff_cpld_reg.src_108_8=cpld +sff_cpld_reg.frmt_108_8=bit +sff_cpld_reg.pola_108_8=negative +sff_cpld_reg.addr_108_8=0x04010011 +sff_cpld_reg.len_108_8=1 +sff_cpld_reg.bit_offset_108_8=3 + +sff_cpld_reg.mode_109_8=config +sff_cpld_reg.src_109_8=cpld +sff_cpld_reg.frmt_109_8=bit +sff_cpld_reg.pola_109_8=negative +sff_cpld_reg.addr_109_8=0x04010011 +sff_cpld_reg.len_109_8=1 +sff_cpld_reg.bit_offset_109_8=4 + +sff_cpld_reg.mode_110_8=config +sff_cpld_reg.src_110_8=cpld +sff_cpld_reg.frmt_110_8=bit +sff_cpld_reg.pola_110_8=negative +sff_cpld_reg.addr_110_8=0x04010011 +sff_cpld_reg.len_110_8=1 +sff_cpld_reg.bit_offset_110_8=5 + +sff_cpld_reg.mode_111_8=config +sff_cpld_reg.src_111_8=cpld +sff_cpld_reg.frmt_111_8=bit +sff_cpld_reg.pola_111_8=negative +sff_cpld_reg.addr_111_8=0x04010011 +sff_cpld_reg.len_111_8=1 +sff_cpld_reg.bit_offset_111_8=6 + +sff_cpld_reg.mode_112_8=config +sff_cpld_reg.src_112_8=cpld +sff_cpld_reg.frmt_112_8=bit +sff_cpld_reg.pola_112_8=negative +sff_cpld_reg.addr_112_8=0x04010011 +sff_cpld_reg.len_112_8=1 +sff_cpld_reg.bit_offset_112_8=7 + +sff_cpld_reg.mode_113_8=config +sff_cpld_reg.src_113_8=cpld +sff_cpld_reg.frmt_113_8=bit +sff_cpld_reg.pola_113_8=negative +sff_cpld_reg.addr_113_8=0x04000010 +sff_cpld_reg.len_113_8=1 +sff_cpld_reg.bit_offset_113_8=0 + +sff_cpld_reg.mode_114_8=config +sff_cpld_reg.src_114_8=cpld +sff_cpld_reg.frmt_114_8=bit +sff_cpld_reg.pola_114_8=negative +sff_cpld_reg.addr_114_8=0x04000010 +sff_cpld_reg.len_114_8=1 +sff_cpld_reg.bit_offset_114_8=1 + +sff_cpld_reg.mode_115_8=config +sff_cpld_reg.src_115_8=cpld +sff_cpld_reg.frmt_115_8=bit +sff_cpld_reg.pola_115_8=negative +sff_cpld_reg.addr_115_8=0x04000010 +sff_cpld_reg.len_115_8=1 +sff_cpld_reg.bit_offset_115_8=2 + +sff_cpld_reg.mode_116_8=config +sff_cpld_reg.src_116_8=cpld +sff_cpld_reg.frmt_116_8=bit +sff_cpld_reg.pola_116_8=negative +sff_cpld_reg.addr_116_8=0x04000010 +sff_cpld_reg.len_116_8=1 +sff_cpld_reg.bit_offset_116_8=3 + +sff_cpld_reg.mode_117_8=config +sff_cpld_reg.src_117_8=cpld +sff_cpld_reg.frmt_117_8=bit +sff_cpld_reg.pola_117_8=negative +sff_cpld_reg.addr_117_8=0x04000010 +sff_cpld_reg.len_117_8=1 +sff_cpld_reg.bit_offset_117_8=4 + +sff_cpld_reg.mode_118_8=config +sff_cpld_reg.src_118_8=cpld +sff_cpld_reg.frmt_118_8=bit +sff_cpld_reg.pola_118_8=negative +sff_cpld_reg.addr_118_8=0x04000010 +sff_cpld_reg.len_118_8=1 +sff_cpld_reg.bit_offset_118_8=5 + +sff_cpld_reg.mode_119_8=config +sff_cpld_reg.src_119_8=cpld +sff_cpld_reg.frmt_119_8=bit +sff_cpld_reg.pola_119_8=negative +sff_cpld_reg.addr_119_8=0x04000010 +sff_cpld_reg.len_119_8=1 +sff_cpld_reg.bit_offset_119_8=6 + +sff_cpld_reg.mode_120_8=config +sff_cpld_reg.src_120_8=cpld +sff_cpld_reg.frmt_120_8=bit +sff_cpld_reg.pola_120_8=negative +sff_cpld_reg.addr_120_8=0x04000010 +sff_cpld_reg.len_120_8=1 +sff_cpld_reg.bit_offset_120_8=7 + +sff_cpld_reg.mode_121_8=config +sff_cpld_reg.src_121_8=cpld +sff_cpld_reg.frmt_121_8=bit +sff_cpld_reg.pola_121_8=negative +sff_cpld_reg.addr_121_8=0x04000011 +sff_cpld_reg.len_121_8=1 +sff_cpld_reg.bit_offset_121_8=0 + +sff_cpld_reg.mode_122_8=config +sff_cpld_reg.src_122_8=cpld +sff_cpld_reg.frmt_122_8=bit +sff_cpld_reg.pola_122_8=negative +sff_cpld_reg.addr_122_8=0x04000011 +sff_cpld_reg.len_122_8=1 +sff_cpld_reg.bit_offset_122_8=1 + +sff_cpld_reg.mode_123_8=config +sff_cpld_reg.src_123_8=cpld +sff_cpld_reg.frmt_123_8=bit +sff_cpld_reg.pola_123_8=negative +sff_cpld_reg.addr_123_8=0x04000011 +sff_cpld_reg.len_123_8=1 +sff_cpld_reg.bit_offset_123_8=2 + +sff_cpld_reg.mode_124_8=config +sff_cpld_reg.src_124_8=cpld +sff_cpld_reg.frmt_124_8=bit +sff_cpld_reg.pola_124_8=negative +sff_cpld_reg.addr_124_8=0x04000011 +sff_cpld_reg.len_124_8=1 +sff_cpld_reg.bit_offset_124_8=3 + +sff_cpld_reg.mode_125_8=config +sff_cpld_reg.src_125_8=cpld +sff_cpld_reg.frmt_125_8=bit +sff_cpld_reg.pola_125_8=negative +sff_cpld_reg.addr_125_8=0x04000011 +sff_cpld_reg.len_125_8=1 +sff_cpld_reg.bit_offset_125_8=4 + +sff_cpld_reg.mode_126_8=config +sff_cpld_reg.src_126_8=cpld +sff_cpld_reg.frmt_126_8=bit +sff_cpld_reg.pola_126_8=negative +sff_cpld_reg.addr_126_8=0x04000011 +sff_cpld_reg.len_126_8=1 +sff_cpld_reg.bit_offset_126_8=5 + +sff_cpld_reg.mode_127_8=config +sff_cpld_reg.src_127_8=cpld +sff_cpld_reg.frmt_127_8=bit +sff_cpld_reg.pola_127_8=negative +sff_cpld_reg.addr_127_8=0x04000011 +sff_cpld_reg.len_127_8=1 +sff_cpld_reg.bit_offset_127_8=6 + +sff_cpld_reg.mode_128_8=config +sff_cpld_reg.src_128_8=cpld +sff_cpld_reg.frmt_128_8=bit +sff_cpld_reg.pola_128_8=negative +sff_cpld_reg.addr_128_8=0x04000011 +sff_cpld_reg.len_128_8=1 +sff_cpld_reg.bit_offset_128_8=7 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SLOT.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SLOT.cfg new file mode 100755 index 000000000000..3298104cf1bf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SLOT.cfg @@ -0,0 +1,1316 @@ +# Configuration item: i2c bus address of the sub-card +# Filling instructions: Format other_i2c_dev.bus_[slot_id]_[slot_index] other_i2c_dev.addr_[i2c_id]_[slot_index] +# Note: The slot_id of the child card is 5, and the slot_index starts from 1 +other_i2c_dev.bus_5_1=3 +other_i2c_dev.addr_5_1=0x56 +other_i2c_dev.bus_5_2=4 +other_i2c_dev.addr_5_2=0x56 +other_i2c_dev.bus_5_3=5 +other_i2c_dev.addr_5_3=0x56 +other_i2c_dev.bus_5_4=6 +other_i2c_dev.addr_5_4=0x56 + +slot_sysfs_name=eeprom + +# Number of sub-card +dev_num_5_0=4 + +# Number of sub-card temperature sensors +dev_num_5_1=0 + +# Number of sub-card voltage sensors +dev_num_5_2=12 + +# Number of current sensors on sub-card +dev_num_5_3=0 + +# Number of FPGA of subcards +dev_num_5_9=0 + +dev_present_status.mode_5_1=config +dev_present_status.int_cons_5_1= +dev_present_status.src_5_1=cpld +dev_present_status.frmt_5_1=bit +dev_present_status.pola_5_1=negative +dev_present_status.fpath_5_1= +dev_present_status.addr_5_1=0x0001002c +dev_present_status.len_5_1=1 +dev_present_status.bit_offset_5_1=4 + +dev_present_status.mode_5_2=config +dev_present_status.int_cons_5_2= +dev_present_status.src_5_2=cpld +dev_present_status.frmt_5_2=bit +dev_present_status.pola_5_2=negative +dev_present_status.fpath_5_2= +dev_present_status.addr_5_2=0x0001002c +dev_present_status.len_5_2=1 +dev_present_status.bit_offset_5_2=5 + +dev_present_status.mode_5_3=config +dev_present_status.int_cons_5_3= +dev_present_status.src_5_3=cpld +dev_present_status.frmt_5_3=bit +dev_present_status.pola_5_3=negative +dev_present_status.fpath_5_3= +dev_present_status.addr_5_3=0x0001002c +dev_present_status.len_5_3=1 +dev_present_status.bit_offset_5_3=6 + +dev_present_status.mode_5_4=config +dev_present_status.int_cons_5_4= +dev_present_status.src_5_4=cpld +dev_present_status.frmt_5_4=bit +dev_present_status.pola_5_4=negative +dev_present_status.fpath_5_4= +dev_present_status.addr_5_4=0x0001002c +dev_present_status.len_5_4=1 +dev_present_status.bit_offset_5_4=7 + +#slot1 in1 input +hwmon_in.mode_0x0101_0x50=config +hwmon_in.int_cons_0x0101_0x50=0 +hwmon_in.src_0x0101_0x50=cpld +hwmon_in.frmt_0x0101_0x50=num_bytes +hwmon_in.addr_0x0101_0x50=0x01000041 +hwmon_in.len_0x0101_0x50=2 +hwmon_in.int_extra1_0x0101_0x50=0x01000047 +hwmon_in.int_extra2_0x0101_0x50=2480 + +#slot1 in1 alais +hwmon_in.mode_0x0101_0x51=str_constant +hwmon_in.str_cons_0x0101_0x51=SLOT1_VDD3v3_QSFP_1 + +#slot1 in1 type +hwmon_in.mode_0x0101_0x52=str_constant +hwmon_in.str_cons_0x0101_0x52=cpld + +#slot1 in1 max +hwmon_in.mode_0x0101_0x53=str_constant +hwmon_in.str_cons_0x0101_0x53=3500 + +#slot1 in1 min +hwmon_in.mode_0x0101_0x55=str_constant +hwmon_in.str_cons_0x0101_0x55=3135 + +#slot1 in2 input +hwmon_in.mode_0x0102_0x50=config +hwmon_in.int_cons_0x0102_0x50=0 +hwmon_in.src_0x0102_0x50=cpld +hwmon_in.frmt_0x0102_0x50=num_bytes +hwmon_in.addr_0x0102_0x50=0x01000043 +hwmon_in.len_0x0102_0x50=2 +hwmon_in.int_extra1_0x0102_0x50=0x01000047 +hwmon_in.int_extra2_0x0102_0x50=2480 + +#slot1 in2 alais +hwmon_in.mode_0x0102_0x51=str_constant +hwmon_in.str_cons_0x0102_0x51=SLOT1_VDD3v3_QSFP_2 + +#slot1 in2 type +hwmon_in.mode_0x0102_0x52=str_constant +hwmon_in.str_cons_0x0102_0x52=cpld + +#slot1 in2 max +hwmon_in.mode_0x0102_0x53=str_constant +hwmon_in.str_cons_0x0102_0x53=3500 + +#slot1 in2 min +hwmon_in.mode_0x0102_0x55=str_constant +hwmon_in.str_cons_0x0102_0x55=3135 + +#slot1 in3 input +hwmon_in.mode_0x0103_0x50=config +hwmon_in.int_cons_0x0103_0x50=0 +hwmon_in.src_0x0103_0x50=cpld +hwmon_in.frmt_0x0103_0x50=num_bytes +hwmon_in.addr_0x0103_0x50=0x01000045 +hwmon_in.len_0x0103_0x50=2 +hwmon_in.int_extra1_0x0103_0x50=0x01000047 +hwmon_in.int_extra2_0x0103_0x50=1240 + +#slot1 in3 alais +hwmon_in.mode_0x0103_0x51=str_constant +hwmon_in.str_cons_0x0103_0x51=SLOT1_VDD1v8 + +#slot1 in3 type +hwmon_in.mode_0x0103_0x52=str_constant +hwmon_in.str_cons_0x0103_0x52=cpld + +#slot1 in3 max +hwmon_in.mode_0x0103_0x53=str_constant +hwmon_in.str_cons_0x0103_0x53=1926 + +#slot1 in3 min +hwmon_in.mode_0x0103_0x55=str_constant +hwmon_in.str_cons_0x0103_0x55=1710 + +#slot1 in4 input +hwmon_in.mode_0x0104_0x50=config +hwmon_in.int_cons_0x0104_0x50=0 +hwmon_in.src_0x0104_0x50=cpld +hwmon_in.frmt_0x0104_0x50=num_bytes +hwmon_in.addr_0x0104_0x50=0x01000047 +hwmon_in.len_0x0104_0x50=2 +hwmon_in.int_extra1_0x0104_0x50=0x01000047 +hwmon_in.int_extra2_0x0104_0x50=1000 + +#slot1 in4 alais +hwmon_in.mode_0x0104_0x51=str_constant +hwmon_in.str_cons_0x0104_0x51=SLOT1_TEST1v24 + +#slot1 in4 type +hwmon_in.mode_0x0104_0x52=str_constant +hwmon_in.str_cons_0x0104_0x52=cpld + +#slot1 in4 max +hwmon_in.mode_0x0104_0x53=str_constant +hwmon_in.str_cons_0x0104_0x53=1302 + +#slot1 in4 min +hwmon_in.mode_0x0104_0x55=str_constant +hwmon_in.str_cons_0x0104_0x55=1178 + +#slot1 in5 input +hwmon_in.mode_0x0105_0x50=config +hwmon_in.int_cons_0x0105_0x50=0 +hwmon_in.src_0x0105_0x50=cpld +hwmon_in.frmt_0x0105_0x50=num_bytes +hwmon_in.addr_0x0105_0x50=0x01000049 +hwmon_in.len_0x0105_0x50=2 +hwmon_in.int_extra1_0x0105_0x50=0x01000047 +hwmon_in.int_extra2_0x0105_0x50=2480 + +#slot1 in5 alais +hwmon_in.mode_0x0105_0x51=str_constant +hwmon_in.str_cons_0x0105_0x51=SLOT1_VDD3v3_CLK + +#slot1 in5 type +hwmon_in.mode_0x0105_0x52=str_constant +hwmon_in.str_cons_0x0105_0x52=cpld + +#slot1 in5 max +hwmon_in.mode_0x0105_0x53=str_constant +hwmon_in.str_cons_0x0105_0x53=3556 + +#slot1 in5 min +hwmon_in.mode_0x0105_0x55=str_constant +hwmon_in.str_cons_0x0105_0x55=3135 + +#slot1 in6 input +hwmon_in.mode_0x0106_0x50=config +hwmon_in.int_cons_0x0106_0x50=0 +hwmon_in.src_0x0106_0x50=cpld +hwmon_in.frmt_0x0106_0x50=num_bytes +hwmon_in.addr_0x0106_0x50=0x0100004b +hwmon_in.len_0x0106_0x50=2 +hwmon_in.int_extra1_0x0106_0x50=0x01000047 +hwmon_in.int_extra2_0x0106_0x50=2480 + +#slot1 in6 alais +hwmon_in.mode_0x0106_0x51=str_constant +hwmon_in.str_cons_0x0106_0x51=SLOT1_VDD5v0 + +#slot1 in6 type +hwmon_in.mode_0x0106_0x52=str_constant +hwmon_in.str_cons_0x0106_0x52=cpld + +#slot1 in6 max +hwmon_in.mode_0x0106_0x53=str_constant +hwmon_in.str_cons_0x0106_0x53=5331 + +#slot1 in6 min +hwmon_in.mode_0x0106_0x55=str_constant +hwmon_in.str_cons_0x0106_0x55=4750 + +#slot1 in7 input +hwmon_in.mode_0x0107_0x50=config +hwmon_in.int_cons_0x0107_0x50=0 +hwmon_in.src_0x0107_0x50=cpld +hwmon_in.frmt_0x0107_0x50=num_bytes +hwmon_in.addr_0x0107_0x50=0x0100004d +hwmon_in.len_0x0107_0x50=2 +hwmon_in.int_extra1_0x0107_0x50=0x01000047 +hwmon_in.int_extra2_0x0107_0x50=2480 + +#slot1 in7 alais +hwmon_in.mode_0x0107_0x51=str_constant +hwmon_in.str_cons_0x0107_0x51=SLOT1_VDD3v7_CLK_MCU + +#slot1 in7 type +hwmon_in.mode_0x0107_0x52=str_constant +hwmon_in.str_cons_0x0107_0x52=cpld + +#slot1 in7 max +hwmon_in.mode_0x0107_0x53=str_constant +hwmon_in.str_cons_0x0107_0x53=4022 + +#slot1 in7 min +hwmon_in.mode_0x0107_0x55=str_constant +hwmon_in.str_cons_0x0107_0x55=3639 + +#slot1 in8 input +hwmon_in.mode_0x0108_0x50=config +hwmon_in.int_cons_0x0108_0x50=0 +hwmon_in.src_0x0108_0x50=cpld +hwmon_in.frmt_0x0108_0x50=num_bytes +hwmon_in.addr_0x0108_0x50=0x0100004f +hwmon_in.len_0x0108_0x50=2 +hwmon_in.int_extra1_0x0108_0x50=0x01000047 +hwmon_in.int_extra2_0x0108_0x50=1240 + +#slot1 in8 alais +hwmon_in.mode_0x0108_0x51=str_constant +hwmon_in.str_cons_0x0108_0x51=SLOT1_VDD1v2 + +#slot1 in8 type +hwmon_in.mode_0x0108_0x52=str_constant +hwmon_in.str_cons_0x0108_0x52=cpld + +#slot1 in8 max +hwmon_in.mode_0x0108_0x53=str_constant +hwmon_in.str_cons_0x0108_0x53=1260 + +#slot1 in8 min +hwmon_in.mode_0x0108_0x55=str_constant +hwmon_in.str_cons_0x0108_0x55=1140 + +#slot1 in9 input +hwmon_in.mode_0x0109_0x50=config +hwmon_in.int_cons_0x0109_0x50=0 +hwmon_in.src_0x0109_0x50=cpld +hwmon_in.frmt_0x0109_0x50=num_bytes +hwmon_in.addr_0x0109_0x50=0x01000051 +hwmon_in.len_0x0109_0x50=2 +hwmon_in.int_extra1_0x0109_0x50=0x01000047 +hwmon_in.int_extra2_0x0109_0x50=2480 + +#slot1 in9 alais +hwmon_in.mode_0x0109_0x51=str_constant +hwmon_in.str_cons_0x0109_0x51=SLOT1_VDD3v3 + +#slot1 in9 type +hwmon_in.mode_0x0109_0x52=str_constant +hwmon_in.str_cons_0x0109_0x52=cpld + +#slot1 in9 max +hwmon_in.mode_0x0109_0x53=str_constant +hwmon_in.str_cons_0x0109_0x53=3539 + +#slot1 in9 min +hwmon_in.mode_0x0109_0x55=str_constant +hwmon_in.str_cons_0x0109_0x55=3135 + +#slot1 in10 input +hwmon_in.mode_0x010a_0x50=config +hwmon_in.int_cons_0x010a_0x50=0 +hwmon_in.src_0x010a_0x50=cpld +hwmon_in.frmt_0x010a_0x50=num_bytes +hwmon_in.addr_0x010a_0x50=0x01000053 +hwmon_in.len_0x010a_0x50=2 +hwmon_in.int_extra1_0x010a_0x50=0x01000047 +hwmon_in.int_extra2_0x010a_0x50=1240 + +#slot1 in10 alais +hwmon_in.mode_0x010a_0x51=str_constant +hwmon_in.str_cons_0x010a_0x51=SLOT1_DVDD_0V8 + +#slot1 in10 type +hwmon_in.mode_0x010a_0x52=str_constant +hwmon_in.str_cons_0x010a_0x52=cpld + +#slot1 in10 max +hwmon_in.mode_0x010a_0x53=str_constant +hwmon_in.str_cons_0x010a_0x53=772 + +#slot1 in10 min +hwmon_in.mode_0x010a_0x55=str_constant +hwmon_in.str_cons_0x010a_0x55=684 + +#slot1 in11 input +hwmon_in.mode_0x010b_0x50=config +hwmon_in.int_cons_0x010b_0x50=0 +hwmon_in.src_0x010b_0x50=cpld +hwmon_in.frmt_0x010b_0x50=num_bytes +hwmon_in.addr_0x010b_0x50=0x01000055 +hwmon_in.len_0x010b_0x50=2 +hwmon_in.int_extra1_0x010b_0x50=0x01000047 +hwmon_in.int_extra2_0x010b_0x50=1240 + +#slot1 in11 alais +hwmon_in.mode_0x010b_0x51=str_constant +hwmon_in.str_cons_0x010b_0x51=SLOT1_VDD1V8_CPLD + +#slot1 in11 type +hwmon_in.mode_0x010b_0x52=str_constant +hwmon_in.str_cons_0x010b_0x52=cpld + +#slot1 in11 max +hwmon_in.mode_0x010b_0x53=str_constant +hwmon_in.str_cons_0x010b_0x53=1909 + +#slot1 in11 min +hwmon_in.mode_0x010b_0x55=str_constant +hwmon_in.str_cons_0x010b_0x55=1710 + +#slot1 in12 input +hwmon_in.mode_0x010c_0x50=config +hwmon_in.int_cons_0x010c_0x50=0 +hwmon_in.src_0x010c_0x50=cpld +hwmon_in.frmt_0x010c_0x50=num_bytes +hwmon_in.addr_0x010c_0x50=0x01000057 +hwmon_in.len_0x010c_0x50=2 +hwmon_in.int_extra1_0x010c_0x50=0x01000047 +hwmon_in.int_extra2_0x010c_0x50=1240 + +#slot1 in12 alais +hwmon_in.mode_0x010c_0x51=str_constant +hwmon_in.str_cons_0x010c_0x51=SLOT1_AVDD0V8 + +#slot1 in12 type +hwmon_in.mode_0x010c_0x52=str_constant +hwmon_in.str_cons_0x010c_0x52=cpld + +#slot1 in12 max +hwmon_in.mode_0x010c_0x53=str_constant +hwmon_in.str_cons_0x010c_0x53=877 + +#slot1 in12 min +hwmon_in.mode_0x010c_0x55=str_constant +hwmon_in.str_cons_0x010c_0x55=776 + +#slot2 in1 input +hwmon_in.mode_0x0201_0x50=config +hwmon_in.int_cons_0x0201_0x50=0 +hwmon_in.src_0x0201_0x50=cpld +hwmon_in.frmt_0x0201_0x50=num_bytes +hwmon_in.addr_0x0201_0x50=0x02000041 +hwmon_in.len_0x0201_0x50=2 +hwmon_in.int_extra1_0x0201_0x50=0x02000047 +hwmon_in.int_extra2_0x0201_0x50=2480 + +#slot2 in1 alais +hwmon_in.mode_0x0201_0x51=str_constant +hwmon_in.str_cons_0x0201_0x51=SLOT2_VDD3v3_QSFP_1 + +#slot2 in1 type +hwmon_in.mode_0x0201_0x52=str_constant +hwmon_in.str_cons_0x0201_0x52=cpld + +#slot2 in1 max +hwmon_in.mode_0x0201_0x53=str_constant +hwmon_in.str_cons_0x0201_0x53=3500 + +#slot2 in1 min +hwmon_in.mode_0x0201_0x55=str_constant +hwmon_in.str_cons_0x0201_0x55=3135 + +#slot2 in2 input +hwmon_in.mode_0x0202_0x50=config +hwmon_in.int_cons_0x0202_0x50=0 +hwmon_in.src_0x0202_0x50=cpld +hwmon_in.frmt_0x0202_0x50=num_bytes +hwmon_in.addr_0x0202_0x50=0x02000043 +hwmon_in.len_0x0202_0x50=2 +hwmon_in.int_extra1_0x0202_0x50=0x02000047 +hwmon_in.int_extra2_0x0202_0x50=2480 + +#slot2 in2 alais +hwmon_in.mode_0x0202_0x51=str_constant +hwmon_in.str_cons_0x0202_0x51=SLOT2_VDD3v3_QSFP_2 + +#slot2 in2 type +hwmon_in.mode_0x0202_0x52=str_constant +hwmon_in.str_cons_0x0202_0x52=cpld + +#slot2 in2 max +hwmon_in.mode_0x0202_0x53=str_constant +hwmon_in.str_cons_0x0202_0x53=3500 + +#slot2 in2 min +hwmon_in.mode_0x0202_0x55=str_constant +hwmon_in.str_cons_0x0202_0x55=3135 + +#slot2 in3 input +hwmon_in.mode_0x0203_0x50=config +hwmon_in.int_cons_0x0203_0x50=0 +hwmon_in.src_0x0203_0x50=cpld +hwmon_in.frmt_0x0203_0x50=num_bytes +hwmon_in.addr_0x0203_0x50=0x02000045 +hwmon_in.len_0x0203_0x50=2 +hwmon_in.int_extra1_0x0203_0x50=0x02000047 +hwmon_in.int_extra2_0x0203_0x50=1240 + +#slot2 in3 alais +hwmon_in.mode_0x0203_0x51=str_constant +hwmon_in.str_cons_0x0203_0x51=SLOT2_VDD1v8 + +#slot2 in3 type +hwmon_in.mode_0x0203_0x52=str_constant +hwmon_in.str_cons_0x0203_0x52=cpld + +#slot2 in3 max +hwmon_in.mode_0x0203_0x53=str_constant +hwmon_in.str_cons_0x0203_0x53=1926 + +#slot2 in3 min +hwmon_in.mode_0x0203_0x55=str_constant +hwmon_in.str_cons_0x0203_0x55=1710 + +#slot2 in4 input +hwmon_in.mode_0x0204_0x50=config +hwmon_in.int_cons_0x0204_0x50=0 +hwmon_in.src_0x0204_0x50=cpld +hwmon_in.frmt_0x0204_0x50=num_bytes +hwmon_in.addr_0x0204_0x50=0x02000047 +hwmon_in.len_0x0204_0x50=2 +hwmon_in.int_extra1_0x0204_0x50=0x02000047 +hwmon_in.int_extra2_0x0204_0x50=1000 + +#slot2 in4 alais +hwmon_in.mode_0x0204_0x51=str_constant +hwmon_in.str_cons_0x0204_0x51=SLOT2_TEST1v24 + +#slot2 in4 type +hwmon_in.mode_0x0204_0x52=str_constant +hwmon_in.str_cons_0x0204_0x52=cpld + +#slot2 in4 max +hwmon_in.mode_0x0204_0x53=str_constant +hwmon_in.str_cons_0x0204_0x53=1302 + +#slot2 in4 min +hwmon_in.mode_0x0204_0x55=str_constant +hwmon_in.str_cons_0x0204_0x55=1178 + +#slot2 in5 input +hwmon_in.mode_0x0205_0x50=config +hwmon_in.int_cons_0x0205_0x50=0 +hwmon_in.src_0x0205_0x50=cpld +hwmon_in.frmt_0x0205_0x50=num_bytes +hwmon_in.addr_0x0205_0x50=0x02000049 +hwmon_in.len_0x0205_0x50=2 +hwmon_in.int_extra1_0x0205_0x50=0x02000047 +hwmon_in.int_extra2_0x0205_0x50=2480 + +#slot2 in5 alais +hwmon_in.mode_0x0205_0x51=str_constant +hwmon_in.str_cons_0x0205_0x51=SLOT2_VDD3v3_CLK + +#slot2 in5 type +hwmon_in.mode_0x0205_0x52=str_constant +hwmon_in.str_cons_0x0205_0x52=cpld + +#slot2 in5 max +hwmon_in.mode_0x0205_0x53=str_constant +hwmon_in.str_cons_0x0205_0x53=3556 + +#slot2 in5 min +hwmon_in.mode_0x0205_0x55=str_constant +hwmon_in.str_cons_0x0205_0x55=3135 + +#slot2 in6 input +hwmon_in.mode_0x0206_0x50=config +hwmon_in.int_cons_0x0206_0x50=0 +hwmon_in.src_0x0206_0x50=cpld +hwmon_in.frmt_0x0206_0x50=num_bytes +hwmon_in.addr_0x0206_0x50=0x0200004b +hwmon_in.len_0x0206_0x50=2 +hwmon_in.int_extra1_0x0206_0x50=0x02000047 +hwmon_in.int_extra2_0x0206_0x50=2480 + +#slot2 in6 alais +hwmon_in.mode_0x0206_0x51=str_constant +hwmon_in.str_cons_0x0206_0x51=SLOT2_VDD5v0 + +#slot2 in6 type +hwmon_in.mode_0x0206_0x52=str_constant +hwmon_in.str_cons_0x0206_0x52=cpld + +#slot2 in6 max +hwmon_in.mode_0x0206_0x53=str_constant +hwmon_in.str_cons_0x0206_0x53=5331 + +#slot2 in6 min +hwmon_in.mode_0x0206_0x55=str_constant +hwmon_in.str_cons_0x0206_0x55=4750 + +#slot2 in7 input +hwmon_in.mode_0x0207_0x50=config +hwmon_in.int_cons_0x0207_0x50=0 +hwmon_in.src_0x0207_0x50=cpld +hwmon_in.frmt_0x0207_0x50=num_bytes +hwmon_in.addr_0x0207_0x50=0x0200004d +hwmon_in.len_0x0207_0x50=2 +hwmon_in.int_extra1_0x0207_0x50=0x02000047 +hwmon_in.int_extra2_0x0207_0x50=2480 + +#slot2 in7 alais +hwmon_in.mode_0x0207_0x51=str_constant +hwmon_in.str_cons_0x0207_0x51=SLOT2_VDD3v7_CLK_MCU + +#slot2 in7 type +hwmon_in.mode_0x0207_0x52=str_constant +hwmon_in.str_cons_0x0207_0x52=cpld + +#slot2 in7 max +hwmon_in.mode_0x0207_0x53=str_constant +hwmon_in.str_cons_0x0207_0x53=4022 + +#slot2 in7 min +hwmon_in.mode_0x0207_0x55=str_constant +hwmon_in.str_cons_0x0207_0x55=3639 + +#slot2 in8 input +hwmon_in.mode_0x0208_0x50=config +hwmon_in.int_cons_0x0208_0x50=0 +hwmon_in.src_0x0208_0x50=cpld +hwmon_in.frmt_0x0208_0x50=num_bytes +hwmon_in.addr_0x0208_0x50=0x0200004f +hwmon_in.len_0x0208_0x50=2 +hwmon_in.int_extra1_0x0208_0x50=0x02000047 +hwmon_in.int_extra2_0x0208_0x50=1240 + +#slot2 in8 alais +hwmon_in.mode_0x0208_0x51=str_constant +hwmon_in.str_cons_0x0208_0x51=SLOT2_VDD1v2 + +#slot2 in8 type +hwmon_in.mode_0x0208_0x52=str_constant +hwmon_in.str_cons_0x0208_0x52=cpld + +#slot2 in8 max +hwmon_in.mode_0x0208_0x53=str_constant +hwmon_in.str_cons_0x0208_0x53=1260 + +#slot2 in8 min +hwmon_in.mode_0x0208_0x55=str_constant +hwmon_in.str_cons_0x0208_0x55=1140 + +#slot2 in9 input +hwmon_in.mode_0x0209_0x50=config +hwmon_in.int_cons_0x0209_0x50=0 +hwmon_in.src_0x0209_0x50=cpld +hwmon_in.frmt_0x0209_0x50=num_bytes +hwmon_in.addr_0x0209_0x50=0x02000051 +hwmon_in.len_0x0209_0x50=2 +hwmon_in.int_extra1_0x0209_0x50=0x02000047 +hwmon_in.int_extra2_0x0209_0x50=2480 + +#slot2 in9 alais +hwmon_in.mode_0x0209_0x51=str_constant +hwmon_in.str_cons_0x0209_0x51=SLOT2_VDD3v3 + +#slot2 in9 type +hwmon_in.mode_0x0209_0x52=str_constant +hwmon_in.str_cons_0x0209_0x52=cpld + +#slot2 in9 max +hwmon_in.mode_0x0209_0x53=str_constant +hwmon_in.str_cons_0x0209_0x53=3539 + +#slot2 in9 min +hwmon_in.mode_0x0209_0x55=str_constant +hwmon_in.str_cons_0x0209_0x55=3135 + +#slot2 in10 input +hwmon_in.mode_0x020a_0x50=config +hwmon_in.int_cons_0x020a_0x50=0 +hwmon_in.src_0x020a_0x50=cpld +hwmon_in.frmt_0x020a_0x50=num_bytes +hwmon_in.addr_0x020a_0x50=0x02000053 +hwmon_in.len_0x020a_0x50=2 +hwmon_in.int_extra1_0x020a_0x50=0x02000047 +hwmon_in.int_extra2_0x020a_0x50=1240 + +#slot2 in10 alais +hwmon_in.mode_0x020a_0x51=str_constant +hwmon_in.str_cons_0x020a_0x51=SLOT2_DVDD_0V8 + +#slot2 in10 type +hwmon_in.mode_0x020a_0x52=str_constant +hwmon_in.str_cons_0x020a_0x52=cpld + +#slot2 in10 max +hwmon_in.mode_0x020a_0x53=str_constant +hwmon_in.str_cons_0x020a_0x53=772 + +#slot2 in10 min +hwmon_in.mode_0x020a_0x55=str_constant +hwmon_in.str_cons_0x020a_0x55=684 + +#slot2 in11 input +hwmon_in.mode_0x020b_0x50=config +hwmon_in.int_cons_0x020b_0x50=0 +hwmon_in.src_0x020b_0x50=cpld +hwmon_in.frmt_0x020b_0x50=num_bytes +hwmon_in.addr_0x020b_0x50=0x02000055 +hwmon_in.len_0x020b_0x50=2 +hwmon_in.int_extra1_0x020b_0x50=0x02000047 +hwmon_in.int_extra2_0x020b_0x50=1240 + +#slot2 in11 alais +hwmon_in.mode_0x020b_0x51=str_constant +hwmon_in.str_cons_0x020b_0x51=SLOT2_VDD1V8_CPLD + +#slot2 in11 type +hwmon_in.mode_0x020b_0x52=str_constant +hwmon_in.str_cons_0x020b_0x52=cpld + +#slot2 in11 max +hwmon_in.mode_0x020b_0x53=str_constant +hwmon_in.str_cons_0x020b_0x53=1909 + +#slot2 in11 min +hwmon_in.mode_0x020b_0x55=str_constant +hwmon_in.str_cons_0x020b_0x55=1710 + +#slot2 in12 input +hwmon_in.mode_0x020c_0x50=config +hwmon_in.int_cons_0x020c_0x50=0 +hwmon_in.src_0x020c_0x50=cpld +hwmon_in.frmt_0x020c_0x50=num_bytes +hwmon_in.addr_0x020c_0x50=0x02000057 +hwmon_in.len_0x020c_0x50=2 +hwmon_in.int_extra1_0x020c_0x50=0x02000047 +hwmon_in.int_extra2_0x020c_0x50=1240 + +#slot2 in12 alais +hwmon_in.mode_0x020c_0x51=str_constant +hwmon_in.str_cons_0x020c_0x51=SLOT2_AVDD0V8 + +#slot2 in12 type +hwmon_in.mode_0x020c_0x52=str_constant +hwmon_in.str_cons_0x020c_0x52=cpld + +#slot2 in12 max +hwmon_in.mode_0x020c_0x53=str_constant +hwmon_in.str_cons_0x020c_0x53=877 + +#slot2 in12 min +hwmon_in.mode_0x020c_0x55=str_constant +hwmon_in.str_cons_0x020c_0x55=776 + +#slot3 in1 input +hwmon_in.mode_0x0301_0x50=config +hwmon_in.int_cons_0x0301_0x50=0 +hwmon_in.src_0x0301_0x50=cpld +hwmon_in.frmt_0x0301_0x50=num_bytes +hwmon_in.addr_0x0301_0x50=0x03000041 +hwmon_in.len_0x0301_0x50=2 +hwmon_in.int_extra1_0x0301_0x50=0x03000047 +hwmon_in.int_extra2_0x0301_0x50=2480 + +#slot3 in1 alais +hwmon_in.mode_0x0301_0x51=str_constant +hwmon_in.str_cons_0x0301_0x51=SLOT3_VDD3v3_QSFP_1 + +#slot3 in1 type +hwmon_in.mode_0x0301_0x52=str_constant +hwmon_in.str_cons_0x0301_0x52=cpld + +#slot3 in1 max +hwmon_in.mode_0x0301_0x53=str_constant +hwmon_in.str_cons_0x0301_0x53=3500 + +#slot3 in1 min +hwmon_in.mode_0x0301_0x55=str_constant +hwmon_in.str_cons_0x0301_0x55=3135 + +#slot3 in2 input +hwmon_in.mode_0x0302_0x50=config +hwmon_in.int_cons_0x0302_0x50=0 +hwmon_in.src_0x0302_0x50=cpld +hwmon_in.frmt_0x0302_0x50=num_bytes +hwmon_in.addr_0x0302_0x50=0x03000043 +hwmon_in.len_0x0302_0x50=2 +hwmon_in.int_extra1_0x0302_0x50=0x03000047 +hwmon_in.int_extra2_0x0302_0x50=2480 + +#slot3 in2 alais +hwmon_in.mode_0x0302_0x51=str_constant +hwmon_in.str_cons_0x0302_0x51=SLOT3_VDD3v3_QSFP_2 + +#slot3 in2 type +hwmon_in.mode_0x0302_0x52=str_constant +hwmon_in.str_cons_0x0302_0x52=cpld + +#slot3 in2 max +hwmon_in.mode_0x0302_0x53=str_constant +hwmon_in.str_cons_0x0302_0x53=3500 + +#slot3 in2 min +hwmon_in.mode_0x0302_0x55=str_constant +hwmon_in.str_cons_0x0302_0x55=3135 + +#slot3 in3 input +hwmon_in.mode_0x0303_0x50=config +hwmon_in.int_cons_0x0303_0x50=0 +hwmon_in.src_0x0303_0x50=cpld +hwmon_in.frmt_0x0303_0x50=num_bytes +hwmon_in.addr_0x0303_0x50=0x03000045 +hwmon_in.len_0x0303_0x50=2 +hwmon_in.int_extra1_0x0303_0x50=0x03000047 +hwmon_in.int_extra2_0x0303_0x50=1240 + +#slot3 in3 alais +hwmon_in.mode_0x0303_0x51=str_constant +hwmon_in.str_cons_0x0303_0x51=SLOT3_VDD1v8 + +#slot3 in3 type +hwmon_in.mode_0x0303_0x52=str_constant +hwmon_in.str_cons_0x0303_0x52=cpld + +#slot3 in3 max +hwmon_in.mode_0x0303_0x53=str_constant +hwmon_in.str_cons_0x0303_0x53=1926 + +#slot3 in3 min +hwmon_in.mode_0x0303_0x55=str_constant +hwmon_in.str_cons_0x0303_0x55=1710 + +#slot3 in4 input +hwmon_in.mode_0x0304_0x50=config +hwmon_in.int_cons_0x0304_0x50=0 +hwmon_in.src_0x0304_0x50=cpld +hwmon_in.frmt_0x0304_0x50=num_bytes +hwmon_in.addr_0x0304_0x50=0x03000047 +hwmon_in.len_0x0304_0x50=2 +hwmon_in.int_extra1_0x0304_0x50=0x03000047 +hwmon_in.int_extra2_0x0304_0x50=1000 + +#slot3 in4 alais +hwmon_in.mode_0x0304_0x51=str_constant +hwmon_in.str_cons_0x0304_0x51=SLOT3_TEST1v24 + +#slot3 in4 type +hwmon_in.mode_0x0304_0x52=str_constant +hwmon_in.str_cons_0x0304_0x52=cpld + +#slot3 in4 max +hwmon_in.mode_0x0304_0x53=str_constant +hwmon_in.str_cons_0x0304_0x53=1302 + +#slot3 in4 min +hwmon_in.mode_0x0304_0x55=str_constant +hwmon_in.str_cons_0x0304_0x55=1178 + +#slot3 in5 input +hwmon_in.mode_0x0305_0x50=config +hwmon_in.int_cons_0x0305_0x50=0 +hwmon_in.src_0x0305_0x50=cpld +hwmon_in.frmt_0x0305_0x50=num_bytes +hwmon_in.addr_0x0305_0x50=0x03000049 +hwmon_in.len_0x0305_0x50=2 +hwmon_in.int_extra1_0x0305_0x50=0x03000047 +hwmon_in.int_extra2_0x0305_0x50=2480 + +#slot3 in5 alais +hwmon_in.mode_0x0305_0x51=str_constant +hwmon_in.str_cons_0x0305_0x51=SLOT3_VDD3v3_CLK + +#slot3 in5 type +hwmon_in.mode_0x0305_0x52=str_constant +hwmon_in.str_cons_0x0305_0x52=cpld + +#slot3 in5 max +hwmon_in.mode_0x0305_0x53=str_constant +hwmon_in.str_cons_0x0305_0x53=3556 + +#slot3 in5 min +hwmon_in.mode_0x0305_0x55=str_constant +hwmon_in.str_cons_0x0305_0x55=3135 + +#slot3 in6 input +hwmon_in.mode_0x0306_0x50=config +hwmon_in.int_cons_0x0306_0x50=0 +hwmon_in.src_0x0306_0x50=cpld +hwmon_in.frmt_0x0306_0x50=num_bytes +hwmon_in.addr_0x0306_0x50=0x0300004b +hwmon_in.len_0x0306_0x50=2 +hwmon_in.int_extra1_0x0306_0x50=0x03000047 +hwmon_in.int_extra2_0x0306_0x50=2480 + +#slot3 in6 alais +hwmon_in.mode_0x0306_0x51=str_constant +hwmon_in.str_cons_0x0306_0x51=SLOT3_VDD5v0 + +#slot3 in6 type +hwmon_in.mode_0x0306_0x52=str_constant +hwmon_in.str_cons_0x0306_0x52=cpld + +#slot3 in6 max +hwmon_in.mode_0x0306_0x53=str_constant +hwmon_in.str_cons_0x0306_0x53=5331 + +#slot3 in6 min +hwmon_in.mode_0x0306_0x55=str_constant +hwmon_in.str_cons_0x0306_0x55=4750 + +#slot3 in7 input +hwmon_in.mode_0x0307_0x50=config +hwmon_in.int_cons_0x0307_0x50=0 +hwmon_in.src_0x0307_0x50=cpld +hwmon_in.frmt_0x0307_0x50=num_bytes +hwmon_in.addr_0x0307_0x50=0x0300004d +hwmon_in.len_0x0307_0x50=2 +hwmon_in.int_extra1_0x0307_0x50=0x03000047 +hwmon_in.int_extra2_0x0307_0x50=2480 + +#slot3 in7 alais +hwmon_in.mode_0x0307_0x51=str_constant +hwmon_in.str_cons_0x0307_0x51=SLOT3_VDD3v7_CLK_MCU + +#slot3 in7 type +hwmon_in.mode_0x0307_0x52=str_constant +hwmon_in.str_cons_0x0307_0x52=cpld + +#slot3 in7 max +hwmon_in.mode_0x0307_0x53=str_constant +hwmon_in.str_cons_0x0307_0x53=4022 + +#slot3 in7 min +hwmon_in.mode_0x0307_0x55=str_constant +hwmon_in.str_cons_0x0307_0x55=3639 + +#slot3 in8 input +hwmon_in.mode_0x0308_0x50=config +hwmon_in.int_cons_0x0308_0x50=0 +hwmon_in.src_0x0308_0x50=cpld +hwmon_in.frmt_0x0308_0x50=num_bytes +hwmon_in.addr_0x0308_0x50=0x0300004f +hwmon_in.len_0x0308_0x50=2 +hwmon_in.int_extra1_0x0308_0x50=0x03000047 +hwmon_in.int_extra2_0x0308_0x50=1240 + +#slot3 in8 alais +hwmon_in.mode_0x0308_0x51=str_constant +hwmon_in.str_cons_0x0308_0x51=SLOT3_VDD1v2 + +#slot3 in8 type +hwmon_in.mode_0x0308_0x52=str_constant +hwmon_in.str_cons_0x0308_0x52=cpld + +#slot3 in8 max +hwmon_in.mode_0x0308_0x53=str_constant +hwmon_in.str_cons_0x0308_0x53=1260 + +#slot3 in8 min +hwmon_in.mode_0x0308_0x55=str_constant +hwmon_in.str_cons_0x0308_0x55=1140 + +#slot3 in9 input +hwmon_in.mode_0x0309_0x50=config +hwmon_in.int_cons_0x0309_0x50=0 +hwmon_in.src_0x0309_0x50=cpld +hwmon_in.frmt_0x0309_0x50=num_bytes +hwmon_in.addr_0x0309_0x50=0x03000051 +hwmon_in.len_0x0309_0x50=2 +hwmon_in.int_extra1_0x0309_0x50=0x03000047 +hwmon_in.int_extra2_0x0309_0x50=2480 + +#slot3 in9 alais +hwmon_in.mode_0x0309_0x51=str_constant +hwmon_in.str_cons_0x0309_0x51=SLOT3_VDD3v3 + +#slot3 in9 type +hwmon_in.mode_0x0309_0x52=str_constant +hwmon_in.str_cons_0x0309_0x52=cpld + +#slot3 in9 max +hwmon_in.mode_0x0309_0x53=str_constant +hwmon_in.str_cons_0x0309_0x53=3539 + +#slot3 in9 min +hwmon_in.mode_0x0309_0x55=str_constant +hwmon_in.str_cons_0x0309_0x55=3135 + +#slot3 in10 input +hwmon_in.mode_0x030a_0x50=config +hwmon_in.int_cons_0x030a_0x50=0 +hwmon_in.src_0x030a_0x50=cpld +hwmon_in.frmt_0x030a_0x50=num_bytes +hwmon_in.addr_0x030a_0x50=0x03000053 +hwmon_in.len_0x030a_0x50=2 +hwmon_in.int_extra1_0x030a_0x50=0x03000047 +hwmon_in.int_extra2_0x030a_0x50=1240 + +#slot3 in10 alais +hwmon_in.mode_0x030a_0x51=str_constant +hwmon_in.str_cons_0x030a_0x51=SLOT3_DVDD_0V8 + +#slot3 in10 type +hwmon_in.mode_0x030a_0x52=str_constant +hwmon_in.str_cons_0x030a_0x52=cpld + +#slot3 in10 max +hwmon_in.mode_0x030a_0x53=str_constant +hwmon_in.str_cons_0x030a_0x53=772 + +#slot3 in10 min +hwmon_in.mode_0x030a_0x55=str_constant +hwmon_in.str_cons_0x030a_0x55=684 + +#slot3 in11 input +hwmon_in.mode_0x030b_0x50=config +hwmon_in.int_cons_0x030b_0x50=0 +hwmon_in.src_0x030b_0x50=cpld +hwmon_in.frmt_0x030b_0x50=num_bytes +hwmon_in.addr_0x030b_0x50=0x03000055 +hwmon_in.len_0x030b_0x50=2 +hwmon_in.int_extra1_0x030b_0x50=0x03000047 +hwmon_in.int_extra2_0x030b_0x50=1240 + +#slot3 in11 alais +hwmon_in.mode_0x030b_0x51=str_constant +hwmon_in.str_cons_0x030b_0x51=SLOT3_VDD1V8_CPLD + +#slot3 in11 type +hwmon_in.mode_0x030b_0x52=str_constant +hwmon_in.str_cons_0x030b_0x52=cpld + +#slot3 in11 max +hwmon_in.mode_0x030b_0x53=str_constant +hwmon_in.str_cons_0x030b_0x53=1909 + +#slot3 in11 min +hwmon_in.mode_0x030b_0x55=str_constant +hwmon_in.str_cons_0x030b_0x55=1710 + +#slot3 in12 input +hwmon_in.mode_0x030c_0x50=config +hwmon_in.int_cons_0x030c_0x50=0 +hwmon_in.src_0x030c_0x50=cpld +hwmon_in.frmt_0x030c_0x50=num_bytes +hwmon_in.addr_0x030c_0x50=0x03000057 +hwmon_in.len_0x030c_0x50=2 +hwmon_in.int_extra1_0x030c_0x50=0x03000047 +hwmon_in.int_extra2_0x030c_0x50=1240 + +#slot3 in12 alais +hwmon_in.mode_0x030c_0x51=str_constant +hwmon_in.str_cons_0x030c_0x51=SLOT3_AVDD0V8 + +#slot3 in12 type +hwmon_in.mode_0x030c_0x52=str_constant +hwmon_in.str_cons_0x030c_0x52=cpld + +#slot3 in12 max +hwmon_in.mode_0x030c_0x53=str_constant +hwmon_in.str_cons_0x030c_0x53=877 + +#slot3 in12 min +hwmon_in.mode_0x030c_0x55=str_constant +hwmon_in.str_cons_0x030c_0x55=776 + +#slot4 in1 input +hwmon_in.mode_0x0401_0x50=config +hwmon_in.int_cons_0x0401_0x50=0 +hwmon_in.src_0x0401_0x50=cpld +hwmon_in.frmt_0x0401_0x50=num_bytes +hwmon_in.addr_0x0401_0x50=0x04000041 +hwmon_in.len_0x0401_0x50=2 +hwmon_in.int_extra1_0x0401_0x50=0x04000047 +hwmon_in.int_extra2_0x0401_0x50=2480 + +#slot4 in1 alais +hwmon_in.mode_0x0401_0x51=str_constant +hwmon_in.str_cons_0x0401_0x51=SLOT4_VDD3v3_QSFP_1 + +#slot4 in1 type +hwmon_in.mode_0x0401_0x52=str_constant +hwmon_in.str_cons_0x0401_0x52=cpld + +#slot4 in1 max +hwmon_in.mode_0x0401_0x53=str_constant +hwmon_in.str_cons_0x0401_0x53=3500 + +#slot4 in1 min +hwmon_in.mode_0x0401_0x55=str_constant +hwmon_in.str_cons_0x0401_0x55=3135 + +#slot4 in2 input +hwmon_in.mode_0x0402_0x50=config +hwmon_in.int_cons_0x0402_0x50=0 +hwmon_in.src_0x0402_0x50=cpld +hwmon_in.frmt_0x0402_0x50=num_bytes +hwmon_in.addr_0x0402_0x50=0x04000043 +hwmon_in.len_0x0402_0x50=2 +hwmon_in.int_extra1_0x0402_0x50=0x04000047 +hwmon_in.int_extra2_0x0402_0x50=2480 + +#slot4 in2 alais +hwmon_in.mode_0x0402_0x51=str_constant +hwmon_in.str_cons_0x0402_0x51=SLOT4_VDD3v3_QSFP_2 + +#slot4 in2 type +hwmon_in.mode_0x0402_0x52=str_constant +hwmon_in.str_cons_0x0402_0x52=cpld + +#slot4 in2 max +hwmon_in.mode_0x0402_0x53=str_constant +hwmon_in.str_cons_0x0402_0x53=3500 + +#slot4 in2 min +hwmon_in.mode_0x0402_0x55=str_constant +hwmon_in.str_cons_0x0402_0x55=3135 + +#slot4 in3 input +hwmon_in.mode_0x0403_0x50=config +hwmon_in.int_cons_0x0403_0x50=0 +hwmon_in.src_0x0403_0x50=cpld +hwmon_in.frmt_0x0403_0x50=num_bytes +hwmon_in.addr_0x0403_0x50=0x04000045 +hwmon_in.len_0x0403_0x50=2 +hwmon_in.int_extra1_0x0403_0x50=0x04000047 +hwmon_in.int_extra2_0x0403_0x50=1240 + +#slot4 in3 alais +hwmon_in.mode_0x0403_0x51=str_constant +hwmon_in.str_cons_0x0403_0x51=SLOT4_VDD1v8 + +#slot4 in3 type +hwmon_in.mode_0x0403_0x52=str_constant +hwmon_in.str_cons_0x0403_0x52=cpld + +#slot4 in3 max +hwmon_in.mode_0x0403_0x53=str_constant +hwmon_in.str_cons_0x0403_0x53=1926 + +#slot4 in3 min +hwmon_in.mode_0x0403_0x55=str_constant +hwmon_in.str_cons_0x0403_0x55=1710 + +#slot4 in4 input +hwmon_in.mode_0x0404_0x50=config +hwmon_in.int_cons_0x0404_0x50=0 +hwmon_in.src_0x0404_0x50=cpld +hwmon_in.frmt_0x0404_0x50=num_bytes +hwmon_in.addr_0x0404_0x50=0x04000047 +hwmon_in.len_0x0404_0x50=2 +hwmon_in.int_extra1_0x0404_0x50=0x04000047 +hwmon_in.int_extra2_0x0404_0x50=1000 + +#slot4 in4 alais +hwmon_in.mode_0x0404_0x51=str_constant +hwmon_in.str_cons_0x0404_0x51=SLOT4_TEST1v24 + +#slot4 in4 type +hwmon_in.mode_0x0404_0x52=str_constant +hwmon_in.str_cons_0x0404_0x52=cpld + +#slot4 in4 max +hwmon_in.mode_0x0404_0x53=str_constant +hwmon_in.str_cons_0x0404_0x53=1302 + +#slot4 in4 min +hwmon_in.mode_0x0404_0x55=str_constant +hwmon_in.str_cons_0x0404_0x55=1178 + +#slot4 in5 input +hwmon_in.mode_0x0405_0x50=config +hwmon_in.int_cons_0x0405_0x50=0 +hwmon_in.src_0x0405_0x50=cpld +hwmon_in.frmt_0x0405_0x50=num_bytes +hwmon_in.addr_0x0405_0x50=0x04000049 +hwmon_in.len_0x0405_0x50=2 +hwmon_in.int_extra1_0x0405_0x50=0x04000047 +hwmon_in.int_extra2_0x0405_0x50=2480 + +#slot4 in5 alais +hwmon_in.mode_0x0405_0x51=str_constant +hwmon_in.str_cons_0x0405_0x51=SLOT4_VDD3v3_CLK + +#slot4 in5 type +hwmon_in.mode_0x0405_0x52=str_constant +hwmon_in.str_cons_0x0405_0x52=cpld + +#slot4 in5 max +hwmon_in.mode_0x0405_0x53=str_constant +hwmon_in.str_cons_0x0405_0x53=3556 + +#slot4 in5 min +hwmon_in.mode_0x0405_0x55=str_constant +hwmon_in.str_cons_0x0405_0x55=3135 + +#slot4 in6 input +hwmon_in.mode_0x0406_0x50=config +hwmon_in.int_cons_0x0406_0x50=0 +hwmon_in.src_0x0406_0x50=cpld +hwmon_in.frmt_0x0406_0x50=num_bytes +hwmon_in.addr_0x0406_0x50=0x0400004b +hwmon_in.len_0x0406_0x50=2 +hwmon_in.int_extra1_0x0406_0x50=0x04000047 +hwmon_in.int_extra2_0x0406_0x50=2480 + +#slot4 in6 alais +hwmon_in.mode_0x0406_0x51=str_constant +hwmon_in.str_cons_0x0406_0x51=SLOT4_VDD5v0 + +#slot4 in6 type +hwmon_in.mode_0x0406_0x52=str_constant +hwmon_in.str_cons_0x0406_0x52=cpld + +#slot4 in6 max +hwmon_in.mode_0x0406_0x53=str_constant +hwmon_in.str_cons_0x0406_0x53=5331 + +#slot4 in6 min +hwmon_in.mode_0x0406_0x55=str_constant +hwmon_in.str_cons_0x0406_0x55=4750 + +#slot4 in7 input +hwmon_in.mode_0x0407_0x50=config +hwmon_in.int_cons_0x0407_0x50=0 +hwmon_in.src_0x0407_0x50=cpld +hwmon_in.frmt_0x0407_0x50=num_bytes +hwmon_in.addr_0x0407_0x50=0x0400004d +hwmon_in.len_0x0407_0x50=2 +hwmon_in.int_extra1_0x0407_0x50=0x04000047 +hwmon_in.int_extra2_0x0407_0x50=2480 + +#slot4 in7 alais +hwmon_in.mode_0x0407_0x51=str_constant +hwmon_in.str_cons_0x0407_0x51=SLOT4_VDD3v7_CLK_MCU + +#slot4 in7 type +hwmon_in.mode_0x0407_0x52=str_constant +hwmon_in.str_cons_0x0407_0x52=cpld + +#slot4 in7 max +hwmon_in.mode_0x0407_0x53=str_constant +hwmon_in.str_cons_0x0407_0x53=4022 + +#slot4 in7 min +hwmon_in.mode_0x0407_0x55=str_constant +hwmon_in.str_cons_0x0407_0x55=3639 + +#slot4 in8 input +hwmon_in.mode_0x0408_0x50=config +hwmon_in.int_cons_0x0408_0x50=0 +hwmon_in.src_0x0408_0x50=cpld +hwmon_in.frmt_0x0408_0x50=num_bytes +hwmon_in.addr_0x0408_0x50=0x0400004f +hwmon_in.len_0x0408_0x50=2 +hwmon_in.int_extra1_0x0408_0x50=0x04000047 +hwmon_in.int_extra2_0x0408_0x50=1240 + +#slot4 in8 alais +hwmon_in.mode_0x0408_0x51=str_constant +hwmon_in.str_cons_0x0408_0x51=SLOT4_VDD1v2 + +#slot4 in8 type +hwmon_in.mode_0x0408_0x52=str_constant +hwmon_in.str_cons_0x0408_0x52=cpld + +#slot4 in8 max +hwmon_in.mode_0x0408_0x53=str_constant +hwmon_in.str_cons_0x0408_0x53=1260 + +#slot4 in8 min +hwmon_in.mode_0x0408_0x55=str_constant +hwmon_in.str_cons_0x0408_0x55=1140 + +#slot4 in9 input +hwmon_in.mode_0x0409_0x50=config +hwmon_in.int_cons_0x0409_0x50=0 +hwmon_in.src_0x0409_0x50=cpld +hwmon_in.frmt_0x0409_0x50=num_bytes +hwmon_in.addr_0x0409_0x50=0x04000051 +hwmon_in.len_0x0409_0x50=2 +hwmon_in.int_extra1_0x0409_0x50=0x04000047 +hwmon_in.int_extra2_0x0409_0x50=2480 + +#slot4 in9 alais +hwmon_in.mode_0x0409_0x51=str_constant +hwmon_in.str_cons_0x0409_0x51=SLOT4_VDD3v3 + +#slot4 in9 type +hwmon_in.mode_0x0409_0x52=str_constant +hwmon_in.str_cons_0x0409_0x52=cpld + +#slot4 in9 max +hwmon_in.mode_0x0409_0x53=str_constant +hwmon_in.str_cons_0x0409_0x53=3539 + +#slot4 in9 min +hwmon_in.mode_0x0409_0x55=str_constant +hwmon_in.str_cons_0x0409_0x55=3135 + +#slot4 in10 input +hwmon_in.mode_0x040a_0x50=config +hwmon_in.int_cons_0x040a_0x50=0 +hwmon_in.src_0x040a_0x50=cpld +hwmon_in.frmt_0x040a_0x50=num_bytes +hwmon_in.addr_0x040a_0x50=0x04000053 +hwmon_in.len_0x040a_0x50=2 +hwmon_in.int_extra1_0x040a_0x50=0x04000047 +hwmon_in.int_extra2_0x040a_0x50=1240 + +#slot4 in10 alais +hwmon_in.mode_0x040a_0x51=str_constant +hwmon_in.str_cons_0x040a_0x51=SLOT4_DVDD_0V8 + +#slot4 in10 type +hwmon_in.mode_0x040a_0x52=str_constant +hwmon_in.str_cons_0x040a_0x52=cpld + +#slot4 in10 max +hwmon_in.mode_0x040a_0x53=str_constant +hwmon_in.str_cons_0x040a_0x53=772 + +#slot4 in10 min +hwmon_in.mode_0x040a_0x55=str_constant +hwmon_in.str_cons_0x040a_0x55=684 + +#slot4 in11 input +hwmon_in.mode_0x040b_0x50=config +hwmon_in.int_cons_0x040b_0x50=0 +hwmon_in.src_0x040b_0x50=cpld +hwmon_in.frmt_0x040b_0x50=num_bytes +hwmon_in.addr_0x040b_0x50=0x04000055 +hwmon_in.len_0x040b_0x50=2 +hwmon_in.int_extra1_0x040b_0x50=0x04000047 +hwmon_in.int_extra2_0x040b_0x50=1240 + +#slot4 in11 alais +hwmon_in.mode_0x040b_0x51=str_constant +hwmon_in.str_cons_0x040b_0x51=SLOT4_VDD1V8_CPLD + +#slot4 in11 type +hwmon_in.mode_0x040b_0x52=str_constant +hwmon_in.str_cons_0x040b_0x52=cpld + +#slot4 in11 max +hwmon_in.mode_0x040b_0x53=str_constant +hwmon_in.str_cons_0x040b_0x53=1909 + +#slot4 in11 min +hwmon_in.mode_0x040b_0x55=str_constant +hwmon_in.str_cons_0x040b_0x55=1710 + +#slot4 in12 input +hwmon_in.mode_0x040c_0x50=config +hwmon_in.int_cons_0x040c_0x50=0 +hwmon_in.src_0x040c_0x50=cpld +hwmon_in.frmt_0x040c_0x50=num_bytes +hwmon_in.addr_0x040c_0x50=0x04000057 +hwmon_in.len_0x040c_0x50=2 +hwmon_in.int_extra1_0x040c_0x50=0x04000047 +hwmon_in.int_extra2_0x040c_0x50=1240 + +#slot4 in12 alais +hwmon_in.mode_0x040c_0x51=str_constant +hwmon_in.str_cons_0x040c_0x51=SLOT4_AVDD0V8 + +#slot4 in12 type +hwmon_in.mode_0x040c_0x52=str_constant +hwmon_in.str_cons_0x040c_0x52=cpld + +#slot4 in12 max +hwmon_in.mode_0x040c_0x53=str_constant +hwmon_in.str_cons_0x040c_0x53=877 + +#slot4 in12 min +hwmon_in.mode_0x040c_0x55=str_constant +hwmon_in.str_cons_0x040c_0x55=776 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/cfg_file_name new file mode 100755 index 000000000000..d31debee1cd2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,6 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF +WB_PLAT_SENSOR +WB_PLAT_SLOT diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py old mode 100644 new mode 100755 index f36055fb4e6d..6c3916921abb --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py @@ -3,18 +3,25 @@ setup( name='sonic-platform', version='1.0', - description='SONiC platform API implementation on RAGILE Platforms', + description='SONiC platform API implementation', license='Apache 2.0', author='SONiC Team', - author_email='support@ragile.com', + author_email='support', url='', - maintainer='RAGILE SUPPORT TEAM', + maintainer='support', maintainer_email='', packages=[ 'sonic_platform', - 'rgutil', + 'plat_hal', + 'wbutil', 'eepromutil', - 'sonic_pcie', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', ], classifiers=[ 'Development Status :: 3 - Alpha', @@ -30,4 +37,3 @@ ], keywords='sonic SONiC platform PLATFORM', ) - diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index c1f70dc7be65..5c40f413ff5f 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -167,6 +167,7 @@ ifp_inports_support_enable port_flex_enable pdma_descriptor_prefetch_enable pktdma_poll_mode_channel_bitmap +warmboot_knet_shutdown_mode num_queues_pci num_queues_uc0 num_queues_uc1 @@ -312,3 +313,8 @@ port_gmii_mode phy_force_firmware_load phy_pcs_repeater l3_alpm_hit_skip +sai_fdb_entry_l2_discard_src_enable +svi_my_station_optimization +sai_nbr_bcast_ifp_optimized +sai_pfc_defaults_disable +sai_optimized_mmu From 668a0069522731d77948547532e0d7af269c72d9 Mon Sep 17 00:00:00 2001 From: pettershao-ragilenetworks Date: Mon, 27 Mar 2023 04:36:50 -0400 Subject: [PATCH 2/4] [Platform/Ragile] Adapt kernel 5.10 for broadcom Signed-off-by: pettershao-ragilenetworks --- .../td3-ra-b6510-32c-32x100G.config.bcm | 31 +- .../x86_64-ragile_ra-b6510-32c-r0/bcm.rc | 1 - .../x86_64-ragile_ra-b6510-32c-r0/bcm_pre.rc | 1 - .../cancun/sdk_6.5.12/bcm56870_a0_cch.pkg | Bin 28736 -> 0 bytes .../cancun/sdk_6.5.12/bcm56870_a0_ceh.pkg | Bin 6044 -> 0 bytes .../cancun/sdk_6.5.12/bcm56870_a0_cfh.pkg | Bin 46376 -> 0 bytes .../cancun/sdk_6.5.12/bcm56870_a0_cih.pkg | Bin 736164 -> 0 bytes .../cancun/sdk_6.5.12/bcm56870_a0_cmh.pkg | Bin 3612 -> 0 bytes .../cancun/sdk_6.5.13/bcm56870_a0_cch.pkg | Bin 34788 -> 0 bytes .../cancun/sdk_6.5.13/bcm56870_a0_ceh.pkg | Bin 6384 -> 0 bytes .../cancun/sdk_6.5.13/bcm56870_a0_cfh.pkg | Bin 42228 -> 0 bytes .../cancun/sdk_6.5.13/bcm56870_a0_cih.pkg | Bin 754308 -> 0 bytes .../cancun/sdk_6.5.13/bcm56870_a0_cmh.pkg | Bin 3816 -> 0 bytes .../cancun/sdk_6.5.14/bcm56870_a0_cch.pkg | Bin 34720 -> 0 bytes .../cancun/sdk_6.5.14/bcm56870_a0_ceh.pkg | Bin 6384 -> 0 bytes .../cancun/sdk_6.5.14/bcm56870_a0_cfh.pkg | Bin 42228 -> 0 bytes .../cancun/sdk_6.5.14/bcm56870_a0_cih.pkg | Bin 754308 -> 0 bytes .../cancun/sdk_6.5.14/bcm56870_a0_cmh.pkg | Bin 3808 -> 0 bytes .../cancun/sdk_6.5.16/bcm56870_a0_cch.pkg | Bin 35136 -> 0 bytes .../cancun/sdk_6.5.16/bcm56870_a0_ceh.pkg | Bin 6384 -> 0 bytes .../cancun/sdk_6.5.16/bcm56870_a0_cfh.pkg | Bin 42228 -> 0 bytes .../cancun/sdk_6.5.16/bcm56870_a0_cih.pkg | Bin 754308 -> 0 bytes .../cancun/sdk_6.5.16/bcm56870_a0_cmh.pkg | Bin 3808 -> 0 bytes .../x86_64-ragile_ra-b6510-32c-r0/dev.xml | 535 +- .../dev_exhaust.xml | 431 + .../x86_64-ragile_ra-b6510-32c-r0/fru.py | 115 +- .../installer.conf | 1 - .../minigraph.xml | 63 - .../x86_64-ragile_ra-b6510-32c-r0/monitor.py | 419 +- .../x86_64-ragile_ra-b6510-32c-r0/pcie.yaml | 440 + .../pddf/pd-plugin.json | 67 - .../pddf/pddf-device.json | 4471 ----- .../plugins/eeprom.py | 13 - .../plugins/psuutil.py | 63 - .../plugins/sfputil.py | 145 +- .../plugins/ssd_util.py | 309 + .../sensors.conf | 21 - ...t => system_health_monitoring_config.json} | 0 .../x86_64-ragile_ra-b6510-32c-r0/systest.py | 43 - .../RA-B6510-48V8C/port_config.ini | 114 +- .../RA-B6510-48V8C/sai.profile | 2 +- ...3-ra-b6510-48v8c-48x25G+8x100G.config.bcm} | 677 +- .../custom_led.bin | Bin 300 -> 236 bytes .../x86_64-ragile_ra-b6510-48v8c-r0/dev.xml | 508 +- .../dev_exhaust.xml | 418 + .../x86_64-ragile_ra-b6510-48v8c-r0/fru.py | 961 ++ .../monitor.py | 376 +- .../x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml | 21 +- .../pddf/pd-plugin.json | 67 - .../pddf/pddf-device.json | 6332 ------- .../plugins/sfputil.py | 243 + .../plugins/ssd_util.py | 309 + .../pmon_daemon_control.json | 8 +- .../sensors.conf | 21 - .../sonic_platform_config/chassis.json | 3 - .../sonic_platform_config/component.json | 60 - .../sonic_platform_config/fan.json | 152 - .../sonic_platform_config/psu.json | 134 - .../sonic_platform_config/thermal.json | 130 - ...t => system_health_monitoring_config.json} | 0 .../systest.py | 43 - .../th2-ra-b6910-64c-64x100G.config.bcm | 5 + .../x86_64-ragile_ra-b6910-64c-r0/bcm.rc | 1 - .../x86_64-ragile_ra-b6910-64c-r0/dev.xml | 178 +- .../fantlv.py | 65 +- .../x86_64-ragile_ra-b6910-64c-r0/fru.py | 961 ++ .../minigraph.xml | 63 - .../x86_64-ragile_ra-b6910-64c-r0/monitor.py | 445 +- .../pddf/pd-plugin.json | 67 - .../pddf/pddf-device.json | 7012 -------- .../plugins/eeprom.py | 25 - .../plugins/fanutil.py | 199 - .../plugins/ledutil.py | 59 - .../plugins/psuutil.py | 270 - .../plugins/sfputil.py | 390 +- .../plugins/ssd_util.py | 309 + .../plugins/sysstatutil.py | 82 - .../plugins/thermalutil.py | 75 - .../pmon_daemon_control.json | 6 +- .../sensors.conf | 21 - .../sonic_platform_config/chassis.json | 3 - .../sonic_platform_config/component.json | 60 - .../sonic_platform_config/fan.json | 152 - .../sonic_platform_config/psu.json | 134 - .../sonic_platform_config/thermal.json | 130 - .../system_health_monitoring_config.json} | 0 .../x86_64-ragile_ra-b6910-64c-r0/systest.py | 43 - .../RA-B6920-4S/cust_plp.cfg | 843 + .../th3-ra-b6920-4s-128x100G.config.bcm | 233 +- .../x86_64-ragile_ra-b6920-4s-r0/bcm.rc | 1 - .../x86_64-ragile_ra-b6920-4s-r0/bcm_pre.rc | 1 - .../x86_64-ragile_ra-b6920-4s-r0/dev.xml | 734 +- .../device_data.json | 3716 ----- .../x86_64-ragile_ra-b6920-4s-r0/fru.py | 961 ++ .../minigraph.xml | 63 - .../x86_64-ragile_ra-b6920-4s-r0/monitor.py | 416 +- .../x86_64-ragile_ra-b6920-4s-r0/pcie.yaml | 441 + .../pddf/pd-plugin.json | 67 - .../pddf/pddf-device.json | 13877 ---------------- .../x86_64-ragile_ra-b6920-4s-r0/pddf_support | 0 .../platform_components.json | 21 - .../platform_env.conf | 0 .../plugins/eeprom.py | 13 - .../plugins/psuutil.py | 59 - .../plugins/sfputil.py | 149 +- .../plugins/ssd_util.py | 277 +- .../x86_64-ragile_ra-b6920-4s-r0/sensors.conf | 14 - .../system_health_monitoring_config.json} | 0 .../x86_64-ragile_ra-b6920-4s-r0/systest.py | 43 - platform/broadcom/platform-modules-ragile.mk | 2 +- platform/broadcom/rules.mk | 2 +- .../sonic-platform-modules-ragile/LICENSE | 1 - .../common/Makefile | 27 +- .../common/app/Makefile | 25 + .../common/app/dev_util/Makefile | 30 + .../common/app/dev_util/dfd_debug.c | 43 + .../common/app/dev_util/dfd_utest.c | 1802 ++ .../common/app/dev_util/dfd_utest.h | 103 + .../common/app/firmware_upgrade/Makefile | 19 + .../common/app/firmware_upgrade/Rules.mk | 42 + .../firmware_upgrade/firmware_driver/Makefile | 19 + .../firmware_driver_cpld/Makefile | 23 + .../firmware_driver_cpld/firmware.c | 144 + .../firmware_driver_cpld/firmware_cpld.c | 384 + .../firmware_cpld_upgrade.c | 1879 +++ .../firmware_driver_cpld/include/firmware.h | 82 + .../include/firmware_cpld.h | 64 + .../firmware_driver_cpld/include/jbi.h | 15 + .../firmware_driver_cpld/jbicomp.c | 438 + .../firmware_driver_cpld/jbicomp.h | 37 + .../firmware_driver_cpld/jbiexprt.h | 224 + .../firmware_driver_cpld/jbijtag.c | 1679 ++ .../firmware_driver_cpld/jbijtag.h | 146 + .../firmware_driver_cpld/jbimain.c | 3362 ++++ .../firmware_driver_cpld/jbiport.h | 45 + .../firmware_driver_cpld/jbistub.c | 2518 +++ .../firmware_driver_cpld/jbistub.h | 95 + .../firmware_driver_ispvme/Makefile | 22 + .../firmware_cpld_ispvme.c | 450 + .../firmware_cpld_upgrade_ispvme.c | 691 + .../firmware_driver_ispvme/firmware_ispvme.c | 140 + .../include/firmware_cpld_ispvme.h | 70 + .../include/firmware_ispvme.h | 86 + .../firmware_driver_sysfs/Makefile | 22 + .../firmware_driver_sysfs/firmware.c | 143 + .../firmware_driver_sysfs/firmware_sysfs.c | 495 + .../firmware_sysfs_upgrade.c | 258 + .../include/firmware_sysfs.h | 88 + .../include/firmware_sysfs_upgrade.h | 72 + .../include/firmware_upgrade.h | 57 + .../firmware_upgrade/Makefile | 33 + .../firmware_upgrade/firmware_upgrade/crc32.c | 216 + .../firmware_upgrade/firmware_upgrade/debug.c | 60 + .../firmware_upgrade/firmware_app.c | 985 ++ .../fw_upg_gpio_vme/hardware.c | 263 + .../fw_upg_gpio_vme/ispvm_ui.c | 837 + .../fw_upg_gpio_vme/ivm_core.c | 3097 ++++ .../fw_upg_isc/firmware_upgrade_isc.c | 68 + .../fw_upg_mtd/firmware_upgrade_mtd.c | 446 + .../fw_upg_mtd/firmware_upgrade_mtd.h | 32 + .../firmware_upgrade/fw_upg_mtd/mtd-abi.h | 259 + .../fw_upg_sysfs/firmware_upgrade_sysfs.c | 285 + .../fw_upg_sysfs/firmware_upgrade_sysfs.h | 16 + .../fw_upg_sysfs/fw_upg_spi_logic_dev.c | 1181 ++ .../fw_upg_sysfs/fw_upg_spi_logic_dev.h | 90 + .../firmware_upgrade/include/debug.h | 34 + .../firmware_upgrade/include/firmware_app.h | 172 + .../firmware_upgrade/include/vmopcode.h | 192 + .../common/app/fw_upgrade/Makefile | 18 + .../common/app/fw_upgrade/Rules.mk | 42 + .../common/app/fw_upgrade/fw_upgrade/Makefile | 39 + .../app/fw_upgrade/fw_upgrade/fw_upgrade.c | 1632 ++ .../fw_upgrade/fw_upgrade/fw_upgrade_debug.c | 51 + .../fw_upgrade/include/fw_upgrade.h | 230 + .../fw_upgrade/include/fw_upgrade_debug.h | 25 + .../common/depmod_conf/distsearch.conf | 4 - .../lib/{rgutil => algorithm}/__init__.py | 0 .../common/lib/algorithm/hysteresis.py | 169 + .../common/lib/algorithm/openloop.py | 104 + .../common/lib/algorithm/pid.py | 106 + .../common/lib/eepromutil/fantlv.py | 76 +- .../common/lib/eepromutil/fru.py | 121 +- .../common/lib/eepromutil/onietlv.py | 441 + .../common/lib/plat_hal/__init__.py | 0 .../common/lib/plat_hal/baseutil.py | 164 + .../common/lib/plat_hal/chassisbase.py | 318 + .../common/lib/plat_hal/component.py | 33 + .../common/lib/plat_hal/cpld.py | 66 + .../common/lib/plat_hal/cpu.py | 34 + .../common/lib/plat_hal/dcdc.py | 11 + .../common/lib/plat_hal/devicebase.py | 355 + .../common/lib/plat_hal/fan.py | 413 + .../common/lib/plat_hal/interface.py | 1311 ++ .../common/lib/plat_hal/led.py | 52 + .../common/lib/plat_hal/onie_e2.py | 127 + .../common/lib/plat_hal/osutil.py | 440 + .../common/lib/plat_hal/psu.py | 607 + .../common/lib/plat_hal/rotor.py | 149 + .../common/lib/plat_hal/sensor.py | 219 + .../common/lib/plat_hal/temp.py | 139 + .../common/lib/rgutil/logutil.py | 67 - .../common/lib/wbutil/__init__.py | 0 .../common/lib/{rgutil => wbutil}/baseutil.py | 23 +- .../common/lib/{rgutil => wbutil}/smbus.py | 93 +- .../kernel_drivers_blacklist.conf | 5 + .../common/modules/Makefile | 70 +- .../common/modules/csu550.c | 209 - .../common/modules/dfd_tlveeprom.c | 516 + .../common/modules/dfd_tlveeprom.h | 121 + .../common/modules/fpga_i2c.h | 133 + .../common/modules/fpga_i2c_ocores.c | 906 - .../common/modules/fpga_i2c_ocores.h | 13 - .../common/modules/fpga_pcie_i2c.c | 1144 -- .../common/modules/fpga_pcie_i2c.h | 107 - .../common/modules/fpga_reg_defs.h | 174 - .../common/modules/i2c-mux-pca954x.c | 1413 -- .../common/modules/i2c-mux-pca9641.c | 643 - .../common/modules/intel_spi/Makefile | 21 + .../modules/intel_spi/include/intel_spi.h | 23 + .../common/modules/intel_spi/intel_spi.c | 969 ++ .../modules/intel_spi/intel_spi_platform.c | 167 + .../common/modules/linux-5.10/Makefile | 34 + .../common/modules/linux-5.10/wb_at24.c | 861 + .../common/modules/linux-5.10/wb_csu550.c | 238 + .../modules/linux-5.10/wb_i2c_algo_bit.c | 725 + .../common/modules/linux-5.10/wb_i2c_gpio.c | 431 + .../modules/linux-5.10/wb_i2c_gpio_device.c | 110 + .../common/modules/linux-5.10/wb_i2c_i801.c | 2114 +++ .../modules/linux-5.10/wb_i2c_mux_pca954x.c | 1343 ++ .../modules/linux-5.10/wb_i2c_mux_pca954x.h | 67 + .../modules/linux-5.10/wb_i2c_mux_pca9641.c | 1375 ++ .../modules/linux-5.10/wb_i2c_mux_pca9641.h | 64 + .../common/modules/linux-5.10/wb_ina3221.c | 1031 ++ .../common/modules/linux-5.10/wb_isl68137.c | 572 + .../common/modules/linux-5.10/wb_lm75.c | 987 ++ .../common/modules/linux-5.10/wb_lm75.h | 40 + .../common/modules/linux-5.10/wb_pmbus.h | 535 + .../common/modules/linux-5.10/wb_pmbus_core.c | 2780 ++++ .../common/modules/linux-5.10/wb_tmp401.c | 798 + .../common/modules/linux-5.10/wb_tps53622.c | 265 + .../common/modules/linux-5.10/wb_ucd9000.c | 675 + .../common/modules/lpc_cpld_i2c_ocores.c | 837 - .../common/modules/lpc_cpld_i2c_ocores.h | 13 - .../common/modules/lpc_dbg.c | 534 - .../common/modules/lpc_dbg.h | 39 - .../common/modules/plat_sysfs/Makefile | 20 + .../modules/plat_sysfs/dev_cfg/Makefile | 25 + .../modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c | 812 + .../plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c | 351 + .../plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c | 236 + .../plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c | 587 + .../plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c | 82 + .../plat_sysfs/dev_cfg/dfd_fan_driver.c | 170 + .../modules/plat_sysfs/dev_cfg/dfd_module.c | 95 + .../plat_sysfs/dev_cfg/dfd_psu_driver.c | 70 + .../plat_sysfs/dev_cfg/dfd_sensors_driver.c | 149 + .../plat_sysfs/dev_cfg/dfd_sff_driver.c | 56 + .../plat_sysfs/dev_cfg/dfd_slot_driver.c | 27 + .../plat_sysfs/dev_cfg/include/dfd_cfg.h | 97 + .../dev_cfg/include/dfd_cfg_adapter.h | 46 + .../plat_sysfs/dev_cfg/include/dfd_cfg_file.h | 37 + .../plat_sysfs/dev_cfg/include/dfd_cfg_info.h | 109 + .../dev_cfg/include/dfd_cfg_listnode.h | 30 + .../dev_cfg/include/dfd_fan_driver.h | 18 + .../plat_sysfs/dev_cfg/include/dfd_module.h | 96 + .../dev_cfg/include/dfd_psu_driver.h | 10 + .../dev_cfg/include/dfd_sensors_driver.h | 10 + .../dev_cfg/include/dfd_sff_driver.h | 8 + .../dev_cfg/include/dfd_slot_driver.h | 6 + .../modules/plat_sysfs/dev_sysfs/Makefile | 21 + .../dev_sysfs/include/plat_switch.h | 86 + .../dev_sysfs/include/sysfs_common.h | 90 + .../modules/plat_sysfs/dev_sysfs/plat_fan.c | 505 + .../modules/plat_sysfs/dev_sysfs/plat_psu.c | 430 + .../plat_sysfs/dev_sysfs/plat_sensor.c | 457 + .../modules/plat_sysfs/dev_sysfs/plat_sff.c | 291 + .../modules/plat_sysfs/dev_sysfs/plat_slot.c | 667 + .../plat_sysfs/dev_sysfs/plat_switch.c | 135 + .../common/modules/platform_common.h | 74 + .../common/modules/platform_common_module.c | 210 + .../common/modules/pmbus.h | 466 - .../common/modules/ragile_common_module.c | 79 - .../common/modules/ragile_platform.c | 97 - .../common/modules/rg-gpio-xeon.c | 357 - .../common/modules/rg-i2c-algo-bit.c | 734 - .../common/modules/rg-i2c-gpio.c | 431 - .../common/modules/rg_fan.c | 266 - .../common/modules/rg_psu.c | 340 - .../common/modules/spi-bitbang-txrx.h | 107 + .../common/modules/wb_eeprom_93xx46.c | 558 + .../common/modules/wb_fpga_i2c_bus_drv.c | 1103 ++ .../common/modules/wb_fpga_pca954x_drv.c | 525 + .../common/modules/wb_fpga_pcie.c | 164 + .../common/modules/wb_gpio_d1500.c | 367 + .../common/modules/wb_gpio_device.c | 54 + .../common/modules/wb_i2c_dev.c | 774 + .../common/modules/wb_i2c_dev.h | 20 + .../common/modules/wb_i2c_ocores.c | 1143 ++ .../common/modules/wb_i2c_ocores.h | 28 + .../common/modules/wb_io_dev.c | 571 + .../common/modules/wb_io_dev.h | 21 + .../common/modules/wb_lpc_drv.c | 166 + .../common/modules/wb_lpc_drv.h | 18 + .../common/modules/wb_mac_bsc.c | 660 + .../common/modules/wb_optoe.c | 1192 ++ .../common/modules/wb_pcie_dev.c | 770 + .../common/modules/wb_pcie_dev.h | 26 + .../common/modules/wb_platform_i2c_dev.c | 749 + .../common/modules/wb_platform_i2c_dev.h | 19 + .../common/modules/wb_spi_93xx46.c | 111 + .../common/modules/wb_spi_dev.c | 583 + .../common/modules/wb_spi_dev.h | 16 + .../common/modules/wb_spi_gpio.c | 477 + .../common/modules/wb_spi_gpio_device.c | 153 + .../common/modules/wb_spi_nor_device.c | 87 + .../common/modules/wb_spi_ocores.c | 1025 ++ .../common/modules/wb_spi_ocores.h | 21 + .../common/modules/wb_uio_irq.c | 282 + .../common/modules/wb_wdt.c | 1038 ++ .../common/modules/wb_wdt.h | 46 + .../common/modules/wb_xdpe132g5c.c | 574 + .../common/script/auto_update.py | 196 + .../common/script/avscontrol.py | 236 +- .../common/script/dev_monitor.py | 303 + .../common/script/device_i2c.py | 345 - .../common/script/fancontrol.py | 993 -- .../common/script/generate_airflow.py | 236 + .../common/script/hal_fanctrl.py | 1135 ++ .../common/script/hal_ledctrl.py | 830 + .../common/script/hal_pltfm.py | 475 + .../common/script/intelligent_monitor.py | 144 + .../script/intelligent_monitor/monitor_fan.py | 284 + .../common/script/platform_common.py | 178 + .../common/script/platform_config.py | 184 + .../common/script/platform_driver.py | 258 + .../common/script/platform_e2.py | 434 + .../common/script/platform_intf.py | 367 + .../common/script/platform_ipmi.py | 92 + .../common/script/platform_manufacturer.py | 591 + .../common/script/platform_process.py | 396 + .../common/script/platform_sensors.py | 253 + .../common/script/platform_test.py | 142 + .../common/script/platform_util.py | 845 + .../common/script/pmon_syslog.py | 519 + .../common/script/ragilecommon.py | 1365 -- .../common/script/ragileconfig.py | 225 - .../common/script/ragileutil.py | 2101 --- .../common/script/reboot_cause.py | 183 + .../common/script/reboot_ctrl.py | 150 + .../common/script/sensors | 8 + .../common/script/sfp_highest_temperatue.py | 148 + .../common/script/slot_monitor.py | 242 + .../common/script/ssdmon | 82 + .../common/script/tty_console.py | 91 + .../common/script/upgrade.py | 991 ++ .../common/script/warm_upgrade.py | 514 + .../common/service/device_i2c.service | 15 - .../common/service/platform_driver.service | 15 + .../common/service/platform_process.service | 15 + .../common/sonic_platform/__init__.py | 2 + .../common/sonic_platform/chassis.py | 520 + .../common/sonic_platform/component.py | 211 + .../common/sonic_platform/dcdc.py | 85 + .../common/sonic_platform/eeprom.py | 92 + .../common/sonic_platform/fan.py | 308 + .../common/sonic_platform/fan_drawer.py | 167 + .../common/sonic_platform/pcie.py | 21 + .../sonic_platform/platform.py | 19 +- .../common/sonic_platform/psu.py | 359 + .../common/sonic_platform/sfp.py | 480 + .../common/sonic_platform/thermal.py | 234 + .../common/sonic_platform/watchdog.py | 236 + .../debian/compat | 2 +- .../debian/control | 6 +- .../debian/copyright | 1 - ...form-modules-ragile-ra-b6510-48v8c.install | 2 +- ...orm-modules-ragile-ra-b6510-48v8c.postinst | 7 - ...latform-modules-ragile-ra-b6920-4s.install | 2 +- .../debian/rule-ragile.mk | 8 - .../debian/rules | 63 +- .../.upgrade_test/cpld_test_header.vme | Bin 0 -> 413 bytes .../.upgrade_test/fpga_test_header.bin | 10 + .../ra-b6510-32c/LICENSE | 15 - .../ra-b6510-32c/MAINTAINERS | 5 - .../ra-b6510-32c/Makefile | 16 +- .../ra-b6510-32c/README.md | 1 - .../x86_64_ragile_ra_b6510_32c_r0_config.py | 1288 +- ...6_64_ragile_ra_b6510_32c_r0_port_config.py | 7 + .../x86_64_ragile_ra_b6510_32c_r0_device.py | 1241 ++ ...4_ragile_ra_b6510_32c_r0_exhaust_device.py | 1240 ++ .../x86_64_ragile_ra_b6510_32c_r0_monitor.py | 150 + .../ra-b6510-32c/modules/driver/Makefile | 19 +- .../modules/driver/pddf_client_defs.h | 135 - .../modules/driver/pddf_custom_led_module.c | 736 - .../modules/driver/pddf_custom_psu.c | 104 - .../modules/driver/pddf_led_defs.h | 120 - .../ra-b6510-32c/modules/driver/rg_cpld.c | 495 - .../ra-b6510-32c/modules/driver/rg_lpc_cpld.c | 237 - .../driver/wb_firmware_upgrade_device.c | 178 + .../modules/driver/wb_i2c_dev_device.c | 125 + .../driver/wb_i2c_mux_pca954x_device.c | 224 + .../modules/driver/wb_i2c_ocores_device.c | 423 + .../modules/driver/wb_io_dev_device.c | 103 + .../modules/driver/wb_lpc_drv_device.c | 130 + .../modules/driver/wb_pcie_dev_device.c | 93 + .../plat_sysfs_cfg/WB_PLAT_CPLD.cfg | 38 + .../plat_sysfs_cfg/WB_PLAT_FAN.cfg | 372 + .../plat_sysfs_cfg/WB_PLAT_PSU.cfg | 64 + .../plat_sysfs_cfg/WB_PLAT_SFF.cfg | 306 + .../ra-b6510-32c/plat_sysfs_cfg/cfg_file_name | 4 + .../ra-b6510-32c/setup.py | 18 +- .../ra-b6510-32c/sonic_pcie/__init__.py | 1 - .../ra-b6510-32c/sonic_pcie/pcie_common.py | 107 - .../ra-b6510-32c/sonic_platform/__init__.py | 4 - .../ra-b6510-32c/sonic_platform/chassis.py | 108 - .../ra-b6510-32c/sonic_platform/common.py | 44 - .../ra-b6510-32c/sonic_platform/component.py | 85 - .../ra-b6510-32c/sonic_platform/config.py | 771 - .../ra-b6510-32c/sonic_platform/eeprom.py | 12 - .../ra-b6510-32c/sonic_platform/fan.py | 42 - .../ra-b6510-32c/sonic_platform/fan_drawer.py | 69 - .../ra-b6510-32c/sonic_platform/logger.py | 19 - .../ra-b6510-32c/sonic_platform/pcie.py | 43 - .../ra-b6510-32c/sonic_platform/platform.py | 23 - .../ra-b6510-32c/sonic_platform/psu.py | 32 - .../ra-b6510-32c/sonic_platform/regutil.py | 245 - .../ra-b6510-32c/sonic_platform/rotor.py | 41 - .../ra-b6510-32c/sonic_platform/sfp.py | 287 - .../ra-b6510-32c/sonic_platform/thermal.py | 14 - .../ra-b6510-32c/sonic_platform/watchdog.py | 21 - .../systemd/pddf-platform-init.service | 1 - .../.upgrade_test/cpld_test_header.vme | Bin 0 -> 406 bytes .../.upgrade_test/fpga_test_header.bin | 10 + .../ra-b6510-48v8c/LICENSE | 15 - .../ra-b6510-48v8c/MAINTAINERS | 5 - .../ra-b6510-48v8c/Makefile | 15 +- .../ra-b6510-48v8c/README.md | 1 - .../x86_64_ragile_ra_b6510_48v8c_r0_config.py | 1481 +- ...64_ragile_ra_b6510_48v8c_r0_port_config.py | 7 + .../x86_64_ragile_ra_b6510_48v8c_r0_device.py | 1212 ++ ...ragile_ra_b6510_48v8c_r0_exhaust_device.py | 1211 ++ ...x86_64_ragile_ra_b6510_48v8c_r0_monitor.py | 204 + .../ra-b6510-48v8c/modules/driver/Makefile | 16 +- .../ra-b6510-48v8c/modules/driver/rg_cpld.c | 602 - .../driver/wb_firmware_upgrade_device.c | 178 + .../modules/driver/wb_i2c_dev_device.c | 140 + .../driver/wb_i2c_mux_pca954x_device.c | 296 + .../modules/driver/wb_i2c_ocores_device.c | 423 + .../modules/driver/wb_io_dev_device.c | 103 + .../modules/driver/wb_lpc_drv_device.c | 130 + .../modules/driver/wb_pcie_dev_device.c | 93 + .../plat_sysfs_cfg/WB_PLAT_CPLD.cfg | 41 + .../plat_sysfs_cfg/WB_PLAT_FAN.cfg | 304 + .../plat_sysfs_cfg/WB_PLAT_PSU.cfg | 64 + .../plat_sysfs_cfg/WB_PLAT_SFF.cfg | 521 + .../plat_sysfs_cfg/cfg_file_name | 4 + .../scripts/pddf_post_driver_install.sh | 31 - .../ra-b6510-48v8c/setup.py | 18 +- .../ra-b6510-48v8c/sonic_pcie/__init__.py | 1 - .../ra-b6510-48v8c/sonic_pcie/pcie_common.py | 107 - .../ra-b6510-48v8c/sonic_platform/__init__.py | 4 - .../ra-b6510-48v8c/sonic_platform/chassis.py | 135 - .../ra-b6510-48v8c/sonic_platform/common.py | 44 - .../sonic_platform/component.py | 85 - .../ra-b6510-48v8c/sonic_platform/config.py | 558 - .../ra-b6510-48v8c/sonic_platform/eeprom.py | 12 - .../ra-b6510-48v8c/sonic_platform/fan.py | 36 - .../sonic_platform/fan_drawer.py | 71 - .../ra-b6510-48v8c/sonic_platform/logger.py | 19 - .../ra-b6510-48v8c/sonic_platform/pcie.py | 43 - .../ra-b6510-48v8c/sonic_platform/platform.py | 23 - .../ra-b6510-48v8c/sonic_platform/psu.py | 32 - .../ra-b6510-48v8c/sonic_platform/regutil.py | 245 - .../ra-b6510-48v8c/sonic_platform/rotor.py | 41 - .../ra-b6510-48v8c/sonic_platform/sfp.py | 15 - .../ra-b6510-48v8c/sonic_platform/thermal.py | 14 - .../ra-b6510-48v8c/sonic_platform/watchdog.py | 21 - .../systemd/pddf-platform-init.service | 1 - .../.upgrade_test/cpld_test_header.vme | Bin 0 -> 357 bytes .../ra-b6910-64c/LICENSE | 15 - .../ra-b6910-64c/MAINTAINERS | 5 - .../ra-b6910-64c/Makefile | 15 +- .../ra-b6910-64c/README.md | 1 - .../x86_64_ragile_ra_b6910_64c_r0_config.py | 1169 +- ...6_64_ragile_ra_b6910_64c_r0_port_config.py | 7 + .../x86_64_ragile_ra_b6910_64c_r0_device.py | 700 + .../x86_64_ragile_ra_b6910_64c_r0_monitor.py | 115 + .../ra-b6910-64c/modules/driver/Makefile | 15 +- .../modules/driver/platform_common.h} | 16 +- .../ra-b6910-64c/modules/driver/rg_cpld.c | 509 - .../driver/wb_firmware_upgrade_device.c | 155 + .../driver/wb_i2c_mux_pca954x_device.c | 278 + .../driver/wb_i2c_mux_pca9641_device.c | 99 + .../modules/driver/wb_io_dev_device.c | 88 + .../modules/driver/wb_lpc_drv_device.c | 92 + .../driver/wb_platform_i2c_dev_device.c | 199 + .../plat_sysfs_cfg/WB_PLAT_CPLD.cfg | 48 + .../plat_sysfs_cfg/WB_PLAT_FAN.cfg | 145 + .../plat_sysfs_cfg/WB_PLAT_PSU.cfg | 64 + .../plat_sysfs_cfg/WB_PLAT_SENSOR.cfg | 225 + .../plat_sysfs_cfg/WB_PLAT_SFF.cfg | 592 + .../ra-b6910-64c/plat_sysfs_cfg/cfg_file_name | 5 + .../scripts/pddf_post_driver_install.sh | 31 - .../ra-b6910-64c/setup.py | 19 +- .../ra-b6910-64c/sonic_platform/__init__.py | 4 - .../ra-b6910-64c/sonic_platform/chassis.py | 137 - .../ra-b6910-64c/sonic_platform/common.py | 44 - .../ra-b6910-64c/sonic_platform/eeprom.py | 14 - .../ra-b6910-64c/sonic_platform/fan.py | 39 - .../ra-b6910-64c/sonic_platform/fan_drawer.py | 71 - .../ra-b6910-64c/sonic_platform/platform.py | 25 - .../ra-b6910-64c/sonic_platform/psu.py | 36 - .../ra-b6910-64c/sonic_platform/sfp.py | 17 - .../ra-b6910-64c/sonic_platform/thermal.py | 17 - .../ra-b6910-64c/sonic_platform/watchdog.py | 23 - .../systemd/pddf-platform-init.service | 1 - .../.upgrade_test/board_cpld_test_header.vme | Bin 0 -> 470 bytes .../.upgrade_test/slot_cpld_test_header.vme | Bin 0 -> 316 bytes .../ra-b6920-4s/LICENSE | 15 - .../ra-b6920-4s/MAINTAINERS | 5 - .../ra-b6920-4s/Makefile | 16 +- .../ra-b6920-4s/README.md | 1 - .../x86_64_ragile_ra_b6920_4s_r0_config.py | 2075 ++- ...86_64_ragile_ra_b6920_4s_r0_port_config.py | 7 + .../x86_64_ragile_ra_b6920_4s_r0_device.py | 1247 ++ .../x86_64_ragile_ra_b6920_4s_r0_monitor.py | 113 + .../ra-b6920-4s/modules/driver/Makefile | 22 +- .../ra-b6920-4s/modules/driver/lpc_cpld_i2c.c | 131 - .../modules/driver/pddf_custom_fan.c | 268 - .../modules/driver/pddf_custom_led_module.c | 745 - .../modules/driver/pddf_custom_psu.c | 320 - .../modules/driver/pddf_custom_xcvr.c | 77 - .../modules/driver/platform_common.h} | 25 +- .../ra-b6920-4s/modules/driver/rg_cpld.c | 559 - .../ra-b6920-4s/modules/driver/rg_lpc_cpld.c | 250 - .../driver/wb_firmware_upgrade_device.c | 243 + .../driver/wb_i2c_mux_pca954x_device.c | 632 + .../modules/driver/wb_i2c_ocores_device.c | 178 + .../modules/driver/wb_io_dev_device.c | 118 + .../modules/driver/wb_lpc_drv_device.c | 130 + .../driver/wb_platform_i2c_dev_device.c | 263 + .../plat_sysfs_cfg/WB_PLAT_CPLD.cfg | 61 + .../plat_sysfs_cfg/WB_PLAT_FAN.cfg | 440 + .../plat_sysfs_cfg/WB_PLAT_PSU.cfg | 118 + .../plat_sysfs_cfg/WB_PLAT_SENSOR.cfg | 365 + .../plat_sysfs_cfg/WB_PLAT_SFF.cfg | 1169 ++ .../plat_sysfs_cfg/WB_PLAT_SLOT.cfg | 1316 ++ .../ra-b6920-4s/plat_sysfs_cfg/cfg_file_name | 6 + .../scripts/pddf_post_device_create.sh | 16 - .../ra-b6920-4s/setup.py | 18 +- .../ra-b6920-4s/sonic_pcie/__init__.py | 1 - .../ra-b6920-4s/sonic_pcie/pcie_common.py | 107 - .../ra-b6920-4s/sonic_platform/__init__.py | 4 - .../ra-b6920-4s/sonic_platform/chassis.py | 108 - .../ra-b6920-4s/sonic_platform/common.py | 44 - .../ra-b6920-4s/sonic_platform/component.py | 85 - .../ra-b6920-4s/sonic_platform/config.py | 771 - .../ra-b6920-4s/sonic_platform/eeprom.py | 12 - .../ra-b6920-4s/sonic_platform/fan.py | 42 - .../ra-b6920-4s/sonic_platform/fan_drawer.py | 69 - .../ra-b6920-4s/sonic_platform/logger.py | 19 - .../ra-b6920-4s/sonic_platform/pcie.py | 43 - .../ra-b6920-4s/sonic_platform/psu.py | 32 - .../ra-b6920-4s/sonic_platform/regutil.py | 245 - .../ra-b6920-4s/sonic_platform/rotor.py | 41 - .../ra-b6920-4s/sonic_platform/sfp.py | 287 - .../ra-b6920-4s/sonic_platform/thermal.py | 14 - .../ra-b6920-4s/sonic_platform/watchdog.py | 21 - .../systemd/pddf-platform-init.service | 1 - src/sonic-device-data/tests/permitted_list | 6 + 570 files changed, 115307 insertions(+), 67187 deletions(-) delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/bcm.rc delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/bcm_pre.rc delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cch.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_ceh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cfh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cih.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cmh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_cch.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_ceh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_cfh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_cih.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_cmh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.14/bcm56870_a0_cch.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.14/bcm56870_a0_ceh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.14/bcm56870_a0_cfh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.14/bcm56870_a0_cih.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.14/bcm56870_a0_cmh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cch.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_ceh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cfh.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cih.pkg delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cmh.pkg create mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev_exhaust.xml delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/minigraph.xml create mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/pcie.yaml delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf/pd-plugin.json delete mode 100755 device/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf/pddf-device.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/eeprom.py delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/psuutil.py create mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/sensors.conf rename device/ragile/x86_64-ragile_ra-b6510-32c-r0/{pddf_support => system_health_monitoring_config.json} (100%) mode change 100644 => 100755 delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-32c-r0/systest.py rename device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/{td3-b6510-48vs8cq-48x25G+8x100G.config.bcm => td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm} (65%) mode change 100755 => 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml create mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev_exhaust.xml create mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/fru.py mode change 100755 => 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf/pd-plugin.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf/pddf-device.json create mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/sfputil.py create mode 100755 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/ssd_util.py delete mode 100755 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sensors.conf delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/chassis.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/component.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/fan.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/psu.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/thermal.json rename device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/{pddf_support => system_health_monitoring_config.json} (100%) mode change 100644 => 100755 delete mode 100644 device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/systest.py delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/bcm.rc rename device/ragile/{x86_64-ragile_ra-b6510-32c-r0 => x86_64-ragile_ra-b6910-64c-r0}/fantlv.py (84%) mode change 100644 => 100755 create mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/fru.py delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/minigraph.xml delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/pddf/pd-plugin.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/pddf/pddf-device.json delete mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/plugins/eeprom.py delete mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/plugins/fanutil.py delete mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/plugins/ledutil.py delete mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/plugins/psuutil.py create mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/plugins/ssd_util.py delete mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/plugins/sysstatutil.py delete mode 100755 device/ragile/x86_64-ragile_ra-b6910-64c-r0/plugins/thermalutil.py delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/sensors.conf delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/sonic_platform_config/chassis.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/sonic_platform_config/component.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/sonic_platform_config/fan.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/sonic_platform_config/psu.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/sonic_platform_config/thermal.json rename device/ragile/{x86_64-ragile_ra-b6510-48v8c-r0/platform_env.conf => x86_64-ragile_ra-b6910-64c-r0/system_health_monitoring_config.json} (100%) mode change 100644 => 100755 delete mode 100644 device/ragile/x86_64-ragile_ra-b6910-64c-r0/systest.py create mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/RA-B6920-4S/cust_plp.cfg delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/bcm.rc delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/bcm_pre.rc delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/device_data.json create mode 100755 device/ragile/x86_64-ragile_ra-b6920-4s-r0/fru.py delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/minigraph.xml create mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/pcie.yaml delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf/pd-plugin.json delete mode 100755 device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf/pddf-device.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf_support delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/platform_components.json delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/platform_env.conf delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/eeprom.py delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/psuutil.py delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/sensors.conf rename device/ragile/{x86_64-ragile_ra-b6910-64c-r0/bcm_pre.rc => x86_64-ragile_ra-b6920-4s-r0/system_health_monitoring_config.json} (100%) mode change 100644 => 100755 delete mode 100644 device/ragile/x86_64-ragile_ra-b6920-4s-r0/systest.py mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-ragile/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_debug.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Rules.mk create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld_upgrade.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware_cpld.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/jbi.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiexprt.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbimain.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiport.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_ispvme.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_upgrade_ispvme.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_ispvme.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_cpld_ispvme.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_ispvme.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs_upgrade.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs_upgrade.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/include/firmware_upgrade.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/crc32.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/debug.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/firmware_app.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/hardware.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ispvm_ui.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ivm_core.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_isc/firmware_upgrade_isc.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/mtd-abi.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/debug.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/firmware_app.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/vmopcode.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Rules.mk create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/depmod_conf/distsearch.conf rename platform/broadcom/sonic-platform-modules-ragile/common/lib/{rgutil => algorithm}/__init__.py (100%) mode change 100755 => 100644 create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/hysteresis.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/openloop.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/pid.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/onietlv.py rename device/ragile/x86_64-ragile_ra-b6910-64c-r0/pddf_support => platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/__init__.py (100%) create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/baseutil.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/chassisbase.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/component.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpld.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpu.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/dcdc.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/devicebase.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/interface.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/led.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/onie_e2.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/osutil.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/rotor.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/sensor.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/temp.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/logutil.py rename device/ragile/x86_64-ragile_ra-b6910-64c-r0/platform_env.conf => platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/__init__.py (100%) rename platform/broadcom/sonic-platform-modules-ragile/common/lib/{rgutil => wbutil}/baseutil.py (51%) rename platform/broadcom/sonic-platform-modules-ragile/common/lib/{rgutil => wbutil}/smbus.py (89%) create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modprobe_conf/kernel_drivers_blacklist.conf mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/csu550.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c.h delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c_ocores.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c_ocores.h delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_pcie_i2c.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_pcie_i2c.h delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_reg_defs.h delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/i2c-mux-pca954x.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/i2c-mux-pca9641.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/include/intel_spi.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi_platform.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_at24.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_csu550.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_algo_bit.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_i801.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ina3221.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_isl68137.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus_core.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tmp401.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tps53622.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ucd9000.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_cpld_i2c_ocores.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_cpld_i2c_ocores.h delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_dbg.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_dbg.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_module.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_fan.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sff.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_slot.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_switch.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common_module.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/pmbus.h delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/ragile_common_module.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/ragile_platform.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-gpio-xeon.c delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-i2c-algo-bit.c delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-i2c-gpio.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/rg_fan.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/modules/rg_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/spi-bitbang-txrx.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_eeprom_93xx46.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_i2c_bus_drv.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pca954x_drv.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pcie.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_d1500.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_mac_bsc.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_optoe.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_93xx46.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_nor_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_uio_irq.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.h create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_xdpe132g5c.c create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/auto_update.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/dev_monitor.py delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/device_i2c.py delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/fancontrol.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/generate_airflow.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/hal_fanctrl.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/hal_ledctrl.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/hal_pltfm.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor/monitor_fan.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_common.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_config.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_driver.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_e2.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_intf.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_ipmi.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_manufacturer.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_process.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_test.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/platform_util.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/pmon_syslog.py delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/ragilecommon.py delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/ragileconfig.py delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/ragileutil.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_cause.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_ctrl.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/sensors create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/sfp_highest_temperatue.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/slot_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/ssdmon create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/tty_console.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/upgrade.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/script/warm_upgrade.py delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/common/service/device_i2c.service create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/service/platform_driver.service create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/service/platform_process.service create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/dcdc.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan_drawer.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/pcie.py rename platform/broadcom/sonic-platform-modules-ragile/{ra-b6920-4s => common}/sonic_platform/platform.py (50%) create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/thermal.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/watchdog.py delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/debian/rule-ragile.mk create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/.upgrade_test/cpld_test_header.vme create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/.upgrade_test/fpga_test_header.bin delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/LICENSE delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/MAINTAINERS mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/Makefile delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/README.md create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/config/x86_64_ragile_ra_b6510_32c_r0_port_config.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/hal-config/x86_64_ragile_ra_b6510_32c_r0_device.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/hal-config/x86_64_ragile_ra_b6510_32c_r0_exhaust_device.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/hal-config/x86_64_ragile_ra_b6510_32c_r0_monitor.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_client_defs.h delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_custom_led_module.c delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_custom_psu.c delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_led_defs.h delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/rg_cpld.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/rg_lpc_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_ocores_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_io_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_lpc_drv_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_pcie_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_PSU.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_SFF.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/cfg_file_name delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_pcie/__init__.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_pcie/pcie_common.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/__init__.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/chassis.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/common.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/component.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/config.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/eeprom.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/fan.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/fan_drawer.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/logger.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/pcie.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/platform.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/psu.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/regutil.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/rotor.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/sfp.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/thermal.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/watchdog.py delete mode 120000 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/systemd/pddf-platform-init.service create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/cpld_test_header.vme create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/fpga_test_header.bin delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/LICENSE delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/MAINTAINERS mode change 100755 => 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/README.md create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_port_config.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_device.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_exhaust_device.py create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_monitor.py delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/rg_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_ocores_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_io_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_lpc_drv_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_pcie_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_PSU.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_SFF.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/cfg_file_name delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/scripts/pddf_post_driver_install.sh delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_pcie/__init__.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_pcie/pcie_common.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/__init__.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/chassis.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/common.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/component.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/config.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/eeprom.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/fan.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/fan_drawer.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/logger.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/pcie.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/platform.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/psu.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/regutil.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/rotor.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/sfp.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/thermal.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/watchdog.py delete mode 120000 platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/systemd/pddf-platform-init.service create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/.upgrade_test/cpld_test_header.vme delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/LICENSE delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/MAINTAINERS delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/README.md create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/config/x86_64_ragile_ra_b6910_64c_r0_port_config.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/hal-config/x86_64_ragile_ra_b6910_64c_r0_device.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/hal-config/x86_64_ragile_ra_b6910_64c_r0_monitor.py rename platform/broadcom/sonic-platform-modules-ragile/{ra-b6920-4s/modules/driver/ragile.h => ra-b6910-64c/modules/driver/platform_common.h} (92%) mode change 100755 => 100644 delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/rg_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca9641_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_io_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_lpc_drv_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_platform_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_PSU.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SFF.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/cfg_file_name delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/scripts/pddf_post_driver_install.sh mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/__init__.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/chassis.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/common.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/eeprom.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/fan.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/fan_drawer.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/platform.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/psu.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/sfp.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/thermal.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/watchdog.py delete mode 120000 platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/systemd/pddf-platform-init.service create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/.upgrade_test/board_cpld_test_header.vme create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/.upgrade_test/slot_cpld_test_header.vme delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/LICENSE delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/MAINTAINERS delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/README.md create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_port_config.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_device.py create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_monitor.py delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/lpc_cpld_i2c.c delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_fan.c delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_led_module.c delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_psu.c delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_xcvr.c rename platform/broadcom/sonic-platform-modules-ragile/{ra-b6510-32c/modules/driver/ragile.h => ra-b6920-4s/modules/driver/platform_common.h} (89%) mode change 100755 => 100644 delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/rg_cpld.c delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/rg_lpc_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_ocores_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_io_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_lpc_drv_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_platform_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_PSU.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg create mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SFF.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SLOT.cfg create mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/cfg_file_name delete mode 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/scripts/pddf_post_device_create.sh mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_pcie/__init__.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_pcie/pcie_common.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/__init__.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/chassis.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/common.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/component.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/config.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/eeprom.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/fan.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/fan_drawer.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/logger.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/pcie.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/psu.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/regutil.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/rotor.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/sfp.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/thermal.py delete mode 100644 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/watchdog.py delete mode 120000 platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/systemd/pddf-platform-init.service diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/RA-B6510-32C/td3-ra-b6510-32c-32x100G.config.bcm b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/RA-B6510-32C/td3-ra-b6510-32c-32x100G.config.bcm index 30780ab6ec71..c81f3b6f3310 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/RA-B6510-32C/td3-ra-b6510-32c-32x100G.config.bcm +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/RA-B6510-32C/td3-ra-b6510-32c-32x100G.config.bcm @@ -5,6 +5,8 @@ l3_alpm_enable=2 ipv6_lpm_128b_enable=0x1 l2xmsg_mode=0 l3_max_ecmp_mode=1 +svi_my_station_optimization=1 +sai_nbr_bcast_ifp_optimized=2 bcm_num_cos=8 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 @@ -447,7 +449,32 @@ serdes_if_type_127=14 serdes_if_type_123=14 reglist_enable=1 -scache_filename=/tmp/scache +scache_filename=/var/warmboot/wbscache schan_intr_enable=0 -stable_size=0x5500000 +stable_size=0x55000000 +stable_location=3 +warmboot_knet_shutdown_mode=1 tdma_timeout_usec=3000000 + +#vxlan flex flow mode +flow_init_mode=1 + +riot_enable=1 +riot_overlay_l3_intf_mem_size=4096 +riot_overlay_l3_egress_mem_size=32768 +riot_overlay_ecmp_resilient_hash_size=16384 + +l3_ecmp_levels=2 + +use_all_splithorizon_groups=1 +sai_tunnel_support=1 + +#This property allows to enable L2 FDB entry to discard based on Source Mac +sai_fdb_entry_l2_discard_src_enable=1 + +#RDMA +sai_pfc_defaults_disable=1 +sai_optimized_mmu=1 + +#ACL wb count +ctr_evict_enable=0 \ No newline at end of file diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/bcm.rc b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/bcm.rc deleted file mode 100644 index 7f69f10d3bda..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/bcm.rc +++ /dev/null @@ -1 +0,0 @@ -rcload /usr/share/sonic/platform/led_proc_init.soc diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/bcm_pre.rc b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/bcm_pre.rc deleted file mode 100644 index ff9e51918031..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/bcm_pre.rc +++ /dev/null @@ -1 +0,0 @@ -m0 load 0 0 /usr/share/sonic/platform/linkscan_led.bin diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cch.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cch.pkg deleted file mode 100644 index 26c3c437a5584bae367d9e9392d15dcdfe9e9c1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28736 zcmd6w3zS|}b;r*)VGAg1;BMTVCE=@aKZrf+GZX3%)0K zLeM=XrRjpXf@1_H3+@!$D|kro6TusTP1lr71Xl|FRq%|Ub8JfM3nmK=6&x!#S@2oG zMS|-E4+tI+yeZghTuL(qO9W>ME)-lVSSDB@_`cv#!Lx!F1u?xLdZV?ZgWx#91p?9? zdUlR4@v482)Y zCU`^8v3_59Q{!s*&gZ$F%4{O&791wHNN|;)D%~Ld@+|M+j7IL?DtJ}(4V3pxsPB2< z8*Px%EWu#YQpsE+_{SRA{}I3I-DR!k>AAd#|FZdP)!y?e^JY!C@f&J>6C5MR)5T5R zHCf)RqQ5VASn#-D%lGt3E)xFfK=tJ@JRuu z9=SH58-1VlT3H`7c>sw$hk5&ozVPF4yVL7SUT3S7RyUv9#Jst$tww%z^9io)L{TU9 zwq20F{eLybsxQlym-f@vr6@;yxE%5u>|Ewg6^ zaQ2CLF|KL9eTQqBZGd0@YwdxLq0V9SYwo*tdPm=l6uq(cbAzxquZqJpj&ggq(>vOG zr09*kpC5$1^-4Tq?A=c9Xz$_Hn`9$^pnDYT*3fNTesbyd#?WgB%-Y4SR zeaq2hxwV_+X@~ioJ*{Q)`mefK`lM}&_K;)mOL@{_gp|-=e>G~o*!%AANxkXeD=2Ayvxl6x!RrDfi*Vf}%afP1IAbOhuwSoFQH-9ZxT$ zO1U_Gc&A5>@q>=ok0)mWF&1eLAYCS1i7n_21-V~2mdbg(^G9#YG6wTHCb#=%sZ7az=LxWeyYJAsToJy_vT>du=8>!0 zzkE*lBO&P`pV}QMu$YKq+BCJVW;(1MCt#aHjU%@{% zol?Y!%jEq(N99PlKAh*)>BHD;r_Z<31F1@%Po%SZ^r1|y&$)#*r9N@|%xmhy_{r_V ze9=yybJFFN`pifN_2@&HT%XU^=yPDuhdDI*i+QV^K3Al#R_b$bTF|2pWu~fb>gWCI zwA;#gjq!oM022Aw=^7dcm*NB1;*!Gv`-Y6C3)$smWs<$$9u9 z=jA$HKm|%v6z9CjqOGIbBu3GV^tZxEx!k(qwUWEAkm@hj73AnId%D=(7e$lEJ6sc? zZNXYads7-aHCU^RvsM}3L*>yEK;HcSk2b1ocad};kw;&woA;IUrAqGNLaM)<_rG;= zm(<94U8|G3v__73(Kf8o^RgN_@3UynK1QD3UfK5%SBS#Hj(hA?8l?XqKo{%F@7}q-FVyG~`>~el za6jyWsy)C}Do4uo~coP@ijPSSi;B+WKH$Xzn`LpU`)FyX5D6{F3rWd7ZpNx=!+PxoZ(p%H{A+ zE4k|mss3`GWS+gP|GtB2#%iLX41LCrKi65>8u|~Kgf2PHamxLd z7^l38QdhSCdG6BWV~X<-=0oxU#u4*AYg~L!gwNid`PVpeiOYCABKvgB7_^?;(TRGl zb$)qA#Cmeyr)jH5u>+iJ+otbl8#&bXXXKM7s4%UTxN3C@6e2gym%k8tr zbeo#`du--8oA%=wz|RJt3-_N|>B4@-ZF-JIFV379RDG4r_Cc9?$cb7xFVr=CqtgY~(!b zlJl6?avr|Sd5npiho5sEv6u7kLC&M^^o1v5h4B&hYWIbARBXjN>Pp>@qWtzvIcyrw zq9~W!(&vu34IM++&NwzRj;)MiBjeb{I5shkEsSFW|0{;;>XK61`?Bu!QncOih2{1?evZ@Iox`CUg7R> zoL89t=ohiclY70+$B*3c{pqjEJl0dna6j2)n9H`jU-#>u)Hh0cuF&%?e(H z7;yFy=6400F=jqv%=pBBV<+>s3HY`F-#p-31sq%dwSXsnz`wa4XqSBa;5*;=!8m>} zjvtKU2jlp`IDRmWAB^J%xxCwTpNDBGD7lyLxE&YYTXeTGe;24lmvx>k`dA+4skI2csSKSl`j0 zBzALs`2K@>fXM=X|FQJ*um3l^vzkxv#R8s;1=h2CEFe$5w%t8*Df5WuRpt@n%p=AJ zJGUTr<4fyc^|5(5oUoL-Kz=>P)iCg0f0zNuToXH_xAciuoU3x&DF7?fA;& z@s)9WWgK4_$5+Pjm2rG!99tO2SH|&`@%aJASLWj@<6QyASLVmH3}2a#uZ-g>ggl<{G3PK zV+1_;CNZuN2dh4GB38)f+sNmezbT6>>=n-@uoZJTXA=(wzpvTkPu3mbIQK{X4?}s^ zL;0zarBA%S@V-*zySL>#+m3#}{+#|vX9-q;gfui9ZbEPg|(`e{V=-lz3Yn0>V056@xkx$LE|h~q*e4Ur0J$9pzTGWKYI|{ zi~jGUdwA?gcGHt`!~%TI7B+6)p{cW5JnzCEBjs$No!;?mVYu~H=oNnF8)MFKtH$1O z3QA2AJu#Y}_bRL388AM~%Mo8WkGRNrl;bx?>NsRZ`K@l1UdyNS>O|~}*E#c8{pW!6 z809{wW3GtBS4+9LHgR@A8>*&||6{IA)`RcHqaG8q=RqIVIQqV!!-|=bIw5a4%lr>oUjD$Y%dw<@i z=x6rEF`xZx%x8~VmCt(;<+!KDy)>`e#K6C3uRZEleGaQFObA;aQ^B zXms|_3dy!**cY{{XTku=&?x6d=*Djq{60~&k6Wk#MH$KiWvqNum=mMLNk2pgZC8eR zV!Uqn$iU}w_N*f%Ufby%<8`Fy&Aa!cLD;+3=MUP+{hpK=N{W$_%M(YyE&}T3jFI1^ zG7`oBvD7t)SmOP3BSO>?u--Tl#6w6|6{OqFkV@gsf%y_!NQCd~d|sJyPPeo!&8Chg)yQD}QS-#_NmMrSz%*pR6t5 z$(eMkzsW#d-e(gFJ|pMdn7@5UjM87nfY9R1iL%^RHy@hv>*!Pp9*Ok_zV$_ys4seP zUQT(x%klRjT?W4IhdZC&cVa%j_0Ud?!OsjL2H6u1R}3eSXXQIi z=2G_V{M|G5MEw0D&dK?kgx3l9`%}f=aT87)v(|BMl)u~KwV8di+hDK6{Y?ITWY_)W zxhZ!E*k|J}+md;_oh{?I7zwsSXZQ1uZA*ORaYdZAx|>Z*5?8*P?J>Y_1=bH+UoM|9 zr&9NF0dkCM#xi3MzJYaSyC%(V`A^>6NUx;d7Wu?dq&XLlH1{zg&2L(fX52?w;n0VE zPexD7=t&v9O-65<(ex>{C$bNX9b!JVigag2Ge^aI=8H%Z^O5GalSt#ANaN>7Gmaw7 zSw*B-S0lZ3MsJnTjFnh^os4E}j`{2zB28>ZdcBO^ETefBjpY?eedsMRdh?9#&gjV* z-IdY!H^wvTQjBN(Sr^ab#dwB}@eCc~89K%@bc|={7|+l#o}ptrL&tcAj`0i~;~6@} zGc?KehK}(J4aEEy&*a5;hK}(J9pf1~#xrz`XXqHu&@rB&V?0C0c!rMg3?1VcI>s|} zjA!T=&(JZRp<_Hl$9RU0@eCc~89K%@bc|={7|+n%f@uF3&*XPy`S|w$0eP&YteeC$ zG(tw>c}VEzBr|u8h14cg%m`KHr1Y|v7-1oit>-?_k@LwMGgE-j7)o=kw!Ph z^yDuVy|{5|1OMWaX9e%1PV~&{eEJ>MDe-=F(hf1plW%ss=0WrQPRwtt>YLBHiY%Zi$!!XD##|mT_;KF>jplZk*Tx=i4{NdHfCuK7V6{_Ko9Xsr@x^DbDEU2 zQR7EF%JJtBIEEO_*XI3yo%e}wkn zj$iue_yuPkad~8kVajq>gumyW_g`5l-W4I9tL`*R6`y)|m*Jg+da##u6k6n?%RN(i z`RFrT?_cO1*RGl$JK5a)`xwF=K17buUvZ(J_9 z#?s=h4C9c!U(Va2g7=LI-U}5xE%W{A9-Z%L<-`ZohJySMa(kc-vR--dDlHPx}h+E8p?dolVBSuSd+4@loy_L>Bv{oX1`v z=P}pjJZzcsx+-|RaoO80_Q++K8*?80%X!3O&SO83^RN-^P%nR@n7>O*?AOh?{7yqz zy&&8hBIKDBCPmE6vcvrx& ry~|(=`=R|#ed_-JH3biG diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_ceh.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_ceh.pkg deleted file mode 100644 index a429810ef5e651d6686aed2bda158d8e7c7feb99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6044 zcmcJTU8o&b6~}j)#(r318)G$AsfD6_D0uJ5&CSIJ>)bhW&lxjkW;!$H-sBqH5-f@h z7_myLeb5p$iWtA>gQfUEd}@*UQ4ubvP$8mus1Vc#5d$TD1i!Ep-}L|6GyB|q#^|LF zF77%r|GoBFd+oK?T6?(DIFHBo#b%c|^@Hooo?XA+WArY%Y0pb|?7FbE^;?ZSd;h7^ z4)Y^=llbN059~JP$?J_-&zopu6MiOfR5xalPRuCDlPZnPq|9o&WV2{B$?QhjjBUJO z77wkg*y*q|<&nm&WyOX~hjy`@JLt__tD?~)(GpEst@(0Ew@T0 z%^O>+CzZ3gmf_aDwkhmpQWdS@`dVX}X`aiQCaETA9yQ6(R8dv7mgHR%msW<_`RQ8a zmf2p_tfi%y=11~kBe!Kaw9TxoqiYvLV`llX|K^QbiAbd-)vTCOjd`7_x_>e7s+iHm+St@5bS zo`&+MKGLpmxOb*S8QnWg?0_u|{B{R~#pdI7iWjr=0K)xPgl#L zYAoTX(|nXAZD@25WLeW>ZG<-uZigxzO-fTtl?b-1QdCDu23#nji4s$$W??0fNe#El zB#&0LfZL%CqCQsJ@vt&k7Iy(O$uMnf+*BDy;)>v47v`=qtgjF`=<>y+@uXZ|Hk^`E zIMj<8auba$;g)|cT=VBd)+(fnvuyNhWkpf0MmkAXt1ft^j+-v$U0J%)RTV3ld*{n~ zb0_Xro<+#7q0*%M$muMdX!nz%N^CQZ^6fk~b+I~8kwoz@vg=E#l1XfmqfHgXuDpG~ zRO0>+NpiAoc~*}mX~rfS%%zGe&sjSN>aWNXA9rOJ0dle3_N~j!cDQR)bMZH2RMpCm zff6D)YR9S$R~5EO>S@;4#Y1+%Y%XkP6#>yCrIB%&?D|7CFixwUPKqNcUOEK5z*m~- zYGTn>An{#In^~vPrjyE@juOTnM~#?1RFrWs?DEDP=af#|9j8lZWs054LkIls{ULh8 zuG{Je6l=n-bDcy-ZI7Uj-)U(fBerR4pOeatQtT7mPIz0)-M zcaouSRh8Sv5E7EuioXhdN&8bzIBVv z!s^@Pug zZxXxjH9fQIjCpB*-=gofy#bD8Lrcu&*OIf8*MC45^7t7|=H26mH953*QSwm#&+?6L zLO=fn2}AkbYmIqXApeCXhW2jP`h0YH{rBm+GPHNOw;$#`C!56L2C-h}*1KEt!~K3k zfH~fNKR$1kAe1iyg8AQ4d_(`97si&iNBs0R!;D|A0d!s={;cLh;8%+mI{RSs%FYmY zpZJ{tM*n1h_X~fO;EI^9P?>w!tO)!n@jC+iO5ythe5>$Aus*Ms0{@8Vp7-~Xls#tb?OL39yu+6z^!C8iD1;9DA1UuPev%6iIuLu~oxMTVC|<y?Eei#5sy>i^8gWeL42Wm zXD{$YvGrnY_~hOqyjc&j^G?7dsO7l8=;dhzpOh~YEhTeOI`_d4N0fZ57& zfH|KNf&I4%KM}}@?^(&Qtzk#s?B+A}l=xtfAB_E|n}~m`HxWa~zAXMDKm@)^{8QQU zbIFI#$)5M0Uh<5D9`n4mOLFvy(kS3&?G+}de)aE`{#~@w-LcbM(Z8!6my_%RKR({=l{n-35)O&L$cYDc1HRrV?$=uXZrJHA z=%4+Iy$kxacS1hlGXB!5`nA!|-F~k1dt<-$&dVmm8VllnZTEZCPPNsq<$mwnskZue zO}|$9y}W-{yx3al*G9ir_iJIN+<%+$jUGa-eTg3t7`jJHeGqGUCf^dAD`OLqQAF!R zjh^P^-&3*?{{R30 diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cfh.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cfh.pkg deleted file mode 100644 index 4fc198389bfde07bb7e6c47fb456626b814e89d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46376 zcmeI537p(jmGA!zCi)~O%M3E;V6looAl(TGh(ape)tw^UT}@SWCjq4lkYFHTQPwCJ zAdDb{MFs^F2pE(AkxiBmmIM`}^0u)u(R$|4Mh! z-Nq;N$;tnJ?zzj^?m6fFyO#d;-u9WD?NLi~`Xg_S#2*obKTKEwmaY9*6qmmMcswMtp2`A$3S0&`77B{Dc{vw8R*S-RA%SPELJW?`Es_) z&JDZSj*jA_sIxmar;_W)m({Hsj$`?H3LQBoT4#4*cBMNzBiCK&FXbw^-g2?fH@993 zH7qLhWsmMhH63k(w`d?=%(a&tXFW_&X+6wx)6>^oif5jS5{(9sz9ZL(h`loleU%y6 zQm&(p*GgxhnCWh-NTp6W;yjAyE6*-CzDwn7`>cvn(~LsNH9JMcovVvRJ=ykHFBMre za%SwXjF*b-*sR(sS1MU zFKNm)J7t3E54H5z$=a$;hR{=DSC*gJP6?Atv-EnGo>Xa_7Gb(VzB6`qCs8E#DfHvX zm6^G02baE?GoqRKu6$ReeP*_|D~GX5c*)=na3+hln0A<%8 zebxQw_jF;PJ6pHmHDkUvTh3Kv6$OQO|7!B;@b0$i+*L1VQw+dhaSWL3_D>0^y4?;i zyld}N;=n;b%5@cSaJOTsu5Nr+p{EwI68!6s1f9f;1Qt@9)NXWfvRCo0uUxND7v01V zTFLj8JDp5ypmL$T&|Qlx1d&{K4%Gyl&g>{wI=cyOGxFt<-zrI=u++gwiLPDSS16V% z{pEaj{+O(`8)1+rS7HUiln;ahbFfdWta$4Uu<3iT{A}!4H9$E#164Z%7xRU3r7(~y zc4y}{;3FF7n_a5Zb>4h;)om^<9&-_gYM85!k;v+o^PcIpiTuXzJ(yJFo{Qtg{!s|j zxH%84b#^AB6pFb@e@7pCHP=3?)ZY`8%iWc%bq3;*MZ0pnxdHT3O;53l;Hq}t4Cbf0 z4AfWX&bQC4$O&5`gG}0Nu7P5w4+=^VHr!O&@N}aBaKC#7!=20AhfS-rwh^<^6KTKn zhBo8urtD3w&K0Y>vCfz#O2d1;2fswON>sD6#g6(ogdr!BWqZp}snA~}=9mrZc!{&P zv!{xOgl26VA}!vE>vq#uNxZi4s&zsxrq(K#cqXTXY;Vn7lS~x(eOn(jqEbh=6LGOR zP1vp0LCsK^F_-PzUg#(Nv)hQRliT7=>uM1fC!B=U{NarotD)4{Ss?-{Hr6fFpg4#F zshq%72S_;8>o94Bb}i6=1L%_pL<4z@g_ae!;vi0>K(w8`r9$fOp4cX)v;=N+0Zv`jzme#09&ekxw+<)7*Sf)nUSf zm7w9tR-y6kPboahg$9LZN1>PW;mV*qWj;j`nXRML-d8Qr757beIGV}oV=q<7VA@vg ze!yTTijtfZtbonA4_c1p_{@>g5*;zLrMlSY(t~%-{04VfQQDr9|x%=c>;Xf zL>QUKE*va|VmXqlp}IJbYp<)OO8Gd~#*^1FN8m2b%5f=IV(Vt-)=ECJ1>%F9YEu`=_;@MVy-tme0Tl}_oGId}TS5)1?M*pcJqkP7JG9AsEb+0@=gyvv z*1_Ah1QFZnjxQ|hRT_t+pn!VB`33p)74V$RIQvR2QzanY4j z9d54Ny8SR%aLWNF`FN7;$o5eN&zw=KGD(|5*@jBlvccf-u&o*x#BG8a8=WgvD{%5q z*<1=LlDZ%sY!)p~P%1@(vQ^^pg&J(|%+@Fy*Bq{vj-$S8v7FC#*B$FQhF71g@Wer7 zS8Ncp81UM9s7}X@t4e2TVv4IQIc4p5zvV&Rfoi$Jp7vDd_T~ul#aY#@-RSuQ6-70q zO^$qZX4U2POk%!t2hG|rCFTYZD}HF?`Qm{~F3)L%vkoU7YX4Z~LGNj;7N0={)8@B4 z+P3AZvG3-7-#W<(RL)^#RYUAY0;99Ef|O@1j)v8zSnOLp%&O&Q2JqCt2akA9o2LdO zMAD3_bgRWxTUgbNeoGYX##Q%+(`grX z|LV9X`WttD9gDt$`)%R-TlBf3>mwJdzreqyft&<#h;0N{yL}z*@FRnE^=VIN>q=-- z-&wR50$R!7$8bN-;qy(q#%}4gkp5=_=K~iGVeBRJxeQpI(DxeCcAdMw!Ch}Mv^1V> zZP4fT2DEU#Ri^K1bAO+^e~{}M;BiB{L9dL9j^7S+@UJF z=Qo2Oou>a}bBvz@u6ZA&W7hQjE$gWE@N<6=x$_Q}-cLrZE{97W!e?^T+_JOq z8ScJ_%^j?GS2Oo1CuDON#8b)&qS3RWhnp?Q8!qtCAeB=WTSAXG0aP@Nj z3qCR%Tw_k#Hi~jwxx{i8=!Z+}wer(ei*BYYJJ;tTK7g+3YgD>WO zs>5Sj;3s<<`fD(7l)+zQzIQuZ>kAkE0*x2$dG17?htekb#fxaLSL3AwV;?g3aqNMN z!QX}c_c8cJ@M8@APvFNoTx+jl{D%#_6-F>YO}~Ey@_umXVIF?O@R%3rdr$o6B!`QB zCAhBMmcQX1)zo-@5}%#saOpw#M2CwP;rlsUvI{@R;hOgc=%U@>8ZW%h(3i4D=7USG zq6q}}J!NEzXDVr{TJ{@K()#QDUR2U z?y4Fje7%#ly@B^S+EjPdd87mA0R{lo79Rl?1A5uI;T+nQx%SJrUI|#!oS-&^k43cU>f1i)c z^kO$oxkqivi)XktDTH@&(+WZ*Ocyu1P#!G%(RS$i_^dXf; zOTZJwLzB*Q?z8l0j#m2f_W^Q^D^Bmrdkb;&C!?hv_p7d^Nb$!J)K$#f=kB zqUjuE=ROSlo?zVjXuHpi^E~J*bU$sv6*s2?4}saffS-cHmKP^_4wz?E;>l&Fe>PIp8rfPagb9H_q!~rWxnw znnl}sGp^g=n$ydE6!+`sqxIA#S}*W5+BCQL)ZAYO_v3Ue02^o%UF+$pv&=@?G>_&h z0p9?ZK1A2~An+a9ynH%`K5xdUkIuF)&?Y}nKjpmRftTGl<;4o{ zeTOSI%mZF>^GG-9a~$xZYm$BvV+E+1pFwN zdjW0#K-+lEkI!Xz=J8K|h|iBS*Ix4w@GP)b3EH}U1<>&=x?`-}FSgAfTND?Pd5E?dE{?5oo`2b3PH!7DD?^H|I|R z+R4!FceFo3BV^a)I|Z8FE1>n>MjuO?xPZUakrPBa7#b<8Hm-P06#X0dfT3~SN=mBT zfA04@$9Ho+P5U%6?xJiqKkoUUo^7Lp+bP z9GD@xWj(q|X$ zM*Bvw;h&4-T5c4puLW#9V)qoOx6W5>oi;h3*;=d=&}_Z+v4EDgPaEZ8$)J5B`So1? zFHL^ZY%G5(SN#nolwUDEEp950rRf|}s{hNUZ2r3f+~$9q|J!D|TZ}@$UJw=ZfFa?sdX#-MQjz447cXY5cK({@xbq zP5sjJrux|G?G*3~;Q6s1dl15XBVYYX zjZ-=^rP<>3#wpeJdapyM@9DRLt-v#e_ z??|W{<@q#Ul-|;8r8s3{>Z{;3_bZmm|Mgy!aLq>kFaNN4<3{id;B&)R+bS*JO8zw6 zjFuhk8E#3S7wJdOF!g?%DLg=50~4o#OP|Vr$D;K8abDS5FI_c8VC{brxb}qFmBSw> zN73&IpsF+a0seegv&H!5`MVr6t)cn$F|^gtc4ZRHBbuL6w!f8Uad$ILdXgRm>ZjLj z&~BuYXxeN1iLpjgpH4vUU3!fUZ>IoJEu{73s~^-j3dvAL;U9vw1|f965YScgNjFyh z=fFL${3$g0={(N0tfe)?i+J+9HX}b`M?d33b#H}X>GT0$H#6s@ceX^+!L^?BV%Phk zbi>0;@q8_i0X#3d9uHiYpc}0@(z?+z)n??^xMuCY68WqL%Rv1 zN;k`a4B&P1C1`g!+TwurWoT<0P4l^NOSz5ifc7E=(0Ypi%?C{960L%^D+bhhtAPw4 zx?Z}f_R;(2LO<19BW(-W_cZ=ybTrD9Pldh_+DU(3^Sq|*Q$2HUb7y0%8820ss;-QbJcSAdn0O4yNOIrSct0$01@o2|od23JfLjWQ!zf=>Gxqqe<(Nr0a>?b$uuqql#d`uSCjD*;x1 zyBAM@mX^cLfo5}+NS;;aA0jqX1L zG-D6#9cz!*c(2v=Y&gw%6Cgbc^wL#l|0@%C)gDdbRq@IC&SdbR@T%tmR_EF~mRGy4 zJ_aq#cRmHp`c9*LB^f&beNHLdADTm-y*PqEDg7)1CIDVPY4U4aTI`UGt&Hv9R>teU z$@2u-w4UOMmC?$7Qb7CR^5t zjAVY09Qu6bSjeF|!ur)n%Awq$&kBZejE2vJ_82RlQw-2&BtscTBL;-F8g2{_ub&$u zUc+4846piJ=~(DBj90_uRnL}gNZ?iWO3RV*SDPcX=ZBIbLm!yOI9os18bN#6)(^H0 zxCEN51MGXFu7sv_e4S&@7oRmWzpni1M&zGKpxuc>%PKcE+ykGdU2U3od*B@E+3T4^ zHOmJ9D}UPizce(UIFfNHMjA)szpAZz^iz$wi*tvY5W|-oLl0j zlRjTa;77Je<43gf(A{=UcZYz#Ufu1-96$Ra-^;~jkS^u}x_Te5a-2uI)$5@xEz#i^ zR{bvpb~fXzUoE6P&9CIEp62J4U)_|To3Zw*q1sWOaS!*vXxNc0mbwS_fwr~S5msXV zk&o-U2Zo~?`H=PTDd5(})ArnG`LR7GpXlWBd!rd2XNp=p()S>Qy3t-r+y7gNooTum zN_>>9ZcX54to?W*d~9ugtURypo(OHFxRqwBEye0ITWyW<%Qy6$8ln87;Tv1Z^IMy5 zNH;6D0^KNAZEdBH_5k`$ zo=~Th#dXhuXMj%t{Ma;o>-=Tw82!!7)-h@N*1WHs!r1XupXdd*b#+?a(A@t>9beqG zI&MC=Jp)>Qn+MJMo8243sqw|D_Km*(DAZe{J>KlT32VIJ?iuBV$M*HRf z_^|entwzEgucscB|KF9M8~J~lk82-TAJ@LJKAz^Q`_gYTI(H}NZLDMQSm^XbWF2Xp%4b5Is@`6mpwrQ)x3|WFKJ`2-uxX}q9T6-6K~%D#INV`n0K~B2NRUk zw!yV~+S;pHBAxq0dpe+9&UYuhkDw>oIzU%H?g@S*>ti^9+BUg%PkR!Yz86!p^?>}t z({$B)AoU%zp`R+gjcFMmd?eJ?Dxk+tuA!MHCV*i{HP zQog?n^IQAg8?0yT`v5d=3*{PX-+O{_*1q=#G;3e!#m~uYWbONKFwWZdZfK!>l@}gK zu&;O>Y5PiV&BPk{#gFjsi`;(N1TLTOe$njb$~3+cSd$>Xo;5ThzwBc3$#dYUF}0RH ziyO+%*P+(rNc&8d;`gt%Z;5)CT=PE!X#aWn@8)wiFFTrIn{tS!t>trt`dtr=y93bq z!_%hRQ~g|_-xs?Yn);j$Jer`Jtu20!_WmAf{0{f`2B%N2Z@a(8Dt=!J4{NdEGkZqS z&oTZB;Ig;!Wi$RQ-%9gu`Ie2}E5IeYm*2+dF9kGfL)AtZGwz=Cd{&=LB);bW(zBn_ z=5G0K#?ZpOruSs~acO&vv|Jb4Z+Bz-I2+rwpR}(;+YYd?eWh#n~4&hIt5 zf3079IT&Z-{t9S*J#Opb{@vhO%dcnS{;jlYT~G7zQnp+TSbh4>VT-2Ejf63whqlKO z{7KIroAD>fljcu~GwomFy$Rfi|9QYt06BEoES4^)(nN~h@;sj>#3&lK2zWQ(n2G zMyvi-TwI?Z|7gSv`BW(XP-Dhz-zR>PedPVy#*=$oyQh7KaYwVTbgTCkr`2co z2jgsgCS7a1pR?I>`B$kWevPw=cfq{soYT2P4?_D_{7~(S09V&c=Qdtf@kGCoGZyhg z^+LFxhEiuJS2o&Dwg!%gT?uTy(|)^i?9v*%~UhKv~(?$M#-d_AkO zF?ge!&+}r>!QX&p7Tubrut)7L$lv=rg}1CX!d)~mIO5WJ!jIt z8@H6(=pkx}cks6#@h}?@9bTq$i5`ab4GwSGBl^6027ng79)b2rXd1T&kX(M8`ltrc zZ{>w{QvZ>*lk{Z2cSdX2+N~Ko>6~D{lSp>3bK39YTMaD(c-`pQ3FvnLL;0Kin}TeR zR_|*sHu?^@(a_CMzso7qn{?9yJe#1KW}hE6(vAGt>Sif;2Jp6Oq#L{US1{)F?tS^x z>(SfsjNg=?H_bcJdrJGcnSC=-@h#j_Hoh%~w+!HIXye=BfM#Qu&Pi_EQf{L)#IS2! z3_A+ko}(Ux_B(UN(ptcDF7dj`L(e7HLh_HaE%f|stZiZSwm<7<0O>%lwdm$yf}!?Z zsME)wJ;tU}3=VbrIJ6ZE(zwuuPe8lZ(L&ol3GD*6UTEKS&?*!FJ`aUZOzo5Hu8q1ch+5a|Z zt8hxSFE=#Fao(5sZ9lHM*Gqjo_?(esf1fi%3u~11#FP%&MOz72zj+GUr&&z2zYl0y zSNhg(EDuND(or+|mYo{udo*-v|85rA@K2%dz0iSvi~3Xy^6w~e4!GVy@C@MRP2#FQ7fZ$*IuF_cM>~Q> zOIt!-nMJ;oJbG!2hx4Ho9nH7ts@E;|wnW#!u=v~$us(4Qv>hGoih$;y390sY1$YbK z=k(8nL_^fNXF}>DzF$6&weis#5OguP)>n<&=(iuN|K{myd9|_XBxv48cjtaMzYC!l z>E%eP;}lD-MmHsVCP{BzH{gEDa=)IghXOxL(2aE2NH=NnYn?{&59b;D zP;{gG(nvRwQFZ)3B*-W|H6!CY88_B4p1-6engheyr|keCsbHYBc$SSv zx{jBBg|*sHo_lND*Qgy2BW`$Kwfk)YwDAZn8jl^~xMTfTwepXV@tXa}f5f_{z(p5K zpTXZl-Th@;CAZqOAKtQQ?VYc3{rb}9TYP`e_%)yZ_W(|)qVe}hx!Z=9g-{h^^g07L zE51wq?>w5%2R@ZduC-py-BrM6ft!F^0sFe$B2C_}V%%yo_CD?(G`PQA!_DI!Nx814 zePaUc8QPu$zH4YNasMNO5A{~|l5fc`-T_!?-JnhGyT@Jrz?KwyTkPz z;(ok-V@EkfxlQxwcV%?O)O`n_^N;5B{rotcdvyNsxPCiD=P1Q&jn(h0=nSB-Ax*!} zqQ75==KFd6JpPS3VP({n04ukv&0nUW_m2+<otc#+rmM57e)a3GzRJpabk&jlhxZ@4bw6|1@$Xex+4AhCf{xOXB$Msp`U(MOS*1cN;e|m`j$(558;I-PHlVd_y`z7?)BW4%;D0IrC*mJeWX=DE z&# z->>%fZTa^T|1Yh4->UzB+CS1~B>r)I*8CsH*}vJrzZMur`5*gdZGW1?|Mbd!vHw>7 zW5zxk^-5xV=7GTu{$Y1c+kcSwKe|#B+kf1#F(^YF{GSZil7H6x8It_>i|yxT19_Nq zxPw36rxdoo!TiGdj{W~($=`1LM>_bQO^JV4-_d_W^0yoRQR*KCmMm2%e}d0%?&v>C z{2yB>;s&eL|MAG2x_mp9$-kiOKPLI_x9Y!&`0pQ424LrvEByEg{qWsRE#E5Q@2{L} zG0eK2oHI`RY5y~vS*Z{l|7p!T80zRhPW;)*eze}jCvTX4feGRtb&RPfi~ZvPX%tn( z1o3}-r8)@Xxp@4ciN_zp4Ww$?EOo1ie{nozs_wL7$ZF#M#L9mBY#jZ2J0)LCNgr_7 zsXN(+>oW})1)H9|*x~38 z@X-tWwfQB9-@Id%l?qXOPJN{x`52$`5A&TROt0*voQ;qETKtN{58NVud?&;wIEtM4 z3sebzV=(3MSK+k@i*#fMHrLHW(zwAG8UNM@e=3;ncqyDd;Aey>M(ZK`(~5CSs_KNV zWStsjEKGmp=WQw*S@^h2HTk`SAGQy}_gHEl`XoMIzlI{d>H5_#@gbN$E`4a;lK+6j z=l=IZd{cjiE#1iu)Mxlw1nTvbfwMi#ZIcn*edMs01b$sdP<;m1S8N38 z8{p4^gKs^5!F+F=B?Z_a1z%!}+`eFit>7@sA_ zzjCGOS4{gQK@c!LgkRu%<9<)XXKeT3(>JDugU%g_W8@KN7KKMvwxBJHzoh2Y4jh|^e^V@Un2gl?m5Kj}w;XIhJFd-z6^D z+W#KnfAUj{*h0)={ts5n^S@5~dH%bxBm;lG2JrmX@UQ3W-yr@x{{{a<`>)~O$l1S_ z`1AZ1{1ffJhJSC){(Z!s=f4-_Pn7*(`@cV`hpT{;heKPRM?-zY|J0`(?8?ny{*N9s z&;Nen&-34l<{o8#*#2wy_vh?CK>T_BC;Wx>U&DVOXa6Sg=lP%T7utUf|7OnqgT$X< z>+Hh6utaNsgZ;M+Q7yh^TLT7(|LM1U+?BW1{tv1AJ@ms8+3#KC{u=QgBL0uQ#fkv7 zw*C&Q{K;;$2mNR6j|Zu{EW^bAu}}F(7{~Uf=g}@YV-85PzQk3V)ve8vbi?_MasF zJpUE`JpVQPCv)~+OZ@Tb{F1^Sx;t=OI!i{1sSI2BzfR#V8ien%Y^)R$ zt|R_WCS!o##IQK**TU~>ivEdL_U?V<{D!xu49UUd1&Lp{u(riu{2szD z`^Ciz3vazax|-TwsZROq^zuJ+cZo*Zc{d2Z%1(R##Uj6#@ay(clYg&1!Y}%E^S@u> z+s*$0%D0^VO^I(e{|5;l@~3USb^GBE;n%wbbQph_@Ync-SDd{soF9IBqQjI~KlX(4 z%l!BZ-vx$q+b%GAzxnL~9_PURNpOB)8HRW%uHd1HPGwv;zr6UX=k~!Ab03BN`P2`x zOy8dGunhjq6#vVe=kKt5{UNrw#=nrWe=&={LHvt3`z{;-4Y^%Q^d3viQgC5An~?{#0`IuV(Q# zh<`O_|C-95hdE5PWd6sUM%);{<{(4-YsCNLuYBCA3yyDFxIU*Ri+>b<>YpM1dvf-# zXYr5npZaHre?4daMizgA_&0L)?ugRcO% z4)C|>e|m}ksUME-8@lLB{TkZ;4Ucx3I-MJR(x>om`q8JN|78vTzMTF075?qwAAYmU z@$V=8Uk&4bkEQqzDE!;Szgz!-oc)^$|HQ?stv(Rue=$CBm^uDU;(z*w_4LL7vn$4T!Z+J5dWtW@pml5e^lWw#=qsS6aUei{l|!ZaQuO0 zbF}|X>NE6z#)$u;zw&XT+r;+Yd6e)p-mc2xAN7Ce<~~FJb5+j%<5~Qp{wMX%5dZO< z{U@^c8^nJiXaCj2pZ7midC0fFst?-NttS3Y{g7W@#CZOjZ+_Vtg@1DQF}4H$4Cx+^ z9u2I?*?*Gw^Y+J!<{rE{ZrJ|p58k)-0q6=LPKWO%iT`82dT#H~#lRx0pXu#NT%QOso8bG{UEfYu86@$k~5G&i*sRAGg1*DzNHZthE#0K*?*JD-z5_8BUO5Rc(@Jjcz=~m#Q)1b9Ea^MTonZI zAAZz)`@31wKm3Lr{WlZ;XF`A6{@U=L&E_9mAHJcrT%tZuryj&C@qgTM{I_WOhu>tm zlm8at{}s#e-zxh*w5A~CrO)%9-&(4*3}C3E|5oDv#1F@@|FeYspT3HD|7V-*@4Avc z%u(Hb3SUO`W*hPUQrLbTu+)BTr~WDlgSzd+-%qksaY}xkVc20S!u5?k{^@-u-+bl4 zmma=h`@|-9@R?b>b2;-4WMHXADaiZ_C+{!(c42-`r)Pbz`ib`ghu3$05r$FhKdQ)jZhD zo-Z8hdAasL<+@W}zwp%5TiIBuu?8i6oIlCYwex2vo&QqeR{h%i;dDOF|8wVXcTzw9 zM+hIbU!?uH{Wh3`w*M&M)As+lb3CE6`EV)A;pFo>obNLB;b_UiF5Y`QJW++t>!f)7 zN-BRihQbTR-*6YBr1lTaUs%ZhvcmspJhUbrQi=uTqrK*}pH<-%t2I8vArR(3i7+f2u#6 zX9(N>_Y5vH>d)DKAjKbUA(Du{elL1}_(S{CT7NBEf7ML&cN6~l>u)n>|G`v$FX6Ah z{to8sKa}e4C;au--=UoShg1FStiQuK`;Sn6*#8Z-zsdZ+n(3Ai;va2)pR=_69ZmK3 z68UpjSD%gM>_3+3?ux1N1N&K<> zM^v!?&IdKg!DMSy{?Yv<&>x0fgE_1v{xln}cliCacCEw4?FZ)ZUr+p<0-GI*u;?ERYkqklA`Uq7JVt&MG5+5aB~ zqhp@v9}UM-bT{A<|3}{$m<0kn@CD+pzgdqZrey!#_-QieAFT`V6x|I>5&tvq4Didt zgX=d87cQtw%l@BXk+TK=Y1tokOvC)Ku>Nk4{eLqUg~dYtZy^3(d}n}Pln~^<`N`B7 z>JP^cKkh<+nrwmj&;(8KZp6jtE5RpSl^Npy_$B^)!#Nl7zx=c=wWY8z#s5F|Iad5P zruci7{5PfeL;PLGH;?}&;{Sx@_-{_}hxl9Z-<;xaEB>=8e~3HgKac++EQ2eKcK**2 z|0jd^doJcrzy5ihXbsqs;*a@n!+%SPKaal!|E(&22JJ$VUF7W#oNmMTN8h*G*R5** zc^?0#&Evl<#UJ8t#eZ9hKaal!|LrP&AEMl3OFaHz{&ySqX#DNOKWu-j<^NSF{t$mF z{#T{=+sgl|Q~V+R%QoVFHSxFI{#=vd5AnC+e@%+Nt@zKW{9T^^o{jDAoZ8=7|7S;v zKg8dP|Be*@p#6b%+OS-!^2a?4_{ZZ9`vNB0-)o6~*#5XK-~O8WUzg$!@weiCU5bB@ z|K|QXRsJrIzt7vBsUZHki+QKo-&+1(pW+Ykx8i?&ia(FPh5eTsRQ{zP|9Sk&LHu=> z^bKnNri=M+;rPS*Qv5OhZTP=0#XpF@ZdSIY+okdk+8>Ym8@4~Yh<~{M>+<;PpB9O~ zz>O*X*#6t_zcIz1$KQhgO)37+{<}8(ZzBG-+yD2c_(S}y_`g5J-&Xv0tNeZVf&JgX z{x58J-&d<)ans{hA0Ylu1^#ov@mpx)49m?b zf7t(p_+RAyhWo!a6aO&&^MSwl{_h@@zt7{p%>Bds(GAlcwZFCe@l^gU_xE`IPnqSv zr}np&KYLaFu>FGk@p$|Vw_kgSf0+Mnu>P9o|2~y}iTm@wY;dzXzy49{-2@dAez*|8Ri#fBn)) z$VleSL;TAY&cA$6 zv}f!#;{TOPC-MBRyBnyhD(3Cy?J52zuCe2Pdy4WA z@xO!kKljd_Wr)mzi%YfN{QUKuDgGr~v=;pDO!4OVmE16{2>okt!b{4oEm#b=oCAwT!R zVS)4ej%|5){DJ=K&V2pVr=~xp-yDq){#yU3Wt%Y?CHy^p|0_S}9M;TZjLG~92lc}t z&36^ykFv&IIIMAg`q;$F%?Ik&J^J2p>2%J^}KO@O-^u$zk6S48k{XfAWqu<5W$@TzY?=65gNZaooSNaD2~Uvj2+8L(|{M z*}tIhKcCV6Vut&Z7bO2hJbLIpX(|3im49@6GWk6){?%kfw&9}M-`erXlEVM*Rcb4$ z{8xQZapDs3KXchB+q^$aS>>s%wr7w$+qp?;>SXp^p_g(|KjDvD&8OFdEWl$ z_j{r__GI$+Q~dF0QTx)9vwuC4KODwU#(%P70P8vXH?sK`Qv6A#$;+aVvwv>}fBu6} zW&Atme=qSrlgxkE5i>1)nf!h2{O`-zzdw_|e*X98>_3prUpxN?a`tbk{D;J>^zbd_ zfBbya;B#Id45t2t%M6A7KeqokaG|)DgG1Ge+m36t@-mI^hAHU|C_;og7`mmX#o4I)~;_{t@0P+ zAAA`ae{|2_zgqU^@ei&~Fwg%r)F1Q5V*J+-|Ht16;(r|T$HMiclPZ6U@t-9APlWl; z{Vn{yW39?R>c1uP1M?^9zeTx|{5;4q>F-+NfBKyPq|XKMH_xASD*tIkZlnK(u)Yib zb;KX;53?F5UJ!p=mCeffG=GZK^j}Z>pA5L(PTqc+`@7WtVVHs6lK=H@e)F4eLn&N_ z{zIZ3zYdm8{Wq8RpSx6ie?W)z_iLS|Zh52)O)31x-FWO)hC~17UCbXW?@EWVf_lZ@ zDdO*6I@y5p7gHaD_}jR?aa!SDlKVNh{gU=y6uMH?wB%pJR=^Fe50pmlx?+REzh=>Y zLyCWJePGwR(gZUK|6Ys!GqOJ>efawhNvG?IjSBzh`R1io_6zxgy8>CuM&kd>r6OM4 z3-sDH-kvW~Wc`1{ET&3C_;!!8Tg=kHDOEesb3f6%XDhFZJ6v`F}U{s!!y zP`;=8RZ4_!|N49}{`~se2QE;5U42#|{sF%rU7xQzgDT;}^|v1Uyx3Z)5&mAw*WdQY ze5=>r)(Jm||2}KWx1r>pu*UCI@hv`ovybp6g3Phz-%t2qVp`)55PqH}jtUYz~N^KNMSi#>e9bVA)AEEp+ z{eSzKh3#(Z8{Z*b|9lER5qBW@egNq^8QkDucdLHyfKo8{B8!e6-yrs-dn z{nwyZu>NK-Y(Gv#;V)!KG`XgKCB;8je^ z>zAS=#QafA&}G#S^@r`(IQ)|f=8vjg9y3`pMEp-B{r`{dc}X@74=en$_8%xq^?sQ6 zpT2Z5Yy>d==G(6kmA}}`gjx`Pjq{Hq#Q$8<-@^UzMiu@|)%jE0{%ZJ-68}dpoeb%? z{;HN(cXeabANrrl>wkPb|1skK^rd2WcGiynDuuuD`X5dIRg(WntN!EE|6>k&Tb2Ks z{^OFr-S|&X|L0TkPqY1>ApU1!yq)%cHT6G)GjQX%!~@(vu3wJpI}EHQ{*Q&fe_^=) zH5Tnpbbz$^cujkMKb}a->{LcvaV}1gAoxm@q2LeJN1r9C>EH(9 z|KvLZTVWiR`&;<^$c)P04=s{@=%1|5=s!dJpL%EDTA*9|{m904{^8f)FPi=viNF8O zz)b-b`_Jb4kDI7}GUn7j`99VUsS*+Tqn$A2sJKa(Pf>#s)HO8mc) zWLP+UwT=3}l$=3g7=J&dQMM8Puf_~J`M;g|$9y{j+lhaR3jQB%z0)0X*t^2@leX_~ zSy1t(Pg}cxW>Lkrcz@24#OL=9JpbackGwqh!0PLs{`zZuGn@5~BbFsT++Xzm*R92; zLis_WSi63#O8A4Ps<=~ke(~)?pP$_~w&BTVe(=Q&|D?a2uMvKj=hpZ=gm3ZI+g!Cy z_`~|C5`J~@r9t@o`aQV5(N_F>34b`Pez*n}k2=_gc-+A;J&mYc2l6DSTV`KSKCX{@A+z^C;olj?Wn3 zZ#eagV)?3$*hCr9{&f}MkNSNFAN%>w|Jqi3#w9*n&gPX1^#ktnr?Y#b=*>eEJA~I9$KR!aPOW1%vjdpYp@?OW+%{ zKLeB>dJBAm_NPhsqpJ8Av_FHCuZoXB`!huOs`wbRKf{DS9IjtuVV?5*F=&5ADBndQ zV*=lx{TZeF&|Baev_E5nKdOq4LHo0c@?9PtF+K+E&p73);$zVMOb~t}T)+CmJjHLb zq`F^2@HIRBT}}Dn`X%tUbi|~Nu!izOZ-IX+Oun3oX#2q=;rFTHqr9H1EjIpeE#<4? zgJ<+K%R0(e#pgDFFYC=fUP^{YS3Q=~3AdTgA^rF=JF3H+&`PUr6w<%iw^e=m@i zb?A&u6Mmm6K8iiotaIBy`ED?!;6I&}CXY8m`KtKrgXxy#X|vR9B>ZByepSLeMTTq8 z{%oTBaQzba2JO#g$`8E-zCrslOZj2`RKn%J<72RXZJ~S@iHr$+gY|1G<%iw^-(daP zM)+k_{us2++bLg_KL+jdRg|yFAA|P!YRXsTk3su$4duH$eZ>4RXn*D?UzI-w?avOv zp9u43JX{X=Z7#w?N`i0I{oiXTKg=J24>v*Uo*YbZ9p#7K0{;;3m-Xhblk&s-84s5O zQZM3WTC-eF`5{T*yZZbaC_nTT_?~`z-beU@Vg57|`LkeC9yh<%iw^{}7Oub?Er03-S1WPnbWoME)%4q4`vMDc=oX0za$^KI!i7KFSZh z1-=K&J2uuK>=v%j*N$b57}^!STb} z2!CzpDDVxAzuivwc=JpwV+sES1OGb+KRiD!@(uj&B>d0G@cw3OJmG(l>GwbHA^hn2t7d|~ zV8H(n;YWu`Y6<=l#7no_OZc!T!=-sKc!l=C)rG@!M`V5&qKiQTWXS)p%ny$STnrvV zZpi-~nIC4O9sYeXKfFTC4*w%EzY;7?JN%Ez{OImE{vMo>Vf=qr!4DU(75>K*{O|@J zR`|cC;Nt^GpjhF5T)}5&f*G*);MFkxzpvtd(;k08#edx%|9%z!ZF~F&B);zk^ouLwiO>2&zLoavsLY4V4CY`XfBrz`H$#6b?LQ>AaQztEukg{v)i{S=JT~x!%T@Lt z20jMg=O<2dJz4nGvc5Pf{vS*HbGrP3#GjV^nWODrRPm`lbF}?S5`U%=JmBXSkL_VR z{`W!rPfgv<+^jKAj#rlW(=wkq+Wd;l_p99W7mL+7@IPN2fiBUhuv3&&%QRe-_!n5v zp^Eu1H+_Ch=KF*{W5Vx|`K&C)XV!#Ym-#gQuqUh^pN7Q$8TH?3!ta&&)E}Pcs_)+? z@u&SN@1Q{b+zcs*`PtOx_e*@pPm%AM@CRhRPxvz?{HDxjWzm1ugg+?rY5eC*_(KvO z@>BHRX~G|t`P6^634cW5Lw?q(eU%LGDGM~nu=cg{;mH3dKqCd}1 zUH+8Jr~W)Yb@|g0e>yyV0{Mw)dcF$#OOCJG|J)$+{a{xp=41a>n?ED*A^*`E*DriI zkG*Mq{zjSa6F%m@w*MxX&w{2P_Q(9!=5LnyKH+aS;m<1gWclLyrR~2(;=}rd%eA$9 zasATfZ@~@Zp7p(GckoXXPnx6*y7w?n!5PysOT@oMSZ;^ka#E1A>-PEb&X>@`clc7TW(kDn9oY`MT}1r{eSDC&0fs z+m|Bo~9zyGqc5M4Xc&8$AC;0Mw=If6?V1lK3SS zblT$h?85lJFw2&74sqP7;Nt_ZAwQ$#i~Li%{M#gcLH39E>+)|`@FjoPzUcDrkoYC$ zz$(V$6P$mnVf^3x@6N?wx!`Bn%bgOxAoC$Uy8OcuAN;vqynK!P?^5uC3xEXvIbHvG zi4XCi{s!^6Tfvw7Vg1$hzenPieA0eS^8DGtwDRXe3O;Fnkbmw?P5!+SzaaZ#{5APU z6nx1au&p^in%P*igYaJiZ z?LT}};vX&X<`b^p;1|&Rhk*si&sTN%zbo+{konBf=6_7$A1wvfr^Wt9P5ggP;y)ns z4g5bY@m~r<{R?P@;^q7Iy7B*giGLJUFnjs4An_r4YRHE)jrLy*_TTSU@#+4H!T#w3 zDn8wRF*v{f2^F92zd-w}yL^vI{1@f?VUBkG{DH)OK+YeCzpno$B|hX2ZU2Fg0QTuNYpHEBtX}SG3;D1Kq!{X)lWft~-wU_T7N_<$plyBhwS&1L1 z3hif9i3_Hy@<$T?glhfL=Krz84_7a2KU?j;ue*Nz3yB|W-Ff>Q@eR(u9GCbkygVGQ zZx6R$%=5YmdSc`UCBE+lALI4C5#LWt(cR#mNPNcXL5Tc4xcz$Z5x>A@m%F33#{N?k ze;@xm$@g1RbT{;nf*&qnxV}A#&x|(za|(XAfD`;#ZT`Ph@cHH!&U&@{w`=qNm4e^8 z{y&P(oHqYq1;2Iuf5hLZ&HvXb{x?}r-i!FVwE2Ig;=fM$yS4fMM#X>I9{=+)KTQ8b z`vX^S=$1d1`C$W{;KK=QUH%tjez<)X_~CczelCy5{QiKF;76OB?(xi*`HA0`Mfs@# z4kuZZ`C+Ut!fV9W4i7sa^Wl08EaCR$#VgV8seA0-wS_C zOM&q3*$hO#W{qDY{7-L0oXW@%+KNh_(OVZXYkwbhuF?tTWx>Ck!5_Y_ z(x35%x+bF`55x1(ME|$eFW^|g`fDEl3h}SH@L1VtoI_ANpOyB(zY4ZLZd8k}_&~+Z z4^@QcuL=HNTwBCOfBq=M-?i|lr7H1nxDXrJ{{Y{j!Dp?K%^#lcmaBh__z$~mXnPnWBIo%r+o4-XJWxq|Be&wtYXWLbaV`FDc< z<7*2@nZx{VT4;Y7#GmKC>>uR6hCe)CFIWFw;?MJ6@(=T0!ylgCm#cpt@#pz3`G@(h z;SbLT%+tLtTTK*3x{29)H7W7xu)A7iAc)p?F z4}DoIOGk9$$@Bc3rE-dbSv+4eH;59!)jXtayCjD30UDBRVb&_I~r*xP4hE`t03D_(#idXoDAM zwL6u&lE*jx;)NZjW|oWl-f-S69_TgCA&1HSaDXy)a$Fb;{V!|y!ya6&{&4L_SMd+O zSmyW_i2uJ2?lN~9?1>-pXVQ;O={D&@$;QySE z|G2AdR>}(hW}+kLxWJF|zk7c;E}5%;Md9Br{$aE-=RY);g8xfG{+q|Ys_<_Y|8D(Z zOO>mCP2mrY@qsJHg?DlOGpF19hg}lE|5+jbr5zTSS$CyJ;Sb#_rT^t(_x^A{=3M>j z3V(=z(tic~!{}trf7n$N{QpwOfAjb^6#nhv->pB~Pd!)vUWI?6`@kF*jHCQN2}hK= zZ2zH!5&TaH`ETA2?Nj(SeQ*wofcoOC$_)-=hi?EGRpsA++JjkKePpc|LGTY9Do@3zX$#QUA^Yp z-$8|cV*4xjU)J!4J(OJihZO#a?pu&9QT(HaOYmAeJJ|XBGFkcs`0)p^D$6_gDUjg*)C&$jg0jS~ugF4ZKh7$Jzw+=N_(T7*>jIY>=ITFA{XMm! z^D(77bV=J6IEF3wDg9mPs|WFK)n|?W zI^zFjA^zqE)7NYIXN^Bx?J30ne-Pqt?hluPh{vBjFl&W5)Pw^P*#0N#v&J7L5&WMP z;;(bZqF9L!OlkUul#cm7Mf|@Z#NXV1n))9V!rc0@?-o@TbIr9zP!CNL|0iE?3i0-L zyLy^#YByx_Z$fje^2c8bv@IKQ_McJudy*4uF2TQ5pEduXizDR!*Iw9h!shmOqo#lO z1v}>dM&kePLVsJ^-%U#Y)^;{p5JCJ~^;zS;iTHn2h`;&vYqO?**7$EG{?7~XH}{`a z`nyrsn1e>L?F#caJ?P5k{NxRiXO zH|(%CgzE!){L}kRzWK_7FFkz2_K8jI;4`!QS6bcyJv?Nb#J_Oz{=$!!&YYdx{Efcb z!xqRpqsfOO0iwSqCvCD4;WtiJE);)Wd*_b(rjwIs$EPgus~1ka;0!u9-n@JGYw>|- z?f6s(zsE1X^61hhlI}*sRf&JvJ9%;MgGV18+upNjeDLX6e$ZAsJ~f%Yd~)H$j~31x zpIr5g^6g{^flz&Uiv@*~~`F@{w%hJ!{#5bKuKjHWJ)mI1KoH$RKPVM*)5dMJQv$r^P;=$by zSGGGXdF}W&3BQ4xaf@Y;@ZpKkK4CH zaAvGkwE64P_|MH-S-x&M|G=Du4``<(Tf6bVj zKk+x}dZ35+NBMK!QvTEx{;OdLyA1X$!uY@Ez<_3{6aTONrdXU@euVvvCI3dMznk#i zq-oDsBWM5KRDUnwe^A@MH)sF8RDVC=|ERWqU(Wvhss4<2J~8v(b1K^T-=DMpK#D)~ zs}u3pUw;RPKeRuI^;bAXthJ1rss3)lUw{2==IlS1>hC4|_1E9Qoc)JV{r!Z${`xzV zv;T0azn%4WIA{M6>JR(B!S*+q|8SO7vy2e`X!|>7Y5O~x>hC4;=dh+dW1~6ykEQzi z3IC_H{l{|lUzO^g%>RDv?boWD{l`=Mu?O1ff9mJ|IPs6RUqSwxZ@(r|{k??0e*RD7 z?7uqI-%kFo&e?xWs=uB5Uz4-{q{@GaXFub|PoiPX7HE?AWBZS&VE^6x_`_P2e{|a! zJpKd2uBJOqwwCzg`iu2}zxn#Rj`*`{S#SLNviFMb85}x9O}38spLuKj64sx=-^V?P zLuO^Y?Ee|a{Ghy7HuhgH`=3X+Eq^%9ARPZ^1-tQgWq;SE|CH=+HU3kwKff%&R{W=l zf0Q~HBO7I!`1?s{beu9-*X6LoekxpFx2MbLJB?nTeE-((Ux?bbP7`PNyh!*B%hxZJ z2!GUXSY5M{+n~c_VpVzdi_QXuiqHq$FI!4h@}uMmTk-%w-o=P z%0KEC;`v9z>mQ10e{0u2lobA-j8?+S{1g(r({GSU#Q)51iglaU50q8@QT);0F#cuY z57!UyA7$CPexRc8kHQ}vKaAgN3{+%)tL;x!;U8Z=vtl0qD)INj7}$z`jryN~C%#4b zV`2TR{bBnRpMSyl!zSiENB{V95ApxvZ;AtW{lhLx=U?in{vKnozy9&(dd~ih zRDa0S*#GG;YrB7GJLZZVt@VfFTFYY_oevrqqecXe*X6nf7pH{@?U?u7-d3# zs=t@WAN~CA&)I(<)!$F}>*xPK&i>6*e>?dP_nH*?|F-jIP~|_xvp4w zAKQOK*gF3*r1FoBPvZJ(c>ZOG_+$KA{^slNF!jGS5n%nxmSV^-@qax0yB*njE$$ymkA4r74g8wM-e=5ZD^B0L9m?h@g)!-QQpH56}!GDbSM=kLI zYxlP#$4}byR&zQ$){L$YFXM+CGa9Gvt%Q*3m zPMHS&(T+y9)YkYD)W7wSm7xjZ?ld{zU}z*=genpr+9x(Xi*Qe9+c?g_i^8kf8j~o z#c0t4uc{j^;+SIT74~0F{4&vgZZ|x*3Nvyt_%GjvMtc4Zll*7m?`Ofkp!9d6S@<~6 zioc6*|EH7j|7^0e9%H*2C}!|)#ora!S^VKgn$*7)e+&L4rN7uOe3z#? z<`1cdCt!CfCE|bbmsLD}1O>kR_DV2l@VA`7pYhd9&%d0re?{Rx4(qC1&|g(AkD08g z5dTxZthP4q-|4*kk}TD5RpEa?dACT z_x1ei#Q#gbtimH(!eYU{q42LM{Rg%3ry={pBU|kG_fr3lIqYqv|CE-0uk3F%{(aQ{ z7{rG9V>1D_J5bg~u}pdGBmR%SwSFgz>hjSi&DY<4m486zvxvK*=uhi2G=KfX|H-%3 z9{{k&;gj9B$9%fPp8=J>AC8dpL;qwwewO?^oP@p%5dWv%T7NH$v%trj1g2qWs{C>L zMcvRps*l|1I0~00@jv_4`lB$K&qtli08lWKRfB2%$&qka(|?fo`){p(C`Mb@{ti)p z==;Dgmlfroi~K7nK517qMEqN~oW%ZTyD77MHcb6->B3cyQsMH7dTB(lVwm_p@iPce zR3>Rd7k!ZZb%gr!lvH?X`j1fmx7K^Hody3<>d)h^XxF0rk7u53V3hcOS%|;+`a4Gb zIntj081)z8Z|=W}`eXc6Sd71_zQbZzMf|^-jQ{f;CeHBjIQ2(Im8YivIQ37)--7=H z^~dHx*)04sTnd>XAY_yY;t&1j@Rpn~qJ{qRYL!262;PFfMp;e#TkSuk)}lf?gAas&(ghqcuI0M0-W zXMV6vQJ?ft46h~re~}!=Lj2b${S|TM{)+mfk79To@&9^q91HPZPyJs?&LA;-Im5xi z#OTrBdgA|F^Z~wFSbtsWpXgpCXT_La`{U;9KPCB#)~4^Kh`+%5j_^+Fjl=#?IDZZ2 zXZOP0md@`xw&msV2l}r&^YvGsn*LO)%iHZt3M&5eX>0tVif_@sB=M(SISu?5kA39j zxd&EX_w?6a>zmo!eY+6Fu`KZ+{`bFbEj|^>4`yub{Arc&ZC{^IllVQV-eDBZu3vj7 zziUGK3F?GDte+~%88rx>|Guxl&M&@w=<~Dt#x^|p%n!b};h*%^-(JEWwi~LCLixeGt?@?*-}e0n#t1(QowfX2Mfl;#DQnxWal*IlKSB7m^Jg{XTh1TGK7SXR zug~CGi+fiugaLXle2rduH7|8>2!Dd_!ogi5=a784%FeUWMaEowr&9__KHQZo;(yzW zUsUqp?wp(-7+*B-FHydWOcEbgKR#t8pTx(2Us3W&d<^(i%I9$>@$s0;!-k>jvecA( z5+C4qiH%3^QSwQA4E*baKiI@sH(4{ve^|d3n7)5Q$scd=Vf`}U_bU1D4HD}Y@)wG1 z0iJc=b?Kvg7ZD^ru6}&_m3$H(1O9-LPvT?1Z&H4^ehK;G>91ddN(>&dlx7)G^5It#5g*pCB~3O?Hmc;qDF)6Dz)Qi4*55J8cM$`>`iuOb z{aNC5Sl@kFrR0# zZ!m)?C7;CKfIqF|Lo9gw;T4MO@)xZ?8z`T1Nqjv0WiX@UllU0$H!ArMie!8Y_?rly zKlKidQNDKtOO>&I*u&n`4-eZ+`26B?!hZq2j&7MHe135<;oooIzlHD}6eavAU3r*p zE8z!E9fbWO&NSb@-bVPr#oN$-PVg5D;t|I&(KCpim@ePj; zTut~ve4u}u;4c`&=NiHf;se|F1b>MS>;0J{{2)HCf11EuH1OX+_|e7xL41OlEEw>w zCH(NmDZ-^POTlck{$5A;u>QjJGZ3B2SJw06SBCwEoicySCjWYw5B?DS$RGOWu2y7% ziEfbj;BSxrKA9g}zr_6m2NVBYG9Ub*SmNI(^P&B3hTBKjKpMvXCMAEo#W&1PxYSuV zKFqgYEQ&a6U;aVwx)2^?_~S_YX}`+xzgVo!!3aOa>(!i7!F;2svcDE2{)I5%V?NAH zpI?;uey~Et{23E|N#?UM7&8|0XHEEJnNQ;nOF=(A6^Z{d>c7*3UzPdPf42$0Ch;LZ z`7dA~{x`#7!2E3L$EQc)Lw<^U*Mwh}`99&#nD84ipOr=bSrdM*%%}06GvW71e8^AH zf2Rq*U*=Q)-6s42i4Xb7JBN^;UkLLP*59(``MajXhx`=zF0Nm?{6U%T6FzT0b@@Xw zpOr;_-hS%xhh;vEKW{&E`6Ch^@>BHZ?WZn(ROVBE-hS%x$0R=F=OM^T+%KM9`X~@^r!fHd&k%9f3B1HKIdZo2Yl?`YV+4ie8_*~w)n0I-^0QLFqd5+D3)p+9aPv4Fqs_IInq z2Y-wFZ4w{+gZAHH34h)8dAr01e~bL9B>uF#d=2)0ua@`^Smj?M@qcEOKPT}oSmp1K z_z-`Zp9cFE*GhbdzeWCa5+CAkk-t;oL;NlBub21`|3ld5K>Hc3zXtu!8zer&-y;8g z5+CAkk-tmgL;NlBZ$cDDSMmAr6X4&Bc?9LG{`Pmb ziqG$ll;Hd9C%XOf52*MqN&_EyZoEMJ@7KKk@MeksQmFci*6*Qx_V>E}dnA5A&L4yJ z(^K(j{us0mdsTdzKL*EF_o?_af0(14Kl>&Ai}Lbij`s3BAn{@Ox|o%T{Dk=H=FbNu zKD0l)06!`|^L6N6MtTuoQ6K(pZQNRDDSEbi8eFhgI#(xc_<-#ApF(0T< zCs(Uw^Eo(dx4>V+`S2a^^`Z^_@jKbR`V6kD7@wMjm?RMeCh~)0d&x1(h8=cH@DCeL zGiYLJhaDC8txj`dB!fYRy(;kkF41ZlVB<+0_J+XM-;&2jVE~>VA@E-pJ~e*>&yNuJ zubLwT0z5xL;QPX-=5OF`r~?0>IZ_}L2!EgOsreg+Egw#{5BBrtb%Ad`e?-3R{BhWi z1b_R>SLEAXzK|h@liSBasZy)=+H6HjBEQxbQ0-+}GBP4#0-u`B| zFB8@3y!HzGQmwZ+KB>b=o2Du7!}vEx#(UhEIU6&2Tggwe>AwEgBEPkK$9ErayT?gW ztO)$*W4?S{8_V~%>HOxng)eYf;J22q8(k_MeI>ouD!T{T=bdr4VNnm0I#rGEznnUz z-UmG*|C?v@FsW13MgHU8P90P4gEISguJNxBzU}x|MZWd;*F?Vc_!q_H%WUU=iSTX5 zzbx{t$G;--^^&~JRF1fOt;fGW__pI;6#3TUUlRFkBB}RL8ICt6+ke{~^h(Zr_WZNS z{^!KP{H~egp?STiB&It5Z1Vm>;r_c9pWIxAn$q+j~nufgkSU#h~*1D{`E0n7xm*)qI?d;Km6pf&-rY6{-9?3%PKx! z2Lk>gU*Oa8w`uY#N`CAg#0UI!^9O!_B`n|8!&!op?_qpq_iFmr2>*+y&dYoJZ^*w_ zm)}G9Q^5g5H~{^H8b6?jhoar-19xls*C`(lQa14t*)QOafccOKzd`wdKg=Zb$0&jS zgRQ_}P3F=|_}5$J_YwY%6uxf!`w4%8W&Qx+Px0l8e}d)9+c$&wHwpiG%ltvY-;u)C zjsFngZ?McCCj2QELhs^CzTm>zHFq3_m^*XePc-v?gz`P$d7SS7|F|iCl=9J+pYP@E z=gR-bx0L$Z-!UbB9H_ze zk9QBT!{0>sJJ46*uiO9MtmMo7y8Kzf5Aw&}^4&uC!TM#7zm@QV^~)ZA8{r4}e?HFt zM_`C8=x^V*6Mm5Y=K-3?PXqo{gdgOm%-7AIs|kMtra#;?B<%kL?GO0t@~&JhN@Pqg-gMT9a2K*g_AH-kg>&E9=!VluJ6vv0>r>7sE>j*!Hj~mD55g1|y z{GEg!#7E}q#^-v%5At&yF82zKpIq4k{_cST`>Mh%rSMy2DmM`RHa=C%_f7flBmAo@ z^LG*cHJ14|5`Gwen2Wf7q`Q1?BK$D^*7)xy{4oC3_`3-|jK4Mh2M9liKlZPJ{oknn ztQ-HE2|tLxJ^miT58`i+?-70we|!ABgdfCzIck4au6zI%g|FZK>{Ii_W(M?C}p0evm)*__q*#5T9ixtiJ}!_YmO+{r^_~mbVWJ z`u&Gnm3({sx7!Fm*uSvHzn$=d{IR$G-l67OTfTP^K6DJB`1~*aIm0XT*Wbg0KNyn} z+n0;ehjh;$-9`8fksrR>qVC1n(D=$hv#JDQH%x(gunbCs|M#x zjj)M{mxSvd{>R=gfAoKyhNW`x@&ElZ|65`-?ZLl!mVLNBgXkl^N{{oZEPotE`NthrDlo@`sr^06-`@cDtHqzGeDuhX4Yw9vZTQ!9#V<(w zW59P>{9(dh{!mx^qQpOI)xRY1p+&anUzYgi;d&PM391J-c;=>O#IR8JR|FzFImb>$>N&MG4 z@Vm>O9*O@WSiX!&{(r~g5Ao^Fzb^4#@4)ZQzajCxR(#ma*ggdD|9`;$wm*UR4|lbG z^-BDC&Swi@eq#G`GyK!!_euO9f8zW^KISLSpF-F9)1Sr%BwxQG{&`%!$S-ykp8=WA zm#^fnnLo`mKJ{PL^B!TKfn$MNqjKZnxz)L%3H!!o}^{JZlXN#j$0&G?T>e2=eR zO>94d^_MxA|9t)0*Y)~4Ch^1dx79v#ehK-vcF$iW@uBsE_Ol6JgZYo}{)vOX;&~g} zp9@{LpW`WfM))=4bN}nQT7M^Gep&Lz_#Z?6?&GsMg)jI6zZdx$@n0kH;n+Y4F2IeJ z?Te_G;0|MNh?|1rTI+K2Aqvq9oFi@5#<%Xdexe}wxlKf?GFp6s^&HY4#}XrJMq z2TZ>T{6f$lI(B4!n)AO>S}Nf}$yPR|@p1Abe<9)*yW($>_+H=(F99E3F=_aHyJ<6kZDmw0>-AI3izoYV8aM&kR0_$D0w9`4U);D-Dz{pTb;fWqbz*54L? zA<56){_K$WU>osa5aZ7av=4mwcInU9>zk9m-wA1q-~C7WgD3mDD}|i-MZ!N4mhLRm z$FAheujb5$4Eb(y`4*S3bG4nh(O15*0uS?Ry^X4~zrOt4IB zXJF{>FwuX9W&Z;8=bhWFu|5m@TkpFZD&*{6r2b0{$RF%5^Rj%!(7#Ch_hS5`HZ7Wq z!D~tK?*;#dBBHT>DQEw(?+<3|Unc%{TaJH4^2hl9iM9Awa`uNUxY+(MyZK)w z{+R#FV*b}8f4li#%h|t2^0%A+J;WdL-)8*llE2;jujlOFp#Dq!u>JK7`Fcn z;(x#8_6K%x#r2o_51~3QrvAOe|3S>Q2hrQ^U;Bu^?d@+r_4hG< zf?YpE-C}o2c;q^IY^!%|@&7(Rz$M7mio;a?XCi*!|BdKv_pc7i*S|pg_lxa+ z;QwCt-q92V;y(%>*xdguD*fa3-`F2cuM7EO+rLEoinlEB)=oznrsw zh4`No+y5|s;=?IXT4#Q(5P#eG13zmg?Wf)2S5@L~JAZ1#|NFfCkB?s&$G=AWZO6Zd z_!lkv_Yi;E@rQeP2*=0%(|_GtJCHfMJC6wWMlTuPXSa&dKR(IrDoIe4FvF z=ge;?_{sR04)-efHsjN$;F~%pr|(zruUKp$2H5w6_W$O$?QS38_n}hzpZtF2!*2-w z<~)%A&mR={Q%$@5pAzBQ?w^!%=2r;ccK@fEGrvaow&UNEGrvyww&UN(ncqwJw%eb+ zocaBP&uWXcdzK3Kh^>hJy8*&~|66w3=O*FXj{hLx?|9a(KVv@;wlDgTR!`{=ezNa? z!|JKB*OnCg>{E9hvz#-(qTnZE)Y-887}cElH3h%DQFovAZb0v%CH>_EVvMi`$lD z`)WGuDEKz}4<(szsw_-j&Y54ynP1JBU(1=_lQX}bGry5Dzc*)oU(WnNiEq3A#)RwB znqLxDZ{s)68t2M~yB`VseKotMPvNJ^x$@ywMY;0fyl<|2h<2|0YR-JP)l9DbaHrc` z`Ha0Q^-pZJ5Khkgg3LE=bCQ5!&iqo&{Bq9xO3wUh&iq=={GOco4m&P9UtsSN+}zt@ zS!4^hCZAv6x)$MpIzjlJXP1A9@D~>B^3M>y@7v{{CH$o&yZj}>UtYG$UncyE7wz&L z!nd8D1;V$TpC!V#ou4(rx1FC&!nd8DF5%nGPml0z=O^4u^u^@wzwBl|-Y7)L_iW7v zZZ@p+cP-7JnZmdA1s);%R^PS+yG}OBlOIk#|HTF|$#59qd$7mqCC4xwKKoL>{)At# z>tA4mUjx2x8k5%aCCbN#$#|{LO^3>qU)g7sUy=AHtn#Z8zu?%6Pfg|*Z1Q_3AM4;KT76tHoiTeKz@gt{*I}o9ks& zxX06REAuH({vWRYp2NQ1_tVREB2}XN#dXj^z)?R-{zbxnjPv2BmL)!8&k60nXC>+_ zh(q{(>mw^e1;TILIn4?lmZTUT-%i@Za*q%`^yn&bmFK&C z?^$-VK7+rw#@`2F=JQf;yl_Z-8Mtx6CA8l z@kM{iFDv=T;RQC9$uh^^z)TbMvqxs{ZbFrZpM8t+D@uNR2loVrqxqfPMZSCFoAbag zcsPQ@ud4YtE*8Rf75vb@;NkcZzoz87I4+h9{PzAmN()Z!V0e4#$#^A$$oH&XdQGv~!@96)~X_zjN_;h$L+`16`?`6T~) z+wel0d@##zDLwu4PJ_7}xwU1AKDj(v*voSDl`9pk!`u6dG-v_DNXJ!82 zTzLDL$RD?D{xnnhs{9H0LjFX2b^Z*d@>ThRe40OQ+x!`7!u04=BztyqA%iOwtP0U%7(ESmOH9P1ruySYa7z z*|+BRi`)0HHvBTr!bGx%{A#kE@SB9cO36nR=h#O0>%xC=3Hh6o^`%|lfBX+!{B5v4b!eGo_m8|FSnQNxS ze{~yvnL7q;a*|(7))PLB{~9G9Y0j|^a!(K61SO2mE%46e%NPcDe4vMz6936I{2=~b zz{bBq{KI;}r}1B_;s^Qv&A6`{tpl7t@NTPri@D45A71(VzD47+PQ@?axQ-S6dKI7h z4}Mcvk6?~be6C!b#V>d;eZ-gZC*X(m0YA=98lNc@pXa=@B*j1I-zwq{ zI$=IF_lfK8w9JRJL4Rk-!O3{RSX>Slt7`dPgwH+r2mM3R{%nx>kkdHs)Ka$iUn{hq zls}Wo-?1dOpQwmeho&yyZ&UupRKD|eg@0$ceQv{-;=e{U^X#0GF#6Q!KU*hu*|8(HLPvX1b z_Sabw_g@}{_#<;*rJMbiT`GRT1CFyK_Rm}VZu;jps`w?&_f!0rMSrpXFi*CRH>vo6 zzn|j2EczoqegES9Dn8@+?_>VB@GmG3AHLQOEMxw-K_x7!S=_$EBKNUIYJYYs`8cYR zk&nmU()k}y^4%`@Ge>6c!Q-DkOe6c>tm4Dim_KD6Cl}v9!Tec<*MXI4vYzk1%)|B( zKa=}EdsO@aj*5KjyLtEqN|K+b=lliOzAWQNQvb?R@ne6SBq~Wh*5UGo!q?v=I8wTd z?-v?dZ!ZMEjKhg73hcfXItl~4s zBdqMrMww?B8O_ywFEQ z@)O^T!@q0Wwm9wdn!9NSk4gO36Y+N;&iH+>B;&uiRnOx;2giRr7)Or(?@9ba ziTEe^$@pjIe_Z0@_m1N4!f@o@iqE@OHYe&aKI#6y--aKMWqxpcEUFjzH2w<`pHBx( zo8txU_#LpI{~Xj~{;z^9jEj{}=8pWwc|3k{2;WHge}5ak3lp?Bt@z9c^>};|`5x5D z`SU;re%#OD{wsipj(@tygChFV_ULv!j~@$4X{)2w^cuP#GhY=g{xk^pX|Wr+0=o5vJL-JZTNt7TAnR` z=sqUu+xs8uz*qTGemnn9EBQ#p^$Y%ww=d{_9RA_@^*iu73;(d(bmUv}P1wGu=otFjp_A=IfUS{eQLp zXWQ{1OZnVl{tD*{$3KC8a{fp2Y5Dm_9r&}MWf&hN-*3bJ<92-JtNo$AHQ)CB|DprG z#o^00@F)Cs{>PR4C_i0@4h~~U=Fc^W<%{__2j@o);Yd>Z|6p5w4JPq$Iw(ngGJh~X z@%)PiMgQ$L&ix|6fXc3}cuxkd0!Q<8Mns{Z{Y~um4o^5C4^tA5wwi3NvW& zTlM1gnKV8REBWEnnfNpJ^5eq=k3o_8xBptn$5EjOali_-|F@&~DENP-v>50`HW{|ib!#s?N|G7eC~68`u$D0qGZ;{!qp|3{R3oHF3MI2e@# z-;L^66dyI;SMqV{to$fGYW|{f?UH;xVefXC-(8vm)xe1x^)&(SSD%+kYmQv9D*^7({{KPtX^ zgm2$d_+L`;T?HGfRQzcD@^A#n|E!XaqZT~)LkjZA^+m9(PR!$I9{!Q|J?z!Z$>;Op zNLZ5hxNHsY2|n!NZ=LXu9653?{5!(f$u21Aqc#Y?bT`tGZ>RJUen7X!@00mqe4v@I zQ2J%Q)%Xk$J}4vKY30m+Zw+2q-}N_g*otufr2+Azc-K5Sfx|w3Z}Ru!|L0$_eKu!N zAbi-5E>H)P_eH|@{=ErJp0-5za8h$j9!tNbO!&)|T+4({dnKk{r$YE*-@}y7Se5WybEH715xysUYW}8&@TG2{;VkNuZ#jV) zgg@fwN zk1538i$Ae50MEx1`1ace!nd42@O(_c-*)=|&&L$_%(oNwh*DuMZDIG;XX;RaZ9|dW z%W8fw7dIGb1v=1=RefADE_U64uCS#o$@}B|E%e@=zm8vs7SIje@&7US`uh!~6O-2^fB3Om7=JGq&nW(N;{PTv{p%6}hJ(G5|3g;e-%I>$ z$G^hP3Hdqb8wP|-UM2jQYwT`e>V$vQ@mCtc@85_|w{Lq1-?l&8zitbC{&=^J?Z$`u z*GYW*{fw8Zn#Q(1?$G@oX$M~PM6#rt*{w3#ul=P>>(F2B992*+ob__Nvg(+&d_;{S@}{I90?C$(KzSp4srH2aA`isX`HP_#U!rx~9p_lk?fZzTe^CAB6AzZh#%>C!$8i-)#(wnn? zAMr1ij+P$sL9cZpKI;Ey9aibf*}tFqvxk`EAGH5k{{6(?cKbg-{Ywv3c4GYTghNn_ z;y*zAas9QK|4r%-@t6D!;@>3xw&OoY{Y!THZ-d0&cKnB^e;9vT=XZvPzwPZWV=oK) zcV6v6>&#TN1{l0LIr9sIzi+%S`1r!94ek^?xzs`_=FBeV9>TYM{-RF!w)3ZvGru=yeqYY~e!{n%{{w_?d-*mA-?slC;oJ5fB7EEH zFJs?RoFBBXVF?kAl5g+)Y$1h@=YX-8ev@L({F0JyYTcT?tmFr=u@Rq&lHZ!Y=}
  • lxocZv4nOwIo@O&AG zZ*%=Euvdls$A-o_)NYbu&ir!D`~q7h@o)ESyZ@}1GrycOzrxOw>!aN6gV1J*HI(nz z<*%cB{&a#iLS23|N%;l4{%Z+;!Lt8)!Y}YMBV7ie?dbP@IC*{4velzk_$%>z`31uN ze=Yw21Fn}B;$xd%BK!wi*A28?YFR%l6aJrB=Jyf)lI8qq=FIQUnctf;e=ukMK+gP8 z!nd9OBRTVj34hA+`Zbg@e~j>Lw-2jw=C3Av+uN@-gm1h3pCo+S{^Nvid;OXqeB1f6 zmhjJJ-SA}`Zyn*klX1H2qwU-({{GJH^+j;cm#xX)-#OuVcfV+-qv$Z|&#%w%@%y{@ z2W~12$D6c&Kj;wu!A7tL{B+TGIoCAvOAtK}{bf7|hgJ3$G{*Y@#w zxQm& zaa&Q;A6iTJ3%*@G+|&7Ba{qcsUo~aQ@7$K;A5R%ew;JwWkt@HDGryQK-(eS@P2S&$ zz5b`}f4KyYv#?YOln@)gn#S) z?%&MXj1T;NMBx9=ul;bHO+Ng7N5~(4y7+jnrPv?_eqSTJIP4)I{`J4zHexsa4-5XU+&#%}6l&`WIP4A4|F2el-nul|d@c_Asj&Wj<9BS{ z9RQEt{zUM9{IzZC_B?Iw9T5s?d`maUbC@s0$7XKgcYxnt=gfan$j>T1D#>DT*tuN! zj6Esz-!y+jnfi^LocT?{?@u++`(TjpZO6wYe5*HCgs(hB__qD$a^~;IneXMy-jIrA5C=HH()|9H;)2Xp58IrA5D=AX@(|K*(dON4K!TNQ8YUdWkWW#8G7+`qeb ziT|?9v(=BQ5dKf%Z)Rrz?msE`$5cx*g8R=1*N?U0;>EKv8G!rG2>jO3F*|(5{wC-C zVZMAfXaA|3`CiWay*cyebLQWjGyg|~Z@Yc|an5|^h{);*Dn>pv_V9xxNoa6IO&ir{2AKUqVcg}n-Xa3%t`NwnSKbSLrA!q*m zIrHZT-*)@CBWJ#wGk+>)zEAkJ+n>dp`Db(He>rDS3caIFjqd@KQLE5+}}^&+s+@j|DM1f)Vj(%y{U!!;|YA*?E~Du zE>}L>UoKZZ-2YAB+g^W%bLLMHzU|+ajS#-=_>ASuUq$$~<1al*G9|B0OWs|nwB{MY2npCo+S@n4%W ze;wi5j{o|c`7Ys)TW&w6a^_DH{(8&)8*=8)5WemBZ_Js$iSTX5e{;_K+5exmy8(=& zEb{>V?nl1Ubd#oSXiK{-X$epuEd@bQwxyI5DyG2X{`1c6?C$fdk|x>R-#+=z zJI}l`JG%=$cm9V6`-g(ho&RCN{#@|6^FLhJKLUL2{Erm&d%;gL_s@C4{(SHcX0HDz zVSfSm-OTkL4L)~1$AHgW|J%UluK!r@xyS!;!v5RA=g#LH!v68#&t@L~?*yNF`MwK$ z?)pyvpL_Xc!0%zsf1$9y2>c_N>pxN0UkpBX{wE3hOTg#O|72mm4}9+YmkRr*fX|)( zslxs;@VWDUx3GU2_}uxwN7(NNzn8gxE*JJs2mfu%^}koxUjaUM{wsz3Gr;H0|9!&# zD)71UKU3I03w-YU-!JT+4L*1N9}xCG2tIfI=Lq{*@Q-EgpR0xaHQ=AXT>rVk{#x+4 z^FL46Uk5&S{vQ(d*MrZU|A&SBkATme|33-)=Y!9k|3`)WkAcsf{{_PS0Qec^{&}IW ze-Zd6GuQudVgF+Ax%2;ou>VQ$x%2;&uzv~o-1&c6*#8Xp-1&c2*uNBf?)*O|?0+77 z?))zk_H*F(G5606!v03^-@{!0<--0Z@VWEb?~|K|Aw%? z6@2dezbWj03w-YUzb))v4?cJP-x2n|3qE)LHwgPf;ICrtpEnBo-vj>~=KB9x*uM#U z?)+~S_HO~7JOA$s``f_h&i@C({tvU9Ux%2UCd-1+~vu>U{cbLanwGWXARVZQ_XZ!p(CLD=sEpF97F z!u}-ix$~ba?013Bo&N#C{uJ=J^Pej0PXnJj{{w~n>ELtcKSS70gTIxzf6f&4XMukM zbNvSi``zGk=RaH6p94O3{s#;DJ>YZae~7SuDEQp@A13V21)n?r!-f4Lz~|2YNMXMh z{2}K4IZxQ15B~R=>px1^UjROL{znV@$AHhB|J#K9W5MUn|2Sd)?cj6g{|;gQc<{ON zf2XkjF7UbYKS9{ffX|)(LScUq_}uxQDC{o=pF97Pg#9JpbLW4uu-^whcm7L-{Zqi_ z&i_~992JO3{V`&WU_o&T4F{j0&}&i~88 z{x#rp=l>O9e-M1`{I>}E*MiTT|5t_m>%iyE|7*hj*TLt`{~N;oR`9v=|E942E%3SX z|F*DyJ^0-De@EE=F8JK}-yrM{fzO@)jl%x-z~|2YpN0LKz~|2YW?}yp@VWEpF96w2>W+}&z=7-h5cWF&z=9Th5g@v&z=9j3H$#JK6n0i3H!s~bLT%I?B5MO zcmBT>_P2x2o&OGD{~qwU^Z%W&zY~1!{O=X^?*pGZ|KAJy_k+)!|9=Sk4}i~|{~v_? zUEp))zgyUU5Pa_Z|5Mn12z>7R_Xzuc1fM(q{}T2e2A@0sM}+-9fzO@)pN0KL!ROBZ zzlHt(0iQen$AtY+@VWDUT-bjCeD3_86!!Om&z=8M!v53XbLanzu>UOh-1+~nu>TzR z-1+~Xu>U;x-1+}S*na_h?)+aA_V$KV=l_bZ|0?+0`Ttee{~P$+`M)OY zzYack{(l$t{{cRC{%;8T`@!eV|4m{4E%3SX9~1T))XrPgs^;!irBsUk`|jNLPN#q9 zGJ5a)*$L;{W~FYY8w~Y0KdMyH{iggs_256*Sh&ypy2AJRyK4M8@JD-e&8E<6=F@k% zxR&8kLH$YavxnsUuXFeb@KrjI&;RzhZvJlh)#Nil-E^y3)Z85-LoZ(yebKp(TKb<( z^mCgV?3!hS;7PYU~W!hXH5-yrNa3j0mM zezUOOBJ8&c`{RWDHer9fu%8n4+lBoOVSf_%dLF@fnGC+_L8F}3|xby{cNLyy5dr*`o01D`l^)hJ2ir@$0_Hf34Gq}pj0#XtSc`C(E>gl3Shmo zg5ScbD>V*$eVl{y(gyxGPMoaq;I}dRDe%WL`|aR!Zv#5OZ)dK50{9)wekb^0(;t1T zsk%$&Pm7QLyi^?$dasz0_2a^R0{q8A|I+HNNP^Fuf1R*jFYGsfe`9qqhu*6Z{N16q ztnP{?VZT|}ZxQxeh5d2hbB~`k@Y|Uu=;OiX?hh$pzg^hx0H1sPRjThx#oNalnRoDF z;K!K9PaJ&i`V+!_9r(+c^REYg3$xzqg#C75KP~Lf6!v?C{dvNEM%Z5{?Dq@%%Z2?c_>-&K%!b};wXi<`K6n4T zP}t9bKO;2B>aN%z><@y^o&OeLe@NKBQP{st*#D`pKP>Ez2>ZK){oTU;sIdRIu)j~( ze@WO^G2!{Yu%8n4+lBqKus>7S?-lmv3Hupgf1$A7FYGTD_OrtNYGHps*uPNN&k6e* zg#AHbe~Yl+p!WG*zeammAH3G=Y7MDvSJT1D{=$COZF39X>sN;L6#p3VeM~*?JAak= z@U4o2&wYMl0(|cC4_nmzzT=-N6B1;VzitITw~+S?vT@)m=JU7P(9iHb0X80e=Hv4z z@VUo-JNPQjdxmlc`phf9gn-Zc0G;SFzko9q@T*)=L+(~D>^BPgO1Tch0b&0_VLvDAZxHqeh5aqU{*bVL zqp*LQu>VtGe^}Tb5%zZp`@4nxQDOgaVSk^n|B|q;V#4!(VLv78w+s7eVSlEu-z)6T z6ZSL0{z75DU)WzR>}Q4j)x!ROuz#VjpA+^s2>XM={uW`sL8X6E{QiW6!;C|!^GN@( z^!)qdnHxoYe&dIK6m~N!hR$8-1#>N`_15U=iegiw}Q`||2Sd44SeqW z#|!%@@OiiHO0^679pH1nzGH&0-w8f<{u71$N#JwmKUvuC0-rno1BCr4;B)6cRoI^f zK6m~H3j5Q+=gxnIu%8CMtFQyf^4&~fe-`-MuP-}D*zX3PJOA0j{v7bR^FLVF?*X4X z|3ifRL&4|H|1e>HF8JK}A1>@40X}#BM+*DB;Ll;{`UPYj`02t`EZ@xs|6mrifE*?4 zF95&0@X##Z9SuHrKF5I1UH{v_=dS-)@Y5`*7m(wG{kMb9ozFXj{o}!(U5Jk5yLW=0 zW>E{syTIqJ{{-;4mv09Ap2DBT^4&sVe-ZdcvQ%9_P89YRgU_A+Ny7dT@VWCpS=jFb zpF97h!u~1XbLW4mu)hp^?)={^?4JfccmD4Y_WQx_EwnzC@0JVur-T1CmZ}TLdxiZK z;B)7{QrJHOeD3_;C+x2RpF96Eh5fU@=g$BA!v5LdbLam7VgG~RbLW4Ku%8A0*h1@L z`EIqazXtphSgI}{=L-94!ROBZJYjzw_}uw_NZ4NwK6m~f7WO{^K6n2ABS!zX9}&4<+}@o{fodqnWgFi@^NARV(>GChi3Wi6TizbNcq1wMEFUlR7O2A@0sFAMwEfX|)(SA_jR@cUW1 zW&znE>|YE1`w9=u^4(X3{p-Nz&i`w|{@20h&i@<2{#Nk0^Z%x>|1I#j^Z&N6e?9oz z`F}^)|1S94`QISy4}rgmrE3U+-pF9755%zxsK6m~<7WQuipF97b2>Z8zpJnNq1>~o~{_Ws@sPND%-~Fqw ze+T$kmZ}TL&xHM-gU_A+FNFO&!ROBZm%{$9z~|2Y*TVj9z~|2Y--P{t2cJ9tyM+B= z@Yfew2g`RO!v5XhU%*mz0r{=4za4z;{C5cZ_khox|L=tTo#1olf3L8AANbt)|6bU? zAAIio|3lb+0DSKJ{~+w|0)L>;`dGf(E$lxC{-;=~E+GFY>^}rPcm8{X{Xc@wo&SFc z`wxT9o&O`k{-40-&i~KC{-fY?=l|cr{{Mi_o&RIP{wVmLFSI_E?;Z#L5*D?9JOTb? zg{xS;ds5in3;v}nRTq$_z~|2AY4Ex0e+GQ+`kw`#dwl+{u>TzR-1+>Uu>U;xpDPSq zmhb)oKKJr{0etTIUj(0f`R)Th$C7#hc}duR8T=~?56$x3E5iP(;OAJXE+Bsu_WuSx zcmA&l`>%t~o&Vp3{eOVZo&Ouc{(kVe^M6y=e+zu>{KtfS74yIU|K>vLVEHa4?8m|X z3QN@mBq8i4h5b74xtDJ}_}uw72>XrTbLZ0}>^FnYoqvn4-zw~n1D|{Owt>%`|9D|P z1^!^6^|5@{F6?)J{|%O^3&;dvzf;(s2tN1nodiC2{*#6MF7UbYIY8K-0zP;CQ-%F$ z!v2Bab1&cN;B)6cL)cG)zqQc%SiYMn?9T%K29~M|$U(w>x3E7OeD38t2Yl}Q4;J=& zz~|2A5MlpN@VWCpOxT|*>>mz3_wqdgeD3^@6!v?;A1bsymha{X`}4v7K1OVu>Vf*xtH&|z~|2Y1Yth| zK6gF~h5bd~bLW4eu)kQ?KM8#9<+}uY?)*;{_WQu+&S$Bxe+u~A`JXE6FBA6P4L*B{NE$&_k+)!&vIe^bnv z5Pa@@wg~&zg3q1*SB3rSg#E99&%J!V4nBAO-w^hi2K6n1V6ZUt4&z;Y`!v1~WbLaniVgG(%|3ARzUcL{2&z=7tg#BIMbLX>L z*nbdw?)?8#*ndda-vd7P^8F+D-1+~Pu>Ual-1$5r?EeXT?)?8O>^~~(|2O#D%lCi4 z=g$8zVSf~S?tC5>_MZTsJO3wz{k_8eQ{Zzi->1Rn&i@%<|5@<4^Z8$4|2gov^Z!3# z|9N5mFW_@8-xt8=&i_SWe;@eV`Mf0TzYIQi{;vr8uL}Er1)qEQ{tbNY{9hCHUk9H% zpT7(H{{Wvm|2KsF{lfm6;BznEx4`Gle@xhKP<=m9tD3u8l~O7CZ)om&rz_P%->LiN zzZg@wIDOZwe=NGBl0`q1{?3*q>l}VeE&ho*t+~5_YSj62U*h1$m>(bkzD|epk_5jndUzhC4*cjNJKE#dgI^cz zZjo=*0DgVsdq%rqBlvopa$cIiZ{)3?KTV<^e*9v}1tsvZg9Qb-Wz^BShEy8}Qus=@NZxi;%3;QWyzg^hx5cbEb{ohb$HFxWI z75CghZ_3*OzGVws!vl{C`1(=dQiI|H=&MY?e{pia&qS@iHQ@IL{TTs2ay~Kj>NnJy=59T&wJcfs zZARn8mz2I?(Q%M{7YzD-F21dbSL_o`!ZyN&1L=Iee`c|yyMT_y;`dDae3m;p5I#5&v-X=|D_=O>u+zV z^>0Y3Nf^Cb9D=LJw^=#O>ab00si2cP@+c?0;|$Iod3 zaaQs8=N_L*We!m*n!ELJZN1_roau+ks9({s^`z+qditCi{%u0Nb%NS|SFWOibg@uB zm7~Wj_Q%FNzk;c5Jlxk$Yu4;1!u?#^>n-T-AJh3%P=7MS-=ui*sSEd6@~IE;GwQiq zo7!BQj~PF&>U_*^X;4ME%%c9kxOsusH-9uC%AG2>%|XJx$}Ck&n!9yh)_?YxxxDqM z`(jL;?u)8kE$YZ`f7ku^XBGVM_0 zb^2D(FY$n%TGpeIanIlM)i&k&w_UPn-R~Ncl|6%-2>4Xn_`2}=GnLh!4ER+4_`2}= z7gtt)Or4*m?N_&+*XqhDm^wvT2r;$R=X0Mw5K~!Uf0d}O)T7gi^N$p2MK>B1^;fCR z1AX(8;W;U_s-gl*-nbw9cy38b^_9F!MOXHLpUA9Z^)uin)fFjqY(*uOyzyD!*Nxti zQUfLLQqh&CgI_;%PfBGgB1+!)6!06ePqX@qz;8^~w{vbE9|b?QYfihmwB(;$(UlK@ zuLhU2tMe-&O5XT>^!wMb`rFY@Et#y&E?H7VSN;k7m>&NZS45P&@q^$iJ^t60yh}w_ z-iN*(|BU|K=LK z-uP_rn{@xVq~u*Hx^e~h&AR`ruZSpl<7MEt=>Eg#F9!eZy8kfFPqu;LK+;_!Bd?u=+XhC#icnIP*Uf{MO+sS;x9F3;wjBD<-I1MMTLPUj_bw*;`os zjo?pD-!p;p_`vnx&)D_!1kUk)9r)?N`cBUAe>M0s`{%Iwo4|iZY8`8Tz6AVPJC}5F z_U8fc58Ax0lXL#F9{ldUD_H$3__G^t>ExXMdmEe+~GD^vs#adHnDn;Hzh;|7W%RezcXA$IdJg^db6EW+(C=B&$$5Nf zKl%@^>r_`)6miKLzl#3WD>^xkuRf3ds#{q7z36w{)5&@K_I2=0|7SctybpZS{~3?( zJqy0+|BU`9_@@6e9^bnZ{6imJGLdtBaxwUaZCy8!bN+lj_;XiX!RoIC|M0F`CUVYC z?gamco%gWje;fEmZho3IpKajx_SH|~T)so#&ug4Bi8KFSfj|G*C6m-p$(CNxmA8X` z)V6h#IQQ><2>ycgSFrlu1OMorTPAVN4}SyxF%RD}No}hr;*vMM1N^sbeR>k-{@stj zKXz69WKRDk@Q>@7GnunL$J8BZ)!)(GNGa;`XAY}BE7h%5b@iWDGS(@v7``h7-y#9Fbb$_^&ZSB%M*DdX+wB zv(`&zz}L%n+oFM+Yn7e*PXyoDzVP{zz}Mqv#Q}FN;;CNIxxxPNQ&@k8t{VB8K3TlB zOIN^m)~|l1<$D15-ulbsPXXUqfBBa0RPYPi_n{w-?5REfX%=6vzx_WO{UOKtbzs1E zw(ng2^nh>H-%|#DR@=Dr?mYwj{Pun5zLAMZ?`Bp1o3{8S{~e?EapXTU;5*yjekOkw z_+EeBcY8L&QU5^!UoYQFmiFeVj@)<0Zt$J{%;(PrU-yUKOzUEspUeTj&>u#3jAUx> z4+mR(JwEr{oy~GA-=2W)^an2gkbrN-&+^_u-!Q29heOfN_lMD^M$C(;s;12y53~3t z{|B=6ckd&>_xg|SZzI3oSo5n~j|})``*Qlgj?vj8 z=Ea;|CDr}g3%)x)Wb@~NZ{~+H?>v3qMcLu%D)!%NKKOrocp zY#;ZGJ~z^G`Gz`wITio3AmF?66DI%YfN#dnSp$1UPa4U1uPU#&?ED>$K|kMrhMMpG z+NN(bBx-xb+1o6>$^WU*=DSb5JXY($tYZVdJ3nFaj|=!F|1|?ojh;7>t3Cg>TmAgv zsrj3CSp99(A8Muza6I^h{kzdGaBN@R8Sr)fulMfz9#8%60^i%ed*3qqV zPSJk}H8|>|5?8mqHZc#t37WiL3p6nSMc1I}3Ka0RmCN~cb_jAaOvBc)5`TQ98@pxZK z4VhNW@*oSruZwR>seOF@Nj86&&tGoyZ{zbn0)9`j@oU4wEYTa}Ebyl%cYbx)+XOH? zOb7U8{O1^8m-sOFhs1m6{N9+JO0Znc1b;^S*$Jwb&u<6cjQ=#BKM8!3e}*L*gG>b9 z)IZ8M{wF5<{h9p1tm4b(gHV4mx$~jn0ls{u1bpiMjQPJ^*#7|db@69ARf;eF0|Gwv zf5!21oUq>vKCNH7?qyuQP2lVCpMIQg{W=2t81wvRKKQ2puytpBeu%$6aQlaY&prP+ z27Hr$ny>$yBJ3{(-{iwMzd8+k?tI=2K6m}|z&G1R#`)nmVSg3)m&dXxbtm8WTo1mA zQEz*l&%eaxGuGc{^SAQV{|NZ$c;j{He!lJRBQbyfoEh)AF2gv#eI)MpXT|#-n#EZE znJ_=p`D7XWN5G#Q-`1%Z{WFvPd=84Qf9Tu+#^noscYO18Sw{cNx?ugQIsJOSugA|C z#{3@vU*|K*SpOpp{`&R!RLl96?-u9}sd(eH=?tR}{h=+sb4!MC|8xuVhw<@ech6$1 zza7?Joe!NE#Wn-o0{*!8wsytnx5N6|9`AYZ+$>}L;CICPuB9`J*z#$I{-En$&FRDX ztH;k8#{9Q{uk#sYtbYsi2R%O3LcaWOw)KbgjJ~Zu^fCIj{=iuOY*>Fye_-@)2H*4t zMt?S}zotKIX3QUa(;pc9*|z?`>BIVK`U7MBH-m5b17rO++xo+Y`IhfW=nvfczk7oI zV4Csx-X7>bRR3Ux@%Y0Y=s)D|n#EZEO6U)|{w$-vC+M>tUtJ0PLFaR>;v1iPft6}|LHlbsmv7J?9A&J35A+{BJ{9Bf=Mm@+X8$F{H-1K-KbZX&#^;wu zpg)-X7smP*!uo6GCyf3G_-1~>=r4rz*UV3P8J92kW`4rxFNFSJ_Fp)CSbxp@gfagS z@Xh>$vHlV04`%u=NMV{<*`}ABOp!U)y2p4~+Gn1naNq4~+f}@J)YU^iP8I z*YpR*?biD&q{mWtfHS-5X ze>eDM{=n!jhxOOYANDaWU+~TRfze+M{lV;CaQd+Rn)w4`{=309^9RQIcSC-_&(=+B+W%@6Jv;yb_YTIfF$liMELp5yaxvDLqm(YMvl`2MSBK>gh3-~KV^@7j^! z%jb`f57obGdz#O`8|pXXbAZu@`px+4=kxEe)t_PXZS|-5{QIDOy?i;x&wWro_xO20 zxc&!(>)&XrpKMq567yov|?!C}UHPKSKBU;pwT_$L2ezJMNtd`y31 zJNr=4M=kr$zcrOJ`bqHX)o_Y$cBNFO&1W1x-8P?b`7W^e8NTte*yi{1`73OGmd{^n z^9T6+i-rA7Hb2c*|8+K>aeUrn^D}()-(m9^$LDsNpXICnA)C)QKKI)E9AEt@@Re@P zoB8}X;K!234h}Q!f6WFz9$%GGecl`M)c$v@0iS#SZZ-IH{DJlO*gEh{{fzzLJn&8Z zjK|L}0-wA73&H2E|C8XG`ZKkUOHcR&_@;iw<6}AS&EsahN3Z?gL7UImKZk67uJ*b; z;WnE;=v`a;zZsjal=Bu_we$3H;yZnxkJH{br}fd)>#>2>^wP|d;s;13t9du^IQYLv zd|o9}TYLJ4hkmfIV^d?(@6>$9O*S?bKU~D`6X3Tu%;|Wv+ji$_s#hwBemcO8EwrTYK4EL{z`p-Dty^|ynDJ0I_k9pJ4H)vdo1OZuZV`;$uf*F9OYKNrX+yp4Xp>ej~3x4gF?b|3LIxdHw0&7uH{Q``fVLhg~0dCym+a z*54W6>;60~u`@N$e`E9ZJ;gJU>bAe>Fn{m|S3R`nkfP0Ob^gpSzyAl#5AErx*`F2W z5B~D1SND9lX8)itf7dUY|GMWRHT&J6{tue>>^Zb%e|DHZc;i*u_cYb)&jCL${#R~p zishF@QcR(RsK(BscwAsfFG>?+FK8;q5ea__v-II?}wm+i*{jn+j z)yj6K3VzoZ@Vi+3Ch$*C8(ICBS`6zKZ$9yW&znyo;7?`ECmHa&Di|H*Z(0}drm=e%?YI_pT*VtN$?li{1w&vb>MHX`D?59>%kwf`4?C3$JC~D@%#U;b%!L^KQT4v z^XY&t>m{a!eEv>WT_4Ey``elQn7YkZzweMX!(-8>X!!g^3}!L0N?qdn`~@{Ur&p~i zzC~@{_oJU%(yRJvGmG!thkj-qtDiw%UD2zKEv}%p@6SSi^p;*VP@7qN@6*vAx~ErV zi*Hfe_otwreVWx@gnqhy9-UOib~zjUU32ECOW1g|0{y`y^VE7ie;NAy>sbB8=%>~l z!`UCUqCdQDK4<=e=;yAO&zb*b^fR}x`Z@H~J@Yy9{}cMU|6I&BJ|9G1_aDYd%6;hT z{=?|sjlS+bEBNwx6n)))F6HwdLSOfv^ZESy(bxTl(cg}~?muVq)&DU1JLmLr`n%BI zyrfqxTf__oqQDM{NWPxcdldg2hiVq#ZjE&e?9tr zx3KzI^c(LvigWyb2K{HBK1${I`rAe5Z>wLxxqtT&^w-Z}_1B=^vt$A1{^LK;*ZFVa z%l~Ecb^eU=+vm{N`7`=Yps(|1oZs$8|KW8D)YW|Xzl#3WD;99hZ=Xkh)h(?4Ui7=} zS-?5JeI0$>{~71c`_R|@pK<>DEc&|tGy0?G>;BI;f4&rbJ^nZIjsJ_$*W;h@_|p04 z>+#R%uSH*vf5ziiccQ=ZY1aI2Lw|Gq(VY2gL%(kht3QN(u+K8zlVO$Jx6oS4}XLH!%rWrw(;e22l`vpOxxXtGfEn5bh`q+vwrn6E#Cvc_tsx7e+u}{`pdU`r-JW||9!X9 zr$Blk*6{DNfUonvWNB}%2DIp|2ZHa6e?EUY_&WdJOzUFn|1-cZ%&$gwjAUvb|7nY_ z`{%y9=~FC=a;)~-nE~IKUvc@f0=^kP%X^vjQ4c~tKffA%Y9v>C{@oVe=`|2B(rftt>foN^z;2^sQK=%ZTdz- zqOGR&+)KmAPp{D5!rUo-I3=y@Z#cum>pJ0E5BYi5gp zP5#$66L1K7_Wvz$zh58U zxoZ|<{p|_Auk)cJhin~a3-~SZ_3et$Z%_K`Z;UtYJ~zu)Kln}Yo-K6bjV+({x?ugQ zIsJOSugA|C#{9Q{uk#sYtba>`zkWSF)k41fXG4E5^PfIG|7P$_|5?xI+xib@{kHzY zSpRJ352pVx`Zt4b`VXT&8~TIkKbsksFZibaF#5A?{fEyL>lk@YVN1#8L`ALee zzl}hDF#AW0$0tXiKbZX^#`+h+`fKJVjQ$AtW`4rxFNF2i%ujk5moNBce!}Q4g#MuG zU(M;m`fKJVjQNj%Z{{bA^^ZV*(Bo6J^DW;Uw*J7_KX=&r1LN_x9k%|!SpP||{+j;4 z=p_*Y1V> zpywxP#(eID{-FKLFk}7DAN2fi7GwQOVg1$hbM9Z<8}wQCFP6gktMlR9zqmK(v+iFk zh5n%H=iI+o3hS@-IrlH_4f?G67xzMc(BqSH|6+r!KQOMp8*Keyh_63vu=NMV`eQ+V zFwN-)^GPYjd}6`=Ge~DPvOPbtA?UMyzFsWYe|DWa%2HFL1M25K|KyKBf7gx-Up{|?e5n3i+tYmh-B7<-z5|Rt z)NjUrKc9b(t^N$7Z>vAe=idkQ>*dQie(r<%xyR1~!u3BOT>pbmzZw6%e9QMisNal# zw%MUlyP=YK`Lj7b zxsP%Af^UvbGWyG5eruk;;PhdBYmQGc=D!P)AM!D!Gxq1Cu-|F(8T0A3`Hb7g1vWopmIBL{#Wug6 zg*M0vo1f+L*V_C6K0jmgSwEkh*4F-x?nWwEuU3W6PfQ==|0}Bd{KvTR``n*TodCa3 zKYf1dlH$Lhy84r)eEs?C`AcC!!hWN$-z4le3;Qj?ek=Gz>(^BS4C8-X zxZlj-w}t!nUC2;>Ox@&veKh;$x1!Je`K{=4e|{_a+@IfyKKJLhg3tc>t>CkNek=OC zpHCW7+hF{2f4(aEy!9sn^>cr|YM}o7jDh2uxF92! z^-k}fCh{LZn>K6Wfb%A2`xE<}_for##@F*lC^dZdp=#U5Ue&j0RLRk?nXwGLS8wnV z3;6Vw$4aHm|LGfo$MnVXJIS9*zaPGj{L=<9^bX05sx$lNbS$mvyV43Tahq>$=G->a ze?Zqyewylce0nb>=RU=ckw8BK^_%KL>rc13_4mfov3kq5^? zg}dL^p`X8vc@WB9nFSEYUoYPy2K0?e=2IW^lTM3seOj``%Qv+#<}6=b|7jOxlBWLj zBWcPfZpps^{S1u=Jy6}-?t}VQc;iR=^Dj=*Z5vgGJAU-t;L>REokvKUTbA>4DqirX z15Q6S1^r}k{d&dH0R{5c^&jzZcloaUb8q`B$|rbf4*Kqm(&pd&kbi#t(#!YO^2@gc z{jAHo`Iqz`aDA2ivtC~Hmg8!z=$mEhwg`GCr#t9;obHmZU-yTO3zd`qfYTqQr@i9x z|Bkcx{_*LoV2S-L=017fjGqhjSfl0Z`j+w87W9)UZL5F0-`Dxizc8Ik>G5NHYyTOK zzEP5^yz$=}r-Wz(S@UW8gp*H~JN_->GiC9$UgW#u(~{2-pK$W=d{dkMOFQ~z`RX^& zPn#PS`m>YIb@5c8{~vJ?&HwWKN7Y;E@38n<5BEC@{Re$>KmV5r=+o87UVWRi{!-LG zo%&P7{pW=X(<#&6x1S)Zdw}KNVj8w1BUA=H5B?&Pe%3SiT3M zue8s%e5a#N{cYONw4r?cv|x+3@A>hm`~SSJ9qq>jt&oTh}93Tf6$vh=zOmIxZ}Iy$L1dz^iz@6U+s6itou*Ce%tzcnAH!C zpTP3f^XE3x-zfj^{xCP_)BaIW{?6`We*MbN&vpH$>+QR)pZaH$egEk2pifIEg0Jg8 z{T1c&E%VPKfEXWz#6lK@t@fL2CV{K{ws>d&-|CtSGVW)FRb(D zUW-q24!WfE7qyRMy@q-F7kS_8AC=#~o`=4UMlZAc`s?|yf8^}n(ef=_|9p$D^|HRR zf9D<_@b>TY{rs1sEI!pwH%glu7WRL`>Nn%l-9Po)`X~CZU;ptp%17&EeXssB4dxR2 zr$^g-vkcPaQ9_UZcz#N4F8JmyzAwk1PuKd7Z}{gw`SGv)qT?Ism|lO=K3o6rHuQBq zo%))z{!+C6GQs@p^B9bBWa{GIr`u;)=g-Fm{G{iblnVQ&rThg;!~EmIeW(7g z{-*QE*B|b`-Qqh5rCneDqerPTKY@H^>Hd&RxxS^py#xJBJ|EY2j?j3%uRlbn|9Fe< zuirbq;na_QE>^n!ccQPy&wwsH?bh!MA+P?~u?ys5NofBe_0&x>FE@6 zleGC7#n0F8r_E0%1^k|h{hPeyn-0zpmjwLYiv4{37XRdcKeu8(Uwd*^7Vf@ey+FgdVZ2knCBPt9etN~ zTYTpRW|FA)AD5_wvDZ7bZm9PJbxO<|2?6;Gm7%Q`>5I<&ObkUvGMiuv##&ns_;*L!1u0m{QWUS z`xkh8vS|G11x5SUVfil)@x3lotABdX*M+BP6q!F{e{8?y_$t-!Jiko0qy3A{wNCwA z<}SW3@3r}Kud=?LKYWbVFFigz-zPgitg!i}cAolIT6{+?<43Ij4D{2wcx{*Q_5Qog z$ICyipWhD#^gfI4$Ps-nf9(f(wF>==DV*wZ{6_=Fw|(a)q+8wk2Xz0j)PJVUC%vri z=5P8NjUVIdyTRqG5Z_zBLhFy{zaRZH6|hYg;pJbZKj`gCp+5xr+u1f>^HF_&{|WdX z2=TpqD(pW2|AXk~x4#kdG4+RUzs?EqE2}@;&jx)uep{S>NdNTKU$cIN`>WAU``53~ z{_Oc)e+XH>*4X@t>v#LV{f@^+^B-@1Sm)V74uGs_0Il+%1<>NGu7lUm!^{m7a`I@V#9o&U?n(NFXG7o(r?`;X@Lze?AC z5!D|Uob;!B0)0Bo*Gb0Bhx(6`zw>wd@@ZQ$Q=k8~nDY5Zi{1Yu`Wf=G+H!oHf19;(rQ#+M~kyi~BSB$ zR9v4wcC|VGZR_cKXKteNWB1be71@@wvh}x(Hs72d80PEwVJ@p?#-Kk3@mcCI7zDqi8ox8#-va(o z%>K3DC;WcCKNs@R+ZVHZTem$p%RN4`U}-kw_{>+q=g#Lk@Dr(S=lo}PmTMnB`R&(1 zdi^amKEH-O4Nr6av+H~P*~=%teWCqp>i-An`E!!yS7GD->*y=LU!s1s^<(E9(Nh5 zqx0vB^Kp*9S?hnyZZNCVmi?e>Y{xt)%H(T1j0sX9D(q8?6so!~ilYVlZ-!%1Go}U^* zKY#vzVf?>hj_;Yr_1E9=gqfdr)AliJ|My0#uMaZW{Xv@l9X(!oLOmUT@~(_x=6T9slm}rEWSuJZ$`YKj8cKf4%Xrx_`AIIOZ)ou z5!%=Lr_>Z}{q0{YzVrHs;^k|pUmst+{fYD-`DG&yA|1Z%u$N%-~cbxJ0XukiL`c;2%J~Y45 z`IMSp{VLpd@&P|p?CbTH@+o!v|JUg2`C(Smh5l1K{(XLg`hSCdpYbjE&_mM2=Tm?1 z>JNK<>PIwxzP9x9J0n5gt3Rq=a{hcb`YDq?ElmIT%ulc? z%>TDRU)NuWUo!vg==X(OS=K{IJ6Q zT&n)xqu&>nk25}f^}GF9*B|!${{84@v>#l)f&C+I{z==fQvQDgeVYGAT)wpbqPM?m zOYFZq5bl>>zSo>PbFhQ_68kTIKwr;K%d@ReC>et&}UH?TP z`**w1&*=GK(ef=dzb%@-h0Q-7wE4Y7et!OAuiwi*tp5K*zfU{*3=Zd2#*fnZfeBSO ze=`64i`l=X*YDHv)%({23H$!_L+CGdboy!*u=b0eAI$rD{GWEA^ZMly{vPx*x_)|A z$gO|BuAd&k8$Ws9tDnYysrvtD@wHCA{-O%?x0;{B{A@@*|7G!M7MSI#|6%k=j+Bqy z|9XIyZ<%}^vHB6}kLdpi{fw@^Fg|zX$B!j{8b5Sn=lGA#-*W!mpDn)D=`qX#4)tMt zhArPmEk2b*kKn9dp}roUMfIEY%ToV;TYRlYt)FgKa{T`f`eYa9vo9=vv;SULf5Y;5 zEX2i1rsXsLg%#n+V=`^D$S=6$_>QU3b*yHdx8pR)MD{EO=MmT$!R zpSJjzzpsAJk68aR=x6j&OlG}&aQl)U|6cv{{s8&$Z^{2zi?7$;vc6ltd3{!i_3M8v zzOLUJ|AG3wd?MEWoW*zhj}9uZ{axYt5$pdyi%-vAI`p*u;`X2X`P=$;(0{JE zDF6I#SUxWX{bCIsuBKhvB)L+jV?>HHZ* zizaY+Da`LQ`RpHa=l^5+#5=m=`@gO~|NbH5C+z1hy&UFy`MdM~vVO?;7CgJs z$m*Ei)bZ>n6Uf)`Hel24Ed<%WDo%a{=eE<1Boxb-MTAlXZ zUx>z!_4(zofbYG(kn6u`hCa>zor|-4ht2CRir-%-?EGOB!}lNa-d`xXuiyV9%#Q_p z@BM|M`}+M)!u&Y;8OkTCvv7PmzgkC=&&L^`g?z4F-P(0i2|p3=DW3}cQu!nUKIK!P zUn-wE^i$sZFM0WU`*)NQT}qChthtHrOMSri-hU~&pU=nQHw1j|{g&86WUzd{*e^^U-C&B^B^#d}j5Hs;J*G ze%b>*jn4}GeEk-`BjD5ctkA#7TfQ0kv*9u!;M4fb>KjGRCtrU?-_L*P4EQuYv-&pC z{Y_r|e%kyLQ>_Q6(>uDG=qG0n1#dJqhQF!g=Q#SKaBut>t}gduOr;J`eI4C84PF10 zF?vf{=dHlX-8Itn@u1(P)a5ZnUpX!@b^es%&;QkXEBZbEoy&`3cU?w5zOnN~`njry ziA%mI|A(>tpT4!~d>X+wv6$ui_rHw2Mn8RAkI(A!Z?gEW zy?Mf2-`W4&zwG_g$M)Z4{0FM8zuDp!jUQ(z*RXusEIy6@8^$hsi|m8nxIsU{r>oCr zyxphuR{LXrzd?VkA^#Nk51#P9W3RpWryI`x%v)c6=Cv2cZqWIE`lhP$ZwFtOtMhkS zgwx-~-l%^0c7*umaSC6mu785Xclz56e|hG$3*Kup0y0dBNCgG(In*UQxsNJP`b% zd_HRWoAImfZ_~kd>!*Kic+vC+?bp!XW`y~dJwW}L`u{81uYUZeLw()u(6upJL6w0qWmF&p}_$ zxc)W<>K~_aIllZGp?>c1(`2hZ!&iTkaQ)4J`rB2GvHoVLpL_hYVExYKVbp(kdtcQ@ z)LWqbnK9n&SF5G|!A*tnV>SU*S5Ig9L;dsSDfL~(^>>`5{vpQt$3gwOdwJ_`v(!Jh zm@oe}sDB>w_!)1he~7XE@lZc^|D-s4^OI>0J1a2PR~qU*znKem9h#|$`gP!Q=hGnU z(^!(et-)F9$PLH3c zPU+~T_1HYWU-f~2kmW|7jt+jv4XgZhQrNEx_*EV#3HkdPg#AWgze(6{7WP{Le#nBV z^4IkF6QbjPT)^iYpKSrZ${<4SHa_6<*59BSef_hgKctW@X-IALF@W8wHY9e?v5Kdf@>hKM*F*i>gU_80eOiide!{)~9t-#|z-s(49`JeR z|A~NKW5ICuWWeXGzfRb%5BTs0*8F3yuYYpyf5nun9~br$!ajXAl4$;Q!hXH5Pw%EA z+&^XgxN!XmVLvJC*9rUe!hVyQdw^Qf(XF2ncV0i3HXV7GX(G`q?6(AbXM>V)-rmOf zp@y%m0Y9y^_;#jz#sz%0@WLr@HB_(YWsdgc%T@n)@H3{`#<=_P)|zV9cTRzyR%!j~ zIM?`W2Vdigo|NahbbudE8#$g~8b1@jci)_fEg$-{W@~>KU^+%TG2okghA*TihB+=V zH4W<5D^`r{44`<3&$RlgM2K(uERkyRN(OvA_}i{{{HcN`Ox`A zf%@s3dba%O{37u6IrV%#onI92x3wv@`qkT2vs&D-Am27)akja?8B6bw_38NY0cuf4 zx9*qv_{@E)a0J)(^Gwx0mGbG<`Dp*LO|QMk)thx?-RQsdTK>IU_4T!0W~2W%UcU$Y zvD5xG#+gqa`XA%1e<}LQc>P1rzn?dse)M1X8|(O47VvrVIa}DDYw$7f7s zr>Yel-THMYy8mR_8y7B2U7k|$bmKQBWNHf~H8n9A!{YSXmh{y$K_SiXyapJP!ANF03b`V-)D*H3?mFaO62 ze;Uhow62Q!G?qnunoRlp4VA1s5fY^1RH8n;F2(OhsHu{h&~Z*tpI*P_^SQ?-HC~^e ztK^T5a9eu)ny63P6`#L6LQR$2gr24l_33FMpTD7!;v(FZUcV;l)6+ygpF4kg{hH6; z!rXs4z~`=?Uhn9upL_Xs3H#$zk7)gE;BzluI{(&JKX?Be4?g$!q0e5KSUf+Z?E&j0 z27V21#bB)~1wMEE?ch(gR#E*g)8KR0KNEcJ{CmOYu794epAq&K3j6)S{&HbIE9|cp z_6LOh3&H1Je{4`J{;~sn=G}KSA?RnSEY*6qPVnhQi>x=S@|P2X zex^#wdbdg7bN8Rg;L|faDr>Ez+Fzz8$?pI9{c8JI*k6}YexE!4cJTT4e`V|Mh5EVk z$q4)X!hTlR9}xC)!v3JJKP2qmChQLj`@4kw29*(>-yZLq--h(@+>DSb%KbX7{C>#f zs%n3nn&!`kd4AglKKJ}^Joq$!$dt>plIv3ezv#_FDuF_7+YUbE!+QQ<2l$jvHl&oQ zemwzvs()rxQ0SfRpQcuIbnBPH>3zq98n2G&q;JynpPnp^snHp4y)<@Neg$jvR*~-e z_V4iJ%`d`IPsQQR+_y zeC5>N>*k|${xNk)zJBL{&DRL|*M<1~-JTzNOZ%7R{mPbaeVE_l_dj2y-w^ao{{4sg z{X#zZ`Xh~>#-Oi0smH%_IiLP9`KWyTt={;lkMa`ICX0WD_MPQ>yz%KX4L+0i^{?m> zYo4{t`L5*G=AhqA<8$jG=U$g8wRddBTNfT%s6RjclglEkUoAmjk5BT=DS;U(l=8Vy zsS~_1drUq#mFT=Q!uV_r^-a2^{Ap4Aap0dwWt#k*@jsV-d}{{fUl{+LZvD+YQTjt$ znD31Lyk8jqmHFetd}sXU{lfUq`-ev9KPm9v>*SNB^A_~w5@-2RB>C}~_dAwFSibGx zpGzp^AH`2a@jJkGm#^nvZ0e`wYpK6Eia!B-sy|j#KdoOh{_XzUDEW7SPx(jnkBH(= z1fTLL_Dki{7R8?geu6$&oBG4xB9*4lRfc|a`om@VN8L2?{U;tJ|H+}g@hJb={4Veh z%GYmv8vp3$w=Ywo)PDf@biSIKPg%b)ia!PX!=n4sqxe(7r{h1x^;`1K=QAmaKMi~u zKW6^ZpC3QepLJBu_@OOUVf@@5q5m8h^mYBJ-^8!n?IZQKbIdO)_NRmIjvvpb@uRoD z#eP1YDN*X50lqtaqWFzb{51IP_=)0AkK)e+-yJ`mZ^=KO&!i~+Ebt5cC#x4|hW;z= zKlEc^{49$wehv!tHLb^w>pSCzeyq&z2EWjMGGyuPFZ%g>BK4oy;1~K&SwB+$nFD^I z|CIG3^`C>mFZ3VdTk_B66RH37fbWhU8lPE37yTg4{NL$6^kZT9Mj4-ng!-EH#!tRK zRO}xLzB_)Xe&f62r`XTu6RH0k27aOcl=UO^pSj={`cGLuQvW#|{6haRzB_)b`9$hJ zM}SY`r`x)HnW5ZEe*8o_K5!)Xw0w*G!uBQa=a=uaDD$^o@M-x*^;@I(^T4O`t-Fs| zkl+5A`p5JuI)n8`^5=t3<0oqU=_vId1wM_RV!yEc3fA8h#a{qEEnoHX!u*8tagNWp z`BXeVIojeEjZcf8A3u@$!!h8~_;KfNX1JH~BlU;3fltdfsvoI891A`z-(sJZFXo@m zCsKbn4tyH_%0K>N^g+fn{!cJ@(elmvk@9&v_|$)j>pwqOf4=`jI{x{Npzj=iGv(^- zmoFdsZQhU6-;M{L#(%Mou;p~^Dgjd{70=nl79mDH2$Od zk@{N(d>a47zGeC5^N-Zu7J{$G=OokL^mp$3YBWFo_3!8h_Yz@#zR2P`{ms0GSB4~K z{^qP-^y4P-)A5Ze(X~HSB z9IyYvGMA;Heo;O?e}U&uiQ=DP_i6rLG(Ja*$4_PTpBm~H=Tp7EEYvR=pT7Dl%jeyp zesTWA^;hPf7UHLz_Ylm`@PPi4Gb1L~*f=T5@_moR*ZnP}CTS-_?GpTp9bYAqQP$sn zi?920xIbWg`Vx;)|8k4()Nh)vrT)s+-_tF=Q-7GRy!A^BN9h0WwfJY4?U#vxB5?Ef zQc<18&#C6-D8~m@fUoC=MZRVJllMEK_$$Gu`IYheoO(<7sVM##;8R!D&o2}m-^2M~ zzWzwhFT5}4yYmP02W050Gya{wM}N&P-@>oLzguPTk1^xl+$Td{$$!av&!LLm`>-e1w`yJ_U}2j5ICO6B5RNAFK) z_nij_^CRa^?@ws+X)QC`$Gq>3PhD2LyD_IXoRKc{{)9n4TW2Pp1Q=hB|HQDHn4?C{ zhhG1FpgOCgThB(E{*X0LOu6sSJnHV4=I8(B0dnzV-Sk|9w<)I2p9=A5ozj<3zhQcA zigS}vU+MFwLVW$#&?VHbo35rhH!1a%K7T62cVCHA%AZzBcCMq(p9=BmohS6AgrAF0 zKYjjGh_AQwrG0gvbCXhE>GP*TeEp7Ibg|b@SF}u5`n-iQmxfSZZ_(&dqu&_nyPH6} zpGhXEes|Sy3bB7}3iatsN`0~WbOrfoeS^}M=1|{#rAm!{OQ`Su@isr#y&;*5O^ zXltnN4i1}7ulFiJ>*MCZ;nKbIa!M6AC(=$ma<`Rz;nbQPihcZB-owl9s5 z{0X6cx$O(pAE7^YhWh2UFZI)N5wX+NTMDq^_^~-Hv$d9mnnG))k+rE&WF5e%fhWh2UFVXyIp?eIY->_GM6_}TwSa=SAO`=6u`fIbo^w|@d2N24jMabyqR_a%U-&z zetiVLHIhHu>Z^H4r!v}q^wsa=lNrtA-c9+qo6u5!#2l-i4D+3QGNVfM#hY{9(kSr& z2U~qLvt<3lk7sh9h&4xfrB#pBPlowU{lkwdH9*VP-9(fqUmarg>m&HId?WaWTK&c_ z-(9{>M$YFjtKS;tyUX{<$ob5*`fU;XX!#s&^XUVw=zU-H#XkNwI^#dzEu7n0zaC-p zhm%b{e+KlQyU9PC#%F}%|3_N<(e3qNzLWpmqjXq@)~^VDug$+Fir*T^pJ(wYNPqp< zpDV~`KKet{bca*NdHI{;+rIpBUsN+_{8RopcM54;u1o7D{m zEi~H~^Au3{venltw)%zqt$qdDuaj&(^#^bK1bvmOWc#?p<_~w2$VYus&2+cF5$3li zTm8cLf%^6M*{ti2x_#`k`PBbI@*&^JC#t{H<_}K_%SZbrA2WZ8uzf$p=8twQrTX=s z;LLAlxEALV0YmxcIV|Agi1)L()BZmU0K zX-Qx0HTgvO7}nFkH~oh`z}4p$=C|oWwuxqEQ&jkk?YsAYZ~Bi?U-XU7g74&0!Th-& ze7F8@hWHiNzZ`tG{w*QCQ-1~fU#Ej_>Q5(Pl)pZDXU1pI_P6M?kYt;4ilr^}!tdT2 z?su2=>)LYeB($Qj}Op(Xr`_Hz;Z z_l5g&OZYice}p&dTNUmfQNkZK^+)i}4EOa|3>}{vb^h*COmw@@%UR+6e7aMZpV59U zg8%+-e?bX9XXnc`Jr$9&FxYPv!~|bw0=c+Gtv)P z{rVC{&3KD z4Sl|$-ybr^2TJ)j#KhWnJ`hBNZ6fW9d6*Zrv-T!5X@8uuauR}j;^7mS=n@`Tad_NjJpL+D2d}2`l40rtK zYrA?rAKh=T``-SkKK*%y$-j7felWV26UIE`3Z1nwEE`{?ZLu^H2IiG)+X z6I(Vnkkv^=xHO0P&VBQK;r&(Uifpbg8^P8$X$knw9gFIx{!o4Wtzo|NFuH!@S6lx$ z^vN~(J3jSi{pw#D|1-=l++nNwoU6-!ZL|4>?W*x-s4Knot73n=&8KctM@P=+;`&to z38vPH{glPmQk~Nwv`@)Y@3-6htkzAb#vh$gz29N;so_u0Or6FKYb<*nG48 zmhdmx*OxA;vDCLyEWU1Vb!w5mTWJ2hrO=}5rds^0ssBXJ59UK>w-ga2zny0D_4d*C z`lew1QR_d@;!{D?AM*9n{2`aFB$4t9V%hx>lVSHK~xc$ob9<9U=vqF7y zaH?kipitjL?B#>?M;`y(p}u)>QO*ABP~Yr4*X+-+`?UX6y#1p2&k1HBdfS)C`5YYT znkn~-3NT^?2fA#*MA^sPb>OU;h=c#{gi0>ai)%S

    nGJH`E6sDDd%K-ukT0p;~{>x zQxp0{ujq)I2~3I7%~c7ze_V0>ZH4+*xL)M?lOcXc{YCTUX!X~D?;a97WV^E@y?n;T zJIhz+pB`G6q56|?cMec8qWTbjak$^>`m>_=4Pm}hl~+HFAEOnGpJb%**=YB3+mq%2 zTwm>X^U;4*Mfo&^`M!Lr_nSj}fBrtdqWoLJd|&>y{tzwyR`9)3R=(i)oo;^^n|Xto zfEG<_>lZ~CKjXlsT?>7QZF2tg#?M&H=|4rjbAxhU+rT&dZHVUoEjfKx$5(n6#?-H$ z)6P`}dgmhd%Q{t4!GtKUrdn9}n3 zSDQ}<_)b3LJLd+J@T2830emN))(G`S%cm23Z;{nG<0n7DH>E$~sihnTpmpkWVc>AYbKE?Z|nW2TVMpS+C z##n^&A9}!dYw~;=K&Jl``))qb_J0ov_|Eve$({ee_|$)$>7Vgf{CiRQ=b_+x zJ{KeIOV&na^VI z^>U6g=CcfZ>TmSkj~q+ZF&2TZ$7m~~e+u~YlD8bEzXW`J()KvU`cDI&j{oF1{rkXQ zPJSC>{r7->I^{E-(SHE^_fq|w{@vjBQ~jLzjDo+I{3K&O&w_sv<-_Uk1%Cg~W!0)5_>ly2R82qJFKd1i?_@_|)4UF|a3jV27Kc~MQeEqtGM#lQrf=~0? z9H*ZJUzgs*SpWIp)BHKd>8}D`ANFr%tbYagG=I)<`u*VR`F{&z{bz$u^Ya|1zZra* zpQ{vO{hPq2`FW1hzZ!f!KW}HOKL>t>>gV+P)cL;sNB-jveqYbeIWNnge*WVR{`wgg zt%+eh)bGA-jV+?J;PW5f@aMySe8cZ^AKzF7`8ZGevc<1ffX{#Y#GeoM@smYRzurIP zyqp4lgtug==;4=u@4TqEBBJDtPXphapHT81m0h_M{F#;Az3i<|0)JN7dsKFVcY}XW zWp^)o>xJN_%ig218>|MuyRy5Nz4eE|pI!DImEGVx@aI%^_p-PCDEJ4Ly+>s?SPp(q zWp^)o>odVWr0hK^yTMBE53TI(WpDif@DD3{kIHUvBKW<|7u}BC+zpd{QW_X|M86DXEFGC{HGZG zW#H5J&vE)0@M-+3cE~eSDyv zvHn%y)A4~Er@sPxeSDySvHr8c*T-);{axVqQT>gK^*;>$QmUWRe+c|jsQxC#`X2@V zRH~oT9|eCg)!)om|FhtqMD=s}d%<5q^|vtA|2+67Q~jL&BJlO`vH!2_Uf`>!?mU2> zxv$(jNkRevQ7#x1-vQC8we1Z80=@zTMXMGNtXgXUwbjd)Yj+bA62<9`->d;bR0 z-wwXLe}g$boDbtGn}6o`Y7Y1||Ero%k_~0)9(g9C-ILX#=jH%WfDKr-vRz|iGMsX{%63yOyXzy z1K=-}_zxk*pN0Nq=YNhS`YG`3{Le8&zX5zZ|HJeR_<4!{SYrJ1z_;z6xqoMaZ`=O_ zV*KZTZ`(i9?*@OV#D6F;{$Z{{ryk z`fP#eUkJXvKAR)PzZiVEK3ib=mw<1t&rTx7zZd)~C4Q#=WAHyH@lPhk|1$V1Bz~s< zYw%Y}{D%|ce+B%@C4Q#=@8Ewx;_oEJe-`+1{k_2S&jjCIf1g5(|2**J`g?)tp8>wT z|KSK?{NDwCwZzZ#p9Fu6#D63){_lf-t;Emt9|M1t#6Oi7|5-3TvH55EXM%6@e-ttP z^T4J^lt?}kocz&{jY*wBk?o+9QY~mnb()6 zD*K(v{;|q_Gx+T5*B#1!o3cMa**7!gQv_$W&X9gvTy7|RWqnDTMPn+T?_q2QBQ7cM zn~AoiYQXOy$Dag0PxfbnUm*J%!0#vfJHVF*=Tnz-5N)4%vOgRA0@>dHem~jY0Y3BI zQoAG53CKTj>|p&3;1|e#IvI_hUEh-6v+F|*`1JY)`KQMZK0AInE>4Xczigu-E;1gE z`gQL<{r*Pm$o{Q491`SmC2v+GYC z=AYbv>XrQl@cH#2ntyhE7z^=}(=W%z=1BkLx6i20Zl4*5pL}{J=hxBr?e$IOQVaeG zOkAu0d@^qm=+o`S+ywF4>vzm0VRDiFWe0T3B?&$|KLPklRx+cPd*#7r*XI_K zkK|v@H>gW1`0V_Q2A^Hu+QBc+v$B#j27G&chq<(wi&gh;2l(v#j02yYpTJBVXXdna z+IDZ}p0B!QsxgJ3KmL!Lm@$?F_;clSL*8MQ=#Udj#*#!|y0a<#>aE+odAEfov|^Wzk}6}<$3wh_!C?|g?CPl{)^oFH=#e4oBvVhzsSvhGx!B*pUkBNeQBRezt!=Xy1Z8$eQE#9HMD_m zq;MV$ z3qwh!p9J5YAN3RCPoXdEhv}!$m-fT-GvM3vBWC_<(3kef^t0d>kP3Vj(LGW}-o?fEIQf3=`5`DgmA z=u7^Y{%G_i|4hFPd^5oNU>JQWJ0RK|*@qHZn>Y|nf^P_m;5v9!zqqGG{o$`rz-oW zp)dJoj(^?>zRZtN``78{@8QiUuJ&JL|^(Z)1QmJ^k1ew4}6(lqW0hU z=#$59XQ59XznzUfdHi+`_;UVEZJ+0&FZpM-pYzZskKcOGCy(D2pidsZEks}P&m6zK z7k$Y;(_e%>dHl8*d^>-*lQ@5JKKe3$^zyCK0zI}Hhb4h_u zdRyplh-vW04F87nO$PkKIP9=e1O5@izu|n71^;*sJFL`#fAa8eIN#KP|85RDtki>_ zBzLd|@YfEnne$CxIwSXg7T?6rp^Hia{jEe?s3iF7N7;8M@|G0%R%Wgs9pkg!yKH04 z#Q3B~4_IEFUleUW?BiD!e7jEOI%;El=Ka-mF+TGcSs&xuXT-CX2JqK&-yUQd!Dsd@ zn}a6sO>>t#bAq>wit$O0J}Cy-jQ&1u{DF}NhRkg3w0+7x5}=#(T!3@! z&4SN*E<-uGTJTf(@^3g_>%dRz;Ea;|AzCm75v8MIBr=P4Sv(U@^3g_lcsB`Ik&ab9&_!k z{Z7jy4qQ^w;O{Y$R~P1fGP&!wJ&#Umc-N>W-Z{r>IFtqddNXrk;kiRvSjXYoSighj zH-dlMt=;tzn(|CzHJ>cQV*5+@e=gB(YPFWeESSMrHw+$e!{C`W4!(AyJYfW0b1*+Pf&WbQ zvFv-~5rV9x9(-y4&t$jDyW&|Zs5Rp&KVNAA%Pl)~QQzxeST-xZCd}zm&HUC*d(Lj_ zb8*RamcR4<8pQghZ@HbM$@_0j68z%mBv*0?&(KVPALfVWr@?>V!7U3}V-p)|2K+Go z;{PfCt5No|;6E@+!p`w#uo}Q;=cf_;ue>5xcyh9nKS@cy%>TsoU)~H{J@^mXew+J8 zS`!V-DUtefRXW?v$xNsOW`*kfPd)hT`G*AfGjq)B7@41p=7&AM(F8tweq$8)wSC0hyRlXLV?FpYF3es( zgLd??^BX;p`Hg2xBAnll2an2`(KF3!n>Q7zh`aof4EQqt@C@(d#a`=m;t$VHN%7Z! z&z?WYg8%rIW!Wvu%GvY(S_{4;zmYiwkp^F$7wI2#g-{Rvk4>t$XA{qKbO+giXI8#c z@yFGC+Za7RmCuvoE=^HiKJbLQjEefx-$;4YdkiixOCsaj;_q|i^WUBL=Lh|B2K+BR z`iL=0&kP;H`ELSzcKkKqOZ-1gEiIkj5#rCHZ#N*v>tnU(+x+KBPj4s0p9a5_|KbMUc3&3Z6GE2Av19L^>{Nlkh>yvRpzs6i086WO2De5JX zEch}$30Fb73Kp1~BJKaj=FhaYAMW3%e+k*IG1o=nFYXoM{B}0hfABt5k^=BqZrD2Q z`O8Dm{*^EPhVwN6exkr}%SsabWPkZLoUbYHiKV|7UcFqt!1e3FuiwG-8^CYK@UD&66g7h1nCJRU;5QYx{wVM_^>h7Z z@S6kf_@@Q@zHYAH3Vu_8>j&n+$oNO*90Jo_>U@MR3CHgZ%p?L_B9e~ZeJ68@Cgu1x zKO0Pnw3ZC`!uit=vMf~>;-E0aolk&uvpM1s6s=WK9p@Z&pjU)SQ zeYX9td(Er;H;wF9WWKLYHmj;-)X4tT`|~q2@aG{(P!&t_$o_TTyxEw-C;#YC9gJxi z*}v&g*}uL^>&Siu-Pd1j{_D)v$o$yy6!!$a0sM6-vo_ISdM5>iiukMlHgJ8LiUP|| zfNvv}_`AoE;!no-vWh&*mjOiN{^aJ|klh5{l8E{|xFjW&{gkdBn7+vT>a%HXh7#a^ zpX>+b@ksnZo*jSG=g$vE{dN7^_*0OdR8ZYo zR{mJk_X+U7W>ViUiElKo{SE<_h?3y*W@f_8O}V}yOq&enGL1eHm$hWkub8=RkkHr&x=Ff5#T+NXu0e63KonI%x z|Lne@i6+-&{g2*TJU{(|*ZFA*{6OBnv+w3>?d)MHBk}v5p{CLAjNb#*{%Z~R75TaO ze(&gQeTcT7O8+k3-?c%530g?=4+-#t4(|L<5`2ljcwAw{pNjYUbEN#F!I$|f8-IQp${VYEV{>o-<`!VV0{7iGse@t$3JiKJ0{_wxEzNu06v&w$E__JDv z-!f%O+RzXyIrjSI`pEM+(>%H;CBUC9gUwfohnQrHZ%mH16@j@mlArMTt~@^hK0E(O z@SBRKy}bBS;3tyBH>lI{p9a54j`-aDyD74N+4)bHsLyZzuFuR*3gT}q*!s_FKY^JL znct?I^j5UK1o-5mm(2e}!;r9=<;4k#!oLAR@f06SSe*aJp{%L-k^XdlhPj~*p?;je$C%ok@5>ONP z{I}0W>(BVe+WmiMhWM#BM@e`s;OG5AjtH&bPmlc8|A*1wliyxx+Q47qA96%!2miXr zZ~cE51OD0mWJDMX{-Vfl{eNgSKZ?9Rv4wnkJzm-GQ1%Z2ztt=(_-B2;FizQT0iV5p zv*0fyx1Uz<+4&!>?6)cV?aKZbWq+))zr?&Asc$QKU+y()duXQtJ>Xv^K2JAhuHy&9 z=w+fA{N=q1Xt}Xf?jrD4_6`i}BkqBP;IAn9yge{K#%H#lnc!b0@$;fL=3?+A{{gcH zECOHhFFtPz&W`b!Jzy62lK+6&16~3@tUp~}*gpdB`|dgLZT;ct#ysWt!CI!@5B~Dr zX|&wf%-#q7O39B|n@_OzaUb}0|MGNWZgu>C7`@zK0{&&a-L%};{9g$E%HG~yX8m6P z{)(c{t3UH%d}jUc2LCdNpBKF`p8@~!QvO+ObTjzj{$=UL+!o_A`)@D!w*By;x9{(Y zjz7ctlcSB{R)KHp4^KDd3daxDGX16CU)DQ`mK$4tz6Ji}#rmJ4)zF8)xBHi;8}nty zxB2I_(5>LFko@y>WBwBS%ZuZ4UJt$-{P6sOw*|My_`K+iyth4CAME)HFM4C{2Ve3Z zFh@XJzz@$acw4Y3#%GRz)`M@)Uzj7HkAYuq|EwCi2K=!7vvgywit!Ec2(TP{+x~gc z8*>x*<@V27$93R`?VqI^b9Ic*JOZx(-?o3|5%}BSf1p(VS;w%igCF)UmTt`7#Q3)T zvnt#dz_%u({b#M?5%9zQ#nO%WYK+eu0X+!5?Z3)9r%)#IgbBOl6enMEBM#eiJy{pkC2vy;IFCcTSuac%<wV>(XvyWd*%KpiY|4@QCewYS6yM8t*`zi33QLDc(>%m{Xu0UNwo8$LT{Vm{M zCjE=K1)VW|p11`Mf^X|Xp11`wV*M`K7CZv}%3}Oov@Mu5f}bO8!QZ-KNtMOlg#WGvl;yLiF@iECZ2(94x;lj)@RN@Y)(Y|4dOr0 z%3DKAGV0UwV@WTQFsW`oqf56t_MUk6$c*o9h?r56vH;{;>STP#@MNcF^X2Yz-O&f1QjUnDd{5 zP=Bo7Puzk*s6V!TKG4cr!(ylp^!&Jff|>utP#?nl@YXOG=M%SJG1MP+{EMMJu-ng| z>r4G1<{#>h#4kRt{SU;{hX;sP*al+i1M>>=Kx}>Bt)biPzjf67xPF4^cgOYLR^A#0 z;(X#3bjQ{QUi{r||CQqlul)?TzVu&S`~$J|ffxUdnED`R*X7e2@2@*z>Vur!dAns` zM{IrItzov?f9=_CdG+33ceuWteeib6!0fpGE9Wn)HSCD~F zK+mr`T)%k!Ld$<_ec-kKoiX(xNU@?fW@k)&FibzTKJeBs&+Wf;)cm-9g6YqT>%XnM zHSCP@iCZu)wm$IUpXc^psSmvNv(xpZKJen-8CxHC@$ZVM51WbC*LKC!2j(4`yJG7D zZw(9F{#!@QkLxFx{(`vv+sa$Rt~j5#1q)*9126ssZvU0~z-vFdTwm$~FaBMz^??_E zFVqLQ|Ei8RdN8IJ>Vx$?his9T2d+=OKdl$)kDZ^C;|pyG;(X#31WZkR2SNDxM0^+y#=d-Te*}eEB@WcG@*6^j+{P6tqA^tVQYYR3% zFMxlo>|fs15%D2E*5_RvF=l&A{Jhy)@nhoW&E6XGL`?j=*)e181wU;6ygmFxOn!K? zSH?UI@!R&pJG&M?CVt-8wK2~s$N#Ky{JUe~=bgP6vpXh!-r0+N{zmlvG$`WXBJP2O;O{B=yge{K#%H#lnczP!@$;g$&*zM` zAIX23*#j1VFZmarw*_a%_{<(K3w+6cn%M(>1b#XH&u!yWpgrJ+`Df|Id@sh|yn*LG z4!+I*E>do6hJOHlx&E-WU^n<-{bA{L{2A@P*6$?cL{_vtV<|XjM<1cRw&w+1` zzdYSOpEjC*d;Dek{owCj&usnn`Lxma2aDsMep-#|1K;jno^GE{8;yUDj|`1=s8#;pS19)EedeLi!v z{n+C#(_aey^Xng`<;EU=KL&oe{;;-T4ftXGVd?hysL}jezmK>FmV0C@b|ZW&N^NPzuf*gx-q|t@ooEO`9B9gZ2v6Xm^Z*LAAebEcoqEc_{-9b z`IX}{vv15k@a^%J7rp&_glPSIp*a8W5bYe}A@J?~<>~hG5u))A7RNul@$FXd_elPE zx-mC`Uq1h39U)hPAD;iRbYrfJ@tNbFW#HTMUtaXa{1f;umgXN=ZS-OA!~M(BjrmH9 zZ}ZP;qYr>@+Ye7S=G)-ESek!et>f$9hvO@jZl4bytv}Xh=Kl-e+wmJOdi#9%X#A4@ z;`{?^9glz?j;~m{eLj3Ne(T#KFsuDP2)-S^F^>Q}=Jd$@50f_9vtr(o0Dqv#wfl~< zp95Om5`e!elXjqo&Z+)+Of$jX-c+~+pKovDmj{_wwajt+z8a*g-(Qt(%tFWSxdkbo z{GaUjOJn2D<4WJ=&sTx}nB@Npw?ywA_KE)@$M36ofaqTd{_~j)PW-lg=5eRL&HP;G z`1d&R`}nQkKh`Aqf#*Z|{=Q9#N_&)J>gTGtykNwxDKFoIfdz|*~6aNCoU+nZ> zpZHI5{FSlszs=_8{Mi`r!}b$x>^|+M9sIEUM17z9Ukd)?#rFSjBu75+j|bo8XBRv@ z!NSxZL&^38tETu z!QYc9`jO8U*y?e7*$V!Qjront&lflz{OwKL@yT>$ze(9Y4*cC2ZvCI8>^Ca=^TFTV zv?@}YZNKrUpYy=qow?reeU889g3pdW1^zVh`Q3W(r*G`1uA$BG^HhHe_$NwzD-fSA z(HZ0S5Vzn#@NIqWA?|}2vHnup7CZv}NyYe=(zamM2>vS47Ca9A$))&Lk+xvbh<<^x z1$)4M$8h`w$`-6RfZs>hf}ewbN=5vAge|xZ{L1_=;$H&(NT2Ue7-<0b7XN;Qt~qxzc3YzKg>^b4LqJ<6X)~V&tBKhyaqkYCqH{@ocP7(#lJbe zK15~^ed6C7Umtk>NcEv&4LR zk?KQ5hP-^Y|AxmGlE2yY!}`GTN2(7be=gLAkv<=)+VRO0@a_EJ!)HdXH~Q?~ZQzH; z_vjkD{Mhce~Mdwq`p<^e)Vme>q~Xu`BUQRkJPuyHTdLbTbvJD;Nwpj zp}w)=pW@b^Vtr%z+g!g`-)Q~_^^N5(hWfyspBx1Lc{zVs4Ktv&{ZzXQLjAEm&ft3a zP=9Rwd~Hm04L<&2s1Nk~xPFG2|HV)r!u&+n;FF)hI3Kpa$6pNfhaLZ7s1NM+GwAwK ze~9^q`Xlj+&ujk!G4-Jr?y&ILzXLJ#0q?-_@?+~mbPYa!x7&Z4sQGdI4Abw9>%U{7 zYw*d>K%5U-;Ny44)(2kv-ERMt;|s6-47k4ZUtatJvGsu$|BjgYusLS@Q0@H>J7VfX zAJdPm579N)_E~NGv)%qH=P%KlL45ojt}mm1oz$M7@hn1^WysNnCKq%$AGW~9pBGync=6A3`!DtUbf@c6&o6ey)(2ku z-xX6I7Qh|QKKpl9OntyR5WW1^`Vd`%kH5g}zfIKqxPFG|FNo{EW1?&D$)goUi;bQ`cfZw@$ZVQ54`w$p+4-E`Mt`qk3H`C?B8Cf57x(HxsM;X zeuf%9)E_%P`P!K17I?)U=ff6w`A~o8``7g$dcXD)K>Z2xAKk+~`RR@GVGDfx0O}h% z{s8I^yM6Y?#ZSynuN%MAPvZWC`YHJlpV)und}4ln0QLFtrhWGAjaw?;!Rd2<{tuvj zT0eSsk>CCQcgM$Had(2JA0I!>KLX;n@1Lr?_Gnv@PyW9Iezx_9X8UAA5B8}K?Qni!?;o&tuU75@J3g=W`cX5)A3ZYSo;diQ^WZN# z6Q7=N@Mh&JmV^J8y#Kcg-WTMP|25!0Ui72yQS|Ybf&aX`KNsWoIsaM>{+^;Ajo-(= z9Q-gp`N$sd$$gKy)nHWzWP%Ybj=kNdl-|EEOplQT@N32tGSM$1D3MDElWX`|nWpPXWLBmJ~J&>ri|$tN7PopQ;}y`w3+~sqCke{j{>5QTA(;{j9QItL)b)`}N9xgR^CX$>~|>pjSzJCyxXl>Jkc{nM2FcPjg*EBo(K_TR1Szem~6EBoEb{!C^6 z3}t_ovOindpQG%bsqD{H_U9@4^OgOxl>M`n{d1K4bCvz`l>HuMe}S^UP}zU4vcE{# zU##q(uk2r->@QLFFI4s~Qug1c>|dHAX`&TRbA5!+OQT9Kq?5|SxS1bE#l>KX!{p*zd>y`bFDEl8( z_HR)3Z&da_rtE)Q*}qBI|Aeyt7s~$4%6>uF?^X8KD*Nk{{q@TJ24#PvvVV)Rf2*>8 zo3ekqvVVuNze(A@Q`x^u+5e=n->2+vR`%~!_CKZUZ&CK|QTFdu_CKxc->2+aQ}#cv>~B@}A5iwcpzME9*?&;k-=^$;N!kBvW&g{{{#TU!zft!8 zR@wimvi~(@|L>IjzgPAjQuZHK_P?&||AVssh_e3;W&fMX{y!@F-%|GfN!kClvj5M@ z{-etNca;5qQTG2;+3#2O2bBHo%Kl@@{^QF24rTudW&cTK|0!jEr?UUFvj1IW|9i^* zGs^z6%KrD2{pXbZUCRD$W&e3)e~+?1sO-O>?7yh&zohK%RrY_N?Eg^N|BMJ5`}>srmzDjWD*HcE_J6MIzoP8_LfQYNvi~b(|JTa?ZV%KnhD zADHO#|37B3ReXrR$S+BOzs59-{Kr-NCgb|4p!`8URe1Q48pof2f8zCX+VLA+AO4^s zFFAa1*71qSkyX^WJ~jWfu20QRz2oNyS>I12z+X%5UrF#k#%w&Y8F}-D>gR)WEBiB* z{WFyPS<3!wWq*#cf2OiOSJ|JZ?9W&B&rG(D{z7H{y~_R~ zWq+}@?0-nvzed^ru(H2O*fuTl1|Rraq__ODm=Kceh^ zRN22l*}qZQ|CqA>ab^D|W&ab({$D8jH!J%E@b3z^*9ZF@pL>1E1kvjkcLg2$FU}CY z%R7FKpzbFMjz4w(FA3lEJAM~ItsoMZ|5GY{>HlpW{I3Ud{m}}c0RA_FRTaM_d>b?$ zWoET@CWNvrKOm5mM4;>^l>MZ#FBhv-^Pg7sGs=FAvY%Do3UXl1`m*>6|&$0++_mHiH7f1I*EUfDlH*`J{7AFAvhrtD8t_H)Yq zBxQfHvVXX;->K|RQTC5e_K#Hdrz-nLDf>q&`^PBz$13~BDf`DO`zI*-UCRD6Wq-P| zf11gvVV@Uf3C8Bp0eMg>@QIE7b^SjRrVJt`-_$R z^OgMzl>H^j{)Ni^MausBl>Lj9{Y#YnOO^fiEBi~8{bkDja%KNAWq*aTzf#%1T-pDC zvVVoLf2Fd2m9qaqW&dhr|3k|DHOl^nmHk!9{%U1^jk15OvVWbjf4#E*5oQ0Q%Ki_4UK?^O1mR`$QE?0-+$e@5AV zR@wi)vj3d2zf0NQt?WOq?C(+b2bKL7l>HZ#{g;&ey~_R%l>Hwn`#)0lf2{2Po3j5C zWq+Tt|FW|GQ)T~W%Kp!l{a2LzUnu*(RQ7+R?EhNX|BbT$TV?-u%KpDA`~RWr|EIG5 zs&pIrDf|De?Eg{Oe?!^-A7%f4mHj^{`)?}y|EKK#S=k>__5%}r z{`{rn&(}zRe>vGtf`4hi{rrwJ_zQ!!%8xhj{ywAZ*Es$J@0crrl;by4{@VNdTF2*p zeoCFPU+?%i@0?TuS;yzL{}%A)ko#AwvOn7Kx$URf@wuN*G|ln3@lRLwPjq~4`|omm zZu`%He+~KgH3@t<{{ARI+=R*C%kh`$9}d18f2sZy@D~Q$ zy}-Z|IDoQM=OLZ_>!Mr1S$Jzhn%I>^?w@F@%%dQ z1Jlb1yrk5F&(41X_fiL}w>Idd~Q_cCUo%NCxJF*JQ*$b0}ChXzY$@7`YU@4-_X zpBw)Xj=w+u2|^D(((x+E2Y@bV0rcZW3A(cqCR%uqetUo~ixwigSt-qmnV}4#?V{^qH zSMlwD<2Sbt`vvI%o@>~CAm6r6PyaE;@2QO6dkxJ_`zg22ja6jZeMyVsm)fV>EGt{6)j*{}!Z2@@4-r{Nv*MK1uu&690lxlYDn_dz`#l`9HQ)> z;Q05aOpoOM_B-=;=I`3wG|6utcOA$tG!6RtCp!L3(fR*Gs@rFVc!uN4{BwAH!Ok9f z>c*U;?4RuT!}$s4pFOwW9S87>^Q)fzDUSbWIsfJPXRkG!>iFFJoaXrZ<1fwMdd2@v z$KM}6Bmbwne(C&o`1+dHA>dt(e|p&`%+4G0ZpR-yk(9RKuk`wZjv((Pp& z9G`RZ)2-~!bbOot7L(5mx1U04cdF`f#2Jon^I!DC{Cnxf%yN8aKZ#VY&+%op<44+$ zr*3Z(aN3WYcggWR%)h;Uy1Dx7+xeLozkGbOx>t6Lnd|t_er$$X)03+$Lh~Fy(tbR3 zW9B>lqviIw|M=yx1!p<_aDK|icMsi|tm9uCrn+!vwJDFhuGaDIFZ+4M8tNSXM-{&R z8tNT?(TX{%l5&2x$=umlZdr*3jtqdsaMQ{ro1%8k!uxZDnS) z_+}Gj4IPfZDD?a9psZn><8KN5!X1<~9OL+VLO*{8Weu&4Kit2}U6Gzx-4CN3zp{V% zuc6KHCxqj}f}Ee4JH5AIg5%r%EBC(*_pZCVdhnr+zhzd@ujpMqYdFmD_jDHhNbjnC z4HF%|EnW1XcU8NFoZ~NgWp*+D*ng{A!z9PwvZLt7^sZ{waJ1v^3H{jqd+=+R?D%$m zGMqoW-TUZb%;B-VJ$}jjd7m7?yjs68(_{TG{<_V+dht%cqs;u)PJ1!IhI*dR#@vvY z+E)C={@}HU67d(z^5UEqj{=_^zl`)%S$Ms04E!<*j{#QJyJ z_^t1~1p~4E=80?Xl>99C)XVqmyCCPY1vSa&{=IT~NBh!Vdkh=wzsKC0zt`OBHG)ez z{!4Af`V`%mwBz5G3a_sf_3dWKa&P#> z^Z$Xt_Om1uB|nTMf&R>rFD;X?B+;LKU&!{~Ls>&N_Zcj>u00k=JASGE7RL|%tH_M(Q|fb#aF$$fZH%p+5&Siji*jeqNx@n@`GjGxf@&z?7u&y$-+K)O@UNU+YX6k#Z{$=u+J3};uy&d3UrP0tr|`u1^Fp7}{@2C$wacXa z*!aD(FZDmxFXo5R{x`(>#rP@hf8&9CLVj+E_3ixwTPW@S)>uExf4kSrPgoRhi}l0& zx9{>l0^EKee}V7l#F#r`{V@L$zxN&<0AJ3(9^Cn=#XrG9#h8_F+jMSte7 zPnaDrW;FWK%jc&OKVc0Ez?b)c0`#?TnhW>fSzpuSeoS!e{$8!swa{P|+{D06+n4y2#@t2h1|CF7-@{Hb? zod@y>S75&D`1iHaUdfK+j?{NGj;q~|8{Fwh0swWQQOMUab z#`C1(-`BpioS$L^^;<)YIW}_tN$)#L&zH!T?&GeqZkAtmJotfG5&kOw`SPE5eVyj| zrTY^m&YVbiKG^Z5D{}u{80@Vzc_VjLGM3u~n$eM+9@N> z@cG6=vKV9kqbv#Vi)gqGik}2OJh=1XmmtTRnXNNQt~s3&^?oF2wseT!X?;5sxBG#) z1mN5IteHz1{2C@MRtEf9vOflV`2(c>4}KNkFnKSS{&Z#kL}h=5vVW4Yf3mWF4*2Zx+XdjW$5$7E&mRB0AAI)sz z4e=sR1NhD2|6TcF6(LiN;HM-%lZp9h0^cNFB}BcS7==FReRt(GG^0=LUH1MisQ=lA zsB36NfB5r#%3J97b+qGm5nHD*ZRiJm!O6oH%l%@vuWkoFWxA-Rz+)Vr+rP$wZ|j49 zR`v@S^Q$qH&nL0hXA46&cfB!Gyb?TBei$0MxsWt($k&=jWY7FrzIpp0)PX-K1al?? z_Xkq^?$(3$8^E7d^oK^ec|$7q!NqTKatXEK{*8o0PF*G``;(RZ!*%_P`CX)a+Ll+* zK93EXQ$7(kr`Hd<{mA{KQ!Afe2mAIn)ARr7 zs87f^5IvtZm)3RK>pJ$#wA5d7@JFQ|W3T??5(hY^4NRP-NB&m)?1;Y&%$GA}PTlbRjdO|@z_#b7`WEKW z8WZ4~eE18Np9Ft>7=I7TPk}#YwT*v!{#a6e(y@MT7t7CpzrGlMZx73t_R~_?e!{)G zJwGA*#{2)$eq#LIE|xFtC&uT+FYPDBH-;6zjIYkB%s;>Xg5Pa-X>S*+f64eQ5+pe;VQs>jSg@Lj3gpd+etx+s{ms8px-*drI#D^X|XK{Aj#c)Y@4ml0D!CIr(3> z>>FY1T)6etk&jp97ni>V=r1k*#*E~fmX?;`KYFWg66oiLUonzj_{>4XpG1GZy8pZ3 zRfgY8K8W}OGvQD(x3$xbM2Z8RH67_`+3rN@>1Az?=K!wa$H1H(^_OR#49u(`b^D|V zj6-As{QNTOrxGkbFokIR^!#iE-)t=A=jothq)C*6*$oL3_4BK(FZm()fq8vG<@L37 z%^kCrHqYKV)plsYl8EsO>t~GR9}dpNjFB@dxIONd7mj$<0rgogk1GD5%-S+SLh30w0_V4=K_V4=4_ycosB>!{P zR diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cmh.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.12/bcm56870_a0_cmh.pkg deleted file mode 100644 index 3abde95310de5e600c24397c44770649e8833a8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3612 zcmb`JONfq97{|{$jG1AWVcf=TBx#h!YF48$w-~o^n~QRZg%MF|63vPlO%@2vLP@zT zEEI`YU?IsyQ7n{VX@S*DS@HjU@B8pNa}G_-Q~&Rr^F06Oa<1>!)!Nb8zNytE?&zZu zSDXw^aOz9Sizm_0FO1cm5$c5#;?N%wt_gR9$HEKYjqp(zi+mAzICDrW*;oRMkz1=A z^+JoVS=c3nD&gj2#<;j(Z`K<=r1BD@mb37>_p!VjUi$hjJ!LFf_sgaKhlxGf;B zvo;;2zaIj+ynQ_TUzDp@`S48;43Gpi`^hnscn@^SW z^xw;e`sn*U)PO$ZV>aK%)<5LK{6cvwf5^w;`S)+FVj=kC@89A~=kwd8M|^%wrt|sh z3hdGR>Ii>*gg-aJ-w@%?j_@}|_}m-juKi~J_zMwerBijV=TzonNuhRdiKfIiF0RM&d>>6&PtKl}5ah&iA;SL@tW{Q>2Fl+}SA zxgZ<;{nhFG(J^Kp;a-&e;qg?*m^!hWjehfB>Wl4?_}Cg-((faE4{UGkTiuq`VRj8&{(D`jF>e5N`~KR0gEg5R82&gez@4bQl?UMJs=BP*J>5#1m5+IOTO| z?BJr9Bj`&SJ|r)7UkyJm-OU{`v>ON8EYPP1+*0>vcrM$h@`9;XpC3}w-X}Bs&xyBO z@Veneag5+zfzuk{9V1M&&TnbT-KG4ufl?cdBKJwi({?G2zb${v!Ba z!O%^LVzQvWX@AxIuwdz?MRA?rPQfn)PR|A0ypf}fb?4hQdAln=S#Y^vMU#irpM}3H z7&5w1XO!}(f*qSQ+>U@Zq`LpUt6A0=WEKV-$&;G&;)L&3zS!hnrF_C><`%^l0^ZGS zV3(@w-WKIZt!Y!9w)tApJHBq+TAwBP`Jv8X!v8hUCk4E(EnnD=I?LMBxmM-BXvz#8 zQxrQ3J}mgMfOKy&f2f&1-pn@}+bHMnlz^LixOm3~{@DRX=2Fq$5Zo5{PYM5HpkE9) zb%u=NujV1;V+7kb=?1s)ch4qozVgE}6jdLQLui|4D( z(>3+>o=_CW3rJTg|8Wy{4R{1T0JDarS$RB9(o@nO7w&*S$)x@_ByzbJz zV{cRa4}~_44)~{=_?gPj6?{qXA59(_z8&xt0k6}3uVfw)JS_N~;471KUl5SK*327J z_urKX|K5Z~@}(xP+*0>$L0y`svePo<*C)KYoAkrVhi_FBy9(N+IZc@*%9jal5j-Gx zM$j&eo}8DMDE`z;*|y>xFZffYENyAwly1%v;kO8$2t1d*(Buu%dUt|gt{|7r68}4y zvfpKR)Gr15G;?UuTBW^|pEJf-zZAuSPObSzl*K{cFN%W&^Pbn5OZ8V@ zqczK8MRA05trEUka(9USz1Hr}%C2L@dtP#X5&k#9i-I+Rmjs`BZ&92oTTYXnMY0FK z>>$uKqq>$Q&o%r4O&LJCWXGalYXPn0U9nuYs0G0akdQh8F29NDmi)lWX>N;=mTP*@Z%k;Wo+!UfLgV*X zu5C*XdPG7WkkAVfdR{{Bm(cW$sE@5hq&G@vZH;=AzagRDp3plbG)ubJK1=CHPfqB! zCiE@|JtLu~C-lsO-YubzNa!gEO&^cr;hbbVFrMqi17&eMK*#X_9mfN7hrs@Tj^hD3 zjtA&C9-!lRfR5tmlb}OwL*Y z9_1n{-fz^&DFf&~yKPr$oE}usM~mj#S&y{y%_zyy27T7oN?rQ&5W)U6{CCvwnM-o* zbky)?)$nK6@aNRH9hU+iLiG*6??&;nSCM?K8%6d}5X369f7uzGoe`oCHm;{<0WH(d1SZOpv?nbWt&_}YA1eTd{TzLF1)?rFOgN>J>kfrgED}0;n%@7 zEk0hu|6~pS6E*x(-k)#()EfS2HT*?2e9sN+CF0yLZE@q8=IUzj0sETUKiS<^;Q5+= zr#XU{LUYf!bvamB^#dVQS;}KgpYld$c-%8mIa*J7^tqIWjVX`*neyn9Deo<(_Vhc~ zK1%<5&E(Ss=w~?lvv!2*(oAGtWI{12HUGMth>vncWUk{|+(bu!q!Pm@L z>x-}3*&Tg7kakC3&t3;#b3YjW>(5lKulMi~nY!rxga99LK6;cCaG!*Z zK4Selw#j47f5>gBSDskiuURv(FG+dqNmAbP8J=!Az2siV@V3tI*k`0V*khzT_TDLv zy==MfK*lZZF>Ao@~6dhObyg_DqBKTi(O?vj&r-c%l5(pJm5;kpqITv5__@Hw%K0Rk>+6&{OG5T zi6&8oUXLC73B7YvhV9_?Pi#Zm$ttC7EC}_O%iIQSN52n~cH8!_{La}6dPq569p5PG zvYEQT-U933I-`!^lCbT>7Th}QE9MyU$kW*B$fZiYPV42YrcUpOL@%+h4(nwOGB2lB zM>$nW_0AU8dQ+cnAic<=gX`s9)=CHSD2Y08yx2-qt}3NEHW#-} z$3}?`V%kc_i47IKt^*&}=@^;lXxINvs?oujbDfTj6CK>MTV2PeYII;*osLa{4(3Sa zFUBbepQrsw*qqM!V53sqYu5oJ6~EoO0fP4#sKDw$oKkO6zeSb-ncZ$0oK>*S6(!oPh$R zR0nfUosMyd4(7*JIzEE}rBny&*E${J6CKPq)oyKXRTBALWE#?UKQ~0Tl zv&17&7W)wMg?*Td@7YvRO6yG#&-GHIVsh_wbkjEl;~hyunv6A z+8jm=Sa^?l=!=bsb+sfl{htPx0z>ygtz}S+dqa zJ88_9ibtX>&L7l42lsXQH1|1Vc$Vy-dwTx9%kvz}{giY4hhAS6yOz6_oHH0_933P6 zTK!|~W1R7Be7}IFc3z+|QfepnQ`?#L%{NFIdG}3^E4P#C_!0$5sSf(Ibx@Yp`!bc3 z(t4bWwW{}(s#foMuv^u;u%;gRTh+U$rXJ5ww5q3DSC!K1V_di%IDSTkKJwn-z556< zleowDMoRV4AEVy1-oID1de>u2yWWUqyPV(oH%sh$!>=3XdFV{ry;M9> zY7gskx0|bXSyiidy)kX-U0zcUyISeHqNW~mf$MRtI|;~nPV?H^^XtfCHMW@xkUK^2 z!iu7}tXx+8Mh|cL%%Zrmyt<2K?_(L}1jeUjOtW9HjPIA0G0lFXolF{^WvW9;XFEuX z$(dit`Tf!5jE&pxEQ|T8^jz>mT2Fpc?~MFX&jSCb@tep};g?8$k6Df1Sy!naUMQO1 zruZ%J2GzY-GQS;P7MF@opQBCmFwdN(c3F#wta#juu$}U~1fFL)0zNC?wwd2(UMrii z#d>%an&&&B&0FZ;gK>f!vEccr3yQ0%{$`x}C-}FEl~p{=XG|HVzCEMAy4`*!MfH_2-msJ zfA^!#fA*u!{r#x((|*+XSwHG%$gH#9?&?RKmHnu*q91h@_M^@T{ivg9VV(UpMgwGB z`}Np<)cJWoY+K!rIw$s{&V&7^^O1hkVJ>10BIn(ZI43e+F(-Q7;(Wq$pXWQ~!7-2b ze7?%h&BeBP=Ok@=Y)!qWlf8s>4i9*2n|E2#wqqNt7u*JG5aZ)&^vAY&N2XQVzE9u> z)(&oae2cbO&)`$u6FRx(+;CqRYQJMoqN zv47+mh#NW=bat=tp|AOR*|nDAy(ZuHse{jX<^g<~0Quq9^^OJ4E7BJ!2k<}lZ0_^# zmHg(#wq0@gOtG}Ozasu;96}9@4vOO#bXy+=&jbzZw}VEX_Jpmk8g1H z`j#11V++^Bn8POCeS7y`d#*wMphjYBUeQ>aq&L58KkxFjvR_kQmkpjbs{SFquZ6v~ z`_qVkGtO-P@EZHEjXJhJ_J6L$&-4>hWO$d*GVBGP)LQ)s!Bc|A1<0glFRawzW9L|1 z5WdIHB=cGG(w9ktn{x^BVRHm9 z?xBfp+O;0*X3t?BZNxpujjwVKLVKzIHck9Te`T&9<>W^v^7s}Xl5+B65_$S`EBOhD zJpG`R{N{-~V?5fAUt|2INFEy;f94AN+c98nHIHl3G+kXA_p{3%={W}3Wy?-_8`ftF`|XZ)rhb7Q~{4)|dKKQ!P+1^mi@9}@7J1ODBBFAw;w z0sle3Zx8t10Y5+BpAYx}0smmY7X+Mh8ejX|fS(@lGXnm;fPXaLM+Uqz;2NS`?avH& z8rv({#P&Oi?I0y$Yn<2`C$`3kt#M*&oY)#Cw#JFAabjzn*cvCc#;*)Gu{EFA8Yi~K ziLG&BYn<2`C$`3kt#M*&oY)#Cw#JFAabjzn*cvCc#!nA8u{EFA8Yi~KiLLR@fD>Eu ziLG&Bo6dDxCvye!b(~vv5DkxWCC-nS=b3+K3m{R>{IOVy&1bGyU!MPMXLo%5ccAUw zO@70Nyq6!}Rf5Nwk9!fgZqwBoiGw7)N7y{!T%FNA*C=ECh79*8%V6isyBqhcU6nJxZM;cY?a7dh_FeW$ zqrcNGWdJGK2QOzI_fX2%b6GbwvtD_t_C5Ow<_h?&hTrtqmvNp-9pZzJ_@2X8dtN%Xr6^3kMjj*$$gzK=ws{4e9_MCIA5$Ub~8V7mfu%@v#uK`f77SjPdNK; zXLt1XK-%rT&-YwBKIrrQEyveHEcm^oud!fmUSDF-&h8kCfwbGP;JZ387Jl#5<-GSF z%X!b8n8kU1UULr_=U9pKnCH1~&)=T2spGfUR;#@QeG-h6@hUY}kV@QVVzG~nk2{PKWb5%B8*uH%!g z_OA)}xdFdA;9TE00Xg4N+EdPt*Ed-UFUkO}leG=&t|#R$UpMP#^L>VdOxpH4TC~mm z-)+RUx!0Rd{EVa9@#H%Zt-b>>uUU`pKzN++4T#)0ahrSxEA1oGgD=!%k3K@5<$CEO ztaI!`cxfN;b4v6P<6KW{gZ0w7w!ygfQ z@fe3G54%zx73@pC;T3&3eokY~aXHU?#B!ehpuT<0oEGO2%HnrCwi3-ao~SR-M7@0f zBev_aMC;`{W3l|ND;w8Hf5$I8Tfp-Ksh?C-Jgf=EzQfK3o`xP=>8G52p7OAbd6s&d z_1C@6_`NXKaL$yzFGxGIPtG?Sd=1QP?2&d+3E#o^$a^#&sjZuoBWr(hzixF#i7fYD zpHbRhd>6pFkXhT=Xm_%3XyQz4-7hs=6i2xEn_IQUZ)zZloZpBUub z4)W;zjDVbd4SN^shsWHyO|zW&@x0&YkB;}21^kMD|1jVy1HK~Q>aJbwoDuMw0)At_ z&keXPqpL2lwLRwrTrTV4Um0+Pw2Oapz&XQlJIe#k8IJj!;TTsJ>B1+=N#=9!G5)21 zbH6eF{D40g@XrVQw16)P_~`-vTELGAIOjRm^+>?44*0JFepkSW_Y?u+i)ZP0el8um zlrhKAH<3R|fBcOU)-J?{c%{4(GIGQ$m7~oa1k9nVdwG@!8?29V66M&kIPC4|*8{cg zjdrsKX=is__YSn(p4XVqnZx7wkMqwI`PcIgzK?O@*{{CFiFtOQ;uLM>d9=RTO#d4w zo1?GkTkU)u`_}s4Yiw@k>uB>p`Z|td<{zF{>}wyP?m+dCXgB_DXLt1X`eJu=&an>u zW-YkB_?zcoTlJIZ@AbuQ{LS;ct?XVL?yu};))#-bvpf2GpzR(jzcGjNo#l^e;nvFE z@m){qAis%rl8jN3*FDf91mqW7+r6)#4tqVHud^10$1~+TLym4}>bXt6!)%(hz-`Y{ zxX8sTn2$s1FpU6f7jnKQ9rrfa5X<@2bS(E7r>}u;PP;t42J7G()s~^{M;~wKVBHCg zAJTnp{I<lN-tbAq$&v$N8RF+Ee_TnZV0enCB-bGZ-j8&>QC z{GNqA`;l{{)Q{5?U}R_)JMBAo#=QrpAE$kYJ+<}kp*q;bS=XKce@DRg3i#Ut{G^SbUNS~)q&&{CQXVl# zd7Lk&Jm%w+NB>HB_&nt?eo`KNCFQvfk#p|qK7(I4C*>SA`knKn_#7W)={ZvD$KzB^ zU*bI*-l@sWtMObi=ZBmR(K}Uuot#Z^29;~OQ_ev@^793E9IHP%8CrYH8a;ofItMoL zd9iF^vuyuHzF#a$>d`J^mz@8r!2YXrPAZE9H)*e^xdb~srkUegor@vM`hjyXVn*BC z6WuoD^nLDml=->51)YuOeDQ4h;#bc2*2S-D?4M>HeV3MP zBR!7Cngd^4%eAa+=JaW3-s$mmL-T$QxqZ&_3@*p#JUhVeN<8C$oPEwStF7iy+RM$O zyu0M~X^*~7Zu@wSzg0QU;-}@<>A3QJSeHAl%sXzMGjx}um-BR&@hpBUOKszM`dqnv zLZ3?K&?j~CM~}hZJB7B*+=JaNHgg~0Hwt8I8_$nh27YQA&sMi8=XvL}99`E7@E>a& z)-`G0M2552Daz5iyC4Rh z!-Rs#z@I|55WH4IM-<$J;nzI93AEl2{?1R`RVtmv5{XOY17xwH$Z)Dw26%O ziHt9J_?zFma{l(YKXMldKCLy!pmH!ODm^EQ9-{wy)HG|Jb~2arK?Z-dYX_yQ$*_&} z3TuLYpYmwiXEpR8*0{O0{j4Oh z<{aTpIeMg4WYj0E6g^76RGTKZujxO$|K8XBgN}jfKhbXbNISb@9~o%7HW?4-*1_}xkhx7zI{ts+*jULtskL}%kYq;ZF1fn;~g>juE?sb`1>H^ z%zKUajFHq_&b4cs=i75_bB^Y={R}*|6UR7b6I1xC+0f599rG7@9aG9l>3Lmap6mYqH;_qr z^qrJPyD5(~N6JGlF(&8#8H{!_hGIEql(C%i%2#)>L=IWHEP0|WkGz<(U@{R6%*;9BB$UGKgD|8T%R67cs0T;0E`?!N{6k$`swT;01%{(}ME zJ>YK*ct^mAYm7PXpR|g(pNl2t#)-LcVs4z68z<(*iMerNZhS?+iMjd2+&D2ePRxxH zbK}I^I59U)%#9Oss zJTK=y=rwO#3r9Zfj22Lr-=ym9x$$|^Ns?{!v+jODJF)-p-LSs)ANtfl^&hU=cC+_s zXLsyB18Fxg^W4BU-|#ipLL30n6WUyu)-=&;Zb)Oscij3KGuDR#6|-nJF>7acjM+fj Y&0Y@sS=W1gOx*Y_o-y_8{O^wYKM%PK@c;k- diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_ceh.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_ceh.pkg deleted file mode 100644 index 9f33b76ac51a75cc4346c43ad81d7a87b62f2b3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6384 zcmbtYZOCO+72abrHs(x?I+~e@`H=}l@4fGb17^*+=k9y&;hrzg$9+E_whRqaKTH}0 zseYJI#YbL2EtxPu4g|#_~ z>DHB|%FLE7vS#9JRH>>?Q+QM9B8k$V(nD1QMc!C~cU71h7*cVT<%1xcn!LzHQLIf~ z6^)T-RM@rWuBcIzt2&*g*?Ma7d}yl8TsQmGlg4tCnka9Es`bq6GDwFE$Y3;7<6J9v zXC_&0!mP$l;JbAk_LhvESer}AN4*8qS7~N4<{`q5+Ul7ksKN1am=XDezkQR}+Q)wtF+B~@Ld zL4iFD;ZZqlR=BK_=qwMethMQLOMTgHpJ6d+IWhTWJT&q0g4711)$O$zZVDsDw(CKj z6_sH)$|xNpi8eGy1WT`~;wHjd%kxl0<0MyEjp{(+BTgNoLg+#kB&b%HYQxIvX1&;5 z>NFT&0lPy)Di6}-CL4OADuU3~uN5LoG z4ZJGD${iwm&TTJ1TfjkR%CC$JrcLV{rgbHb`*nf^Zm^*$U2G5-KkX5@mD}DGMGO*6~_IYVJdI!cP!*|I#$ zhOWMBl4~}6mt=cHP*G-~crB3KGcaX@$THZ-ViIhaSf^eN!@A%|6B^gn+j}GAO`}-; zILpo1LUY&S!oEucd;cqfwh>;2P+GtI#$r2`9d%a_${|V-K04|u){5UQ?Z!3oHU>z9 zRID}3G}+niP`7)E(peCrIdi5vj_u9!_UESQFk370Qh29`G@9?wixjWNQ4qzvFzqd@ zW*c#k+WksnXs%CGcjLUb_4W>9PqABMxY&KV*P!Cb#<88>Ot@_guUynNT0RO0%~%?J z(`nl>l3eiCv#rQp04huqIo@l{@!slt@xX1~X2M2Yt}}jgNM5X4O)G77=akyign7*f z!o?zxs<*-7E^Yaiz}*_@G&<aND&%r8cMSp6Tw zZ!)1P@NyOSCh%?GcSH9$rC;Ltd+>$!LvTKG3VbK{8SsVp?hC>1hG^zR@J=w_U)qfy z5b-YXN#Hl}(|7o*90b`9P(1I#B)*@@LC|+G|1>-WAIIEtJ^c0eD|Ly7AHw`Sz+C4w zXIp%E9J(Z8%IV+d!5;+E%}XKw0G^a{Y=}JzrcK5~F#UPVIn4*dbBIPk#I*e~4S|R$ z`U@73`FnxS#J4nwa`EXw_{?u@&i^TYK*Xe91Jf@KKf(bJ--V}Ggt}boK^Wzp$RvK( zlLT|lQ7lS*j-8DSi2hr^*LwQYF^G*Xzqy0&bFrlkZSU^bd)2e|SI94Mv7!F?V9uFh z4%eb;cmCxrR@8qU{3KsMd{E@ue;N1!1c5R#_j6sxAFlU3EX4K5w}P2tj+0JcKg_Y< z`;ixkJ>@sT9^)+X#~{a0i+|^8PvpOaGT#LsgR*b$b;$ks1FZicPyY*umoL8#m^CE! z{)89b-pyE_aTNJK5eVPje71fKpH z{PF$!CNOP@J;o1zE#^3T1?QXr-p|B>h|dQ9$k`|6yu;2A@#)|r9_IXSd3ZnY-?&*2 z^=Z1|Wrh?5(V6@~wE6^#Ik?Ff8$={y_-27X6{#r{J&X^SJ}Y zsVDxfL0K@zegV1Y6aNcBu}6Fle?Xi=ei8a2Cq4?f%oiQr1@yfJXV7QM!NWe86B5UA z@K-!JdoE)n`dsJZU=q{tFnA42mly-a_hjcEALQq_5Qy*e=LLs3{{Z+9SnTs$zTwFy z!2bZ|T-s;79s!d$|4ZN-2|%<_fzP2Lh?xJ3>3Mhs_;Vf}0{;w5qCMKbo-ZKIzXp7q z07Se5e%8H9Y)=4-f2_~bVP7!o|L<09}M zynNE1TReO0_doP7r9RIOr z{|D3u7CHO-!@x41`P=DX=I1GI{!PHoAittd*M34J5N(q7c=j3ZJ#b3aV=p`nm?jw} z^2I1(k+Z(8fL!d$cL2Yw=^MunVo{bP=WzY*eX(7C->#qk*L{LD_$|-%F9LVZPq*K1 z*WbJOe6Rhzd!7!#Cy5vPPq*H?_1LYSZok`!ph`YizsJEOuCWB}p4V>w+3vh_&u6zE kZg*a~_eZz>yZyP_|KDr(^b diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_cfh.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_cfh.pkg deleted file mode 100644 index 00c3a165f9b15205460ecd24cefe26f7cd162bae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42228 zcmeI537nlpmFT~I!{P`**09JxvqU09NGBl+Zn^2coo>=w`rgh0!X@lWP(YN2h(=)q z3fXWY$LBJW85ggQ!8Q+_E%6t08H}5y{e$4y-zgu-v_shMVq)nn= z?ypbRck0xsI_K1>Q&rzO);-kS*V~DJ22%4_S&mh|>#LzTW-_wZ1)ysTR5${WbD`g%rdz5V5Zo=R=7 zr`~vJsHZki9$HxKqwbm0*RFedwq&%IR_bC}2yqS>92uz821*Oc19jm>%Y(z!a<*ik zG*nwQP^y+`wr6;3!9Y11m|5#7_agg9seiQAHDhjbg|lj1T}|@N$OdNA2FrsB%A=J& z*wkZmnC42|)&Ak3TBTeK2GMW`G;3xw-jX5YELAG~3x{f$p+?jF{k@c~m3n$cr)Rwb zlk`BiZmsY4I3++e6>s1Itk+Q8F5?(aiMP*vM$s zyR-+>4wm|d(!zNq2oPkhR7>59YQd)#42Qmow#f_ETgnDY-MMw@o))|+S}~WlGTKe& z*GrWvP5ls@wA51?sn$mN7BuX-aHQNy?^&tH3rZMvNojySYxJN#Ug*Wxxocc5s!>@o z(yEaeX(P>}tTwQ8v=z(Tl%+*~%}MF>%P?N0TMUmeR%?CbQV$9GXMOz(`xn-_`$|I# z%eZ}oZeQcIp*!-?tfIkFRU;j+ct4Jv4OYim`hHr}v1n+>N5ZUGwYhVeY6`wwudhHQ6y>vEY>>a5#**O|=VR@*$q}-^V zHp>HL>{pPr-nSYp4|4UPVhBJ92ja-^Xtg$0?H}krs$^&+z7e!4)J3?75pD_Lc&O1- zE?ie0N3=w4x+M&4W`W95`a2Kl$Pof}eSF6eXp}Ro#t2Ka&6bQTt<*;QhpV;WCFRk9 z(()F=t7-JuY#xUZusPl}<}fD1*u{&-Nh1rex zng)+ToQ<<(5@(USf3UWopV3bM@)Hd%%9`$r>ZBu5!B`$=6kL=jOJ_SzXa2F|0IHpWE}bKt4Qj zGc?7SHI6c?xJ+w|_NYg5Y^cwzYxrl^X3wg%@U@0yxzklxqBRGv;R2qi9Co9lM%Da%&+q&g02q|N; zPfX8!A~e}brfx-|!-|7lk8(PE^!Tgxd05;df3bC??|E~D!;~^~U z!{Vqpoh%!aZ5iB@H{*x~5Oh z<833h46yO)8y@XH3XXi2MCa9q&i^v!76moO2> zV3S+S$dx>h+n)Y`2s*`nIX<;Sz!p1aRA9M|usIRet7q~d#6h$RlBWJB~`hhi-X9^P1jI1!* zhe#gJnPelS(Q1Ebpn1n1n#P#xF$LovO(C!D9L9>&KSPxiF3hft&Gouhd5JU3%Fpzq z&fvPI`SgPBp-tDsF#RV#Wt8;{53w8%d(eK)BC$i|#7|G9dn6lY)aQGr*a~MX%Ka?p z*<`TQzy`$`cSbzDQ|JTNa%&cii8rn7nqAXVBUZ}{b2pI$@U`o#_i2TVWp^LLJKx>J zh>;7PZ;o&lPbcJy^{npQ^>u?Htiw(61zH}L-1ZR7 z^4(mQ=k_|D`1&1(l1`rUouB2n|H6;cewil#w~rZxRJy-C>Ph4OtHaSgjhr7OC@y_7lQp+^riUx>e% zASZzwmS#p`l3MPFP^PqwvXQNia>Kw9;27XU;8b8kek()yvq;Yk#}{m19k%!Wz;juF z_X_Y2hrH_(+AYa(l=ss~-W?o&F5vej`LS%8eyIihYc29po_PG=dX|gj)AXSU@;+MN zdmQ|!B=39S`0q)7oaD#0f8HYR7v%k_MZP@0CjYl>XtB<9r7yt$pGh5mhQGhk!86Wp zhjq}$Va-W9C;XF><8|>(l)e{j><3H*4x3fz6P3gO52XqV`*Cjnq{2>jsT41 z(g^1bS){!lus!R5oX2U)N_%6#rEkN0@P>dJ-&Zr~92;=k*%yYtAXQK4yX>506;frA zW}YaI6j(Gn)oLvJCD@z$0O4$Qiqtd%eTb`18$oOcfvPGqix0a2e<5% z7~zmWv#tk$X@JMw)H_HT+dK=yQgzPvGYokQ$F^zNzeB#^fZOJ3m=*6%#ZcIj*je3=no*s-U)sqddv;D?eB~{)qvZ+_*lTL_wC599M*67 zr?3eoZP-YBS8&UYBI}z-Eh~Njw6~Cwo%4=BIG$tea2%CPA+@aSN;@Iow)1t?28&7M zl`cL?YP~PuEAvU^wd}``@x*{zR^0V~yp})oRasUewcQht>2;*?s@F91ogQ%MkF)le z8E|>eq1~Qe}y7+78^aAvy;JM7Si(5BjmbMH$mmeBUH)J{!pIHKK8()V;x8^iu zl5d36V`-?{(DnZ^;JN~Cz2b)l+`7bP1YDUujDE_kEyV9ZKT~<7xn{#)%pp}L%b{YtE>q%09Q%oc&1NqWDT zoA75l{v31hHx`bM3Tchhb?(`~J42pj-^=l(0e8)LE#NxywvcysNMpUGt}VX|{59|` zz_rYs%w6qJetU*=pO79zIvto7@VFkRm&SKO{s8G> zU$lBlO)`l-Vcb9Y8u2Fs{!Id2bHsc=c|fZLz?giUkZC#&}bqk3ekd9AL^YY~)#v zP@T_Z{Yg3V1oJHK9AN4?Zh$;->4g34$fS&U&I^mkvu=5qDzYJP+jed-&-rdJ@J$YR zOc8mxScd5;$1NZ8m^QOv_@X?n6GlQku|3xum86Vw@M7?21M73`VHuAjpX<1#zdKP7u$0V8!Pb1zl^-eq}J#9&wA4Kq*=y1%WF5=IVR*;zj^9;bi!+%^XsumIc;b8 zqYCx8KUk5Jlh?KGapXlk&2!#Ak-W*I;;wm42z<6>o@z_v6 z+sIP}d6YpO>xpGtZ=Xe;^_uT``|aS$IT?^onIfOq9y9x1930f4K-=amOQv*){x=M;Q(W&I4BuWss)?e1JT8 zlzSfVUU1`rI@^|e-S?3vE{|)?ivy4NeBdv^wVCa>2YE-Ji*uO0E8y1WUi$su$}t(R zjs<{n#5&yTzB81Gc9=`vdqNrYn*&^tl(C*3;L@ZX%e)(0nsu9Y1DAw6>$a{ka9POH zHsA%T?|}DUXs3bUaJ{`6 zTw3fa_qrb=FKv5(yjZV%M+RKJSoavm@}+exCGUoi7j58v=jx<>%P$M%q73exZVY@; z)^vH{i9B^SPapN1#4Y5- zGVarFPWX&lHQ-YrPZ`WR7PvL!sgLv1@xZ6av;J7_IF4^4&-yL10=PYtiF_xL_gCai z4rNXtwH{@Uc_)Q3+pupsmVo~^t1n1TVM8Ux!EhYucL}r}F9p5}xc*-SxK`g5!_EgT z0iFW(#-Q&79t9>5OnZS30N(&6F>o&juES8j0;XWZD}nCBoFVediyU^-+BxDog^ zup5JE3|Iv`1suR6eGTv&us@x77Vrpg3%2cJa=j9`5BOW)dEk}w$w9zupbTvJZLz=> z3p87RP?Vpub6;}KG~xwu<23S&m#z_hK#Vw#aZXsuf2Q&X*Y+`1iAf$CFFDMQ2^HBB zk8zHQ_+&kVrK}UMoWIL|#JZIDBF*}y0FgHTX~sT?xU^WOb)0iuM|L4~5*G9Gz_t_l zOwR+{BNg>P{0ZrS>e*#)VLl?J+2&Hfc4C{?+{^qKbMHA>>Ee3(y{>)1@r~v|Xf` z+Q05^xAgBCo7$Hzm;RlLE}p9>_Af(hLgQC|ok*;a?=pP&{4i#Ue!Be+Ic|p`j>o4wZ(g*UacpCcx5?Cb4D-!A=9^YAZX)B2P?GILOnD4}o$Kxf()o60 zXbW)yX;&0zyFhz0fk@gHfi&Lk3hg<9R;;rVdW>PaL7U2)A?-{crA>ym3qe5IBS4&M zIm~v4wv=EfO<6jDSf{Du+v^;~zSuIp>$a(GCfgXp@54{GrLUZ)uLe4S*jJlk&2aPi z9odwyX1I^GJQo?;Tc34-*SU&*qn~Z;F+7Pn)AiKd;GIB}bs}SUeb$WbOL^LDEgc=} z8(T+XO4|QL9XCb)uTLL)o$}?}$Aj42>#ju|x6I+=&*AUEZp*Qo_olsz31=mftK*Ta zV$Szd$zm-cz7`4%%D-mb9A-w0odkN8pk6V1f2|Xg38}ep;Y?0osLu_9C=&e!mym z^W<5l_o1h>k<(dc2i?8TJKdu^axK?CDGY1AcZ+Kc=jdN<(~(UI`h6RG4q!Qd+i}BM zU(msOz4Ylw8+dm|b}oV_i}#1wZ;^KAogLYi1K$j2>0Zh*ujHTi7W~tmT<-zjo-)eo zUiBS^qCbLJug?smyy-cC+o8pEikCtDHz(yD4*F|T;~`1@Tl_fJzmbP#@_UF^kwP=c zPJ?zDjkTg}|1`eBy3cx)$1)x(>m+C&MNaWkft2=LD+9!ft<`!tZ&@RN*^4(aV4MIB|<4Joep;1*f1ntv7zZn$J-jNm5%Q@=^qCC-JNK$It) zo4X2p?QCj)rvB!2to8A?T&Bd|df{v5Z_f4Y{LS@Q>Tlv}4pS^+m^U zJ70WfLW}LXNAljoVn10&J707xr+slXc)PyPW}QHkHC+eJEYQ-mUZp@w*K=<#(AxDO zA-3(fi1FxP%6K1SQGe;}^e4GC5^iQ6tm?TX7H?QA zjxk67U(v#*F9-iOezfz&=>O_}{08c;ZPIvKjQ{P%qieQy@@$TI>J7Bt3B++~>OAGW z(Z%uqQkkcmTmBU0Df`KL+Fz>uhJS6FGu~y+YhJf9-k%pQ`0}~f1i`Oi_Oe1=R-YbwSvl?Yf`$S+k=4mP_}2mXAK8tf~HIfOi7w;V-?8u^PM+h_v)t z#hnFOdOhMh1zLJN;+N3kIV29V^m@b#1=>XV!g15CFSNmUeUV;sXlHMq!P{c*HNNkD zXj9pHZ|e5>#-hFL<97b-+NYg7j{Wpn)$`!#wJQC55O`~gHXXC=+LV@#sjq=|0&(1= z{%^c#=l}nsKpW5h+v%wOsg4(cr#g=3|G!Tx(r$0tK)Y=RPr3&$+AX!IcIyP9O~%Vdk$NdZ8nwP9FP8IqyIH@zh6tCfb3>q%g;7hOJpGf|yI?ZG)zwjIY?D_9QKjN8J1ke_5 z1EvCz*3M^MO_`r@o%h!`vV5z7REOwK>Ut)X*(b5i=uf#F$V~m|we;aX;Ei6E#`brDo9`T*>Txl6J3VfOwiO_sKKU)~ znR%A_%sU8}4oLIY?mV&dcISy57oYkB*XdEhI+p^e9_fAbr$Ez|vAy&;iVMhhzK^u@ z`r1|G8@D1YKAU1+?+&ExS>|BCcNY}xW`CxAoZ3d&zkzK!DCDu%&r{p9(_a}<{jUH| z<++1Fy^=!Kc@v;~Q4dqEfBKGuqO97roviYu{a6B@h^%MBm&%&<)%&2e>#L7KOZ!TB z^i|(WQPg8|`>JE9U0?k%`l@m4zqYWOe$}r3)iLdVuiLIq|GP#_ef0$JcKz?1+^+vG zftL3Fcw<%H=mmVYO3^p0V!|39Tb+iC&N z<%SqH2U;3$CmP4JjpN_OQ_f%uBFnr@)7WKyta$0+B}V`hl8(AT(!Nl zuTBC_V@?`Z-T^I*Ice;;44PxqxZp2c=S%@l>$FT2@I6oekNbu{vlH(d1$S=HuI=_X zt^wQaanwJx+ZVyx+3ow#^a5L_9eZC=Nm zcNn;K5tIkoe3I-?Xd`5r-)cT|f8{$!i*~dBCt|np{Koa^MEpj7OMTAUTUgbu!ZS;DUWlQ?-Kqp1un)R9OvfSe%cq#4bg6>oqdyQ z2+I&cJq`z^1M>N6ch2&4(6+sU=fByw%XboB8u?Z-IX%c`(Y*5k{WH>T-@YUJCj^jo zDPVkxwDdWo)5ur$NK2oIJG(%$%mKg$Tj*~)?ey1AA4LC$g8n{-us-@9O1V_W%fV9} zm8Tc*UCPD&(B|#rSyz8dB!sj;r5i%neeH?O-a#1MRGTxl1_x+u2|aqJlaym7)fmadJ{akB!NWuo2E@xLK4PJZp?`_o^l zcC%0Z5Oy-7koNz@;A#JlH;>uJ#{Unukacs%|DqoHc&f)l z{rLBZ8}_5`?l1cPc>TC3;=l1W)xXs|?pXEv1Vvf5#JKkBIQ`%CsNVr8+RZgxyZFDZ z^-sI8I*mHhvHHj2<9=77sQ-9AKG9fJTsLfJtkTE*F34^GTdc-4Bz=4$=P`^gX&*lc zuHO2E_skXde_oH1=C9rU&-pyv<9!Bv2O#p@xMxT9*EDR~UjlYaXw!KA?N3lf+M|Hy zSt4J$kMsIQTIYNC_}(>iihDx+*8N)KGpz!CKc#3l`*9+68}Iy&c1z!1-w7^6d5SiD zV?t|ZQ|tU=v*}sL2=9R0#B4By)O9}G<`YJ(rb?o7x>cai{CEL((8-ggqGHsUSE8oz?WWM{1&u$ z&V<8UCgX|U{wen1MB~Z2#zoQIFV%SBoay(Aigwe#Hn#6irp}_>*2hmd)z|bM`l4^d zdl|N&oN^1%PvgA|(u~i=c&gv{eW;@TTl{9-^N`=QD%x$!JhbKdyGlfLt7lm&Z9u2k=6A6Lr#%4 z-H%j$y#8%^OhlE{z%&i+7D1l{N#kD-FAg`I);*VeSubj_S;EynsZQ`hqP-C zv~36&^3felv;k;c3&)As|eB!60+HlHNx;`+mnVX`hErOkl0f=u&o z23*Tf=X{cECbVA%+7aL>&2~Qn_#M6CINP24%{|V1Y3ExJN}pDjPCyy`?FelqnbKAQ zoj{~*>~Tib*?42A-FPwHw;M0kIo^1ADU1nqNXNuf@a=)v59ye=yg-}in6Pfgvfq9@ zjK$9zi797->j$2%Sl?&2`YD^rn(mKJffnZi=a=+dxMScu15wA~nyo9LwcA^`&r6?& zE7~pEhA`V0-?6=Qt=SHM=T>aEDQ1&BU2q0fkz#UgJ0yj+ld5Y%MpsRP9V0K zp64Mumr0s7Pv2Ru?sQ3m&ob)zi5BwMW;=P5pn#b|nkGy^#wH5CX@VYLr{QH5(8|^Ev-&)-eUTydazPtJb(yf2{CLf*6 z>nF*7#sKHrzB=0Szh&aj{m|lo7zftp$FRzu1zbUTYG7DN`gY*FfSdUI;(G&r5$Pr2 zxK*;6%qt6os|)yb;NDx%?srQde5zf67Wvwb<#+y_6~DJ4?mgvx=gIFqiBB%z+Bc=U zj__G-@4K+PxX*oikA{71eSRCtZ$wG+d2yc`k99{{EbBMMe9pmkA}yAUwAfCHtB2ox z@%t~4?)Tb^y%F~tZN^)1%lo|-zxxvL=Q!{iF%kE>E`Hx7;(l|+Z_kLU%W;7BltkS7 bN4$?D;y$bHGwYGxZ^-y9nGYTDiv|B5Q|QG6<0E1|tU(0*x%&isK}5 zf)gfjOto49@oS7_j2+@M4#{BF<41Wm^Nc4$@-%|MB=&ghS;voe*1Ox_8H2}OZ}X7Z zQFaO1?>qH-zH{o{x~EPZP~W=eR=xGsS6`hv^>gbU-v7S+2d~@DEOz{xHLGkrwNhYz zxq(Hc$lk~H)puEbP4F6xka4Kt-jpl9J7<26$j=xJdGcP7Z#@2eIrAIt?K!XCeEB`1 zzr2Dn*7WAg?-TjP^N0QTc6Muhst3Z*#87mL@o>GjzbL+Sp$LP^MfTQSta{R`U%|@O z>}<-ix-s#YF#yR$nmcUr_t| z+KgrOFA)DnR*Pi_iLv+>)&5@8qrXA?p~lOfaqqLX`BNnRCsvCX|J|5B<5kF=g>3m# zBL2m;`R|FR&Hobdm-FA_>HaON{hfg4dILfHVf*z;TK_Wfm-F8TYQ9v|{%(Nt2ekbw z#9z+;U`~3kRkeQzBmQB1+W1#<_OG?^_l1M_hyH1|-x~3kx8D${HPA);>HZ5F3n(%F z&f1?Y;=j1MSOH$t{w!u|f9k}awm-5zUmlh={`I#09#8jgqmBPb4;+iXSCKaV8fb~BA6{KF>ffvO zcTM^C693PxzF^e9PwgM*GZO!>K5hQ@V<6rZPgZvNu)3!fN;(uy&zu12({}yAP z2zn(UKJ`F<8-Kq$r|sWQ{O?^YitRrh*kmXJZTuhd*ph$R{27q^_lxc4mJISR>0ldw zeoQIsf4%wn^=5Tfetld2A<5rt{D-N(A6T+hrTpQ+*e}wq6)%|F_n@`@zz5t`dKj;`!Q5O1#1JWp}ic#YK zz-qN0#z$n=C%wmWC`=z1-+rgvHum9wpg0p!oYu;?n`s>IJA0 z{$_8=<1fN%6ISWaPHe85v81uRF;f1m5&ncX-SLt?y~j@pQ;gO{_@@-(WT~nXzLIrv zkTE~~m7lk$Y^34iI@RQN6TaU*4Blj@edv++eES**_*u8FUWpIE{C?>JbB6r;BtG}Q zDd1=Ix7h2qvjg=hz7>IbeYNk=E@rpLh|WH;*e?WrW3||1u1S9F4tB6Uh1)AO0`*Ps zXWqiMPR3m?ATX_0ZWs6~8+kp$*ZJ&ou-JbQ_>Gm|fDzbkc0OZI{2jZdK83q-jL(wg zUbs+oD_Q#`UJx)ogkRwN%>AB#&)CU3;@2OG^9c=&X8(t=+wNf3*QfBL58sKrcHu%e zhu+9ScgQ0CCCp6Mqd6`s?c@KJS@|tE0$2>@f(w&wfh^*`@Y(`D|4?9WUl_eNT#^9X z@oRzj*JS?#``l&LrRiVD*}q8qo09+1B>MMj`WJKdFA;xR@}GVd{U9e1)GVwq0nuQIhgZaPyrR@1%A^tr7Yxq}k_OB9u zp8qj_FZ*W~c>ZhnS9A8S5r3ZlF@G=nXBT+>Yxvi4_U|J8Jpb*e8TPgUzx~I)OIXsi z|6Rm?@nZ|vLQG@+_gAv#f1UXA{I^3%2L5~t;Q6oNU(eaULHv3C3;wb8U&FtVvwt`7 z=lL)A$J&1l|L&aqdx$^Je<#SFAp8CHe}7O9cL6C+hen?VLp{X*)~Oo3no(@#py;^B3BG4gbEJ{hP#}=YPy!X#X|*n>qXU6Mu%S zvkm|J5^Mn$_TM%IwfLHD3+N~Qr(SdMP~KSkKcMn=&<{&sKfA#FHR3-&{O^5@6#;B) z`yEvIlf!BU`p?`SPf~YS28sWDA9Il~g6&V&y&b|7qYtV4`GIOMGTQs`htqtWmLcMQ z`eVFvWut%3OP$i>@rQ|j74p9{5FgLWp%Ugl@lUe_3={wR@3SgEH|D>F_&31+fWp6~ z>Axmt|Fy(_u*8-o75+_4|Ft>$j}ZS&B{u!6!r#{PAIaH&l=$=f#|#yUxe(ke}zBKe+~b2Is1N@hN=ADpzs$B{C8<~R*DHX z5dVkbF~B9sSS+^dj`;U$itdT$XJ?;3yXp0bjAU=}g2XSJTbO<2?B%a-HNr1S{1Xd> zJFhjuMo3BG7f$TE^JB*NWr@GIPh3Bo=r_K((KH6r=v>%@q zt}pZRGyD)3u5H`E=ziwe0-oo<{)u;eVHt*aDX!wFigsmQxW2sb^C$Mf6f?I%|9s-5 zG}E`{TP%ftGr|9S`}tceU;jcH{|xajUj z{u$z5&Dp=E^5mGOy&-vgR z0B!^PZStRP;(zknBl`wctchPh`@iYlc2g&FgHL)C{!KUdRP;Zu;op<9f3L#7Rs8)W zOCA4S;{OFd{x=zlf1kp?Rs1{k@5|Z0sql~8yc+d^F#n6;g~QbGZxa7g-yXsK&ocIZ z)>pFkfBF^v&FJP{!T-F5e}B&Y0}B60-_Mqy{SmIu`ukvil%$sd;_rT&pC9(F4;r{X zYEa?d4AVsPKd<3Gn6v+o!e5O4II}ave~9=$5{tiOApXM&e=+`%zfSyzbM{|D{JrxJ zG@FCtcT%6C|Feep-}`eHce>3vXn(AG2~Xqg+BE(_|A+4GQ}jRA=IlR`#y{wPQvVe3 zAIaH&G>w0T_>bo7zmE9x{--Jr`Tke+LF>A8#Q))M^ZSb!&;RVZUpA)jj~_mUcHo~P z-NVs?fw7$Z$B930f1F_M-m7K%?azMieRK>!HwbY$d^b+~@B8@^vjZy&P3-@Vy@ZFt z*~)qie}9h9himV@p7@{f{jvXS!heIxU)%{mA8wz2{<#znRx1Au#Q*fqpTG;hXR-e| zd=1_zo2_hA`8y&rOa5#m{-*QC*6{b2E>-+(;%_>CCRF|g^Jjwio6es}mA{bY7;V4( zsfu}(=G`RmzyIehUSBqLf7GU&{Ws<8KSlg;|7)uP%ddY)AIwNKq+*KrKlE+y;u_wc z!|&82<9GUYb2|T~cl}PH?~!Uq#pay-FH-s2L;@ajK<^Lt_rYzSuW}Lb|J=7nVE+r> z%7*w4-kW{@yG7IAU&6NjTZsQ-zCZ4NP54iz^Y`u#-xRHvpbylp2Qf|jA21yMt(yM+ zk}S9L-%9*HZ#e$jWdFOy3Q}IWJpcKlrJ{8JLv8)H5&s9jJ%at8CG7w7RI>Mfw#)uD zoLrKNy8V>LBQ@KJ|7ZR7^MIlDa|iV&^UwNr2l02~KvkULpQjkM*lywe#xD2NzQtFb z|K!tmzhlSfMRxyV)94uV&z=%C$%>Y-7rzZ247w1oW zZ~pZ0@wHzm-{5Zo+VSb4{KO^I`=Czvjc-+!i?5zu?Y^aOXnJzw#xwX3rVR0ENc`&Z z$)$zn^Sd|fDLx)LYsaUX@{Ql$D7HThx5v5GE_}~@X19UXjj>+p-)@H;hAiDcALW0m z=D=?DY~fhfbG0Lt%TIp!+`|*ErDLha>X-Oo{+tY3hYa~Mkj#I&dmkLkctv~r9ZcqX z`F~~>n|^Kn5aGlAi?%=4Pn^`}4->xB{-4=@I!pV;*xkbZ*ZKxy9}J=nhj?%E=3$lp z4XQhPJu2QmdEP1xt?ac=VE@O!^$SbkANm>aw^+XZ1%?0J!2%fYFXZfBRQTUQ{8ytV zG6kQcel1G=3)q6%Ck^FKN#!3jI~f0rhZrTbKf~i+6Zv0O_#X}YpUduFCjMv6dk^9? zBLBF#liGZhtDo{|o0A*Z{OYr+NIfv4J70s{DEU;YZrS{P9}RaH0+ds>FZ6 ze}1f~_}3Esq5Bj1>&L%F{UQEXO!;>y{KN2u`J=!8>XQ7;?!W5P{}+sT`S0fsPf`8+ zsT2P%`1$iAL;2rG^oO+&#ve{tYL*7|_qShD{@n`ybzo~VH}rqo?*-{BLO1b${QQE| zyRw)4XG8JtN%V&m?Z-che^1W-y@~#I%>OU6^QSjw|Gq?jC+7c>wtrvF{>=n`W+?xg z#2@y*QT`jaf2=>z-%S4Z=j=a_=x-+f2XgiwO!POC|ARUE4^e+O{x#YD4-x;M{eQwx z`#+rMAJ3m}XtzJZIs30k^pEGyceVZ3pf&EV?c>Ep=<9m&=j`#IHX7KS$KiN94~(*wb3 zMgL$poT9UV^~8Vijg1G8z^`9l(-})O_6FJiyZymAH}nsNRTHPE+d%y9eWPz0CW9Xw zf%rd?0?=lZjk14t_-iKUA8ZS4I7uIGB>t!0=;OC1d-o4yT)8k)TlW7r3!Dx3+p<4D z17XU4LiYbmJL9|E2_g$B_S2frKg8dN|JDS59)AP= z+f@E8M7znBc>MkR*Ny)+;_tUV#`1rAfLX5&ugQ{Jr)E+UbmCM&*x3 z81RqBAC3jG?0;v7zu*4YHsAkd_urY|5AiqRzcaz#%m3{Dm#O@19)Fj&KNDX3byxFc zYJX$-e|dsG#NUYjB|0eve zNbvXKubY+8bnj64d+m?I{WG>d?;!sE@vqI}->bV;BmZ|M_+$HT!vCEK{yhE${C6k# zL;G)=@ZU}RO}GD7Cip}Ajrd=g;BPAaSE>A6_=5M}!|^Zdc;8-NnfAX|5&uWtT&zI$ zI{f^nf#b(_sr+rvAH}ntKY17Nf7tV%@y_37-+uR~{NeZ);=jWEGamo$A^v~r`OkU& z*^htUt@8KsXPNu^`2*`*tGrw7Z!CYVR{7gJe;l6w6WQ|rYU1zbzp?z;tMZ5a7vzt_ z^X>k*}(PF{VIRR zAMj_q|Bx|%_7nd<_Wb$tugdpkS+m}>2NL`rHROMQ_bJ3k@*S;~8ezaM{N_itZA{R`~TX5ft5Z!oO65Z4g@$KKd`!b6#f|FzWLg~zQr zzAVOn)*seu~A~SE} zTJ6n#{rZLk{}QfR1O7K8_&bLD4<-2XRcpZi5b^)g8+#p$zt?}u9{=}J|673`6!700 z3~Ro=m-xHDG5P$N_qF!dZ+QIWeIN0E()ai7f6Lzfyr25}^ELJIe&X-O!P)iUNOzC$ z{okzl64%4w0_D5cy>JeDpoU73@EhLu-wo06_r=8c47-iYIT@EL6MnyY>cgca?>m<9 z@pOkPgx~nqW(W9xNuLkUtvQ1#;g1^juMxiK_1i`Grv2-L@8^%P=QA`YpYi-O#_y(l zw}GvWF@BH4@5b%R7{6EM8};ua{65X?C~2|*!uRvvSbPQvAM$e+P79pfcWmo(BS(5K zKmFwwAD;Y}ev>yu`0L$=mrcfKnDF zs`z(4PWb$m-`1dnPuCHC(0-bV&lu$=c<5G-6aLohU4B7jJ>d_#6VIFc1;Pyy-)#H8 zQQ~(SZJ!x?RQP?sV##7(7b57tf#-Y653^iJv9^xU=i8L<`8E&W@u`9Hla|7N)u6w{ z^7V()c~bn(ru1J)@qF)s5_t-<`rAqN$xf-NgTNJbw&aU+zie?%GCmzkS62et%4_{mkC}G*$kpA2~;V;rHF5uYo7Z!v{^` zj}H^Y!u<{8e?RrdUp#Pd4y3^TS5d!A#**Il6aN$Mbon^%!}h<@w)v8Hv|=EgKmI`S0r1o^YmK>iG? z{N>YC4)>Sq+xia^|HV(ad>N;B{%3E0)}-@4pzFUz_UF>3{MSYKc?^>A^s1)*@wMz zWA`_Xs{Fp#K)+PW*E(%cQ^K#Q)SAeMq12;-9_!T(9zZY#V>#P z%V(h!&O`qpR*#E=rCtALBk@1;X7ODf9k$=c+f5yLBn{aL{}DSJJIL@E?0>$6`GX}o zaWdmoB>%OEzx(E51J3_X+y?PCaew24!oMWpvm+7qJzvz54@`mpknz zlM4TuLI24FfA9Xlw3f-^ZBqDm8}#2K`(x7k-|tBFO8d!_!e9J-a89y${%hpVRL=gJ z75>5RgO`G>7xp)Ce>{}&OWXY4O#B~vvxs-6xnBN9GYEj4zFySAzZT)O{Vz)J_wqlQ zL8soq_*+`|cSm?_|1HG-b8i;0)8IC7|J57KAn@t*bz0@`L%M6>&qsRxe%ipkE0|5& z{Fx^HpAV+Q*Px#juj_DlYfJwSM*Lq0K4|N|mHI>c2Ub3O)AbPl%?5s7avSykG&F8< z`{^Bj$?Z?D9Eq>nh`;-0aV?B&Z2z@g_P=W^-v1BGu*0L_zdga<)c$LS>_7j7u0T5W zs_DN&_Q#`WWBad*W&b^!{rJb)f6Sj^uwRR{|FH#B4_-|CAA55V`#;9o|4Ul<$J&2w z|4S15O|}1*w(yU&|JweS693P=xrnW>vG#w4`X}vDI!T&XD$Nl8;FN=@-$&j_{ZGec z9v{^7-%0!*^_l$nmh?PLe10j1FQfh`r%OB9WyIf&PniAims!jaz8^6g=NlL<5PrW~ z#SAree=nTW7yNtNP1wJpd`EXtN`!Cz`w^l)zyJBjIqI*g&nm><;}@jwN9fL=O89X9 zv(watDWOQ>>>`>Q@^T~{Lh zc>MyW@Z#Tk+BBb*75>UYFirom>_3KH-u9cuu=O|~op`wigwuT|;~ zM>GeR!@}!!A^M*o-5uBrywX1Ny$P$t|BG)H{j*?r{Z6^2!#SoIs8RnPp}%SegZ^SY ztdh2~s1g5#Hy05CeRMqkEb`jI6eDy|e?R{5QJ?#DeCNeKUZ2Lli};(4e_iPxu2&a* zZGOcT{eyb%HI09r_@8()Sc#ZF+2h|x;lF%6E`^?dL-zO2`kV3ZR{DqiH5bjJ_=oja z%} z_~xR&5kdZ}Y2SXeTRVLz{2Bkoke+{E&i+m6{~TZ9FfqgZnAg~Z^=bEGP2&HhH;X-9 zOmX|o9{+x|zr5PgG?wyI@Ka4<|NqNx21$tdqnMz>ssZW``>zrBCl|~gRlPiByk>y- zpN#weuybCVjl+Wq|Fr!F%2K@_B>tz~T=W|OjDPn1*O1CzY-W5dh`+}5$06c>Chl+G z`Gms?|EB8tDeiwY{D+DEy>Bl1bliSbYpk=nHPj#apNjjh;EI)={~F@|$eTs~>Z}?6 zwF-a5{a4!lYbF0hqy8h*|2B)guF8MS_>V~bX5&9f{hv(8Kh5@kl=zd z_K&__MB<;e=Q5tN|9a|w2qWhP;fr3ue_2%@jiDS`Py9~{`IG$u_6CK&tMUYYx9BPz zTUBnz*?*(Le_7>;@mJNil84VW=In1%e`x>3qeM^8x*N~mwvknQY!iQYK0H4fGIjoN zLgD|k?BVMAPbB!8I)6Ax{f~h>-T#)L4%;79y}YbK%_Q-M@9#{)2+iYo{w=tfMwp_r zH=9)cc8r1USkT|*L*5^(4?c@k)4@%||DiYfw!t_y_c!qUohg;S>s!SA&_7{+I1d zYNr3Th5Ga3caY3W2e;%|f@!|QjcfM>aJ{8LM62;j4Z&kwYKUu|t z(z6S%AN=(6zBQX3dhDh9H~m-reoBq-{X93u?;?DIk8bCxb;2LiPZfXB#g_)*^ZO6s z{!CNx?F3W{!XI{f zuDS0gKlw{j@fnf$a67VXuKzGf_{{A&aNnyRHun99b(HU|U}O0|mNTERAK$^|>Qi{? z3$rA6hS1yiEl4a6=^Yn&6XSy!MgExoDD@4ygE8RIdtJhrtLTFiLj}s8_9hbeTlM)x z%J;nm{&m1#P9dupr9}AaRq?6o`ujh-`94YDPw4ZzDBt%M__O-)sT2NsReTEi{te1k#b;8V-%a_d`0UeY_`rFqU zKTk1R<}8 z@loDy*9Po=yq@w^@xd#enq>p!tKxG#z?b!Au#xZ^{`S@D=P6Q`EIl?(WmCTGu>}5v zSEuuLg7STDfjDfmyOrOD$>QNAiZ`(V0ddD=8J zn+d<@Z(kKZPmy6~Xn!uEe1H2A_!-)tEtKzj3;Yc2&ot%x`BU-N1CLLJ?Q1LL+elb`t)mpFbo1dcdVwsWE@4yk+a;?`4$l=a0aj*5_YN`M$TnKM4Hg zPOPJGcTv8dKO_Enz%f^FH?3K&pnRVs@NIqmJ1F1x7Wj^SeBMd;{eJ#5WBD_mA%AvL zzMnq=KSTapN%_9Fz|W9BS5dy7Kh0SF%xB1-cTv8dKLS5P{_LTA-&^2k$e(u;ewUv= zwOIZv)igIQnCxoG_wz^K`*k{V*-QDpx4=IL%31o`@4_weQ$y90CTxBZZP(K!ngeVVX^$NGvvL-_$W zcmS-ggxE8P31mK=}A@Q7mg>{_`394-vk9{axf|@P9Ai2Vc?b zjrlKG-ZJU@eIMcbU%qAnzo0|*rg=Z%2REr!V*Yjp|2e|vUmk&33;YcJHxj=8{5Lid z^Iu{5{m+{SKe)fE8RO4q;D3PdgHt877=H=krCV+$d{~wK+FbEop?$D*;V|7{neT^a z#cO~v@;@l^{j&ipeOx;u|5s$bpN(etx5#||4mdOX56S$Bw>r)6Zt1Y zivPMf{t=1q+8%v{r+?P?e^}zPUY~EIeLE`iAv3)>n8=@x$o!`7Z>0T)vs1$TV-}mb zw{Z#1;ivcYedc_X{YBqxuslDog8Rw*MN9hvKkO^>e@o(@(d8E;{-o^BEN%ayickHS zrR`sm_)``BI5UXd1ugHA2%1wW|P@Mt)v(+K! z5}j0kYdUVK9a3mEc^k95BVwj@5;g-l=;+uPZs`=#E1N>VJ<>`egyYed+So$b6UZdHbo$Un}!jS@h@ar!Id)=F|A|_EVQXD)AvdMStFY>hjmg zeCp5JPhI|)#E1Mmh)F2sXOCunj!S&VPm#~_Qu%sXxz8UH+uRpY+e4Kz?GHo~^?1lI7~|-#5v8*Eor=xxP58!x5<1OAGlJe&)=@#llb8FtL?u-;zK$@#zTB8hR2Us z;P_Yf`0-+if7B@d5{VD~HIxQ_Jb!`({B`%gmr8u_H^`rn_~7rg|AN16`@B=)gTF!k zWfFfL< zRq?sM$k%P39TlISKLP&L{{HJx-2dv8SrwmOfQ<3+`a*Ekv%}f!Q}Llk4tGFA{+!<- z*dKkr#4j*L`FMRn4-da3L$8mNn0Jpz#og$g{~uxCf9H8?KDc+JlUcn-!T0U~68L9y z`PWGNg6t3R(dA#O;7k5+{Y965P~w-E*J%smvm4|8)HGYtImL0Ef{#BC4*40ZU*wihU|Z}uP^_KiVtT@ zO!03~@ok?koPW@J80d#2{uFdfu>2I#F*-k>+kd!K;vX&X=9Aw)0JHgvzIn*c7j^l+ zD)EoVd}e9$Ze?UKbpn=*ChTCnV-S`c8UMAAL^e%GZe1h@94(=4vBvh zHZUw^@@HP+L-y2=4`~`4zhpRmzf;Ah$1fR#O&;1vb6hIoX@ycUAm-{IfXU)#cx%;QMPB z?r#s`Go{V{l!EWC;23{eoBw+XKHvSqRjPf-@knIg65S4kFqH9{cIHYjyHDae^1JMykEd8`2C}x+@hDF7F)W59jH%Xgi-th zO?Yv42Gq>21;W2+tyzAN@PB>SET0knZ=UaiFkPNGE)n2qA^yMq4*0~mBKkPvki|s) zaa_r+IsXFTANeDUKR*D=Xzop3B>cPa;(|ec#-0)4f6MBHzN;TK=U*WFoA5gYM&l#; z-voDCndDoz6!>2sMm z|03bvG=|%kx$PHjAQj^Ofqvk#%c2F$I0QfCBk(6z`&Rml?q5XytYJQ5er>c8ZklgOlxlbP|4FPw>BgeGwb|xuXz&+rUq0Rf&JY zhSWdrf6!)2lal|^n*Q+n zgSqCn(Y^U-%#*>V0{58GnoHP1MN?P`1Aai{k{Cx@Q2?| z%+G;#Z7{u{4K@2|zi=h^$}Q&oh* zzv4pS+`{ZDP5Z~A|2U+F6s9Uj{1fM%pSAk!A5Z+_h%lz!o1(-ooY*(veACn!l#;|h zapDB<_v`6OQfGs*8F{PM!$LIKuq z@pb<)SjOe3Q@&N6b&uoLW~MX@9{?Rg=+TaCR?Kb70&^~|ZshuaMmW%s-WW7~9(49SpEGGNI z3F6SnvSHBoKd<3$v3>3jbE|_ZKX6{0qeY&;9s64f{tE@h>X;TgAUq|6|as%w~D_Xt1G&Dp=E@CV26#Fb^kyDWLQew`}ZpRTgBgBtkn76OZ>koS7YtaAS-JN~^+pqAC z?SBRT^BVsBIr|SN{A1lWFI|H6C-`v>UW-=;+h1QEApVa&#n10KCFuW;7`VPOsPJ!w zY2s&l2LHjF{f89(V*JOMoxy*og+DV8|6zr{82`xsyhi>E=j^{m;qPaS_`=UWh*fFc zts(voKV|VVC`Zmw+xv+J zX=WW%jA{D&vj{RFagJle|0&-e&tIAFA6NQApNAAL{!x9}_>U9+$AtKk3wdOoY2L2a z^!M3q|Q~{!x9}_+Lc)zaYdv`~GW- zrhnS_Zz29q3h~eGKdtn)gRqCMUi_o_wDF%N{%3^vXWxHq)%5oltZn{pCH{Xb#6P?L zHkE%AW-0@&B?A|Lp!dsK1M5Q9I*%y4I5z zX{o+#{_G(BpPiU-0Oa8L&ynuz+waBH|0ug_tRQ*1wEgs#tF8aV#Q(vkcJ4Fje+l*X z#Z0|iLj2u0xD=?bs?tg6hy){@H4xaSZDe%+K zlz(pV&cgSXPCq)n&8R`f$?Xc3fYT_@|u3mDx`oy?f1$u8T(c zADOzcyqV8R(&Wx5v45>D5?hvdyNK@O#|q zi~X;Ro-Ngcd-t^Svybrm+^*T;#EDPtxx2C>xY+@gKs)|T!f)Vi++gV^{4hRG%o)kg zfn@%HnSJ37OgsLAt@vM^o(S3p-Tl`P;m5Y$L(>NQhg6}bY0ba!Op|A+cKp{; zezbo)w0mE8eO#MA(uzN6PXzr3-Ss=#nt$UHO}@ct`>&(?sQrJs+d%$|CG!tW-&Dz* zKXCO`=)Vd1KRL2>F=PI$Z_U5)%$Zs28fwRX1L245+rd#I?c2sA{u6UX)~}t+KQLop z{Z6#ve|0+Z`kf^FSpWIyaRcqcreyx1-8c1SZXc#v@h9!A_hoD!Hn-;A_{5q0r?d2* z8JicjU+Wu;eK6=hylpY~AIfU1s}g*e_VtkP{fLEM7Aw=s_c$duU^nsocT3?Pni=r7 zSib%Rh5y~b0vPZwM#y{gJxRTnR;q?U* z`CnG}2TzD+&t>;76aUZuvdFv4ru-`k|BsUVVeD1y1ga4KGrufaQ_%i2dH!TSSgNZ0 zdH!r**m!#R0|T0+O8gft@j#~HUrY3d)g1ck$G=AXA^x}oru@4U{$Z%mpU+Ky|J5b? z8{L1^ssAq+^YY)%AMUT8KXu}N#>*e)tfBmGB>KZz2;;w^o&OE$?{B}R{JRzY>%i7# zZs`BEr62!p;{SzT7K`J{_prY*6#t$?e>nT>$3KgIPtN|miT-xX|1Y%jr#EN+zC?c~ z=Kqqme_zi2%>;k`9bE(Y()B_ ze{F)lsrGX%@ekThFMqPPpCgI>X7XnwXaCVee>3?rnzR2pmH&i)k1QU)2g6LStRwzk z@G;);SN7xIF_nLC=@k88*w$0$Q;iY-GlGBi{2wR&@M!Gr@cT_~7vIis>WZ6=6aUk% zZCt_+PUH8p9^#{9`mXHEKVp#BB3@!uf(+a~=t%Kk>QO3$-}u&Mr?g}lTZSs(j~e!`5x&2E&lZk# zJy$zYx%}jp&pkZxTIz5}BX$wKY5zLmo6esG82d;b;HGY)l>on}px^R?R6M*(Z*a;oX3WZ!kiGgumW>c-dr(h6sPJ+xz@W8R9`F z9hUj$t})hn;@pl3`(NvX>H7!f==}pVynkSbpFhdIAeO@4mT`3L<%JpY{W`g>9BZ|wSGN#P$}zdj#af7HKzS|a|Ze_5=XynbC)`3Kjp z(Vxd(|N2*%_?y0dT}kwZoj~ZXAO8yVhxlWwXX^TORpF0(Ui|AXS?<58%Kk>%&zizN zy#E9)yJy{gYsBC6Lt`rbUDO}$CJp@!v_D-r``4*I?0>`S7Z`uoMP|AFTPOba|FYPJ z*ROXQx_;3}^tXB1d;a>@FB&=fcPIKgF@OE*7u`Ag_ayl9>lX&{r-%5%{wtP0**ogJ ziT-Btr#EN+zC?dB`O}xPe^cc@;h*!z{0WAcUTG5l`+bb5>lghh|KR){`e(d;(NFyG z%L-UL|LplcK>g!CU5Sln#xg+sAMklc`TeUI;V}6i^^b?dfd62Ef60*l5cNM0i-`gM zA>#kAkLTzA!>>=p=Go!kF!i5|0Sx#L6aPni`~gGHCtO4Q=Wqso-gEzK+rS#)|Df;h zJzp{V*HG80{2hNL=pPLGRh_=9CH}!BN6$Yv(C(BPjXy&DqmPUXjSzn~PR*_lnKCV$ zznYEn4Gb3uzu&DIu#Uuvgx}+CQYE|-P0`s~%m&bk={p zz)s^|l>MXl8}KhF{l$LaTRhz{e@K0bUr#R)|HYqG@%jrCSo$3mZ!p8(ateROH#0r| za?bu0h5ra_t8zhqRlPiByrx3@PyVbL?cTqhy)#i&_#a@Z?F#)>^>JHyxJvv_{j3_C z-C%5o*AB~5rLU=}{KYi)Vc;)3pFiC^YQ+DGf`8}hlg_nE;onp~wocE#i}>IBv+8i@ z5Pt$tSlQV?o%;XCVkK4lT|NIg@&D}4sso{+0sn@=zozu>*UF!U>_2GIznl8sX0g|m z{u5gM-Lk*Y`1er%V-OwckIe*pU0qop22(xIL;N3jZR0K&)8=E3XWxE%RsJ5G&m!!K zqCc%q(fsui|A$`NcmTi-hmUvO9`os9fBIDZu0KND5B=ly_*wjOe-irANBkdtZR5=_ z&O9G)9GDqPQ{|8QFY1Q=L4Dv($5FU6iT|UoZ9EF2xqQ^|6aWP?Ue%xEA0G*aHU0aE zzx&$8yF#>q{qF$vhrSPd^HEX$xyTnm@ky(y0pcG$G7$Tpt)@)(*&y}DwF`F*N`=cS z>ZK9Iib3N4;Hwazpp4UoF8Cn*>k#$lDXH+(^dF-BuWfWfI|Kg1)St&+(XIvgAI?18 zz%cRuoDl!)+wU6c&ynW**HC{U{@MN4Qh$uU3XAbq)wfv=IBDeB`sisALd|4Z?448(tf(q9p0?ysni`zVGt5dSa7$1xE9jnx0? z_zYsh+&}g{<={r*|3rK`1KY1n{g>i1hz)D{+r;v4iYN&JcDPXYg{$3FDj%#n4MKl0^o^-OK)yj=_8SeEz@|2tnc7M}{` zdown6{kKZ^rthz)N&GHV?=}c$$FE(K-!Y-}1a-n6)K3-Vj2eW`zu#A2XBS>S`043= zYc@Uf*h}|s`mg%iZ#Ur&8jU_=5B2JY7+in_Aav! zpMJuJ{K3zS<<9`&54#3_lsdKqgM{zje`3ski1NL88{-cXzUk)=tRZ|qbjI>?E#dnY z*NpAIMhM@u|0v;`&YyLZZ#aL(2;X#k7<+M^&DE!{RluXqr~Dbb?Y{;u-I})oS%g2z z4{@7pWCqFStL!W*tuSWeJDpNc@<$^6v)TAXC7=0x&v+$+e~I#KWRm#U`td0%`6NCW z_!T9e#3uv4O8Go*NPHY-^RQv)IxICMpTr0F9b&`LyOewqpA7zW!teLDuV!rfnrHg{ z4JChsg?!k)vhcf=eAoiGzZXX2&llPJnD@4$zde+1dg$zWSAX5}yqG0VSWrCj)%aD>k!a_c5 zUrU;7oNQRhhf6TA?JEm^4dvT7*Jk7o`Lo39u)g!MR>>#vu{-AmQ;aD2Bt9AVqm=J& zU*Y=2_&7|v0a~ZzllWxdk16>iJ{kDqgm3xV7mICQ8N$!jEBSB-N5F^eD+_;vlFuSO z3?g55|Fy9tAHYy-{#WmhP5B%KD>M@;QsImC5!(i%I91X zA4h*3Oey&!J{kC%m3#FhWK1c_+ETq{~qHn@nO9`GlcKO z2aZo;xRnh4I|)Dda)cKjZzl5@_?HpB|K%OwR-z?uHd=o#Cw$m`;r=3s&iM-)`T47i z{fAvLe~n506*3?EA^L$o?%%Z{<4yDqnGgQv`0teY-u+$N-*d>~zgy;mKNLg!D`h^k z|4o1Y2s_A(@xMyRABp%G^OLcch4aIF|HXoc!~W&FDZXUK1FHUGN&HE-%JDy4sLsGN zKgRp{tdo{EV>P5jZ9(Fn^AkSg!`$@wMVaq<8&t@j%EB+nd{zcy#zOvd7Jgag)A++$ z(2q|=;=fA$cV*#MWj^)alZ9WC_>iCc8$uBOt6?=@el{UKxJooim&Aws6!~@*eqH9f zgg=#q-;nvNEc#Dp;dje?8vmIr{2qx9`6>GE%EIrJ`P6?;7Ji?^hy3K7L&(q1KtlTM zXIb<5T~p#ieu{h>w=Z3Ozsz?DpSPd7`~jKI%A!ASKXv(oGM~nux1YNFA&C$9Df;vF zQAsV{M6--$b6UZd4B5hM`b=Mi~iHN zed+So$$T1ro}aq>F^LcPDf;vL)a8%MeCp5hQ`tc?*4b1#0P(a{OuAS{Jr+yVljW+_IZcI2Y-Y7izWV~ zynZtr|6U^Tj~L}&D)C=6%Ab+==Zx}qN_>bv&Cd+S7nezVh`&Mpi0Jli~d8J{6zl53{uM zXTQY%s=R)grM-R+NPJkoHfCikKOz3FXeQ8mBtEo1yZ}EaE^{^U>>7y={=CHa8T$X% zN_^%&U2Y}zGjfjO&$Q#0gEHS=fEXXn5a^ccWImh^z_J3@m!Z69;R?|WKf7M$d)GHb zey~#bEIavggUt66C>Ea#{)c3~pEv?v+yA{Xzt>y-7(dt~Ith$F?)zlEe+z`ael?i! zN!~B>{ajgz<&1WC*qqGg*RSFFxOamWT)&R{bUJ*alF#q2@c3~3x>II+e2bl)X9wz2 z7y;Z&*R4Xc;O>l%l5tq%U$c6lZ~m-)ys1oq_)o6(t@Ii6FB1N&VZOy465>C$+UGL( z5qMLjK=?=g2v)NTr^JjE(f`2eg?qMJ=KL-8%se|-pTZ=^{2as0cK#!9PK+&e8(0R5 zxdMM(yxCdKJ_n1P6!>GD56ghBD<=5gyq)cv-zR*U{f)(H^YQ#NpFd53Z$5uS zzUlmdr z(8DB7RU`b*C61~0L6^vX=CmFrajLq=f8g1~G4(zuGwdJc7yk<3n~r}~Wr^$8c>D{5Z#w=(k#9WyC6V7El6oJN;e33& z{W0A^ujI^UwZDz`KS$^1c2C7GUFbz6oT|vi|2F>oCI9%{2`~OGLrrONZlC6fi8A3& z@Hx+gyW=^0Uzj>@M00OnQS#?Q{_%|b8sQgR1Y-G&i+^1V*ouC9x+tGR@ejZF?s7hx zoV!Ld{&f|fZv!5Gfv@n%x$8CgJxYG)@5KlFb@Qi5_=AY%#k)DdkI(e1rvD(}-yh)F z+kD99->l1DL--Tk2}C$S|Ct&;p@^sI?a2c-YWlCGd^}0n#9N3zgI|*7Ls|Ial<)b& zOniTg68L{I3LMs?F6#;Z3d8&jgugR^uN(i3gulr!e~R!Y`1-{^-umV3TZZ^=Cj2W5 z^DiR&oe6y1_-`TnO@{f~2!Fzc(AzkZ&)Bea%^ZgzW=|dX9nJjTPWcY-9L{%ue>^My z63Rzkem$JGpR50a?NJd-!T3k*Np#_gwNw|kbf27^Y|O&zl-pB{0;K2CVbC7 z%zrn?f8FhCFX4OZ*Bsv=d~f}lx=_+RU2MK>C`YQZ&`~TM|`Le$*{|3VM^2glzJw*84_GOO$Uc&db zFLV6&6TX-KXT$uz2Zq?Z{{DTA@V)#$3(#18X5imQ_+Ea>eBJ!HiSRdJ`olw2{Qi&E z{(!$O|7ODX;=dfmpSS<6e*6y;z8C*x@Q=km1OJ1B@5Nu{>&E96!uR5{6vl_=r=uUA z4-vi>A3KcCJut*F@NXr2FFrC~H$J~g_+EaF!0le%`I8HK!QVb`U|&^uVxg z+n?W1^TqWG`!C(~`-agFh_aA;w$v4-3`+dUqjxWsd?G;U!TJ=o3z+}79n_$A<(K6bumTHwIN=l+j<-~LfLEpYQpkrTM>Vd@RvW(5x*|+A2sUVkod4i zG3eh*`25^bsm@9cqox8Zl@zfR&iQGD3d(7yTc|8L-b{qI2h z2RmvX)=T_3&S&%f_Em(&^lHc|1A>V+rA|KF#et8=X4UE`fJ92yUcGB|IYk(B=M=g zX8bRe_zvH`n%I7N+b^>)|8e_zU|+}E?@SUO{p0)Lrr4)%|icho-YPT<2{UEtS{e;vf9L;kyDep&Lz z{5gjH$nUKE-;=->{DI$%eD2>Ff3L(p3)?T;z>Vt{`)?lxcl5ss`JMOQ92Nhhe*l2| z8+`tZ&xa#~PWu0|Nqh&mD!$WMd=5x_x4=qGh>y=NLYy!^r+xqB|G6Xo_ayNF>FpnZ zkB@7x1Ab@mIVkbZGIr8GxW@QA2y9%xj$Zt)OX54gRPj5E{|yo!`sW8?{`U#~&^~k) zpZ7}qW|3ifa{nv5<5N6-{2s=q@KC4i!<@voVgCaEIKK+~0=x(QvBPtdod5aKQVCZ| zx^iO@A18NX{P}=i?1+D}#CJSjc=7n~ivCR=AJ$m@UG{Vb$M3&F`N;K~2RLr`;ty4< zS)POV10UA!RQmG+w^06a3VsLvAEJEMEdMsj$BsXwKlVu-!T5Nwnn%9lv?_ z`xmG`@7!(+^_k}%z3*@c8nayei^RXW)PVefqgKzeU1@i!g+s^pLPA3lFCbN*Cw_OD6)m_NT0 zY^a(2YdQOO5&xp$_NR;ZWBz*`+8{*PUh4_|J~eav>%<@P-=u#-@;BT5G>E_H_;)Ax zn~Hxo@i!g+9?9Qq`_q%Nf3M_kw*BeN*?*Y&vmR(aUknC{Of~){#(b~ zV1g3yKLznO>0g%oz5bgi|8ma$70F-O{|Um`@oREe*%xc4E7&JsK4RkuMy&J8TKEQ{LLPJ zjS~MW-~kp-?$7?a9Z?=175mRF`X3BF_Kx3g58mp$&I|p|9zeiXAdD4@sr*j|e9!+Y z!Q0MXEtao;f%xy|?I)gs;KkwX=lS4m=dT6g&%b|X@cc=M_!kZPmlXac&!1F?|DxFb zc=_{ocsixy6;M(5!$mz~rAqvZqCY$!X%((t>-$#~{wCvJBmOV&_9r}ll{x-3g}=%8 zcM<=hVgD|LzsdMB_SQed?@#!*|7o^%z*u(TiB!th&qbA1A!mM3;+u_6N#dK0Pg&xd z^{+^Lv;Nhb`L&$+T@v4H{Oc0mZ2TJ%->iSP#5e2TlQX|JXZ|qZPc+TOXD#8c`6e^? z^nAuf3E%YoWu3$~8=tY9`QsAb?Dn-@;+u`nhMf6~o&N`ReSNA7JAXVX@^86Sbp^EQ zESayxNt&pTGruVFF+@o^9oLs+e#eYf6O?7XQU8j}Z>7`mXVskfwVe4~GT&(Y>oULN z7`K|BA@hy;cgy@%Ivs!3lQX|JXa2CvH`n+;G}kKl2AenNpX9rLSts*5&XHCVjOEN9 zm-$Awuk|v&)#7&i*@m3?BdjEx-@f{Fv;8Z$-1|e?|LHggEhm@~{9BHy@u9^;{zUWn z+QGTP;FIt*ITNKM@y*7+oHM^7@y*7knlpch@J;9caL)X-g#WJB%;wJs;hT=nDBI|0@d>u~GH07N66$Rg9e5yI~;Z9y5f6zTCmOAyr zIrHK9W5mBtM>BC6c>WmSn~e`Ve~j?W`oni+h5p0VIkWALMflt2XB)Sz7Dirl%$%ky z5x!~va?bn;;hT<6HD`W}@J+|RD`$S4@J+|Rku!gY@J+{mnD9-0}oar z?WfuH8NLoA@lEdEOA3DC&Pd~fa?bpUf^RZD)tvb?1z#h~iIa5Y%&#l>Cgb18nLni9 zCk9jFgJA{VWPC;?zUltkA))`){H#V0T1;ZGeE9{!-&Zr!FANr`m@~hWGrycOzmhY* znlrzaGrucmKHRG<^&d>O5LV9og3J##JtMEhocX1k`Q@DXm7Mw2ocXn!`CU2lE%syK z_hn|6;KvaR7K`2ek@)Y|gx~BiG>-*#^42)twhe)O%n8DG9JBnBgg-xTmVcV?UDquC zQNmwZGRt2g{N-h{{AI#lSuxAE2;X#m76{*TewGN|bbi(d-*kR93Ey;n+JtX9KOMq1 zouBZmlfR39|H5qc`z8pi%P9%o?^IgF~MerJZoN>rv0^jV} zH{5^y=x^e`pZL^%4jJPzH69&58=ZWVR#Nr;rBPs)NlCN zmH*&{=$L`u->kE#zhy`3Q}{#`{Qge()%Swscyl3t`z~C-?2Ss3xpVNY;J_dDHRil1 zgt%A9$2svZkq2d9eIJ7sHda4fVmD%y1D~<4Jxcg}NqWkO_?bE27aSZx;=}!!Dn5>jh45_!-}f&#IKIS(`!f}M8^^_xg5TPIy^@dd zho8}czYhG1O1OTb`qFgC<@xX8XwNeDC1Ly8kjMx1V6BBS@cBZ0z~>vxvvm92n8^2< zIVWV}0P>@s|KV@gH1qr&eEY0R@_$nceks-pcr4#PUf(7@Q;B?tPn^SNpy0FC@!6cn zhxqVp^volFh>uX;IzC&Ke59%J2kUwJ8OtBLW&UhS=L`80@YVUVJ&~`li-k z$&M#!1?w+dz;i5Ned#J}pKGkJ47KcQbNgR(y)}n#8M~qdzs$2Rmh3*i8m}k(CgJZ^ z@^Q}AvCZ(;hX2Ci^S8w7OS{4U_(4|Sou;qNT`T%u*@9o@U^~RK&>yS(dctRfzemL{ zI553+Y#9F9ewzt{Ea0z=*Yo(yG?U{0?iPHw_Z>)Hn+yXXAMPoKH-0_g)A&0|KEkYH z?}5KIUzhkEiXWeAVKA)c@qr#a1)D!!Nh%awQ@!dZh0 zRb=)pcaop)QSwpE0zMX-|Ajv>K33WI2R3FgKdJvUDt^I%36XEZYq)-6{8)XP^?R+7 z57^M(!8cf9e0=NRAKyP(ztsN*72k_L6XGoJ9RU07Mw|BGkdlvL7Vxpy{4e|={(gO% z_`g@hFF1fhJ~Fb!|9wh6U_*Zg-(VsB4zKj`CprE%s`y^~p9zokf>`tItM9Go_zu?r zZ~x(y&+lureYi=*FW|VA5&mHnpZoVeqt2fTFI>2QEl|4r`Jj>ylQZOFvH4&45F)-Ukm>lgXa{+;rVsQBD}=Mw2(!TN>S@h7mv z{e}M9vy}f4C4UY$)-?7Hg;K%#KJl>0YoEJW!NpO(cAOlaepJcFm{@Ex{I%gzO@3_8d!;c!sTIGJA(_|qR?S0(X(SH;Jln1uM8g1<8X8(;nW zJQ=TVlb?4f`3UQTpPZk+r{Whp|1vb7(>SZ3`1yl(u!Z$)^5^%Jd<0rd<{yW8SicfK zIe-2@;va*lu~^5v{PEsF`|s^;p!MX_lpbh^s z65sasFV>QHe0{gyKKHG5a(sP{ieGR*&RP}>s;J_!Ao8Z4J`iuKV%3oCR`99ZjF@J3M=aswR1-E8AzKhkDreXhrO_B?> z>{+`1I;rI2sA>6lemI$bO3Al7;7=W%z6sCIyD*LHf4_R52^T}zlZStw&I^np4H_e^UPERQ%8%xj~8ZgF1L^6aU9l{DK1$qJO-!;wQ)d z^C~{aN_?nYhJP6USn>Q5^Z)S{{HPtoSY!KxCC-PZ2f^{R3kPwmu#BVsD|-Fqi>dg? zRq+{Qa=>?RB#Hk-IzDg``RpY3SM&c^#rL*fH=+H3_8H@4!#^lq|0*&5PpbG}3;6^5 zSUVH7KfsUGd;Oop_UBJj{Lmlg6BNwPWq9N5U&45maR0TG*gkwk#Si@hHomsvC+Gj4 zs`&o?J)!-9_&6}Xp#2f|@3ehbQt=BoJ;vXLS6r7^!tEFMHoW)id3=)FpFdOaLx1E3 zCC(4(;I&QspH}e;4ov9n-(kQnt@z3D|8o_e6D2;>F2lbdfA~m&e`5YW(}HjL2rt&* z_6zY33bsF&wQPUBmWq!&6(8H5fbZZ)Qv364IzDg``7PU@eP453Jz5n4G5+BFI+@^f=$NB_*!GX`1#6K(XzX$$vFe>sL2EX5q(?R(W z93QR1Yae?H&R>P~EYmfeDC~NP%rXn z{Ffy@pAJ@$<#_J63|P>A2I?{Y;i*vYpI2rM|4(yx{^TIOmG1v}z6IZg2_jAupDCdp z&re2t>VK{cALrneWPaSA@?TK$@gekNL2uR1Wcoc}Mj;kWnS4e?Lre@n?{ z+}{PE8MNYsuU{DIV<+KnR6ldrom+;Lt6sk^x8Vm_=;x1;zu1ERcP;n;vm(#PAG(jR z`qut`--fU9r~Fp_-%;|BirW|bAMRh!|2X`^?dwiT1ZXth_^M&)Dz+asE-ds|C{--wlY2VV1kCN}U;QueJ_{>%NLwz*g*8V?e!;d(8 z{d)d{-^%}oN`8=^Hbe)9vBdM|(%AaN{G5U7BL{ILsr~;^OMVR|ad0{)aeh31FhBA7 ziv#1x{Qs=v}#!%et81s^H)kFU1n z<78Np`O_b0!u2T!N0R!VKWW2f3I0*N=ug|v|I(I^T3AH?I6v-B`9G8S!1A}*0td(b z%<$ooP`~Xk@C&TqF!m^WmgdiYQ}Q{6?*(js(0hsaQN11U;rNU4f3D>FQ-f#3!8xe- zQ#Zr;dCyDiix3%#9?@E3X;ImBnhHeG@ zFBFA(y#9jzuup&@UH|=m68UidGj6Ey!uhcM#_NI4^T*>$*LVJhl8;c2Zzu4>`jVeN z3HiZoD`N_Ahr2KR+K2m;`6Zwk#>cUA8~x3f)D3668WPN ze;ERU>(?t$6SM;7wPtuF)`j&h@1MY12S1bg=j$ZC0~~Yw^%5U7B0j$J3ii)u_!;`p zoqxdd^GK5ahSYq7Me*V2hz~J!@SPN&jY>YBQ1M5__xleCd|S!46>O|h@q_$#a0JPJ zi;|C{7999P3i7@Dk3ML!6La{^!9Nnei|xLY&DE!{m*2!O{1Sf#Xf(Vx_&D`zo$wDI zK72F$JIvT(YDTLO8-!oF5$VV`Q@RP?qnqRR$b3IOuo)XDy)xfueEJ9mIrC4^ z;DwDHFOkJ=``h^Q+4{tr9y;dH2`u)5kHnu}@xT5V+h=kX1;U5(B+yowD@DS0{@ffJ zNhQLEi`HvQ&Y?{B%ZB4$$(diJe7yP3V1egf3HcwKjWIO~c>a~ZkM9Fa%%e#7t_f(2 zQ6hY!8yC!{O!(NzHd!i!FZP|XlIc6Ovds1d#+e471D7vVF*E1*vKh7+hk_#tSFmHX>}l=GzC6Z@zsH`EIymW(Gv=5@c;q+t`!Z+VOi2k;ju!ocy@pr;c z%nWo9zWMe+j1M!MKn>z=x_#&-eCC>odqAnOk)7=3`cxe%ux;4HjqW`&CR^qH{PfgH#|JR5e-Zp& z0j7I-vQMXIyy{u#?5qe%r0!oAht6w`St!2cqk)+RDO&>j{5e_%!>Qal$7LKgv7< zi}J(k;hE7KP{^6Tk?;$K{b3fy2}N>8uf<@`x^c|Is5lgf5;!-KL~QL{c3fqdx^j4_NS@v z--YqV69!(%N_P37bvo>Y<$Z!#VQ{Y`4(=g!7?BOEG7DIcNT0&itXA`NKK$3v3tJ{~Apn zR?L}S&Y3@$Gk+*&{&3FxIy)$|Kf7Ok-stgfBWHe3&ip}%ztH=8%ZnS%uV`Hkkv7hu zocY5!^Xu#YX@79fE-j{ZMI&c^PtN>7B|qr>WRKKP&ivt=`GaguXn#!ie};1A59iDu zWQWN1rM)RBCmhO|Kb$ka!lrf#_qPOR{gq4GdF2@8TXyG=7E{3Q_Ywc87Grn*(KzK7 z?9L%ArdUt-@Ov07#_s$h`29g4J_W<;m$5^~;`y^|wD*JGqR*FKApHLxTy^O@)XFJ} zIrB?||4GB&A1M?59~kEM5dM-m&Kt}B3iXfjCpc2dbbnnXXaB0?ALbA7*UO)3 z&i?S+P@#P`eSeNc_@?hKDiFSD|03a=_AlkkFB87$`=cs3^Q$@Y8M}*|zr6rYA2(Ml z1wZ>$g~+d<;G6V^{*)9Slm4Zg`DG>F-1VJG&irc5{4#Te_TTjNol4I9YR>#J`!vb_ zXxlR}RLPlN&6#hp(?b53zCWRuGryEGzbx_1-k(s(nP1JBZ?ThP`!aifLNRB4DQA9J z$v3(GQpMjKznZgunLR4BKj!ye`SPnd`~Caa^_ca=38t@ zXn)N2pY!FHa`rD1{+`zt`aWZ{{So8y|I>Ci08*9p{=lDk*;kfjc3EIWgaH>^6?H*0 zD~o}U7BgE649#jlBs9~-u&68tBqcLj%!*!au3a_i_Cj9kTDO;769V-bn3$$r*L=PG z&G4nPB=-M%o-^mnobP$g%$b?rZ^~t6cjhy{{hsIi&U4P3ndSBygzJx~ZwU7vSwAUU zf1TCm>_4`A`1}Up`lqOiedq6~IPVDrM}VKr@%r>PEzT}JKX9-?3;Qwk)Gvzr!_KxT zz2$%F==X?&Kg{gM)FR*d)%?Q)Pr4_bM6WXZo-x(y>p$Oo59g;3>+|O`zWT5I&9PJG zUmspir9X*>`AlzPh^gm)QM`TUT(|V^8dI+b`>*-Ne}m%NHahhyU;pIx={bD!Po8&e z>dKu9El*LOwuwHUJ`a@j(gr?vK56h-|F{w*F&%vF`g?@^Il_KM*k2&*_X+z;h5f9s zzf#!m7xvc)`#E8Mqp&|9>~9tJ2f^q3+k=WOHw*g>Dm|xo|7F>r`DE8jOg}lpr5^kT z8O&m$4t(!tOivV3Q+%&46mrRUPgTp6IQWI5dpy2U-M;x1_xvFy?5BnO>B4?S*k2&* z_X+z;h5fzYbNA>m)$ z=S5+^5Axw2|4W7ajIh5z*zXti*9rSsVSlBt-vd5(|C}T2r-l9L!hQ~X?*6k;*dGw~ zw+j0WYOQbo_u2(rijLW^UFrkAM|X3)4qOL*6U_M}!ROAuPS~#(_8Y*znK}PP z@VP(VsY%#x7WT&o`z^x$Sn#>WPb>Is%%9IT4t(zZkP`OWg#C8#x!2$E!u}NSxj)~p z1AOj$CJOtLz~|1V6MXLVYclxU^-l$#d-)y#K6m}}=WF*D&p$cOozxRpI)6{pkAu&7 z?yasrA?zo?=gz-Q*slklJO2h@zY%=y{F{XRX7IW5A0zCyfX|)(SYf{veD3_m3HvGV zQ@ZIfUfP8HcJL=L)~>1X!hQ$%-1$!s_9ueRo&O|ZzY~1!{0|fMCxg$O|KY;^6!5w8 zKSJ1_3O;xK(}evr_?^uCbGooU1N>>s^&cthcY)8H|4dQ z;B)7Htgt^DeD3^@6ZVe>pF95(g#8}y)6D&Ij<7!${G*ubKT+792R_r=a=jEz0-rmd zlfmb%{|(@C*MAE5+~fa^!v34U=g#NN!v3k?&-6wv&y}};&%J!#3O;xJ^TFp{z8Ubl zd1CjJ1;YM9@K5lbndi#eg#AU}bLW4Wu)i35?)={_?DvAto&OSH|8(%V^M8l1e+Ky6 z`M*=xKNEcJ{NE+)_krKT(>6V2sjz<*_;2u@ndi#8h5cpVbLYQY*gqS5?)={)?5_Zy zJO6Wp{d2+R&i}o_{(0bY=l?!o|NY=|=l=m=KMVdTJZ;lcRto#8z@P6uGtZUth5gmw zbLW47u)hX;?)*O}?5_o%JO2xX{fofo&i_Ng{>9*P=l@}0{}S-I^S@Ns?*~7_(>6V2 zov?oy_;2@~ndiz!g#Gp4XL!o?l*@(vkAlyg|Hp*=4d8R<|8Zge6X0{_|4Cv03h=q} z|CF%*Y4Ex8zf#!Gf#2(O4xTF;h5b$7zl*1APq|9i-wZx?{+|){uLhqx|7(Q(E#PzK z|5;)GTJX8^|D3RY9r)b&e_q(X9(?ZnzaZ=nfZykJKAtOEh5Z}Ae-BUDp7KRu|3>h+ z^Z$~t|7GyG^Z$ylzYTou{J$#fe+_)@{J$>je*=8({QphZ|0ej{`QIe$4}!nK>wG*{ zZWi{x1^x$k%J!6h7xr%fpF96sh5g&W=g$Az!v1#fx%2;yu>W1~x%2-IVgGyJbLank zVgCo?aeI{indcf~Raxc^Z7~e4YWHyZ&dv z=dS-b@VUqT{|Wnl2A?~h|0nD}5B{gTk;`-CFW_@8-xt8=uK%y#b1&Zm;OBT^_mmff z{g=SM#(QR-D=!QCuYjN9Dce*2ChY$meD3^T74}~PpF9752>bs8pF988h5duzbLamr zVgC^L-1(0R`zq%DeEuz7=is>#6ZYfae}SiLPe};-N$|PzuM_s`!ROAuLD+8upF961 zVZRxC?)=9H`z_#e=Ra21Zv~$_|8c^83j6`D^YL716ZYG|{|Zmpo-$t8?*N}W{|UnW zMDV%upCs&eg3q1*VZ#1o@VWCpT-cuiK6m~{2>VmP=gxncu%8Bho7eexu1pv9XMleb zPuZSwq_E!wK6m~zh5cFJbLW4Qu-^?ncm78U`^SLKo&T}I{%r8M^FL15KOTJU{7(?} zd%z#`Iv>xKIl}&2@W0Jdwx^sZ?9T&#(0gW{D<=v2Cxg$O{~Lt;Q^4oW|Bb@_o51JJ z|INbwso-AO#KVR6-fX|)(0%3n4_}uxwP1s)qK6n173Hyt|=g$A_!hSFK z-1#pN_D=_&JO6hG`)7d9o&P(9{WHPm&i`G)ejoVU`7agr&jO!2|91=f%fRQ(f4Q)K zHu&86zem_#0X}#B=Lq}fg3q1*dxib;z~|2YeZv0x!ROBZ1Hyh5eD3^L3j3?T=g$9p zVShFF-1%Q1?5_czJO2*~`)k4H&i_JT|03|Y^Z$^re=+#n`F~j0zXW{l{4W*u`@!eV zf1R*@8Tj1!e?-_{4?cJPmkawJ1)n?rj|ux5z~|2YZVTpF96w3Hw9f zbLT%S?B4}GcmBT?_U{ItJO7=+{x0yj^Z$*ozZ-n+{Pzg^_khox|GmQgec*HF|3AY1 z{or%w|65^yFZkT~?-TYP0G~Vm-wFEU9Ux$}Qg*nbLq?);w?_MZWtJO5{e{pY~v z&j0^}{Xc`xo&Wz6_MZozJO953`!9gco&R5j{R7~0=l`Ox{}TAz`M)gezXCpY{(lqp z{|-KP{;vxAuYu2<|38HNe}d1Q|Lem3LGZcr|Cg|T2z>7RM}_?c)$x#8(cIOdluFTm z-<BvmE9L*G2mi^&!ei#v6|U=R)%bPbk8~$U zGKF40m#*dFT82vn^(Vp49_{&G=I|5X7b+dulhX^O=u%BS@t~hycq4mMrU<92)%YFi zz<#x`xl4}}J$_V9f8o1K0H2r33XnjbZSug59pr3rlA?x0jN_^c~01u+JE zIuyWqX#sx>tFF{o@L`v_=4WdKe{9X79~cLItN+I}-%5c$u4d5>w1LmP4QL0y&HwZ@ z-x?2od(EOB=m0-#`lF9ERd*S9xcK}!p&_^|bzc2Kj)%~DJ*l!m0#|Zl^!v0wBxyMf{_-)J+^l{*G_lK0Q-zMz0 zgU`MGDs}OXinot9GwhJHpE&s3^(Tb=I`Ee==U)&0R%X8eeD3~`6!sgzAE<6K z82YFt@TW76|7Kx-oUlIzeD3^Pg#EGLUmiLVs{28!u%7~-JO4KDS27=_ED*z7_&wsd&|HOp-l(63>?5BnO>B4@Gus=uG&j|Yq zg#A8Yf2pva1%Fa?(}d7RtrYhA!RPLu>xBIr_|rm@tnLRJh5Z5Wx%1yD><Z*xx7Yj|lru2>STgAcWKL0ZTKKJ>VEvnOZ zd^NYgvXE-{)>!Zr^ZDnk;HNUYFW`*>pB6alB?UhB_-qHCIes-h;PZ~qHt=%`QmpyM zz-Pq?s~7egg?*(K`T7I*@vE4ypAz=lg#EOzKV8`G5%%W@`x#+>fw12v>@OAev%>yL zVZUG4UnlJ6g#C@e{(!K*RoEXC_HP#UcL@7G6849L{b6B$udu&Q*dG!0pAhyB2>UMz z`zj_p{}=XC!hV~upBDC~3;R97{v2UHBkV5__WOkWrNVwz*k38^_Y3>$g#Dbbzfss9 z5canU`}F=DeElVVh;mSMoZvs!?R`F;xkt3uU+Dcu;eNVyKc+IigU_9RgRtKSK6n02 z!hSRO-1(0Y_FKT`&VQ`1-wHl={^NxG6!^SbU!~fF{dVxV-+wV)*zW+JJO2s7{zUM( z^PeQ_cY@EI|6#)ZWbnE3KU~}=Yh|i|NDgf_k+)!{|AKqEcmA|_s^BW z{wnb2GuMBVo;x%2;+u)hI(?)*P4?0*7$?)*O~ z>|X&scmAIe_CF0icm7uj`#JD?nfvEPVSf|&?_#e1Dq(*!_}uw_M%cd^eD3_O5%#x$ z&z=8gh5c*6=g$9g!v1yObLangVgGvYx%2;mus;BPA9MfQD(v3?{(G3~|Dv#eBlz6; ze@WQ?GWgv2e?{2e20nNGUlsPh20nNGUl;bj0X}#B|0e8z6MXLcZxZ$g!C%4LKW`TH zzXkpWnCt&{VgDBJx%0nO*uM>Y?)<+k>~9C3JOA$p``-nhJOBR>_P+-{cmCfO_J06A zcm6*V_IH4vW$vFp683Kg|AWl+|EI8j2l(9i|5(`n3HaRk|Cg|TC-~g?|5Vuj8Tj1! z|F^LJbMU$I|AnysOYph#|CO*m1pZp){y8k{-v$1q%=Q0T*uNWm?)-NO`@6vB&i^;U z{%-KO^WP)v-vd5({`U&|_kquy|NjX4_k+)!|8Ir;z2NsV_s@O8{sZ8DjJf{b3HuL% z&z=8%VgDiUx%2Ual-1$Eu?Ee9L?))DW_8$YEJO4il`~M3*cm9tH`y=3gnz?^I z0saPN|4-mw$?QKV>^}wm70mTN4L)~1&w$Te|Fht8*Z&;&+~f2Ag#AB*&z;Zz6ZW46 z|5ME4|1aQkFW(oy=dS;+;BznE1K{VF^M6s;e+m3+nCpL8*nb6l?)?8I?Ef8n?)+aB z_Fn^^JO6(O`~L)=JO9^({e$3h=l?HZ{}A}x`Hu?wD(3%u{w>V?GbZfE!T$nt{Rv?| zDeTvQ&%J!>!ROAuLD+8upF5u>VZRxC?)=9H`z^x$Sn#=*Z!7rR`HvI!Q{WFU_s=$A zza9LqFxNj`*zXYbCxFkrd?$j>o&O|ZzY~1!d=3-#Cxg$O|KY;^6k-1e@VS@oRPed; zpC;_5!QaN*Kc@@(Gr+%zx&9-C{VrjDCivXTcNX~E`5z_hcZ1KJ&(XsEG2nCOf2^=S zTi8DieD39YJow!CpCIh_fIrCGKj#ShbHV>MbNwd@`}2hTlfdU*z9)mvo&Otz{Zqi_ z&gYH7{+qz(&i~EA{;9(LTfpaDzHbGeJOBB@eg=H*d=?1%3&H2k|82tlB4PhD@VS@o zV(_{1f4i{X3qE%~ON9N?!ROBZ9m4(@!u~tK=U%>Ng3q1*yM+Bd@VWC@D(s&HK6n1_ z7WS73`^&-SUcP68&z=8!g#8uZbLVr8uzxQ2-1)y(*gsF$e;@eV%lG}@bLam7VLuB# zcRnkH{Z-&|=YPJizgpP80DSJ{y9Rvj{68q{uLYkwp9_Wki@@j3|3kw5#lrrF!RKDS zmw?Zm|E0oyKlt4FtP}Px1D`wpj|ltgh5gIH=U%=a1)n?rj|ux5z~|2A_2A@0sD~0_W_}uwy6!tfP&z=8O!v1Dq|1;ooFW;-d=g$8cVSfww z-1&S~*uNHh?)*O|>|ZDBe;$19<$FE&-1&b&*dG9&JD;t>{te)B=l?}v|3+c|OW<=a z-!FsDo&Q&a{cYfL=krxz|7+lL=l^wK{~N;ozk$!ae7^}kcm6jC`-9+f=X0~L|1I#j z^Z$2Y{}y5YR`9u(?``07=l^YCe>?cx`Fuy%|1S94`TvKo|2<*<``~jg-yeX_o&OJo z{T<+Q=kp_B|90@X^Z!p_{|;gQ$KZ1>-=Bcbo&SFc`*(uRozG8&{hxu)o&SFe`#%@< ze*r%C^8F?F-1+}X*dGF)JD*`;|1R*k^Z&K5f48u|6MXLFy9<2o{C^|t?*^YcpFP6< zJ>YZaf3L8ApRoTw;BznE`@!eV|F^>aUhui|*(dBj06usAzZ3Q!6!!On&%Jyf0-rno z-wXQ>gU_AMBf|b4z~|2YQDOfvVgHZdb1&cj1)n?r$A$e7@VWDOLfHQk_}uwFDeONb z>^}`Y_ws!PeD3_8751M4pF5xb6ZZcMK6n2APuPE6*#8Uo+{^a`@VWENpF97Th5c8A{l9_Fy?p-;K6n1F3j42t&z;Xdg#CYl&z=A4!u~;F|6ky9FW*Dp zbLT%Q>^Go z_kg+HHMmlNUkCok!@6Ko|MkbwHB&$EsscX=e)bX1|1yUkQv(mFGn=~_s79SX_azQ~ zjQI%?;OlfaFG=tVqlf2N>cEdavZFnJJ@|Fe9v1mt4dB;Deq^*eHiECmDd(jL{6z7=~}=aQ!5CM9}B+T4sc#t!5_xBJ!VZTAxZxr^Mg#Bh=e~hr- zBJ7V9_FIMhal(E|*l!c|+lBp@TK)Ut?PEI4y8#}j*8WnR+uWt+ZQOGcU1@8;w`}2S zc;c}E-;z%aeoMf&V4ardjQFi_YBl7a!AE8;#qTIJWJxi2FZxa^`t^6?{W6z!=x3Oqd$Tj&Z57uA&`}pc_s@$jQA)g_-ZNBTH z&5h==e(*8+J2>9)w)?0tRrsL>y^{cgF zAAX%OH^)`(2ggq?eEg^ubs5cn=DExNC;!cSglxIGNYam~%#VuaZ|?6=Cf3M5j)NaI zjw6F`#{~G?$LEvaN1YcynV~o9z~??bUk^U_@%aYuxsT7&1mfJ{@y|UzmAa!xEo<)5 z$IbPMZ^jQTDzIdA@%A z8&zC?xeHw>e@O;>=a(<(oBe_Ew!TMQz^8ATaG4yL`1@`|@oH`0ny8;a9MHn*)9(zkElid}sNN zB&uJ3$Jl(cd`tKhEZ-KJPnBm>h_4q<1?%tFfZs=e>pRQ$HQn^8Tz^{wes6idg5|4b z(EMjn^E`^&T)sE{$Gk6b9x3b7{`(2)?B*^#E7Xhb&~W_Fuo@kXkJ8uwQ=^Zo(Lbs~ z7pT$S(f^a9`_$;Zil!K}|L*fgFICenVf1PL-RJx2r?Nk!Mpw3su1t-t>=<21*OQ|w z8|gmI!iw;f_TR((ooe(^HTsAety81-(*KjAd(`Njit?fTcb`8xPEBid^I`Dm_@~c@ zUwQQL_~;+wQ&-1Fe@FkXAKe!p-B-~REDrwYrM_%y_7mV2*FTNQ{!n~$W$Wn5_R*CS zM_1DI`q7oml`Y@W`8*mQeI!0D86Ulu{$D@3CqBBTqI~M0{?T#%d}{S$YOQbi`o=%Y z`s?@k*I&QytDj~4E#Wh)Uv-c_|N48eZ}}FFf4W}t`W07xpMU-J`^EM1tiR#D&ZpM( zs}A#FUVoKZeXd&E+@+^Ddiy(SE{8sLPmF0#`?EB+T-fd%|5@|>9~Uozny;r+%QUsP z-K#&ANcX5r&8!EsfxoFf!|FGJuXKB6tiK)n*ci&knc{lCV=Y(4gP$0aW%WD2=dOPO z_?ud3`7-7+5&X@qIaYrX_}ukR20y181>^Ya6!s5CU+-uzF5kn1eL6liL!I63?H?^z zq}SGDB18L#1H(tGJ2jq}NiWZ4(n|Hbd9nVP?&8rebbJi_)EV6>8F&57Uu;!*f5(Q+ zYkt$1tn3U$Iz9$I)i$m!y#7pO_0#b&@TvZBb>a0ds;vH)8k|AfFYo-u3JzUFS_m<< z&F6EU9~)CQ3j5cI`ZS)W73Uu*)QaxZA?mMCz5e;h(5#eNQBi><@7xD|JhwQdoI^|{ z9~bq9z2GM@YgqjZ_(^qjN}Uq5y7Kos7yP=B+vt?F@{fypkF&t9AKaBv*{F{$f4|eg zZ^%Bw>MsPpFiA6@=_4}h=q_+MTAaZ&Ga5BhriGx~R-ugCwgsMVFf-^1X? zbpK~uzI(wp{r`;ebw$0$ZtzY2XY_}_H~s(AsMVFf-+ACS>Hf2!{NtkDV;T6(y8o<= z`sniaI|KYNy8kfxi@<-A?mvw4lWpLSA6nDSng0Oz9l5L9IrG^9{)EhJtbPvsiE39n zXa47a-!gO!>-bp;{@C2N+c@iA0)A`eH>~~w@W-iV+c@XXUj={C(6jAoOZoLa>OHoC z-hUTU_0i?;cP;owWN%~jH-SGjy=y$@@qurEKW*N_~c|8?L`@0-QyZwCL(sWq(qc?0+}b}#PW?9ct+AGu{s2j~1}E%;r%SF`$A z@MkvO*1RuzyHW4)68hWgJ2;Oo{TcnWvsnE(LG&M9)1j`5nr`{~y@LL>t2;Q4 zuRf3dirZNIr_k@*)xmlE_BHTL|7Sctd;omY{~3?(JqNz&|BU_!_@@6e9^bnH{9_(o zJb`n5vL5_nx2>7LIe)$w{Mjq6X7yKte_ZEn6FBE5cY=TX?p>_;?*RXVEzhv#vmN}N z-uj80%Xbj`IgPU>a_0Xt@aI0ac%m9C-`Atw<96^*+`eWa=l}cw-0x5a z{!#U3x8E_lSMBI2_sD2JuebP|%eNumpWDvqHwJv(<=cdQ!`U5o^zh~1Z1Fks858i& z?cnrVz(2Op@eizwHvY=pYiz*R%l9>=(XT(B$KT(MYvlFEfv@|+6>Qy8_hf(l%j?f> zxg*UtKHDum=lB^9zPo+tyLIGRj`zZM1bn@Gw=e9!wcN;y_VWqgJKGmNe&-gh8eXl=^ zJUwjQOjXlYdgcH{<8r{{17T4QKS5for>* zjK0@@2Al8t(&n!;Bx-xd*&8gr$^Yq*=DXf;Rjk&7S*Ha2{QQK;e`CNm`LF7KdgOxP zTC-+ zcU=B_@SXj;4GW5EsO5SF{6hYE|6=o`TGy`y0pH2rY#%>Y`}ki7zMDUn|2FXR``3E= zSjRCwmFntLXS8?eoKy7QbmdOX55?ST>ZR&)iUs_1ez+Wpxz|*@`gwXB{Dj&u;#3<~ zJ6_Cx8s$sXe`Hu9;17EKpzFu0|IF89z~7N^0@C$6*HjJl*9H7R&mVOC8tShP`h(86 zj4O_O8Up@~y`0OpG2jn+K1cmcL4SZVpXPw?uC;M*O;#^e-$lm+{B(X$#+7?b#cTQ0 z*JYybPgiP%s2^8r{qKKIb`K2Y6XN)1A^6GUmVu!@4%smlgMUo2_e(=*KA%26&6iI+ z-kYNHLsDGNumJqJ`1X`Kz~`R^{;~136Vwo&zZ85^{|-L?BJjJDjb9oX;!0o9hco+^ z@6_b(FAfdx`SfN)-}o`(KgZ`^2>#LWZaP0X#x_3B0e@Qjx$&xp&!;y#`tmX3C(Y;6 z$znd=p7`62y%I^X!` z_E&&^RVDT*xJ$_a(=Kl!zI-e27`X6cV*RRK?TFSS4w?cnN#T#!(XBd6x53TXt zTQiLNr(2;vjEg_FZw6!iZLt38eCW(Bwi)PF@W;ltw<$)y4c6bbc=rS6XBq1Uzdhc2 z1DzSgmQNe>2VMV4P9N4^J$_a(=D!tuozDnk{ac|w=<%r*@a2E2tv{?~^lkm2m(jQN z2gdqm!uo6a1EYT{_@+NF`ZHnuHT_`=WB%Zq{=n$ZwDkv0AJ$*f9~kq$6@1el80){) z)*mk9TfWPoKXC8=?hpC{X~yGw`=S3({R0`s;}83x|B%0T24nrpp+D&QvyA@!pwD`I zbvg70ozMA-Z+z|#`mD$QmqY*2^{-^Ce>wCA?XTiozCnLrgt7kp(0}y!RE)=;hoL{1 z{g)Kq_!)-&VD?`aUtb=E{$TcB80%jE>#v!gF#5yboB0W&zW~->Ge7BJT)yC&`3a-H z0Q!U3f8q3D{WbFw#{7rDH}ez5`iG%EnEjVFzU8~q)*l%A=T2LH7~*? ztiPr|F#0>eH~oRpKMmGj(;pbOUpv7!{ejUx&DI|{eOP}@e_+giC-|m6FxJ1*)*l$> z4|||L==llf{>2{X58CJ4zt{u)LC+64_b-;f`m5{b+`rfp^jY^WmcaU}^WogT*c0?w z_b-+}f6(=F?q4i{^;i3x`xkqHKI{I)9_SBxd~)tz?1TPb_AmDGZQu7ne=z$OjOTyu zgZ^OlFBt1z3hS?#KQQ|Hz&G;;Mt>=+zh?e$fN}YPZ{`n-{!-`7W7%?|2IH??nrKVVCNv;`E@ry|Cx~7{=nTiKL0jb{ks``Tm6im zAA2^`&wc*wLqUJ<&J15Z4?#Xu|K7XPeEwZfzZswXj6T$F#%CX&zspvChS9gxpXT%L zf%^6Ggg~=YHY(?-#CrldXQn<@;su&H9z)8$X+D`S9^79`pw|-=BLH7GwEz5DQ#qrb1ixMlrTAu7O3@#K^1Z*q_-VfUyKFw= z@||b%GkoGjTLZqSpRqq&0KTc8@%Z^=;B(i%4t(zVKMKC7Kf^IH9piHFP5q3=$8zAC zXU+1}KVb72`{$s|&+*m2!{!h0`5Bw9l=Bf`3{MkN&-?zqPg~=xmd8@B#rj*)OEQa# zpCFm6=F`yQ;Qv?R(<+(T*4;NW_?-pqn;V;cqvkqpvazxF=^|cFfZx_ItNpPq+k>mA zUa2JdUOw68z8iAasXE$TnoD*0)PZl!r)4cYLv{JogFh#1)9C&h`QIk$KV!kS*6-v~ z)$(l>_QwhPDPg}&*l!p1#|!%%;1~6`BZoSk=!zZYt`OC&zY|LOBQ^UIOZhiGS+hS0 z{06nkzHOC`R{e2hw>6p5r^sAje z9|L}%{<_r3$r|cE7JTdcxn=FcJF1-j$JBcN=L3&^&Axs2WflEKJm7C*^%DXA>#Tk< z;GgSG2&0Ek;+}N@e+8>wkN&voKMUUWYc!xgI@#YAY!9m7dyN6Vlhtnmf4c`Xu zSigAli3fb%d=dfwaMpa10l%|?(NX@cbpd~J`3F^Sk0$Wv(-{jDJUqf(dwhSNVu4Z_ z=Rrd;`kZg)(oy{)i7CIo(dKtm@6)I7`|2OI`SYsx6X3^UmV6df?jR%k)mLACOx-y{ zEo|@7#p**CtF^~?iK)ANK7BqX>m{Zh^!dA4b^Stu-@lvLkEy48_4{5@V0f-L_zM}# zVq%5*p6~o3H8iV7tth@nZP)wI&n@mzy|tOekM2c3vxe2rps%j(QKuAFP}}u$(I2_3 zNA=fc7C-td^apqKsBG~)YP)_q`q^h#{e|eK>*vr(eQcNW(BC_2j@rP+t7Yg9ES{sB zuFvu$XQ1D=hSgt$ernChoc&=N`a^5xa^^pPe(vhIocV7-KXV(apF>~mn#-C0AJEtR zXFbc%G{^(!>;A(yNx27o-G3PUyU^GDXBl5UkD;&o&lPF-5<%iJOpccy*6Dm9PGD&>y;nb^Emx z{oJ?baQ4q7=x2Vz>MuZFJv)bU{`^(+hn}6wd4B9x^m7d-a&F&0i+<)PR(~V<>g^|T z&L1|Qzk3a<-;e&5t54({|7+3jy^Yn+qTjgdM9%U53G|u;B#zrB7Q=laRk-d+|KZ{l|Zzuk+u`m;X!X>--t#w|_=o=g;W>34NVE^76 z{}uGNT|JL;e)~N7D{f=;pF+QL*F4Vo?Q7`k{?9mnK7hXN|BUnJ=g`;vpV1#dU-y5; z`STU%>+!#ZZ~U)EUypyr<4YH#ug5>5zZ!i#{uz&7-HHD0XIS&!f&P~IlQ{F)j(+bf zR(}xv#>FRb=KnMFpIdX18sr=Qx1+!P>XXy}pZ{I-*WSkJe+&KYT_}IniU<65HM@mN zS1JMiarL}@68t7Lv7WDbrRu;xs{ZWuJ7)K)9X&kHQg87&mv2MBKewIJZw&an%eM*r zhO;~F=;6!1+2V8NGbZ4l+rjC#fPZYG;~!YbGd{-#e7$^MV;cSX?<4#B+i{J&{y6Y; zf4G9Jd+Kvq{Pi!dKfC3QG~f7axA>gnXFT}s_NDLEk!v|lrRfOxdiic&*nca}_?!T~ zvwh+7CxWlX&$7erWIN4e68MGncktTbFI9ium78v7z<1U!uH}0e`0o14#Mh$A8-5>;8G*F8V8?MLAY`b$Y;e=2u+)jDT;(&(a>Iebgh-_vTk4PY>s6&%ev! zoBSWh<~Z`78SwM-A0~fRz&H7y(=%A@i19z}DDd6>)3)(D>|IU$_!)jA383ieEpQFLgZ-3eRW574t-|2Urb>On>P>Hf4|L9oo3;k#C&%?_% zPijbvjcnQOINRdu@!z+97R$)6kWP5!I;pB}kj zI9L67|89UMT7CDY9RJ?we}5JS=`(&V>c`c6zVpw`=STUTzqT6-!A~UD4h;3xW)?qs zvCU5x-=ntcXW9HzZD#SKW8j<5*Ba#e1k(lJH^+P16yx6qInCw|@zuZ7=I`M1+rc;E zGgrKXYP;SBzR5q$_xBkmf^X{2)K+uxqbGoG>L20De=_*o^&byDcYm8}^BMa?EBGcK zM*leQx%!%C*OTahzF!r}I!ROBBo#1oVKgZ@X_UEzS*TuJ|6r;Zt z{D$~*1L+K3f8HAN&#$Qdfed5+-x~M(_3_<%XE4^^mhk&JA3Ac#)`7NyKPJAmO)>gy zNq_x~@y31UXBq1UzbW3mm5#iz<7QS^vJ|e&|0`KkMJ` z-VgnUeAd6;y&U?3uAlSockd7Stbf06IrIme59iEJM@yTK64`%;}vHk_H{+js- zqdyG3nV&HF3t;^<^OGLN#FQ)_)qTzotJh`a8il{ejUx4c1@N9~9&G0pIioM*lQh zf8g|C{Wbl8G5?+5oBqI9|4v(fc!KZsojuSW^!y~vn9m;Q58BTRG1d?LLC+6oFxI~W z)?Zye=l;c>pwGI0u>{s%oe$^!#h#$gx__|*`h%{YbN^xqtiRgl+`rfp^jY^W_CSBo z^*;kvHqaX+W%v={>E5;EZBecuHsz2!TNc}Pq6-h5ypHr+WO}(-}s3Ieb(`R z1N7&Xrz=+`jMbT=6|>yFLr*H-Dd<@%`Pmfp7BJU0cn?kG{>8 z4`cmjL;c+6pF9-w_wLLT|Aw_)e+crS`uElcjmFNOKDIX=ng?*rc)pJeox z!u;7BpFF_0e8D%zCmH>vFuyggUvT;`zct4v8S~!P0%0A z_9b0gPb+@(Cg=}l`%-*|8n4HL{=iVWMzrYReUOj&5o3Q&3i};4pD~{-v_t%IPJv?Lc^`Et2y2R8gzR$lZ{QbxDk^ZNs z?(c8L!MFbXNApD0{r$}Z_=WoE@8>Qq{tc?DKUvDZAy@QCsnz*);B)6wFYGr6`;EeW zld#_`?2i%lTfi?`zpm|P82@9#{bmloHQc{v9Yg&w^|1f_(d>VJ7Jcr&KZ`#1-=9UF z`|r=9&;9pj!Ds*bv*5G;{aN&R|GsKWJqF{S`|rb|&s%>YP(SzIhYi$UJSnO9dR?G? z-oFnUQ>S(o|9#0pwwb5%tH*`?G2l1X`hhC2#9D;?B=}v-^(Vle#q76%&pm$Hh5f_9 z-_AV#rwIEU!v1(+U#at^s8#Js0Q;0|CdC-S4nyVUCb9n@Tk7Heh2xp>8C^YYrj83cWYD~ z*+ZI>b00^y`1g>1W`DXxB^%@9_h{epxvF(G-_T`zr~Y&c z)$jSHBLA0q^t~VF{e&{VLLeWV|MC6$P9^hc2>MB<1?7E8zBvEXrdT2WGcU^|P5$Xe z(v(l!l7A!m8KshXAm#6S0P0^>ynN@bPt$!HXiwV=$|rbf3HtdvrOm$wA%AcD>*f0cXZh;! zlMWgGW6{qVmcFFTm6HDbd0%B8)%U0T1HVEm`exbYS222q!usW`{a*cg{c2yQbpEQn zU)Qhdr>5x<{>wOv?;oFfbn5)am;dXoqSy1)aL&( z9(}WX^#|yu%^eH<*~#a|c*^MydifrInWB5T{fCyX-`2M}EWXym{f+{FlSgR~;Q4 zL;5~x{l#0qXb_p(zWUF+Eba7Xw|;XM-SH-9sDCxN#$%t&02hL^k1W+uhajW z>S;Wf{LhQ&?fZ={rDMsgYJ94zXGyv#9S<}g`b}nleQ9B& zKP%v??%8+FzO%4=odN1@Uwq5=rI*uA|LoD@Q^hUo*HP#z?du_s)?aA+l<*^rpKkQ2 zKTH{%GU)lVV2ihpUj4d%zVr&!pVa-?S-&jxAC0~)nsm>vvHoMwPpOt9wXA~gZeNPm zubdg5+f4qte#*az=0BGDj}7>G{SErI^|yQAZ@F&_ACk|UpilYm`SSw4-hT<^ z@6RW{e{|VPlux}oKcV@99@qZMNmid$GH?C0jnDl4(f!mPwC~OjEk6A*XUJbAlRXjZ zzx}23X0!e}<3DNf-(dB_>mP8pzq&u%@Daz)j~|j?MX6!dBTqNsjn_sd(qy!oxp=Pcd-^Zm1l_Ae~?zd7jB0FB`5`pNl!K+`-4~zX~d;M<>`jk)j`0@PWd^-B6|JeQc=x6l$*O>L{ zr{rHZ`xj3A%ZkV6+!xc=wdwswcmG8{)_+-G@o7#&m$d$(4v??cV0ZrS`DXv6{QmDE z^mR0POnCjl^|B2b z`t)u8@dy9>${YXM&mVtK9jhrHef%LEc!D#~r`nSp`fkpB-Tn8`(edW7KL3Ha@fNB- znOc8ux^0Gae*VsYpLBhbQepqGls|7tn15!tZ|W`hmi)c?!~J(zd?%rNK8Dq!)auXB z{UMpk`icqTz(2KO-^<71 zzc=91_%{`#%~!pDN|&ma@B0FNW5vE#zp2Ro<^2J_yJG(qcloA+M>swZ@Ovuuz4|SF zHsH^$*!Sws__NWsRtEfe75iTO7JpU1r&nxD8ENx1%J|vr=5HS1|8gPvJ?_ub=1RWp z!1&DX-|5$1`dewX)US`9>%YYjSim1b-(ktF#5c$1t^SA6&rpB9g?KYZ*K-GVe(TJy zeEpyLv);bz`E52~j{oZi`YxAPeCG~klBkaq4Q4p-1PFlQP0n517lu)Tr*GKH{GH}Mpq`x>yLr_*M<7dDDwRLvuc0Hdwp}g z@%8JQc|U)z!atVd;s`t|(t5*q({`%d%Eu=+n{@g14R|2X<-I=*2RK^b4~KNi;?w~zl%pr0|pP(qIX zSm5|@{`G6U|8=H*eVO(jDW875emMumO?B>61X?pVQx&Sx-GUH$O&%*c*tiM;U<-u5M8KBoTg z{=6x~udM!X|Ei!Ltv~qIuW1)%|1Vm6M=JO) zoBEykmgnpKTy*|JSp7E!eOkY?UGQHY)%DX%jxOMP=Rbti|0VQuhVj1G=2vF<>h*Wm zD_Oc@V`IHDzjbDi-b2lmFQY%;|9OReV2FMNeZwbLxcRiu^!9bLemQx0`RL_abpA$I zK3}!?S}*cR*W=T&e2dQC2wT2iN8gN3y)5&~*Yuyl^2PHvae+|`t8Py*cob;>QiawpD=_HfShx(6`zw>+h@@ZW)U7sJdi2RGj z*!|nk&yb(hmgD365PjYM7nA>q5dYig(;frXU)-P3FIWF}&{z8P>q7nd{Ec8f`PcXJ z`E*hJYeVY)F8UervjyLtPr=vu%p!k7i2onxr-Ste^C|c`pHlUIAARrqqQdymzBhp| z+plk!2GCqG0^z-KzMfMwK>ik3eAEKXj&yR}im#lwB&}XgxN9bq# z^}FMzRQ_iCgyeI3(D&6J!EZcDkIxYQ*Wiz#wb$8=HTg$AzbiY&ety^8;3sJN)wQFr zeueFSsr#t^zm%S?&mT*wo+V-aF7z{0f6@BeVqP98%nz5vGjzl$cz#!y{~PpEdUmC^ z<@xam^Z(-hw(YE^(wpi0(naHG|7c9wdVbd)^yzq)BcmVOzHDnf-@HD%XhPQ`di!hJ zzTAU8<)7B^d-db?cgUNc)A@U8o&Tb?@ci!$`01|hJG$?1yPWRN#r-E0A5zcLv(xdV zPReJ-b(Bw%&cDhYKEs;N|Ddn5Pe6Vv5cIwMi%!bN?7t*w{F86p{@xG%k#xdnk?)Ov zcm4I|hcrK-eBv#7d?qQM!|nTzzXg9xHGW69zZd)ynf-m>C;Yy5{$wE^Z~3-te_%%b z_2qd>vLXA|4}i~|&+oubq`I8*GxM_)`}i^2Up+pL)a!4l@%bS7G(64unR);D!1&kW zlYH7g+IHsZBlY$@KR&JN?|$@^-!DumbZyuNVe<+Qh>-#?WvSL<6{S5`|cedbB_Phol778{}cM&`N@Ux|FStgQ(V94KWbb1pQfAf zPuoYc|6 z^K*;;bkL{yZAE@z|H9%w6ZG@vZx`|@o}cKIbhgUx9}PV1)UWf`^Jk0yY|y9ri{^*W z|1Eyw%o6_d==ZoYAAkM+{+VCC-u`cX{5V6*_w_FU-@pIj_Gfqb`s(-gAH(x`A?W+| zUn2Ole8c@0(NEF9PhVxyegF7$j;}h8 z-D}1V^*8P7^S8B6{VhvP(dNHw@tyOxiM`a zJrR$;>3qE7hxz)0!(aUqeOkYq^V{>|(>wlb9_)X8=d35a{kzqA|I3ok>sH^NPx1P7 zqq~0Td@ecP@hP7${~-E$d}`j^KKi%sh5B_qXS(~3J&te5=Meh6CZDY9mwf$;{Oj8F z>uX()tPja27K8V9WWs#&`a))TaXvbKI)AmE#%EYQiE!V5h58-e_xhdAKVN^CpG3dX z@uSbbEm40R`sVnpKL6htpO1O{$JDR-Og@GAmCk1t`C;>)hH&4>2mDmAuh(D7M<3q{ z^PAAu^TVvBOZ9(${aq#MZ$`h@_?CR=De2;?pZbGazd62bS$|v5H~FWsZvBP)4e$4h z@(J@>1HPW01efnpBYZ;lU#)!&YO%H&TA(?34F36>>)Gd@G=A0PB}{gwD7 z=g%GJ_lAuhXMBd`Z;qc^#{Yz%@8)kncl=xPah7l4_`JoRh`xD!A-H~(@Xh!MtAA3^ zr}``MOV&Rl;Oo~PgX@?3`nc1d3-c@8pBK~m6*m9r3io~E-}RmTmiP1hXK{)7)hzV& z{IG0)_Sau(es~o6yE#v zdixb`r`JbxK2W>9c~*!|^_zQBf6)IHd^3Nh`Gc-Mg8y#xdo-tQ&(HTa=eDmuT)#e@ z)9)Ye2tWS0%;Gx|`ucg{{L&vd?|=7v=Ptgl%hAstn<>hl>Mxw%=zIO8eVtQ(iQ~6t zTYO!4v0r?Cqvz}Oi}Kg6-+9M}eU&>m-ed8D`4`piE?>QVMW}y;#mD@8^}Bw=`p-c> zqkpet*3AdEFW&ff>!}z+rau%uzanh=lC}9o`5g4-Z{R!m(3uK) z`G)t0l@`A^AF5yH6zp&Le9HCDRp@Iit-s{^k9Yp9{vPz7>n}5}|CW0H+66&B+VNps zfByXurOvNdgFf{)=kpoN?u&Q+gZ1+n=1w=~nG_tN<@iWYs~^1(2_!{l>tG(Z0z z)hFK3#q0mNe(&=W$WPeMUs@aHyZPtGPgy_Y{GSU0zW4qeQ*hz+_fqwTpI>xQxNq_( z_~vFvKH>hwA->z+YV|*C@tqOmjejcKvVY_(U+?oP%=uTA{(K4g8J$CNk+*))^3`YX zx%)56-2UUNztkTZOZJCLExy)^ee?M|`df5Cza^vlf4=`XckzAgN8b#S;`;UH=M?Jq zjepv{>-xRzyCt7>7T;gL?$3qOtI^l>d%mx7=f-8|XT0%m?ttURmrv2>hlHJ9_YsTl zA3q`QFU$7_-T(FHhlGuv_2{Sd@dsVHJ3f8yzbm}Hru_*0^K$gbc0QlP_5J7nbkO;| zh57kP@AFA$`)GZA`J(~f{d|(V|1UH2Y5V0|oaH+d_((N{*kbxr^`1#(?jBeoJ)U%g5qx3i$5lw?y|#E#J)n zzcD{@qWfO`zGR#mp9%QxmN&ZZ)t?T|u&xgHJ=NE5@vjN^?&r5uQGX^F(3XJjett`I z-^<_Pe>UK|pWhPQ-&~?Ud=C8#jnAz9JsrQr={!~UpX&lXjn4{wFCSeNTs|N0X?$k& zovNtcGJdWP_%uE%^u78m{ucs1jn4}GTioTFp-W>e-Gp6pFta{tK zbQ-$;Yhv_~md-~Bm3wHUpT~oKt5R3R6n*8m#MIg;s;|9E?@jCa_1=p9OmgS)*U?{H zNjG2L{a3nO)zigG`lMd@cuju7;=fv`|Mg$dQ;gP7f70R?<&*ahRh>_r&DS*-Uuvko zK8pWn^~<*b{0B~0@{iGj^KaUG#qO@BKJv^zrp^8B=)sTwpz3@Y!8fs(<@=AnjJ`^@ zKBC8G_4zkh{8#@q|5yKZ@SA^m>SLE2{FU+Vue$zbi(fQ;oTXgD@@=*FH2!ZIz48#* zN4+i7mg|g|u z&*t^|Wvik8k5q+gJ8zK@Uo>yx)s?H?ZEQ$8OaeUKu<38cufD%c1wUUu{d3b_O@GjS4gGCen1AK{)Ss#UzpVZ0$A3E1 z*ZtqwzSQDRxA+v!ul_Z9$jl#pMK@}h-_8KvTfSGAe4OnUjemNYs@C5l!6%0bHecyW zette${rs&f+;`?zSJt+CXWD&de)a052Y*GsMJ?lVmfa^+Uuw_iDDa)-JB{YI_kZ}= zk3B=<|M8moTQ~To?EL)pDLucv^2wUkucIx#Grv7VxRZY^^PgiZzWE)Bztqqljs^dp zqwg^NnfkvOpEv2}si8m5M*mlO`(?Jj)PHFHsr%c(eDya9*H6bcg7s(k>TeRRpN^kE{cS48SbsCrzn{)w_y%MD z8H4pZYv+i+Wge*di18Sxe>!vjX|dElP}KkF*V$3a`r88a&zYmtHyQIEYpH*bvHr18 z|GpmH`sw(dfBaM61B(jlZ>{;aLjBy^FFJl0sDF^L{&7%0cmJp3lm7Y#X&#uP)bkfT z|EXpCr=b1?%u?pF4j#z6$lXu-4xW^>dGZI)3Y~ zU(esVi}I(N^Q*|+eaLvIpL_lmQ!9M)^C=Iz&&>009DN?vQxf1iXK8ysuK7wM_}uw4 z3H!~${uuDb*POT?XaRqU|Hn1o8jC*j_-{qO=8FBmIP{t8Pl2D?(%rDaKe_c6RN<{Q z@VVEocJwQ(uiV|ogU{W6VrtnWb$WYO9Tno9zfrEHN`4*>_?0}m{CyL`eq+F|@<3k5 zuhJy!Hw*h?0)EIZTIIJ}g#EDrpLhAT2K*|62zl7JfX`ch3jLQyr-hVK)wkQwul7KB z$g{Tx{E$0V`R(z-ezVH@=Fekj{?B=70e@@zS9?!m-2RRg_M6ptqT8<)@Tb(Wvu;^% zV}*S>+T-7Uq#E?=FNHlwv;SCh(^6!~Z(ZjbpGlfPbIze-w)*Myi{gT5krdx7SuOrB zrey1n+v=y|Cq)J8{r94qSYhegapC&wuzr2~Cs!!9*5g-oQ2%}!Je#_bGs=p}i zTI;We`v1mUe*@I7M?_>-CU zf9up0qT8?ffN#&S+V3_5eBSw|Qd@lEhkO1L6ZYf6ex0yiFYGI|S# z3;Rv#`N?W=dzXGmRv%w-|N7AoQ=@Jc_QwQ#^Gm3V^YJ0hjT*kT1pKtt;&(IUGdAGo z3wPdrS3~8_Lt6uW+Wdg4{&C=EjNTYmO!cS0Pb*V@oNIixfp5yEITqKY9sGFO$ngx* z_!$p=e*I<3r^D{6ex_p(69T@;XK39Ro+S`d4?};`12e{U21-1{XBz%00e;%7Sh1_P z{3Q644dv6u6Fw<*0bf_%l(2mkU^P!#AL3VI*&fpXzMH@8zSVrM5qu~A!>XaIk7)wm zX>A)B$IoMv0`rGly6<^wHI;v}PN6^8?9Ndt*Mg6z5BON`#7XB;M5l@@$ZOzl0wKYpD1WP*3C>N|0Z&$xM~{v517rgBx) zYI{%;{lcL=+ubYvUY)pqCv1P|18rMU16<3XUIqOriqCHd`Wa3?8T9Gz4)N6=5Bjkd z#{3(DK7F7YU;Rx1KU47-FZF+H9MgJ1s`cD`3m!N+JZ~aH3 ze;;rDedxdNch>QFM!@II=R9Gb{uZ~dKa9TcD(m=Pfj;y2r}GnzP|Mo8Xs6Niw@h2( zf(5CoQYxNq+(aLpyCAhWP1ALK(3K9&<@7fzy3qLp0l%-~>X^^>M925GMc((ruOuvf zq5f2SLF1-$;n9`Xp9G&Q)_jz@b87MStG`ez%e5HzITp2m(EM4n{sj2k^(!^cSN{`* zUybEjOxTYL`w8$jRo(}=RXeot<3$W9enQk$Aizkd^?5x4q<~9tJ2ZjBch5a4E{*Q$HAz^f%Z2%=Ru_w|;$7|7W=jRhwHJ{5A_t->TXltIqJ}qcZkqsPen1fUkNk ztJ1PPtWDS-2R@ya9JAF??f2TjXFfcm#s~dOwYAzF*8x7=XQAzW)qZb6(9cwB*&a6$ zeD3};34Hx_&8)4ED!+F)_+0007s}ZnynpTYtL>A8di~c@%I|Y8-!}01_pfE^?}7Tc z^T`PNeZqcL*zXtibHe_BusaZZ9DjsPu6>K zhAZR2r~0QeupZF?KK&qM7u9=6rB|k@742R6?WP(|sB!A#4!V-2|MX;cREtQ-QbR&dcDq+yU^dY4ftnk z-&ww=(zQd==x+{u!pld0i!QO|8D}`xN`9sDR?+XG@j0;2dDIn3JvBP*(7IFTUiphR z{*z}!Sik6P*68c;Nxu0Uf(#W(`K(iFzUz0Jd~zz$aYcmjNg0OtCf!p0lqmjK@ZUyd zn*5#dKbvlv{0rm1BVT`Wca;7>{oYr<=R4!y^9$p@GN1OR?Y=YqJ-;yiJ^z>}{fBzK z&wsa*Pr8%-rOO6q`BEg_`0@PqGa@WsI^OB?&nJ}fkK(7I`0e25^LPFArhZz#EcG`> z@#*ubvHn<5{j`43__zDBqvTJmz~@u`QT^ki_!GdVe2V>2`LssyCxV}#KMd~lhctz* zGIZ1F4_E4&x@ma*Cmtn#Iv(T8r{Eip@~_ROaqjbv^y)W0jeqpL?aSmS_0v1`eLnTm zd_HCU#wh+|@Q;n|PmSUq4nA#TE1rf)2GrppbY(Y$h013{LmJw zFn;cf(0`5y`nrDAr*);Me!YF9{`LWLyJDYKec$rUj~~~k@q@mX&*Uie)9>!{^W!Iq z-x$SDgP$KiQT(Y<{ORE5$B*k<^7rzY7{#9fexW~P^#aY%f5rWWZWhMR84<=0El*$m z1z*#8{N#OS{LszHe42*%{QUT#`BjE2z5PYs%O_I*nF)TO|CIG3^`BYb7y3_GKT`iW z3j9LuY#O<;X~e*8r7BlVx-z%TS4lTUv9So4Y0 ze~t&A#!r`Z`$CP}xp?Cz((!>4z^CO~>=(8#p6@N+DN*Kcv>WQnpO$Y_za@%42Yi}O zcbz=X+y0vRNA){KgY`%9=Ymh;Cu;raDD|HRK8>GZzp(uZ*54V$rzm{+)ACh6Da=nO zALsZ?KA(!`Cns6_qVZ|*z3~&NKb#Ccji3Dd&5ZU^ex&~J2JmV5M)f20hf~0(jQ$WajsN*3FIv8yA1R+VflvLXxc-ZS^?Us%((%tX2Yu)G zn<-aszkK=7cRfE+e>)X?8vn&Ujvw;9d?NL?w}4Oi$E^7W*WXC}=dIw=_>WqDB%g+b zuRqZEkLpM2ZyE4u{1^L{eG=|YyFk^Zx8j0#*Z%_um42qZ@m_u#%HQe73Dud$IqSo zX`!c0KJ>e_Q|~H!SrY0O<>T|`x&GuR{^@p~=FdgrbEJ6uR962xLjB@=s`t+b^^3-* zul~yNd1t6!oPTlsmHB6e_$d|Ee{yEb_}bxw7^5EQ?R;FXa>FD|h`;LlOG_ zyDk3NX8UDgpa}ByyQ!!S1!!9LVxgW8rAP4M`PIX@Q>m|YA^t`tzdppD?)THx*544~=hN`=2j5ICO6B7ItTD`Yo*>MR zoPU$urzT*wkDi|&pSrAgS7T0P+ycw|+idf*b$T=$M5s?^7U)YUe~NRLQeTsyKAl;hFD3k3g!=13eZ8eG?JIim zvfQOU)Tc9p^u=C3{b0;grO#U^b7=_m^%jjTHTsRAetr{Z_cO^P)$h$IoKkFGn?ij$ zb4Oq7KK+3Fw7x^>3;q4dko7nJPM8|~F`<6`m$&)3u8qlLY-*G5hHTc_rFTR$$(C4>=_;luuzS#U+dN>iW{Cqb)GxRFB0pVf&2@e@CDbps z{fg!v5$c!Qe#NKe@-3>=Z!tC0FSq?7Kf?BFTBu)c`<0xUi?IDlhx+BVUsQjD?bq~B zzufkV{0Q5x8KHi;?N_w=j|}z8ZNJEmu>I-+-*mN+;^Pnc_{;{{BF@*t(A}@g7KZ1V>_-3zbDCgC0wlClG z#*gkldi-Z{$5DTdF#g{NzS+JHDZf9}=j-tq*?$xIgS62eN_jqvAF4n1S<2t|x%@6p zsX_E+^wYflsTO~v^!V5HoBk7Je7?ozmmdFlKic?zEBaa9eCAvIlIw3p`DD=1fMqt^Q0hJJ>&FO(0LzX<#U}a``7tH$aKHZ%hGUP z&z|gl&hexCneVege78Tq@}>2cE*1Fiw)&Hol=Rh8CLiY%JoAj9UzUMyUR+S>FrQyI z{*x|1iRPT!WeeX7Tw8AUzp585U2y*~ZN6*1MDx!E-}FzVwubml{uS(>z6X4hPdX8! zeDu*%Q-4wa?Robs>&E+QnHrM^$IpIFNb+J_a^{w=mJIh|q z4fnfC`5WWp=MUkRdXo2s`^S{Hg06r?;Mk`Wfx#BKX;Ge_jbcXX?)%VlVX@thD(w zKcw~7*?Xqrx2=W#RCfwI^9okv4E?-)Iss0H52g7}* zyV!kNf2sZm$N$%c`_9^9_thrtJHKJ6c+`dAzViaP-KX`J@`>PI6zq~d)0#MJ92Sazw$5fnL0wgTx|90OZWtBN_a(4?2Usc6PsSptrBcD0Q_S{lT*SF~cV=hp?{$6MIr=r*2jJ_7KQ#QJ-QTro${$IFge?`=M#-i`k|Jh<+DbIKFkLX%V=`XUysOF}-}9(=FU#(_0u$rLP@k_xBa$PiOuI{1v6u!cV87ACH?e zpz~)~>vtE7PMexbB%J)6r_JX2vjw8$wP|6#^C-_ReEtvpAe-yWmQ)KrOb2}DXGQf> zf2+R!>0!R}G`fD{S6lxK^vTt$u)F^10TffT{yO8wUF?y^&yhC2cwRvMG;5=@uh4&b!hH9|A$$F99}0EdAIu5$^E>}F`X^d^8vnWc`p#`z(*med=lbgR<==Tg^}Eks=HItiefkjeQvQYmDqY5PfBaU9@AS|2 zI(M;;pWdkT&$s!ezm@Pe9O#W&f5zhL4M3e*=+^J_pThW|8PHIYR_(|*hE57Q)#hn5ud^W!hwUs}N50E+*rf<7kx4;Jvv z_EUO&SXR(C;^*x%ZS2Hh{`D2XjN17 zFZAKA^zV_uwb}NWtNR(1p!W|>3!XdNzlj3=(;eHjgg;3Czzy{{LHnVK`*GEqdhGOUQPeDFyF7w+iCuxDx;qh_)4GR`SI&(+Iq>T zvgn(^ufzX4o%w$J+ONpy7Y^fBRnn+s#AOEakH)WbdWZ2fJ@O3}XNCHelpjB|q5PMc zpP9@L@X8m_M|C^V=uY zhl=3CNOJWdJ(_z5bbuFz`F?%SkLvj8{fV|u^~ZmF#D7{X-yZ^Ib`MRT{PvCC)~?Mz zJ|-u7G0#g>^sdVtjfYuF8}oMs@0ri}G<&GWx5n{HsZ6ULAMT6{es=$k=+}?Rzl8Zi`#12N z_wS|5AKJf#HRxpH2z}duMcJbGVMW7x%}jhKhxV= zrwph>gUzW&$XYd|JI=I57p1y{7J_1B5#hSe_g};T>WewKK=nk{%GpwwU!_BuaSHm z|7iSf=I8R0^@q#PiqYg}IrDSSq{*3himT9W=7O`98DG#_ne z{%HD)DGdMD0_KlqpA9dXk9IRZW(t?^*TD4pPS$rH88>x z7cqYnZ#fx3G#_5Z{Oqvbe3HXo&#Ckz)!xvo+r92zt#o!mXI-#mH}iF;AG-Myu$C8? zKa0#LF#dk#rzt;3e=hT>zGaa4X=lFP&k>OHs-@tr*Uwb(){*}z9@ofg_cQapyUIC2%X6DoQIfL||L|B=f|=Hur#%>3ZzH%uQrzp;enC%Ej3 z+XIW3kDos=^Mjs0X=Cy0^Hbz9pZTNs$e^ND-@*LgP4z_)!#?>^=KJ?24Eu`W9-PPg z$;G{V#AnZD{*)14QQQ+QVg3oly?n%Hw=zF9;wy@K!gA&}7x(fJpM4|qr;hlF;-0XI z`6m|l@)4i?5$2yX;wy@KLKpL=75DNHpS_g%Cy)4w;-0XW`KJ{3@)4hXHSG_%U$_4x&|koOYX2FepJqO_e^n2Rznkq}JwFfw`ZqA2<_9uJ zeDf9LGSPd}#=b5kX-$44$Fkj!lQ45U! zCFbkd~#_?tocH!z=$ziJ#X{*}z{p!kvg&CI9c zuNn`Ge;%uEbbTa)^k*|)Ums}##(xR(>H0_p>9;aJMe!d4jDIilms9*me-HClQ2Y~s z@xRFY>nMJtKfwHMivL(({N=2F>G_{ifPRemdj98BpkK{=J^zFB74y>+|7pPZ=P_Tm zf8_q1&3xVdCj#TYg!#JtBmGw9cT@bw0pnlJ`d2f>kMwV3zP>(tJTU%M%s-LhNBSRO zzP>&?2^fDD^Xd9*2I((lzP>)20>;0X`E-3YgY>UvzP>&?85sXz=HE#1BmEyU|HBmj z6kz;sFn=Y*kMw`Z{8beH3BdT@X8!dQKhpnC=6{IdZwAJHG4tvAdj{#xVZOfpJ{1`M zWz47R?-`^&i~0KghZBMEf1mlcQv68&S>~^y_)h}H{{!aVM)4#4UCdui@lONBe=!@M z==>x7In3AjKN%SRWz5(4NBXmvuk(*Qzu3(DD8=6b%ug@#BNTrG=x<`aNAXVw`rlxF z8O4wEQ_PQ%kG#G-P1tW1_D>V`lgvk7zitxt#|rxsh5hH4ujfyY*Y9>SU(cVM1*{J* zFkjD~ApL&krz!rK!1z@geT!*Z!%V81{&HvbC+bIBePew7=c_1P;DAev`AMLysWRqw zg5!@eKMnS0Gd~0NH!!~+?C)VdeK7@eiF;=IOoRQ|%+G-R4b1Nc`+Jy=yth~H$asY1 zA6eVT-@yC~*pEle_|f$(%6xQvC}TdnzOnqH<6kfAmoXompL>M;*~~|`Pfy)`rg40S zR%bd_X7^E5s*^Fsp` z=n`cwc@RE!=d=G^H|wfBfGnOe=~of3E+fpyiP!{YF&466Jnc$N!U`o(Hfs5o3OOZjhh5 zKm)l1^KbI~pZxKY6_^buW4^CaBSj4(Dl9+cuVVGcUrjcu4fNDOqkT@L86l;<@O9L2 zCc^yLzW=39qxx}_`SFO3ALqxoAH;tjD*kw=|Hbtvzl`}F^*E(^)}xNYo_fk?Kh*A9 z->XaRi?)oa`HlFb2=nQyggxH}U8s#RzdW-xh#%y~n6EeZtF@{RwSPVJ+W7qAi<-N= zQf0dDyk*49j_wH&?guaH>=@n4M|@T^-1l4Qh%X++6JnN6`BAA+ymE9;@ze{)<>x;` z1Bjl?7f1KvQ9LWc{M<{@xnCTAdg{(I^S@ui>#w78Zrl>#zIrE$^rOsI6hCr_ai8Kx z`f={}4?_I}^F8vB`7h%>B?sx3Grwmn*013HL2Uc4*2uLG1pmX1@N;E#&^K z;r^@G{MT}SJU0Jz+)IO0*J@=`7BK-!-N9y!h4BV&ok6go8<|}HS$fc3{ z)IO2^ILk-s^jQGhr}mFrLlg6_LE>Z`!+r4hVFLHT$p$jL!_T%zCJ%i_OE*GQ~r^D z1NSNaNPi6XDgQ`+Ec5mJ4AO7pKGh$jKaTrUe~|uo?o<6i`c2Hg27G)!hWp^-`vmTT zkMGAa|60lqGXE2~4<5fA$9?elxKH{2HPD~Teab)5pTd30 z|4)JOpTKQZJr|}6g|EF`G#wW=9oWXq>pCJ7+nNRZ%?;*$kE!hr>)ZReKNefxKEVBh*!p%6^J#tzn*TKSU&ZFX zmHXqd`ETR?tJwU{V!lWDLDsi+%g5H|+03W$8#Mk7?oHHnqJ}>1yj_^xlj2=`ir;^9=|PSzMena3!Fc>g8MXo^?jg!CHHCm3h6K5KFwe40>;0T z`8_nhfz1C^+~11L&j-0r^Bc(gFXKMVFCp`PHS=lw2F?F9-2WUlKi6`f=J$~K@8&+u zuOjomocW6S?{mQZb)DtcDWt!W`TG7z&`gd|m&M`}cb8Q~gK!AL2f> zAEbW+_rdkwQ=5$UcLSR~MXEoa&Ggalzm75={PC9bJ~cCb(A#qT+~|Me%pW)O2xR~h`NdP) zjQa!q4^hC-z7pa7b|6kvl=;1N`W>RUCB}R$BUca)@lo#`*Rdu-e9%WfXr4a*%4|RA z<5xNJ^*WL3s0i_q_qSJu_{d{qRfw;@0|T{GGrt%6_AFJyd}QC!IjCj6O13D_N0ay| zt_$%&A3fvyN$wxP#_y@8jqztI=yMtT;OU<-=0{SwM=(FjnUDHhj9hdT%#WpWk6?aQ zGC$sladS!)^Ap{i5?@b3unw!pfO{hiaRY*>`L`YMfOO>Nmms8s?wAskN%9^O)2h{*sqOhhM9h ze^5ov%Jh3F2hwzIxP|AH>y~TtC=5Al=)N3cjZ6q{CiB; zPcYv(;cSb`m{0j<&v5&*ocV{q`L7W6E16I2|2Jv?*Z!-SPkqWQ;q28lwtpz24z=HT z=)^k@&AIE)yLVMPt+AH*FP85rzlc5}6}40`pW6S6%r`@v^W&V@8e5SIaw^N+Mr#fTiXR0QFew_JV z+tYMiEOijJn-k3UGm`TEh5S<{?3XkD(RKFzWwJ@$yzo%M29y{AbbYBUQ{t&(G86OB?aGrI6WCbp6is(ewYc%tz1v*D=4M z51XF~=A*CgB$;2i9UFf=^U>EA8kmp1zK~G;#{BR%4|U(z{@k(k4Q1s|dz0OBRW_{e zPsKS663dytwWo7Z#y#vIp@RA7{8S42)y)6i%ga7GcTP=eXagO8sbc=jrR8_bgpD5b zy)3(p`N{yqH{<+?;XPh6MBJ{QX7P{-K=t zySFYc-@4o(;q0Xq%%|knAg2)H%ugbBE^SK{^M9;j{+^Az*wpHk54^bQHMYS;{#ng@ z!iy9}czTWO`~%%!WXx~S7uI2yI@6!=re>2vdJ--9QU(S7Yz5Wo z561Z;`uwhj`RMaIkNI8_*SB;tj95PEo9VQ!?{7ErA4y>kFrIqdI6rzkj{4@oApSCS z#2DZ1Q8DNx+H&U8_$pWh=qh}K`Rbx`gAGIdTW=oUVI4OcpQqk2>cfxKU!bdqF#l?> zA7y?Aczj6TFKOh*PaE+1QF*BU_%_r|pzl95;zzl;=1t#!YWP8Za*w+I^i*>TUEgfh zaqH`MUfSKv7b47$Wbz+%|2@k5XurFeFT|J+Jhc0(NiaW=!M30>=9l$j{c`4)(-9fD zR4~6HjrA*;U%3J6S24e857w_{esv;yZUov1HO#L`WBpp@*JiMO9rHK$WBnxalOA?_ zThIKyR;=H^{MroG_f%6${{5dcXXU9@P~#*fV);FunvCSDh66h zg89eX(2YwDNoCBxe>Ie+?-^(92ibTi)C$W7HXiaTx$n3C7c)w2OVh*7OO@s8_D{EH zg8XXB*X>h1lG>AusAOwnc~1@9&RzOa!+hoE2iN{|GmLM%=ak9 znC~6U&)ChhlELWj=%3QxG@al+^wWiO{bc)BDd;Vx<+e{d0Jl`wK6D16lKV&Z@69RN zj5{4SrHcDU+yBio0e&_2^WuMaaIMO;(G1JrPrjySg+B1wV9}kfrm#P@Pq+W|?>e>r z+QNQb=KK0+vr1a(3i~%7&ClS#Uj`{bB`nFp{_Wpct5oJQe{`r0O4S$k?|z#0uj|rK z*w3T;`b*7!r5f9kfB*K181@9dn)&NvYF(sS^-T6MdGVM2t7rQ<6&aKtVZM%(;%_|$ z6n`|tr&Xj;J`Es@>*LAPpxy-B5;1)ooRy-&eoWT)RLq!PeJPI3P=xtE0Q;Ug*NERs zqvJPy{QR)#ukXjkA7lB6d8Hkv3PlxXemsr!6Ux1?(HCL?&r;1DW^MogH5Ples+E-w-#Cj zO_2?4ZSlWUGN1M@Xl5yhrHc9V&S-jnG`&lDCC%>vmP8@{#U_td@yLSC-#n-1wMtz) z)nd$#g*$!fFLV}M%8@6+{GK-mTH8tUZ-ewn+?m0_S?@TVUq_k$g(HKLRH{Y$AA8t8 zKmEPa`Du*#9=-qW$lBZV>|u<)8{YX0HO~F!@I6rK|1D#FUVhd-;vBuM4`%zx_aAUS zeW&XSrk^)InLodAZ>e_$RdSy$-yKXGO7(T?`Kt+0`gX`7SMRB5#{3Lj{$1x) zE3Y0j{}5rm*Myz_i87z!_m3;6_+#OIe+rbJIP+=#O2?m`4)PPs*Uf|W??5@oFAMQ$ z75yl`ocXJg*!DvoV8`aKu=giW2R3}2f9O&s?3WAsjpVmC487$}m$bn_T!uXLC*$+a z<2c%vBFvvbgUxq-GyA20#S zf1LTXR4}mnSG7?8YSsr8YMNB;unW0{k8l6BkIWBMdn5jajIRGFSdu)|XS~10ADqB+ zeSezigO6S`|6}^4oZ}9+xiRK94EN*`9*Z--tpsDZmn4|4-~NSM%9!7d#K|gW{(P`s z!Tg0_zmoY^f&D7xpAYt{nSUYJuVFsmEtN)uwamx9dri^jFPZgcg0Xh@Ka$Lc-W)~Y z)iXcs9VUK{;|w&Pzy82U2u%BU(bB>{w-(za&Y@;U_LtkV}$*&!hWN$KTg;mFYGT- zHyHJ8WzQQuYF#JnG@z6D*O8CYm6~h$9x!^P(#&7c(*?_ou9H_We^t-Gz!BgcSjha9 zzK`1j^Fw@O`)OnTbre4?dZm^zpYrb^d%z;*Q~t@vZNY*NAK3%inNRumkUiiv<_Gns ze`u$_(_%ov|@` za--|dKQsS&zy7CSHFO8__5Q`_N`2Mxb^dWJbUX7`QvPweQh&|->;3ULt_MHJ{NVfo zw*~iw__*j5y|>-05BmHC7rj!CFrV`8AxA)4nID{A;I?3Mh>sir^)g?dzaU3IA7_59 z{iAB=8s-P>AEhgGQ;4sCM}QT~*X$siyLHkGPO5GgdBagrKh?Gas>1^^L774j({R6W6VF_3cdi}#{4yv+t)|*z!$W1SpJSE@*bcD=HFIHevIBd z0$LU_e@$iIdJye1XD}bVe@|zAPb7{EUwOiQEA!Vyo`AN`*_QupX#1>Z{`v^{!1me2 z{B@CspzX7h`ODWqn~xgDeBFNsfP0{k`8xkde**J${QH6NpD*km!+f0|Wc=p|`<2YU z-Ov9UV^FQMg899Ee%`1;`P-Sla((CeBhlZ%TF?yUqmN&;!u~myzaxSiKTKynx_;IO z`!VJ(hgN^3dYQjseFnOQv6kNn^|vzrI_h7@Eoct$)4(lwocX#wq=8#7Gt_T^ZNXE_ zU**T&0^5T20)7g#1-qGleK!6SXbTn<^plV+ILQ1D4aJ{?Y{AN5dj1`UUC_ zY7JBE`arD*r7QJ>?Njf?`BTH{Lj!INPlWlvEtp!M{-826)vgcz@eAcYVf%jlf%ygM z56WN6>chIo9@yNEu0e;Gzn;bq$obDhto~@fAGigFSpCuU^U(&}8Wywq0MC!@N09kn z%<4msAKV%ah55iOSj_4VI{wA1KA_vrA={_=1I$0GKNLUtxb{B~QXd`#USS&usSn62 z%mbnI0k?)$yZ=@~^JDuFq~99We;aUX7zp!$ThJO>A8_%v+WnV~FSzzIVEfd6aq$m? z)(2etdqV01on7ZnZ=8Sb38@cscIWKofIXr00k?+PcK_99zq!>r|J-BydiKHD%>lE+ z`Y)Zopw_S_%m;44?9lpvi+{G=e}nnATml_`?y-IU`~{Z((E5OD|9eB~gBL?Zuhia< z`k;`0Xnnw~VV>Q8E1~(Z{Rq;Z7uJ6paBJ8b<^#82UTA&5#XryPzf>P^?Pss;Q+>e2 zzc;i#;NssOQXjSeudnS7sSn6IH1~(r2izLE?EYH`&5!LzkbYNK|82mnVSktp+=8yq z`hbhS%kIBaA8_qwzwJ|fz{S5mv_9bC?_u?U?!T(UjUJThVf8`#jzc!%<(}__q2u>h{Xw_Sp0N0V z`RTFa*W)W#|LS4&lk!78j8|Tm56sVltUljf*{5d*VyHWq9%S`X`?#z7N}b5!*Z1e6 zuHEUq_!Z^{`N6H>E1~(p`B$*`*8s0A=={9G{M%^%;;xR6&+?;v+|?1Kc80`{o4qAJ zB!1lNty0f~#E+XDQ|e*n2kjrXho1?_4{r8Kspnbzy8YnJuE`IHA9r@G)Jwwgza$+0 zfspudXD><}2#Fte_M$(3!@NI@-e1#z8$FQE;@7^etEeSn`@qqI{(LYqKW_rx+oW@_ zL~S$PAAPX*)(w3d-kFWcPbc$VCLgEk&*wDbf4O%H)K4@2K<~S-+~^!%#r#9Pt$S7j z_rOBtAM}0P9+)5EBim0K^IxX;anb9~=QP_70gISV`6nN@1q(uaWDjU(KIK1- z>;bPcKbQY~Phcw0LFNbfN9jtv5aMsyfb(}VU*~^6C^tI8KV*Kc{-Czt0P}!|42W>{Fi$NV7bxtXDRa!_114dj(@tCf6(`F$KQD& zK63oi%KVopeq8kW^J&fY^GY`Vs5Z2P`N950>H70&&G@z72kZeo%-8J)7rp*`PBZ>j z{P8(%3m#;CaD2yY!F?e^%gh>tu1 z^fF(MpOHs^JDDFGe|NxY+-m0Q<1bFvpU-TzAAS5q`rXWbx%Wv}ZuIf@U|<<96l;^#`Tv&qp=m*FLfbtYp5f zKgb^Nf6PDH{xN4Uzhi!`{bO{ceih>D_K))4WPZ^8QMyv^G5=`$$E@QI%+IxdjIPvg zLVVr+QT|)Z586LUSL#p9&mDhJYj}tG!SNTREA}pa0^bSL$Dw|7v#r0o6vIWPY%JQMyuJ3-NXSQEl{5=Ii!@)0O%z^Iy%*KcLp} zE#?Q~E0nH3AKt7#+DGR9G3M*>8!meN`S51^lz)Hz0kw{&m>-Omx9# z{XfopJ$^$T0Xo$Vg^lxPT%ZUwE{JMRn`A+9MsleY$E&m}aeiy%i`MYW`?-esyZ!e6q>&?+_$M%5=Vw3r^aL0GYUUsG`cZ?-w|O`8#W|eDdwN;$KMUxg7yObYS0$!X8t+Z_*a9rU{OIo1KEOu%zxid{29m=tQ^Mg z18l)t%s)3T{yxAK+|K;`{2=0A!u&$t?~p0+0CR)ohkw6Ass5doAO8IgrTT}Ne=zZO z?G`q};WEBG?3weQ+UGMsPJYDn50U@wICBjy{?e%F!}DYN31t44#?1JG{FrNS$tQbWIb3GNPd+aGE#dXSm_c-je@l3M!1;yhL*5!( z;;*;+uim?Px>7Fw7Tedo3+C5{_1|&k8l2(}^Vt@-`1OVALtciQe7pY!#}|;l#rA{x zfbt8~2arFP)rUgg4^`^;WGeIZ{Na;x%=rM9{rd#-gX6oo1}8tXz5)FL^(}u5F7Z#b z>krkpeBG_SJz@J)9dQ2Cu=+#wEq@Iz`FSGDXItRnPc2a2Q1MT->yKaGQ2rCP@7Fh& zU!cCB{Kc$3pywwKG5=*cf4P;-fa>;B>T-zHAMNuQTqmE^A6-A+9cQk=#b3Dp={db(X2ABK{g!ya>T>RG1`hbhS z)$YG^e8IJ!0o$kki;I6Cv_9bC-xE?FwuFoyO1=MKPe^^}L;9ih!CZrGpQXk>+wQ+~ z{$kz?;^ObIeH#7a{Mljsm(E}E*WeU?n9sJr#h)EoA8_%{w)?Mt{sPO7?fd61Fh8_D z;M)J*kos_|(RzaO_fpR<_J-64bM)irht>yk4Z3}ny3DitFB=^?#&7#UYoYnE{RGnQ3hTe)%r&^=XMdQ_w!p>j3at;g_`B@>OZ5TQe)iiw z)dyVs`$OvkF8&@?9}dv`UjEoeA9r2$Zx5>v+ULh|7vHn}1T=nDfAsw1yW`9)aEd?7 zXItRpv-$(yzqZe!cWXZ$t3N^h%{}arpPn$EZGnsLvHFIN-(&R$-9CH5;s@rZ$Bv)s zCvg9=`bqgAAJ~7xd|-Zl$m;X%+9UezjeGLn!Rc~;{tsFG)V_Ilk=yTo*lXQ>sb6dsXmya6GxxLuYGfL;^s$epN&r3{D)b7vf~q@ z2fNgVMs|Lo?;p^2ujcOqJw7k>`caa_Zyp)>o+$qBH1oX<{^<$DoB6L;!TeqH{@)h% zz95(UuVMaf-#6c*=;AMD{>$|KTpqv6`PZ$?Kj`~r{4W0W%n$ODHuiu^epWF*h~M;G z;?FQ2{rylW=A+wxi?H7hagbnE$RShx&2m>-c#LE`KMOuj6;|tk<@vO4ZgdGk3h*pRk_c z_CKZz`!ksD7Onm2GnkLg&zZvhIl}(?g#B}wZ|@M=>2=PtnaA{TU2{PvmSNo z`k(8^Zb`{|wYNyr_k{h3upbrnW5Rx1*iQ)iWx{^BuwNnUR|@-8!hW@|UnA_-3j1}! zep1-47xo*3{V~G+SYf|W*dHhCj~Divg#BZL{RzVUvBLgDVgEQ`|9D}4lCYl=_9qMb zQ-u8!g#Bh=f2y#5qOgCGus==MKUvs6Mc6-8*gs9!KV8^AL)br4*l!W`rwjWtg#ELG z{h7l4*~0!g!v6b&{d0x=^Mw8Lh5ZYJ{R@Tt_Y34Z{9LVgDXsf0M9(udsigu>Wac zf3vWEzp(#+u>TohzfaiTBJ4jX?0;6+-zw}sB~9zL9~Jf=6ZXF>>_0B-KOyXYMcDsaVgIYb{?~;4zZ3SqF6@6p*#D-m z|M$ZFKM4Cfg#9Ol{cj2T|0wJ~CG3A&*#C~O|4+jHKMVW+BJ6)x*#B2y|7l_Wd&2&| z3H$#p?Dq@%1H%4JVSksfzgyVfBkVsT>_02)KPT+(751MO_P;OezaZ?tDD1x^?EgU6 z-zV(v7xoVb`!5Uo2ZjAZ!u~75{;R_NYr_6vVgHB1{*Q$H*MW&m{};mkFNOVI3H!em_J1Sn|EIA3TVemdg#CAf{da}^ z-wFG_7xw=k?Ekm0|3AY1ABFut3H$#m?Ejyz|7T(UJz@X<3HyH$_6LQ1PnnaS&%Ke1FQ^mTE|ul~c(7yX33qPYKAZu!9E zP$-qQ56ypt?L+fZW%;S%5G8*uPrXzed=)g#DGm{wiVrdSU-V!u}1y z{*A)^O~U?%h5eg_{f`Lyw+QVP6|5L*LT46uK{0BVj^}&A2$6lXOo_YP^0k3IlVFoVNT_ali=A z&RG7m5nfT;!~K@uQXDYSvm-qJ=Z^G>q8?8(|6AVNqFz7JlQYc!j<b67 z_Rkge&lC2~7xpg@_AeCn-!JTcK-j-X*iQ@lt-^krus=)KZx{Aw3;P|y{v2U{uCPB( z*q<-#Uo7k|5cV$-_AeFoFBA4Vh5asJf1$8{xv;-T*k3H{Um@&YDeNy1_LmC#R|)$c z6!w=1`&SG5*9iO93j5u{{&Hb|g|L5}u)k8+UnT5cFYJFv*uO#8zfst~N!b6euz$0# z{}EyT7GeLR!v1Pu|5jmtjj(^4uz$O-e}}ODSHk|sg#9~({kw$yj|=;s5ccmD_CG1? ze@fV2E9_^4{T^X|ov^=N*zXngHwgP1h5dVk{Y}FDy~6%|!v3d){msJu{lfkO!v1H3 z{XSuTi?IKou>VUz>f19xXd13#rh5auG`;Q3weZKQ|Aesr6=DBxh5fGz`(G3G|4!Kdy0HHZVgH-L{@)Ax{~+w|5cZ!G z_P-_U|D&+~l(7G8VgEbA{yz!(|19kPi?IJ)VgFx+{ilWf?+N?=ChY&au-`B24+#4^ zh5cQ^{%&D^kFfuYu>Y*E|D3SDSJ;1E*#Ew;|AMgpqOkvxu>S*Lf1j|wU)Vn&?7uAR z9~AZv3Hz@I`>zW7uL=8yh5a82`#%!)Ul;a&EbRY>u>TWb|A?^vhOqypu>VtG|1Dwv zZDIds!v4>N{a*aq} z{{IO3e-!rrB<%mMu>XI;{-1^Y_k{ibC+z=4*dG-3J!O9W|25$6*N8Cxdaxg5{xu%< z`#a*yU+9f3?)w!+cy>bAFSGoKBSci(!!gURE)E#s*%g+L{r;3nVZX}qQzL9~aSxYU zKDPbWGrt4ezZ!)7F_w>QKS|5Sem~K4%g4q)L)bsd^0Do|#qzQ3KgIl8z{ju2%%|h; z>k;54OkqA9f1&;f%%|fo)St@yg&y|!b)v9;vgKpj|0%-$NtWMS+yQEYXP;{M*zXr> zw)|>n`@u;sPA$ z*%6-qb4PkbQID6g_W2BWe3)kOR+PuQ*_YXO}Vmr)u2@uPE-}a^_Qhe&)p@#UaByyTbP0^eSe}IKderK*5^j%`}?;Vm!EOWr~3BWdSL#?GoRvz`c2F~tiE1+ zCmQAz$1-2HAFmdd|6`a>{R`@QD&3;4XlSmYZPX)kPb~%1ZgSHq^((UvBw#XY2F2o^@(gdi~DzrG!27nw0IwRYtF3$WQk=?137~ zzc3fS=N`RMRhG}%PeZJJXk$zGC1Lq2|B+aBdrH9RCC6F55r1E_(JlUomVaSfSJCYL z%|zpFezoOqZcYdNm+Gf`51wNAL-}vr326T(Sia6brAXJGuANEO3e;@*Pv_cy>&}dO z51wlI*!WMh{G<7g0DACAmY*Mg#Q6v?&GL`tKLV(rCtE%?{Qp~-A$omX1P zF<#Yb`TKHy&pm1PHMAA>y-fgrmgOgd{*~F#bB}UggU9?QTROA(xyQ(3seeScpU(Pf zQ>mo!x+wQsa_xt*V?49OKO($+cE?m7?Sf1!5^pHc%zIhC$Nha{``^+2hMtY-d6|vL zyeF6N>wx7a8;AT1^#I2;>>SS5?bFfUW%-@?@jI^}X|$ z4{P9lddP>g|1sQe*_Yi&9lv`I>tepAvh|JfLlw@sf-W4+2UO_GEx$86{_*2?uF&n4 zpUr<}gZHd+c9fcJ`PuwyU)Kk_Nf-5hI)?L|v!m1;%g^RNh~Ie)b1na9{>uO(lzEna zH2-CQ_CJ3(AJG0Uw)~^{r}&-oA7}oPx#PQ{)>%|b41aQ&<>%^~_TB4Sh2{5U1JT)W zU#cuW7r&o<=M{KrH5;EV3e5g{A@h5YLcXe`lT`Pm&h}$!HI?Z8dw1TKboc8E`Kodc z!cP?PDgH{QnV(?W#})D^euN*j{b0qJd)<>y!fBSjGN!ic@pIkIIzWDsmcMAI{UGu~ z81G;7zo=``{;jQd--37{pY|`pKRwLvqr^W$@psitcHPO1VSXl?pDy?Oj2HGN6!LZc z0r4Lz?4N1*kHl0b?ce+EPv4(@;6UwUw|(3)oS&&ZBLa`$;1xCN*+hdvV5I?-w*Qdq$|~K`Kgy7n*MA+xSC?77&cE;H`mcko zRJr9Z3z|yi{!*Ka@wy7je?=dd4J#ij&ms0 zmcMo7M(t-dL)K7Z`3F}%qy6+|$Qo)bf9$Hnt>mlCkTo<}{-VI||1@L`$5{T>z|VXd zvW8PF|6t&!KMh$!gXItPFZF=Y6HEJJjOFL|FZVT!wfu>}_%=i5*Xn-fZJ22Jy8qJs zdqchJ0jC~(oaJwA_x-%y<+6t3E&pJ%?;E|V^fgSf{IPN0XT7V`HKZ(m(c82A{PX@> z+8QQX{?Qel?iiyU+RPqSOhYzCM1@{C^)E!JJyZ zQZqvRApXiNuDZUH@%9!qzoA)Q4AG%pMzm6QMy8GRf6;$9EfMB-wL5Xvi|d$=j=!Gy z==c-NN5?;o`RMqQ%)cz64==d(6SMsPDvtpDIP<&OwU1j)XZ~doZ2XPF{&-=30`t-N zKUUbE!hCf5KS9`^A?%;Y{M-EYzb%S7zO*p^4sid?L^iSOr`YSiJ)!=V6W4E`>&yEe zN;y}eP@gJXrf#5aOVarYwioI@sN>hZ^A_w1^|wq~w}tZ4_1QNb>VEjhl@3`NDCFOt z^__GY1{U(~4Sbi_b=xS5n(gz(8BLAdJ^C1YsQ)4LaQb2Ou+s=MYWc5?RoaK>O2sXI zTP&D=^W%4lUFXNM{3U^}<9F7TidcSkOm*x0Q|r=}_EK%;y*cPz;4?)(@%6w0~7WnDU4m{L}K;cUk_D#{I)9_h(tYk$>kkq%D6a{{!yPD-~n= z_r@97`l${%*B%YTEkE0T{qckQDiVc#NPRA|{A_*J@dMUSZuzoo$7F!L>c==kV00*=7*hVuaIV+wza*pL($K8ajsa0pp)JmVY$=eg$&ef(#q~d+O<+(`F9# zZ*}j!s>k+&^B3*+KjeG{vu-#aaE7!#)YtPHe*B$oqZ6fiLw)LEe*O5LHnWH2N(4mG8GH;{r0ciTR)9ILw!GfKIeC6bej1IisHSYevtph{q9GA`-bzoTt_ELeLB<+ z@=x(Q@8JRF)BMl3_r62ha@QBUM!*$-=PiFpHvZ4*`7y`nmD)R;54ghfeaqk0 z*dJVf3FgNfw_vyBH#MfR{vk(Omw`Q&za+T6@6W%vUjch&IG^g9>oufjEq`0%_FR7a z3hK6oGPT{fKd0w{?B|E1v-i2{Bswf-FyB)v11jRl*(D!hHm_H_W6Fd9Y->?U2B;97TDY>S$=zrXI+8 zgS056|AQ=L+z(WkPuv96)-W>|G$?f;BE~lCgI8KTa3+&k**{ z6!u$${prH~3}OE)VSlEuf3~oHjqOE18cTzg;fuFJ(S@e044J(c_<+nU5Zy ze1!Sv@xz_WM<3tsVm|u#zMA=`x*u{4;dbU9Ydq@y$8F3%-JLXqTbX~H@u>SB-ONXi zf36euR|@;9g#BgApX|O%4dH6$pI|)d{>LrMpXyE;!bh2ZlJThfA15;(9seoJN5_8$ z^Urioi6NXP?07Te{gsB_q?UNM054L}_cIzkeV>!}_qmI0fK1W% zdm4U>@-qdPANqb(!&i}a08t+$==*I=AN0P&+!~VHhxRUge;SLwd|kSw6OZjc2~D5AInxD$wz(DgXPs z_4Vb<;M$fy4fug?-u)$~ix38nvIi z`-@ahcpN4F-;AZ0vh=#S8=OR2~(=gglB_w{8Y`$YR4?OW^Uj1S{~ zD%{UT96r=dXCKY}NP4N1`G4~MT05+t_r$`#l3!l%QBS>|P#u*+_h)wa7ua^Dr@0pX z>>4A?SLxsZlpke&ZxDYc%8xO><5nI2&h%-Z{KP~3o)(m!V1BP3e@`dM_tf1D`Rymz zyF1epgI}EgjfDC=Ehs-4>f_>%h5AaN;`h|DW%>EX_h06>>RsB?g6dyU7C*lKn(_B` zVdIap_=Ea@?7u92c>mq@z5MpmreXu>SZinYU2@L-_d@mBM75})xsoJ(!1Yq}Pp}** zFgDL@+En;>m3wjS=li+eoqI$T@>P9({m_#}`sD-MPY=DKke~T{5%FKd{iEv9--cEh z{4%A8_&wD*NzH9&)*}&rz_X?)KE1p(5_^96*xe}xm+&Wjzp&}AD1X*d?OyD@$rBNW zNcw(Z!%r{Qek_9WJ@u5~D|mhmGGA@<^YgsdRA`c>nB740{f3{uRr{15kngE!lk%_M ztxq|M>QA`9 z{jl~K;r_xVI&7t3ew6!b=#nrn{uuWcDro#ly)`la{fT|B%mlT{WBwMfe^u3e<^LaB C$sCOU diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_cmh.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.13/bcm56870_a0_cmh.pkg deleted file mode 100644 index 0ad55fd95fed63e518a2d150d1277c706c4d41ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3816 zcmb`KONdWV9LLYac#ZKGkHL6mSg@FyD56XT}(XWRFoRu&%O7j>o@ldBft92Ip_EL{C@Y`d(S!dKdnvcnpUiB3Q0Kp zU~p2AJnSFTmsM2^q@kaV)n1b3OSi?)|C3$o1-RQw%tDXVd6o~}n$xx28dqw9HPQ^J zURo$&&1yGEyQG8CQR$R)Ub-T6NcW^p$?S#t@1)Pt52>nO2vekbX}i=H+b8~XA9Jqu z!rxKsq4ZRG?YQ@D+?RRA*e|O2U8>Og9wkkd=1Psy8flMoNIE8+l`csCYVFF^;|`S) zWtQv=p<6aMFGx(jM%r_?LKvWy{&0y~|1d9vx}`~2nvaPg?2}^jtLG$vdX_s(eR7}I zYyB+B=wjZPvH3NWcS0O7o8QGB+5D!;hY^#nk@j_$)=lnXe)w7%w65+a={<2xdx|fe+apr}eIQK-%a%~M0!|=1m z2PpUDfh?a~+rwowY~K(=Wi>b}sbP$thpjE*SXm8=5vT8K*m|~Wl+|D!7B8zYsSvm4 zD=u4WjR*QzQdh@`3_%GEsPv|wC!D5ley1$`)&`B zAA>7?w{6dPerQVf$l} zEw7dNvhe%s^sA0<8V7D@So?KT$D8hON*pKp9Dk1br!@+Rf>dcE)I`b)vf zg1#H2G*U1{aJXQOV4+~CV3ptr!RU=s`h?&t!D7J;f>nYi1TP5Q5eyrU(vE^X1xE^w z6PzcwQgEl>A;EKkAp=voQShSRPlEBAq_nr-K*0jRRf3xZ-xS<0SR?qg;B~>D1$z!k zX@y{m!6_{gJSuom@T#ESkd(#qMB z5_TBck-L}ZqXO@=KzFRsPF**whA*#Q@2y`Su3y_rcEnz(=fCO7trI?Qcze0Ab$n;X z+tc9(IlR4AN|)97%R~OXfwnq-uHc_C!b&v0ezuF{8cV6=&aaTQy3T(?*NryqilokE z#<+T?2*0jQKdkFpf(auvE(AW!b@U|;_htUt_|+LbD;@8Chd0u_>!_6O7OYR2G`e}| zX_+z~&hV-veJYfl6X>dX&G_d?&IL}^LWldhU#{R^TjwvW$oDdCZ&2ox&Du-e;_!BE zXYAz7Q#w;{q2MZkPj>{Gyfqn~uLJ%3Hu6 zAHH?RnpcZ{EAS?4(_Usu9iQ!Z?YSMXGgRh0!2(zI@;ZKv<8`c6qi$-FpQ{sjx7B5| z>iV=`;Fy&55%@II(HGb8I~~uLZ597_fuIG&oWp)TO^*@l|?HhP=ME_ghdEJGG0|Z0|lE11_=fWh6siqm(tbur1aI-v|pN)(lf#rd@7}}${YXvl&(KMrHL=6 zw0vZd&irOdA781xnaW-wnctAE=fzv4GK)m-^K?r8DH~dJeOq#7ys5a(PU$1(rS#8& zkDZ|XoXUSfGCm<0ztX<>*PqiK>GYJ|+e3TGKd1DW52f@&)p=d@-;mt5ROfBwtrff@ z-n)W73f>c(zfqAcP?@>XjX!1x`Uq%G>-j0+7ijVT($_S{XiHeq+DfK1KdI%~ZG*O( zop?-{u^dxbYzQ5#}+;E`e%5wRNLUP?ZjinBQ+n1Rq}37 zqiWtrX{>mA->p87-dFP27Ge+aIr_!CZ;w}utUmf*xUEPV>mNK4*AewA@&0~Yj^)jq zQqw^>`tzFminLDuS{y#j;gp*sz%KguibGXiiQ7E#022B5ZI-hSpY@$qq<-l~!t%-L z=X0yM=&MTBAI)yYO*6Z{(u?f2{=SlIv+k)r-^Hs~|g z;Zq&{L5FWjrFwZy$!++zTp2CnZTur0eyqc1I{ZY3FLU@&4%Zg0P3CtTzRKaN9e$s~ z?|1nA4!^?TmplAWhs(undJlH^1rBG8FrUnG_bxVm9m-B}Lb-Ql}AT*sJY z+}Iac?3sff)Zk;EH0kNu-qgqcyG`OhRPpSiMEngW{)Q8O!->D)#NTk@Z#eNcocJ3~ z{0%4mh7*6ompPpH8=v?aPW%lg{)Q8O!->D)#NTk@Z#eNcocJ3~{0%4mh7*6oiNE2* z-|%@3C;rAK{)Q8O!->D)vm8$RjZgdym&-fsLD&7P>w8f8PH)+RHnZFBL3@kc?D_9} zrZ$(dJ`f9l#291__IrMKy~W?n?DqcdX}ibBZ}^pad)748H<2ZeJv;kW@|mO9^G{1h zB<3i?_i^~X4&U41dpW$t;mEc1mGc6dV~Opf!?X_;P-YhaSI#Y>jsBj0l*({lyM^v+ zM?0Lojq$f~_|^^|?{IWkd7*8%Ol-sHlU9Z?V>sdYnb=^-^cqz4Ha+}PQ0K=<}1#?yszkk$QmS|AJinRTQ^5IiTcEpD}c@= z^HMsZ_(*{sufLB-qXukwR#6Sdk?DD z`)Dz{lf8X|z1V2BnZ29?84sJ_dq15annWIYu?^h(gx=|*u^rs}<7LptNKwYY;#s{J z4o9~4dwB^WK-We(&QU&zI)1$1 z6Lc_MqK*MU2l)SXTIOSx1!O8UN#UXW>%++zc zaxzPQwfT;*1dxpH=k@bzS!JGI8x9a3yU{_PFdRFP?PYvXGzs}$#-XCE-hmE}HV;=# zvyHWZ^$hu>oL|cG3FVnSuE2)`rZ4Ik;dBsB_#&sn z_wOU>I&3cz>s?$??{HTy`grqT8)M)4SkATuPKS>_^MJKK7n_9@^~Sn-(Y7s}ZS;Tg z&9G9YY%E*e2+(zJaKm zuNGD47}r3@n4lxh{R&apF1rs|T-SmA)3ljlY|*E772vC#id_rNybRyZ;WJg9vHK^LXSb6rFgJ#3P>N`Ivk}%#r8)Lq4(d`$A;(mVM!6vW0}r^iQ*$vn1!7SMZMv!UT%DT zwW1znO&@a>`gu3b?%T-!!)`Cb;>72ztMk8Zm!i*@N! zk9GYy8U3iYtV`F+7E<)l2=T0~jALsnYfZDZ`n9Gf+iErwpA*+3KIQo9p?B#@-SW4s zT{j3P#rSM0p2f$;2Jf=^u`&5CdJp!8MLBnyFNj|=U-Lu~J zv5a2l_~BQJANOd)m-mP*evG+e^!#e3;8?-Yf;bMF`NYSuCw=1Mc=CG0vAlQfC2_n- z@gT)<$ll1}XycIg)h&*!6O6&L)Dc)K%omKqX1?(8>rK8`s&+2*-r!bwpk`&*OAevf>fE1OJwdWQ}%c+R}y$F;q&>E>GjD@VN7LN&~tdb??jwFD*Qht*4}L{*T0_?>HDG?gUqMTsO~J4 zd3$`3TE$1c=^@sCOFh1+EPJ z0$ogh1YG%k$iI_= zKm9xS?0M~d80KxmiKF54FTyuTCW zql@=tY&>%gaL`*i3n+MFyr!44;>aVGkw=9c^&c|%KI^G9`Sx%Y!8k^zrl~afH~J>B zc(Oc;5SgZke!O_1d=>@$526S38Q6#Nq#p~`x6V`DsPjlS>O9s{v;-LUQ1Zqzxq8+9J* zMxB$pQAcj;^d28OY52@-Kh?U<+{v0wGCunx=1|fGD$iU;`A1crwP_;($z-s0880WJ zUy#B4Zskn|>zVP8!Ty6Q-^E^bc>9{nyzloZ*v?wUH=2*jKI#Cr#*IrmB>zpF=Re`f zn;gnhpEh|v3<-W?4M7$uSAJM1k1Tvg%9Yz+QBF6A6U=$E`)DE=ug;(EP&*{mxUL$>h4ulQJIaqN0yp*;oCYEb1u_6WsRq%D|kS+g#3jX00{KG2v^mE^z z#;Qfw44-ku{=@pejR~>ac$Bq1z_;YY5I=}rw%7OZ8RFS{=dmAe7h*?!URkhB*RsJUv_I4^8^A#o|zvx4ukW`Uy52Qo-M+g1>JC zzomjdt%AQ_1%G-4e`*DP?+X5275ooY@OQ7^?^eM-u!7IH$@!VM*<8x+H~6{KpO;XM z?;rhr9=y}kak(07JsPZbkHx$L#kZeRepFj`MV2w%=7f&laPzG>^|r3ykFDU3so-yW zd|v)`75wch_&ZeavDVr*f4ibX`^e+|mvt1J_bu%#foEoha}Q=ogU|eCc$Cd|K2@@Rj=PZxnqeYW~?Fr4N_S*H;!+{-qUK>x)y%^EYhT^`#>9FE(t;x9?GyJ88G7|J7yc z=P&+WGHFY+6W$~NZQ}fwGhAXpUmy=4k&h4k`$YJzr=Ht-yE#v8X19NK&|B=r-<+X$ z)!(d{y~W?n?DqcdEq3E?o<(%k-^|0k#ox{B_Wtf^yKO(g^A5kC;MoV`mid}1-_*tZ z#7S;H!P?~a6FmE34&ryICcc!P*Pl{-KiAjdcY+7@H+k_sz zVZ2!r3VG)U;86x1{mk2+X_@Y1AN%5H^Ko)^Cbv_>m5O*5RB1SQ{U6_|F`Eh{I2HIA^L>_n#bolEY7S_{SZt ztz28(Qyl)h!)H1CIfozbaQdLxK;JXG#o@%#$NcwAVs5_`LCg&&=7tkL2w^{% zr6xRdSosfWkHZ~3bqt4N>leSBXlpX{XeVbmwOX|+zsYE2;D1y1=3WNB@n-o|GWd-$ zD??p=uguHf_uVYNN(S#mTN&!|jx^T|1zdU8+~;$4?DP4ZN}o?#$!84WYu=sZeOdeo z-+;5gUF!5sx_;~zMS3H>S>{g-G-J}|vsQb$CD79Xy?>w?v%dZjfo6>Q{9^-sbf7m2 zv~Jrw)ZZe|qXIoT(C-iQ&VlBh(Y3`RjO+WSYp@BX)&<6&3MxciTdT^iz z2AVPK^=}{Oy#vjD$d_jh@$~ROj|nvMkuSe%peF`;LZI32`1*SU`lEp!8)*7Gb+~da ze*W@kfyOx#u8m^e!a%w*E;-4hhOIK8y$X=!&f-` z4u{|B@Wl?l#o@H;Ap!l4@y@&Pe!N>7bK{*nKi;AJc!&1m9lAwe@qqT@9omm~Xg}Ve z{dkA=;~n}~ftT;cJNbURL;LX#?Z-Q`AMenk1zx@%@8tXO4(-P~v>)%#_}$C%xN8)s-#>W>{s}Ji+{?K|k=7mLW zULY^d3-@SV*uB`joEHp_G8T7J2KURfh360a-Xi0-Z{0R@kg%UJem@0G`N8$)5hB~l zQE!}pGMp2CQa`$hTxjx4?r*f&KsNM2f_u)uk^#JJjO&@-eGT- zdyRGVD{|>WTzUS|Xx~ZS&FwoqA33%^;vFuFFMQtTqJ4t|(0m^epSAKnBzXY+#Lm@C zCcpdbW%Ar6%H%r>e5vZCoUc2X@P$ds}!XuTlF{wNv}}4f5DNWLx|Beey>6{C0Vxe16wFmp@55=uezc^6oUg zsOsbX44yK*<&3hK-TsWSr|q_Q4)}KGc+iJ@Jb2f=tMTaHgYmF7@pk}XAH(0wGqjEQ zZk;v?x$(w)M}G fdv_u{p$!<$>b+Sujq42)dX*gr>We`qpyl#E+Hpm)gA%JKp2 zP#JWDGA9en=RD78=5ybddV|mTy9?3hjAu=KW!w2%4QqA&jnBm@dAwiTua4s%=33sf zCK-+l!-<{YHaAn=V!_{gSf5zzBzaY_u)f6Kl8EiXR?8>;J|F!)ADeRd7Hj4^zBB3S z_+o$8Q}dml7wDtS?Dl=MC++sW=9`?Z`kFZQl&{fkcH`@2c6(p<7Q5-&d^6Qme-G@Rp0wNMA%45o&og$`XZgHa>htZakUb#%h2NU7e0)KD&PBmT)XQ)#%2_D! z6syeh=fd1O=l18GKd3H??*JRU>&m>(*yDFHu+Q4TS+dy)pL1od+{a@pdui_9uo0R( zfW$k*#^YIP?H#}N{H-!P>YDB!&hDt2cl^jlH}>*v7~dS`bo=|o;VK*7FXTQw@{oO@ zfGf}5F5j%(_wYD(+M%A$+0pH<=s!KuUFvYok&OQXhdh^_4qxT))egVU;rBayjGSb;mN@=Z4!_djS2+AJ zhhOgS3miVz;qx56+~FrW{4)-J-r=`6{5gj|=y3WM{gb$J9&xF@L#3aIEP3=V_JQP2 z71$XB=QoCzeN5*R{LLZGk?b8`)@H+JINXmZ&PHey&WrAG7-_-krrR`UN<12sq#FqRaTS z-EibHcW~uA$?Ks#=;2EK0D;Lf8OZ+bYx(z=sb{h|i;A*WRn+r32RfbB26S?kPrt)= z_$&51blZ6x^A&P#RJj4dXbb5=oF&TW>qPgLr;NTrbYFSdXx|>r&SHDK-H0|{(fd4+Jfv|1YCKB@6UcssZ zWg-t-A`d;0hrc6_a<(?`_c4p#*805IrJt9}N!S69?A)4u2#>bd9D^**chCVozFvm& z#n=z{HUR&aY+}#c;$vccf^Puu31z@J>oLDtAENH^ihg7BA@59@t?1?bNv>umXNHaJ zw0R0$JVP`aXsg+8b0c;#4y=sLYw&NYu+!VZSz04oZ2rO);&1x5bUNA7na^yFLqGd( zv+MQ>TYUUD|7v85A5%6bVHfkG*)`PJVsjX_Fh7|sD=KWUzQ*53wfJG*&P((+ zXlpV16f1+zc~_CYMaKJU{7owEpV-IXYhuNfy|mRq7k{&pcK~=+$1^{^lVh*V{CTPJ zsAFS>_kiL&%B#Yv=XrPOU$mJfwD=;q&a-WxXDHMhLi;_g0EC^Rvj3$GsKfjQo8C zcCXap@M#XGoVA^K)wlhNPfCvFS;|;H;yo=NSMq#6VjqrAtsfC9${-tg-qu^ykG%hE z&W2~W*Uh+MEO{B6D^Ldb2K98$$lq&&wsz5ntJ*b5<VKe72jhsHs)xfjb>(H{>g-*ckg@eI$-9Ud+xsX9`5<)`E%bNh%G|{)d!PC zL8=cXgGNzCia}QP!62AEs3?XbA{C9IiQs$)QZkaLh^#LX1=;Vn&tB*5d(xiL;;nnm zZ?Co2UVE*z*FL;DOvCAsQ0-DT{&erIJ-a?}y23l?>^*qH`?Dubtm5tbJ5IaFV*Y^E z!TZ5?zeB0`45j926-%!U` z$8_sDQ)Omb7g;lLKCV<%rzyOtbdf}9Q0b8>f+BA$!MiHV4GgI`%kp6m&P-lp<0#f9 zuZqSS<#+N==kEL)Av+b{V8224pxMsY$LC zyff1*H(^#|C-B`m4tpy`Pp!=r<)hvb>Z>#}8S@a~M{V~^5>(+7!Bu6B2=`ab!KIL| zsB}Il^wLTssYG|1I7nnV*7(>gArE;q@(@~+~ICRlfdK6VAtcsZVvd3oC<-naK zBWEfYjciD)F>J+FmWsk8pAQuCX=kr@;!C*-riO{ZPHbS8Gb-yWWs(8!wUsO?ayFX7 zZv(H&uyTjUo^#s^&=znIn(`|ngK4um$LVFHIu%2|mRDx#+nCGB=m0$BJSB0IAY@5a zXj4stba8T2nGF*hyC56|X1<1VmxRj8fPq@<6RK@+J;UBJ6o2A z*~rzGO>)hK?~-hf2r9}f6|V)ddj_VA5LpHrSxkaW6YJE=VOSR&X+q=LdV6n#ylE86 zA7{BaTWIcjQrLHiVDEoL&^E%W5K8Np-&kzNvZL+_LODb!!beA4#ai(jrQNtj-o^ll zkczd2nI=2i9qM*ZQ92J|G-u9q$FaS6-uT=!9cFuNQ3`Jskw)`PdXeJwI1Zwi7pA?1 z)qFD!QoCPi49)e4>TaC(w%*=h>?wAO3>Ujk_Zn0@**La~n+dnA;gyTpM$1P5p&3h~ zZ#r#TMv@EOdbSnW3qXZwBFB5s9PjPE7Z2R#Z6<8ghvdb&)wI%PcTTBIO_Z< z{3a8+1~1oxkAd$3zZJUADg7MJ--0i-AA*aSGvIr{&www*cV7s8D?~Fdf_H=Y{?cCj zfQa{iPXoV(pT5JN=OD;_fa3W*Oyc{Q90Yw0^UuLk@JYS2h4T; z=xmEGk3*M4Oga6#7JN3CZe9ubyYQr(Vg6Yp=&S^dvp2IW>BBt$^X$VA2 z(ONg|gwOoe=KLS?2SiNzB{2Qs@FN@m@m+X^MX1ZQ9)wZuiA>^m zJxMU<9LJ*6=hy|)CP5naG(ELtqlq@Gy7)rb~`tyRroPQ8}7%cXAE?@QJ zQ{aC9b1v<(UXOxFoc|f{Z3H0NsK6Ie5k$;?#`HYA2K-46kAQyyCea@4-@+FV=idlE zNdO{V0YB^BCAO!4#Xr{Pxv(#o_5XJ;iDqvBU&0`QXz$bDd%X2720nv^K^*=n_`|?r z?*qUS4>MG}TSZROPkZ}21pK5YXMA6SoVGD+X`l0lV-J9jpm^vTZFB6DQPP>M-qJ4?Yeo{?Oh7z_LH?;Y$dr$T|L9 z&;GZl4=i%__lJRHKJ&NR!_3c9-uz?0&mg~|PuG4xB@k_r_IdUh?|pDe)?+U`2bd-q zCi3MdVv)1Hu7Ob6TfP0g-`v8{l3lhZ?X}n5YpuQZ+IydK?m6QQ7%4oe-9viCH#)pT?gZ0Yj%0-#~>h&t5dG#fWvYy)5 zV10CKq^~kqu2*_j*SoXcQmvHN)}5{Ft7OB~fqKu#aIL($R`1Rm$g>7|$Lf8R@?dYZ zKGfT2yfoZfA1n{|*9NG2!MsiDo|mm0>!X#1m=;2uLxx5NtM$Rs^73FqxUurkNUfZ$ z94rmjR}YqIWt#0B8DBnF&IT9Md&_;uK3b}b)w|~}Zmn=(y}P?b-ucJ#MB}X-M$S^TTInCIV}?3SS1Ns!u9tdy$L3{y zgXPura&M(p&rMkA%{yUeq_;e;dDh*iyl-%1RYSr0c(q(FE5qoT)=q0;S?|ix`f$0n zYGiChy?<q8@x|`AF!iXq&unqor)9)RSAM;c3CEq7`##t7AQM zexp>m+R_ifNlU$@(OP|UV0qK7{iEe}dM`{xUS7hmD@%j)S+fWA@j@@g&Yf_%s77_= zXuC${r;W6Zvijhvv34wrQbVoj#RWx|2YNP`e@5iyTq1t#`-%pD=77Y#gNLaYAzWB(Nnu0Gk>Z_J< z$l;!HeR$lll?v8yp0Uz!wNi8R*#t#PqxDr40s{(CKZt2?Ye>1NjgLqLLaT*!V_|bx<~lS60OB-8OSLlGPk>3hIS&qrUtxe+ zsXwi`+&_k=w?x+#7fC{CbKIqEH==YdU!e=F#!%8Ioedj%M{6y1j)v?n50_V#oAuLX zd9aNA3bHo(R-@%Xt}#>$0Vv@>932^})yHd(Yt(~Z?a-VGCxrQs<$`ny^XImCCiu~ImlKGPM@qmBPs7fR&Se^yC9^Dtv)d? z_leMCJDGYEi4G?&uB=j5^^zI8v+BtB7-&~ z$>z>7dSjU1Lht1!sl21dpz$HS5DlIXm~5E>;7mE==SbttVexE|}#thax3Volf>1%*&BpGiAk7H(?5 z`7H*NkB-mRY0mMEQYMAQ{2B*ZWBLjj*m#t<8JX(MLDxNTO7z-f(>K3mU&2HjgH3KR zBU|dOQGl>ubKlaiETO5fk8QWu+qBgd|D9MF>l!%X#Pkv`CnP=TT-aFi=kYpU>r4{5 zTK0DNs*`nIslS?gVRM>p47#REG}c(b3tXIViK3cK$XRb*eqc@Im4bvcKP$}kA(F>y zCfR6dtX3%vw(j^t(-?CKQ!xI~67m|(VXR2~GgL|8!tC1ITyK7rmpH@1{7O&i46b`x zFE8jG+H@j@=|A};qpWvinB{obgI2hT#154UKfTqS(QJ}YpYNSwD_pTCS6I-q$zZF2 z4T>}F{CIh%&o#!d1CS{|3&_7KhT-CVcV z_GWzjjvEdmeb$lp|1ih>7Y;7_WnKW>HD(l2=^nEiN%Q}6!`btiITI((=kyPR-Lq^T z(%;OaZBnl{es`xVdv-YANTI#M`8fz-8sd2509a`1PA zy!R%wYm@UR??;ln8#w<|z;90SW7#yltquJPZSqo{cz*X3%f<3(dhaxO?)c%WYxsYY)bWS-`_2xYNsiq%L!X2- zC+(T=KPx%k9N%>5&!LUy19O4Hr`g^j_>KaW2L9!weZUZ~3Rnxg3`mbxf?ou@4tOK* z7T_|V)A9C%c2#oTsr+R5?=A3OUBEwBz^&`UAP_gW-=z)l>RjduCacRGFliC(XKQ zG;{!|?fi=K6G)|re~7Y6NG*Q~GA$%^h)KKbY4~8kZL@z5e3LZVR(yYO%U*#I4hb~t zx*IqY@Vtk5he%_a=VMr^&iQ_bAy4GoHZA*2LQ;I=P59&qcu5c!qE`Yrz;Ho>G# z8;L&?+_GcHx|Gzi;;)7F5>m2r-cbmraIPIrrjj|NmbG1Jrv}`1?qF?j9I3q0#m7jk z_t*H!GE#Xh`#xkmE#Q_FcRe7lkhc}iXRbh>k^+IaAkT2`YE@z5WfliOy!m4nhlr9acSmD|2i-LSf}OI zl3GsMo}8>9wXEeTfaT;ztvp_cOB)8X>nSL4B&j-C4i$5L>pGru<+Ge^xt_F~{QW@e z=g*^?=YnmE%NOb2gSP~3o^nKSoLmI$0?D?rX8z17TZc-W4I zV=f-!;r#fJ)=6FGUI4r*xB{u6i%*oD5H?ARUp z-fhY}FXSCSIu|gmFA90bgmkicx6`&;;P=G>h7Du9sjzr)BXtfCXBal~EJvu$=dvY9 zIr9YbEbkm(>N@Vl}N+MWz2J4coBKlEe}&gwiMj9XNNrJyQ2f2a#@ZkA}<%q zFkR)iw3x@VnH>XPl*e_#vQSTK&oxI+QpP#B1aAAWE!Q5FvF^y{IvSds9W=lnXHl+$*WKQ`pW`rIEJ zmz0y&weBc+QBU)n_iN-SlelZ1YT&ai^IUU`6!@M`-pYip3w%8A#k%$c09_xu^ zTyLLD-fU9yU2mTXuAIswpE5;0+jHC<4xBOR;9~G7=Mms%fUAcx$WsDd6?l|;3GgT2#)a8{ZMoOI zfIM+|Tx-4pJhrUSjYx}=Qt^a8I5Wo+9r=YmVKZqpv%)gjNit*Z=N6!Nr}=flRSBk11=#i z%5J$zC^wr_yg%UT8tYoY`5WM~jPy!E|zdDqQGPrlTEbv8Hhsb*qdC?cudnNET z@+>1>1>OQ4WjY?bSkDM~Zw_@Uld_1}5F1(=hBZ;1b|LU|$US2H-wm7QwU+ z_;cWkz$^ytWx#td)Wg6WjCcj`4dB0k5uD@-;2XdajB*_?i-9r(Tn;<{%tH7f;N!qd zChh%!^MShoui>m^lKw8RCzI~Uz@@-lz%ESYy}+fwUBG_;hckH}54<1vIq)_ne5Bvr2ec)g^WE{8}_$sjXY;a&5@E~vilk`=< zkAVH@%=3Y-0M}yM0VdZgfLnmS1s(x*rcVw676D~o`?1{u+bz&)0YXuJ&CY$vF)X64 zBW|2Up7GK(!g0ibS2NBDOZj0ckFa2fu}Vzx+<3`peom;!F8LQLmmxN-@vFbC->~JeM!uim!xx1yQ}ojha?8=9q&SbsDBz4ta}LXdQwqG*XUbY$9OUvp>!iOn{lELq$c{uAVIwH_0#RP*>r3eQ%Y@YvpuFv9#c-iZeBMp z`jl~OYmYa!@Y&VOH%pjrjJL%YH=XfDD9NrTrhE;7je|FadSkr#2(*5jK-%R6+DD-s zLm-m&Ss;zKAA|NIDv5P=L63EQ9NJvw3~A>9DeVSmdl3YreFcbfEvMNhpsgYpN>i3D zAl7N>`0i=b7u#cB!#2H-lWmOQ{~JGj8hy0`=T`zW6zjze6KIi z9)Y$P`K4V`p#3js?;-F=ySqU9IkXQ1S$HPjnXpfL*oj!-2(iWZ1 z{kfpK&v~bNlzpyYe?nnc^Szt#C!Qb1Q*pC`eqSa3$Uq~>?s>_KY#`|1vtIhNd>)^F z+l=fL2%;=LA7;Nr+D>=Q$ZijO^P#1CDa-84Kc6kQj(Z#rgYQZi<#n(6-`(iX;=y|T z%|ObVUK6+;T3n}i8{}XvR(?6?uT71IB>A!Hx46fQJT#L(L%fa@nn`vbw6kce9c|`D ze1&zN^(c>JJXh8op}h+^#m@v%+D_13zE^{`s6cxv+2;~O&>@SbhX0xCj0iQJUQ`&*wo{^mt{Kfi$53b`hTL|qcgtB~*7O$bX zhVdE9IL_pY*U+T-JD%C3%Ixt;*4V$KGRwahI23@kj3m1e+Kr^rP9ihtw+uA<6towh zgEYrx%6AhqeL%q{>Zo_Xj zqL4Cs->3_Sb~CkqeDiSAuuy3vJc~L|M~y;DQ1zUF%f~v~)dpVS(1E4+*gy$3=`s z2UEu9AdC7-@1#Frrez&`5_lI7b?h`29V_Wr+>$=FZey3vdKP6>&+V~z%VKeiIr_iP z)D~^}RPcY}M<-v5{;&RHTd2RbN#kuX{&yOWuGu=t^LWftuI;*jI8IHSr+hZL*#A$K zdCIxv_hFv0pK4Fyesat_mHR2KN9-qmGq8O;Ju%mPv7e0lE8FzbQ+?iZtz_I+e}BhP z^wXz;{*$eHQ~mw@%~MhT$@atPy2sxV{l4j+_P@WAn$MzbNaz z-#R_gYv8+)8Q1&LEaQIO-*9F>i`ojL|)ED;IWPLFed;1%_?e?DVefLA#%HI1@x4&;J z+S@+ve-3W9gw9i4?ol2x#UZ8y*+6jU0yaMeD z(7b-E495cd0aUY$B)bFJFIhxbr}y2wB?NP&cMq0NLKt(UeUpR%Xdf_+z_{;7-}X&n9p znQ=W_yodijXt-39FTIC<8u{xQG?PvI!fODry*F>jvX3Hww)hiZZbIwyJUAxI_U1nC zFK}e}E(KB@qCctYc{F67#P*^;NqZ%ksXyICAO0hDv%Io6M^a=NNp?51`2Z>QB zuVS+7%r@VeSq&)Df+l| zOec=X*Qt*k1A%t_Yv)}v*4ZV_AO}o zgmM)3D)*3=?p3zrJqgCcsDG#Z$a5%@?nmZ=r*fwI5!WjAPpmWDkGLM2ozN`ve!zEk z?ROY^cq)y1_`S)Ws!h+Ltai3O*L|tKJpdl@*^$X8?J@6u0c21WN-M=22E1-<_!~j!*jvibH_S6^@Z#5^qm!-4m^=BeP_ij z(6mRSrSCMjlKixv(sx$eRH!q3XT@JaOUFg}&Wf80eCazYv~?;=`p$~m3w-H2D?SO$ zF&1_BBKy>9F@mxSYa6s>B-xjs_2EP2C-%%~^6P89lWn`NZTGe4PutShd|%&oU)#36 z=Gyf4J+8Sf^BtB&Uo#F)XAUjyA<{W?FX~*sq4hfWRNisn8tnFe;hm<$XXk-00_ioT zf8}Df?^u`S9CIKL$LL-BM(k>oaUM{obUkO8A>b8l^w&40qrWnAT0?N@GdrBc*bz*E z%Ci<&2Ox*ZCbs!)=X;hTE$`^M8(bNpZSG;tI~-iQ2+9L(8A*08v{5q6Z#N%eviu#S zMZdBCr(?It{Koa^`VCv|H~L%Z8y^Qh5QzHUjc+_g!;|@j??^4`xZO84?;F1FwP?3( z;T!t%bbLdfnk+V?@3t$B8~x`L!1vz%0XIUf=K|0MGTlcw=F;*1eDdQSVh3nNS?7=! z{jt-!UB14J{BD(kmc0Uqb-M0PV3TojTa-4tK>KUr&B^3R`*4Bw zWoUcQn6#@3H05y)^IgJAaj=VV2*Qt_RF5Nod4PN#ovvBF z5Za?`;?}Tnm+y4IH1h5KHSW!@Sv2n=K>v)i1NNDb{Z9mt_7=eS6lv-2kj^4s*&{9e zP22?qnq>|E{UbG=s-yDs0lrJQ*dN-wlRTU2 zkLld+noE06l)j2K@|xYBwXuzU*~vDW>#OP5W~%+@`@XlNANA>UTrC8jieGK3zDn=u zorWy>XB=0*&6pda9^X}7w2f(bP2&QGb`ChOz$w-LkerE#TG z9P6gszZ1v4OMo{{7{}7JaXN0+LbFV?TRQ%?B*w|F-F$!glhtna$?w8$#*KAt>^524 z@Y?cZe$&Y}j16i3Uksl1|77!+eQf-HV;fl?@AzNTLmyA|n64lHHgUs#^xgeM|DUWM zw?+In-lqDuo5vliexINy>-HGec^#+!yB_sBAVs^mrt1{{H@E)jG*%C#&UCCkQGDF* zN)+{<%*Ur2tBUJ}Esa(BxZeet34Dk1hXD6M`uKFNV;Eo3K7IgPz4Z&9nOnc1^*V<4 zcolxs4(rSGrrqO1`0DBASsgx1NX_Qey;rspG* z-)t%RqI-v}ZBy5J>AUp51g<@!P1Adp`b|np`$FI7O8AO>F(;vQ>I-E_?@N9q@I+bC z`;uRSrY}cYdhhYe1-|tD;#Ui_^#0izl$&W4X{`7tkN6;+=p;b zuLD01NUv?^+`Ez&eS9HKyf*<${98a=_ZX9ofOcFcyMzLfMpn!F4|j#;wU1b*75Qy? zC&MVop4lPrB#A&Ks!{r96Kr5NXR#I^2(XgW|sJU4}B}` zJ3t?xTpl|@`{zJgN@hy?I`1LZJ%+>ZXb))~>3a-s22W`* z20L$V0NTZ1X+H&K1F_EZ{eb6^e`tfYj3oOC_aD9olXVFx?LKI0$u$2Oz_ko@E+fgl z3hftxb`*F@v)zvYen+o3&itLk<2}yq_%_dHB9wlsE?s~!dfX3f0h!XYO&1VpTYH>Q z^`v8|(|9r7cN#C&*}rjO9GnUMWE&IekdBGD;JX5`AJQ>#S%Eg)F=5?~WxxISbLN7h zi7DrS>jz%1nCfr0DwIuSP4{_cK#OyM^Go_J+;Q+dfvDs94Xt};uVF`8r@e*yys12Y zx+CTEdm+}jxi#AXl=b_T7Z4jRrh?UhSKmr?Tmc?+G!8z>eYevH#+D-#XI(&SGri73 zc2gd0p1!kQ-Jb(QK2vplM;m!;vy(i^(5X#n>2H&bU;dt=*rwkrF4|zSHq|Ay!6D#X zNxhxqkuU1$w??<5&B^ps)~V=u)mCg%T{hRI*JJz+>LCm9GX~JTL4R#$t zKm%?2-!k!FxtOmP#f<|~Io43e|C%q(`w@WT1^NIrD z$^!l#@V_kNrRcQ*xh~Dz%(?b^HsE(w{N9SV&y@R}C%^Y3?mjlfwQq{Mj_|kKK6hbx zaUPY+d`82*wm!cNqOM7rN= zb6$$L-)J-5id)|Az4+aii2H3AzY!C0zw6@nT_Wx`XZ-ezxVoGS_)JN}eSXB}NFx4A V0(=D zW(b=9-}N}P|Gn#+I(zThpgwi>sru?WfBm&<*W*+j+W&$52e01G9Cq|uHK*)6wNhYz zv5~b(k$r&etM78cn&`DPg5glZzadwCZ_fNak#86cdGdadZ$174IrAI-M{{1j`SSZj ze|Z5J*7WDh9}xN0^M^h6advZkx(~w8#8C8#@$iGUKQF$0t_Xw6MfUbyta>u2U%|@u zo!br$pTs>Zb7tdkm&be2?w|UC!8#!u!59Yy(AG~P$J52O{aPO_@Uy#B^Wt$`lmPq$y#SU^em zch~;(5dY(=$1A{VwLizr+Mhb{r|pmI&%Y1L8vlAn|A43ax6#4>L;z02Kd8u>{|(9i z1&n`d`}HTf=D~Em9sExPqecE*x1YVl|HSHkar?WaVDtt0)c#%sHTCZ!{tvAlx9Z=o z_V;c1_Y?omt-fH@e?aXY=`#}lxISzC59I9M?BHJujHCRI{j;_|P2zuYb-&nuEB_{A zpNx7XF+TIaU!0bYl*+Vdc4Ij z>w0p|81bk5&v0g?LU8=2HSb`kqyHH3XRG_sdN-fEVg3ciiGS2FrlKtNj|ZetR2AdI z|NhnLAdKhY@rNcJe+V~_s%f*-tt0-$v6QL0(~cqQi2nnt`|-0e^zZGId@&_`z+r#> zarWW*bOT1gre_X2{68oaJy;JOd49vE_7uD=YgzL~cP?Dkp1Ofbn?oTRf8KTU_{9!< z^a6iveo5jtubW||LKL49U+70Z#^>~1d}j&MD|;ztr zRl?sAOnLN0cx}QW9od1+bu*DPZZJm1zcs?245m9;3a1bF8DWaidI zCx#gd(_i^{o61HOJ}y&DelOvN?Zfa5mfD9tiO<)sp@?s~e)UUy2<8t;ADXx1KOphB z{|yn})Zbw*f1DktPxG}1)a$DQkMuCNO-6M0k;A?x@EfbeCi89b-}pE?Sf9rA6&r#2 zX85z<;9Jjd(+dbp>t&I@vWeF-d|fb~gTr1F_>GllhY{GmIiIoBSJ;*HY21`!e3l&l z+_|b>G3}QGLBRMBeu49i`#lk#vDo_{PZq%<^|{U65m+|I74Pvb!!z7cu-+_`uT z{VfaKA&2;vFf;vt=J~9&kN;a{<+ouE;CM6_{4&|TkVE_zUti?M9}4W9bL02K-y{Ne z{aPUYHQE2bK7X0@X!;j&_Ae6ursTggh5mz@{>7aAOT^!m{AZp;|4B{%QqKNm;?MJ+ zcNUV_Kex#9zZm3e_Uvb@O#F|%?qCDzVg7G;$vpon#GmJX(w}Gl+#=6^4gX5c{#D}7 z^FQGqWdGbE&wma7YR>*O;?MIx;U8rG+#=6^4gXrs{yoH>=fB%(hJ&>rZ2z(E5|?c4 ze-H6Le#auV5HpzngBA1quM>Zs|86YFz@M)HJpVQP>pA;3h(FJN!9UUdYxp;E_U|SB zJpTp%MEkGd-afgFlxmnEr(JRgK zzn}Q?{P&`{N7)~?{~G@NIr|R~f1dvdf1&-?@E^$8ze)Ug{wMr}_Fu!lnX~^O@n_gN zyYMe8(Hh`j|7~+ri?7+%fI;Ga@^v3~<*l{ z|C*fr*AoBX5?h*5_%}8E*XHa$M*KII*vzvEe^=9gENB05;?MIRGgK&^&+|Vz^e24Q z{>?b?zrV_leKv9ZEnnGw+AN>0BmO-975+T`HT>7*?7yD)^ZZx%^ZeKFU!Sx81o7wj zukh#jui-zDv;PL-k5}iH6#mfNf#cFyGEy981Mz?0UdB&l*vkKn3V+cce3xZorI>Id z@qaKG1N zUS)-ikdnkN9NTy69oG0|iGO^t@RU9Oio`D-+xL_`|0?CPviVMRBDyt+f6^+yhw#gO zaq-N;>pvu2&4f{RgLTShCzrq9-6a}rXV@V8Dm&@@2aEh(!mry)P5!<52*2pt&HsLh zZ#Vx3DBp7aHzmH^{2wHI$e*_P*6oKwgkSF#&|&;x!e8$fo_FS+Iz9Zxc!w#oetbkY zzs!%%@Lgayx9tL>_nBu4c$@?KC&BrJWf|e>^ALl>u&(QuR`I!&F|14ww zXG6uj|1+rYZ?-P(75vX?_z&jnKcw()>4(`8wLil7*>D>ij*|8=MEw2l^5et7`9TZU zM-40dn{k?m{%1A(hjaEHQTU7TpJ1**{6~oY!-@Di7UDmu@E7CX^4E#~XwLp?h<|YW zfo5~G|4!;N^ncb6|9gJs<3_hR5ABb058-LNU7N)}>i^KqeTM$$+MNBzviL{+PwJl` z{$n}&k7w~Wi2r!b{_BW8?|-WDkZ*rgAGEJqNBkf9F2BBr@%%U6{Ic~5|K#ptYzO`s z(mftM8d#sR{{->p?T;7DJ$QB8u>IK|yl?FT&=o?Q4&O}>|9gM-#N5!zViWuS>tDiM zVY9M9!#|uO^x-=DZy^4Uh5p!ow&A}~p-2S?%!1D87(g(9r4XKzW{ttdPIJt(` z=kO~v$@tyA-IC3}8Jxe9=zF9ZQn4jx|MOJ-E|GxS9MJ2-!)UKs{6GKQG1&e( z47b0-_n2>gw`%%_->{?qR^tC?=#Sf98~!ud{DbSmH@B8c)CcO+gP0-y_gjwtHckKV zn=E(o-$wkuU^)Kh%l>z+FGzXm^Ze(xmTD~n80zSMKJkCxyJOh@S;GELU&XxtbAjyd zx{^N3QQdwDUqCw>sr}qe{Z$eMb=!%*pJb`xl>9uyu*1fL>l=IgllzXp z`uwM!zUy7v$Io*IADwxB4QAsV$iPyKQjqy)j^A4N!P2QmCboX9@7iz|(mSP^I73~L z@-s}+%_t?pZyc|jDgL~Xi zJ{7|6@ypNOv-Gj%bASqZ0|X5Z1CZkYirP9)Q(S0<}V*# zIQGiIsiPBXzgE6BTm`h_(?j{G-&F5|I^j3IQ&}#)c51cvroweIQ)AaZhBsj{h)+Y} zSC>yLEjFLuy>U+f+WZm1hwT?_f3BH4q0b*Be5w6^Z2u{f_KmTdgzc~MO~yVPMICnW-r>!| zD*qc*clUZgyngSjQyf{@>mI}YkA?FWj>13ov*7QreEkaw|GT0uV8OqTvwu{IS^b?@{>2;f?c0fBV%V`POCgRw9I(_Z4eB4Rzqb5)75?kM)@6R||4!Ho()kL##Q*WL zi%$Q_UiP0X#lJ7r9~N{Ne-r<{oc;S#{oREBpK0e$f6o2`ss3KV|0Qkzft>xDDgMk- z{x^v~Y=2w%Z{hl}!Bl@c`9GMm|4^#Go%|ol*?&0I-%kDy=j=a1{bB#tX8S)v{G;~& z2}|w&XsUlQf4-^R{*31Azb4f`nLppx_Ft2;|JoFPTkYps;vco2Jbx^-pJS>1cJgN| zXaDh3e>?dzp0octmH#C6KcV3Mdo+yiHOe~TA03hp_P?}OtJq|{%0Ifl0s6zR8;{-n zz$E#&_M@n?9{-wS8*4*WoBE*#c;nIQhh-sJap+Px9mfBkM@Y_oy*I|Vi~ z6fIWtkA~wZx*OO){Exr6=>QV=`RgmYW2wg8DEohZFgoUj{?V{%;tX{giT^!s4$Q!0 z@W2s>|HByo9Y)zC`}f9AGeQ4oUFg6``*;)aKlSDSzdSj(e!y_y!c1M+{}U{7w&3r| z{`?4pE&oZ`{}+Q%SS;lKB=NuR%>jPeE69KIlX+9rACCWg)P)7pWD9&3Y?ALru0&rc zEl<+wr-=XkZxt&r?yL*>Uw&AZ+M3(u6#u{ObFBDpPVx6F`A?_#L;PLGhu9m&f13C| zU^)IG-?{}-hAL;S7yUy$N&EC08r_(S}cZNz^&@elLg zTKq3e@rU?Z@xL&|-&XuDQu(_)|2-Sq-;0QU*#2AV|6H8n5AnC+e{qU`(EdO>ZCGYi z{r!*3nO z<3Aoh{%K+V@jWVkH}FSs)8i-aA^r~q{#uqKdn*4D_veAf>z_^f{~qywAjp3>MFLa{{hvAN537{xhpCRo z{~`ZP${g|k+?xZt10MLVF<*c8QGY!C5Bc+O(@y_kAMyXnTgM?InL7{hFIzZ&x?klF z`2+rp_a6-NXFu`(YT(cBe^tK6WXT589!T+j#FGC3;{T<fT!{#Q|dA8xnm zg|Zm`xo}wX>33Jl4XY3&H|H50x@%*p5 z2dHZ+=I!UzDgMVUw&QV>xloC-`wkA{Dc0RdHml`{ci?(RKS04 zG_3jhe&X)~$L9TKKG5D@zu^hL?+1wglc9fb{hN9F^Fit#&ezt<2Z_I*1e@!_p6-P3 z`(M+1N$TNnf%5&UUpRw3P)nsq_>JKA@0RHJd@(UTqkh9UCzEnz!XNZceyp?<{Khgl zp6+mk@EhOR;sO6J==}kDHD^#I{Bg_vHNv;Oe0vDrwtt=Q!~C&!e})F-GoGK;_`Q_x zH?Y;Q#_yB(y|{i^~R0i zQ(t-Up{YCco4gUi-{3#AY%@lqgumDCfBvPkU~1H_k@;t?)DMSbu$J&gSz`_kYn+}s zGX7liaDC@JUwNT#YODSX#|VG@v4@|pPCh+*c;>Pv-5Z83xc~8QHx^z^+{r~UY+o_1 z;@|o>;qyy=+k;X*T}Sv)`)Mma>nT6QL$`W@@VA+F`302?gg@#}K5z30gc~Kk-S&Tz z#P7A*J~MVycs^jU3P{qQArP z^)D#=PiORB$#8$~g5PQZMdlRw|0EBr11ZqN^Mn@ z|1WmT{}S;(b=E1{yuV6WWgHcE||1skK&|3r8JGXXy z^34IH&j#@~Z$CGv{HGMTjsBa% z`Y!x85P!Ho%sQZWLHu!5HY*#`{3%w`e8JYzlr+a1vBtl@<0E@FMjbX zl)_o)KP2k$>tN~B|Jg+RAA76#o`4SP@8g}OZh52)xeEU=Hy%66@LBACzK!{VrFGzB zHmFGd>k@zet>XsU4kw4Qp`)^VB zN6!Z@MQbl?Z<7AFD-)KE`M-tuKl)Y?uTJxW{BO-50(Sd)UK{^f3$N{eUW$K^|E(Ex z>m7~1wT*vo3$N|JmH2=Dts-_B{3dR{`dc%Ie7b#|QTd0E-dgmS32{|nIv9sRdae~ACk%ExZF2I9ZP!t*81r~aRT#!YTN zgZ(eL{fWLu>g)N$-+!yP7Dl$V{klN*zjJ-E{~wuQheyNzf)syS+pq1i|H2o0BI(4d zrvG-?ANQiIZNDy*{r7AMR}|5Re; z$w5v39mM~Ukjd|FNsrSc=a+H#66&9Ex~!vJLj3*Ygyy@y%wewZ`-r(D-@cSM$)d+vi^7YR>GT-X;&vn8N;=j+@@@**j$E@*tReX!j-|Qp&@gN7R`S%lkm}1uW z1B4$e-(!kQ)~kZs6bbFKZT~^SUw_ZTFH{e&+41$6k32bh!@3I|e*8P|gB$%ddPv2e znkIa`*x*#d3jX%^@JPhf_aCABQ~lrmj)m=RWX9N?;`Q4n@Dp(dlJ5ub{*PFntxI&B zaQ*h@-a3xKSO|{)NP%i;WgK!c`1Ab$O@D`}{e%9$xql&pKi?0~^e+&9=>KD67lPwI z=Ke+M{}^KvB!3w8xWNDIqL4puO-JYX7m5Gl;19=7teyWYQU7nj{Uubn$Ng0ww67}> ze>{JIQv~sEKW&yz%L;$xE|{i&S@vI#UcvgC#jyQ26@|Z$CDG)X{*@H}VEv8Y`ma^$ z4|_BRn8)Jtb}{;2A>BP#4T91+^MeVi#Q#fg6~m)oc>Yegq~kee8K_bJAELi%1B3oz zJuH%rv#1gO#kYdYG`)fX$x8fhy zV>Le{$_Lu~=_US8B;)@sJXBy-`ZD;p;@`c0pX}d?zXkt(rN6iZc$=p?<`1dQ(Ejuj z|Ko2R4_6|{pEaG^uTD#6AcH^SzZlZl^Tb9OBo(dk-B=-Nm@>Z0Dm_LdMx~v+a{;>TTgMV_t{881*V|5HN#n4iGjsPOkyp5X5n zeWhc&%8fbuZ&LU#t2{COs`_^F@Y$xE{axx0?Z3E}7zjFd;qluJvWkyg;t%(S=X*o8 zjvr1c{GXORd|m&^6n|UC52vXA5s;_b-xAbe`=hFtzpGF)Mf~CSJ5w-1^C%vFi!P=S zrs(d?W|hC2V4yn|^mqAC@CWOo&l1&ia5M3L@XdkqVH}tHTloFXw94NPEs}odpRCX5 zKTZ4}dUN0spj-R>&X#um;n(0Vn*LjezyIdIKYa#9z36-oo*#3#k9oDUzE07ZCq1#&|pVzn%Io z#WN5GH2t>||F6bWJN_3^|Cn!Q;6mcxqJsa2Tkmv-95yXnUu66Ks09^&>ZG;%uNGB& zi}!aeNqm0)$mGD&bcbUmAqZ zuRnzAGi}Acm+*(v`iG)c=68LRZ+=Kan0G(nj|QJw%l`qwSKWVD5bE;Hpo&lKKa5v1 z>6RwpkNW)nw7NKHx*@_3N3a(E;S|2D{2w9wD1U6-KYWz%ZO3N~;cq_isG+3GbZuja%9(D|6!c)ncsKd-q${6?e`JuC_h-h*7ARS&V0t6yPeI~ zr}5AiW=V7pp?C0CkXRnn+b;?x#v3z={Pp3j)Hm*q#(-Pz!H+ar@46c*Q2tCXy};k5 z&o5Gb=q>QC2L5t)-qF}4!r!2Z5B$g^8o%4uGUcn{bG|;mLiwurT%#YKD&emWo3f3w ztw^jui_v=5-B6A4Lz2Ls)aUn5e&{Xm=k()KC;Sbn_`r|!x{FF{>;~nl;xnbs@1=ZI zeD>+br;qT5!}V)Tn5Xzn7Yy2;e##HmFM)5+{tQrl=q>OK+Mg!jkE-Hh(EbckzA8Qj z?avV9tKwtO{tOfTaJYW03GBO`?H4dM^*7LXn)pH zzA8Qj?avtHtKwtO{)`iTBV51w!#u_OSyJ840zb%5)=_@AehK_-89*tctf&0YTi{;} z6ECL#I#f>(exE8n%IobqfWwbBP`)ZYc*aw+Y@~cue69ibvfd0f5q=|Fzxu;GMe35H z$Hu8#%69{nz@H52bpB3Ke&{Xm=YYJdLuYJ?@cUHpQS1?Co!e&0cY`Sf|Ea7rdAw=L zSH))^Ot&mgo26z8;TOa8s}klZGF*f9=RC>}*Drx@(EeW%+`T(av5WG<{22?E1CFzTn`zB*DdmSGf$!?`-$nVMx4`%GKYJ)Y^cMIA z`SV`F?+Np#mdKx_n&!#{lU+giVg3mGuuf+#dnrHk7WfB&ysSgVN3n><=X=8ZsU`Af zNe|7ZnxlL-fC>DtF8HLozxyaZ^cMIYFqgaIMq}?Md?(BwmdGF1Ab$=}ev~UoepDAp zb@BQ>%8$6wE3jOH{JE0y!~B6e8pp+rhq@oQit-~^k{{J|k7oxdKjKEOz;r$Mvkd<< z%GHF=Z|(t{jb}Fnv?rX>iox;2YY2Zs=qT_Fj=xnkHD-2zJdSs zgdg7jjg2MzSD1eP^9I6?uJ39l_zMR74-tNJsHB$QFG0L?%Z-E&i!xlAE5R$Y53Vj8 zraL6_!w{_m4Ui%K!!kcS8n80JwGH{dB=f^;w8Oti=7(3n+2Mag=2wEnX@`Ha%#ZFa z{99H0H|+5bOMKrA=qo(^P2>MDiO>2&zLoavHkl8Z8O*^({(M~KH$#6b?LTyk zh3m)Q_XhVgF2Xtdt4_&m3+4 zqKZ%bnWOCwk1wS0ukhQMLHzeJ9{-yl{wF4{Wp37(C&w#G{3)5w9BqC@=KED{`jf@# zEclh4)e2#e7({y@gYA&zH7oCkoi90 zPn+hthz0h4b@v}Hl=!z<J3_*>-fk@ygQi~RRWe2BkA{uL6x6fR#l zO=zM0->c$tf03`-K6@%YKYjxIE5hy9Be?z5D|0G7KLMHGx80F*n1wA}GONJi*FR|bnk&3@5IQ~Dz!2i~>&O&tUNH?>3pMoD; z10?Vt)8$_&@e8s)#7CEZm4Yw%!}%9o{y~XfVnL@Zj?Zq4|5Gz;N#_v9)e1g7ARO{D zTE56Xq07HU;umCph`%oXS_NP7hwY0l|2m0ZVh*fgJU+qs#~Q}})qinTg5`prWiRiS z_yw5{@zLdfK;nZx*Nd00k^cu3{NMs0f&ZAU|GdP9_)vd?_*}2xOa8F_>iXXx@k>5w zKPPzpY-3va^C1PFv_Hsy>{U(vjS{~g`(yky`G*vI$sgmd$^Wp#FEIv3WXSec`~31R zsrYcj#1{W172gf{!tn>an}L2r;!i`z1j|pLIcpss(Ct6mEb(tE@#d3XKLE4&vw;Q3 z&lh$1zbx?&%Y5c&^KX&(x0QnH)A0HS?thz!|F1~=!!qB%|DzKB=`hqkfo3RPzTeZ0 z|F25?+h7I5VkdtVBtB$M4f&9!(f*6U{`;*eKHYyY*grk2;?w;XgY)|zQ}OBk3$)L= z`!Bai{IART!yN7W`MAVCEawlzUpGH*m-vuBwEYLZ?)6J|sQ9$~H{c&p@!c^0qxPT2 zC%ozuKkB0Vn#7-y+kb=je?sEJ;^mtvVgFZq`Tn}ZhviH82L7Lv_>rp6enypDL_Qex zHzfWs)%vB)|4oS>u3p%Fw%UJRcm4V;i63m;dHWpk4bHzDmG~^YJRGlY54T^;^STav zIKihRzV8Mf;q|={-w(&`{^hqNK4bMDME+jfetrFJzrbdeyC(-z{EmvhkAIfr`?~x) z75s1s!}aY^e5SSepH}e01)Si|X!Czp!RMP_IP2B&->%L7Jq5pY{eKjnS#ADZ3V!SQ z|A@a!oBwZA{AXBD-ii3TwfVoV;=fG!d$jp~pyIz_kN+8&AEtkz{edeubju&g{IG#e z@ZkiuF8{MKKis|x{O~()r3jyW0%n!3s;CsQ?-Tyry^YMCtpy2P1qH>d7iaN}{ogJu8 zV}w!sLrr+`cSKa<*8<_+u+}ag9x5gH|JtZsJ_K9f|Hjz?2-8mExU>K#1pcqR3qJ8K zZGCJwzc6c@5@&%Z$UhyM`c&v(EK&4bB{gnt*FT(IcR*eN0YH?5uf7yg)*0u%W+Yz3lUv&JtH{;zF8;|s0v z8R6gf2K=nmuj8Wto6)^EOk(7)yX5%0K!l?LY{`5H6bPTkANd~qv%oJBeh`0PyLR}D zU3Uk&xjv1t#{4WEfIph{ZT`j>QOV4F^xWx1w?3(&CUOR#OhhE<_k8?PH z4?OL~G%_nr2LA^Q{NeY|x%w9}_)i%4!}Hy8^)IUYYvM9J5&4t)EcpY^j}!buvda^) zS8tyvX;;eN5088f@?XOro=>Or_i=@?;9t(*58qem&-g=!lhKfe;rVx>|LdC;aI9ec zHIILV_*Y$c?C})NAt;{DO8ekn1=}Ats>N4);AH2APQvr`1poUs6tU5tzYXH=T6mOJ zmH0PYh>h%jfN#;@vsTIG56|z*)xSpkhh4TbCHXH+4Qa+7o)4I-e-H8B?6R3>C4Z>W z^oQpU=IUQ3{yhJ~1N2d@;5xwbpR_+&)?awOq2Pc2h5}M%G5?zu+MfpT=lL)D2l=nz z56@4`)xVec^Zb|m!~ECqhvzfq>fcBFdHzfOVg76Q!}A|=_3tPCMHkwC$)A-9xc+MR z!}BEt{|7cW*y*&E{{sqthI60={Z;jJJn|l%Un%%QUlvOf*IyRC399t|I_z!X`NGA; z!kNXnSDWsS#{YRl4=GGlkod>WJU{0Qx<8uy=P_YSy*JPYp#I19O?uz5bp)j(@sAxl z2K@bcy3$l-iC;wjAKLP-Nc`jI|3h2;Rmyix&iS~bXQ|XAetDlweh=Z77mqI%VEGo` z2v3616H>pq)Qo9NZ{5&n31_Ee9inrdD=zHu9l zZxG923A1zPP6WkzV9zx>pW6VuDZeLr;GE*|JL&mo7& z{&0Xec5+-84E@h)_&Y3L|ANB5UHro@mO1`#ZI2NDKMmvmG;AMj#J{NUZx{b={fjyK zmlXcVj+Enqah(6q+IE@$CF1{tkpH-=ZC1((|7M~i=(xa-^S^ula?bu0g@3#FhtbNM z{}tl@w2=Si@vkcU+r__I|7y!e!vZtwuJkDU zp?jtDKU?hHzb9w^y22kKp!8n_|1dh4^S@5~|3t`t^Y}Lu{_W!5t$!nD|6YZEqWi!c z7mTC)KMqHfx@`Y@iT?>9|IPcMeG31k56)q6To{Pje+~b>oc;S1{_Wx)eyz;;-%tF% zF66&?{09{N?c(39|3J?EO@)7A`|E#teId@D)neRUWR8E6_@8`g#{r0e|0~e{-`#7z z{T)>JC$_(W|5*+H!JPev6#j|sTaYeM`x8CfgV*BO!OrKGhlu|pPx0e>9vrtRj#)Ur zGpz7$#%U5}yMh03&i*3`e=+_O%r)>IY2(i<#D7%bFUG&+e^w)ZMsxOGqwo*2MttGN zAH=FG@756ihn{ly5tJoIReQfXhtbM{}S^!FsGz`s==^+P-PuOt3nn4I-7{&@Ut zx;J>lgEX@)D%NZIhqH(>A$5-HiT_ifKOVob;Xk4DhdvJ}LHt|wS>r!J{2vwKPfp~K zd1iULLDN5EcZ~lA;=d%s-`szr(%+T7dJz9seb)GIB>tZl;%|O1eUqkt*7$EC{(mgQ z-`w9-`M1IxF9#m~M19uy!{sKz@#lwy`0Ly;DpukHlbZe^rDOh2692CW@i+IMqW-rr zmI!m}%f4MyUCcGx8bLiYMf@Lp$|=O#-|gyYx~biq&A$oFwaOoVtF-HS zu(<^PR(;m|pC%e_Pw%^OXLr?QFClg7~-Uv&R2C z;{Qb<{^r}St(yK>oKPklD+a)gwhWI}w#NT}TwN2AM{9+yR ze;e`tst|v3|MOM;tuTx6-yFYYrg(oNd0ePcdjo;o<40q!|&D6|3c#b zz*9T++4R4N`iEk+UM?d3eiB?tzR??o6LNR357ejeOadPF>G4nQJO1kPpL+VPcWoa( z&mDYp=KVET8Xg|>)+sP8<)1lzYvBh=ryiNu`nA4m!xqRpr2~g)Age{bCMRt&2(iF# z9Iu=y{vmlac|-Uoz2hr$pSta?HQRg68ykFh=Gq$Mn09<10+hdeeBszD3#X1wto>T~+OVb2 zjt@L9TI6>ff%X$X3n}m$->EDYUpuwhdsE>=ymSrX1Bb*3zq)*4X|ehI?u~njkH>D> z@qsg3BLAwGX=MO@mnic6KJTif*Ak&In+@DdMd0`O)fWd}9Y0;F3D@pv=O-M26!-&v z&s=fx*r)c~RoM=C9~JHRLz^t{8=X2#(Ht|rLKFmk9G@rVt>ouWI{(1zzIX$s9sl8W z{IAbUM(u;{_6x3&7vhsxf3KUd;6K`qKQ(6T54ZA5_n#WO{;?*{QtkM|?L0(&Yx{WJ z?tSt3acw?qW7GLl?qt+|&|SXc?fKU~(c~+fwm;mcF2J2-BoeS^Ch2=R&ePt03czHU1I zz^sMkJK2u^^%>*kJ4N`3{`1ol7TSl+>HO<<-_UQ|K1{dcPr2LfHEbWYwC7*{#AEwU zne?Aw)e-X3`6go@j`{}gI1K)WvdaHP)!n^r7tW6?{-Ri!S-#sV!4A8P-@iKw|Jcuh zzr*tNFDU%)ioSpa|3c3GMTP%O#DDdie)<$;f7qpDUd>YelvMsvw-e)UcnGef_Gfs0 z!AAa<75>p3;@NZN{$=9-gA^PQ!t z%Ae;C^ep21fdS1@CH{*S1t44Tuci9KVvhaw<6oox5P$pzw)}e({&A?$pU+Ky`_&`+ zTit%ussGOz3-UkAAMUT8KXu~&Sdc&7X-oOvNcD%M5XXN-JO3NhKU{xp`S&XP*MY6e z{Mi2;M?e0(#Q%%GC>AG{?`D5#DgJ$_{;+2p#^1!hFK7S$RDU<&|7Y6y)1R~dK&ro& z@PA3$e;{Z7W{N-mjjo0KX%c_f{wDH2Jo*Mrg>D&4^|zD%gE{*TrTV*x{L#<8XFn(Cj-pKofnKchMOuSxY!=Fj)F{nzB| zzc$6+R{Ob@_($z$kU!?_=UA%0o%|Wg*?&CM-%kFF=j^{uxlms zLrk#$WxoHrUgaO1Iz@jNcJTYepI}jI`A*r`e}n9Q+NS?T>R+%M|BbT0Ytw&|>~A&xn`Hl4 zoBl5Gk5UKcVWYUj-%moLk@^$@q^$@;o|2pB@&YuS5GrRfOOZk4oywi|aTzwMX!cBD({C=5l)qjBS&3`eQ zkcYu0;Wxfh^NNS}i6a@j8&dHtMrfGuH~0@N+lcxY`m3t!Z?*lbDg5K>PvEq>>H1qE z{(cx5Tk-Fq{%|#E>~Ep{>B-r@PW@r~8=t?x_`@dBz}`9hC4|_0M1Q=Iq~>;?K`tSje9~;t$)eME;m})caHY?c`5?&i(_b z{&wwk>7+dEr237vi@jdi6Jby7r{PD*MSOS0Z{2!wJ zmjrzN7aLE*GDQ6E4|%uo>sJloF!?a`Plm*T|8RFw&T;EGoP_r#OEtP zi+X^?i@?Y4y)&f;H`{af+3 z;9pYui~Yj4dAei%kopWyPcISw<3Fw9`4=eg?YCEgL4&{L4E~I-W_teRoc${b|1nrs z<%0gIdU?!bO@;WM_-VDZdH-|s&O}w=e}JjhEA&^@CvD~7D)B%0(`s~dgR$*FJ1kF? zy{4w}7t=h1fxmEn{%rH85&tg<{@pK6I@cbBf0Li#p=0X#_YnVkep-cFx`ZWp2cW2~ z%hx*f{~=rvr;5L?=U*rOpZjSQZrKwS3;qp-e@*E>sFgnr*&l8RWY52s`rqQPHJVzt#BnQU4^%MUGU*B{9z#fNBbl)EH=@NeiRQ`TALedZYllAyn^7C*K`Z7TLA9{V$jWEsv zA8!JfhNY?U$L$w&L;t8ga;M`cT$;rHk=Hlf2BZ0W)QJoL1v6PSnC71x35PZP2Z_J` z`ldT$w1w^O5cP+?5B%~`QU0~azk=eEc2z^fzjez%?0>eKGTUdv)E}2Fztbq0p3Aqo zUgXo%x5LE$f!82FQJJ6(TJ%Bo*AeQ^Q&Qon=|4jKU*F`#b{70csXvduqFsyfKc0EE zfl=cBc_IGh>+c%s&yn{0*HC{U{^tH`sXxYFg~j-*>N_lkwZ#96$@o9nVd4xQk5PYg zRC#Lpk5T_*{4My8Q-5q8l+D7w!lCvI0U@J|6MyJGkHn)`=s&Mh`NuOz4uHQ#Sx5X^ z?LWXQwEyd=|0$GIwV!yfL{Z=2JFO@FUr3I>U1NbJr-$JQrN65EL4QR(;nBAf#Q(A6 z2p0Me8>s&QoPi?F{9v1+KIx+v-a!1noE*nO{5LB76>;YNiu$CFVt6C*|4MQk3-RAX z{hvV z@wXlSDal{7Hhnim`~}{h3-7evIILGV{|@Ju=PC|6z3<4j=f)2A?>zOD7ay9sqt#{a zb|&z1Vwpd6(i$Ib;wSSh`j;gB;?z(0{Q4Q!Ui&jZ`N7<+tzS*T zA2#nY3-K8we8?aC+*lpii%TkF>-;oH9dz#7627rwRp zTub=j$u(=+uQ9^6?LSWVw)1BlsK?e zel0M4|Avx3#$rCKUncxsB_GxR?jM8^`3pt10MA$@*&m3$H(w|j0h#h8*$;$y%c zr~GjJikC0O$79+J&^jfb#K(ZYUdbo%G2l-Sz7wurEU|tWgr99t^5F`Oh!5+R34f!K z&suyKM859!Yg1c3fT6hjuihV*@;M9^LKGj!PuE}ulS)2`zX5+r$%j~Qe|Uvr;=h^l zIhVx8(_aSDNE+qUQKCpim@ePj;TtxUme4u}u;4c`&=VHPS;se|F1b>MS z>;0J}{2)HCf11Fp82IlX{OHFKL41OlEEw=FA^h;iJHn+zOTlck{_Z4vSbyRAB8bk} zbMWX%SicPW54&VOJTlfE|5BL`{t*4hAGhyXkqIVxm&^x$d;E9H{NVa7?jJaq`0tka z;19(T|1y~m?SC`ee!&LPF#eY-`C~1Bk>_W zMZRmougiR&@TX1q4Vll%qW_EuzgOnd_|KZ~`y@W(r|7@Sgx@dossA1m{(!`X{N$ZO z$j{G0LWb>US@Zl|Q{qE@ihLK>FJ1ni%=ZbOx1YNFA(_w0qCamxb@{_GpT?iJpSt`J zi4XZH`t$Zvmp>}=sXuQ&b@^)~KIG>?Y$(P2?9GIdfd>VhApSt|@5+CwY^ym4h%b$?>)Su_4E`Ni>p9+6P0Qre&`Xjs_ zf#d6L-#5y9pK~$)13va|wfUPQKIA`gTYT4q@5+3i@G<|j{U>EU3z~vBKA8X7{3)65 z6Fyv}ug~AC;FINx>zB6ww8V$?OI*IVerfZ!$b6shcbo9fQ}9WAaQ)Tx-zxDT9Uz4*R1kqCH@(!{2dY>;!pF_VE^J0i4XC&$lodP zA^sNmyCgou-y;7~i4XBVh>Z@kpV9hj(Eogw#E1A>CKJzv4>`I9b{=6jk z2L1o5Bt8r8F1M0+jGX6%Gwu52pv(`yK!OiP2z1NUG9QiyU|E6l%TQi)aDnKCpIsyK zgY%mrKUye!mfifhR_2EZl!%Xk|8+7yOdNr)?f-t6-yeMc1V36Ox(Q4;?gwOkcnL(f zd^MQKNj@m^!(3TO#lFzSy2>5XRx?5&)e1{#m zgB_?(V+3$DUAGF&g1;j+Ae$?j)}3Q zUJKvBVG9C(U9#C(HlKsTZWH+HIUl|QzOLBdKk;$4uRe{98OEn(Atp&gfrh z|FZC@`5Soth`@i*94Qdsrf34+7d|zAdYqJ&IF7j)=BWor$&YVAci92ncoK+}De0bzXM~{8FvAIX0ogNt1zdq2#eZbXjV`5+zLMT+mE8c__g!(f zVNnm0I#rGEKc70L-UmG*|Cv*InAEB2BLDtpQ^(Z%pv*p+Yy2yOZ#(`~k#9ZzHIZ*U z{zY;5GTZrIB7EENFN=KZ@vn${y(Dill_M@+>+vrTzU}xIMZWd;mqdP>Na}r5hU4+c z_TP2~y^=GZ?fG`H|2e)ezk51)>OwCn@l-`N|Lx@cm%{ybFFyIZ3^k>x`F)xPCd!0A z$>%&DZ;t2jePQ~*Va=_5Maf@?`9}@;HNr3Y2*mPPAOHFouoeCI^iV#B;vatU-RFEZ zHGidM{Oc+{Uk3vIB46NB^Vewd`;`3HKZp*i0B@LLb}2`)|u<1;g-=|4>P_n|s3 z@9@7N|3+Q@8p59p4j{q-`p?$*0YyAi?@k@KUekXq<>NuhCSF4PS^SYSA2Q)jP=4SK zGYS1MO5p#gR^YHEbJ;-nms;j;B>WvIeBJnOBK*yk`O}0y$(Jww36?K!-wfivh43%6 z%s-Ftcck!jgH(TbPPxzBAgxSp9|LNzeL07Gh>z~}{Sw08iuQiYUyb;;YxW;@68<*J z{9S~<#WMd=!k@Iv-%a>D{%ky2zH$6Np&9?n2%pE_BL8y2=kd45e-GjF_*>*(LHL1x zod155|GMkfUcwKSuRXp;_`&kE$Dbp75}!Cfb>p+2@Pp;sl=5Gf|31RM6xUy9_!;{Q z4y>NTzXt8+l}bKb-(rb>knne)ufkuq|9`cTFZ=8AuO<8-f9x&a>j*zszwGhfPx!(5 zWsmyRvdHe6{$Nv!F2k~D9|3v%^_#YTllRqm0Jk^ z0zOsD_f7e~LiiV2=6{s%FSg8IAp9`?Fc)$ENO$?(O88;?t?>^Nei(mi{ErcS7=LU0 zj}v|nf9zic`@d2DSvUT-6MhhXdwjV0)wh$!=Y#m$;~ydXApZ9FpCJ4o{>xGOvwH5m zuqb@}_UG5td~x~0_Dgs9{)UpjB=VvC*X92v;RpF+kN;bQALNfc{!zjY^2Z+kw+TOp z&oUF%UxVd)C*cSE|5pE&w+{>Y{fFOG^6mBCevj~j{R?~iy9htXAA9TXzftq8E#E&N zeCQZL@%dl;bBb5!ufLxm{K1%<*uJbx9n?L4^oNAs5c%P|^R&;eIjr>Us9L6RzL*A9_E3 z^S_&d6kWOhfBVG$Y>0-*i|od4vk%v&v0cFY$Mv8Fy{oV+zkn53;KNC;z;L{!(*3+D z%b%LWKMGAofjJ&b?eATFVKdy17=LDS^PxkVuP(gU@OO5_?~(XNfbX>U!-T*5p|1FK ziT{XI|AxeeEs90|e!}O+mP&P2@*syW{(r(ewg(pPHHQvOUVUu5;dK}P0m3ihu`A%S z7M~%XY4V2%pRs3v-_!E{g5dwlT@3Hk3=gU{}=lRpU|8yFk`Y-GGZ3FD)|f49VECHRjuJ@^Lx-MoM3;IF{m0RA;+VEeeUtM*}c3Lm!W0>6g* zt06vJ^4}x#%aT9l&k^)Tes}Hvo)o^|5By%_bN}x6dnG;`TPnc?+)@AGW8jYdmm|OX z{+p-bp9psVuzz@M$e#`Qu!qo1|9>ux?*UiE_qvPE0g3O!A%iBwC*&8QoxuE@3H_J< zr>^|pm&ONVuzdtR-mbxo_}#_lpu|7T*ohj_1O5Z>ip$s2i~rSWd@qIHW&E#|_|Sho zknq1(@Q3!HyZF3c;x~)9{sznU(qR7-_a9%u_!J)OwtbkF_%3W;;GYLfzY6>Uyocc< zhvug^{|lw15-yZ%<@z)}PM+j1MEqh`{2L{{7x=Ekyj1RQXke_#Be1cdl zAm0n}r;FvgAn})Yd=MYTKNy_V^S@Q%`*6rFKtlV^{rNjL*pWQH9MTxSyO#6^FBa*p6msUnW4Q(YLt*L8 zGJWhy&irc5e8%qj$K>)YE@9_tJ9DG2d~OvUX4!fhRcC)a`j5%qCq54iC$wb|xKdd$F*o{}}Nv!Li^8 zy-+Bp8mInC82=IGMq?Z9zl;-q+wJGN6#q!ywEw@3_}gwj*DL*pVtrHp^*Q@9_ATZ9 zd;A3q_aEVUB4Pi%1V62u@M600fJ6N)@Bcc)|L_8-Qmzvca}G2-u7_8*u0?e2e# z6aP!$1{P25H-BzNE01gcB%J^9(f?rdaj^gX(dez#>pvyWfAs+Zega{wz{zlh|EY){ z_W+x;t~ORoNKvR&}s&)ZKt1i_2P_rK0YZ@Yhmt9t~0{`)(N$4^Sczi8PXF2#}j zZ5}_V5dY(1`xE5PJCFsM1+HY2{F%l0SBZa7^oJWHt-|?hegCS$-)8)4#Qz1}{=~#x&io#UZ#VvRiElUl4T*2pzgObh_3z7>-=8yol<+5;cH^^_ z@Yj5cL6^l|87F+(+n03`-)?-?=ggmw_;%N?4HDmOd^YCHXKel-*){d)GNdH#6@{1F zT1!wz=38SUsE{)so==f$d`dFkYJAEv9~ZH;dBF28Xnd@(5me2Y56{=g)gPX(LHSnW z56{=2e5>(q$b75*y)xgbKRh2K*ZB13%paBc_EuhqG(5k9#>Zy!z{Zt)dtYIl%(t39 z>vQJA^Gy`-w-=ucGT&-^Hs;J9V@HJJCs({-w|_Op7Nq!F4G?=m@VCpx3+Y7uWb^sj z!TG}QlkhV+8>J-i?Z&^HGruD7?Z&5?Gk=8eZRh`J&iu86|DMui$Y5I%O^k|jB=&TvV=*Wsj1Q_h)RQSfcXrV*Eowt2hlk3;wuEX*}-SuKpc=-D|;St5Mf{^gwc z6~eb2pK8wh8sXcHe^1W*I^o-nejQ`7%P$cAzM7qWVf1B-IrB?7^UFE&D>?J4IrD2d z^LujU!;Jx@{)x>N!pWImkonQ7XXUk+GryEGznn9_k~6=WGryKIzb9wD!0PsTp^ zO7iz{cC#PPzbpBkt@#wxeCAr3K{JJK>kHgX_^rNk34VHJqkQkTlF#R|K}<3nM))55 z;?GNtVLDv;+kE{Azhc)PZk8|l*MRSv#-uepJS;-wz8M#*=fzqigqfZ*Ve~| zLk<)8c8|W{_N({X$>%4&w77A$7p}UVU`GwbgUJh&|LdE+<**m}estDOq)L>(xDi?i z`~k2X|03bv%lYuDT}ym;vWt-aUJy2Ge_{CweBT;50KxJV_>fRm3&daG`d;N^=p56+202tI%47ZoACR@Z?oI#(|AV}{QXY+)Axeo1#=;P2hN?t>}{1M z^XK7R!Gk~S8_auA2r>NrPQk}H@i37aWnldPgBCVXKT~4YW0eP=v2Q#=_ybBlj+&M4 zw&f2g`LRFQ7{vaGdeOg0{D+nN*gwI+Iu&2^r~EZaK5}@0jb*aT@;5NkME%U6nd_TS z<>6=FpnUj!qGI{RPk2ahI2wNL&mZ5CsCN%NGY|ZN2cO9NF*P5@#ggFQTUWsk{RFzE8o&_(RVE{(A7QRpRB_sxQrye4hV4j`l3`U-FX;4E(+? zg%9e{Qj2F0@`d_{&sUgd>H51Vl^LQQlb?I zaG`&)zC(PbQ~3~|B!|yH!DsE`vn7=e@!{DRn78~PK0m;h+s0=$m9NSl1)oKH zb$oWD@>ThRe40P)ngu>RaRJjN2&moCTlxyB01P|LnCzyC!) zSaSH5u}j%_ALr~G*#duE_%ALYe`~V7v>W`79%KdHY5Ku!l&`~lzgN)N8ZOhJ$w_CFg{noJC`qG7~t`N9%4%T=i2at_j|I6|A2}gH?(KCS$u{#UB_ z1rH`fz6-DM@=fp)^&OV)RZ2c!V}B3dU`g=tt%rZ4u>QVZ#V>e(Lq0Oh;{O39AF#2%hi|YDe~(wv^^3;;dKEv2 z|1@e4SvV}*Z6#pnKmd~+zaQe(L%s{IG=I>4YpcG)`g@a-50l6K9=^ds z{5@XTDSvKO@wv0JB;^mUSLF}RDwtn$-;2Hz%$fhaMdm}ZkK;N^t?_VKo(;mzRQwhA z+=G9xf45)c|EkP~HVem{TuR9wxIFYK_&my=ON9Op1B9ELLC8OltmpArxG|0YNhKel4wLyup?-kL zd=L6>>iGPYitlm%nKI5MT90t>pN2i;mvA_$=kdWOO#4_V#s6qWK28>v6#mSI*yU;b z-%;`L5t9&~lkj&oV&iL=pC^*_9rE)|B_Cnk@YD12cUAmC;9rIYbOvV?l`wzs3bweu zL;n1pl8-=#$^4^G56f5Lr{~Y_OZ+1+H5TVckUzmYX#a!F4YZ!TnTx7}{JDv-FJjF% zX#eLAB>t(6{2)KW8Fb)(R^q$i_QhEe_pk2?+vkDRZuYP5R`ClS$T>^m{$q>Z&HkgW z;`8l`~Yzp7R&t;{%lc zfQldc2jt*ylF#QCRP*(B36A9dJ-(OPhX+;s*grr7f7|g-r}7_C@q_gX;^P4tV}S+v z_=@rO;5Dr0{;lJ0jI3V|tM~<+9^>!AD{c$0B>67959>L<)&HdY&#U;cKXRjzaX~$2G{})tzj+OXOyA1y@{)rO!r{@3TZTPKr5Mzz)50)f<4BlUU z$iE4?yoF^P{om5_FJH>UN3M#`Ad@4$ha*Y+C$jN@lgei&xWAhJRTV#2fBls92ij+h zmka-(1pTYj_&=%QgDvC_@DuG!tNj6fqCV*Vq_#hQq~gc^IG?CselEkCVEYostAyLH zrPTJ}Ybt*1AF=VZ9X~z)|5(Kjx9=(K55&iV`9`Sm zMft-=iu_aa|Cu&?Cqx9Xj@Ms^e^jvjxuk9T^Nmb=V-o+g z#D4|+=V4UjdkmiMfzv_xA?zQm!s`Hg8;)Pa^*%rT1IK4P_)Nb3;V&fqJaANe-2dvH z|CbWK2^uYa+|Dq}#TLI+-`@Yo9< z7vhZH2TL;kTU+%!{>8S>p5QU=cZ9;Evw`3;NGOJ?8&f=E8qLnLYGB&g1cu zgZNgu{^$8Nd>1BYaa!@27V7c%WQ$Mz&vfA99DLx+}R(`kK^%G z55|`B|HTgc&i=b0{^|VhDEW;0`ye!nR=n`#3qu3!1pIB)&mQvUmto(0xqQxA*^>4t$kA<+t99>N8ul?U%v#e zGw=_~<%hm8--PXpI{x2p%g6b+2!Ybde_VfC^}B)J%AY1_pZ|lzuOSTDX!OTnc;N;4 zr=cGG2VkyVP|dJ?@Sy*%_WwaUK4dAMTg+eOeBt;f@Q=^GGM|>8|FHvqCbSIWqvZQ- z_NZ|DCHN`91|E<^{1u_W{7;>7aB{G5gJBL{IL zsr~<9TYe2D@o+jQNq#baFhBA9iwEP#{Qson@_(e{2l3D5kK314d?^1PJMcUEmcddFnKHP-!Q}B^u`}kT%K2C-uoj>!TCY+!0a3rb!`Qr|Jmg3*47yW7b`JX%T zQ45RcpX4X~DgUQ3A6Vf!Tj1ctpIJU!66()C1pERkcyOy*_AJex|ElD34Bra4;b8F6 z;{y(XFxc(Ve)MVj&SbvlC zz~}iB@TK!R|6R#PXux+<_;GzH%%2qgStTE*&dLw-Cx!nnN-}@8V!o5_~tRV^Mt6{QpnM$EmaOqxh)#B`59o5sLie>sMNSdKe!m zKg+3nMSgOAT7GiAl%EwPAA_sNp9J51Cn%8%l&=GT<`l>AKiqk2%H z{PdOi*`ws+l#2XG@ZA6of1~_V^Xp1JPMwt>#YfE_QSt%r6})&m32);9R}bK7?Zy@S z_y+ubO5ML5?Z9twLZE^V$2U^>;}U-v0)xvpD6J-F1&(WB`yVt*alOy`C-Bz8kEH(j zI*IQA#~y!!#7B)5AKwK9`{%R#2z~6%Kj8U!IL&`!WaVy5`Xd9QLhGChuSIzyAr_ zXLA+>!iVD|&{o+iMZ)*~)E*m2CBlc3)@y9ep-lM8mg8T^nO~)Ry!g*zao9m2|D&TZ zwq{Wv{H85%$SD%OZ<${re5)%LxRwbYJJ~i%h496`llh#ggzuUo1wxJRJ>gUHH$8;U zEH8jMN87PtXSYEu)K8XI7)00&Q-+ucb z`nz_*9#d+>--|!7Gtfi$_S*+BKFo3gHHg3M_Mw;XnQtfV5e1$fy_4NopRPj%whf!v zZETkx?rrjs+<%50fP1TKmA~uu4{X17Chsr$0|5B@yQQR$56^cN{NZ`ztmX$%@`A}$ zxj#QVwbJzt3~XNn|5t(O?@agU_7ix%v*5p(-Dx%cy~N*k{HttMh|l!Jc3aRo;a_<4 z`G)ZO!)^mk#_uJ3+x}HHvy)v@pT>PsT)%K<+U71sUBSnBkguuzwpYQo>EB@P&gA{u zTjyQ1m4yj65dMPjsrj1;!Y4OBGM<4$`SJO1V>Aa8a^`O${DNhF#{RSLd;#122Z!*F z+6jA1DdfyA629&DlnCE;e0p-`*9qTtd>VwW*NckNMH=WOeB1tgg#UJawthC!`mEzng}p5Ff1Zc#kInuqJikWipI8n?{?(lQ z;rTd%zwP~t8u9;u<@nc$KjshYUoaOk1OGt@_m5^_P-p)_%%4BKl(8rG+dE3op#G&h z3z+}#e{?ANpZ{;3|M0V^#tU~x}W&lZhx8z|6Le=JYWzMBmZX3{zJsy_Wtz{@weUn3={vT{b@q%-6;P2 z_{=Q4>%RRNCjNi@ZoBQz2=#BZKT#uR)c%a*>^~~`$L$aC*K2=9bM~*WqeB1W(9#*J zM?kAN^J|1}`}jQ}Up$;Mq6bbLI~z_%`!@Si#5hFHuQZZ8BGnMRAu4tVOkyg8rocW_U^Xu#h(*EF1VPzbnt*Pr-dPcO{RXJK=R#e$h@x(P5&0bbXNv zUlIR734TAt?|st!^+oXecftSAzyJ5hTs~JkHH8DFr9k{`U*844uNVAn#~*&LCge}C zb$yhT>oei^`+~pi_?IOA`1&Z~uXlYE+#euU|1$LtukTGu4(`nU2Y+EX&Rz7FnhkgGrZ{*>f@oIk{0FMr_or@8t=^C%qOvweMzL-@9@FDeke zZT}+S+x9Qz%r6tZ?dzi|IrHIn+d_WY_Gj!3a{Sir?^_)O-~6mXtJhIb@NHfnQdID5 z`j>L%mz8{b=XWYO^Q$@Y;dkA__Qm%3ol4GpILn)>f0>;n?L%wbvoTc3nP1JB@35v2 zf7{n56m#ao^MP{phiB*!zTN8+DmnAvS%10uJFK>g-e1Dz_NACJAD-itt3Ny=QNg#l z{mPdQ&vMMwAD&?-ASAU1?R^(@^{V*LW z=FBhU%>VysyBh$h%6fm`&%Ep_%QCwxupq*K3$BW~Aex!QfQXBlEe3{WIUo|1>0($^ zmIIQKnJs2TFE`h&8g+XiuXU~4z3mzhSl7U$t7W<7>+N5LT4_n_|Mxs+&Y3yi^PHJ8 zGr!*{hj}^YGr#>k&-tC_oH=u*&g%26zxBd?gRnnUjrh;cjPssAa5VVY9IsE`%6dof z`GJGAcKE>Z`&SqH{ejnOdm^S}{kX875cXp#x4ZcF5!BxIr+@J>{oFUxMBnf8`*hj> z)6m337*kt(*TCdKd z`Z0BjuYGef6E|0JnWfNd#?jv#Z!TO~D0H#NFC@^vP@Nl#yma{)W2(c~zRkN&=-|wM zT-cAPPG9@(ZkyU${;!TcM;!cNWQoMh}Q1ig~EQnu)ki|&kFmig#8}yx$Ea#VLvVG&k*)=;B(iXO~U?w zu)j^%Z%~i>_J40)*rf()+2Ms{>jSh|~r{5nGjXx#q zw+Z`ne9U+L;nG-I<-9J+ai?pf`246B3kQHWaQggI){hJO3Gkm}&QB72?)=vY`}M+p z1Ne6`=f4qr?&~`>3H!~${up7uMc5w;K6n3V1;35?`fTIC=dKSaVZTk-ZwH@y{T(mt zPX&JlbN}f8pF2Mjh5bq3bLXcMeD3vY3i#adPXnL3eUAp8JAS3k|84R3lk?n3J%FX_ z1B?1}ePEx@dG4)_pRNxq>eKaseLi>o>H5H;em(fy`EL;R8^Pz!f0MA^3_f@M#|Zm$ z{bbSpN!PCy_38T3KA$`PbbV$~pRT{{^YwRBI48P(wWv?mPxkqfID;pPuKz6R)Ag%; zK6n1<`rD#DU0>SgbLXF~FD>fR^^<)*cmC=6$)Y}8AKT}1=bx^RE$Y+tv3)*w{^|PC zqCQ<;+UIlUf4Z=r2EUWJe$Ei~XM#VSIsRjW{Vwpi^FK@2pA9~D{*M**yTRwq|8c_p z@!)gk{{&%w4*1;pKT+5}34HGSpDgV6fS+crpL2!%dEg(*9RDf8{(SJ6zLx7{;Z*Rs z^K%;b-0{B-eD3&92cNtDzh2ls1AOlMyg}GM6Z~0T&*i!EM)0}Y_f6n)$G-r4?)J@q z-_4VDPgyAJF9QE$@11$>oF(ip2A@0sXAApFz~|2YIl_J~_}uwlD(s&NK6n1l6ZX#s zpF96=7WOXypF96=5%&AQ@8Kz%p0Z5XzYzS_dGE|~=dHs2a`3tHze3o*2z>7RzfIU* z2|joJFBbMM0iQenZx{A21)n?r?-2Ii2|joJFBA5&;GfP@Ha%sPu)iAo1>QUJ+__xX zUjsgO{;v@B*MiTT|91)d>%iyE|GS0#_khox|Mv>}SAx%-|Mv;|SAox+|Eq=le(*Cq zWz$pE3;WlAe~$OgJa^tN>~8=+!xOfrTr2E<0DSKJe^A)p2tIfIKP2pb7<}&he?-{7 z4t(zXe^l8282H@zzh2nSf#2&@4xT%kg#FFnzlA4kPq{(Z-vT~&{y#44-v~Z;{%;cY zw}Q`||4#_}H-pce|4$10w}8)`|4#|~w}Q`||4$411K{_0m5=AnHevrZ@ZZK0wx@hX z*uNco?)-mN*#8{(-1+~!u)iIA?)-m2*#9E<-1+~Ku>WQ7x%2-o!v0sl=g$8f!u}xm zE4|9cbLUQB|Eu6%#uK)u{Hw5k7x>)yzgyV92Yl}Qe@)om0X}#Bzb@>51AOlM|C_M? zP4Kz%|1Dwv+u(EO|2x9|PVlo{<>R^YU19%T@ZZG~wx|5Nuzw%;S?`^B?tD+!|33KK z`Tq}L|9pF98mBkVr}K6n0q zA?)u5zn`aUdddM||6%Yy=)E(~onH$3kATme|AWH*ufXTd|Njd6kAlyg|Hp*=UxUw` z|KAAvkAu&h|KAGxzXP8;|4#_}Bj9i3DVv`1q_F>c@UQpYndi<^!v53XU&j-+r#u5b zcYdA)pF95Nz~_$tdGNXW|Nja5e*m95KmSkI|0DPx^?EMPoj-xk-M%k?&mI4t!RKz@ zL*VCl((WlQ3i~gCf0OslJa=9e_WuHYjwftS`Kz%1H}JXh|BA5xD)`*_|GTjN5AeD3 z|C+FW7<}&h|5MmM0zP;CM}>VA^IyMot5-RA?!<)sIQXCD3ENW=!hRBb?)=vY`}N>+ z=f6SNZv>w^|4qVvGx*&3A0zCyfX|)(vBG{U_}uv)C+w%dAMh$4&z&}5za9L~^Mvgw z`w)sJO4)u`_sVZ&i`~_KMnqN zuk!KSnIY`Y1pf}6us!7%VZRG}?)=XZ_Gg37o&RHn{ciBN^M9PMe?0iy`9DF}p94O3 z{!bM4PXeDi|0fIkJ>U;|m5=AnTw#A6_+R4*+fz;v_UD5?=)E(~ol}MV)4=D>|LcVP z)4}J?|LcYQGr;H0{~Lt;Gr{N1{~Lw|Y2z zcmCfh>@NqOJO3+${fofo&i~tl{gvQz=l^11{}S-I^Z#~X|5EU|^ZyQE|DE7-=l?Qc zKMOv0{#Ob6tHI~a|K-B|8t}REe}%BW7JTmfzf0I(2R?WH-!1IF2Yl}QzgO755`6Cb zzfah|3ViPTUoGtSgU_A+^}_x&;B)8y{lfkR@VWDUt+4+A@VWE<@y^o&P(9 z{jY-0o&SFo_U{6pJO6hJ`}cs)o&T>1`#Zqr&i~hi{cnKJo&SFm_P+@}cmBU6?0*}4 z?)-m8*xw00cmBUC?B5GMcmDrf*uM{a?)-mG*#AEG-1+|xVgG*cx%2-6VgHBVbLam* zh5a9a&z=AO688TaeD3`JSlAx|pF97b z{vq(W^Z%l-{}TAz`F~m1{|ors`Twi1|2Oct^Z$yl|0?+0`Tx7H{}1rF^Z%N#e;9o3 z{QpzfKLS2?{zrxV2DRn4YGrd*i&82@|9xf7Tc^=KG>z<=_e{*W+pN^RG{a!G^H8Od z`8(zRsR#e5#=I(Puy=weA@JG56B$+^Ook#a_aV^7CLHtSZv&VV<=Q#WX_=QME z_T_Y=6iwCSCm!_kjW@DSWr}dRTaDkLdVi}HHFxQrqWh1^=^MUj0{HYEO?A$fjZGonNbScn;eC{;vGRuK|hyfi(Nxg(N~?UY!9J_^c~0C1MQtbSQvzY5{)?tFF{o@L`v_=67oae{9X79~cLI ztN-PiAEm$_SF`8`+Q8@D2DF3U=70N|AB_jUy=Ku5bbuc={L#mns+;;oijU8{SRE3& zR7}bGabZ6J{*$49X>~6o!RO9@ov>do>^FdaXLV@~U8)iM1EF(P_d=7f-z@Bp5%ybz z{juP4_n%hq+n5LFiunL#JNVr7e?0iBnCoYUus;=i?)E(zeD3~#l(4VVExz+NxR3wD zg#DDT-zMy*h5Z@Aevhy}SJ=-8`wNBrK4E{Eu%88gQgy?G(4|%h`~Bc^*U$CBeh&QU zp_#1ig-yc#0QlVb-zMx23j22o`#XjG?+W`v!v3(ZzhBrtAncC_`%en{hlKqXg?$wh z9{&sbDPg}&*iQ@lGlcyfVSlc$pAq&K3j2M+{xV@dE9|cl_WOnX^}>Em*xw}V4+#6) zg#8A!%lG{|+RJ+9ZDv<%Q0=&d4z~6c_Pch@DcslJY%||-D}KsyKVHJ`)?bdR(T}Mi z-}$}FhqqN6eD3o<6X0{7pV^|e`i`&W7FrsqhNs4Yub9t2Zv{V<;r#$_9Qf4WtWyen z?*7>hK6Coj_<+ybL)*a5EljcIKL$Q4PFTIL-ze-W^>bf+;68p86ZTWWew(nL7WQWd z`#r+`Twy;W>@O7d`-J^v!hTlRUnT7K3;XMZ{hYABN!T9{_O}W9gTnru!v0QS|GUEe zkgz{2?C%%$4+#4s!v2%O{vl!iMPXmXgvbBFeoEMH6ZX@>{tRKiN7$b$>}Q1ig~EQH zu)j>$&kFmig#CVDf4#7u6ZSU=`vb!MHetU(b^NaQ`iF(%lY^?`WdE^l@A`OVrf8qP z)R*$pwfix(*LVC-C3%nE#?fcKz()f8B<~eUlIYVBW8P`%?~1=a$a{2NshE=WgU_A+24TMueD3@=3H#09bLW4Iu-^hccmBr;`>o(}=YO2Ap8}tE z>#J0ou-^_o_xCTx3;P}5bLW48us;!e?)*;@_B+An&i`a#e+u~A`9Dh7p9(&A{*M;+ zr-9F%|LMYh8vIV)oeMQX*q;eL_xHb!5%#;l=g$8uVShIG-1$FN*zX3PJO9TC`^SUN zo&OVr{W;)s=l?`u|0M9a^MA6i-vj<^=K4Pu{4}#a5By`9{ZoYf`QUdk$A2pL-1#{T zeD3&P2R?WFr-RSkKVL8Gp8-C1e%>JLp9%gf=KlXi@VVRfP2h9KzW{vh_RWCb&7A** z!u}%gPiBt)EMb2!_}uwFTi9O$K6n1l5%zn*=g$99VgFq4x$}RXuzx=I-1&dAuzvyg z-1&ctu-^xM4|DxoChT7b{_B|If2**+9DMHluMqYx0-rnoZxi-cg3q1*i-rA5z~|2Y z+lBp0!ROBZJB0mrg3q1*%Y^+b_@^`1&sD*so5{~GYmVUGX(!u|&E zx$}Rmu>S$@x%2-)VSgj|-1+~Iu>WE3x%2-KVgEYtx%2-~VgF;`bLanhVLu0cFLV9e zB<@y!lDU4~DeQk0{L7f*|5suEF7UbYf48uI5BS{q z|C+GB1AOlMe_h!B2Ke0h|2JX(o8WWj|69WTx54Mm|96D_o#1Dg>*sfc{d>WG7jyjo zF6`e2K6n1VC+vS8eD3`Jhp>M?_}uybfw2EW@VWEHI9OJV;J@VWDUP}u(!_}uybUt#}I@VWE< zn6UqA@VWE<8)5%(@VWE=l==&e+2)d%>DmQ;B&X{3*d9d|7Y;I z+xHOoIp+MoDD1xk{!PsBzbx$k1$^%O|5e!k8~EJ$e?{1T6@2de|6SPs2l(9ie@)mw z3_f@M|0(Pr0iQenqr$$5`LEBvmAQV#g#9@9pJt9fA?zoG{W|cu+qWKk?)*0h`;Fjp z=ch^7Zw8+`|6_#x7GZxZ_}uN=3O;xK#|ir>@CTUdXPdC!4*utv;~y{VcL@6vz~^q? ziQseRf0D4@2|jmzCJXyhz~|2YQNsRIVgG3Gx!ZRd_}uxQF6^hl-_Be=X9)W&lmPj1)sZpPXnJj|F0AFPY0hnKd%?|&j6o0|8EfX&lL9G z2tIfFz6pHp{4WspGvIUQXQ8ma2z>7RpC#-s7WU5upSyjRfX|)(bAwYzXyEo{J&S&zf#zLANbtudlmTH`M+A&?+2edKkJ44 zYryBu|NDjg4Z{Al;B&X{2f*jf{|ANrjo@?V=R?B&hr#F0|3`%V>xBJ}g3sN)9|NB| z|JMuqIqTxgpSyi;1fM(qHwpV&!ROA;Cxrc*!ROBZCx!i6 zg#Ax}&)vSag3q1*PYe44;B)6^o3MWy_}uybjIe*Zu>V=`x!d=1;B)8y^TPgi@VWEz z1!4b-;B)8yOTzw_h5dg4pSyj(0zP;C?-2F}!ROA;ox=WC!ROBZzY6eD3!BHu&86|BkS~6MXLcd{@}N7kuvg z|GTh%pRoTu@VVRf``~lu|38HN`@!eV&kuzCAA--F|Nj*Be)m``_Sm=l{pT z{t)=w`56}W9{`^_|34A-cM1Eu!RKz@J>YZa|EI$KUhui|vrpK65Pa_Z|4i8bxv>8~ z;B&X{L*R4g{};mke(<^Tb3oXC7<}&h|5Dh0MA$zFK6m^63ViPT|F5wBDEQp@c}&>< zHTc~5|BbN!xUm0Q@VVRfci?m9{|RA#1bpuNJSpt|9(?ZnKPBuxE$lx7K6m>*3qE)L zpA+_<2cJ7X|0nGK0etTK|36{>kHY?+z~^q?7r^Jv|DT2ZL*R4g=S5-vCGffP|FW?E z7h(Ue;B&X{-@xb2|0}}&tKf6z=kLP)KfveC|7*hjVPXHD;B&X{5%9V5KPv1usO7&? zE1SDolu{}BZ*b0ArzzD<_tb;){v1=eINfX34~wQ$vgkqSyY=9!bi!L;o_7!KRN&Wv zKk}#!*u;P9iFD7z54@_tPlBI)%=16T;m1_p@6-j&T@4hY&Oi4Q2S3LA1_|(Wb~vXb z_=VoX^DcGZNAKCu-oGCFx@e0xKOWVZTw>ZxZ&Kh5a$Yev7a_R@iS9_QwhP zDPg}&*l!p1W2)CVQAG&&LxL;SXPjOa||N3ft zdW%B*O6RAs=&>(R4b}J+#NSwrAB?~F@A1XoRJl*lLw<(nv3b@;;ke5EVE@U5 z_aD`wuA%YIe7F6-|DVi9$X2NLNcu6g;r`%r$fKHmU7_wjieKwMJX|GE38QjgA4%bUCOadW-moBl(MoKZXJ zQPR``x>K))ev&w(pBczibPzCR^Jyh0=~pn+joW;R6MPzx=i}FZQ3VIt69L~ziQ_wC zHM4u+`UB)Uv(TOLQ!?N?e|$;b><^T;^&E8ppPn@BJEZTpkyhQl^)}zMZwbGG_HD5F z6nRGZ{HoixG2pxHtNq&Bw<+Me?OVdHpnaPIekR|(BNV>Vz9Wh1*WWQV-?VQDzk>E{ zvH28vMuqsgc`8_c#|Hd90$kr|-&b|ft8)Eq4fws~{R-Mw&7|?q;^z63ax;B%{P%c2 z;ygyykEtzl)kV!+dQ_;J?#OWb$gmn6j*rsq|EbX@)aY;3kt@{bFX{iu(F1DqKt)50 zIQXMitLaxU`U&uT@l)9ERimp~MpvaqS9Of8qWj6wRgE-{(^wI1lcoIKYV-YKBU%&5*pJn|m;WMmXb&!Al z^>@J6zQz5Y?$^A2#g*UZUw{36ar`{%Z@91XQ|tOwhxuV%f0bIiN-b&b(nB1*{T(&a zkq}Dcl=Yp z&*?(J*grdk{iD#=I~t7bJ6YJL<6~XwqIPfpXyIbLwk8u9+D9B1K6?F`@ysmxcs7$( zs^<+$^lQ3`N1y2U82G94yHzso`ddEJs`CEMja%0Kv@u!P8H#j#419`hTwQqlnabj) z<741c{Nw7v<6m4^{4uqwi?(0h`HdAEx`@;WG4&&#&wYMuOx-W+?-ccwnm?mB|B;ef z(M+d{`YY9y{_)As?37wrQGg|9?gKxbTar@FA*PbcMSZas{6uCgtDgZsscuZE)1yXL ze!fe1{+}N;y7Kew1>e+v zMt=x=Q~%E_A6L{lE(O0y*Po41mo7iwa`2mV{aIIjxu|oT5B?Zke;ED6;Gd!E599b` zJNV;=*0yuze*pZB+>Py=`PmBogv>pxeh&PJYEL_7{x1f{<94HvAM6camK$C z{MO7*S^b6Jk5kXJagLwA0RE(*=i1fQsB3@u`L==InQIu&xqf{D{K=VPS^Z7mPf_QL z=Ujh31pb+OZ<@rJpY`CsaqHJ6amN2{@ZZ$?Q&xW!_zN1JW3B%`06(+0p;K)y->;+2 z@m=s2Zaub>bN%`{_=|eaVfF6>|E$J$b#nI4FM@y6$lCF0AZm8Y&vzU6QwMJxuX5#= zi#o^6;2)j6ht=N<{Sw{9)p$<_=lJKt;Lm=3PX}jxxCZ=V zcRbs{x&FQf{O)!26FB|V;2+mLdjjY2!+(IUo~Qb=C2I98Ki^B}@2KzKJihb?^w-U1 z^?#3k_mU3I<4cFpe{^k!x}|(xqt5Xc^ta#G!Fhc3kLa(wht+=?{mwldoX2lp1>e+v z#^b|>z&G`u@%Y~J;G6o-=#PMJ>ObT0z3ad~{?R29IL9X&z&~O8+6kQF=PSXVv+_n( ze+~F2cHT3Ab9{0?_$Te%!VFmdQ@ih($T>dz5%{M)x@V%=Q9iFx=eQ62 z*KL1xBIo|yH^D!BW&I>h|1R)f-#L2{XMK*TmRYK=y{nNDs?Y2>q5hIoms;5wHNWNN ziwFF6HK(QAQqf;efPZ2=ub%|JNlmQi{Qh!(Ngepd)?d_q-<)2xv!~pW(O$2&_?+$A z5b!T)=kyx`K5zRrq2F*($9+9~`ER!PocS3O@Gt4$^jp9`q0#XVt%}zF%FQ)4;Oq8% zm8tjZ>+|^Q+lh_5{y6Y;eYlRTdg_|&kAFq|MJ@NG`TA$O#pmolO?D+jqyJ{=3WdylAga0N>fZ@c9$L*ZpVt~}!lfW;mzk@dqe^#F?Ufa|e z@SXLGt9>Vf@2%*}YU-!>L z4`j0(?b{vjo%+D#9~baV|5?^Ez|((@N8hUtBhL(*FH_a_J||dwlmCaaIgb3#3HbT( zIg@{4z&H87xM#4oytqrB1io8;bbTBC+2)$R<$7|!H`|vB`*)Ab8a7|%bR((m-yZPu z<3l!oF8F4AIOF~c4_%WTsxD&xQuDws)StmW46oQSsUcC@FAkhy@y+(};K(0_$K0@~ z)^9P-5BT}<36p&@^yCGKV!K~8*etvwyul|~^ z$$-Bz<0MGO@7z;0#9tTi2R(n#^=pW~KIjiR{W7jN^3xFTckbtG-^PGH==mJ+HwFCx z&iph7e0Qylduy_Ksro89Cg7*@oieW6dn#VbRbMxXem`BQ>qPyyy2bzf_hk3LP(DK( z|11JOncO-s)W;z^#uD(4PxgLxD9z{7_0xR$iN||Wbbd&R>m3$?Ul-qzQiu5bv%x?`FSVA zpG@w3WGKs*pD6*K>OW)t&k*+C0e)TldAhO_U;ZZte5(J9{pa<;9j9l5hPw3H%uI_-7vYrv9*1XMKK)zdmsLCxXvC{y7bNlm9ed{W(|IUkbj-599di z0`R%>^Jeh51CnE1L!F7Ib-U+}x)TW`-Y`WM#)<6p(;*ZY0le^xW*|1t1&enuGMf2_eDzwV!E z8DINugZhw)H{O=cF#1p*TH|}SWf=EQw?Tav7k~c1Ovd=zVExtkp)J=e%hcu==fK0`mp}${X z-9ObrzWm>9s}JiKeOrC#W%OP9*!06u%zNrt4{w!F3O?}wPn1Aq1ePHxw z+3EwQ59_a~4~+T08+=nA7~{X&Rv+HY*S;&DK5*~<9t`>eX~yGw2ciB@`~w-r;|~X+ z{*b?aCS&|7pg!pMvyA@1pwD`Ibp_N1ouA7UU;jK9^jVMpuYmfa<6p%X{|cxN+F#At zzCnLrgfaeuP=9p)RE)=;hoL^0{g)J9{~3n*VD?`aKVKe(`e6277~@|E>#rG~F#5yb zoAC*wzYx}6Gd}5IY+vxr_=M442=&42zi|4n{+jU#WB!N1H{%n=_=llBnEjVFzV_X1 zs}GFzbGNNN4Do%ww%b-87~?-1)?ZT}82#PgoBF`$pAGA;sSk|XuifCA`oQR)ZL1HQ zKCHi{J}~BgH~6MLFvh>zRv#G05Bs1#=47158CJ4zt{)$L5~kP_b-;h`m5vT z+`rft^jY^Wmcsh0^TWA+u`lSe?q4j0`k>?I+`m`~>#z1X_b>JZeb)VpeNZ2C|K!}i zH~{s*>|gBX+rA%w`e61i7(d@X0QJG_UoghM4Ax&Weqi(ufN#bRjQ%oMf6e&e5M%p- zZ^jRd{xYZ!X8(fIhxONt9~kq00DLokV2u9&)CaSFae%LVH$i>S^(Q^V=tF(berAx- zhx(xF|4hdCV?m#Fd=(4kC#5*!hx()QpJntn1%2N5q5kOhy?lhR{{(&3@nH<=n~r}K zWBf6wKiXf-*}lQ}S@W|g82`WsV}3S4{nY(m4fFM%SkPx3|KA4nxg)vt;oXCL=hxi^ z^=CqI$HTjFeEvPQ`1dmUw)h#ZAA1qR&wc*wuY&&m-5I|8{0j0z@$cW2=JOwb_)Y)p zXY?U{(?9$8{5`h#GmO41{xqNeAjGfRm$Uyo2=R0GpNE9we@Hm~&9?X%+xK(eoAoQp z*MBzK^25igc+el<{C@6*kRR^vzdQ`S$$t-Df*ywanEJ+c_MxJmiuRv>Ya(a#li=5@ zp%mZfN-6p=7T@=;ji2Vrf0xZ?Y~T4dKf@RQVw>N`=P$SUSw4S_&F|;)HwgP%Y<`+A z{@ZOnWBYBQ~G0e?D#VbA0iqz*o9BZ{_o6gC9$tJ}|_% z|1}Hzczk6_^*UFe;rJ_7gU`Kxw+ehZ{=j;CY%TaEe#ZK61^6a@#^dMLfX^NOdhog9 z{{Z+V{tQRYbc}1kH}NwbAIpJn-Zje?|A5VBte=B6KgSpUPMbf#=VxrbQqCp97~Y1y zPVD=ApSH%?Esv*OjrF&rmu8j}zd9~o3P(5?2i}rJHRihZ^sOE zJlPeS?5+^it-ljW`Xe>_6HEEGKUK3o3H%1N+P-b6vOaX8ALsQaqo3sUr=VZY>mP-F zBda*3Yzth3j^?7PyZ>qoV&gNYQi$^5Y zZGY2Y{=nC7e&pbBMVr~`{25_>-`ATTIoMsZKQqi9_`%J8Ir#3H{bR!X{Xb~_>%sTb z?01FwUvEBm@c5ejSz-Rboj30~*i^GW8~i~3U$M0{ZZ=`n_5WkRFY5m{`>$GEUH|L` zKN$aQ-#)&E_>TkMjlb`T-ydIBl>KVQ&&Puwh`%m%TC#@tPXOOKK5SX{=*}v~|1q`Q ze|_N5FWR^7zFb9r5D)mZra+V#@DtviV)r`*HAxZT|e~ z{RH^2m?b}ptM`-OFSPl~tM}``-(>UGRPWb=KWy_iRPQ%{KSTG(Ir`>EjBc*f_tf92 z-y}EMe6!nPe0|_ksru^Uk10ADyr{iP2dfWZtkE9h6jRUpe7Zg->l9P3`ux4Dy8a-+ z@9$#vW2$jhasGWDDKNZO9Q;KLW-+l+?f0Euq=shqsFlTY)ONoQ{oIls)mxicymT-6 znYFBb27Ps7k2<|Lg4*t1g8s-oJ*vMpvv}zX(I4E?qq4h`isy{*UzPs z`q-vR(ceFNuG+}PtL5kqESamEs?YK!=cC`ZmepU3eroM$ob_Ql`a^5yapr#j{oIZ7 zIPM?U)LYTLCS;Z>-xj!KY+fjKg;>@^Empt z{#?iBKZ3rlKhCI@$Io9tf9Sb+oae`G zLqFGW3g`Cy6X<7-W%W0qug*DzbNsLo{k>~h{eJYf-gpXU|6hlG?>(%37X8LOr*QWF z52OG5v!|#WUwyj<{T=o5Irs10gZ{eNto~~ByO+%8+<*KB`a1tx`11b}`a1uN-x_)etsT(UH=*V5%hKaXBWpQ zV*|c!-&dJ>zy5t>e|6)|FPA?Bd}saTYu}^5cl-aLd+Ap=-6YoV@6>>=^S^OvPp$^EXwjp= zcltk{KMj1H{~t~5WUK$v!7q%jMs^QpYVZGPi?8eFp$F(!M2qrR?cEsx-x*(V`7;B) z=|9VQnD$YRLEjr+jXX1)t3Cf+7T@Im;cSj0|FZ&qe*DAa&kpz|{}=ZRR@-Cz%N+~8 zTYvg?k32a1v&}L8cc}c!MtRg7@OAt~GquHByz~U{ zP5dK#`JVzlcl;-T&t2c<*?h+O&U7KR`+minH8{>@!F3&Q?4}Md;dm9~jW6MulT`>Mt zoPNFE*ZpTTWB#{+uk$m)82`2gfBd?Cs)c;{p9S^7jDLFh{JX(7^=BQUZ>v9?@!RST zWBjwAKA8H$=-&;#sXvVVET|8r{%mDzU+_)+Vf1I&>JO(6^}*C1#{Az6zNtTq@!xH$ zKkw#i-xW|FxW{h?gFfr;OCE&!L-Dize)mDBKjgFie)kHf4?2F%-|s#c^jUwuZw1r` zogdEM?>-pxS%1HK1=JrMKj-gvuYmfX{nd=eHx34U*5B_w2=zzzPtM=(9)|j0#wRJh z`Zf&p!R#L~9-kbB`e62t7~@|E>#rG~F#5yboAC*wzYx}6Gd}5IY+vxr_=M442=zh7 zzlzg`_1BC~81p|2z8Rk|#y<@8LHAG9#@D{PZS{e%e(tu_2gc)XyKVJ>G5)h*{WbN0 z(ccZesSk|)*|7ea`k)y55BR1&F#2cP>I0__>#wN~jQQUUzNrt4@$a_PhbQ?y-`NNC zL61+;jQQCI^+EfYA;$QjKIrk`Ovd<^!uqS@=iI;87xY>8FP6gktMkLTf3YviU`{{G#W;=i!A`@e$xQ2hIM zrE4>bmwo`^H|^VBJV$N!AAtBx|L?2KEM9t#E&fdL9JSrwV~amsn_0Z{gAl)NU(WvX zAjHqze;yK!{~_V{ABOl%|L-Yoq1x_04Dp-(&o(+#>Hx%VKEK${xBWc;@te;t7|%~T z0ONo2`2}PA%V7L$j!!cB2f#PSCmH=^Fn%`2Cl4{UFZky8B%{9!#<%A43r-)#x90dH zWBw0-Z;nqg#(x0Dx90PU1AOhf8R~=CzNBlbX~j!#hWcQ(FU2#|ct0NW2Zqu$qD71M zL4M3jjP*Gw?049F#{6{Ie8%nLe4C#sYM>hLF1Go7HKIj}FSq&Gq8VzuyT<1C*N7G^ zp0WA*XKk3KnCkRh|Elo&kLhFlZ&BUvZ^ps5{{EwRqw0QtGXZ`fe)|2~CB=V1b@3-l z`M2eYu9RAxUk5&Se(Ht&24TNZ*l!Z{n}z)`!hQ?*MeEni{S5toY`EXd;kSnS53Xm3 zKc)`*zaP#1`?KhC|Nboc+`m7IKKJj>qR;*Nv*5G;{w(#ZY)mbmQry0SY$H!+Y!(;x$AI5l>jhPc zhm>@`Mc7Y*-^Cn%0{q#`ejE7Q{ij{nKMMRE%>93=u-_rzY37 zlkk3kHcgL|>US=3b~tg^xt7}P)INVaNvWX+j#oRb`iq_=t&$_7Gh!LlpdZ1M2>2>V zOVDI)6v3lMB<1m%6od~yC$n`4FiUvNz(Y4V?bEKT`|Tk_wCenzRJ?nwE04?+CPi`#eJhBVFF z7;iW2tLpV)Fg00x=N-~!&T@WE#S8v4!0F+bpr0&`Uw3?+pg{h0`=0dveEY8XO;6iQ z%1>}=3Hte&(&pd8kbkfL>-PP&)4sa@q(l1uSoE`orJJ<5Q__DZ@2l)@^!$|nz@N~H zzG>V1Dn{>6SihXL--}LGrN;m&4amo<&pu}NIep;_}^3$2` z|CavQZt=BV*UAvO>F*~@#vfO)fdoDn;8rB*~!oC@sv{^bo-uk4UNyd z`a|vOxAmhAi?8)?zoSrp&^OEZZziBmFDHBSJZXJH+ZVTfI`OB9>(2}8(Bo9Z{nQcpr=!qU9UUD*dY-ht@zyWuMCP$C{tK>2JN4O(-^}8>nHu!x zaQZXAKPE*-bWH?iEj~Q@&(YD>=zmW1)E`X#FOBK#`|U5KW67*)e7dV=X}T#L4-_AA zW`chTv)=`N!tblYf%r4AISS%Wg~vZT;H&OA_s_Y%(7sLwb+<3R_I>H)v{OHObpKRw z%ldUJ`bzt{0n+-0`cDZzLjUPTpX$TZ!Ks6uPYqkVee~kj_4B2_Q2a?!3;Z{2Jpw9{rSRNm9uw`0nT(m{<+=cU&l}RZ=&&!CH@lvzFvQWzHR;O9{6kS z%L92|*9VI~C+O4q%jcgQ@O6HQ>c5j7+J0H`)B2Z8E=}=MeGAJ^Pr%pt3HsLj+>+0a z_CxYRKj!S;e@S&ve)xR)u{-ef{!1|b{`}B1QPiXw0`?Y^M)#}qq=B>ZB z{+ZuDdWh{#G z^q@}_I%53oFXih``1<>Ls~_w?f%eto&(?f>>j?MH2>P^tQ53(k`{k`)-uPDM=R#fo z^Yycd_Ae~?e?!ox4jRGN@n86|D(9bR@%50;>z_{iw2^V@gBQOZ9~S$~_W0iv^eI2# z{m1i*^V88!^~dfnKtH3`zs9T=KV|+kvwz{lzr47A&U-O^OPk(*boXEMvi@nI#iub1 zO=*3j4w0|dV0ZlQ`DXv6{QmD^^mS@%;zwv;Rf?$J>9gj?d4w_*yUPoA}q8 z{daHwPA>-25{pmq(_CpYXJP*|EPm7f^ZSp0)5CKtzShh7Zv1-u@3wC~CbM|{W~t3L zZICu|6!tHm|GU0#|Fl?k?w^M~J?%gK;2&Rk{a^d};}5E14dq84e@F-3;C%Ec_GE{i z&6(HTe;*wkZ56_FYQ2fc%hM%R|W?IMRZw~lL*Ed-z>_3+B=PwQOF9`QdyanHq ze=q)U|1B2Z$xuE&hSj~)>d(~mA(_himipX>e#Xm>HGW@x$j4vr`eq6L%`%JckKaB1 z;KYx9E*5X}d`tWnqObc;zm6eo0txniy?>M+pV0A>M$`W{IP0%j!hiGDfbX8?lQuKz z=;;nMb8-HM%=moAOFc8TWLp~VDzX2yJm5FN@z3)9t`h!=fZtNFzomqKalk*_R8KGe zCj5x`$(oeVQw5*qAWV<~BuGZ*Uv{8>=J)UP=P&)OG+OG{$Ita|aReIpz34kE*_HU__`KDB zANm=p&vy}T#^`$N;Er#d@s+RsQ+?LkcRjw%Cd~1Fy`XQp%HlgSm_edGQjj0t7T4!| ze)6ARDEfRM6F2$s+4@00`YM*6#|$6TA?Kl&|J(KWoHj7#^T)OG^}Oj8H8Q#?VLpEh zHyB@kzM1#)a~1x%Cg8iTIsRcffh~Cav#9^*hNAuVu>8M2 z#CNMut^Tz^pN?m`~Qd0&zQteh8+L#!13Yy=hu4w>jM4xGVMQ7e){$L*!;A9xs0FB zzgd4>-%|^BJ{sb?{UH!OaA=)l{*d+6Gky8hJb`g4>%{t%pQ3GviB6SM-%wo z`43_7e-{0mVZ0mL_{y}eUVr!eB}+3lHr6}iTW196Eo$z34*dcD>lONeF8X=&4WC@; z=BI^*x38J?%gL9QAKku1=Wm4N=L;5J>qS24x_?^Qx9I$hu=f2D`lf&Cw#>J$sXvAG z#q&3Ev7+&(rGI|e;yXR1;5+@(dG_|W{rruv`0qfU0(Z{eaD8|D;P~F>%ewzRv?@&> z6{Oa5bUn5@k&d;Sw)5W%qMzpV??gZ2_aFDh|KahkrTDL*_ye7j{*=4Xr_(f@%;fV! z^~cG-^LP95)4FM{0pH3M^KbW8V=ll8mbW!~4LgN1h`Wf=e=BME6{LChQV~GE6=%<762lG?#b$&|4 z|1I>r^NR}oNBiCY!fe03Y>uz0TdvqLbwF)3en|iPcF@nCUliGIoTc+0;(rJIw0nM3 zWWQwmJA*!J{NF`Cox{1}zwf5P~`xV~+_@agmxI=^)Bc-lW2leV7UwGVwd-sQ;X2e&WV zTQ4`C&n}+O^_brN+O{tbqEGox>-2l^R7`^_M z>YtCGPuxr4+5JNQ*X?WKS36$F&NSn<33U8Q*Eg{B!(XGH=JkJr zerhV6-%D@o<;OXGVvYZ$eEe-2LgRlN{S4XZ@Z(E*_jL~aXFgxJ;9A<-(choSA3vw( zar$l0hvSFt_RCqac>BBK)_&R>DeaG-pEXX}JwA3Aw(s8YG3WR{&0PBU|L@WF&QC7% z|Ci12nd10O{ZZT7e?PQ%S0D8HdkvjGOxqWIeqc7C zzrW^7jd}2r)%W*L=lH6#?0(a}RNu6(&)?QQ)we7aMVtS!#dpr%E^c2-{QCIVy}wTn zkiUld&+3r%_b*mIJbq{W&DZB!FL!*Z4`Kda(Wlc}e8>0l{XdX@eSG-atM&1{#x>Nw z+P8f_^lw%l<1g&rdGTwX;&*%}ew+Ua`gFX}w|__R2kUb_Kl%E+nDTFqzghavt5)A1 zf3feyuiH0YpBGd9!~DOa-xKlpo6e7S{4gJXu=}fjpik?UbAEfie|pEC&BFfAcP@O& z+rL|*_rEOpdCltk^HaQj-R`bmIzLxk?)a3SF#j<6x_@fk-9Gxa?}hkvelBqLAA20% zlAj~!_nQ1>YPUk-#f0&;{ztaAr&%Z4Ze;xYf_^m$w-|3%^d-cb}ulh`W3gauCpV{Px zjei=#eJ4NQr;2^O{!)JQ@x3s=34J|2%xbz+{rAV;RU-ao^m~nO$q&6HO}_Z4KDhCl zxH)Q-aF6is= zTOj@te&ew^{~>-V=)3Xz`j6}T##i5@@$+qJtLZ->ep}FYQ#@mJ)RjDKdp*PlNI*Dv?;ai=~P##g#NFQN4-Z2Z#| z?)&<`>pS%=@8|2!k`m*q+34%>VcGiZkH6IT@L2SF!}8$BW!1&x9f714=lz&3dr}2Np_NDz7-M(w7eZ%%IP7L?Ux9_c&&lqSYpYjvtpNzg9 zpP28@`siDk-*}t2IenyWEi`uu;__k>L7B>Ez zZ}WSKd~f_?kKfIISp27<->V({3B26& ziyfVAO#^Gc`15zq*Zu#3_2%<6&v*Vr-|gw>XY|YTsZc)t!#aL?2eg)bl z6n}rhe*9{&#n*b&_-V#M|JRGb^k($4PWD~@P+0!W{(E8l4a-koi0>W$|EF1VsRlXi zyPV?lKEI&v*XZq6yq!KD(fNVc^}`E8e2U-9P4z+lTky^JnZ^$~{s{hC(eKfmwmm;z z-<-$3`f%%pbWVSNyd(Vh=W>hhNa*YLh4V|l?R@{;^PO3Iw=2-kADb!4KgC}-ztQ*k zOZ$2!{u0M;FS7VL@?yXE{6^2$>lfu;e}3m3ANED=Jb0VM59Yrpez$$~`V}Gml@=fK z?~C8{BgTI*`WgLqC9`gRaQou*e>Z;mezDj8E%ogZi?8cjSwA1Y{`}hWb!afX-Qw%` z-Tohl-_1|N_%F5i`TA@k3H2k!f0@On&o8|AsXpY_-+cXX<2Uu8aQ%v~?Mv3?7v;zO z{KczpuJ7cB&Q#Ft8(tq)S^VPsQ2aVi!TOfZPr3TJ8hx#$^-aG1c<0~h=b--FdX4$~ zx77F7t_b?kjt}ej^WTpsb$-QK^r^l%*Jm)hFW&hN*6TCOn_>oMp>s`OXoPTAh&sU+J z(RoNN_SP?IUwwr?cmHL%TOXYDm+C`f$@*}$#n*bVZ?4aypP~uyx;?|NNg0I={CtK40ZspMnyydVFK2SvcPMaulCblKKN#@c z>yt$H_4O0N{EY$My*^2FUtd2V%>OX@8Ol#q=fd&n{A!&VFF#KIEac~wRV|%&mGD0j z@F_nP`la%7UBIXOROpw=PY(T*d;JzS|L*vQvP4tK{*yJc_--}@eE0e-(S0vJ7JqZV zcdy?P-7nR?TLOM#zUM^uz4(2ZaUOg;;JaJi=)Mb{w zOfW%P1HOCxmgv5he~bT#fbU+vCAz<*M1A-q`Wfn_RY|r4bwotr~aAMGeysj z7k@@C=byF(eCnTBJx_FhiyOb6HjiRzWU9Kby{m~HIeREL)95HZQ_15v`XjJ3K8Bae zJ&dWRr>freE}ab>|4lKvq@{Byp>m5xdOaTWTa~&Yrs$Sqim9#BR9}0S-ka9(>%A3y zO>$@Y^XQMSr-!fY{WCqT>h0nseNwM~q9#9K@n0##|Jsk~Ekf5&g{D)6o`uEYp3+~u*-QKRJ-~a62r_cMv=;052yXyQjf^X7d z+V}5&8hwQxyhs@Z@n8Apf*=3O;jjGZ=?`9Y_{YY7sOtEeEq+n|aay^C_HDKJ z)c@}oz5WQ<$G&!leuocLpPzAdpVnLLkN*7*eOp8RQ{X?m;QvNn`RA|ixb(wEKK0xy ze;&O<=l?@@Rh|Df@O8L4|4xZ;>f7jR)wgeZh;QDfa8q^s<1M~Z-|qO+bFW7s93kKci37)V>oezV4rwnf86|HPgNyslIwdhp#{K^ytec)A~#K|Im@=o*2Eps`w|D z_7C4diP7tCwf+?FA6~GO*54=c>+b?;-zP@@`H{P-_KynjDL?NUeTDq%wO@VwQ^D8i z$k)%SM_-}-c|FyN8v5ta;1}iReWtz{zxw(%4g7rk^v@lCHuXXKHPpB1VgB_GQGKTR z|FZV0@BisgU)O(U`%;TP!{SqNe*DkTBWC>YV|q}__;x1vUi)5W^5bm3sQ=U3RJHyd z13ozvu(_q1{P=vd`te&=xbKXwuCJ|qXW4yceD%uJhks0eMJ@evw%sRHPqpXgSn!?p zolfK1hu-(x2cM<>|3ppots8t3c7A;Ov>xAH|5Q!u*Kro#8Q&fu+{u3}iYJfyY#zMwf>$M?icER z4gN{s)2TkM6~+%I);xZQsqEz9;{%E8IF;K{IL>=$ROJ@ba4aIGR!%NHesX}aoO3@c zsw(6Dh2nwuTUq0eL;Q1NyzwV6{yy@j7UiG*+%x@uaz&345dV|3G-v+nF@D{D))d80 z{il}WW%Uq0cmHVMQ$a(wYO3di4Mi$B8`f0J&DOSE;Ws=6|du{z1n0$3pxE zdU)e+wZuQLxUl}#n*UaapL_c?&JzD1WBlVFe(w68!uSVi9GG)fVtuQ}KehD#6vV%f zdHrp}__HaM+fnF0X8cz8b1J^q2Jv&}zdaCt3v2xC5I=YSACK|t@mqIM{^{X@inCr= zU_8XnJ${R+jBk8C_0ht6bKHxg&w&;h3Gkh>z>8+6@oppd-1%t|_M3(MG2oA{G2gg& z3;0uUh8iD_MW4CxW$kvdfWy+_xjb2enruhpLsm^ z-1R4>PM@sKZSSh1P~7u3%10G_j(EV2zHF2^6T*IDz_0Q^UdSKQBf=l9uOAID73yYTe@wtPe}u|7mk)6s)NtDp@Y7n0?_$c&*npo8-1+)l4Us#G zwg&vPd4Vhbao}f+-WXR*@zdpveEl=6O#E@K{@Dh;37^JTToYZM(ieX`ZRB`{ssD@z zKfnI6<)_2$tA3_q5EBBv$Aowg z(t-<7|MB~cX){wcIBQkUQ2+7!8HdSMr3DwF`aIp=f1G(T!C9+%hU#;`XWYE&`fTxY zRmEysi0ZT7FC5yl&0g_yw0;Tu`(gV_7qo3j4REzVy$bqM6`$V_^fR1(GU(Iq4)Mhw z5Bjkd#{4%1eY&6FVT+{#c8@ zqgAoh2X%&OR*T!`du1~gXB+#Qe)R@fKc-Sgt3~Zyx?bwzGY_sT)tf7SZH5}0PWkE5 z`O*IMTVDAyS8dkObfJIb74KS^`t@3;S?K?b*Y5^@^n$;Qa^|NO{i}H6KUdgaivIb$ z@gIl&&w2CThyDwHW9^^k2YlZATq^9(vG|<*ezK$DXKHn1^-`f^>&xhYhSo}i#srbUi z&FR9@mB*h1pDfn=&@Zs0i??6>g`@IUiyBqs88Sj_4%73#8k;F^!;2>pT0lq^SSd+-*5H#+nDPQ zegDztbH`8LPxSfR?b|8rcL@6vh5ZS_K3xq%w0-GnEk2*S|LYHVSkmd-!JU12cLWW&4JIo{%#WX z2Za4?!v3JJf2Xj&Q`rBmusK$uiED(1pQ34mTkF-;B(iXN#N_RYi4bM zRQcRd;B%d~T?l7`@cy;mueMGW;`QH4DZkI%zHQ+1?_bNt-vjY;=O-iV_X+!1VZUG4 z&k6ej!v3JJzf;&B6885C`wi-w{_!FE_<4tK{OqsZ-lJT#7afW#zaKJqtJ)u{`u+J) znT!`T!<|;}xyPU5z^CyEYy7Ezui^}8@rX9?DL<^|-?oEK`N?{3&TwZu_!R#P2G%1w zz^4~Nc2T`WD!kJ*L#=G@(qA{#a6*k!r*+VsH2tRsyQ6Ak`jHn$ulH8qMt2qL`gw$& z5K|%k%(DLMpGO!B#{+(=6Tjhg{4o=M%!@zi#vhLoeHNpkMlXKnjm>R@{MUu}eO;~}JEHyTJioH`tq=3N{r<|J3VsrrgwI@h{T8)4pfYy(81=OB z`OdwPx6MJni~8rlB4?@VlzMt}`jPdgE6?}(fAahY>(`i|ulpzY<~jr!3Y7A*Ua19c znB68nIhE+RE<*oo3H42OOZiiy_+!C8i^4Sdcl!SvdT8=r=>Hx0_?x?<)Q8qE-|7FJ zU+Djp`QyTTr~i9?q5pgS@lone3jDV^`AK)uzcg)h+Luz|^&ih~KR-hIwt;^+p_Kn9 zekzLJ4t~CUU4Mg#pVlu+{LNAP@!(VZv7-2C{i6PF_vb{(e+T%K|ET^+QTz$uQ+|s5 zQu%3(;!gxWK|c)c)Q2=BU1jK@Qy;F^4|UP->Q6jM{wIa{#-se#=68aBj2FN0ssE$z zZC|EDiGMQqblHl0e#-idQT!?3pAg-j7R5gbd^)~V9KR+1UVbJ<@uz}M{l|=d`czsc zC`11pF{Q`pKeWXv^q-$cs6R&seI38*)4Edm?IYE<%gp17{b}Im`;Y5W|IypuV&BWp zlqm5}2S49`qWFzb{51Ia{u9NY7R8?de!l;>z9s)&ekMloXM$g-KUv+N8Tzld{?Nlh z|2aQG|2Zbq*R<|GdEeNcHDL@C)_F`1$^0%}=EIa}xN} zf4Z#Om+2}$dHpBS@qv@Ur}i!O3)>gZ_u6-Al<`{+_|(2p{gx>HT=41lU%F14?`?lg z{G<9C)4}*7`SZZ1{u4F+bd>l{0iXI$v0vDJ1>^6G;?D=4+E;zQFg~IDILBx5`Kfq( za;n8I>Yopzj|!)f4C|H+TvOm{EkN2(961E1PAsvoI7oDM#=S|>K|Bo7fB!2<;)c>RUk?LCp zeCq$jzNLM={70&93&Gd@bE2tl`d)r~HRAPu{Tw~WPZ7rFi!8oV-zIA$L;pGBH)s8# zhg--`$2Y4)=ivzcS)smr{1g3d6Td$G8O2{5>NioWw)iXa&kprlLj2R+_@_pRe@Uo6 zmc>6O)Gz8kdjHyMU$6c|s&Bm(pZaI2PZi~VgpQv(J~evUKEn5 z=g)WjDN+1$?LLkFi~8qCaegX`|GZGYI6u|<=ZE@5{nHnJW%+q?s9&7_;`l4`F9`8d zDy;tGOpnPmHcpJvzHhPky1u2&H%JG5a z;Op^Wk#8CQcz$~ne+Bq7zA}EV6K^R$6~(^@e5%U&^M#`0dpJJy;*a$C!rOv=e*9qm zfDGL_{ona}^sU#vg{Q*rt+e>3nf`B<$c)S3Uc>_0K|GiDJsKaRfUv$5ln>MVUPrAFun-=ArYRu^kXQZjw z=4b27;FAF3>;9h@%4f_`Bj<-!{2A(!_AWgdaq2_XKrxlS0{TdP$J86&nm5SBlXcVR zmzl~=u~47ZDLsYy4byT{oLNfU#zTGm*U%K|*G*GLIkS|yO@#XSZ&H==r`u(hs_SIW@no9WUXlIsExAgm2A-=w%9ZhzhUKle?>GKxKO!WI%A->+C z(Nv?~80zOYfp$NWOj7*$Rl^Cye%lo4)0vujvitM``Dr~v>8Ux?&wmr9Mt@AGpa0`+ zey(d%G8vnuW|WRyzuFS&=R1eZr|&Boe`a}~t`8H^f4ZE7L;b`wr3b5JCb~XMh@Y>= zHb0YINQWuuqx&*Ay-e3{3Gwsa6e{Jl2zdh)iZDaZESN${X+Mokso3E)fwuS+kUl7%SG6JO%Chx+BVU&(2?2-~l8 zs9$dTMe#@2e$5E=%Wc2NkFfok8S0nYenpG_m{7mm_KW-o+pjM0O;sByKK`JO&(LAA z+ydPf-Tk^ut}fP`E89Djnq~EqMaMUMzB%aau<>Tvi7h+Lw)*uE{FX@mu~uKrO*)a$ z{;w~7CqJ2yOzzE;pZq4e)F07p^^;+~lb_6pQoZr!oZA{D-rzW^uV$2tf9T0f?%G&$ zly9OPZ}pR5z7zk@lS=hd`{p-6CBj!HSpE74KDBQIe~#5}4D<8t`&8uooM`o1!u)*u zJ{37XCt3a02!6EuoNV*y2k`2gMzi<-%})RKszr$g?g3wqI!AWh*yQu?@am7wPfzA2 zBT98s|Bvwb#ax@eCyL(^$)5+luAd{j>izLg_r!fZ8de7@~_NCi1Y`Sm`=6%d!qQ%KO^|3+5BA-OT@3f;KrYe;J?o1?}_45{v-IO zgKze_hH_r~X8ZCLum9-!qx*j*cOup22>t){;G6CHkn;P}e7^3Vk^M8!AEb@;P|EY6 z|4{t7Pf-4ipUdy!l;}R{4d|zN{WC58Na_Bs<2UsuO8YeUXQNN?)1=oRJ-PXz-EgyiQL(=Seab&gKEG9ejigHd z9Q4zMUgnNZbo<);MBSKn=OZ{BPWaRdzEhtI_0!beAkFJ8ZbzRFeN zpKI~eP`g+EExz9VI`KyspPy&(M+TE#eX#fgmH6k|{G$2*z8-(-{6ww~Z?^gO6zWg7 zAFcjhVDs+^&5w>>=f@d8M;M>H#pd4=#g8`r>9hE1q;o0Nf4vEC_AjQtN*{w39e)_2 z{V%ATF#r6h5LH+WcPE9ALVDhFAVYB`T*@q>n}|e_;0oPQ-;9DYS)WZ1+}%`(35|y4GBN5MXoN=PnNS zXP5TtTj`fO%TAYs``xAdO>y$`hww|i$=k#I<4gD%?dKx+mxlXuO87Ywe}s!Yz9ZZ} zsf0gd;*a3JGu+pGF|>bf*7-L(n>1I6>9TNt9xWE;XSAP-;Ag}A`6c|Ei9dgcy+rtG zmCdK|A+5j8-ZLG)Z7tNdqV>12)og)E;q=<-aNj9Gp?*_qE?=Zdy~X9>zH@?9sNdYG z@Q{1N`D5=+9z4qYvf!5#Lezh=rUM^1SSA>h%UTO8~OZfDzn-ibZzUtI}VCkt& z-S0pDIc)|_?*5TJeR#T>M&sMdjB`HSc6PsGptr9y>%Cf!{$N>uO83VHdNZC-`c4!2 zPW(DQW`g+jbDiBEjUIn9`dY|N-Q<==?T_g3e__)8%BcAni@p>8CyITgJm1ZKWWN>t ztTQO~=O^cH-}gn&PaFD9eqzP(Q+}rB`;UILv-@Mw{SNe<{J8tqrhl6J7x&MV(ftWk z`0L&o-S4#c)CBJF8FPAmOt(`z0@xS4GC4;1B}&ioJfDu(o~PM?-bB%J&^Z=22aXCuDB^f2F9-t!CB|DhMMx!$OLI^a8SQT$Zjs*it0 zm|uwB_|?Wg6Mg;X>-;-DjUV*4(`o&6`j6Y}k^9dvHotgWpbMP3$*m6+``tF5s%4#8 z>}80~;Yp|k=3&MDaTZ@ob#8`6DEu1y<86Lc>-kX0ADLc#{3qIc3OJc^(nIZQ{LbR_ z>-5|@_vQRtq5t%R`R<29_W0d86zaM!%nkMPJO4HMr&xUI|GE74n@s;7)%m~PMC3F| z`q0K6H^4Ig&bRq=G_RyjKgwN(^834m|9NYupZ{`QjsEgbKYwtcMt_Cfr~T9aU)#OF$yJv31AouV?CkxTY;FWH2^$Fa zBm@LRnO!zl0&GH}0RcB5K~U5Xu%g9gHa9K?-Dse+QVkZYw%US4+gjT0=7IzPlaMHQ zsX?)|t+ilnwJm@5|GaZ%HgkUOnZ3;Wd(P)Wc9)s?p65L0eV_B5_net2JwD3#s>1xd zqpV-Jc$Sa9a{rz2zF8QFKerF!?;W8@Mjl#I)-R2}a{t;g{&rIQ*Om1-@xQB#A8kLC z*N5xN`jPmteP$y&afCl^E#nuaHfxIG+miF6lvIu-;pF!SaN(gU^BTPWD14yP%(lPC zhr7zZ$A>l-+Gnxu=S*7OKR73R?nwWp%lI?n{gN5UvH7*=XYxm`i@OU!9Up2sF7Kh+ zT=@Kf-opRRnsi{V?~S_DmGL_YuLOVn2{2I@V4V0ralbWzU%0+`Mj`%`Io@>q7fq7? z@Xa*Eilj9(`Hl5zRi;-3`jr^>~D z+j!%jT*faGf61_UZ1GP6zc3|!#{RIU7WeN^b1vU6Z2QUV>C8(0Q;Fd*UR=X0{J)dR z_}%6GxdngLSp4bb{BZrn_>29wr2VJH)PHBh`?>w8{0a)bd9#ooyH(@L&#C47NPa5! zJIeUc{73w8<$rcLKazj>9K^8wgj;2dZ9ikm{~6#HZwcET`V$NFZD{7_?185Av@6{; zmiBWd_;TuHmtb4?v)F!yg0Oy$^|UB_wfs95{Cs`hBl8dSIs2T@H}(`SAHTh(ZI_&> zPX0Ljb>x5NfuE1x`n5Ux!V&!XIvKT$y37avMEu64cLd+kqu*e0eym?7`N@Yioc~Jm zvjF@sKjMeO{}KGL<>vzM!~8UiA^x%D=R)v{yR0f~Kf~?c&5whf8~uXu(xjv@h^7#{QItRqx;Qc@|S>L%um4|DL-9f$oli^JbBgJo1EBSBQJC^>n z%<=OddNGP`_iv+I2_1d8!to3Hclh)=wtdR}ZAok$!~R|F_=WvDs^2;$|4Q(O_iyNX z@87GyAKt&^<1g&rwnVX3jkFi8cKpKr9m&si+5J0fEdFZnw}vwSx$ZEiVtz`;pV>W~ zvj$DNZc8wR`+wGeUx=yb%iKo3{*?NK`~m5IApN|#BKl1*O()ww)E?++r zLE`gcsh>B1Uu-`G|FxmKKU_bH^C!6=Nc?y#{p&{Xi}kZ(&B9wwcr=~*9h_F+mDTZEcJ7p&kEQZiuax{W6a5##zeeI``g_6ek@%VU zISzie_$gw3eg^(R$q&sIM5`6IOsfXM8Uo_1V{gf5xb<7~d0CgMa4uUOwuxZvg+SQC~5> zCtMEx-0{79)MsA-{=89NF}^1(27mteUOwuxuLl48QC~5>CoD0~My_Av=g*0QxNh+C z^XEi=Ir#bcbE5w&_;UW38_VYsjdd^V2Vc$~O+bwQdGPJ|W0L3(fS;B8F#UU#{cXzr zPGvu*>@NwT^})9PW@7v42H&>-7NWl#d};qVrk@30+P`Tf#@`G3*Uk^5i2g0$%ltr& z>8}UhhF(RC|2FXL{4LY(0pHFKq>1sb0bk|^a!h{}_;!Avni&7};M@6Irhf?hB@%xP zG5(jqUn=o4{iEP7llW_i@&5q)D*T7#S@z)dM|2g=J zC4Q#g1-_jhn@@~?8TfX7tbyn+0$=9Ga!mg!@a_CqBQgHxz_<5rF#Tu1xA$)}5#xUm ze0%=})87ley?=u_K3oRlE1Q4j_-YaOHvetJ{9gsW%|Fxc0^jC;0x|v`@a6cMWBO~r zm*cOQNQ{3K_;UQsG5zbom*cN#C&u3kz8rsZO#c?}<@jqR5#wJE{vwH=>E8yv9DmJZ zV*E>?zRC5G9MfM2zP&y&g&6;p;LG)q9MkUvKO^x^CB}ac{IwE4(?0E}v?flPKM85%iJO9J<4ft7!|7>FXOToA8pSgb* zf^XaZbYlEhf^XYD)9(boSK>dJ82?)6UmX%Z)4vsbdwup4V*DGxKTYCi`tJwdUZ0&o zjDH3Aa(y<(^sfcqUZ2en<6jNFT%XM`{Tsly*Jo!E<9`MGTP1#`|3mQKC-KiB#{Vk# z>m`1s|1aQgkoZp}#{X0BZid;h~}#Q47j{_PS!)Bh&;na!MF1#%JN`X%rd3@*Pp1*u0M6k`?p@%ZvdZPAENnZ*N4dvKfC{? z%oij5m)}04KD&LUA%61dugpJ0&wg~Vg5SOzxery`t1A!5dWGD%!@Kjk>gf&(6;T@Y(gP9sJ@v zG%HDyz_-^QnafGwv-{U{@Y(%qqWP6-` zlNM7&9Hw6be&0l{UyJ@xZu_r8edsjm(OBAU)n!&4HLmP(mt6>JNnW-nf@fl zXX^4<0O(8mXRcui_%||fv8JL=9zRS&pFDmz34QYTVLJHlmYgx`|HioUc@rXQHcob#hWVh2c|pBqXt{UrGI{Ahp} ze+qqRKTN+0eQ7^TKMlS;KVs&;8hvS>Ouq*FoSYvq^HYnyj6a!v9r`l(c) z@!QGhlgB5gpids3%mCk>zx)ev{Fy;t^8ar{eauG{p2TKwt9D^e;qT^3U|&g1+RRSsyNP{GlOc|Gik*zXW~BKXd%^R`6wh zjM~30MgJ(bzP%0oiQM}3cJz;O>)U1E%lsHM|5^0E%gui$`jff&??V5(-27h-ejxc_ z*0*lQ=ho+i;LG@p8vi2nrT;SXvlxBpzf6A#`qF=y{!;K|eu>(Dm!VG{zg>YodHl8< zee(G2O7P|Uo!UOHLSORFY(H0{PaePZpidsZtw5hVep`vYCV&5&hri=I7n$%lsZQ|GntT{32n$K!OK6@;3qQ0M>s!gz-N6fMlrft@Kf31Bb=Xg;8*o<+@ewse!92#2G>n~oPB z;rvX1-~2kqEh!{zB;rdDQ>^yT-TZbL<*se9FW$lby zPj#l4Ki{7z@IPj{PR{wFC9kgn|EQUDdv3`mlZXGU=joXZZ)<+$t&6-8Rs;TrOxKLu zp_5u!t?bu;|7f>_UCcjW3mU-BlNkbBAR58{(of|IeCDy;D?iCuM-%vYHN(3? zQV;%pLyr*X`lP z-wHna`a&D{?CT3@^IBy7?JLK6Z|#2eq}I0Tnx})A{<*3i(a%rCc?}Y4z~9~1Gb868 z_OMV3K07~k%6$ppE)Sv&Gl-KbDgA2^-k@0i>@l0`k;~+kL+<&LR|Kq2hGNyNN=-7)go=XD! zJV%Vb8hnZW$En`J`5htt8uaZ3WO#j`7JZxlOyS#W2=P~eU&w#{2jibQ@bm4b2ovJ3 z2meoO@5&tg`|C)@_y+K2%KO($hS!DV`*9-u*Pj3WSIW><&|s#_m-*)o3)=Zr_W4~S z`0Vq$0Q{hZ*S91cGX9C?Cum`PGo97#{q0ddk>MU-WWUZYy?^GhD%Lj-hVjey_suW8 z{(iuusF!GKz?bn=xC+u$c=`UvNc`rqi^2_K{o5KnzSBBxA-=#&oL_o<^#Iqe0l!9$$jqe{{MsznuLHks zJJ+uVzy1K%Zvej`T{t%)?Sw|~8?#)$3H+uU*KY=Y=K$Al0ly{Sj&EDR@9*ULZQwWM zxPD+Rjf~%9&MGjSq{b;s!twh8Gn3~h9l!Gd<`5|5_%=V=O^URZH270*>E$Iyq-yXV z*huB&d&Z&tFdL7ATI=}4#v^_m`uX<%Le7|nv+}U_Qt$Y-{mU(yB)`G&ZTmEjWDc|> zOiO2bO<$wj&RzM^2)@bZhu8j_z>n0QhclH2UU+3oyf3#n5|Sh92uyaqS=rWM-!p6H ze*zgk9N#RzyvaF^CD4C$hB3Y34_qey_%BKD`^@nf;=egG#Q7e@6!<0inYdF{GL-zK z{8Raxrqk$CKV8VyPuRc4P;W7d3 zynow?{0t5Lc1RLb!O~LRzw_&xjmdrT*B;funAY)TZ1SbhS08>z(KIh7QDGRBuxWLdrpAR^bt zTQWm-6L?D^>hs`&lvMUpx_)5hMCMmttm0-U0sgnieqgST#2;kY@kf3B{BYFYI>3!T z1^Gz@l^v(bMO6iURhH|g!B21F`qkiXmD5M&QUiWXqS7N_d{njI-`B%dR-as7Jm z>-KT|2Jr8ve*3k(zdhQ2tH|@uf$53NPnNcVlL-@j3GlySQeQKPueEIXI|44jCc)>; z%!HXpxxOJxn+&J93VkLnYpFrMWai3v-Ps#%LM`}(`K97oWEC<+HoUdt|D_Im*}tTj zr7)Iy@a3J+^8RRfm-Kp>-yR zyMpS_m&XgrA?!^Aq5+^PdF2DSz6_i$4W^BANey30nTEz;BX*!QH-e=(P8@Vl9~ST*1;Bm1@BuO$0*;9p1f>%qT->^Fda zDcNrXpYWE-NQ6z`bKkvYR`TifG-ZE^vVRizZDwVTxeKN$ z`>o)!_iqjOYsu}W4SaU~Cn)<9mHl>Qf0D94S=nD>c1G&k`o35D%$6S7X+RJ7H;K>F zjalOO0Wo@Gvf!`lTS3c>t&`V*zoBn%@HlY~tOS33-skOsWidXp{d9qUlf=)9-k9sb zm;49J9%vC*#lk%Kde7+56I z{}te`&-=XkvoywM*8fiMZ<6?V(Hrvz;NM)xKdX)I0zcfpEZvyBijR_`w#Y-wXateKTpfvGwP#!M{0Q|1-22`ULoP|MGNW zzUcTi|GXBu2mJMtf1Ym4AA)~#etgdB!Jh&@Jip*=!Tm8lFM1>IZI9Lmd;Y?U-k3+g zm;49J5zub%!}AN?7VM1inIoWW;M?;T<_PGc;1}CJtA=g@KWzUj-I({r_=b1{SO>ms z|Gempxf}dq`)94=PVmF_&(e*#Eyiaaf!Bj?+duON{0;EmQ>g!}W7t>05BnEOH|9@c zeB1t674Gxk+y2Ybjd>b;$$!57v)1tx_+kHI>Bf9H#%GRz9s}R@U*-rXVIGUjKi^Ki z0N(}vrn)^_6L#QBS{6C}6G`ShKyBdPQ73*%-aSHER)W8&u74|u&NJtN&)&c1fZvy> zVuo)5Wxo^rEs4je?Q@~ye~sEcTfyI&5TDpSSAf4I@gTK*_JF^33$^)}N#NW5J4oCE z?cm$|GyQ4c+xQO?SIYmHj&K@66}_)d{RtS_}TRe12Z7XZd@;U%$0y z>+$3-X)S0z`0V3Xld^xI<3EvLjvwZM&#s@1%6(o{)T+~b7@=9UB=IlwqQT_Hy7g1khWk| zS-*v{1xLYu&v5)Llr304f^P_0@EZ8Hl*DfcTd)p%8NY4mCB$7EAFKgC`OVhq&gx|G zVeg-}IR3oq%ZdJ7jz5zc{}S*M-(+UTm|fs+OFUTjB=HPvR}h__u|9JKVpk&SZx{d3 zHr^UqlTn|ZAJ;Zher}!_tj;-1VjR^8DFx^`VWo zhR5T4;ug#g9Tf=Io5A^)FeuA0*)leV8{P5OrEY2rx!D^^K?D$thePFkr zW3DgthnRn;KN7$Ay!JmBQy(5BUSS)IsSnI6%!9G@fwzWExBu2r^W*vnrr#OYf7^I# z7>x6YThJL>A9(S1y8TyI1L+9Cm%F54`vf$JPg4 z{C!X#HV-sr)YKBy1Y_Z+fCULLqU_5QRzs6TdoQjRaQC5ZEhTM$6~q3>VUCq^%y zbq@6>%s;P%_QmCTK<4q9f6Z7*a zsLyxS_1oEj6zdMAPeJ{(KJV(jF{eTN_Wpd;}e%|buF%N+swtwCpekLYA zyxA*bo`d*p`{A8kiysp|@9f%`7nS3GQ91r2G4b=xUW_>s6F=|l#eV)q^!_w?e@z>2 z^dLUOZ+%-=Sxdt8iK7Sm`C!rf{FwOOCYysb=IO}$qmOR8eS81**B7$#(*yoX;`4O- z`JB=CU)r{d>Sw_}vh598ZfuUP1OM2z&I22XdtfE_NAo^!4=juEneC?w{FfwtUi9|! zIiu}I@?XX50jt25{EN@qg5@zjvj=p8FZr)x_JALNU(ElZ$2k?~DEMLiS-LUL$N0Op z^Zfnb+x#CU<;G_Cd*B!A4{HmKfFIT$mTt$N(f(`weq#Rjf^X{&FM4BM20uLh^44$& ze0%)m>Gtz!qxrYTU#33*{*i6W)^9(bHX8r2{P<^pR^$4?xBHi;+s~(s#(z}u&-8QP zzqDe@poyA&m8}Bg8!1l&x_uEK5ex9e5a6qRvX#{ zez<>Gy8V3GX#CdiC-#6o@NN6yMQ=Z!GaCPQ^5b*f7JLf)@c7Q#g8O59Ui5Z;AetY0 zeCI`PKc6$|OaAlYf7Uv7gCCA>S-LShV|?ZjU>o>${LDN8+y#Dk{C$E}<2HhCkH0+K zem--w{n+C#)9(fUrEO2ra$}Fb9|gZye^}eF3H-4Buyp(RsL}jezn{1V)`4&94=;NA z`KZzOi}i=Kjyu5*>kmt}pN|@i-}=lRupWF{f0#Ysf5AV|{yAqczXZS7{yDla{~F`l z_RsQv41U=DS-LTAf`6j@bJp=I@QdxAqZ{+{7~i&kmj4>~Vf$z4#{35S;_;WYhS$Ll zkH0M4n4dX5GyBFI2j3oldC}YNM~K$X@8stno}is$JORGlzdYT3KSDJAWBKt9Z+yE4 z{G*b8o^H%Xz%QQvvW}3qgCCy%vUFo^jq#b|pS9rI^Iu-{#{3QV-!05Pu-fR8;D`H{ zr5p357~kff)kYr$-?kr~Zp=5p|88OafwhjWf*+2rSi1du_-OsHJ~RKH2j7n0c+ngA zeE4YmlK=et18W^mfgg^qSi1du_-Oprw?|-B`+p34JAPvx0eZ~Q$o&s9ci6LH-jV=+ zu*tRi&#~VFTGh#`Ku=s*`R6fpfxovYcMpEPy^UW!$h@Luk>mGQBh`OS?`IEH zq#Lu+@q6w;$|wI9I(~0V{FU$D_kzDq^8fjJqIVDb#DAUR_g6nk^lt_KrSx_ue%n5? zxYKbbmHGQx$A8d?-^XtQe_xa22R0-qg!3jBHG^Sf=}&)+dXUBg7j z&rb3-*J5 zVIlsFq%Bxg*3VJ4;3)WS8IC_k*@E>W`2B<}cn$oEO5*P)Y{8x2m*$5N{~GYieZNDl z!UN1LjvxR14wd?MIez^2J5=hw0{+qTPn&kZ42RG7_LU$y|7m@k0rK(_QU93uZ%m4= z!N)YN%^IPNk@1*D& zyyB1ZVGDfx)^hcsBtu@l+keC33(4Q*`eA)w`Q_>Z$zKBXq1^XFRXRSI4ZfW}d~$Jg zKEP-HJ`R3(e2=cd%a5&ZM88aZD_w(6{IlKqBlWFR_p5J@yS`Khol@84Q{PzrYN!wF`N?D8za-}`x5EsmZ9kPR z$DsaLA7^mAe5gORe!ej&x&|MAHPi=seq2Az%>Qbr4`F_yYw*d>u{a;Lz{g(=^@kn* zYN!wF_H)ejrT!4}5A{dl7oXSu2V?3(AKYQ#vwsI;>I2?^<>klLhv*u7{7$$3Hc|8A z`e~-$8P|U&Mc3eypTRgEw!p{ljI9s6_&eSHE5{dJ`x$h7>A$@A2V?64Fa85D^q8xm(n$O#UJOx z7WnuJW9tJi{)KM;&7Z%}^5gpX^B0;QTOWAs|6ojgxINN(!t?h^&o2(f)Q9Nk$J39k z579N)_F3t&)a}18I`oX+^+<9yfxAAf0Vec;8v)a}32^V5T_ zPd&dl7+W8B?f-C0eOLi^K>O_9!!h*%??CkOW9vh74L<$~xBoU#^W*wyroSSt|4xdo z!6!e5<9yfxAAdz`ec;8v!tK9OA9(HOu$89R zpgve1kL5mo;QDE5{7`@F{Nx*xqFdkVUhv@y7%H2*Y+-@bpU^xC6sNj~}i0{G$njjqAV zkIfIye+R_Re*eXHz~3kBGkW&um;diTeykro`||Vm#>5|;efIQY;*ZWg`}xnr#J>yX zmwejiGcob^6aD96;%By>=VIb#wx1W3<9|^({v$E*N6(J@+UJp&_@ie>e*PASf3MVs z=;*}Lhxn}@9i9033D<|wiJ$)vX1o zBkqau|D6RtScIRRFn+W273;v?C-48A3-1f^$^Rzs_viiSdlY^Awcx)b@6W~fea^pb z2mff^kH+ug-wb}3pKN3g_~d5;_+k7}-zWYY`0Ve8%7D*q|8tf7US)ryvLBd3^Ub2R z4tu`XQYaj+n5tZ94e|Ls5#x)Odlk;HD_utt{Qoq`fmh7-EtPusx)k_tm>Q~I1-^|R zWAOPq4Ze-v$8%mg*VLJ=wgtuG?cucZ48Q*|PuZUjzF)NNtIq|WouBiR{R@@-wIcexLfKC$`zd9=O4&~< z`_;;Rjj~^>?AIy#^~!#OvfrreH!1tg%6^No->U4lDf<(Y{fWwcyRtt?*`KWJPf_-# zD*Mxv{gaga>B|1e%Kj1gvVV@Uf3C8Bp0Ynz*`KHE&sX-(SN0bu`xhwt7b^R2QT8uV_AgfUFH!d2s_b8? z?7vOff4j1OnX;c%_B)mRE@l66Wxre5U#RRaQuY@s`%9GlrON&?W&a9gf4Q=MrLupO zvVXO*-=plWQ1(|U``0M@tCaoK%Kkf){dX$+Yn1(KmHq3K{dXz**DL!sDEl`m`|nov zdzJmQ%KkcK|0ZRBy|TYS*}qxYe~+?%i?V;Kvj1LX|9#5-ZOZ=pmHiJW`yW*HH!AzL zEBl+2{X3NXJC*$pDf_>p?0;CPga{f{gAJC*$hl>JXA`=3IL%`(IM_|5VxkGiCqF%KlfB{XbXs|3cY+LfL;(+5f7t|Ch@CQ_B9= zl>M(O`+ueE|FyFJH_HAul>NU|_McYv|4!Nedu9J0l>Gr^e^A-qtL*Pn_V+9M2bBG1 zl>Kii`_C%-2bKNjl>Kih`_C);FDUyjD*NA7_75rhhn4*!%Kl5r{!wNBn6m#JW&gX% z{>#e#E6V=&l>P53`#(_jf2i#Lqq6@aW&gOc|EjY8V`cv*%KmH0{!f+te^U1US=s-Y zvi~p2{=X{w|EBE!T-pD3W&an-{(mU@uPgg+DEq%u_Wx7a|CO@;U&{V}EBn7z_J5=7 z|Btf&zsmmqDf@3K`~Oeb|E;n=r0fSK`uYDKH8mw)4&eW53j9r`!5=LV(ypHhieHpd z^1Moat#zzgF45PT7B#vVXm@e}l4r zqq6^QWxrS1U#sk|Q}%CC_SY->8uZ6spHTLb%6>}OuTu8Y%6_%7 zU!&~TD*JWHe!a5apzJp)`%TJzv$Ef!?6)fWZOZ-xWq+cw->&RWQuZe+`%{$tsmlH| zW&b2)f4Z`Nva)}QvOh!F&nWvdmHk=D{;A4-hq6Cg**{I$KV8|MqwJrd?4POZpQY@d zt?Zwp?4PUbpQr54Rrcp8`}39k^OgMt%Kin){)Ni^Ta^8al>Lj9{Y#Ynw<`OWD*JC! z_TR4TU#9G5mHkd-zf0M_T-ond_7^Jqi2+vQTDeg z``eWL?aKZRW&a*!|6XPPK4t%YW&h*K{!V580cHOa%Kj&n{eESCm$LsUW&hL4{%&Re zL1q6TW&ih;{fCwPKT!7nP}%>Cvj2#(|3}LHXO;cWDf@er{YRDk&nx?Xtn5Fg>_4vT ze?i&*6J`I4%Kn#>{XbRq|4iBcvaPn6{sCqG8D;;Q z%Ko#;{y}B`Ic5J_%Kr1p{tL?fi^~4DmHk7?{$XYRh_e5ZvVTV6l1MczbG-dw`$LF^HGnM_*9lv9I2dGh=eU{^MzhA7w@f)b^bB^P4+kegs zM82Pk|NVF96N``C_W}Cc<5$-4Go!S)@jaY#d~W+3aQwOB3vje&CoumPjrNLhJzfp% z^BMB^FbnbXzh5t!ANKd_<;+u&{`(n|491n-;vW<3R9+>6f)@BW5BNC3kv*>p*jxTe4 zq5ZU_T8B5bf?v{(5BX1|3fofwE-yLR@gwo~C)@qvpYHgVR@o|A*uS}Cm7m|>_&YnY zVgHr->EDBAIsS0|JNFXW|EZ2|^Dil~^=HN27T*fg;rLG%+kfZYoPQ6V?fBgIPjmbe z`A-mf@ac|U8h^t32r$R-Pvk#AsGw&!J~#fXxf{km{b8ZWZSP!KS;>jKs?+fg75%<@ zvi@u6D(?sP68y^@za{Knx$S-T82>c{;6FLHr;wj}B6+Ozj|BSJf^Y7vl#IMCiT>PT z`;qKKo>}1^32dLeDbp{zAeTy1wN+@Aylfyq|IoyN*R8+3Z%1}%ZbwVWlPmaj(D7T^ zhy9%N0M9k-9m%)t)6?JQ_&ufZd#|CzX+OpGxub$?yDw>V{6hOQJ93O3)`os|*r&Ar z3Fyx~RM(lIp)SyMD@SloCB~-`@LM{QcH)zNtIF@YCgdiNDTk z<|o|tN#%TrpW!E6KU{I{KL6y4aJJ*GPnkV-{M@{^nUJ3r$6qzvei->l#ro2P&f@$1iYvnSTziFWA{bPu-Xc zl>G}Ge>gwk{Ilm4yk!JGKfmhfU*z~t7xQ17fA(6##g5O-&n1q3BL2estylbSb^H_Y zGxC3_>le;{hp(@B9Rl9w_?H%a!tA^;Z+HCR{1j);y{->l=J=Nu+h-WRmu@fP;P{-I zpH5}J%kgdgTTM1S+gFRB{hg z+GHZHt9ATGihh={hC0XpL5c6bhI+?ewSLjYq@17bG!OJV(Eotv97==Z?_R&d`njEy zH8eW@(e=+*Kf9B%h9<|KxFLPJ_+}?%4O1L{Rp<|VoU(?gj=wwfb04Ry;Vj2L8v5Cf zQ`XSt_{06nd?L~lEBj-D{ORHNHYexT<^k_*nC|$t|H}P)!@cVhUOo6^ z$KTzZ_e*-0&l*l~{G%OtKhnD@U&9Q?pIDXmp?6ifhK%E{`su=a{;~g7wuYIGzxzPm zkLg{Ntl><@KN|Y6{dfFpnC19(el?umyWjihV$7+rzCC`){C~e3!Ms|(G4o^nF#ft- zzPi1W@!|PqSzCv_7-B=cT4-bLO3ay<|Hb~{wIsk_(e1@KFKz~(9e*qM?D*5*v*Vux zK0E#v@UKqT!wawdq#XZ0Y7#`h3j7t_*5@tffPZy@8-Kg9KUvwI20lCgCn@{0z-PDr zQ&u59%y?I#SYIk! zu6eL|SBv)*>>$?vl#So|-dnIQ*55T_%Pz^!ici1#VDCf6-|3O1!E*is1>Z}TVPHA` zzR>rH-L{SDWVC(WI)6%gZ=XE|9~*ekJd}ONJmfV3O*;O|6OHvLx-nIb|8Odtf6K@3 z6}!z(;P`7o-^TB)8AstjxmFdKcziie{B3_vaDmW*D-8wdB5`^g1^u4*R*GC{S5Q(y@mnDe|h47y?&AX zbl{&IV>*LqeF#iR{s*M}4ER;KuJXRLe}DgS$B*RSdktB~AI|@vfAq$rVE^7azfeET zG4I-Afhxx@^xypW!G9I$@;;?LS37>8KHK;SYp8MjV*cC1I_jCCTE{Quzg_B^|58`p zm-^mGK7-jZl2158+8XQI`Hg)1J$|DTW46Wm(#7)mKjxjE?Xi9#esk=Q?;hAO zvhSUrdt!Zie}!$I62I>noblD&#r98V{W3q``orztH}^KcM0uak`i*=VB#zJTmiWW= zBe@SR>Um@;73=5QzwvMVGX9M9^YIf}zuaaxlJDC#C9l=7e!l%PTE9$%MfdNm^9${t zQvHpbN<02zwQFVnQmVh)r5EEb4Sh=c-x}lBu9fy<<0tIjZLxknKa}>rJ=V|1Pig-< zM)C>yxhK}Q_digozqvQo5A)ydHS-e|#rtCYF#qj`{f_|mkL0iL9i15S@mN31zr^po zhX=uz`Jb;Hd|mP{^Hk}vhm_ZreS9sl9>J;nUwE2!TZ zs?Gk${W*PaEqs1Rws4=jO`^wgF8K0!%AuD1oQHbirSn|BaR0-Mt{GnMJPOy*TX*gBl2*`1$!ug7r3;^%rJ}EI;?32vcZrn z#@PQTOEvnTO7n%AX1dxIgo6fSE~P|$0!f-x)5Y(wzReFa_jWA-_>>Rjv2bCj0>8TW z0O@BM{92M*WF~=cKgXT9)F}I>fZxarUaUH0f10wN0l%4?pL%6~Hu!`onMej2l>O7e zpAcEQ{~wLY{v7bz{X>ojP0Icy;7^XM-T#lbfNEN{yb%WzOsM5vcEvtzd+f)P}#o{eD?V8o#3;_Z`UaM*MiR;U%eZA_W0*E@Y&;& z_k+(KKimaA`}qD5@Y%=rjo_cKRy8dY=1H$d=UK8Baiz3aR&J8_|F8N9sh^G zKhHlU5#eHG|98PZBeHh?KRT8Db>Oq>=V{9RhrwsJpTMk{UONA8TD)#&aT-Jd{Vdl{ zqMw`V#NhKkQs`&6@mGPLkvkTcOB(#Fu^*1aTdKj&nSQEY1HLg&@PZeq7W}{*rTTT? zC&WL6c#)?b{3&Kl@B!jQss`{|#Q*c+#Wq5w8o^IVer6H#(*(XryiSPv1ksE>>3xaC zHAudr^_kkc?EPur*E~U8LmT?T-#=B{LcgCA9Dgpcbs94f{h&X%aQI@pU+nhP?ck@( zTqwx4pic8`?bgH$(X=*>mKNp`p#Wr1_2ftbR)N z%x~qFv4pa(_rdBBw4h zmHk=D{;9ft+FT#mzqaL-w9m7{=9Eo@&FNR;Za;x}VqWRz6T-gzKi~T~lI8uJe0cN! z`3@ygqxfU*sj%gRKdZ|7vLlRle#{(cKPC4UnZEcqD*nG`fWNC^DgK3LM*T1Pf8|ARZmjFD*NyC%Z=oJ!B2OCr zBlhZ2CNaV}^T*MYn{h5pM7ufb@=lB->!Wt9cn{4<1%TI#8EsVd1<)^@3bi0jz zZ}x0beyU>qzPT(v4gR)#{CzzvKQO%$OWRMlclTzehrf9Ln~3%M=Cb@`tj~*I-Yg!I zA7fbY2jok;e88)W34a5-LPY@WOK-txz*;){zv--do~@exzb zH?6I$!%rIRm$##z9ezbQKlcaYi2pM5PpBt;8(wAj%dBz4ADBC5nk8)=b|jJ?@NAk= zHLs>Kk$P_J#Qhn7EBI5sUpVTotNCVNx`WjHGp92Sk@Ee*5kI@u`l$rVm(RP3_=cXJ z-+*s+ET36={cdZ^lr2x z=^q|cmyN9$NkP5zt@5Iay}rV*Zt;A=l>4T>YTx$At4aA8lTB-}!#r z6xT025nc%IgipdZp<3%XRhTcV6SfF#!r$8A-^6x`>k=*qSDcO|sTOb_85P2yY-`pD zIDC{#tCBERWs$yFe$4CVWImsNTS;B6uZ!rnNA%Mo`W+Gdl!$(3L|+@xw?y<)Bl_JD z{fvmdHKLy`zqU@O$;$3}oxNseJ)O(6rn9MzP`|x83FlP$`QIZS=GTkM2cOrsA(nal z#LVaQdrRta{iKL~Uqr91SJwRcMG(MNoKeC%=j04r+GIQXI*cCIW>Q4acLd{K^>Io{^q z&oh2}l;mK4o0fH+m36@{cSzPIXW6rE3j~RI}+o#lxCx`8?trF0$9t1Kte3WlqCt)!2nf^?rd@_EMFm&=Y zP+oW*!kEm*yy082N^hTMX^fw@W#Z6m)I*38qh#NqT`vA`SL)-Nd4M;LdTn1C3%5dg zxGw!La%WRFJ>{dUJ$N|deS60J%l2sB;D2|vDf=1*OQ0!^5f-Bz`UM3UVFWyEZ5G< z;=P``7W27j6Q9@fJA`>X=dq~oya%u%z0cj3O3Snhvv{xPZpD0VzJb?IMlADsI~!il zTMzSkJ8Qfhx#udhQNQXB4R;Az<7?#Klzkt%oP-a@({oRI)xY7$Vdu*3YU?8$mcOU% hjpk!m6ZAzf#`ze=6N};gh4V4ieo;H*n{sK<=U?qhSa1LU diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cch.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cch.pkg deleted file mode 100644 index a921132b979a7739d3b519a864c07dd0735a8d4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35136 zcmd6w36xgVk;m_26+{IEQ5I=7MTuJ!!3`P^MFm91UFYBeIw~4>CULb|?oJ zN}AO?yA^rJdtynx)5O0>aHZgS!L5Sd2+G3iO6#&(2-^tu5zG~wD~Q821#h|HuLRwC zgfL35jbMMlQGy={*6kU>IKhE}Qw0Af*lG0;E*2~jyeH`1D}*6}odmN4#|kbGEEK#a z_(ITc4UGrEc)5DpR? zC735TUvQ=1cEN*!rvyH{E_$QhA&e0aCKoaIG>1cfop7M)I{X`~FP7yP)qPS?|Jg-+ zRV&+js>t`E%m1GR{=VV{L61I_7W)^mwLh|;#}@I(wJoI*Z{_HT!Z%!}!r!roo9C`j zQ;M|diuV!xqhL+AB z!M`v{zcr%CdryM*Xo5%HXC1%6;iOsU)6cLF#uoV9Mf`~3cU^i@&Jg;q8^RO;;UvX3 z6?lcy^#5}u{H7e`*sEWoEVaI?@ir9YSZt-4tIiN9(X7LbzObKjDLp4B?tnL%8k?_4%a`h6xsS&cY85m+m&t!l;H2 z?l?4rJB9y3aF<|(%Kq}VA$(Wm$F7rw#dTSjFJ8U!E?uUzlwg;YA-w-p2)m0v{UOa! zkA$#?@;|>>78VNj-cED4VBe`)+bMod=?Bja;SlA&Np1Y;L5)+DJ5uyff};h;2<8fo zQ@-1gL-nm(JqvdTKTZ781!oA(6f|_L=tIlITrbG5$K~QHpcZs>wZ75jRwL=qM&4xqv&qCKA1(gKaYfC_$vVa`aYjR_! zT5^AP$BrjAV{H5?=$qweN6~jJxxKzSirnbCeiii1vc03|yO!Ku-yKD6^xgga*83A} zmD^3<_!RF?YRT>O-JWur%;Zy{_9+ zZm;W}tDtKgzqOmL<26YwxxKF2Tkh`C8}hTx{fdR70`x0$vYgM+5j5*izqZ70zOOS! z(g1wn%8kL+3h$NhN#zKJvaF^5;m*ohwQS8fZfsNio2bkK)3pu`_lJ5_)LWIzRJ?`2 z*ULU&Rq7pGqh3EApLx8xync<$F>*&)L)4PnkH_|w+r}gNC_f$({Cb+ zvT(qEH?N2Nt>vSg?i*IpIlhBtEn(^C`PUz0;qm3#zrGU!W9X~*LU`!2Ea2Zh7S3Ma zh1r$0-p!Jky%_Th^ZGAT_Dki-##Pqd)Nk#uZ~Hde*+h+@fA-l6UadT{(8vG~wv%sJ zS26l}T5!N8A-tUZF|+;Wfuf(!UdSj%I7oEQPOEpa^nVj?Rm;56hBCizLz&;Tq0ArJ zQ0B!pl+n@4D(mfqHk4V~hB8mIq0Evtl$qOxGAFm8%o}Ye(^n73s*dY^Z7B0{8)SR4 z4Q1xFq0Dn_D05^R%HWH(6yRex7u>p-fABG+0R++yle6!p7~bxJAN)|~dD)2EUoj7K z73@~Rm#a(W-=>7WM+tvM2_O0JrO3t^=kZ!QvW^s)%YMB(gB&6r^XSdtzHo#1l%*VV z9sI+>34wDX%VTpWXPq`@Q06uL2KcIgvcByTTG95uh9{D3pBT<=Y@0lB-6yu9?sLNB z$+{-3K#3PXA<-qnPM@s(hQAmMuyF2;uQItC%JG6!TU24crzf8}u z{I)M3-Rtpq(FBvj#)Rn+IVLOJWHSBvI!?%IXjun-*vd_HcsxeBsdd^%wku>8+OPnh zF;9Q6Icfa%Q)@1uF3L_9*jzwao*87HR>B`&!kwQ(Ph&ZH){p}qg4{OO@*A?BYpMHzIr(u_-mb{- zq|PjueeW;fKUBhhu!R5U>~#H)mGB=g;s2(DznP>(Vtz~a=YR07)p+bxq_bYIwE*h{ z!S96cK!|7JLAU&GP2;qf>;RcQq3_x2wky3GEo*RVe_ z**N5V06z}V70<(_0%FcqI4fa(M}Fi02&6M+{rMsFw%7S#th;%Vg%Ilw8OwCntA_4u z&NKaRCR9s5{+zNS>F1ww?X=Vn=Urv`S)+!2c&<`@?E58cq0h3m)^u&*yBU8Luqo?8 z+A=@JyDD3cY`%xvR*B>x|4hL_Z)9QXZ0l@KhjXT8{@@DnPkCLwSm7#%U+r)`B8_=2 zcKG!Uzro?RJNyoZ-{SC#9KO)u@tFRB(g^XGWgh zNBSqt0_{W77V{mpu|2@)!U^P|Ez|!L(a1dDB zU{0Ye)&!|BaF)^uaXI#SRxZ|6zZx=9SE{YEX-FY%i#1SLTkFqmJ@EoEf9l(jXeMqBto#x-@& z2j;O!ZXSad&tpS0kB!O3P(xPqk+R{BX-FY%Yp8f-Z4If>maRotJ9!&0uM?2tcsXcvN4r}IXlrz~RmNW5 z@JSBePx;9UP~P(VJ=#d=jkOK|dFYGDHeR&J7C&c0m5Y3g?bI5szxb)PE)ky)x5ar+ zSzE(uw1r(#ZCy%33UOQY;+3^EJZg)2El>|<(y6w7Qe=wT;ykIWtr4!Rl&{j%mTc>? zlD0T=Dr;+GjkboUEV9SGCZA@DH1E67Ic=4#Nmy?asMD8YZnbjpnA*t6m>N?&A1N8H z6rT{c#Tc}}uuMcMxJZp{*QaYf}OKggrX%E3|fxPT7vK zM`vF}i2KT#E7e!_+qL@Y_uCz*uRqIs+On_6XnjqMzn_@TDtjlgiIi5@U$v2MPUs5MPU+M)cH(=K1#ZaUS4l{GF$H&ONUy_%!_&hJ}XXK5c;CFryMP zo*L8U7HQKeF=MMSEh_h<(x?ZY!u$H(ryygQPa)0w6lm{LpuJClt{2#tf}R-B-lvf6 zeG2r~C?wD&3G zXPo+U?^8(kJ_XwQ6lm=3%X^hQ-LK17PKIys{>{7Q#k?(j<;{+z=varl`IpYQOq9Db|A z=Q#XmhrjLcg${qq;Y%HkjcqJ*7e{KWSUUG~R7>X$k80`M?@=wC?l<%WH^4xQ0${YHAEaeA2kprbI0AD^{XGdN151K%1YYOgGS@B6_ezmmQ zv=*`Q@RsWAWsp|x@HP_=b9NK|Cf(x9=8?*~=lE;;oj5>u0CejOYZrk?(3j@6&{5>XZWittGmP z?&~y~dAU}epSL0peXLavje1=?wmjVjuM76)DP4>dpFVQd!+e|4X?*5WnU|Z+H&wit ztDAV(Db7bbF)x1}qVrPvcZz`gjBUnpN-k`~xjFe+M?d`smCNSk-!b7k$0v9b61)!+ zyfF!$9;+5@Y?$C}pWtnm;4uzknYT>vSR=>zwoUL@`^EV-N$^G|c%u?L)`D?;v!v{p zw@o4+>-abycCu%m@0hEd!OFDxxuKoGZYr8F#qVl-FU)x0`J_&OKssZ_zx&F#Z?E6g zkjv!eH?mrC``^eqirna%Z?9XcZ~EL(^j%ACukVf`H~Qw=_}1#1d7z`{yO!Ku-|a28 zt*yEH!PY5^0q%hyMn3!r_aSfx0`|bSkOmNrRwYJLUp%*wpS>`7_~!K0zLk1J=6>om zx7Hyq=V9@;tgJ_k-^<}ci#k}ttTiw_Z|u@)!h{k#>$I!I*B zAMnJ}l_kDRj%a zH>STP`q=EGjP(;^WbC(4=k%{xCw+k zZ0T+OU=5qww;tHsaBOZkHa8rb8;;El$L5A(bHkT79Ge>-n;VYJ4aeq&V{^l?x#8H{ zaBOZkHa8rb8;;El$L5A(bHlN@;n>`8Y;HIbg=Qi*Rhkus<|Hpe3yi0*U_T|9w z8Fh-uKUy&BsVsb!eV+SD($7!u&P(vlP4L*^$MyXsk?(&KJc-+)?3W4NdkNmV3Ep25 zJob>Wd|M`X>>=ZPnDLhc9x&Ejtat1lFxxA#2jI>t%5_m5>I4Wp z3yf*M$0bjD?E#Pl9TGF2?@)4v^ljXsVftckT}xkn@6n$6!j6Lk#H?BSecpV0ux9O6 zr0<~Ez9ZS*;cE)Fwd}4AU(4Z)Ez3h&=8HLVjeYT(&KEPj%>QCj!>Qv`0Wo&|;G^dL z93RXxLi&vYTLj8%^cKE{%f7IcRIeaIFU+VBn96sIQhdF$Aho9;2ogIFb!_Rj3!45y#;jZ4Jk^hGSd9{kjU<8h?Sq{aOv% zS{`g`IJPw$+Zv8-4ac^IV_UM_#aBOQhwly5v8jfuZ$F_!_<#23kd~9ntwly5v z8h(hwv90m3t>OKIV_*Ju!M^HzwK>KA7DpNKuc=>zWVSrm+ylL-0GhdqyB(|5>*p$b zRC~=;UT)@$T5|h2qrK(!=NuzGZ0>tk^_&AetXtTR^DXZ7#D3VEG=M<8##>u-e7?mz z6!R#%hJcv&tUImIe12P~xyHBQ=a)f6Ip)P_f2VoT&Y1X(*q<@^-z&Qpa`8L1<)IJ! zrky`q!ijlTb=lIEdlV&wKTBDZAzx489^7xh%?*{%MRaeSIvQn|!a~GUX=dK#cs~dUDZ?u+< zpEzFcIrBRuzuWqDxSz`M!AA~sWbN=bQGEJ4GML$nzlmaLl=HqF z@SQT>RZkm{qHL%BKua`4^&@4>`8Z_b8mO7 zBPE6X^?;Ly{?NvkI!)`Orwy8be~o$l#iI_$`ySG-~%n2Pu-?ilS z`fhKzdrNPO^L%}*`4WAL%z1vTzLR)%_A|xdlr`VPnY=wiJhPk$@h+av!}{IlVJ&a# zPu48t<&I{{!?VV{#@w6C9mL$-Odj)5tk+nhdAT_^A`ftn!1k@s{(0ta0W^wGpp(IPJ0)C+0hY_&cYU zB`oV4(y=M^aW^&kH5^|8&fVb1YJAp2hEtxonwakud^_lyc8EzwuU4PcLEY2!x&!F| zfjW50m;bG9zIBM}o>5ZHx5-|{+O$5zcb)T{L|nJ8!*oJ9))ZFX9wqI2x%tMTTHU65 z>Sml--7~Ayjn6@+_$v02_#D%*>5w&ytxKu5o;3_V_Jkz@AL>1k_pd4M^Ucz98rzKK zys0Vgl4fa2X-3ofU;#3*UuKUS%S|8b3<5um?Ra^lr!ec+GK?Y0=)Z~XrqOBi3ejCO zvW+IT=a;`L!##YoTd757hkD@110Wkd`CGW7x`KH=dt-|Eu|i zJ73M7+#S!eMjmj^J9#gMJZ68&j;UgElZEdrs>x!{81)Ts?Vwwe(VlB$;rTLI?3skW zO^GbjW3rr4Ll%4XkOkdZ`vYB@j3LvDJ)gACI^EgnaBoJUy;0Y~QqBZ7Pe8ipL1!J?7D3 z%oD2xkLNzlhn->``j2^xiUZYPo2YA$5`3n z4oBa{XPg<%b8I+1#c*V1ZAMwCsIzx7c+>D)_V>CoI!LX1CPT=Kmi-}t4*7iVi;*Rz&o;hF52{9P;+ a4JQa<9(9|ox!bpzt*P5=edKEs7X3f$@0wKr diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_ceh.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_ceh.pkg deleted file mode 100644 index aaa24ebeecd3217d947d8a08e6bfc9641c34a5f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6384 zcmbtWZOCO+72abrI_8+8jb>(Heq>_Nd++<5#H+;z`+ z_S$>xwb$1^b(n^e{h`{XZvDm1Z9BGo@=S$y(C!_0!~0W5k1pfwqOYBC$YTD1R>8Z$ z_q|K0_-v(SX%&o(=3f#9Wu=lRQDdFzA_`TK$E8^@aWK%aS&yoT3D;F`b?;tN4|A1I zD>I6-brTIuubJEL%pDcMIMLXmin7!M6EzAmZFCw2xhbn*vuLeZq@uJk*-RH!=P0IG zH<~IlTe`@ag|ktmsyaoQm4THBCRb&&=I z&NPHY<+R!1x=x_8Jh-verq3hw<+y#i#iZrLx_18uZ?h%7%`4r5Av+2 z4Bb&i=@>z@u0bG}dQ}xS9^P7>yDAzdxyou}2Lc~)=@=P86S5#dwnA0wR%SQz#hy~9 z!2lcB6T(w@kS;gT&>K||gf@Sz5K$^OOEVc3Dvm?vU8RRnWx}e6882Hl%Pt14mWgeLvU$Y9yD&QZPeR3~F-*W%6$ed}}C86ALC&MJwc1TIUmLYrz5 zr1Q#AWj07qc0o7{%xnd9mxRiTf_NF7MACv~!#rMVD_rSnqT>ES^4WrKyN*}US*j&i zFq+-N#$axn%l2m2^}~fYsXQo3z4^=9kL6uPYA%Jf#vlG<9D=P4b6Nk~j( zYr}S&xUcN0vQDxo+5vkGyNlGWa#hxonx=mTQPuV?99kDPW=JdvM@ca|Tb75}(B+p6 za?OVCf^16!8D$od*8({`9aBc|ES-%gCc%b@b?U`1tP74bu5oR>y*EPMG>YkuT5f6! z&0UWR`z{{r{VxyNMtB`uY3=eGi|tr;)LlVHhbV>nXsF9rD?VA+jceqs4-g2+SgV*} zva4NDw`YpdSrDT+bEPZC_U1Wx-83C$Yh|7aZ|9L_=G*il#p`htL@_T+dkd@CMjWK} zywVt&>l4}C81Eguy~Eg3>=EfMcAxGws94!3+xg9e+t%>PMQ)?zBZ1J2rO`K?woN06 z1#dmuitGiT!ZeZcUTeyGtMB;(w|N^0>vg%#_|YM8v1T=`v^kxd)P^R^YkCkS7J+2F zbrw%))3+Qq7k%RI&9mU`V7@=M6MrD$9pE#- zZ{n}-@E14;vLB#${s4>kehvpg-@y9w@f3UvYcKWim(Eh^Y7akx^}B$%&nr&1*z!xv zB@t6j`#ueR513|N1Npo0q?}_zoLMk+(kFsx&)={}@VUT`yF>6nciqfQK*ZeZc`61G zQ*Q51 z@;jlAeir%TkYlLDe|EVi@;_lR-vuAVWMAK_ko)Tg*#A6l{%7DXUw#`fb58WVj2B{%=p%=HHVBp$@~;7|4gR3F26 z1oQc8tQSmuhw&$v>$gG9CuMxDLBC**J;*w3ut={&aj>>2M_!FyocG7=_8Tz z95;KIb+aGFh@7GLqlfA5bFjb2SvS{Ul3?0&DS%-1jjKF4O+Vu4qm7Sxa-Lzkhw0ZR zVWjAzpKkEZ!#aHvld#140}pjRhdBu1*rVWQxG9KuFZgv2Pk;}CNtE9L{uu#? znDz8`0ub@-;Ip|2i1_Q^U34ml_y{;501@8@{x<=L_@m%WZ~h73H5XsXUjl#I!yCZ6 z=?oC%cYr_c;fH`r3P61P7<@mS1|t3~`1_vxJHWs9@Lj-9fvJ+mBD1DR9LvFX5`c&+ z@Fffqi1-k==iwFLPkDFFf;6Hf!_5q)8{^$Jd z;HSOydw@6G`6<5={DL=sH}GSg{3hTvFkQ}VnD769Qo)S>39w-Hs|zquF#F+0pkMF@ zfyW-Eef(AuIZb`S!>qqgU{K`jpHrM)FrOd7pJ3MCbKZQ`&+8uM_uz3HT;}sk&v@(E z@A+*fa+spF!ykg_pTBx?_6~mgiJbNKKu6yad3?|FY*l#^{K5UiSZ8 z9%et;<;8=!c@=^r_AuUW5rF7x@>%=?@xfF&)5-ZDA9r%T^ZY-elR$2o9pkq(eM|fH z!G6Y#a-Qc@_e1wSI931e-WRlq-}2o5N^rOTo^HQCRln}`_wN00y8XO+zjXV1x8HT^ zwOh}};3E=a#eUN5H{Jfx?JwQ>@8)Z_p1bwZt*>r9|G)L}U-f`|W$rOePnQ3u%I{ka HTzmXKOi)H- diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cfh.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cfh.pkg deleted file mode 100644 index c4acd218b0a7a7b6c750df2967d36f552902df5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42228 zcmeI537p+UmGA#yRrY<8r6B|Y1V|?#3j*e*`*x>EZ}h#L1%*oz5Kx#0<0v1-=a_ML zA_5N;_lGhwE`ul{;5It0qv)uh1Ea$tA}Z<|1wk3-xeUJV_kXKy*ZrseolcveVD6_+ z*T3pl%Q>e`ovQk;qg{htOMAMqY1u^|f7Y~Zr=5IM#xcL$w%yL)+k0l&vg)cvebsQa zF;J;3o1OI!4J{iTZglqzH|o`qfku6FaIo6n=o?->Kl5LsQ3IOYSTsNDs*m(HhDU~a z`ueMlzV4Nc&aAsqujI9LX3Kl}vccNYM%U0_y}GjA=*%0)la_XmG}>f+53MxWG!yI`Gcep=YxGx^RQsFEjZ_DQ>eXy{e`T<- zvcFQV(row8=#u_w)<3t=UG0JQ;Y!~~qjS!}_6p}UIy>9=os;#?X$({cmQ+V-ODU!t zBSSP->8ke)4K`}kdQgapgQ0nIqw+2nCpoRub_x1IVyHV-x9+{o>^jB9l zs@;9{My|rX?z|HQhPtb>TSuME%6s~URx|}{jMl1+syqy@YVWjGEbCrA+!(CZR}76T zYxIr`jSgo+!DzAlrf;O$RS$d(P*bCGQ7TNXOB+~)Fo}>+ajj-%H%5m?vYr*) zsCJ;zH<)J5D}jN)bFE(KTGj|QwPYytRn$$Mx!F=SQ0dCG)3mf;RZ)vMx3!TjI=`8# zT5IcvV5F7q%5c3gymU!Ruf4<7@#LPDvb>~%VwYF?>9bZ3YU71ojGa4Xa#4)h^5O9s znUglsKFS*XD@MjEvM?<&PJb;(ar$KltI{lnMj5M(rPWF|0rF={`+EC&8(m8)gS}PE zzDBo?S#9W!d^9U)uvEoJ2Q1c)VP^yN(Q$1*&FWaxHRK~<-n_=b1#LA2TW;1@t74FY zUDd|msADT-tZ6(WmBCtH-O*3_9j$r9+-nGp{5?9(9cWK*AFP-yO=t8T}l{9l_gZkd#dYhi3B73WY)#cSz{j^!_ zucE&Kug$(yX}ObY4i#MhLO2kIheqm+(RyEh-{}=yBmNDiRiiH4P4sZfamRzLrgG*w zb3dXca@8$oXfq4cR?y$MONWo(xSQiUjzGPfZZ&#Xylu98ctx!-(l=CZ3@xvY^jB7m zGrZbHkIm+O7zW$@U26_wGK^h(+GwR)y4KEIP>OxmUq|iP=8<7 zs)kZ^W=Ujr(_ovLo->Jgd2VN8t|PhWrkksUyc@m)+714YT?3MH+fN4G>H$Z3^wQXd@YayyTkRd|uE zp;6WtxB{H~+&N47>b1xf8fE5+7M|<6*3;9#KL_4w!RV6}XoT`EWc9XTz6(rRu-ztR z=Qa_V9FM0iS)#-7i_80%vFPWfg*ScSqD6YZ#(0a(F#nFTWGo%E!K-DeBMMuzZiidD zIpzZ}tTb~!*jyyf#-+6eThwOK({^klcJp}dEH%nzi)l)9HBAkU=_HK$)}oURotr!N zcExw*dQ;#^y*|>ngw;!?@6KvNqa*0KJ~BGEj46WoF`of!u9FpFZ5jVv@i)gqSlEZf zUtx}0e`fETn~IRvQ?gL44^6O8ZA}`yP;|3#MEdQ*V-lO zwtP!J8?U89BYme+BHty^dCeg-Oc*N3r<~eAT4gXj)}vW>@9@}~usI3}u3!$6cD^iJ zUx9Pl6lgg*K3}If$2&@y6q@sE9B9qyD@b7Dk>i$UYP1Gj=hz|MYrRe1oVI-l6LEAl zxyJNtskuf5!h+3xOH;GBrsh6&yv5%7t+v_k*veSbz!1l#mv}lM=}G6p=9)kE*ZEp! z0@u~Hx64hc+80O_?dQxL> z-P3-0LGw_jV?Ip#$xj(&-9v*c$HN}9kF!YZP&x6_UF#aoCK&bk-YK@i8H;Kk3wkyg zY&Fn9amJk!Pwy1^z_r}iqA{_i^-Z&LcB;gBm0|8C5(mD1oy|V2v9au0%J9y2H_>C{ zjOUvpjK$Ll`C@rgH_%vG!KP4F%LtnTI@!CU8Qgl-wC?7*K^8V(Ciwy__e*Yj@MigL zuG4dS)4uk}8;>L0XTet=%;WwGKTi8)o&ek_CKN((fBQ9q*8k^(qk~&1V+V(FxRtb9 zmhDUUyKQNk(DRM=J}b-i562IYY433SVwkWE^W09O2M}%z-?x(I#h<_ZaMPvun@i*z zBFCqR5llk!ofz^|Hjpg{~{c}d?V|yy;p@YR}{)# zP5kvC?X3xReR3T6eQ%O>BgY>M@mrJhm^TeSIu8DcanjN<@%Yn|%op>g;peAV_Vz-# zuMod8NxLf?e~a+GBt5qM&^T!illIeb(k=5C=}(kkvCa*JzoGo^k~+4=-gj{DOz_)f z1Na0*b7+sG{65L?hRRJ9KY%t4g=Rv>PqDrElsgeRC6r%6*aHnfE1=cTpF!#GrNl3V zUIG0z^cv_YsOL^tTquUss6#Z6R)5?wIJvY>Uw2k31Xy8Zhe=+mX;?v26loUgv-lA$_?R z?!3i|*mEJ_0BCU({K*kFj;X7BFUCSlaA@xzFl_ZpON zOu($`)6gu)<1XqQAdGEZgkq^WFZUpdJcDD~H1EH{-%yC#=9Ls$7UIfgyg$U1&G@My zE+0?soMqJ{{sG!DJ=T9L9od!OpMsGCllXPWu`tAKe-HSnhq&z<9}RKqeF^-_hxMEP zPIQ7wTRJkn7jg5B!0Rc5<~9Cuuon=LoR=L2Si`Y;IEzYV5SrI^#ny(n?R=88!D)n+ z6*oRYXuZF|Ru&Ul*1T_n$FoD+yvAJ*Sl0Z_ zd9vIvp~qr~+miLa7;v2-ZoS4&2yyE&J}1QG>GjAb-|E8n&B$kHSuxjam`olQGhO^^ z&{D`c&9|D+d}4cWu!_*U=IevZXL-cR{e^L{K}fx>L5Kx}%49x7%*$KX=^V?S`E1Me zr1>o03&no^M`ZI@vTfs*i}-z%tq?a&-1rhgdHyQ?;}F7F)_6yV+tx4P<9Q)2?{?O4 zN&NMUGuY0{%jW=XpOxTuFs|k&@onfgnrP+!G4=Hj--dPUAZ@*8uWfgimq;9D%ZOY^ z_+b+_4=?g*5ZNlH=EexNFWgL#{L59nx+JVXW8CwdKd4 ze}X;-xi}Kf0&_6<-hwg^%fgXZ>2>k?l4Eh!H zB(x)aJ<)GB@V&>$b8twTPB;_Nug?!@&kNy1^=`qoXy8vp1G)`;yrFal3r$1k07Hgh zE6sek>U=J{Gs$O~WSaS%0}Nfq{VQq4#c})D*ONS^IWK&JH0!nuQ$=<+aocuoG0pkz zu24?COk;}3^Tj+&S9x44rZH`1|37i+I$5^||&ikH@i` z>$q=|7S{)^YyLfyi|sjw-B&1Q`3Fdga=8App0qtN^O$CS^=3QY3u)GGnsR-Up<>dyQR7V0~Qv>ztl z9mM}5l#6v8M%qtF(z_s16Qs$5W#qv!))Vu%-u_S0tk-nc+y9Svv=__CQ!HnDj=STb|017p^Be=Y z!H70xnrq=-g}UTH{hbJH8}h}nbCP`O!F-+JU$_vmN&!zfNSAkKcv3 z^>LVOPk#B3H|tme$w#ciz3y)UuTc*RN!vQ)QN9Jx9-*G7gKpAxPU5)>Vae32Exaw58CVNt$I(gAODu@@~GqkWc*>?+tNfjdd;KcrVID9lA$)4)G}e z2yyF`N9%CCy&G}cjD6)^_h8b}w);to^;+)K5Vu^cdz53#rFE?!ts|sG9k}1wFR9=B zD?`4>gL|h#L%GQ70BQS@7Hv_vmqUk;W**};=pf>er_+fS>lq^LfKazQ={uhf9Y&fm zo2HGP0Ub_S%;P?NdQwim)qrM(Gcz|o|e6W zI&q8nd0^X#}&^Q{1gmC`BT4O z-2;&4lZrCBM&Hyj?n|AijISf!0Yw=Pz6jl+XLW2}q`Vg8pOKU+lV6=~y>ME#0Ach~ zAA(rgw%YqFlh@@mBK8G{Zf;?haq&REEic+k%8UGJ8=jjh>TPq_hPo)q&$7D3Ynl9( z+mZhF`be~K=ccIdoxqM~+=$uV(M~zc^YjpU&afz>dU~pDqbUDm?B8w8=IVcSk%^UZiZZYtvqSHd}ut+Fq} zuzv6+D4lP20qeyG#I7!2yMjFrMm0?t*y8(|y1Dl$(v3cR7VDzz=_}{yYoQJ( z_SNQCGn~v#2s6T(;WpaxTx4u-GV21ba~17IJKNM_cxUQN*HbqU?|>q&QyIgPSu?sX zy?-1T9qXG~Mtw@!|3w)$NB>WzkG)R$Ozz_W^zL=nqKsSS@QLT}zd~={L2nBf41dXl za{-g9y(4YTVKuIG{~<`^@jxc@8SozuNHo2CclSx z9U+)Ob_Lk^G&UagzDKz}&AQKe|ws$Mo19YmGVaVP)^MB6kG9&Y1x^n_dw^T{(4Jhpcr*r`FjZAeVZ9Rzj( zzrZ;;8WFn+vX3LSh8uQ2jBShkPbjv>VYU|R4Z;6hmSAMh%R6Qt8b_zV{h`5+FK9tGJA8bFS9q-XQ{oN!nK1hqA2z78c01x z`BGbS442vB%MvWM>mJE_4~zX|9c8xYSWf%mTH$ZNU|oLj)swO*}&rR%wu z6tJ>B#Ko45i|CJzCXe?)7UdT&lOH$Jwhlg%cn1_^EE|iCm2@m_OdngfzRP<(i@Yl5 z7GJz^zBu|E?caN9i#mNK*uVax%od~lEB}u+Qhs%l`rD%aFB^}p*~<8ND&{HIb{$Y0 zr-sf`-Wy%)|EJ45<=pb8Fi+V}-qZec?I*{~Gr6DQdc=P6nSrNkKRwgOQ|u@GzR!9T z`{|iJ@3~ge?<>F0u{;yypJ?5i%J1_x&qVnr+7GAe9-k%pQx-k{#3@lA)d-Ok^TQZzDT|KOlh&NCequElu7sCMZKju zRc{?o)agXJDf83%#WKC=r~eRoa}DQnwne=?)pOW}bhEkaW)1TDeDWa}?rqHBUK7%% z8)}eUjq5;_Rl&fM+Lsq#=cOdvU`o3Q`39!tv9Zj)W-~XIT14Lo&t6R>DvN` zb<zbIsdUkPs6BEkj zJ(^|z00Zjce?T*#$V-{cJcm5JT<3iZL$=(NP%1;TCuO~m%IuR^XS64=my(#;(+v9X zehkw5^5Psxmc;~I$K5KMgHsiglrdt~?KL}};Xi`0*3ZQgWt2DDndo`8v@ceYHB<(CUSE41>8PoN#b;CO>wTfLJ?lOi^4$eRz1g2>AE&yJ_l4+Y8ksyk14?yMCciwS z@?T9n<>x%^{kecl*7*)d{-XSbosjQHDDtXa%Xqb1+K(0DQ{nYu%B8%fef8I1WqtJ~ zu(Yq_M_cv16h%3nYFl+ImG#vhqpj-4{(Bs~X;)?auZ(H`d);<2{qGtzwN=c$wEvxx z%liLvu(bat8mrny59GU5ind`LQ}JV#E9+y&cq(HT@zlmwKFmE=VT{+nQW;bGKevFr z`5d0h4L;62Na}B=>c`ZL3-992^IUpwN&a?-atGZuVr$m^VF|$ z>+Pics_mtHbq?{==cImx+v(bTPU<_Z0CSA$7yPB`oEgN^I?Ypue9zNoIh)m{EB~vT*kXcgCRh(PWO|~{ z9J9Q(<~!N8*xD9bi}tiRZO!-fZLzh@Yiq7e|J41O>oVVAS+q6%;8f;N*Cl0h=$>H3 z^Wc+t$A$a8?>@o#L;SPzz-OTJ9Mfxg4$OC~i#f*}4#hG0;=`w9*CCAafHI|fNb`6u z#CK~J<<~Z*BELM8$C4i^F7Ovws&-Wnz%ef-5kZ7 zcRX?RBFPWfVuI{wuwfESA8$T%f8{$!i+Z#Fr=qus?8f!!RP083OKszQ#8cb20NZ$y zh9|NO-;r9Baf@wi*fxCMYf*2T!#1?%sn~`#HIZ*f-)&bMH;$h*kng?y?+(7tzzLx5 zlIT9dF_(`2LrIT&2z^75*BPW)pTDwoyX78wly{So(Y)6{u};_hsc-xjGNiuoP#Aa* z{>E~Wwr=R}-C(D(i8X#T6fxy^8P6Dgl!iU_7t0%djQ1v0a18SGNfOfb;oJE@0y9?MXu-$1)?2QFXew@R6m+)d5ybObIoSSa@XYw9knBmiGmI z9|pu;1L>b4mOh7cKI!rvvGkd^iwl@}rbD}qBfssG$*-L*K>p7M`CmYMGV&iszEsAm zh^I2jPY>j~l#BhL&dd1OP=8G2de=HvumJnyz+G?|`k6o9h zdUJkC^)^u-r_V+VQZDr?Wqz!ae6tuE_ijDr$I`WNI&M~zS6>qKmX808@o|<{Z@xeM z>8dyT?54~%^bKkMUq(Fb|B2=?`&j?K&p5n3)&9RI#~;I7 zZ9n?%{-XU))Q_9P|LbqlaXj8U?pXEv1VvuA__*?Qoc8Z})bD^4_2!zc%>Qp_{Zlqp zXIbYT$r=Y%@;O2q_q!5B`6sgRsrstox?y8|l{W5oL9Rc!d7t22#N7vJ<5M}0p`T3q z_zvRAtzCG}Tyg(*P{0UE_kYgk=^pO};=4fB>92C)wCtZ~*tS0k?FL2cpLzf70|+B_ zJLDcbV(C84>lH&T}5%S#t(~e%7__;wH9^V7>PrE+&m~>j<(v9?h~>G0-e0&4FT_2Y~$>iz?IS z6|ft?t{|g%V_A=-_k&#cP{v=FVCwA_uos~yv9}hme+PSF=O*SH6z3uJ zdLP(!I1J0pFJRvTi+RsWFxLtXgIyhXvF~HPd>z3HEI+<`lXv+{^)d_WCK@)se5Tmy zmD94v>07aTpdLuR{H+1|LBLKSF~u(7I>HFLRuBFx6X`F(Rs}4k#V~!3;UHzyhnTp|XO2vgd$vcOVHHz$G3B~eV> zq}Zk&XH=g}G?vQ7i~hcByjbT%<7N8OU`!}OIwock-wD!={H0^!D&i?N)iGh+j%C07 z`120FBZ^PCkhpf>`HIOtyVXbDl%I5ed@fj=3!Golds9b=?*T;_i)*&d1S{KHxX+u+ z{ioZJPrH|5dmCD_O((D4w|ohOE~A2#p{zbKm2nyID5HMxxV1bZhch-Gt~l#}Vw>rC z9+F%9sPpul^~&ygG?p_|)+5H@$2QCOk%zK2#nNY!^fjjS z9Z9`q{8%o^>9Q9X^ZiuHHhp?GvZ?=xkm; zLH^SRINvU9M#uecp7?{se7$H~KQNi!Dl(k`t%lAE1uh_b33N$_8~FU!rCtdyR5BZ%HzqexCd&>RJlizzX?mjk+tKT&4 zI>KkUz3;;O#(nPFdo=88>+{=Cej`fE=f!<)Jk}ktnAdNN`J998L@efwSZpVaD~I2G z@%t|k_j_&5OEK;@+Vr=^&F}YK{O(JP`)wG%5fkHn*TwI<#JJy_@!K=TmE|nRdrD&5 c`$xQwB*uMK-DlQgdA}j!w`6vG)AlF-e~kpy^8f$< diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cih.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cih.pkg deleted file mode 100644 index a92ae2cf13fd69a187aa08b823b35f30f7cc000b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 754308 zcmcG%3!EI)dFXkn-_t#hp7)GqG^!bmq|pNyfv^P@s78{7co+{DIhYV-(2qf4T6hV+v{s*6aTzf@9uze4UWCu;fHUo za+jd}zEh8``p&8D>T^yVX}YUVSN-eXUww7z)T65p@4tTkp{w^Ziyiw$#VT4)t>)NY zPOwJFv+LQu>MqN#37#7xXb#of8#Cp1X3X!3^EIO(PTn2o8;^fa#{8Q5!Hk!0w*0QR zzqo)jYq~S$_r&?e^M|eOVYgJLyC4j83`J)=9%Q zn=xJg9Pxj6EnkF?7>j>i?(apt@fgG(YP|dz_ugxnKY8MRd@Yah-;Mb*UWVLR)XSd& z@z1x+e@{GZ{uhY9nExJ6^|2`TcLJX44FvIr_17zD{foq3%zq!K_*9bny8+H0Q1&ko ze=+}qIjKFD<^Caz_=ojr<6q9$ztY0r7Y^bd`lnrgE5u)1e?z3wKnL-s+b?V^phW!J zYkxY3|I*r033!e6XGyR9sSueS8}c&d-J7XBwZa3ua-McVwY3H~o& z{2SY^KUFpNrt56sf65yz@Nc{Q>?Hmt*7nD@zngMeAD~O_?*vd?|1RSH(Attw|8BXz zYs$Zy_Ir%&+TA8$XmXvo8){Vn|Y zK4onC>&?%vZ`uFv7yQk}f1ri`BMI^M>s$H{2>xc{KS=%kz>=jZXjJ2=QlY`_XzgpS-630Y-^`&@rZ>Ec6ctgi&M_qs0II zwQ?_vXXEjQIv#)UH;}Sv)6}ga{`rxFsoK*HA?t|$18e*7y%F^9Y?XW=C3(PNKitFK zU!AVODA@GOVTb?wg}ejn!6VPF|M;GqvuT*sZ?fn7W$nltsH8dM((&hQOO2mz!ACFf zSLPQ4e*L-`R>%eMIq`*VDKerQzc;RpfUPzTZCd-)N|P=o0vR{pt(&y6acBz=vRdzwo|!L;gJipZnh! z@OAwy_LDvAKy{k0MW9|?>v^Pu*-bK{y|*m(dW>IN%h#D}lK)S8*rDn)uCLe#R5!xI zf`u;~%}p;LFs)yW^H(?UdWO#n`g5?@Kg9U8)nJDa*seYw!f+=$Se?dAImTz%a?hVH zyCvOzi5CQn58>xHU%THE@EO~6MfCh*ej%ZuQSARPW?#XssZQfTAHETJ?fm(04&4n4 z)gg=c7cetjkLI|nu#f+(u;N>=2e1^(1wTx>4`dPl#n%@3@rN9H`~2uV;U@{eZ9nIT ze?{~^u+Lp#9g6B(BAL4dD5&;9t$yzefCd{>S_y?Z1M5Eo1*q z;?MIx<{xSQ75qCh_U|J8JpY{_e}e4y+yDJRJzNDOJsjG2KN#vF{wF?SVOMSz^MCN5 ze*Sk8f1dwNF!vz){q|qMzdK|99^%jQKjI&2{}uduGWM?%f1dvl|5*F4;9t+!znAzk zY@KcR^GmP>SlEBt7}Vl(x;3De_@8{u#a(%0?SG%l-$6etf&JVf_g9F2AMwBEHI@gk zvGuoK=1+F39q2!Ee>_OtX6YyX_kP4h!U(oM9rv^elZ-wf^XEIN!N_Ru#~%*!wOa;= z|EZ7g&XtY+T`#pu6UQGU{${p{{e}A zMbUpKWB*~|-(O(MQxgBWqW^Hl{v*VHV}Z>)EAh7#{YNtPA0_@g|1m>j#c_H52Z#P* z?=^ohO8oCH^JAZNTz`uPn@^kO-F3vD=fA|C=f8sgx{UqDh(FJNi9gSO1^=;({l|$v z&wq(O&wmB~@r?b~6Mwuqzaa64?hYK6PLq-Gan=+62kvG3REDYipOE;+4g6PWHdc}e zCy4)p(HP(-(JU70ydwJjn!J1b`MJ60&un~sQj_dWo)h@Fvx{@DoVn!ntw#8Hfq#54 zciUA)*a#^I{M_+ z=;jyCF1+?b($$O@wKrI$e0Fl>yX{?~(R7A2!Y{Lv&VM$@? z#Lh4C<1>607|w0m!03GD*&H6{!2XGMeqjZMc*(Efp^8>zDt3H+@n?_kgDGZjf&TgA zOKGNW&bL?!|9XP|xz_WyShoJTH2xa#&t>eNPvfr<|9r;&1*tzjz~p{%3_75({O9#; z<$r_;$EG1eES~#u5L#f{~-R_y&Hp6X@R!LCoy7mdw@3E%ty+^mhxUKtJ*}or<_7O{N&M?>@NV4yoPvK>#{S(B|7P*` zKUwPdcN70F`tiTfQ2cu&{>|dwu76L){&k6e7?v44MQ}FN2*uPKW-_ZB7C1`(Q=V$$Gus=%DQy=knzs-*id*=rY zTp!gh@vnzz68Ar+;NPFI|A53l9)CDPpb`H8;{R|Y{+5CG4@&&w@o)I6#D6ej{~_Y< z9e<$N9PGc7`V{@2A>x0}&s^N-*5{%9vF;%}g_px={Db}v-Q1_>e-3BtKa$2j=zmiG z6!9O)*nc#QzefB=GxlFc{CWRVmWO=%D|@4P-8$m`(6{;ZMU3aa{^pmBN&KU`kD(p- zr%3m3^k85tWB+mD&)Xj-n7j9E*?#-8-+SHI2cRoNd^&tJPW9y@J0#N9e<~_Fqr@Py7DZe>UMiA@h%K1fUPM&p-ZLhz2W_{{-Oss9|N9Ncf2*Ru z|4CL_`EMouUoag1ZKD63V>ux&U7r8^)>4gS07EVPw-NsbzCD8dpJnX-bd~h`Kifrr z8xAgsMc#gjHr736n;AY68E! za$5>yqoPB8WwR9}mSiJ&2%%2ls>!6W8eaZZ%JNLoPj8~M`-~MF2 zm;a~du<2Lk4-h_Vzi9h&&EyGn{vhEC?f>chr*zsk#x9I)f32@G_WmI1u#5LLZywh8 zV^H1R^K|_B$#YhIV0Ev39Q!{8&RxtIzc&>Bu0(%W(0=@N{JS#t?@si$BmRG`oIl+e`}ZXJI}!hvl>K`$_OB=SGeh}b zC;qVgZREd!>&JQ%{mtZmZ^r(8iT-Btzb|9|{zQK>`QM+h{{Z!e{a=&q{{Zn1+W*H5 zwf}>O{?YvTx^nw7n6dv*qJK1hzN_p%l(GMCg1@QubC~!C?I+J41MTNXqQ9B^8Ohjx zG|}Ho{)}eqzfR^qiTzI~xc?pu<7LQEhW^2@Y~mDk6U6_XH+p7ZGWfv} zi2uVW04+w@Ao_QPzh;8|!Mf0bll1lm;(zLm9)5YUcm06o!iAaIqW?!(;B3I(7XA4V z2vh!(qW>>?gRmIL|4HJ1-y1#rw3nCv`X}?Is6QP4`JfF8rp^}lF4!dBja&^rQc|8I z)lU)s``_fhuQzK${udusr8efaF~R?@yDTIA8x#B;L;lkV{t$oLav}Db@t-FC4;YUB zrUZY8zY+gU3I3+yzggxFamW1U@n3{xaNbhR|INhzK`;J}jrr4!8+*O7CBYx_--Q2` z1b-fX1O78Ie+KOW{BSI9f8cZv#$Po`GsOQZUi{~I{2$hj|JDS5h`$m4tqJ}-{s#QF z$^2c2cAYKr`1|><8vkv?-*116<^T2se~7;k|LqC>rt*JBfLX5&sJk{7uFGLYcqK^WQPC{k@R*`|ZE6{?A1T{t$m7{ud?qd+iUj)0$;g=8tBV1lF<&hA zH{(k=>N=7e^{k#*H3jk{tx-D zQ|5^O=icbq?eV~WNPqp^NB!~mKjhEDbu;~keZ>EXH_{awf(h(9kb zT=@y{*D3EN{(k(8UB7*h`sdgq^}rd|-(XnrLmVXjkG`?@xQ8+m|Es9K3%6T!d|8bD zoIkAibQSUcV~;ccLChZm*AE<$_)ocveQXoV2>qe`ggGhNGj@phf8os~JpXI&0qSr` zzx}*A!Tk|C=qBY=u9r6G28+#p$zt?}$kNf--}Kv`_fmg=AEO2Ju(XG#o9O=H~)Dtg0 zH1!enCU1c7*Sim`n2gaN;qP_3pMNPSm7FV!-PM`YIAT{HayPgC(3qx=L9)#`D=->To`kEyID{6Tl}d6U0DI3e)Ow*MOhey7p) znX$`bzYmx%SnMxi5%gcc{k_GTS+1s7TAS(pZ3=jQoBMJ9)WGpcOX9y~(BER&`sXD6 zXHxpFrntX%PVisEqo4MJhT@->`3J{Wqn`uwryQ+FH=LLI8#}&QkobQ`rnV-_{})^4 ze}VX)I%gG4-e09C^B3X|w*f|fA^zeTO+R{(_?y1JN-32;d?2ZR>-d+bKg1tDqpAC= zlqLQ&hWxc+`&kzKjkcc^iT}$&{=g@I#zxE^=_idByT^}`<=mjs;T_p6JY!W|655-Ky5r%Gxo2g@^=&b zpKR%0%hB`u@JC(nB{&Z*T-y`$ygN%t3 z2ZwR}4S(O$dz06DgNctl#Q#2jOt1aaZ-44Cf7y?mqkru8-5Os5Pn3r@>ck&!CW?jo z8_54&>W{y8;NTocf$guPeua!ByzC|Z$KUDlajwVqztpn%5_q(tFP%UBK90=aZDr7x zv44L$|CPMlf2Eawf5!d;>HH7D{rP3_r<-KDc-a8;|0HZnplpWx*=Znu24()@;VOsw zi}fx22Z{gECtdy-r+NPCw?9Ma{12%54~hO<+LZq=^)ImT$!Pmo@PESre;*;*e!d95 z&L!(-^XN7nhKWC1Ux##ipP~4VQ2%A{FE!@RhtL!K>HcF1{}JN<(3?HjJ2!THs(XFax(C|MOq`;up_C$(@7# zL!=%*4whE^pAE$S^qcv2d30ERA8R#r!y{?PmiUj@;n+cj&tm`cEzBP*jRPmMUPbbw zP5j+AmuhhQfAUs{zlrM`Cnf#`v7h7lN4LM8a!db7!9S0!fbCr$nEbiZzB489uNd^7 zO7Qot4@_&BJl;l$f2TqJjiNs$z5o4=WUsXEOiTRZzYoqyHqU>B{F%NMBO|HcdgV7t$ooA_56cxC_13I1OGH)hbTcQF2z zCjOlbyt4lm;{W+K^Vn%{>$v^uZp?X=I=u~E8)*adj5Xez_u%xP0Re5A^u+o zro`uA#iwL;U+zKXl_Y5dTdEeqVAM_5TbsZesiC?SF~w zPw+VspSKZz_s#q;jBITCwO#bTb1d5b56rN`qu{?i!Qa&OYlrB+@WqZmI`XXOzeDuL zy=Y_GuM0%~J)8XaN7{ePpM0=gi?sid4=5kJfcQW9<`VXQjJ5w4Ht~z_MBzR~NStAy{xf1k1CTa)sS8{>D%_y&J}vy1RYy&N#+-%a>_iW%eg5Wcs3 zk4rLHt*TD=ru};ff9#%zUnn0L+WFO)4?H=0Kjy@$0uw;5+dhNWLGy`#f| zVc~hZ5dANZ?hdR5UTK~A-h^f1|D`wc{!uVIeEv052;Vl{&W-nr8k%S zl?d`@sCE0*YU%W(@MruRLu&p#8T;3%|8x8khlv?($GpZStWUcgs}uh(znSmyVv6gp ze*Amo{^DXw(^!gA!A~{C`_E6j86+X*k7R;2tNN%vY`;d}Pb`=}vU+jMXiXpSKN0o+ zLHoQY8;AQP{%QLUlqGxJPyA25x#Twj7=Qik*MQ7F-pu$~5Pya9j|0U2bkyI#{Rsyp z{&m^;Q{4V4_zx2Qd){2~>A3#NmRNgrL)0JopOWjZ;Ea`;{}Azi_|3e3cGislu*6?- z{gtx+u;9OB)PIEf-)gbfW%;id{}I98Z2U*5|C0&%r`Z0F68}>n-c0+yj`|U`pWB>8y{*CV! zk@%$-{daGWNHrKeYexy+lvYx(korwvd&)Z4-aEKRn+XGIjiLQsV!# z=;5mRPbT=AI(|4s{f~k?-ToG!4%;7Dz4%#UHB-bNzP~dCBh-)K@web&n%ETWz1S%8 zw<8R6$AbPgAMzfsK6o!uO$Rp;{|Ddb*#_g-+~2_Wccx|ju5S_bL;q-fO8;r%|Iiyf z7X#hc_jfim^Y=dne^T_{MEu=1dM@{{*nigFf80#{qcNxc(bp-5HxqyO{+I1dYNr3T zh5GaTcbOdSzsu^I*KHyGkA|b0@t=|S3+)V_=f8;UPw0|7Fhl%d|I6t9<5ro!R0sSO z%2wiUI{w?J|EUB?Tz?hHHsT+$nd|Lw&8iy_`j{_mjv%i#>-1B(7T zi2omjR5Sh;Q2&r`X5a$i-=Kp3`x~!Rhb%S_yZ+Pk{ZVr={?tih_g~G+_y+IqS`hgB z{*!0Edh`R&%^q2I$-_^4vuk>b`f<>rz=!+O-uAMw_>?H$OB7?*zm*BU_e2?YO3y65 ze&{nZ`-V0?_~=XbZTv6l{gevf`+07R-$D2WZ{5yStAyXLo+|!Fk3ZE2pI?6n*JqlF ze<$JhC-o2GTB%=kQNI2mjo7@q34hRg*I54d5WejG!!e;YU-ZiO)%}Zt*rDsr%O`UlyM!b$%!1%i^<7Jw9E8-|w$qLw=rO zwk&A0Ki!n?uU|2~M*Gu4`M!6IuhIV034c%)AC2~>m-1!t(P)4AC|?#IjrOOX@caGs zYsk-2osO4g(f$llzV995YqUQ@gg+>Yk4F15O!>0-XtX~glrM{qM*A~L z_%(n1>h|*#^JiIhKMQ;#MOjDr{`wW;Z%qM87-fv|eeW3mYM6K>0nnm)obbD3@sVC{ z*8=Rny`J)A@xe2mie-ZGW%0QN;45k~*g*I-fBowA^AxGemKqzUvMJy8STX*jSEuqg zN%_8aj6VnD6%{&TQ-t3oi;rZFIPKgvQoij?8S|e?OB2VNrhHj^_Q7;3;Yi7e@6V}fS+cy!u(I=eYSQUFQ$Aye`5R@b^axk?|aAihk(D*j&)<) zU6k+V&xpSqaLiTQOe>a4Dc>i>__jL#9hC2T$M}wVeBMd;y?*}GBl)wSkw3dB-_M^I zUn74mqkP{x#@EQ7%PHT_pL!&J7BuqbU6k+VPmHgTKYJ+O_m1&3^5+V|@9^`d63L(C zisH%zlU+&qe*VPxex1r(_ENs@9pfJY@`?%_e~Kl3e7?iapGqWumetUFsyWKHJy?wI z*Lm->_qdPpeeW3G0p?13++ghegm3xz!y@@(Yvj)X$`5iS$`9%SsWzV9P5A*gcm|fO zkv|71-_IYoqj6a5aH#!(t0+H!MfpKp`*?PU@&j)03{2aBhZXo!C|46czqto+CeCf} zXpdWkRgL3^*AV`C-!aD5IR17m;p5Fku?$807c~5@BYgk-dz`P~{~p2*zM|P3@n5#Q z&!qBrJ>mObzGg9gPKE4E^IpOaE>bN;{A~^YdBW#k9)VfM_!|B<5Wau^H#QRSUuEk3 z&l?FpxW20%;V)?L-$(etp^{33zYOtGEjJN9EJ}ZAu6obVKG>>onC`I1_d~SmH9(sD z_ltc0XuxU@*Vg3!ipck~(G34)k?&stXNLa)kzeu_ry2e&B0sphkh>RWq#6HTmGJ!q zY=nQSgzw(~#R&h`Bz*jV94JQkAC&OfDQ^bsZFts<|F6sV&zR#c$oMat&g6&miEb#@$V4$r&akmfj=esGfUY&FXK~xW-0p@1pai1 z-_8u;znAg&-wg3TF?lVs)5bhHUQysriF{@$^GhP%EpyYKES6`%|4exRx+pL-zDxMiI{doGXT`Yxj1Iq7 zhSvnKICWIf0quwU*uE&Jv#gWfe-mv!CZv={46~A?PoFAv2Qa?2L(RlXPj^2 z`lZSr68SFS^Y&AfKP>WDG49XXPgVYi$fxn=?WZb#RNzB?#{GHwsmfm`@~J;>KUMi- z0w4185GG+fKf4t3b6ns|hiq2zK8X*mzsmkQ1U{rAWIV*jVz~c^1@?bc_a841 z__rJ7Unuawzk<@>kH=52fWPYY_acE0{s#H80w4Un_CMyY+CJ|T_~37lf3d)y5|^*W z{^KPA|A3{5KE&T3f49Jg_#5P3Ch#Ht2Kko@ ze2D)cY;+>+k4FFVT>>BCZ;-!7;6wZk@~;s15PyUGD+PYRU%qgf&_MgYSH|c5alUH% z?8x~1_zCc@^tWG+;PzLo%*put1Z0Gd=NE#ro^8%%pNtPZa<~Gb;m`SPg8k9=3;Y~o zl#k~Z)bQ|IGW7gQfqB=6l-v#8@&6G9{+L_h6C4BE1pcwzOD*vFs&x!sJ zA65QU629OM=U-I$hXj6sd7ZW}KD#mgPtCApl|vj?OZfN$;gFxf@J_{_mCWy$gV1{L`xb^8z2@L;W@4bAyC0_`~|E>VKoaFSw-r9OwD7l_}-V`y_nQ z{viMKD~kM^1b$BR$M`Gq4@>xhKgM5?|9*jAU<{7PknOMX`Q=}c@!^PxDgMnezU}j4 z#~;*g2KoVkKMfrdEI)zftZ{rmwf}I7z`wn~n@@iI0Ldzb5dHhesn%@3+bLbpJ(T|MZBAPxoIm&hLLn#;5x)&_1i~zuYeHzbfVrvy}7a zHw69>F@GTbs`>e0fe-mZ+kfDzUcdAa8K1WQ8vLU&zU}9K(EjuI_*b3cTWyrz6!=qO z`>zrIj|zNPynIs?+y7NwzP}~#Vfj+NhX2O|exMp_KZD9PBJYj*+XDZ%Z2eN^-y!h* z)eGCtM*Huou3x_+@V%`&Z=VCc#`%|H0-yPphvW6_{`QMGPTPU^C-}I)cWv)2yuLT! zyZ+eiKYc>rGgkFN?@;Fdo`m1H{y&J%tTO*D3BPguf56|R%>R8E{~6|$ zw*&reW&WpS{FfEp9KAgZ-<$qS>``h;z z-~UYQ&*g5B-|bN%{9u#QKAyQEKl1&uAU_qr{v?Yc-;ebwJO_N`@UY_|AFkKH;%{HR zdS3C&f=5{r`F=LW_>MPr`;R9?K3*^275x5DP;ORBQH$-nf*q(%V}w!seRX(pcLr4L z=N#eRIBb@mC;Z^yfzkNH{cnV;txWPQ z;=gX~{Qv#ir_99%PPWJ5|1rLPnauw<{~#>ig){2g6E7f_e>I?9brRP)pxWwrz*frH@ymkWl552Zw9-iR37x=-rPD~@cVx{nZP{ZG1 z+4|>F_>XJ&=Q8%s%ls?xWqKm;C-rIaCr|u+vdt5+Q*ECpYF9|%4?p?r<-dY|A;I6p z70Q5rF@-;TUa3FhKRO(ZhB#cL{;zFVz_GmbS3mwG;$ODmXOE|F4qkCwR@euBC2W7} zpcbF;2Pa$q=wylb-?u)GjsE=Y5P#diPid8jf6a#2i2euo77gBOlyv^(jQuObzu#ud zQ-c5URG(t}D;fKD5dV$vgX+%;{!pdp-;uF@mH6}g_Ycqqxq|Be&wtYXq*;Hf#Q*;F zIi$>D{?`q(KQ-dd^I!D$@?XKfma%^)@#pz3`1|><;NO|Ce;4uR`7ikU`LE#Lm9c*} z@z2}P{tN!Bki+#?!M~gMKd|1yPN%W_?~(X3oC7WBFRQ2Hk=H%MANsOb>bU+g|Akkj z_GmFT_WQ#5#oXD&xmW7;k4AqvpoWZ1l@s{K&ptnA_1Zt0{N+e&OtlwzfuB3RZ_@dO zsUs)_fq(q?ap3P)(-o#F3j93!|In0wN#HM`{|`<1mnq*mIp^Yzo}mI4Psj7qD(*AM z?;!l*;?iOcmT&%b|1_B9=crP?Rh)B=sa(k}7pW0`8Tn_-@jD5>>at0>iCS$J;g9-f zPt|C$sh*7=-?$yeal;WU8wNX{c^0=XYk8NwbvJ)&1rBZS0uNn#+RSkd187c zzwd|ETloW>`Z;7V(H{;FhfbCagTDVc1%HcW>z|YOH;cdj!BWRRNBsZHkN?xKeKZmO zyu`m*{M+@_2XZb_&1AxyZ+^j{VNiGa10MzSvI^1^PgGmw*M94|D{;| z3p*?@v-V1d#2>m>QvY-L_We6D_OD9(Ap%nWHSqVNlRE#a#Q#rY`L7@Un#8|Z{M+@f zW$fQ6@sD&Lm}P@;kpD|?M5)dGPbcv|5zBx5erT7(zwUywUo0C2g7#m*zbj+^Zi#=h z`1>C#b^dn~|F6dKUqAjm68~oLZ`Z#kWBTiF0CH|4^Z_NLkf`4zu{(TbvNcYW4m!SO#e%yoC;@QF0=a>74|07TF z<9kj4`u`&a&hPX~{Oe(w_}Q-E-=DGnfW$u@|8Zt(_zyJkX9nUwDDjWSzu|vQA%6xl z_8*e?`&koz;>RE2RcT%g5&wstviK2{Wqy4{8bb4Nh9&;e!+YQl{m-_`aK`>4)ZdXS zTDMB&p-bAlj1Yeu8;<{Y6HPatHqE=E>HO;n{;*V~e&RuxSsN8&ivIpAf=o!9;~4RO%J;|PS0?<&rT)<8A;pV-qdsl? z$BF-=vG|h{d1RhxUanX4_t`Duzn=In$KtQ=KOyzEg^%vVzfqqy{u9Li^Rf8rA57n% z=$|(J8;Jj(#Nw~-Z_E4}VGfrAkAI{-ZTxNG|8Ok+DtC+umH5D-$ep|Jxahgt_ry-^$A_=9+DcARn3{{trH7<-+an4*4|g)NV}YUx(&e=8xajXj(RA z>_08_cLXQcT!Me2K5hO_6aUAa+IigM_IHz_zyASS=Km(*|Hr<+sqOD(sefZT8!QMf z{*C&y@!w4RzZi?Z{`PB&qJP@>Zz29q#^SH$eoj@#&!awj

    (B3=*pq)ObW@H`C*@xiGK~y$QNG*d zT($gaBs6-n=_dRxxBO!7E2C!$mDsg=%K6zt_&sjNTz>NS$M@V-+7Vpr0G~iP{&m8y zwdydn8LnQ!599OrypjCuOXeS#-4|}al;hvujQ`b{$)J5u-F^)aeq{ZpV-9<3CLKjqT%gyZ43X$Cddb&G=LHWYB+5UB08u`8PaX=PR7D|2oQV zwEs_c8pxlqWd3zCHi&cEUG={f8gD#w3<@Wb})(5R92Z9@|O z@p&W5*G}dim^H9`C!6uVI-|XOrwBjNe|~!0K>M&UnSb5x8@sjJhv{bgDSPX^n(f1; z=KLETKfV8yPXC#)ug3Q8tgkcn{-BTWw#DE-l(k4#C3rLK^W(AaM=bs#Uz%CD+bO^f zyNU0=TN3}!%z(eevh~kN{O<}rfC2wp#{PMU|INgI?Yw&WX{`d(@ z`FBYC!%(9?pPTyjt3&iRy8WtB|DQAF<-eal++RI^s>J`amp{%KL-}7z^oOMo#(z~g z|7+CWUw=*ccS`)%fvwHl(En{qJ^r1<|BJuK=f_v>W`AWU{#}XwaP--azm9)b#{S)j z{&vLw&z1A1J7fQzM1LpZ|B|wQPsaZB1b_Y=T?6@3C;qVgjpV<7^bMK{)zX{jZzlhH zGxqOG^tU7Vqn`hL8T}@&BTa@%F#;_kYJ^{=unJ^oL zH@%&ITjS6bHytPbr(WBzjBlL6?`J*8N6~s%FZzF!1+C@VMQ#7}qW>9_{u9(cXEy#5 zqQ7m@e}m|6H2xbze|}B8sr<2te~>y_Ng0{gCjM^ZJr*2ijn=g}Y_Suu<8SbzVn$1j z^4+UnI2*KY2IiC}{F>qGX9|Qr=+=xb;v(Vqx+gap2up}45q|BPo1DV3W$ZJQ34heE ze}(Y<<$ES~wBxzTkelaaQ;#K{Aq#spZZ0< zYV!PbQRW|j%j83$7*&{SCA~9U1#qCGii>Uts)U6RC6l zw@Uo)`$fJ7&tLC0bpE22=x_71_x#n*U(_=8?@aV}BL3>BgJHj_-KSyVADnXZ{DU3scBzf=N2q_}Eh9rC#NUll z_4OfB?ui}0nv3!c4Ce^H*DV{cZiwXxzsubyOL(U-MSDX9!Z&^VzexD~GW+(FV`G;n zU;mPa7{5&TaD3PauOEnwsrI5m_;ZGj4|j-sqsND2u%wB9j`%+ujsM4@o%Img z)<8amep3?u8IZyW%c5i(V7zRKk?IYWApwO`kjfg#Qy-3tykzTtB=}> z!)4-s@~7qC=mujuymnZeDt%2w<{wXU9|r!h`}3!pM}_!*Ddyk)@}zU^koec7x2;q2 z?;!s7{Ion6Iz;aP6jru3P^JDqv{*qFe^<@FO8h_f({f*EXu!WF@vlhzdzJF1Ci?fA z^zWqpw_5CVssE&sf2ZhgH2z)G|0qO<`eQSJza${54}&Qm=pz32zqVl)jA`?+$Mx6W zZkfMF=d%dAqUcZSQ#60w#Q(w9HXH!3!{OuYx5s?C$U~3J-}Og``k{Zc9^Z?;?@vOX zdWio+uWh&q##!LwjRRA&)Mfs-{i1H@AJhl#bR3CGo%lcU+J@UI|${?PY5c1SFL1b9b-zNTl6hWG3eA%F0FWBJoZ_=B#2AEl0bf_}pHuRk&7KS253yp8b(3E%Yn2ZjjW z51q069437Ku+`(! zE#;H=Xz+Wad=eiGex36D^($Py7#~M{{pywSNqjW;eNsM&j|RV=@H_nVs}fnimNBIi z%Yc+W!a_c*U(1SYoNQ3ahf^?-^-G68MEN$(wchZD{8{F8Sl@mbmhwq_?Do0A6eChT ziH`<c z9sY!r&l-FfM84|wYeQ2$fT7s@QSHH|d=7(!5X1-a)7F^5q?AwMufd;^@*x)7AD*G; z_-~|q&L#12)R)1uluzQL!QUk1Lr|je(co_;{82#TY1p^VV}YL%`tDx#ih6k17Q*Kj z=M(-@I8VhgL-_pSZNk4z!+$H`Tj)vnlZx&***3!G@yGo~&eY$(-cI=5#qH34j_?;W z;mWp6f0kCzZWtiN!55k%+Q z`3?N|m1h58m&hM7$-h+OgFi$+@W<`DQe?b|-XZeA-yHv)BHz2di~D;HI{v#wKKMg1 z#J^1BL;GL%w~w%a)Qtb-QvOJTubH2W{UCOHm~X#W5OLVPd^g3H?07)s50=26a?2e5 zlg08ZO!FhWp3gdAc{7$nn$+e5{#ifaLq5z+ou3!^uD3#k{AnG2LFBU{7&8{~XLR^Q zkx%0fOF=z8C4v7c_1~q#FN=KYzek5(5%`dw{2M|L|0`iJV1CviKDbB}N{7IQ{EYK$ z9e!2hyM#Zj!>@^aR*d`4=kJ_>iBxa|rqQ zSx88~{VXb;zpD#;$j><6#`Q~;-z)N6!sqR$D!)(Uvtrzzx1Xx~evwb(&)ZK`{(!)T z{EYka_EVKVDDtU4Z$DM}LjoW2^AI+a@%-#k%+Fzg5BVAA^ZZohkBEGi@Ogf!@<&BJ zE5`k2aQ#x{uM_z+{yaZb`C|ef@-yzw^HY^SF7l~A&renUdVxRXe~SR}6VvoZcs~Nm zRo%W%h8w5V&KXMyzr`Z{s_pX*fe-!$ z`4Ug4Ax(b{^vUcKE&T3|D6IK;%|_@Ti`?d4e~D&_yvFY!WSii z_-nNPm&^FvKh9TepWh|p^W!JLzY_BZ$|JD-^@iGh+#}=j`$t9iF8fr0U~@jLZDi%7Wr^I0LvU-h0&h>Q(b ztQ6zF9D7&)MUL=a)JMh$dBS&N@9Mv>STz=(gZjuAAxHT8V(;p|u-Kb>EKbttF+8ago!A#>{B7D>FFUR@D<6nvMjmJM9 zU%t$A{uc<}bo`5PzVY~%;(WCvZ!(n?U%tlUpCf$J@z2Nk#^Yaz^P5Cc?X4mlkB_$h zraS1RjQQ-tcSMiRj4sUYo{pZnP>V`9Rh}KYBYOWOfB)SHPyVhzO<`(&pW=auBH>T+ zInRfi<9U3Yn?7(vacf_a@)tt>F-?Aj@bfMLv3%CWM;8OOsve&X%I8pg;3wZ*&Sz8e z2NmOAmGSvH;PDsv0-u_{Mv>no<%j-We868df9iza_;DZa;sifFGjodm{e*uXs`K(T zfAsk`sq%*if6_aE2nXmtTj2*3@ld@zb>Id?|6$6A|Kp9oVNL3?p71X<%%33qoe6x^_-`QmjfVNtgg?obFFtt7m$z>k@!v%Fmm218 zCj6ZVeAW1GA^eSo`P&G8(uUC6IFrxXuy)NJgCS;5ANYh~{%@yz2Y3$WJHS7t%fFEF z(U+eO=k4d(f8$$9_3iIPQvL`~z3t0+(&;{3{9H^AGdi z4f0=g{n|_T-tslacL?8GzUKIIgiqoV=BH|W_7lFheCtB~tMcDX_?P1P3k^SGpTU8( z^Z2OIejb$a@$M>S_=gC8C;CeKRr~)}OZlR|D*sx-_wvWw^1Y7mz4gl+|2>57tzYK& z?V)V1@-OwJmGu!e+HnD{M6vzK=@vMihR}lxsmWUV*0~PRs8;s*ZzRN zD*qSz=GvRyjSq|gF^V3m}&j$$K zi;o?~=WZBc8vI)b-;0mPSB=lF626z8BXGHwcl_l1UhuaM9N1Tm-Es>*RjP6;;cw?t zg?v|+|7(PQfnoj!3I8I)`~|}I;}3I*?;oiy-`fb^kH0bg5yJQ5Z;byT!uR8EjQ<;i z@5LYcSKj__(0^8q|Az_Ri@!PkM+o1Gzd8O;E_Ux4eB=Q13r{O3F9afBQYc_x3N$@$VvhFMrIfzrQc%8(Y4AK={xxgyQl? zd^p7`)Ysq75Pok+j%;66rw*x}Kl($$uf_TPtIf*i*DQ9;9ntHb`SFHu9{K}0!q+EK z!ax2lJ6N60Lp5%-pm>Ye8`gfbSOPyh&!absoSg6IQ5#d|llaE`4}CHofB)-!4F#=Spe_gAN}UBLXu^`HX1E5EF~fE8Ha%}FQ6aJ=Qh{k$s8Lq*^pvsfX=EC;4` z_pZFK5$;EfU$eR8@ZpVD=U%M2m$b$25co%dZ#DS+gun8>w)jT=^HkWTd;pcsR=#M`L-|%mnKP2$K2mTK04&sw9taAQeWBf0Evi4$o@gElW zFSp>gm;WOI|9g<168~@U{P}Xb{-Xl_o*`}eiI{>~=x(Lc&xRpVchz~^|%zps7&T}gZrp9025f&Wf{ z&kFF5)gAZ*?%lk9XyLcOUI+d)XJPwzNn7p1?gTz;)noh$@~?*Yw8?*$$S(^1m_J9+ zANlRI|9cYnF@NB9BA@%W$KNaP;n-3EF5nLO4<7<|^uHYW?f2gt8UKX81AzU*YkmH# z&xbvPcKZKwNqh&mGQQJZd=3bFH^&Nfh>y?DLpy=_Iph1U{7-H9zdMN!NN@WHe7s$Q z9q`+W&mn<-hOra=&Nas80bt|ub=2a2brRnJri|Za{I3=G&_6#A@xM3b5A8#H@p+HH zujg_7^_K6Y-u@}>KYkD6lY6k;_F-P&+pv9sKL?m@8TdJP4Z}wd&rfmw7YfS-Tqxl^Mxmm56|dd=kZ~+mEUDgx3T~JE0m91zj=WDb}#-=#p=a* zh(GXQ`A(-lK5#STucY9&;r{{3cg^x|rF`u8L;7Ry1Uvo^4(~hCuv>88YQ}1Ad-?xs z0^c>t|DeEMj@+b#`}0qN>jU?9+VlT)fzOH2f1AK}bKy-~+`ZhN&%pNi@PXRdJ{}SH0P>qpSbrP*g(yFL`*VlD2it%T zgBX8apnc%Ww@rV>zO_F3{V$)!_}#UH2fSFMy^_nApC|moereA#dF)cg{Bp*8_#v_1 zk1pT*GIp+ZFgy6j=hxuJG8-?0>h#aQ{Qc2I;P|4zgH zIqJ_lx7$K}=J_{Xw>gx{*gsGF%gZ&$pIt%16nuZXP3>^>Jn=W3KZOK;UqIWxK>SVT zPf_sig!tcSEdE8}Z#w>^1b_vbo@IL{7uEbllYsC zf0y8Iw*BeK*uPuwH{1SnXY4;n{aF{ZpDzZD!peE-z~2dlb^S+(e*umKkE?}3I@KukU&ioVv~2%9`~aH!kC2O> zj_$t~;H#D6PDs}tu&BS`{a=gt{~fHnPwv;&4gm$?UuNF^uRlW2e+$QNcc4K0PeS}n z`WFR%um5JsznHOqN${8Uf7%UuIDU!vo6aBjT3u}YEi-BVC-iA|pq#OPh4|+U=YNIx zn{IzP1b?&n-;uF@Rq!{P|5fS_?Wf81zb5#b&Hq}){sYwC@4toXspj@~fcO_j&9?u8 zQh%ZU6Mmd_2L`GCdb9q+)Zg&_*D&#)#QiUW{f80iZ+QP}g!o&A{YM3Vv-@A8#Q##b zfyI;i^?$dck;hJK`>363lQ)X2xG-!GXGNn-}C=U@Us19 zi)HJdBmVn&`-z7jcyajt*SX+j`_DPz&%b|X@c2oA_~#A#7bN~BkDru?|5CjD@$%>G z@Ni1o3!o(NX9nY6CjR-jKinW`4bESy`tdh`-l< zn)C0F_?wJBT-Y4DKH=Z}&0OU`+gYAGfhF+Ob5S;zT*myoz&9J8g1|Q$pQ6Aw>t7Q1 zX8p?<^D7ziI|RPj_*VtK+4$E4zFGfHfp6BoD`S3l#{5CTpRAjW&oJQ+eS;aidp={M zgl~HLvQFTejn7!d{BePAcKuo}@Xf|&B4a*d|M2_ln(A~BHvYI*_t>k25W?N zP2?N(?-cpXblQHeD`S3l#{5B%Z?5ryXbwyG2AenNpJcmzSts(_&XHyljAhIp7x_ll zuk|9o*~e}By@`zZBWx{p{N&2l&GxTG*w2OjPuoFgIzc6Ne7@?o|4-mfT{2$DiKTP=Vdd=+e9U*+v@fjuj zonJER4_}7ByL0C4AHIuVu_1AbivLKS=nd<1N z{ee4MWx9R0Bz%+G_kx6KS>?XUs2T%r9olFJ;UxXUwl; z%~@S7cm=CR1WcWIPw+lIhC<~ZRyj#>T*!e3Z0 z%RfcPP{>qA3{tDr*uA1drgl{@ObA)d?KMRC!IzKCfZ#qBggl{@O zZNfL5pAO-h&QHdE{=3opOPI}mypfHR@0glTPR?hxp&8T@_@+L<-GtxhI~NLOKEluE zqQB2&hS{LN@{RKyxSzMF;PBa8^T}-e3BP34AAVmi?q31E+lZg;P=WIC$G#k0YGe8$ z<(Kvu<(CBhaijdQz|X-~b{n5hcc>!r;VZSe)W-B3l#ltd(s*BY$YRGn5?j9=x*s?+SJ*g6GEDnnM;|lI;63)W zM+m=1%EwXD^6jSlJ}E!+CmVy%KT;p}uM_`%DL?d&aIj9skNZ>pkd%)cUSMMxEwlUu z%rsIzb9m;4I#fCM-q$F9SjrE7;UU7|X#UF&alU={nR(#n92`O5kI4BrE*8SKC4ApM z=ivAPe^ko1aa=4Z_|5&-OZgaoxUv!+9r$aMaQQas3o`|m=f8`iJ=f~;;K3`#;rR(p8M84O|IUySdknjCGkHd%XVTO7ByyjV#M(T-1aw<`2>#KGEe~u$#tbHjyvO9|@lYe0h9! zCh}$ZgM6Al&EvC6#xFQPv5w-sp6qCnmazW(c|67v))y|v_PN4xD^Sb6HoyNx*IRP< zlCevh@QXYPBgyXb;hs1!rC(3@b;92*<>Q>KqnqH-hJRu4`CFp(h27wP>=4WGPSe-s zuZsI$)`VZ=U^~RK&>yS(dctRfzemQ;IWWC-bPyhGzs-a}7Vw9o^*lba^`!V;(S%>* zj$WG_<(H%Ngiqt|Ncl*!j=r0FI{3mXetfQiS2kb9Fu>yjJ;a3g&o$wD@pn8nKE~qj z*AqUC{{b1_%l{R)w-i9b{9HL-#@9V7?d0dXrF_6J3;0-U{s<2dK33WI;K!$tpVa@L zjGuF0Lgd@<94_AoKT_Xf`CcXE12*(`@CB9#A7487AS_?%f31w~#h=CE9OF9xPS-wM zC*`A<1$-PJ#RJk?{FFL_8*@4{JuuphZ|-59FA)l;UAXqxqt67^87jf!uj*q0;S8J z_e=ROIYT}cn?J&XAOG_&#Ohn*&#%b%IR|jax8a%Q5BhIu)VElFZLMP89(R6 z2m5ca;>XAP!BzhqZ~Yxe^8YO<-;2+?0bxgH;PVee>v?<@Zc5^ROv*>7#YFxwsPADS z-+}&{JU+i8<2&4criil%)*~GJzxo~I7jQVJ=kdW`n0B#Ji2t#ce4NZL3H+J&vCEVA zzboV8PfS95PQv4Cz{Y1kKTkyKTjb}RQa-}k;V0+kr)2z`=U;>dbOvV?6hD9P3bwGm zMgIJrl#f7*iTqJ?zL%f=3|jC%EAVZ9`(iD}_pk5r+vlFOcJ{CDmhp2A$XUzr{l^Bso&85w z#^>7?%T4fKiTlU5kMsLqbo~H>BV&s)e$Ih+EH}Y_CGH>JK2rXYjL)~ZmW%mg!=G2~ zf+t*?asMt-UzmaI3pPnE)Us#k_UnX{kE5pLajPZBi*{|pRjpJ{OtX~hy_&J;&<8Q+=E=w#?z74Padd_e3KPmt7GJfcf z+@M7HK^;7|i2tK9e$Igj(LY+6@ss2K1sR`X1wPcSz#qmxQat~}{C}(o-wH7pYixh8 zMEN7|`trl>&Cun|t>EbYik^S@QYt=jWqbyi9Pk|+N#H-8jt`tfK0Cqv<@`UA@xAre zO=y3hea3j%@CU`~UnR!>Nf{q(A%B1$X=fVk5AY-PUjHYt{rO`VKlI1>1O@YR1zvdD zmoQ!h+a$@%{$GQPikPiTK2J`T(;Xn*3{ciKKI%lJ8*9^-Gr zGcHRk;ra`F8(#bMJU+?o&!5Wpp+9ni66FVV@Z2K)Ps{i@2PX8k?=aw(X8h#%|Cx-> zi2@&LSKu$mA3jpxpP2v8G~ru5!i#md{zCkNg6+@6P1~QZrQ#z`#>e(2;5#^y(EdD| zjt`tfe$)2nUkUsbVAUb{==CjldE_>2SZiPt~;rNEyD zj*O4{U+we%O5oQ)qrnf`8HTyo;5X`<`~RCJd@nLVd>VZ3^lwlf;XeZBH=P&V#(Klp zHw6C6k@(vXXZ$=^qVeC-sORyYh2uXCj3dVX-wFIfk@!dX(fFt5KPT|z;q_!+RE|18vF{tq)7{&{8g z@c%fE$4?I7OX2#T=bP|tn4rOF#AiBIkH;q)eCmI;1s~_&m1KU@pYmUj^6@70mV@Nh z{&;>IkFPo~wwV7fw&1t+-wp9k=6_SlXWZWfp;@%zg)d(i>R~6~u~9#J*qvX2g)3ja zFSp^Z$;Nk5pX0;D5M%LH}d$ zhwIm`!1E0JVY&S9*XHr~zdZimZOX^_*a(5r$bVda8}++^-^iajX`lbIz^@<-+GzC0 zVR+&N`DdUW{d-`pj#tgFeQ==vFZcg`Gd^S~pIgXZ0TSOyb~lP@?>3{$PIM`4RQ9<3RKqdD!3|fOi}9xP58l zCvE@#j~0BHKjlaBpYnes<$Li@=a1W$Mtms$|7^i;?T_1+Wd17xAGa;s9~T0|8J97Z zyWp_)tb^@C0bVug@%V5Z&QHNxlI`QGE%`VZmSq0S`|5Ch%E6I@{^yTd@L7U?qdx9W z+s}V!$ww_LasMbk>QDJU75TvO*V!BgM;>PRa3NN|?J)3jEax!x2z!?1&p%4}9K*K) zwm;}SHTaEsyTOP3FUtR!l*TiNygcWPJPZwje$d z{{JK8+Xzd^pT22Z6aW7z<<|i|$AoX_meBuvK30$CU(g@62~dRdzyFlThwGnlMU58D zhxIpF4}6|K9$z@W^WUU=gnE2Cfgjcv{QODapOf-&>a=`6e-ilrEahYTA*9hbKn;_{ zhXwHgA;_O&q<{6_rF?{Wd>aRY65-oH9Sh7LI<|C{TAC7MDA*K$#65_K# z%I6bG9%OvK|B%49rF>h$#wr;<$bSb%5d61D`8aCMfd^8M@8y5vjXFC%kFOkj5cnPJ z<@Id7I*q;jI*#F&=siFi!+V3bQ$JS;|M20%H^JXw#+FhunvGZ^{K5@LN4}ZTN%$V! z9KTEC`|*L**g)wP`9|Z@L-?SKe5;W&|J)cnzoG3{I0>{>=1QLMoj)_jMpA+B;iUDD$vG4Wf5mY8OBwUal#dtx87vn2 zSS@&nKey7yUi}-2LrRlE<$S|2$m# zQ*pg0Io@Pz+@BwwT5Wp=rb_%@0j7INvQNA3bQ1rK>`tTc?$MP^&j zD&b#n?D<;k`-klYoQ&T|_@@2K?6HaH?^oi^w8>qJs)Ud8ARkltWv7I1(!a(YorvDQ zy>Z@ESvfZ0dct3by{rFXobbubkF;lCQGR$nTpP^+xs3T62tQ}opRosHzb|0A|6mdR zF*9KgDY=aKdBQgxp90~Vj!#F%{3_v_j!%v7)p}83x(EZEgm2ovi|`*24D>3x3E#AT ziTz`&f18K?)hAuXmK)l?Jio~Mw~eojG~R1DRAN7g^?#m+?vKg-Z8^a|vK+Mh%NhGu zh`;Imiwg1ozTx;+i9hBK>|Zb&G6Vmh`1?n*FsQPB5zn7LyOgmf_nSLPP^12ZJ9C)- z@IN>d{mcKC=RbUHDtg~Q_%vxsjl|!yf0y8Yd*MzO%qr9$PV6iAcV+C~P5mK%eE%T4 z!TPJzt?nlNrrV#o#D5pY9}gIKMa#dQv40=&H@$z|NBm8KYfI6I{*6#f8R*1_x^X0Q39C)&>Vb^;gBkO4>};(6Sxf!N(~X$Vm|x78-=8sm zAY=Yu#{3-nk7WCsE-%uKmCu-8%$VPwF@GRq{$R%ZD*KyQ`?LGy=Z)_F)-vXIWz6pv z_>0}2T3MPnx2kkHL|E+xGUg9v%&)TVlJ*C;?83)XuBc_q@5-3pFXaclAN@!TWXvDT znBUL-KGy!2?*9yA%pc5{-_L$P)-UB%Njl*`#{9vI`6c$R$@NjT^mD3Kj#0j4mOnxH z{MQduZN=%vDL-e{e?8$Z81~;l__^S$j`&d(YyM&`dVSrB(cTY!i#}U^j`06$aMndJ z8g#OJ#{2@|f86l*M~a01X~X<3!e2I=KlP0H-5K*cGv@bZ%?em~() z8eYHpGUg8vzUlU1IAi`g!vDVE_GgUne_)tDPWYy`zaxZidi@$DeAD@}p70-`8)(hf z6NLYUCQqDv+lDN^KgHPQ4bksUS^jlbZr)5s(PDA`;QAsPJ}CY{@xDLB?|st#^+gu( zKm70iJu+9$=TA-HfNseVf791@<%qxO_~(g#zHxn&k?S+_#NTxM3xa=meH8ImyFRLr zv44^J``7nIuCLR||040f`jr3#^K|AiicYi-?PwEd+*U zIUo|6>4I2jmIIQKnJs2T<;}ILMBOs-TGzVW+%-T@uK`I{)2?g2-u`CzQd%PWf1c;e zIdjhUJZJXI%i{Kc@WY{A%X<$BQ?;=VwM~ParrP{A`Za7h=ot?(+ltDjo2? z=ihXq+wbw+U)eVzg4d5S`!QxeA~s&>{`&}G*VXCYz9s+MH_;`EzC3M!XlkM>jEGx2 zpN~D6=GW4lpFRq{a|h8C`T2oYig~qd>a;QSp7Ml8Ki5u~kNo^VkAMFok4>QTBjPsC z_{mL<-BQNKECr?+MSp#?w(!wHflmv4M-2Ui;_OK1XAl3th*;>!zjnvbEtL63nf-`Z zJ>>pk_~ z^2pH>X5SWEPpS7rgZ#EqCG+DWVu>do%5_V>D{;LJuw$ZA88LKbE9iI6o z&2McMmUV>LPl4Z1cxjSrP2f}KlLnvkk1NRpCV@{~e+RQagW1n8`<={wH?zNh+0Qcj zOPT#1W`7m4pJVpdG5fvD{w8L>4}8kMJ*YN-cQgCdV%r4w{^_DV{mHHws(D-j{3l7a z>II|coa>+O^Rmqho_=Tf;G`v&{ZdX1@b`>i#){*-tb3lbHP+_|*Mp9kbud>~CWB z<==hv?El`<*(Q1`+2MufCVam0fOd-afvdnz&KNIf&p~;cdH9CyUt__iu3x@+>Y2Y$FWilb%{aWy;^RHv}>%phae+0AN06um8jm&-u zeDymjl$R!EzZv{7l*LPHB(vWFK6U=1nElb44(I{(9%{juOv=Rc0w9}hlt z{)aRB6Tqj=eG4=!Kcpu7-s)i@Tv1Zj@j=3KTX^}XE6IS!JkH4|MATJEbxhbE!Rom1n{Zz zIT3v7`cDF%y8e^Fryl>OF#D&1Po2*PnElhhpW=*Mnkyd!pL+S84nB4Lv%#lcz8Ub_ zX<~PjPG)}&_{TY~OmpQ7W`8dD)cK#u?9T(AI{&kn{VwpS^PkV`pA9~B{^v0J=Ymh2 z|A(0U^T4Oh|HI6FH~1YiZPQT}F#8L^KgoGznkye+_7{Oqo&REH|9tSN^ZzKbzXW{h z{4ZekF9e@D|Bo^I7lBWm|HqmAPk>LI|HaIH7W|WG+NPr{W%ieWKihd_nk$zu`^&+n z&i_(oe+Br|`G1nxUkN^S{+BWPmxE88|EHM!E5N7D|I^I=mEcq7e-*Re1Ad04Z92*- zW`8yKXF0D-bLDDge+~E9DV{{v?Khu~A^|8LCxkHDwS|HsV! zec)5){}X0^8~9nL^U+-SDYJh+_@AUH+fn|V*?$21tn`9H?&KMp>1{{PMFKLI{<{=a4R_kiC+(>5Jt zFSEZ7{LebCOmpRT%>I+$Q|G^*+5bKG)cOApv;P$M)cHTn?Ee9L>inN!_MZixI{!a1 z`~M3*b^gyW`-9-GrD>av@;tNuC-84@UYX{~3(WqD;9pNuwxhfRK6O4XgHK)mE8tVt z|0?*@8@nEkiG&(W0aD1T%2{|-KN{_imR?}AUA|38@he}Ye)|9i~-LGY>bf1lYu z1U_~CL(IO2ct8JtqtiKPu0)vqDEMEcDcezE%zhkv>inyi{RH^b`ByXhN${!juVMCU z!Kco@j@hpVpE~~$%zgv-)cH3u`zi2yoz6#drHR>Z2LGEhWjo49X1@h|>ikDB`=i09 z&VLNE-wHl;{)aL9W5K7+e;l(v9(?Nj4`=o#fKQ$OL}ot?{${81(Oj9t>`w;&E}F6( zH!nsq;UE**_M1>imym_B+7u zb2=Z*l^M+bOz^)?Q?{cV&+N|vzt4GPnky$T`zL}=o&QP9{>k7|=YI;be=7LY`G0`f zKMj29{6EO-pAJ5C{%D z?4J!jb^hlt`{#mBo&SfJ{qw-5&i}*AemD5k`7dDh7lKcn|3{epMc`BCznIxSAAIWk zKg#Sc0iQbm3z+>2!KcpuW6b_V;8W-Sac2J$;8W*+F|(fqpF01g%>FX)sq?>t*ipL+`|H7{&i_Vce*^f``G1kwzX^Qm{BLIVH-b-{|CgBkTfnEz|I5t&t>9DV z{}pEcHt?zQ|0=WJ3qE!Jo0$FE!KcpuYs~%~;8W-Sb!Pt?;8W-SO=f>H_|*A-i`oA+ z_|*A-huOaqeCquFh1vfu_|*B|#q9TiPo4kW%>MVlr_TRhnf-gfr_TRgW`7I#)cJp( z+20C2b^bqK_J0UIb^iax?EeUS>imDq?B54Ib^bqL_P2pgo&Qgn{rkbE&i~(;{RhCO z&i`l3{?Eau&i_A{{RhFP&i@z8{x89&&i_A|{a=Ako&SF^`@aUCI{$~5{eJMN^B-XL z9|oT~|KBkC+rg*Ke+RR_6MX9YA7S=)flrF*`sq_CGv;QRc)cNmc_J0pPb^iau>^}uQb^cE?`+oqRI{#;w{b#|a z&i{|h{{Mnco&R&p{vi0&`9II>{|S8R{9j=9Uj&~z|CgBkm%*pb{}pEcRq(0v|37B` z&)`$%|Nof%*TARF|1Zq`>)=!8|5s-J0Ql7TzrpOk2|jiHZ!!CCgHN6R-!Dv7kb-F zc`X-JGF(ciKMsEONXP#Mg&zaIQ0d_AoLVTZOF8*O{eFJo4ek~h7cQ@s7O>8=3tSv){z*H#7UA!OzbKNw$p&83Vp(A)__aihfGZQpjFp9QuNG z1~C@>T$-$Q1&v2vw35!RBI4k+;=J0nYWZ5U$y+f*!KWUdG4M^h6ILbVeT{>!_AV$d zRp5u;a|>5R0({t|3x^bWR5kdCB9ATSt|a(soKjwDz^CmFLezp!y7I~(>cE$W0!T0Q z;MbArLW}?(cBw0VwFdAzVx#;9nCs63V-yf!R-iPn~}g_)CcoP&R{4-Ty~|zm&LtwlMqS z!KYrnhl5W&{>L%ijn``+dy*-OTDsp{|#neM40FQ%zld5Z({b-%>E>1zk}JI!R%+4{Z3}To7rE$ z>}Q$%rObX0v%iYj&oTS!nEhU6e-pD`Ehb#&{{1_-m-UI;^{!T**m|ox*xFs#@7gxK za9#aooBk~~_qPn!qec97^~-S;`VleyI`{d##D}*<6nyIQKV#ripPwnuH}o7|&2<_U zQU%|V=No!_L45wXJm1jcr!ur};K}`Uk1rQE=_Lg|_4t(M1A6Nx9zY{~KJ5!MfuHM? zi4k68-rjr&ZAHm`!0OAiS$!cUdwlBSR}p4E#q2jR`)Ou>60_gI?9X8KGt7P`v)|3^ zFJShw%>GhlzlYgh#q8&p{dLTKFSEai+3#ca?`HP5G5bGd_WPOr0cL*>v%i~}Kz-OT<1W=P}=d5?8FpO2>>5$^q$L@_^IxgQZ}&+$VMr#*ff zMW6TsK4R#{X+NPPj=nl#OnN!nlRxdzc_AW#*N=ivef&Ab?8m{U&cBM;Pk>LIe>Jn8 z1fM$p8fL#1eCqt`nEiV2sq-Jf>^FcnlVPv)>Fp_3vMdWcFLYr_O&A zvp*Vq>iowr`>o(p=YJTpKNfuI{Kql-|U*`EwP z_3wWj!R)tzPo4i1W`8R9)cH?i_S?ay&i_be|0wXO^FNx|pAJ5C{>L!;$AV9t|8dNI z2l!Ko`~M8^)5QKv@TU>`$20r0z;7e2{{--<^EnZG>iSOtpSu2&!KWUdr!f1cf=`{# z2blfSz@I`q{yzvl_3}L(eCqmVgHOGDGvK!q=ikZf&jJ59;`+~E_UD36o&TB4{ygxh z^FNE(?*gAX|M|@R+2B*>e-5*MF8I{>e~8&X4}9wUKg{fRgWo~iKNm3j3&B5$xc-kY z`-{M*&VMnpe?Ius`G1tzUjjaL{ueO&7lKcn|Hqj9i@>MO|KrU5C%~u9|6*o83;xN( z{c|a^zYP4@#Pwgo>@NqOI{!5BM44{<(_TUk(0Q#Pwgz?5_czI{#~!{m+0;o&RT<{k7mz=YK7;e;xSL z`G1btzaD(*{6Ej^e*t{z{BL0PbKrLo_s@0A{(A5~OkDqs%>D-Osq_CLvwsu#)cN1c z>~930I{z;*`?r8ko&T4a{aeAO&i^aS{%zn>=l@k^zZd*&;{Lgb*}on9j}q7aHD><~ z@Tv3vI8!t8$+eCqt~V)pyMUqakJ z?`HPD2mZyx_5Ulge-HT7`QOXzZvme=|L-&VTfwK!{|C(e55cF-|KFJXAAwJu|Bspd z`@pBp|0m4;Ht@5={qv{H{{7&8lDPhVXZ9ZepF01aG5bFUpF02lVD=vbpF00vF#Ep* zpF02lWcGgrK6U>8#q9qYeCqrkV)pyNUrF3Q2bleb!M}>Q{@*bB+rg*Ke+RR_6MX9Y zA7S=)flrizu;5n{~WVF2>us{ z`{(oEuO;^X1pW=g{tL|hi{M{RT>nepQ|I$C_|)~k0zP&9uYylKKL3x||1D@Qsh4j9_|*9~GW#j;dx`sJ z6SLn8{x^y1AIa>uF#Dsxr(V9J!KcoD471+~K6O5aG5ce|r_O&Ivp=5MKOB7Oij1%`)Tku6Zg+a%>HEX?;@`M2xh;H*`ESF_41txK6U=nnEiI}sq;CK**^+=>imyp z_NO!Z$AC}0e2)d6I{)LC{SNT^i2LUZW`8F5-zTpBcxHbVvws5k)XVoo@Tv1ZiP=9H zeCm8oVfIf2pE~~!F#D%5`yT|KdikCXK6U=Hnf(m-)cJHW`*Xmj&i@Q%e=f6sCiv9L zcOLlE`Jct?cY#lx&wOV8Z1Ab`KZn^rm)ZXi_|(hyJn*UW|1h)P4L)@~3z+?d;8W-S z5oUi8v%eU8>g9Vr_|*A-l-XYbK6O49F#8vRPo4kAnEi{G{f~oBy?j3bK6U;VGy7Ta zsq@NeKI{!BpJn#ff=`{#waor?;8W-S zIcEQQX8-fxQ!n2yfKQ$O4a|NHeCmAGG5hPmr_TRIW`6^-|3&brm+wvBQ|Es(v%e91 z>U_S$?B4=Db^c#w_HSkOzXCq>^1Tgw>ioaT?Dv9CozEs_|90@H^Zy#Ne+RSwb?~W| z?>E4w&i|Xt{$}v0^Z6FD|84N8^ZyRBe z{Qs5NzlYhs7kujFy9Ipe{J+oaZv~$^pC2&$KLnpT|9@llf5hzn7<}sGdms4J`TvC3 z-v&N)K0jsl?+2ec|9@xpA7J)>20r!j{WaI{$~5{eJMN^BG|F9|oT~|KBkC+nN0x;8QQ(o#0dF{|K|c3w-K)b~F2r zf=`|QW6b{J%>I9aPrZDf0G~Sl-!l7qz^BeL8K6U=jF#FFk`+o$Vdink@_|*A7$LtS+Po2;6%>JLir_TQcX8%QI z|0VFLm+#BqQ|JE*v;Qji)cO1$v;SxCsq_DT%>HZ4{$IeSUcRq`Po4i?nf(LcQ|I#r zv;QXe)cL=~?7z+I{|$WV<@U{pe?Ee#d>ipkh_75`q?}Jahd=G(7 zo&ONCUoBQ#CzjN<)e9j~^1r_6ADJLTySyeIo%z>@$VKI~T6NQPNyS|^ieF8DFVZpR z2{WB*aHRyl3jD#RRKdFb+m4afbp61K68t#$*{2=<8x(#-EWb{iSKC%CYgGADU!veg zh+iNEzDkGk5(mF9dT3sy3jFXRJKXChz^@ATw9t>L20sz{nc*Io1YeC)%1aISNlIK= zwcytf`*q-BtE}|p>cOw86oluG0AFnfC@&4*kD$b*)d+qAv7Z9Jk=SnnpL!e641N=F z{UgC|CiaEsx=zfgZByGVl?`=&jxhUCW>qWiP>*v_9J4aXZx5=({6wp#W$`L7uL3^c^mcIL{-}0^9@`03SM}G z&o|^#fnV?Q4Opw;HA8-@QQQIfXYiSstMEHQ^czz2KT3Y50sX{wd|c+L7WJ+2_RL10 zFET#=uVZ|ECT#unKEK=VPxSer^NEPtuN2E_+tj?-uw>h;`q zKUPFb_9ZUIQ^8LixJv#}i^6RWFJdM8){p5rj&tCuoRD>zFY%K7v>r+YFMZ&ujlq6Z z$-bN_~z@wWY}x-xxSo_O2#>xcC-_Cxdk${@V!Z%489cSOm48rQFmV(V8!$v*rz z!`y5v-S>~5T=4i2^#pRrSM6`d>eSE|IIfjWf^xaYLgT`@a z5FQu=pO&n<5P&W6U3t0Hg()w zt@wKU$c3B{+vKgd?gjEnLiGP8c0hfnH&@a@z=+A0D?w4egsE=SBOq|djPuktHjzBNAIUcN>A5|(eR&(GwS@1QK-TE2s^ z^4H%wldqR=5x<1xTW|7Zyc!YIu(XCVEw9s{OQ-XY*+(Npd)i-;bIUo+&heiWKmM6}5mbCVCGKn%^O~LdBe8Uc z$W+WaKoj`u6B$xJ3BFM6nXvw5@FR6HA8U&1{EU@c83}%@E=%gSfKOfjDDc-e$mL6z z&uH*BG~`JAG2m0zKNkF)Y7~Uyvz6H&hrZg;AY8tOG5Znm>lSf-v$KEHIajT%@mNOg zBlZp)zUs7SW{P}!Hj@^j;{)^5eX5IxzeIh0>fCk_kJ|o*uQiCgzisV?6^|t2rJbP| z^ZBy2#;V}@Go{rZ_xZB^#;V}@=ayD~L_E+Uw_ncrjU^nq2(=I*Vw=aOK0h`h?ql|U z$m$F6-DY?Gp+YU`L4B;gZQSwZS& zz>kZYQsU&2N-X-|3&F1%+>#PKMW0gAoeRNF^zBTEY)M4X2cHdob@pXae-8M`bfSrJ z`}i#Qkv&tJ#PvmgfQQkE7qcg4ExRernzraZ%BdO1kq8;78Q> zUsDoM^uhbU7i#=3FZz^{?tBz|HU0_xhtXH#e^EJcwj;73&dCtSXJz}Nl%+@d9w zbmuPcb^j;y`@z@!|Fn`yEc)P!z^_sLXKm4^lyv7J@M~57Sy>WM^ugzXU#I#Hp+6V= zQ&s;VoS$q4e`NoPX3G3~!Eedk)J&PrM({^vwvhTc@JEZC&6N3H0DgV{&7|XJ0r(?w z-*2L$MnC_EH;)z6n*d}@LO}$BPrLfFM)qp zW*Vu#4*ap=tdW%K@3r8cw(I6Gl=-Xz|AQO9KZdgY%fLUq>k(3aDfqLKuaNftUx1(4 zRoyB!7ah_i-T71SJ2y^irCh&$0REh=vq=5B!9OGU$yUno`EBsW4Xzj|dP|D9=!0(u ze|+CfBSo(0Q%bt?7VrQfjhyUxaZ}Ol;i&n@YB7C7RvE|EBKST zr;_>`!2dvM1!;d?3;yI?^I9nTa}W4OY+TVoIsaJ+ep}Z~q<$9sDakD@l=GkKz@Pf+ z&KAo4up0bnTVHOWTz@YIzkOw56s5lm{3F|^j-ot%_)qY~tFr%WD5(V(eej#;Z%wpN z9$)%1`YWfB`hP;deO?RY@uh?4KeeJo+*&l!lJ0yP{mnPEP##}>4gDosNc|VlZ{68K zdHnWW@OA$uJU)B?eBJ*EkMF$-zV82o{vi0e{}UeHyB_?bo|-p`a(=P~{G&Io7)3dM zz5@K|OKu|dmxF&y>y}ZJ^OFa`KX%tn()_o9f855GN%PqXen(egH0AQ`1Aj(x>S)UR ze+mA~SLclueI>Q{q7S|w{NuN-7)`l<_e1b!t-OiU{~q`!v~L+rIY0ar_$NNKbF|o6 zG}4mpd;t8DHorWYa{ul};GeuCF^1B=2mDi7r;efQ&k^xdi|B4{OUhK$nLS4*E=;wF zC9NfeT;#z~pWiH|*B5z0iFd`oKPExz$HA`=qf0u!f4Co~3jAq_^P3---X*qm4EM}% z_a_WKR_T4h@ zb#=0MWtUc;Z>?Wc%l9zw?e&++9}B*<{?aYqao`uW?|nZU*k5`6;|;!Af4hG+_(O{I z>u{fMZQrT<2|i!1zi0Ol{Tk9l^quW{-=hPg;*|}4`Rug8*ZJ=le3T;pNj~4&{&o}j zlfk$9^MU)b8H)Ok@cC-_uASeJt2lZMw1IE+XF7ih_^LnrYJ4l%{A4Qlh5j(OV<1y` zf0$v29`Z(kPn>=>LfpnsXu zuB5zwJHXG+56S!);OqI}qz4xsSe@-JuVU}BW`bYnKYf25SiE6Ob*!?#IB>kd*W1Va zgMS{VyK!Bmzr{Su=jZ1qME(grUyq*)d-e~WIgnAm3|!geMD(5h(^vcO*Ef8#I#$_l zoSkIwb^b36);@gBjgd+ZW}WQw^YarT{}i9E^Iz8U(%_{7xytiD)#z8YOx@4^fYIM7 z`-A&Y?}6zO{e1w$oihCD$|H z7xGv87aPV@x_))~d@Fywef)Ce<9`nLcK%fU8Q|yluhsUkieh{UF}YEk+uWvdPRai! z343aOC}Lj|Zmi__V#yE$d)k={G;MsU++)T`4RA=(XNy{KO{x<3Z39rMYpEJ0XqLo z@Q;qJ93}ec`~~3a`nS>fmxJFPPkz0>pDKMJKb+Y+{wKtDeXYNj&Tj@^kN+H(wnqpyw>9dv#Z_HN{)>-;lx`Huo$*FQ)%{zt{U<5T**SwWZ2 zC!qd#eAkoxS-O12`h3~{3G+Xd+5b5BRnb@FCp*#Qf0)mg{hx6BoWktaf-l#vJ-Z2) zZw>fr{HLF%TfdG4KSDhJnF+q`KV;omo!{c^57hoK;8V|kP6S`)pQh_SXEXcr!Pof^ z&ach`pE{opflpok4Dj{#k#K%Eg4tgJ{*94rN<2t6K39S-BC@x=OXsgO`Goa%nf%Rk z^*;@MI-0yA-A%XseLCXppOd2PcVr0Xw@*jC{^V%alamSSzX0ZkDxWN&|1|hhqFd$p z;&l065clSDM0Dkom-Nv2PlMkU-FQcq(7&L{U;k1{KjHP&_*q7n|I^^BdeGGYBqu>Pui%Z63A1l(@wwmclOF$H4E;ydzm%~4#n2y= zzl?JE`u*NP!ut0^|54*p5FURXfc~KOUs81AX8`(x-hUx{e|Z4iG#_{sZ9a`3YhD1JEDz{!0_x z^4($T4}|@5hp9jG)4jj8!_*%L>pv6LU)>)F{T<-z{y^xT3G1)!4}{yV9pLN!KJOAYtiQTH5az!FeBB=i>)&DO4}|lF-OwM@{DgArd_>-htrzW~->J%2br zxO~Ca^9MqI0rUsGe?jTP`m5&;g!%6UU(X*1>)#9gLGNGerCYx1pg*YolkO+R(D&e+2rE@|RIAUw{3i`K_k)3@g{4AZn+~oJr`D>W{4JJQLSN|O* zpKyHMWAZa}^*>Q^AkKPwwp}-2a*a zel)ryCAzFnprQCFmVr;bf43BTdHjL&_}B{Yb^V0>;ZpE*{e;KQSA$Po|0?jQ>;DY+ zy8aBs$h3@Wz}NK?9v{nruU|DwSAVa`C+wenCO=14|2C7~OXp`yz7W<&gb}<BcHf@6RaD9CrM{GxPZjvaeCk)qS12!^1o$(8 zHjVa=k^gDJ{xbr6WBpb>Wi8(ZX1|fyPci#V%ziVoKa$yR0pHc%j_7ZBzAbW?y+V|? z{*Ef@4_54tF6Q6yLdE_V@T|K%0?ZGrv|YWMFy zs$zdikl%avE!+3kRP0X$-#7jjZ)}L_O;~y3e;W9%@qdf=Q>)7xpY7oL>%aZJqbjKX zNbv3YyD$CIQB|(=%bh?`3hF-^eB=DNe&ti!%AEg4#2)YG0}p-MynXj% z75+xl=WizUV?O^oq<-AzUuaJV!-r7hkySo_38|kzzp?z!f;asb)#wk6^|l4mlS=qr z(&x95`ZeIs7VAmvi{8{DuG4LZ1Lq2oM z_v7Gqn*2rO`&HntGx^KQ_Y>d`nEW;6`_Nlu!4z1yOF zb>LHoMEUhcM1PBz)7++tRfjN^E06FJ5j#D;{CrN*OGG^3@pqBx>Wu`izn$2Rh~Ina z_q?S*@LEyu=Mb1~Vu^Uo^Y<@A|I`k##QliMu6LuKo7W+_Dl^^B?m|Dag4EBTFK+4( zC%Y@C?D~c14{qrYJ(Zd6XD>v*Z)bzD(-RK|h_CAy4WfyIh3+o~bj$ zS~6ZNLce$33}JPBk{3A_{q7Z{{#^7^D^8^B51Y~NUon$1|6cTSH_fEXeHH_rSN+GD z)sno(L4V`C4skAB{kzcbT0!dfqo2H~L!3re z{{`sx-%PswT7Z7;`!gu}=X~@tkC6JE=!;ioP|lyfg?|4lGbzuH-GqLw`gqFi`Ir=N7lKRWgZ=W}da{uw4=&SrU(B=Oo`YM0I`R$+4SNRkAe?nj7PdL9l zi2hS6W{F$r@_!rs%{R@WoZr5N{*o=E{)_0h?wmzAzkL^d)&B|S&j-*~{hx6D{3`mY z{}cLy=&SxuIDft#eKr0!(vAN$=&SKhczo#!^wsz$^p~Tr#y{cls|V5F^)hMx+tA;b zIDs;st>|}6CH4EzPtH4mGXGzq|LTepL?7MwzaRarH=Q7Q>HHs}zj6zy|2_2Ecb-5w zKl~N?PrZDC*h-hr1L$u~oG3Qa`9DH`$y8GR9`sx1ok-cABjQ=l?*|>7xG>cwmb6kO z6!rPdVtPH5E<_CcV-mD}9Q+zFIzd;x5LMt$OPt^Q!1OM$t%K%O5(b}g`BwY<3!5qZ zq|c{azBTAqpWpI82VMTP2A?vYI-h@G3#DHV{?SRxKd_W$e2(z>YWcoPH2T%wNA~u& zW0JIfBlxO6Tu;_L)j2KR`WGk8uYVv-H$IyUKIQls3BJ93>ArXH7K&48T714*zFX(? z+)Fb)M}co`U+DbN;H&Yo=&%RLPIDOpeqsIXyJg_(<)3$Dr`ziDt@Vp)`5p$oz5Y`9 zW5Ku9U%KTx4t#t3AGlxs6;3Hd@EW1 zp9p?oel@sbAXEAHPaAyIKMy=C|B9$9$8xVu^7+>Miprnt^Y!>y&_T41dIb8;{A%!} zfn4SJw;6n$|GsRFBL68qKR^E=@~8TIo&N9fOY!JhndK{T(Xr zbHm(f_xY;+tqXg03{Dvk>m%_nNRh`J34VV2OXeR1zTW;$dT`-^)!F_cWre=$Xz&aD zr|-`Li#Lp^j*SRynI1UZ;H&Z9y?^k}19dm9t91Dui z>na^T$D!}^pT63MzrNv{)v*Rstf9ZxVeobSFAdf{e9n!LN)Hyy@cCB%=_c}L`h1=L zvYwX)FCEC0f8M_x;PFP^zL(&5qzD0+C9Q5yM8vaKOcOZ4`F{h4}9u;J_J5>{WDBHVSgS0epPg9 zN)Y;+z^{(J+MCYM_2*3y@BB*E-=$&>!^tr;E9{P|GnVr{zF**y{7(i8Qt<-4E=$6{68Bb?#0j_RQ;5Hzk9#mC;j_-h;`{R7Y+ z)c6!lbjx>#sXq|*&mE@zKzRIZhp9gh)_*3fzq&sV`a8ha{ejRw6V_kd9|Ym}0blnA zLjO!tf1vbX{nh<}F#jFk>;6Dk{|-}sc%JV4o!!tM)chn(n9pwL56aK<6V?y?LCp^* z6V^W;)?ZaW<^IKPzfZbbr`h%*Ua{ppJtiQ^q+`riE_eu9J zc0+$qlMtVf}uewEss;{f)5xh`;~rSw^{h{q@t1AAkM5gM|64Gxg5_y73e7 z`=sOlcIeOb@r`?T^i_7whWpvKL;o2O-@12u&i#nWu1|&f_1|YF{Qd4N;Ol&LRaUe6 z*;`Ec5Y~S_)K7i>$?yICo*fzYPgvRY-$OpK{yp2%m6`5mKMeKj<=f+aL}k|>hWhpR z@2<>rKYORC{*3z(m0jOysy|(s>3;U3P`_Hfl;h`7sGoZLJi%Q56U_DRgZlOO?{F`n z%C7H&`t|rHn;i2Pi|Nf(Xq4NIzW(@p7{qpbU&U60+<<%cA=HH%keNt+9eiiuC`6QVAYGyyl z?AI{+wak7UvtJLsYyG;VhhY4V2=;3!{Dxrv(NzTXM?`d_`|qy_^1nZeKK0+9MW6cb z&!SKL_h-?k{`<4wlmGo$@X7!FEcUo|4)F#f6kJ}mmQ^~ZemQ~!NfU;XY$NyXQz zeD%}*eb|UNw$a_+`p9OU){h=#_Upi}t@Hy`V2RZ;`*HBwi0hAmKb6>T0-t*PG&B3- zz~4$d{>L->EzJH%W?zUoO=4MdTa#Sx)M1~P^9N|tdQI%HKIH6R?4b2oYIn%x^V+dO z^gn!**m~vL>M>~%9~_z#$%tzG4DXki&lhp|40+LCgoKCG#r9jIKV9D2|Ag{;GV)FJF;RPlHR1!M9!^tsgm@pA*r7 zKLK!gv(E3w-Sw-1uLAPrua@tzSLc`S@@G1lCd+*MmwLaSe^6Tgdl2$>#=ly=_gTwV zjh}SD_#c6ORqAE2Ms4=nU&E1x@}DXTxI<$LUEAs=b?AGv(Jwz?(%c(>12 zda&P8=s)P|=Xt-3LSNn;?@*6Pt1oiz5ov`nIS3^H!&={%qH;AL98k-tSMR^e2ITL@F+< z&8S|B4-UOQH1wYQpH;ma4?6#gB5M17$D8R$JS&nfwsp);*QBGq<|BWS$>1MP?6-j* z^ZMeTul`JAx`6sq!Szq|`J#RLgVP@@EMIGY+S?b;@_qBIwADX5)c6!p!}>K1eW83c z1k&n@96v?;5aXvEec2zz_l@s!e7RuV+efE<)j!{STh<>}{n=W-4D}z0zA9Skj$dK@ zN1>k*^>Nv<3ckI4aj#!FJw7+<{8jxj{~9^}G1Pyw&sXcO-#4wl?Y)1?-PxP>Revz} z)BV0&f9d?=e7?%Z)&H${x9X?;>X*sCr}rGK$M|=N8J=c5bH288(BQI(7MI4a6T7&KRzvJuu zm*Mw+=c2EoQDegC54I2cFV_B-96!$fi*bH_romVGu)eN;mEM1M_V3iw;4;tP%lhS` z()y8w{nMcO_4v>4KLRdqo@MZrKCExoujc>u^3B(zpPv6R-{k9Mkk*eV>|en6w|&q4 zsav+LpM$>qw)gmhcYfuJf92??Xc)^>aP` zzM0W_S${mW=CO3sWaIq&Lq0!l`#Pn<{$nwJ*8CvrJeBti{ka?cjFXSCeoueM*PpO`{S5Dy1qR<+zkU3{svrGaB${-5L;VZU zSL3Hg)sWVO_{YE6Kg!QfPS6bF7)}Q zmFzqD82pdef=9KdWTlso&r)^ZD`}8(l_Pe+@H!HrV;=XL!F{hJJ^A ze_CJ3w;dRt`TaZf{!34ToGtaJy7<*_b~5ub$|+TxsyF2k1$nI#Q6I-@5yAKA-&i7ecgBHy#FLY4a0_z{&}Sw|7!a#=bu6Kf7akzGL3&N`e~8h{tn}-{YQ8GQS zzCC^d>ksLF0sXXm?XBwd?fi!s|Ehl$#=md(F<$ zFCp{M^#}Lo^#Oiq^#}Vm`u%YI!Lxn^`!}JVmJ2rRUcLeS$Kwb0pPSLo*!y4k^(*4_ zJ=@29tM&eGBDLn36(i02zh4UQ?fjpu(7y%!tjiC2Ia%+HZ*AMw*MoGl)w>=%? z_xk;O5&7l&zMB8w`;YnUZ+?EF&aVjCe%+3~o|Y&(pTF+^Z^`_v+bwqe*6}xCAAi%n zA^)!#d`l|$Z|VB2`Ih6W{_HycA*lX4{JvbjlwI)O8&dVlnVh_U@0|Y-RR7n}&uPZ_ zVwzv+<*U};oo{F51Cz;wHNUlHkj_)}m2aTm>%G53-#0|RiN5CJOYD5=<@EMFy?$AF zIr*sN>pFiUD4%Z`e5Jd5sjKm6SiY|FH-eV$chJ}4Q!UH<^40yPuzd0SjaUKUG7 zn)R~te(6I$P3zx{e#YxR>&*Xy>t7-3UoGqR4Nm!^+>5?EP18yypO5T6R{qw{?a8NM z*(7y-)LiLbUT5~Vpr4U`R#}#h^F#Di|DPxQ>jM1mqc8Uuuzq)cMt`{ae}KMF?_U?{ zSLbi|^U1%zpUBk$$$|oAW97Dxay+UmM{68~SN~{r-FkzRIUq{Xa(E zIlrhdew6P_AoTX@PJMh;+{mVeSTNA&U}8? zcJO0z`_;Csuzm&Ye~HIs|9>+*Nu56y7ajA1{GI4$Wc{x7w_d+JQkWkuie}^yC;$0f zLH;A?r_}69ZOilH6XyT!{4Oukj-6PM>-Wyei6=JVg^3*}27zZLNN&i+NK%t!CP#O3&xzH$5e z1o%hD6GmOWGyd)M*O?#6`H9RYTCc`uT;?;*y#M%H@axL)TY~*P;2%%y?*%{R^_}x4 z3;8(9w|?us$@%w}XU)$B>|gH#pE{r4fgek?S?6cwXDR0Kqqo0md>*0J-(utQN%ZCL z)aPgB{nvcsUyV=c%l)Ix=Pf@%ZQt|b)42ZbM_+jTBK3>SS6+IAnx7OK|G!5+Z2fZl zgKw<=f6z~jAFt0Zm0ew3?E39}L#u!GtNBUm<~LuQtnzOgsrrMte?EnNhw>#nod2-& zUtg~KL))mluL^?8)94GcUl{*t`Re+`*4ML>_55v=JbtD68`$dRAJ9+J`p=-B8ZXc9 zl`rh%V;w&+*8gU{{-!m7^*@V#M%wA%<4bDyb-MgdzrS$aHF9r9{r*(`___Q(UjFF! z;rOAw{j#3v-u`aAtw-*S6!!iK`(zwZ*uSMzhV|6=f8^!aLj>-X*P zWBJzpMZ4U;xU)A}n4cT`m;An*-#5(_e+dfKbNA@+Bm0~3)%n}Xm;Eg(o1)2o%ivq*Z@ZVTp?-CI?EXKcd!@fz zj-O=#>+jn}Ke&Et{mu91+b*$u*&l-Zzo9QrZ}A-8%a4Cw{_6PfeaqDGz2tJae3ftd z{m{P~eXPH*f9KS%d|AKcTlJg#chHx|8$J7XvVMPm&gYZw&vRw|`uLk+{Jd-Qz4g0& zr+&43^Zj|Q%sNQ`~J?t7o7dO zl{Zhw|I{&sv{Z;7e+~O8zv$Na6y{edpQ+Lhn*US> z`&K^Sr`*0;e`P-E_+F4-gT9&{W))qm|9k6iD^h%;?er(?}zxt7!Ki@7k>hTlcH~D?L{;-A>DioTj34%?r-^%t8TPD8&dC?9Kldg{;jXH~y`f7UR5jzmABeE;(G z&Cl)mr`&!O^N;rXa{eE3`O5tlwR~5|xHotYv--70!vrK-6 z%Xj8K=KAgYgX%vK{VwIGci^qxQhZjP-xU*u^WU8JU-bU9{QY9Ne4XQmhVg$A`g1K^ ze$@+D`R@1M9bb+A^H%Bi*Bsya5j|f|Mn9wOmhTGX>p!UKm#<)tAIG=rm*d~@4fUU5 z@Rcro^+gowx85HN^7Ziz{S5DyQw_eH1!k%0KMj2;hssCoe?1|W?=bm%(CCM#Kcqh! z{fw%=Fh2J<yL<5zPHzS6_iFCSPK|LSRQ`4IY9D}CEP5R|{(e=n@RLHTqC_|EbF_w|}9dyut! z7s>jZ_b=q{*Qo7Rv{}ACqVj>-)y;(gzN}wATJ{I^Z^75|XE}dR^@s33f_{hMlis+C_^_vP>&8b7zCV9g{r2)z>sN^Sml%A^ z-&4Qshphhs^fT(`if8S7aQotnf4hG9`^C=qH}tm)4ZiAc!}|I9)%(|uuS$c<#|*xz z-yZ+I`t5u|)_;+~&-Z6tNuVFH{)-L1eE-6!U-pOm`kU`RcKy0P6h6NqX#0{i`L2BI z_g|d;X8Tq?@=OJ_e1rSLQiJc#N7k=$^7prVKEw6TW#}s{t-j>@k8}R5`X2P3+g9uM ze~bP8+NFL!-0@*mfByF)ik)Av0)5%vtj}lAyD!f955~`Dm^n$GKO>sgJSNYd5pvP^ zE}snYTXa4Lhw}6PA$8)Nyg2<|)$e?Mg7jnN^Osfz`F8&K`Twwf!1+Iy`F!X1cXYvp z_uq@vAAEk%<-xwrqu}eC0r>>`R|NQWf2-90w86JVkTd>e;fDPqYxz2#U!l*xGW6#w z(a)$H;&Yw#ODfBgU) zKc0MCpC1x*e%;ju-#dN+e!nc=A5{NWpC1x5e%7F$R>vPy>Gt^a{Qh0x{Wax>=%3f1 zFKz4dNo?PH{!fcMzqc?yU+R25iQGOK-(UWW&$mCHB=5hkhrZl?Sr=>h_WM4cBhlwV{Ix#c{(O?~zWV%xApbh_Gcup7%EI#H`PC{KCm(Bk7V^1uX?^QG zMf}hCe3?&)ezAP6_xUoP68&QN4{ABe*JYUxNeEaiT!uw7> z27kTJw?DrnykBhjZt(fZ{KyIKJN0{#v2J|P=i6J}@V--j+CRg($>(>JU%$b>+2`Az z-%>{X8Gk?htCJ zEYWxJQDwp9D?VS2&#Zb-8TA{+&uuUrMFCZ8|IXI4EXyuZP&-%IOT5wRvE7B;ul$XnJP3O;CP2)|Rx?I`+# z@NB#dcMo?nB0iH6UCnJO4ORcm5&4mp)<+2q_ta4LNBw?-5I07I{7P|&h^{8l-Q1@3 zrd9oFZ$*73xpn#L&_g%KoA2%VtGr#-%SDU&QoZ51iu{wQwzr6U_D-S-T{U^$ zD_Fh_249ZVTP?!sZ$s~uzkHhmeEm9wFJ;$1(%@VD?XJJP z^3GN7S>wO_`dbWsp=^2JXXv?#mhUKoug2%adilQco?gD6D}Q{BMqj;|BmINdAA0eX zt51LLuD70+{b$!J@@Fb*`!&YoA9VbKcfIwz^vkcm)!?gq4&HF+#i6&3lk2a{|Jp;Z zJU4VhS@j=Q+&_4i3`VWL<@#g6-#2@{Tz{X-ufMb9@_laT{mP{{(fW0y!MEnOha_(0 zU&;LED1)zm2KSc=`oq!S|8wXZ-JfOu*W>dp^*R;w=jrG_q_$sr`z!m8oPVnRcI`dt zRmxg_j|uh*{l5bLSn%bkKJOLg564tIe~5?&8r;VRV%bKK+fX>pdtgZ9W>;`5A|kfQ zU6{i0lf5$Koc(4|S&4g}6!q2LKw5tk>Yovztv`nKcT0b~D}VXpp630LOS%<<`k$B2 zrp!Nq^{er-+*Q9EKb0IWOF;e9<0t8>e}u^8=;}{0*I#3*KSNi44RigqzWSR)jWc{s&`e)1#;=6?T zk1*8VM_B&|sDEz37*01Jo z?XLXg&DkZVUU5b?U*PjAEx3Rr?iFa~~C6#o$34H4H zs~P>0svG{nBf+QcKM~Q_AkJ=XtCFSI=Wh&ORrp6leSY}ohIwR+*-!fXG7sbh{4h1l zel4?K=ko)8&@#VW&+L!z`LxTo!RMD5M8MM;eLijdDfHhOnix<@S>J9#zuW`m0k7Wd z^8+4O=C?;O`?canp80c~oc~i^>cQXC{H?At3Aeu^nEhJ$DSDjSuX^yuSF*EiSa2hl zeIcIozW*X?Q18DK_8|5CqwA)j$fDoc;~AfEIf15}Lq|;Y%l9wb1yMi1m&Z?B1*`pc*G;Uj`0Xfj{Z&}MI{uR@lw0ZXt175}zZ^W2$Ila3e}}B!6?die zC!qen5!YW0^{dg4apkXWs_&J1sfPL^#K#Y-#CA`A7&lmMrRL`)z^C3nss?{7@&0d> z=x5!2C49a)$8x`0?el5ppF%wD89&tXp9r%bW%jF>{RFcw#4gtHA7S>R%zhQKpJ4WD z#Kx4E*W9Mwl2yl-?7x20Pt>Sunf*GSuYU-Uu|7V;x>3Q`dY_+GT68;6J|ld7zHsZ; z?<%O=dTN8uPwP9V>Td);qxED|5Y?XoKP`0qQL6FT1img`&atR2&EQAVT8?Ij#?MIb z^Xo5JJ}qWn^bj3`80GVIKK-leXqG@kTo3(C4a^AH87R>JpJ@1t82D+uVnuGG^5fvk zY-B!7G~r97%IB-fYhtF)0xai669IlXmgzaw;M@6|9$U`$lHgnUA65=!d`=DcR%=^F zIDQT`_~s9}boXnr5rTL#EKc241JASOkWc&{;>pM|{Pq=xP{n=lCMC8h<)%2t| z`h`P#riYjOJ-L2)^C$POfbFmRK->CMFV!+g2){pG(D~JVKSSxq{l0w1fv*0j-;dN2 z=AZQY@&n!I>aX$nnUcqNu_x3Te9G}T%HSVtq|2wy;MWu8U+?qfr;`)fN?yvMR1^vI%`t9Hko%i=4%6z)ezmm58vzh(*=$}hl|B>iF zPMd!>`mg_;bbOxc^J(+Bh}oZR@F~at67-43e?&anBo;Nd$(=^s-!e_f&d$`0DG^O4 z*UOL2?M!V*%jvp0=qeA*<;1sc2_%eY)`M z((8|dFD=r1gjn6|-hTBIiY2)g0Y68g7LX|T)b+=}r>ijo?$SUn%f&A$npd4;cwQ_41XUmeAlHKh>oa7vixI@XP+7jeyrmflpn36Zm5S z>L~ZyY4EA*p9DU2{vF^`*FS^V&oKL)%zihszku1#GW$!J{T^n275LQaZw`Fw^>-b! z-^=W8V)px({kxg{ZOr~pnf-ode*k>y^>+{W)a!4x_@&wfaNd8EC)8BMKU(f=$N#*D zc(6g7*W9M+R_|}B{|uM@a&wD<-(ZCa%KUE1=ZlWjWm=}EH8J~* z;LFpJBc?ja{a!Qp#D{0ZNWY&cw^q~hTELf&nPYlfx!)V*_cP^Mrss_YpSu5y0bl*P zX4X_lnco`+KGk{Kg>rt)ynpTW%k7hedcD_D!s}Bn-zMD?|}NL^T{y#-OPTL z+3#WYbIg7(v){+;Z)5iRnf*P?ezo|6cYa7de}2j{fA)57=T@%V4;_jMuOBdZE88C- ze&x+aWHL_G1Xmisr=EW{f-mPMr1htKzK9aU;t);X%X~=BzikFz=96_^oZ!kx@MZmz z2v~<`0bkw`u#4(ErNk@WXckMF+tja{DmW$@#fdHQN?QJ>Cc8soaN?mihHh|H;H13@ zwmlwVBt%4jKY3Vx>f<3M!%?5#VAZdARewa+A93oB+x17o)F1Qv5uMNQemqS5ai1@& z`aAOZ2$g?Ctaa+QURZw(k$+Wy-`!^WkwePA-tkLYzKI~e-Rpm$OuyRi>-@Wq^7@5* zoccqJpQPUxpHbuAx~N~n)A`unkiXqvkDr8EXNJ4f82s~v|zx9GZA&)ycx~o$(((H^ll?=l9k4l)nBPf{ZLw z=CewO*>;)jI-i_~wOk)!eAWm0I^AOa_%Qwm@XwHC>in(oKV9C``4`52OTPZv_AvdS zA;`DJzvCCie`$VWkZ+BD$1jY3$3H4e|4D)W5i6f`tNd49)>_L~M&gVg$8SD2#PV$d z{}PGH{KNREFn%-m`Q>Z-Yjpi`{W8>F8^#|AzN|mus$Z^Oa{Qb9>0$D30bk}H);~6k zKMH)AkJ~SnPeT}gH25+3hrzA>kd~o~jJ#>}ha1#Q)ij*`6AhF9m_T29GXKi_R`8E- z>es#;|L8m0m$6~$KMZ{Nu@(7zhV_$S{ITF49p0Z1#vcd1Jig?v-;lqP&*(7zc<|-; z(es~fkyZg^#@d<++r2R&*LHb&*6Sw)i1i0E<}F&DEr&R`gY0w1n~3Y$M)s; zQQKd)@8mN!O#KtV&ySxlelm=o20uT3!uS)y_>;iTk00ANOaSTU+6#D&yOEt zKB4;0vEa+`(`MYhOceQxGk!uHA2<$txqRJzVf*6v&hi}}X8zUzzFfXx{rWKe4DjXO ze`z~$mb3lU^$)4vnD*Bn%AX0o96w>}Plu`hc<|-;ar=esm%skjF#as?d_E=5PfjrSuJLK`o$(W@Kb#1@96$N_n;!1P{80VjB=F_(4eN*M4<~~!m#^EG z%NO%^@(I-+P61#2{Uh)AkH|m7EXV(BotIp`jvp$YQ^A-0$6fyw{`#H%6YBWq2mHQu z{7sjuwqKrnqxP?zK3m22j%f|%a;p1t@DvT zT=Qw_CmiN7KhSsOqsE24D5( zV82KE@=G*K{R<4fRljb&hWblee-|2jtNtKg*z1?**AKCO9P_^)G5F`}?U#PMj3A%C z^Yj+&=R|F7nBxPBz*qA_mv5N=IDT^&e=+!Sex>~`tKMRMDvWAzurrdP@PUqam1 zEY5FkQ~O0J`CrT`&#o~wIQ07KuQ$k9S5ALR`uftE|99AbBIsxIQ^@=%`ijp+j*N>l z)U}itlz;GTqO9La$f`emAZ5M1tsYYR5;OTiNMB#HKT(vQPu%RU@AUfpvFGf_^d0%t z!+KD$uT=s5IwC(2;7{`U>2m9@4)F77IQfIGCl|$XvF}R;`PK^r`JwZ#G5c~Y)7wYK z&yP=4RG9k>FsP%zd6fWmsPJ{Gjz~l=WnjpGyzK zLe}3D=uZmviCR2OqQFihM~P*m&sK{YIDT~X8yh@MnCR4zTxrpL2v7+(OS6^JM3ku z(NBc%>qGg|jJ}u=w!8@Oe$J`|MQvLHIdpdzlnB~(T@lDR{j0Y3(+H&Z+;V0qTPdEC> zAV0r+UkIJgF-E^W$j>j|7eeQAtkG`>;fKrTIFm2`0A7`~(9Gk1y*2)wZc$_bcYv>E zorBwNs`2=DIsHfF(~)kn*8G9 zKktVd|EHs$rOjuy(J#9GmXuEheHrdxU-T4vep2c9=|n#x{d)p^xqZ>&GxYMEgMQAc zU!NT!-_oeG{xi_e$nA^FhsvJ|zVZFpLjPY`Y+W_ocP9F>etA)Akh<9UjL+|1l>a;5lZ8+_5G5_lfR|Ve}esR{r^0Ze@|dOs(zJ^HGd8M z6JYIMOnf)yIsVWu_rKKsb-;&7%I7(k1;M_WJ(>NS<%jt*-wOkLyFbA4mFus(l;D5F z=#QOW)E6)6e5_OO^eYB_Sp>d*^FoNjJbvN$Pr3lbYIAm%Eqv2=ZL!(^mRh*-g8PqY z{ayVfoPR#}x_=6>DZsb#FJb@mqu}d&(y@rlM;$%Y^}G6iN1^_BgLMjR;X9^lOM?Bj z;(k>_EEZ9G)h@Vk@E`)zk zus^+spVRe+_^`*12m8ks@%wfCA^cAS`)Vu(j?eWff4#FQA64XXaj-vAJ}t=4C_fj% z&j$OmiugHQfBq1Ak@Ce-lP~9oa{aaTp5^h|hC+XHt-r|zy#*?U%lnoE`&J7I^lKV& z`6gBDB`yi}trMgI{n`eRZ{o%L<-xwyD+By>(b|Sw2>;Sx-|8-AU#`Eh{`@Im#p+)X z?5nws+*vX%U%CFu`a}4i4EC+=V)o_wE9(z&{C{PzZ>>FMU#wTY^%EA0M_d-{TW^q? zeYyV1d_wq_2mA6Y;^6$XA7cIe6!_NuQCzLRYVE=KgIs@edqijUoLp3{Um-rs_6nn) zDB{akT_5|h@5=d_+Q+51Q8^x=tOf}G!8tetb^*Vgur_jYv`XPtW! z==Tllk8S^AZ&$_P5bqc2du`d(}M=fl@ui@p-Fo2;_gf9VTm<&<8GU+wL@i(IbPIdfbQOkE@oR^f{k^XI z<(dCJe@St*aPI{4qfz&X^~qSqz{`PQ=>zwr4# z@{Vk-D_c}8+?n?I)_tz}Wq&Kb{z*Z;^)jk{?U!5sWb~!0^S6IQ`3eys*I#S=*o!^% z_&LJlyXOVcpD1p&`$NfoyUCZ`vP#T#5}K&$pRI3}>>p|Hl~iRs1kGR`mO#` z7(a4`bs+!owRQ@@|8^Sutghb~pZ@hrp4}BJdheNI^40vo`u)V9^|veR`rBpjWd-Z4 zS+2a6AOEq5p1Q1K2cB=4Z=7THWq-(DEdPa}i|udde?#nfSF`!b*ZU)$ZlM^&Bq z13!0WGI>uX1A%}D0|v$SfM|WIPC^JTq9zCm)|Y@_)mn?Fty)_q5b&jFgGFn%Zi`mC zecjcr?e2DMH{nIaRx1c9t!>e2-?xixx9zt6oBwm}oe6WEb0^8n`91gZktEK{_dfTz z=REh^bMMS#FFuh^<$@m{)5h9{`J=0#pSyq9&0k#5&!#w6f6n!T%%yGA?dPI`e)i3E zj{cH@es*%f(O(+w)A?!s@sY+?CFbYif`0bmnIC`Y{w3kQnrpxP9;Qhe4=pR` z=f_{Vzr29I5fuNW1$|8X?%D8_040m@yFD`x`V%~qx=VNrpX-_M;(8C0Y4i*_w(M7HM;ndVLsizR3QE( z*&K{I{xJpo0`cdK%SRXgxKKY20b;me+TO` ze!tM|C$+6LP5F;ShQ@ed4Kw@yjws-_7xr7S{2nZ+_7iNCQo8+&D*wka zKX*&m#=xiPX}`V=PW`+-(Bz+X#oI>HevV^4oqFlT>kWS9+RvaD)X&kL76q@Se_NRE z*XM0C|4^OL&k1~`Px1Wt^)+q1WK?2D1LTckTR?uN+N% zIFtE#?O*%Dw4c%S-?NxMw14y4C)J0_;KN9A^&zeDuMy}-3M^-b`F?%yUqJEG`x9-S z>Q4cX{qI)G_lJO)okPkZBKs%H=12{F&a?I&DD3tJZs?xc_Gv^RqGKe45+v>rcL)&5t*2 zxV+>ZyUg-~_W4+L{6p^_$*-S!>-_o|@gk3orhZ<|{9OCV`fm;T{!snQ&7WjEFY@MS z`qvfA&(+W7;o~1rO{I6#IQ2q3k8)T)>UDH7KR3ZMYG8yXE@A#C-f}X6Xg+)y^RvT#^GObWJ*U2vRPD)T z-R^b&YNfLiI%|Y2JDIOL{m{*yfVF&|`E$sO0^{#zewy-w^yf35>RSexpLXW!{Tu=2 zXA$$MzR_pf0(NYcXk)%^qcuQ(A@k`inHi+t!F>Iug<4?z7cigZe=F;CyLW;i}82{_cKab)^`qwaDzb~Z%82>8f)A%-n^t+j_ zL$3tJe?9YQ{G37h%b2gH{i}fSFJV57pEF3mllgl5Uk!}^GUn6xJcIP_Vm^(}RRS1) zFY{@9oFe=1a#_UU$Im~Q@dJ0QpN4B#{JQ=l zmsQNi&u^Id!Ow4)K6-v*8Ou*_*%!A5mM|Ybe`4kbJ%7^1;@9V=$Ymk(NAZzCMXkPr z`N5m&iz0@7@&(NI?@t)^6~#TcfcaC4d-;gZp3D4cBfg@zC!Ejxql$a^h|g|ierm*5 z6!(M`%x^C460@)4hX9`k38_=@75Fpv4OihKEp&%TiP zr;PZD;+`;H{nEI8;m@A~2XXDp_vg=n{vzi4^XEYSIp)*(V`em;OElWOu#@?8{-``) z{NHE3K7Wh?{eI@BDL+X6E@8h{*xxMdXN3Lvo>?Ds`>zMKpLXW!_MZUyig3Q%-8d`NWYW$dVU}djDH#PX?`Gs z^p`MS&kvLXE`v-!gw5#gFvcn6Kx@W&z`0$b3CNRs-}qm{0R#8Ki#! z^Y#2#EinG)nXm8PK>E)xU*Eq`2aNwk=Ii@6kp6b&>-#s5M<<*ZD{KZOqsC9|MfPllgS~%^>|{%%|h88Vihn3G?arn?d@QF`tgVsu37}H}mQE zn?d^5FrSXUY8){BRm|_8_>ung%%|h88V`(r0jqCxeI$eQ=Q3YkA87){e?If+`bY-p zw=zFP@lOE8znl3hD1M~Bi}@=l{)xc&Uts=K6hG1*V175ne*`f83f8~${LgVfKgN7L z|8qRhuVKEP|3UhS`Du#(1YrCNn6KMEa{ta{zHa}MfbpNteBJ($ek=34DgGmY@vmV0 ztC`|Q`qwgFU!R=}jDI!rkEZyM{s)<_ug^{a#^1$!x;~ph`pcQGug|7{@h@dQU7yV$ z{mYrJug^{e#(#kM*HZjQ|HsV#0L4EI82=m0Uq$gF{a-PEHN}4vF#flhe>KIA^#7ar z@2B{if$^Wme7gRgLHhHUudlyP2gZLP^Xd9~2I^BShCkXoq=A*A)HwpV= zh5bpw{&URN^C!sbcRQJ{=TA-n)`#yiU(cT){eI@BDgN2O_*ENyi)mYOHq}jkxi$L} z^`lI^RhR$yDoPhP;1Xkg0%&WhocW#L_@m5EgZ;V8&w%}n%X3OaWcWJhOeK z!Twz4XTbhO=J$jBUCc+`+pBkES%l>uS=-3p$ovf0FN>P-qw8Cg`RMvk&U|=%WBEtN zzd_h9XFfVVcMAJ+nU8Lto_g&_Y(HcoPsOD#muGi{)=y)rjKr)^!@Ti{NU4H zntw2Tef=G|(D&CH@t=&u$?}*F=4pIr#!mwl=n`c-ZD`Xh2Vg8AtF zHHrD?{xw#`C+DBPquXZ_^U?cv0`t-P*HfDksw3H~^P;aUTzA6^r80wm{=aHWD~d3G zzW=456_F++8;YW}t=mFd3qh7mJ6x+g@qAH1xyV{|Vc z@mbMu-*2TOzIYT*h*>`6N2Nyb%F#WA^52l3{|pTvdNQ9I-HS)@EXu#(=U$S|{o?r3 zQ$IX1|NAw({(3s+#w`)oJD`xHOYFXMjyAk>dD-yFMl`BzfTkoEsa?t{mllerHbe@@{(czl&&z8;?=JJ?k2 zQ+|;CH11P=kp5BJr}l~TJ@pgo{Ad8!0V3Sb3`UWDl==Gns2>=AjQiAnkbW8Wsr?}R zIP>-S5iet#eEuoBK>Oa)A$hS*D#+3M9}=ya-YVZ z$oT8HPvcLdU(bCSA0qt(^Y!^DvVS#jpYo6Nlia8LBmFVlr~D)RvCP-=Gf2OY`&56B z{y6Sa{XzQUxli>6={GU|3h?oL0{6kk_levGAK#B){*{y;Wd0{{A3T0LlKbHC$z<+> z$0t*mug_n81ss2-xKH{24bY#;eab)5pT>R4|IdK&AH{s#{*n1_<~}(8)431M|Iys1 z{J#y%|1r$hN18r|}6g|0i;v z#wW=9oWy+^pCJ8{nNRZ%?;^+lE!vOb({`GbSV{(FY7ec2>TKKH5rBK-x-r}-sl|6Ry^@c8XK?t{l~i?|OSzn#x~ zI)8_@&kMLu`A4>&3%L&-zjbmSJbvrqK6w1LnERA}*Li)?NPxDthfblP9ehtyy2|qF71CeDe0~2U za(-+j^E1@Hknyi(zOMhs{d+a{ss1DV_j8}x57NJe`{4TTsW*+!9{@Ieid26-o9Uz9 ze;s8$_~R|ptt4vxzYcWF@N09BbZ;}%%6;5hm>;WA3gL4=9dcQpM+tDluG8G zHuMPQmn!C;gJFl1YUW459ju1=>xb5i`NdPeHtxUmKSTjT`$~lS+kiMxQRes7>vxFa zmKgK3j9fukh>v>jxQ;a*;)6c=LG$$aS7!S`AHOP?uh)rOM`ehQyuZCF#77<@t3!PK z9T=#khWWkNw`ZwZ<|F%-&OsgXRiZ_KKAOZ&aeasn`sf+oPjLSrHhxdNYm7fzL7&Uu z2T%W$Ge45bJ%agJ!F<%`V&tN$WPU82dj#{diuq-o7&oU>Ge6#)dj#{dhWX`dFm6t% zWqw5__Xy@^9rG)}em(OSg8Ns3`PENg@{&^;m|xSMdj#_{$^6=vFm6s6!~D8~xkoTR zBh0TqgmH69l=%th=tqA(m|6cD63Ee&KEF2oWD4s?)uAKR1<7VT=FweiMqzVJj&;Ey+E{bnA zo>%H03Fd!HMXp-8XhH?*9HxQ!==hV&N5}7}-yf-#B%AfeHR}5C-r0RjQDH9p5yTUBI-{^s)fmBJ*TRV@BWf%&i&^6(+l-g-%34+ zo_5bxl=)BU@|ntx-i~t)pX!X6pXr(e`en@j@~)<mRpoaNAnF7FBqL%qzew(hqrykq7_>-7*)G^;zQ@AT6)y#iV_uJIJp-z8Q zJ@BpbFf&{2PN#+Of<9tv3(Ww8|l~uH2T4tbls>=BO1@!fi zYUZQo=OfH-OChtP==zjG=E-gYG?x;f2n5v?Bx}=%!Z8~{Cim@=g&{Rpd!KiWK6|qX5)p#`o!jp z!#2=x$MEU={RP6fXX9=2QG{#=5iTcYydSxUV-Lh3f;A+}HU}Wxu@!5Puo-v-$UbApWUhzTbXw zFd+VF=KquKU8#NFy%cner(?L$zoydr*HjAEg*_E9e0~1=zcB?{L5*rM&VSM8ceTt% zpWk`R_Y%0irJG^I@@Yf?T%yd6q_77VPt{D$zklYjGSoK@21zJab;j|1mx@6z(N-{@ z##g~AKv&@-%va~04&1v$HJHbDSjWvq>8Wu>efY8ZJ9HHh=3fr>qs;FBj}OaL(#VgW zHsJN6ictTthfq7gV?N5wHS!4agZ$(kb^qz97UTHhrQOYZA;SDfCjU|Q-=oZr_Pd+; zLX7#qL%YA4IP>EfYzr!9etAFEuV8+Ko{<19mCUb9WBn@TS8c@l)y%Knh4pKgUlY%s z8-eygE%R&BSig?>bs4N*&-~5(SUXc zlbDF*_jqb5&W~Dt>%GV!P|Wgmem1HYXf1K(Pq?NVmmHGHnSbvZC{N!r&e{*M@ldFh zmJe(^$iZQGXsvl^%HZm5FelZgB)8ht}b#6DF(0$!5Ba;oo29(eUBmI{M>X%yBHj z{Wqp4)lGi?x%7|w5@mjmIyi;=cLxVC-=i2~eqMgYZl;wCMt@KLl>VmaIQOBSE~M)x z+rLUdZ!xW~ecA!IrPB7HGZ0nWKivMWPtj)F>bNP@+&|p@ub&O@Yq*~m|AT|;RHlvI zK{xo*FY8&Mb6y)Py3^Gb_Q&?=_P^mBr}kf0*w4#+UmtB&NlSfU|N6uE865cgASI}T zB~jSF`CIFh%6#(A4%I?c>mtQ;|XW5$5YiDgM?8p!lO9KCL2+@@W8JTpv%Q2K6T3mWb)& z;H(rC_G7ZXr&7lJ>Wg&42y%%q{|8{-Q)e3Sdue3!`uyGW@$L9B9{v0S42uZ5{5@r$^5(9uznTuV?9{En)y{buzn5m z?}2{%wZ6aI?7wB;`DahfHs&YuTfvcliM|N)zpi56RFQ8c)_(_pQ?OCy<7Q@pOvG$o z0j5oc(p<)UBu;Co;C|lBm2$eXH`s(q=4a=Za%-Vg&=lFw))xOu74vETf@YS2SgM&% z?~JDRN7K8cSJC_)V2Ky&x#`qba)EVz^-PlWkB zZxFPuljh$B>65rKgM)JpIh|ieng7{?gHu$hMf)Fl&_6%@gVXtGjQJkjkbZF8O?vh) z7N_`K&rr*_-yFUNO8vj(%+Jfux`&;k*Y&|{Kl%QBuF0W|u4I1R{AB+8#@(gf6;#E2 zx_ozV-6^2iVSWF(nV*0B*%VsA7v9Cp-YU9X+w`ZrP3<4J)H2_j2E>VqGr#98T_2wC z>%+tJ>)`o^&Q+?fThCujjMBG57P)#)%`)a^=<@G+uSR(dp!tUg^SvhQ{7;nm6u*C5 zLB$^n_xn?z{FE`D=C5@8>6suu&V1cGX#WmWfc)|hpH|V2@++9XI)QCJ^Z|Bk{tA14 z0(D@+*ZGGo<-&f2u-{02dvfS4cegUGiZ~KE2h#Vjh=7W!3H2-79U&=Y|aGM)r zesZ`cm+)8_^V>==hI>hz`TFf&$fcb5?MR%g3g#~a`<2XJ4EC#-e<|3nX8xIAzlQl| zgZ*0O1Kv_;L|Dgs?7P<#eg2YJeK=PE|?(f zH!vT)e=C^30^EL*%tz;cjIcje*l!f}#|iu6h5cn}u~FYv^}Nxe)_1~A13H<175O+_ zsri=g0i&mhX6CQ#>4N1(*U3wnzq)5&;2>}hEN1>H-^cBNg&{t&{j@RvDvBQ$y;7Gk zpYrb^d%zOrQ~t@vZNZ`tAK3%inNRumkUiiv<_Gns;; z`73*7!g8Z?{1Ee3Q-0L?bOg1J` zuGE(-U*{j!Lbox073CkNEAwe2(REWaM3IE zF!L$@9&!Y1#SyAhxo`5P%rcK`3rIcbUX8N?H^S`*D^n7|0rFl>q2}5JOZp_ zzHa}x=#{#I`MLIwTF1@I586LUSL*r@A9(~`#eCiVkw@TfGynbB`j0w>eS`Ty|3c|X zeI>-#?H^U)9%a7nzc^i~r;k;kF!bFSro6WTr-n7<)HKCpduF@JsJ0ciW|Wd4fv(B`AYF<Rln#Fwd@vBbQKh5%=h#cPUc^o zjXwq2f+Yq01Y`^LG5`HT@h2c#uxc1z0k+^R=3kQ+zXEK*O6Jq}ZGAT&?%e2L8S|sh zHk7xPM{^H5|GdWXXO_@U=Q0; zZpBYNF8=APKIrq`hW40qUCsfIGe78GxHUW;T7Q6kf%=15!*shoQ0qbIN*L~zd-##`Ab=SSRdI1oBPobrA>HGz?hFxJka0}*!)(2et zbM5{c%)jLl==gJ&?fd61u>6PC2VDE#9a0~>7%F-Fdw)DU7_^>7k`)Cf2ls;+Rq-_r}}`4 ze@|$Az{TIg>I2<>RfQWpDAmL2gZ3SVY{tty+lStt*2C(Lo}Z-S3vBVieBc&%tp33F zuk8b)r_VZP^(V+bu7&o5`M@pkSbams@3H!WZl672@dNYIW5=(@SFrxo!|EsHhkO{X zyf7b_pZi&TzPYMT&kn>;cQD=0>ZkT`SND}Vn#Hg0&qrOm(|hrY%n$N|Tf-Ma^Mms* zX7R5DUR%)ld4>5m(f-9<9U-6PNBg*|BT8)#i61w6OMXcFxY=8!o(YK`H#?@(gUk=w zKW+~{6Otd??3Gf_v-oxU!JS=`9}++A>{_W8h2wuwIR3pM@#D^3l-e5-Kkn>BfBuGf ze;U2NCW#w8kk8`RzOJjNC1U%)(S!bcFf%`I0^i%DbFfTZXS_dpU+;|@`!*h$i^@+Y z^Is+(r|Zw>G~<7{cMH@{Gkc7~&(_PaE@J zrucEu>(A#j+YjZx4A}#gFrV^IK5h#Zh4{!G(9V3ye;Kj|yw3bw{$F|=Q-Ss|Kgd5y zSL*vA{+5k6e<$;G{`Y`#qci+N=I81UY76!~m@9jmle*O8hX8im8@lQXj#`Q5@?_Zp*KcCi& ze;?%^>1UY#a_;~vH@f~TXa4@)hK|t=WEF z$>tx`hPE(2*uN-Ue?F}lzxMlpJ)npAy8Ymy*PqX6#{Y^xKF4jr{mc)J@3<|vC&b4^ zujdEM{OIF5E_(g>oTg9t_s9RJb!=sRFuq0UN^K7Dkw<`D=Iik@@(6G%^Mm8>6R;Y$ zhWYyVi_`VzGn?&4AAga4H}hZaeG--%ef+(h`MLUo+J?2v59$v}SM>R)X8yI`2iyZI znXl^)E_(g>sAl}R`h!}>&CCz#4@%dck7~xRePj<<#e7|VkUik9%s<@zF=sKqXMV2z zV|1l{9pdZukMiGSe$f6=x>D~l|8V=qtmBW&&$WMyuGDWseBJ(0{#(os+CNHH>MzXC z9e+`4IK=$m_>0n&`laO~v#-=a=Ii4xE_(g_2xk3!#h-t80(Oq^1oQR&#p(L{5zP4a z`{N(n_;wrf_fh_Fx>C0>KX?9%Izrya{NVf-r7Lx9h>slqtYE%A|HVbG)PFGl)$IHO zs*OI${9ym0bfvx=;_LjQ+UO(9*X;+VEA?&WznYzYK&|5&%n!y_C|!R(yjg#=kIet0 z%-7>LT=e?$;m!Cd|Ni^~Y8_88KNw%3bp848X8hXMM_^R@e~kHh{DwRNbgB;<_diVC zq|b_RON99Yb++AiqW&Jx(iV^Td*Wpl^u+n4e;!jC^S9S!?&P0uuj8i=GB0WAu>8Jq zPW7GG{kfM)(v@0l`JH!i$|e7&S$=m&{H5>T>zKcT^8e_a=H0_C@n35BedUh;{cD;3 za(tr|ziyvtzSH?mD)9Gm%YVR%-^EWde@7kVhkZVzOa2>}|8kt-XTD4Pt<2v``RD!D zr9RBH{0FS||HS#LKG#{|{_V2-rB?rSiT_l~UmX&E>Gg9Q^Mm$dCc~xuG%`PEKc?@} zey(8tPQU#>Y2?Ty{)x=j`PsuhJ;BAloca6w{$H-^%<`sJ>-@pD)oI;&%eK;4$Xw`rHZJ2eU){ZrBz)#r#wK_`6|S z&|bh_1KNU}%s(v~{~FL1EGg(`AX~7H`R^HuKLgo3?+rnlzT*kKtJahh2`+Nq- z$&Z-+e)8WLXRg7;Umi7mcz$d@j?Dk^m>GYNA9D>Z`8g2gvn_D(mzT-LzdRo1vHhSvp!`Dh0p!nT^`X%BLzOx{ zna+GYfB57)b3VXj|31$A;P`H?!O0J;Z$Q65eal~iOZ?OA`a|_CUw5l-kJ~;~2b@1W zto~4a%U^>_ejX3=*%r9?(+ku$RQ%KJ`s3F(l>fNx`}Gax7pQM2e<`aE==sV0%zv5A zUv6YGpt}8(y6k85NBevR*U4w~N7v7H#+hqy@t3mt0MC!@$C3G8%IZUqA9D>Z`Pm=l zvn_D(m$LeUj(;hu59s!@-}b5g0Q1l455-SDuKf>$)Q28+hlR`j9SErp{0=N9KeRrW zYjE*f?fzQ_&5!NJk$!7f{~c$p!6iQfVLsae7r!;MKH%bSwfip}UvTYb!1k&C;^H3& ztq-{PcZJl4Eg|EFQtyA*6;dDikbY==FxQ~lXQ}bewfirfznC|JxcIwlpGN;Ue{NX+ zrSq5kH8{l|=Cdtu@#lut2VDGf?f&bZzrgZi`~LY0%nz*(xc0w0q(0new4UJnz0~uI z-68eC9Q`=@q4mLBgKnRtE(`4b%SMNe@!LKdoxAx9!uszxa}T@ZXLp#-w!p<-5LzE_ z@h`CZFZBF$x9vmEFLsC42VDE#6H*_#*d5R=`*%-Bec*Q>I{BgX!CZrj-(~mTI%s}u zKaTXf!uszxa}6%}*%RioEpYL>LhA!A{w}-!QhmU+pFOru^#K?Ep3wS$i@%4}hrKkv zmp}H=$6c5G+r#RE_W7~g#rJGK4vnAHA3Z<$&Ny=moZ=7j*%mnYtp33FukEww-P(`G z>Q9h=a}T@Zrzgy3Tj1h*tiGY+_gMWwx6hui_<{N9vE!%u3EaP|eo}tO2ln4EADEvX zviiKU?x4PVpAU&2*?yi6i67a1UKEc1MdA4OhQx249l5p7y&>_N zXGd=SdKUk7st@Mq#L;K*Yu_B5xcL#=XQLB0|3Q|Y?D)j!!7lZok)2=Y`v>&htNHst zkIzfJew1MGn@2{zCyM_&&3vzee|kdkX8tQyGJglX|F?y`FUTeTYni{(_s#bxy7()Y z|1!Nlm&fmN{&ges_xZjVzl(o0^Mm}PjXmI!pViC{;x~Pl_%qB$e?L@;`RMlFBJ6hy z`)h=KPu)CObtIeh`C=klI1Z??Onwb<`8^Wilb3meonx1}jwtj0prZW;)W-Ftdi-@U z=D(vVpne(ib^JUAm%ro8*YUe})@xf-m1;}Q&K+;}#I0wz{g0W#{w(IZMQgwMB<7>@ zbF#31ny~*KVgGdI+k43E|IB7SdjFm(>wD_#$*MistVf-?{^$C!TT=2~?adeUJz+m0 z>_>(Dn6O_a?8k-ua$&zh*sm1!tAzb(VZTP$uNC&|g#CJ9KOyWl2>VH4e~hp{R@iS8 z_QwhP>nxYPZsv42>U5vf2y!QP1rw5*l!m0rwjW>3;V|i z`!j_7V}&;udsiPuz#+wpBDC8h5a^Re~z%FBkSN753jJ>|ZAA zUoPxlA?#l%>~{XEx{~BTcT4Db>VgCcd{`JEC2Zj9` zg#8Z*`)h>#8-@L~!v0Od{>{SvEyDhXh5e5R`?m`Fw+Z{V3;Q1x_U{n(KPK#dT-aYH z>}Q1i9$|mIu)jgr?-lkp3j3Rc{X2#IyM+C_h5dVk{Z9z{n}z**h5h@4{Z9(}eZu}0 zVgG(%|5L*LR$>1EVgEs4|I@<$L&E-Ng#CXI_CG7^KP>G3qp<%uVgK{O{x)I%5n=yP zVgC!l{$s-a5e-`%tMc98r*nd*k|Aw&t zufqOQ!u~gf{cj2T|0eAJyRiQs!v42~{r?p9pBDDNBkX@y*#9qKzhBrN5canV`#XgF zox=VuVgDIn|5;)GIbnadu>ZWU|2<*<`@;SU!v2fG{ttxxmxTR2!v0=i|7Br+pRm7Q z*ndUXe^uCjP1rvm?Eg^M|B{!fMdgTnqB!v34W{?CN{w}kz-h5erk z`@azOe<|$$O4$Fku>Tuj|F^>ae+&D+6ZZc{*gqufza#AbUfBPGu>VJ4|9^%3KMDJP z7WV%l?Ejyz|5suEZ^Hh&!v6mg_Wv&I4+{I9GC%+Sc2$x0@}5`fujQ6MsZ=WTb!C=c^T(kt`U!nSasRWz@`1^rP^xSnn*U1Mhvui+@>9hn zc!Xz1n7~{$J^Mw8R!u|qbf1$8{ zp0K}2*gs#`zd+c(P}uJj_Pd1r#lrqY!u}Frf2pv4v9N!Mu)j>$UoPxlD(t^c*uPBJ zzg*bALfF4j*zXqhR|xwnh5f69{Z+#LYGMCsVgLQY{x!n>wZi^&!u|(@{p*GO4+{G? z2>Txr_SXpeHwyb}h5eg^{hNjTTZH`&3;Q1t_HPyTZxi-!7xq6Y?B5~me@xi_xUj!Y z*v~NkJ`a0+u;22r*QbqyWEk9KpFv7DlmOo>JR}}YfzvZ_S2aNRW z2+#lNBfX-i$J5NG_X8L8`jMWTVg9$gH6y*GxW~P2(d%oTupbfjqr!en*e?_I^BPg`xN*j}-PN3;R=q{gkjjRoI^<>>nlUHw*jIh5e(2{bPjv8N&Xt!v1l>{_(>8 z3Bvw~!v0CZ{>j3Ai?Baa*qV`-y`gwF6^Hn?4K#@pC#;{E$qKn z*gr?uKUdgK3;V6Yew(mAN7!!{_U8)w9m4)RVSm1`zd+buDD0mn>@O1b&lmPD5cV$= z_B)0BE@6MMuz!)TzeLzyD(qh@>|Y}6FBA5c3;UM}`|lI>FBA4J7xu3Z_OBH7yM_G~ z!v0EO|0-dBm9W2B*uPrXf4{JQjj(^Muz#Jf{{dnDdSU;A!u}1y{)dG9HNyUl!v0!e z|0ZGoW?}ypVgJLz{zruUTZR4Gg#Fuv{f`R!cL@6*6ZStY?5`8{Gs1q4u)ki|-yrPw z3i}&{{Y}FDox=WI!v5XD{yoC}CxrdY!v4L&{(Zv!Cx!h!VSkITf4{K*DPe!Bu>XLt z|Ddq{X<`2%VgED2{yzx&pB45W7WV&9*#Dfc|9N45o3Q_gu>YvA{{>%#s&3;X{f>^~vwKPl{gL)iaUVgD&%|C_@8w}kzF z6ZZdI*#8e<|J%a;e+v6g3;W*@_P;Ca|Cg}eFYFHp``d;69m4)jVSksf|BSHztg!!_ zu)kZ_e_q)Cp0NLYVgChT|3zW{2g3eK!u}p%f3L9rvar8T*xxVgzas3vD(t@|>>m*J ze<^?%)c7!N11N!<<}GkjPUGA%g26yN|mr*ZTYDYwz#;5D=Z(|{u`Lz0q$Q(VSkL}W7|){ z^0D7fG}H32@y`v%J$@Z6>>q3S*!F*%uz!r@Hy3w+8sXW;TR!&t#hNX@2HHMnSU$G>XVmq^_jBRD z|Bm~>;-mMy$9?SaD{c9y5n5bv4`(bN+dlg(zoobUM|yUI=l}GPUQyKJ<*a=^10Ely zS^W6#*E92j{(ilTy4vW!pH)$>s05GjWKXR%`~zy^2(Kva;Ry48r0yvW7~$FF%>S8M zKf)`Dd$@x6l%Jn_u}E>qFwd^E{WrZToL|L!PxTBFP4N#^GasG*8s;AWx1U<(|44nZ z_#_PTiaO>WP+uPA*~LFp&wT1%KlhTj_LE@#0ksY4CoO;Dug^%};vd6&$`8~Z%lrfC zXlQ+IWWK+DYjF7)$9$@9ziR;Ie?0RkeyHEX`~&K%#do4%UU3BTb^Gz^aQUCWeCl6N z-&5yIRu?Cmt7#kc$lOzlf~`#}$VNmge{;@nLmX+MmY<>gHLG`GO40sZ-!P|h!`=-}CuCDYeY%FxG30mlrh=4}@^4+JkBh&; z^6$vj=k-17)tvN(?Hfu7d+0SO+b>fYy^0|}-RrOiYAyflT>PGU^h#A*K5IY8Si{i9 zmhem5@>%{PvF!GgfYVEkw0tA}zG$Oc{F5yI>@rv_Epzj0EPr!zI_SStKizxq zG|L~#f9rNY`#;L^b^a+uy8d)+PqndUKm|S4^0D!!)j~G@=?e-?W@GDu(n^l;s#eQ?Dd+dxnRZ`8TVdb3 z3*gVO{6x^dG8=pDRPJl=nEzx;XEr}~8hI@Bj|lhESzp~%Drvkf%KesH`=RU@&n)qe z2ydU=G1W)AAQOv}B}+8(Ue@n%|E010hqS-3XH$AXW>X^X$tC$Z;i-+?875XB}@63*W{P>+Kbi3te^Pk!1J?oqurRG|GHvih! z^}%k^Mg5f#o00e>tH2FC5MXwEy!g|8V{( ze&_s`G5^Wj@m*2tEUG1jKe^oUbM;O8?)9zG^82!Z=KI}^Lvp(zN(^=RQILc_G4-dmFWJvx8IX+_ZtfNs%jU)j~DVO{wk-LpJ3a^74j*5 zgdes2V8xlc-IGtk36{Sqrnc$vbN%*uKzbjE~!~9G(KV9zm887TlEadC_1L8kI*gx6wAC9R`+Q0YQo4z-F z-`={ZZu_`pI6qUj-_<|G^6xO`|0A*1n8SJeY|E$l=ivH+o;`Hbl{!_}Kh5%o@)OKI zJ8r>yhVlLRRY(7H%YQnT|J?ku(;CjOd~ANswEV;IXXkI7;y=ss566$l|Jk;mJ^vlL zzUFiYc(3K3o$~>+^Gcm#`9t~1&7M15A3WFc&(5{aAbuxZU&i6%b8LQEh5a_m*ZFTy z>G)9l$;9@?N*+hdv3#9>-w*Qdq$|~K`K`X(S96teVc&Qe(1c5j_*PK z_4U&&rDtEy&xH87%HFNZBS z&+>=zlRLgU=t^A>>gy7n*MA+xR~K5o&cE;H`mckoRE6bV7BrR2y`?r8<8_sm|8UMv zBi2x5`LE~s?rW&F{3WY8)q`+i>Ua#;gS zKC}7fea*ga^sds^Fvar6mia#GU8SxeW%*0qp6lnI_utaiFxB$6?(+SR-c`yPjY4hk7B=O5GZnG1mV@|KYSmnBUdz#91${XFfXq2IiyVk24<~|2XEO<4-XE!iYY+ z;Mz~j^8cqI0`$w6-_@>t+;SrGFN|R0Zxr^&3;Pq9kIw%Q!u~Yoquc*c!u~8_|77Oh zw{VWSa$`4|RaKA056>Xgv-MfW4_HHm<>&I>7}Qb66jfS&F8_^G-`tm~!amhE_odqMbNQ$E z0r{WL{Ji6@*9bVmEVTTgcP%y=oroijDO}?{^9)l707W5GHm?ssi%WZo7vaD)xGb`QPuHpN*k@Hh#7LCD%Q$X?Wi`KX-=u`u+;t zJ}G|JHCW@TJ96zG(E4e9!1jmQziaMwfRVyJp!F;IG)O)^zk}ir+7IPExTxolsaUA* zw}0i{`f2ih8nT0h-pIGpd=HYu;=p}yb#5v`x5!p!}9?W}D3hg5$>r_z@HSmg@Z zzmV!rcj<-r3j!a~{x^j9l`E+I==cHqw>Q-H^8;!B8$*3Ren|V@G@K8}&z+&ZzW)JI z{ncHeevto0rS+ zm(qx{3w@_QKfYw=H`3I49L6QNmnOO2Hsk|lACwxy{aLy5Uy2{FhA!q)|Dw)COM0uG zA$B}_RBG{XK45<1BFoR6|N8MepJDH@{p|d??>o<*?;XwuTmg95@*ir<`1AkS{5WpG zbC%zfyT0Hx0=V*}VzMQ1i821kc z;$7uw6?ezAa1TN4$=Ng_50;F#4H9^ki>s{-sw3H~O+AqH25C`B{|8yhxgV%7pSX#t zEjc?FG$?g8B(`G6@IBLg+U{xQrSW31i%k6K}W2J;); zLpFpuVgF3#k2lut{>NF&pWsd!LPFR-f%#L6wY&duqOgCGuz#|!-y-bK6!vEc`=q0E18cT|6I>}^!Vh1%twzOZe>3D_6IP=p=e>f6uDQA90^+Ej#<}39CE_jkEneVB6P``@#5%MPkFY;6~zez3g zZUA1Ss$o8T-i`Oqxr=RpOw}?!M){cr%ugNjRpbyL>cd1m_d)MV%&j58eQ58}_ouP? zU-1NV4N2|~eg9N$3*CN>vHTWb>r`qi_q{&vw4safZn5iEH!`1&H_%hyah8wmU*nmt z>w|k%4hwYrqOX`a{Qcef`f_G)UCUnv{VUls=#Rm{b(yI83;isAiuTOk>6g)mK=s-1 zrv_k31>oU8{NL^>+Nb(y_%nTfu+YsRRJn_bU!~|0aNhkP5sDnTOcnO03HwLM`f)YO z*uT2v<+aZfg65Qt1kLG>MYkVMy>(>%=M%Dh`#0D7IiiLA41IX>-&}_hu@U^y_f)p! z*+0t)`?MpJbAHqeYCn1R7pb1`I7GW``L)Yhq~$PquCz`FO@R?Pu^eahV}EFSol}+D+)eJ^)aqG zs)p{*?C>wJZBNf|E&SOv(gDfvRXTV8&M^IiSj*FSCijU?P)>vuPBQj-+#^cd%Ljlm$CSR`he`eEPix8pqJM(rART+cmdssu6+T|^7rdAI-9yhP)*}&rz_YfgY-UAkB=-D@u{%=? zF5yp4y=eL?E1vaKyBE7>>LkP=GQ#}y3hl=tDBn|u%=qE?p|`ji`B$6#{5IRUw*A{aGJa3}#K?cg+7wOE_ruy}g!_w|=&+TB`BCn#rAxxV_+#8(tf28LwW%Th W{fT|B%mlT{WBwMf-*Lr(YyLkNa!N`7 diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cmh.pkg b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/cancun/sdk_6.5.16/bcm56870_a0_cmh.pkg deleted file mode 100644 index 74e52b26c944ea51e2edcd05a1799843a640fced..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3808 zcmb`JONdBO7{|}WnDH8q@tPUWGIkb{$Ee9<#0V%lgm41QHEVL&$orV6q#ybg4EcP>T zU;PC?79-SsP`od~HzCu#7$ejc_oG4Me4$Bb6FP)l!Xe>=a7MTwToVu-kE<3a@m7^{ zFLq{bN}L^1~j>jej|Q7^AKfL(^ysVw=S3sFxAFAytRjV=< zq$lp8n#}b{WRF2TS z{^9eWw;HOYUskNwKFHkt!@ef!8Z(HE7*>Cq_D20Tr9-fxW8CvoISU=ZQ?$~~N)9Q2_N z=Y~G!W46$T9+2{>l#Tl4798s@yweuXa=}AKuOa6Crpz6Gr1?wVlMZUlo=nUy|6wy_ zF%rjwxCphFm_6K!or}dTpPB8`d~7c(6|}tna<3#GHoiyH(Wf4C`K;Hmwr6BExSx7_ zf6Di|)cc)o_q`V$92;-S&Kf&9(}(%Y_CNEH*I@6$solO`+gW3mu9@*hw|}n8L%!N< zE@l38@p(>VzV+x;C4RZ*&PwoG6MVjlvG{EXzOH7JzdFIUe=*yy)xRde=bIXBt!RH>u;%`Xs?cXhozcInL_budaO7Q95v3fQq`1Ir$e@lYTy^ZlZ i5`4Z_G5*#BpYK(Szb(P%e=o-0p5V`s{`K3%2mb)DAbgYn diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev.xml b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev.xml index 7438d26a39c7..66bc7a92f7fc 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev.xml +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev.xml @@ -7,130 +7,425 @@ --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev_exhaust.xml b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev_exhaust.xml new file mode 100644 index 000000000000..779bbeecd952 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/dev_exhaust.xml @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/fru.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/fru.py index 3f1bef50af25..f95164e03601 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/fru.py +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/fru.py @@ -1,15 +1,14 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- +#!/usr/bin/python3 import collections -from bitarray import bitarray from datetime import datetime, timedelta -import sys +from bitarray import bitarray + __DEBUG__ = "N" class FruException(Exception): - def __init__(self, message='fruerror', code=-100): + def __init__(self, message='fruerror', code=-100): err = 'errcode: {0} message:{1}'.format(code, message) Exception.__init__(self, err) self.code = code @@ -21,7 +20,7 @@ def e_print(err): def d_print(debug_info): - if(__DEBUG__ == "Y"): + if __DEBUG__ == "Y": print(debug_info) @@ -40,7 +39,7 @@ def minToData(): starttime = datetime(1996, 1, 1, 0, 0, 0) endtime = datetime.now() seconds = (endtime - starttime).total_seconds() - mins = seconds / 60 + mins = seconds // 60 m = int(round(mins)) return m @@ -50,7 +49,7 @@ def getTimeFormat(): @staticmethod def getTypeLength(value): - if value is None: + if value is None or len(value) == 0: return 0 a = bitarray(8) a.setall(False) @@ -62,8 +61,8 @@ def getTypeLength(value): @staticmethod def checksum(b): result = 0 - for i in range(len(b)): - result += ord(b[i]) + for item in b: + result += ord(item) return (0x100 - (result & 0xff)) & 0xff @@ -86,7 +85,6 @@ def __init__(self, name="", size=0, offset=0): self._size = size self._isPresent = False self._data = b'\x00' * size - self.__dataoffset = 0 @property def childList(self): @@ -141,6 +139,9 @@ class BoardInfoArea(BaseArea): _boardTime = None _fields = None _mfg_date = None + areaversion = None + _boardversion = None + _language = None def __str__(self): formatstr = "version : %x\n" \ @@ -227,7 +228,6 @@ def decodedata(self): index += templen + 1 d_print("decode fruFileId:%s" % self.fruFileId) - for i in range(1, 11): valtmp = "boardextra%d" % i if self.data[index] != chr(0xc1): @@ -239,6 +239,11 @@ def decodedata(self): else: break + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + def recalcute(self): d_print("boardInfoArea version:%x" % ord(self.boardversion)) d_print("boardInfoArea length:%d" % self.size) @@ -247,7 +252,7 @@ def recalcute(self): d_print("boardInfoArea mfg_date:%x" % self.mfg_date) self.data = chr(ord(self.boardversion)) + \ - chr(self.size / 8) + chr(self.language) + chr(self.size // 8) + chr(self.language) self.data += chr(self.mfg_date & 0xFF) self.data += chr((self.mfg_date >> 8) & 0xFF) @@ -280,9 +285,7 @@ def recalcute(self): valtmpval = getattr(self, valtmp) d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) self.data += chr(FruUtil.getTypeLength(valtmpval)) - if valtmpval is None: - pass - else: + if valtmpval is not None: self.data += valtmpval else: break @@ -290,14 +293,14 @@ def recalcute(self): self.data += chr(0xc1) if len(self.data) > (self.size - 1): - incr = (len(self.data) - self.size) / 8 + 1 + incr = (len(self.data) - self.size) // 8 + 1 self.size += incr * 8 - self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:] + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] d_print("self data:%d" % len(self.data)) d_print("self size:%d" % self.size) d_print("adjust size:%d" % (self.size - len(self.data) - 1)) - self.data = self.data.ljust((self.size - 1), self.INITVALUE) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) # checksum checksum = FruUtil.checksum(self.data) @@ -388,6 +391,7 @@ class ProductInfoArea(BaseArea): _productManufacturer = None _productAssetTag = None _FRUFileID = None + _language = None def __str__(self): formatstr = "version : %x\n" \ @@ -564,12 +568,17 @@ def fruFileId(self): def fruFileId(self, name): self._FRUFileID = name + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + def recalcute(self): d_print("product version:%x" % ord(self.areaversion)) d_print("product length:%d" % self.size) d_print("product language:%x" % self.language) self.data = chr(ord(self.areaversion)) + \ - chr(self.size / 8) + chr(self.language) + chr(self.size // 8) + chr(self.language) typelength = FruUtil.getTypeLength(self.productManufacturer) self.data += chr(typelength) @@ -600,22 +609,20 @@ def recalcute(self): valtmpval = getattr(self, valtmp) d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) self.data += chr(FruUtil.getTypeLength(valtmpval)) - if valtmpval is None: - pass - else: + if valtmpval is not None: self.data += valtmpval else: break self.data += chr(0xc1) if len(self.data) > (self.size - 1): - incr = (len(self.data) - self.size) / 8 + 1 + incr = (len(self.data) - self.size) // 8 + 1 self.size += incr * 8 d_print("self.data:%d" % len(self.data)) d_print("self.size:%d" % self.size) - self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:] - self.data = self.data.ljust((self.size - 1), self.INITVALUE) + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) checksum = FruUtil.checksum(self.data) d_print("board info checksum:%x" % checksum) self.data += chr(checksum) @@ -631,17 +638,13 @@ def __init__(self, fieldType="ASCII", fieldData=""): self.fieldData = fieldData self.fieldType = fieldType - @property - def data(self): - return self._data - @property def fieldType(self): - return self._fieldType + return self.fieldType @property def fieldData(self): - return self._fieldData + return self.fieldData class ipmifru(BaseArea): @@ -659,6 +662,7 @@ class ipmifru(BaseArea): _bodybin = None _version = BaseArea.COMMON_HEAD_VERSION _zeroCheckSum = None + _frusize = 256 def __str__(self): tmpstr = "" @@ -673,13 +677,13 @@ def __str__(self): def decodeBin(self, eeprom): commonHead = eeprom[0:8] d_print("decode version %x" % ord(commonHead[0])) - if self.COMMON_HEAD_VERSION != commonHead[0]: + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): raise FruException("HEAD VERSION error,not Fru format!", -10) if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): strtemp = "check header checksum error [cal:%02x data:%02x]" % ( FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) raise FruException(strtemp, -3) - if commonHead[1] != self.INITVALUE: + if ord(commonHead[1]) != ord(self.INITVALUE): d_print("Internal Use Area is present") self.internalUseArea = InternalUseArea( name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) @@ -687,7 +691,7 @@ def decodeBin(self, eeprom): self.internalUserAreaOffset = ord(commonHead[1]) self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( self.internalUserAreaOffset * 8 + self.internalUseArea.size)] - if commonHead[2] != self.INITVALUE: + if ord(commonHead[2]) != ord(self.INITVALUE): d_print("Chassis Info Area is present") self.chassisInfoArea = ChassisInfoArea( name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) @@ -695,7 +699,7 @@ def decodeBin(self, eeprom): self.chassicInfoAreaOffset = ord(commonHead[2]) self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] - if commonHead[3] != self.INITVALUE: + if ord(commonHead[3]) != ord(self.INITVALUE): self.boardInfoArea = BoardInfoArea( name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) self.boardInfoArea.isPresent = True @@ -707,12 +711,12 @@ def decodeBin(self, eeprom): self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): - print "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ (FruUtil.checksum( self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) - sys.exit(-1) + raise FruException(strtmp, -3) self.boardInfoArea.decodedata() - if commonHead[4] != self.INITVALUE: + if ord(commonHead[4]) != ord(self.INITVALUE): d_print("Product Info Area is present") self.productInfoArea = ProductInfoArea( name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) @@ -732,7 +736,7 @@ def decodeBin(self, eeprom): FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) raise FruException(strtmp, -3) self.productInfoArea.decodedata() - if commonHead[5] != self.INITVALUE: + if ord(commonHead[5]) != ord(self.INITVALUE): self.multiRecordArea = MultiRecordArea( name="MultiRecord record Area ") d_print("MultiRecord record present") @@ -748,7 +752,6 @@ def initDefault(self): self.boardInfoAreaOffset = self.INITVALUE self.productinfoAreaOffset = self.INITVALUE self.multiRecordAreaOffset = self.INITVALUE - self.PAD = self.INITVALUE self.zeroCheckSum = self.INITVALUE self.offset = self.SUGGESTED_SIZE_COMMON_HEADER self.productInfoArea = None @@ -874,30 +877,31 @@ def recalcuteCommonHead(self): self.bindata = "" self.offset = self.SUGGESTED_SIZE_COMMON_HEADER d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) if self.internalUseArea is not None and self.internalUseArea.isPresent: - self.internalUserAreaOffset = self.offset / 8 + self.internalUserAreaOffset = self.offset // 8 self.offset += self.internalUseArea.size d_print("internalUseArea is present offset:%d" % self.offset) if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: - self.chassicInfoAreaOffset = self.offset / 8 + self.chassicInfoAreaOffset = self.offset // 8 self.offset += self.chassisInfoArea.size d_print("chassisInfoArea is present offset:%d" % self.offset) if self.boardInfoArea is not None and self.boardInfoArea.isPresent: - self.boardInfoAreaOffset = self.offset / 8 + self.boardInfoAreaOffset = self.offset // 8 self.offset += self.boardInfoArea.size d_print("boardInfoArea is present offset:%d" % self.offset) d_print("boardInfoArea is present size:%d" % self.boardInfoArea.size) if self.productInfoArea is not None and self.productInfoArea.isPresent: - self.productinfoAreaOffset = self.offset / 8 + self.productinfoAreaOffset = self.offset // 8 self.offset += self.productInfoArea.size d_print("productInfoArea is present offset:%d" % self.offset) if self.multiRecordArea is not None and self.multiRecordArea.isPresent: - self.multiRecordAreaOffset = self.offset / 8 + self.multiRecordAreaOffset = self.offset // 8 d_print("multiRecordArea is present offset:%d" % self.offset) if self.internalUserAreaOffset == self.INITVALUE: @@ -914,16 +918,17 @@ def recalcuteCommonHead(self): self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff d_print("zerochecksum:%x" % self.zeroCheckSum) - self.data = self.version + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( - self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + self.INITVALUE + chr(self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) self.bindata = self.data + self.bodybin totallen = len(self.bindata) d_print("totallen %d" % totallen) - if (totallen < 256): - self.bindata = self.bindata.ljust(256, self.INITVALUE) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) else: - raise FruException('bin data more than 256', -2) + raise FruException('bin data more than %d' % self._frusize, -2) def recalcutebin(self): self.bodybin = "" @@ -945,6 +950,12 @@ def recalcutebin(self): d_print("multiRecordArea present") self.bodybin += self.productInfoArea.data - def recalcute(self): + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size self.recalcutebin() self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/installer.conf b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/installer.conf index df846113776d..5e62742c11bf 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/installer.conf +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/installer.conf @@ -1,2 +1 @@ CONSOLE_SPEED=115200 -ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_pstate=disable intel_idle.max_cstate=0 modprobe.blacklist=fpga_pcie_i2c" diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/minigraph.xml b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/minigraph.xml deleted file mode 100644 index d33d99d6e76f..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/minigraph.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - switch2 - - - - - - - - - - - - - switch2 - RA-B6510-32C - - - - - - - switch2 - - - DhcpResources - - - - - NtpResources - - 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org - - - SyslogResources - - - - - ErspanDestinationIpv4 - - 2.2.2.2 - - - - - - - switch2 - RA-B6510-32C - diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/monitor.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/monitor.py index ab4d14ec3daa..c50d6c248b5a 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/monitor.py +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/monitor.py @@ -1,5 +1,4 @@ -#!/usr/bin/python -# -*- coding: UTF-8 -*- +#!/usr/bin/python3 # * onboard temperature sensors # * FAN trays # * PSU @@ -7,97 +6,154 @@ import os import xml.etree.ElementTree as ET import glob -from fru import * -from fantlv import * - +import json +from decimal import Decimal +from fru import ipmifru MAILBOX_DIR = "/sys/bus/i2c/devices/" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + CONFIG_NAME = "dev.xml" + +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + return val + + +def get_board_id(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +boardid = get_board_id() +boardairflow = getboardairflow() + + +DEV_XML_FILE_LIST = [ + "dev_" + boardid + "_" + boardairflow + ".xml", + "dev_" + boardid + ".xml", + "dev_" + boardairflow + ".xml", +] + + +def dev_file_read(path, offset, read_len): + retval = "ERR" + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + return False, "%s %s not found" % (retval, path) + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, "%s %s" % (retval, msg) + finally: + if fd > 0: + os.close(fd) + return True, val_list + + def getPMCreg(location): retval = 'ERR' - if (not os.path.isfile(location)): - return "%s %s notfound"% (retval , location) + if not os.path.isfile(location): + return "%s %s notfound" % (retval, location) try: with open(location, 'r') as fd: retval = fd.read() except Exception as error: - pass + return "ERR %s" % str(error) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval + + # Get a mailbox register def get_pmc_register(reg_name): retval = 'ERR' - mb_reg_file = MAILBOX_DIR + reg_name + mb_reg_file = reg_name filepath = glob.glob(mb_reg_file) - if(len(filepath) == 0): - return "%s %s notfound"% (retval , mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) mb_reg_file = filepath[0] - if (not os.path.isfile(mb_reg_file)): - #print mb_reg_file, 'not found !' - return "%s %s notfound"% (retval , mb_reg_file) + if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' + return "%s %s notfound" % (retval, mb_reg_file) try: - with open(mb_reg_file, 'r') as fd: + with open(mb_reg_file, 'rb') as fd: retval = fd.read() + retval = typeTostr(retval) except Exception as error: - pass + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval + class checktype(): def __init__(self, test1): self.test1 = test1 + @staticmethod - def check(name,location, bit, value, tips , err1): - psu_status = int(get_pmc_register(location),16) - val = (psu_status & (1<< bit)) >> bit - if (val != value): - err1["errmsg"] = tips - err1["code"] = -1 - return -1 - else: - err1["errmsg"] = "none" - err1["code"] = 0 - return 0 - @staticmethod - def getValue(location, bit , type): - value_t = get_pmc_register(location) - if value_t.startswith("ERR") : + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) return value_t - if (type == 1): - return float(value_t)/1000 - elif (type == 2): - return float(value_t)/100 - elif (type == 3): - psu_status = int(value_t,16) - return (psu_status & (1<< bit)) >> bit - elif (type == 4): - return int(value_t,10) - elif (type == 5): - return float(value_t)/1000/1000 - else: - return value_t; -#######temp - @staticmethod - def getTemp(self, name, location , ret_t): - ret2 = self.getValue(location + "temp1_input" ," " ,1); - ret3 = self.getValue(location + "temp1_max" ," ", 1); - ret4 = self.getValue(location + "temp1_max_hyst" ," ", 1); - ret_t["temp1_input"] = ret2 - ret_t["temp1_max"] = ret3 - ret_t["temp1_max_hyst"] = ret4 - @staticmethod - def getLM75(name, location, result): - c1=checktype - r1={} - c1.getTemp(c1, name, location, r1) - result[name] = r1 -##########fanFRU + except Exception as e: + value_t = "ERR %s" % str(e) + return value_t + + # fanFRU @staticmethod def decodeBinByValue(retval): fru = ipmifru() @@ -105,67 +161,70 @@ def decodeBinByValue(retval): return fru @staticmethod - def printbinvalue(b): - index = 0 - print " ", - for width in range(16): - print "%02x " % width, - print "" - for i in range(0, len(b)): - if index % 16 == 0: - print " " - print " %02x " % i, - print "%02x " % ord(b[i]), - index += 1 - print "" - - @staticmethod - def getfruValue(val): + def getfruValue(prob_t, root, val): try: - binval = checktype.getValue(val, 0 , 0) - if binval.startswith("ERR"): - return binval + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) fanpro = {} ret = checktype.decodeBinByValue(binval) - fanpro['fan_type'] = ret.productInfoArea.productName - fanpro['hw_version'] = ret.productInfoArea.productVersion - fanpro['sn'] = ret.productInfoArea.productSerialNumber - fanpro['fanid'] = ret.productInfoArea.productextra2 + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = ret.productInfoArea.productVersion + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] return fanpro except Exception as error: return "ERR " + str(error) @staticmethod - def getslottlvValue(val): + def getslotfruValue(val): try: - binval = checktype.getValue(val, 0 , 0) + binval = checktype.getValue(val, 0, 0) if binval.startswith("ERR"): return binval slotpro = {} - slottlv = fan_tlv() - rets = slottlv.decode(binval) - if len(rets) == 0: - raise Exception("decode fan tlv fail") - slotpro['slot_type'] = slottlv.typename - slotpro['hw_version'] = slottlv.typehwinfo - slotpro['sn'] = slottlv.typesn - slotpro['slotid'] = slottlv.typedevtype + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber return slotpro except Exception as error: return "ERR " + str(error) @staticmethod - def getslotfruValue(val): + def getpsufruValue(prob_t, root, val): try: - binval = checktype.getValue(val, 0 , 0) + psu_match = False + binval = checktype.getValue(val, 0, 0) if binval.startswith("ERR"): return binval - slotpro = {} + psupro = {} ret = checktype.decodeBinByValue(binval) - slotpro['slot_type'] = ret.boardInfoArea.boardProductName - slotpro['hw_version'] = ret.boardInfoArea.boardextra1 - slotpro['sn'] = ret.boardInfoArea.boardSerialNumber - return slotpro + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name in psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro except Exception as error: return "ERR " + str(error) @@ -178,120 +237,139 @@ def __init__(self, productname): def getETroot(filename): tree = ET.parse(filename) root = tree.getroot() - return root; + return root @staticmethod def getDecodValue(collection, decode): decodes = collection.find('decode') testdecode = decodes.find(decode) - test={} + test = {} + if testdecode is None: + return test for neighbor in testdecode.iter('code'): - test[neighbor.attrib["key"]]=neighbor.attrib["value"] + test[neighbor.attrib["key"]] = neighbor.attrib["value"] return test + @staticmethod def getfileValue(location): - return checktype.getValue(location," "," ") + return checktype.getValue(location, " ", " ") + @staticmethod def getETValue(a, filename, tagname): root = status.getETroot(filename) for neighbor in root.iter(tagname): prob_t = {} prob_t = neighbor.attrib - prob_t['errcode']= 0 + prob_t['errcode'] = 0 prob_t['errmsg'] = '' for pros in neighbor.iter("property"): - ret = dict(neighbor.attrib.items() + pros.attrib.items()) + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) if ret.get('e2type') == 'fru' and ret.get("name") == "fru": - fruval = checktype.getfruValue(ret["location"]) - if isinstance(fruval, str) and fruval.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= fruval - else: - prob_t.update(fruval) - if ret.get("name") == "slot" and ret.get('e2type') == 'tlv': - slotval = checktype.getslottlvValue(ret["location"]) - if isinstance(slotval, str) and slotval.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= slotval - else: - prob_t.update(slotval) - if ret.get("name") == "slot" and ret.get('e2type') == 'fru': - slotval = checktype.getslotfruValue(ret["location"]) - if isinstance(slotval, str) and slotval.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= slotval - else: - prob_t.update(slotval) - - if ('type' not in ret.keys()): - val = "0"; + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break + prob_t.update(fruval) + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): + val = "0" else: val = ret["type"] - if ('bit' not in ret.keys()): - bit = "0"; + if 'bit' not in ret.keys(): + bit = "0" else: bit = ret["bit"] - s = checktype.getValue(ret["location"], int(bit),int(val)) - if isinstance(s, str) and s.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= s - if ('default' in ret.keys()): - rt = status.getDecodValue(root,ret['decode']) - prob_t['errmsg']= rt[str(s)] + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) + if isinstance(s, str) and s.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] if str(s) != ret["default"]: - prob_t['errcode']= -1 - break; + prob_t['errcode'] = -1 + break else: - if ('decode' in ret.keys()): - rt = status.getDecodValue(root,ret['decode']) - if(ret['decode'] == "psutype" and s.replace("\x00","").rstrip() not in rt.keys()): - prob_t['errcode']= -1 - prob_t['errmsg'] = '%s'% ("Not supported PSU type") + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) else: - s = rt[str(s).replace("\x00","").rstrip()] + s = rt[str(s).replace("\x00", "").rstrip()] name = ret["name"] - prob_t[name]=str(s) + prob_t[name] = str(s) a.append(prob_t) + @staticmethod def getCPUValue(a, filename, tagname): root = status.getETroot(filename) for neighbor in root.iter(tagname): - location = neighbor.attrib["location"] - L=[] + location = neighbor.attrib["location"] + L = [] for dirpath, dirnames, filenames in os.walk(location): - for file in filenames : + for file in filenames: if file.endswith("input"): L.append(os.path.join(dirpath, file)) - L =sorted(L,reverse=False) + L = sorted(L, reverse=False) for i in range(len(L)): prob_t = {} - prob_t["name"] = getPMCreg("%s/temp%d_label"%(location,i+1)) - prob_t["temp"] = float(getPMCreg("%s/temp%d_input"%(location,i+1)))/1000 - prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm"%(location,i+1)))/1000 - prob_t["crit"] = float(getPMCreg("%s/temp%d_crit"%(location,i+1)))/1000 - prob_t["max"] = float(getPMCreg("%s/temp%d_max"%(location,i+1)))/1000 + prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 + prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 a.append(prob_t) @staticmethod def getFileName(): - return os.path.dirname(os.path.realpath(__file__)) + "/"+ CONFIG_NAME - @staticmethod - def getFan(ret): - _filename = status.getFileName() - _tagname = "fan" - status.getvalue(ret, _filename, _tagname) + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME + @staticmethod def checkFan(ret): _filename = status.getFileName() # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "fan" status.getETValue(ret, _filename, _tagname) + @staticmethod def getTemp(ret): _filename = status.getFileName() - #_filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "temp" status.getETValue(ret, _filename, _tagname) + @staticmethod def getPsu(ret): _filename = status.getFileName() @@ -306,10 +384,19 @@ def getcputemp(ret): status.getCPUValue(ret, _filename, _tagname) @staticmethod - def checkSlot(ret): + def getDcdc(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() - _tagname = "slot" + _tagname = "dcdc" status.getETValue(ret, _filename, _tagname) + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + @staticmethod + def getmacpower(ret): + _filename = status.getFileName() + _tagname = "macpower" + status.getETValue(ret, _filename, _tagname) diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pcie.yaml b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pcie.yaml new file mode 100644 index 000000000000..ab6315b6f5e2 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pcie.yaml @@ -0,0 +1,440 @@ +- 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: '01' + fn: '1' + id: 6f03 + 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: '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: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: '16' + fn: '0' + id: 8c3a + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #1 (rev 04)' +- bus: '00' + dev: '16' + fn: '1' + id: 8c3b + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #2 (rev 04)' +- 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: 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: '01' + dev: '00' + fn: '0' + id: b870 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b870 (rev 01)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '04' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '04' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '07' + dev: '00' + fn: '0' + id: '1537' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Backplane Connection + (rev 03)' +- bus: 08 + dev: '00' + fn: '0' + id: '7022' + name: 'Memory controller: Xilinx Corporation Device 7022' +- 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: 0c + fn: '2' + id: 6fe2 + 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: '3' + id: 6fe3 + 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/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf/pd-plugin.json b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf/pd-plugin.json deleted file mode 100644 index ffa06ff74303..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf/pd-plugin.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "XCVR": { - "xcvr_present": { - "i2c": { - "valmap-SFP28": { - "1": true, - "0": false - }, - "valmap-QSFP28": { - "1": true, - "0": false - } - } - } - }, - - "PSU": { - "psu_present": { - "i2c": { - "valmap": { - "1": true, - "0": false - } - } - }, - - "psu_power_good": { - "i2c": { - "valmap": { - "1": true, - "0": false - } - } - }, - - "psu_fan_dir": { - "i2c": { - "valmap": { - "F2B": "EXHAUST", - "B2F": "INTAKE" - } - } - }, - "PSU_FAN_MAX_SPEED": "18000" - }, - - "FAN": { - "direction": { - "i2c": { - "valmap": { - "1": "INTAKE", - "0": "EXHAUST" - } - } - }, - "present": { - "i2c": { - "valmap": { - "1": true, - "0": false - } - } - }, - "duty_cycle_to_pwm": "lambda dc: dc*255/100", - "pwm_to_duty_cycle": "lambda pwm: pwm*100/255" - } -} diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf/pddf-device.json b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf/pddf-device.json deleted file mode 100755 index 0f337006edad..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf/pddf-device.json +++ /dev/null @@ -1,4471 +0,0 @@ -{ - "PLATFORM": { - "num_psus": 2, - "num_fantrays": 5, - "num_fans_pertray": 2, - "num_ports": 32, - "num_temps": 5, - "pddf_dev_types": { - "description": "RA-B6510-32C", - "CPLD": [ - "i2c_cpld" - ], - "PSU": [ - "psu_eeprom", - "psu_pmbus" - ], - "FAN": [ - "fan_ctrl", - "fan_cpld", - "fan_eeprom" - ], - "PORT_MODULE": [ - "pddf_xcvr", - "optoe1", - "optoe2" - ] - }, - "std_kos": [ - "i2c-i801", - "i2c_dev", - "rg_i2c_gpio", - "rg_i2c_algo_bit", - "i2c_mux", - "rg_gpio_xeon", - "i2c_mux_pca9641", - "i2c_mux_pca954x force_create_bus=1", - "ragile_common dfd_my_type=0x404b", - "fpga_pcie_i2c ocore_ctl_startbus=2", - "lpc_dbg", - "fpga_i2c_ocores", - "rg_lpc_cpld", - "lm75", - "optoe", - "at24", - "pmbus_core" - ], - "pddf_kos": [ - "pddf_client_module", - "pddf_cpld_module", - "pddf_cpld_driver", - "pddf_mux_module", - "pddf_xcvr_module", - "pddf_xcvr_driver_module", - "pddf_psu_driver_module", - "pddf_psu_module", - "pddf_fan_driver_module", - "pddf_fan_module", - "pddf_sysstatus_module" - ], - "custom_kos": [ - "pddf_custom_psu", - "pddf_custom_led_module" - ] - - }, - - "SYSTEM": { - "dev_info": { - "device_type": "CPU", - "device_name": "ROOT_COMPLEX", - "device_parent": null - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-0", - "dev": "SMBUS0" - }, { - "dev_name": "i2c-1", - "dev": "I2C-GPIO0" - }, { - "dev_name": "i2c-2", - "dev": "FPGA-OCORE0" - }, { - "dev_name": "i2c-3", - "dev": "FPGA-OCORE1" - },{ - "dev_name": "i2c-4", - "dev": "FPGA-OCORE2" - },{ - "dev_name": "i2c-5", - "dev": "FPGA-OCORE3" - },{ - "dev_name": "i2c-6", - "dev": "FPGA-OCORE4" - },{ - "dev_name": "i2c-7", - "dev": "FPGA-OCORE5" - },{ - "dev_name": "i2c-8", - "dev": "FPGA-OCORE6" - },{ - "dev_name": "i2c-9", - "dev": "FPGA-OCORE7" - },{ - "dev_name": "i2c-10", - "dev": "FPGA-OCORE8" - },{ - "dev_name": "i2c-11", - "dev": "FPGA-OCORE9" - },{ - "dev_name": "i2c-12", - "dev": "FPGA-OCORE10" - },{ - "dev_name": "i2c-13", - "dev": "FPGA-OCORE11" - },{ - "dev_name": "i2c-14", - "dev": "FPGA-OCORE12" - },{ - "dev_name": "i2c-15", - "dev": "FPGA-OCORE13" - }] - } - }, - - "SMBUS0": { - "dev_info": { - "device_type": "SMBUS", - "device_name": "SMBUS0", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x0" - }, - "DEVICES": [] - } - }, - - "I2C-GPIO0": { - "dev_info": { - "device_type": "I2C-GPIO", - "device_name": "I2C-GPIO0", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x1" - }, - "DEVICES": [{ - "dev": "EEPROM1" - } - ] - } - }, - - "EEPROM1": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "EEPROM1", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x56", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FPGA-OCORE0": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE0", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x2" - }, - "DEVICES": [ - { - "dev": "FAN-CTRL" - }, { - "dev": "MUX0" - } - ] - } - }, - - "FAN-CTRL": { - "dev_info": { - "device_type": "FAN", - "device_name": "FAN-CTRL", - "device_parent": "FPGA-OCORE0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x0d", - "dev_type": "fan_cpld" - }, - "dev_attr": { - "num_fantrays": "5" - }, - "attr_list": [{ - "attr_name": "fan1_present", - "attr_offset": "0x30", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan2_present", - "attr_offset": "0x30", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan3_present", - "attr_offset": "0x30", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan4_present", - "attr_offset": "0x30", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan5_present", - "attr_offset": "0x30", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan6_present", - "attr_offset": "0x30", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan7_present", - "attr_offset": "0x30", - "attr_mask": "0x8", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan8_present", - "attr_offset": "0x30", - "attr_mask": "0x8", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan9_present", - "attr_offset": "0x30", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan10_present", - "attr_offset": "0x30", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan1_input", - "attr_offset": "0x1b", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan2_input", - "attr_offset": "0x25", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan3_input", - "attr_offset": "0x1d", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan4_input", - "attr_offset": "0x27", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan5_input", - "attr_offset": "0x1f", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan6_input", - "attr_offset": "0x29", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan7_input", - "attr_offset": "0x21", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan8_input", - "attr_offset": "0x2b", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan9_input", - "attr_offset": "0x23", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan10_input", - "attr_offset": "0x2d", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan1_pwm", - "attr_offset": "0x14", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan2_pwm", - "attr_offset": "0x14", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan3_pwm", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan4_pwm", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan5_pwm", - "attr_offset": "0x16", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan6_pwm", - "attr_offset": "0x16", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan7_pwm", - "attr_offset": "0x17", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan8_pwm", - "attr_offset": "0x17", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan9_pwm", - "attr_offset": "0x18", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan10_pwm", - "attr_offset": "0x18", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan1_fault", - "attr_offset": "0x31", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan2_fault", - "attr_offset": "0x31", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan3_fault", - "attr_offset": "0x31", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan4_fault", - "attr_offset": "0x31", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan5_fault", - "attr_offset": "0x31", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan6_fault", - "attr_offset": "0x31", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan7_fault", - "attr_offset": "0x31", - "attr_mask": "0x8", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan8_fault", - "attr_offset": "0x31", - "attr_mask": "0x8", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan9_fault", - "attr_offset": "0x31", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan10_fault", - "attr_offset": "0x31", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - } - ] - } - }, - - "MUX0": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX0", - "device_parent": "FPGA-OCORE0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x10" - }, - "channel": [{ - "chn": "0", - "dev": "FAN1-EEPROM" - }, - { - "chn": "1", - "dev": "FAN2-EEPROM" - }, - { - "chn": "2", - "dev": "FAN3-EEPROM" - }, - { - "chn": "3", - "dev": "FAN4-EEPROM" - }, - { - "chn": "4", - "dev": "FAN5-EEPROM" - } - ] - } - }, - - "FAN1-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN1-EEPROM", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x10", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN2-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN2-EEPROM", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x11", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN3-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN3-EEPROM", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x12", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN4-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN4-EEPROM", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x13", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN5-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN5-EEPROM", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x14", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FPGA-OCORE1": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE1", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x3" - }, - "DEVICES": [ - { - "dev": "TEMP1" - }, - { - "dev": "TEMP2" - }, - { - "dev": "TEMP3" - }, - { - "dev": "TEMP4" - }, - { - "dev": "TEMP5" - } - ] - } - }, - - "TEMP1": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "TEMP-MAC-INLET-R", - "device_parent": "FPGA-OCORE1" - }, - "dev_attr": { - "display_name": "Temp_MAC_INLET_R" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "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": "TEMP-MAC-INLET-F", - "device_parent": "FPGA-OCORE1" - }, - "dev_attr": { - "display_name": "Temp_MAC_INLET_F" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "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": "TEMP-MAC-INLET-B", - "device_parent": "FPGA-OCORE1" - }, - "dev_attr": { - "display_name": "Temp_MAC_INLET_B" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "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": "TEMP-MAC-INLET-L", - "device_parent": "FPGA-OCORE1" - }, - "dev_attr": { - "display_name": "Temp_MAC_INLET_L" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x4b", - "dev_type": "lm75" - }, - "attr_list": [{ - "attr_name": "temp1_high_threshold", - "drv_attr_name": "temp1_max" - }, - { - "attr_name": "temp1_max_hyst" - }, - { - "attr_name": "temp1_input" - } - ] - } - }, - - "TEMP5": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "TEMP-CPU-BOARD", - "device_parent": "FPGA-OCORE1" - }, - "dev_attr": { - "display_name": "Temp_CPU_BOARD" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x4c", - "dev_type": "lm75" - }, - "attr_list": [{ - "attr_name": "temp1_high_threshold", - "drv_attr_name": "temp1_max" - }, - { - "attr_name": "temp1_max_hyst" - }, - { - "attr_name": "temp1_input" - } - ] - } - }, - - "FPGA-OCORE2": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE2", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x4" - }, - "DEVICES": [ - { - "dev": "MUX1" - } - ] - } - }, - - "MUX1": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX1", - "device_parent": "FPGA-OCORE2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x18" - }, - "channel": [{ - "chn": "0", - "dev": "PSU1" - }, - { - "chn": "1", - "dev": "PSU2" - } - ] - } - }, - - "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" - }, - { - "itf": "eeprom", - "dev": "PSU1-EEPROM" - } - ] - } - }, - - "PSU1-PMBUS": { - "dev_info": { - "device_type": "PSU-PMBUS", - "device_name": "PSU1-PMBUS", - "device_parent": "MUX1", - "virt_parent": "PSU1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x18", - "dev_addr": "0x58", - "dev_type": "psu_pmbus" - }, - "attr_list": [{ - "attr_name": "psu_present", - "attr_devtype": "io", - "attr_offset": "0x951", - "attr_mask": "0x1", - "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": "12" - }, - { - "attr_name": "psu_power_good", - "attr_devtype": "io", - "attr_offset": "0x951", - "attr_mask": "0x2", - "attr_cmpval": "0x2", - "attr_len": "1" - }, - { - "attr_name": "psu_mfr_id", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0x99", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "10" - }, - { - "attr_name": "psu_fan_dir", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0xc3", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "5" - }, - { - "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_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" - } - ] - } - }, - - "PSU1-EEPROM": { - "dev_info": { - "device_type": "PSU-EEPROM", - "device_name": "PSU1-EEPROM", - "device_parent": "MUX1", - "virt_parent": "PSU1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x18", - "dev_addr": "0x50", - "dev_type": "psu_eeprom" - }, - "attr_list": [{ - "attr_name": "psu_serial_num", - "attr_devaddr": "0x50", - "attr_devtype": "eeprom", - "attr_offset": "0x38", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "20" - }] - } - }, - - "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" - }, - { - "itf": "eeprom", - "dev": "PSU2-EEPROM" - } - ] - } - }, - - "PSU2-PMBUS": { - "dev_info": { - "device_type": "PSU-PMBUS", - "device_name": "PSU2-PMBUS", - "device_parent": "MUX1", - "virt_parent": "PSU2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x19", - "dev_addr": "0x58", - "dev_type": "psu_pmbus" - }, - "attr_list": [{ - "attr_name": "psu_present", - "attr_devtype": "io", - "attr_offset": "0x951", - "attr_mask": "0x10", - "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": "12" - }, - { - "attr_name": "psu_power_good", - "attr_devtype": "io", - "attr_offset": "0x951", - "attr_mask": "0x20", - "attr_cmpval": "0x20", - "attr_len": "1" - }, - { - "attr_name": "psu_mfr_id", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0x99", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "10" - }, - { - "attr_name": "psu_fan_dir", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0xc3", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "5" - }, - { - "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_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-EEPROM": { - "dev_info": { - "device_type": "PSU-EEPROM", - "device_name": "PSU2-EEPROM", - "device_parent": "MUX1", - "virt_parent": "PSU2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x19", - "dev_addr": "0x50", - "dev_type": "psu_eeprom" - }, - "attr_list": [{ - "attr_name": "psu_serial_num", - "attr_devaddr": "0x50", - "attr_devtype": "eeprom", - "attr_offset": "0x38", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "20" - }] - } - }, - - "FPGA-OCORE3": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE3", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x5" - }, - "DEVICES": [ - { - "dev": "EEPROM2" - } - ] - } - }, - - "EEPROM2": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "MAC-EEPROM", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x51", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FPGA-OCORE4": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE4", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x6" - }, - "DEVICES": [ - { - "dev": "CPU_BOARD_CPLD" - } - ] - } - }, - - "CPU_BOARD_CPLD": { - "dev_info": { - "device_type": "CPLD", - "device_name": "CPU_BOARD_CPLD", - "device_parent": "FPGA-OCORE4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x0d", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "FPGA-OCORE5": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE5", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x7" - }, - "DEVICES": [] - } - }, - - "FPGA-OCORE6": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE6", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x8" - }, - "DEVICES": [ - { - "dev": "MAC_BOARD_CPLD1" - }, { - "dev": "MAC_BOARD_CPLD2" - } - ] - } - }, - - "MAC_BOARD_CPLD1": { - "dev_info": { - "device_type": "CPLD", - "device_name": "MAC_BOARD_CPLD1", - "device_parent": "FPGA-OCORE6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8", - "dev_addr": "0x30", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "MAC_BOARD_CPLD2": { - "dev_info": { - "device_type": "CPLD", - "device_name": "MAC_BOARD_CPLD2", - "device_parent": "FPGA-OCORE6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8", - "dev_addr": "0x31", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "FPGA-OCORE7": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE7", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x9" - }, - "DEVICES": [] - } - }, - - "FPGA-OCORE8": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE8", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0xa" - }, - "DEVICES": [] - } - }, - - "FPGA-OCORE9": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE9", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0xb" - }, - "DEVICES": [] - } - }, - - "FPGA-OCORE10": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE10", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0xc" - }, - "DEVICES": [ - { - "dev": "PORT-MUX0" - }, - { - "dev": "PORT-MUX1" - }, - { - "dev": "PORT-MUX2" - }, - { - "dev": "PORT-MUX3" - } - ] - } - }, - - "PORT-MUX0": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX0", - "device_parent": "FPGA-OCORE10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc", - "dev_addr": "0x70", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x20" - }, - "channel": [{ - "chn": "0", - "dev": "PORT1" - }, - { - "chn": "1", - "dev": "PORT2" - }, - { - "chn": "2", - "dev": "PORT3" - }, - { - "chn": "3", - "dev": "PORT4" - }, - { - "chn": "4", - "dev": "PORT5" - }, - { - "chn": "5", - "dev": "PORT6" - }, - { - "chn": "6", - "dev": "PORT7" - }, - { - "chn": "7", - "dev": "PORT8" - } - ] - } - }, - - "PORT-MUX1": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX1", - "device_parent": "FPGA-OCORE10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc", - "dev_addr": "0x71", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x28" - }, - "channel": [{ - "chn": "0", - "dev": "PORT9" - }, - { - "chn": "1", - "dev": "PORT10" - }, - { - "chn": "2", - "dev": "PORT11" - }, - { - "chn": "3", - "dev": "PORT12" - }, - { - "chn": "4", - "dev": "PORT13" - }, - { - "chn": "5", - "dev": "PORT14" - }, - { - "chn": "6", - "dev": "PORT15" - }, - { - "chn": "7", - "dev": "PORT16" - } - ] - } - }, - - "PORT-MUX2": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX2", - "device_parent": "FPGA-OCORE10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc", - "dev_addr": "0x72", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x30" - }, - "channel": [{ - "chn": "0", - "dev": "PORT17" - }, - { - "chn": "1", - "dev": "PORT18" - }, - { - "chn": "2", - "dev": "PORT19" - }, - { - "chn": "3", - "dev": "PORT20" - }, - { - "chn": "4", - "dev": "PORT21" - }, - { - "chn": "5", - "dev": "PORT22" - }, - { - "chn": "6", - "dev": "PORT23" - }, - { - "chn": "7", - "dev": "PORT24" - } - ] - } - }, - - "PORT-MUX3": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX3", - "device_parent": "FPGA-OCORE10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc", - "dev_addr": "0x73", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x38" - }, - "channel": [{ - "chn": "0", - "dev": "PORT25" - }, - { - "chn": "1", - "dev": "PORT26" - }, - { - "chn": "2", - "dev": "PORT27" - }, - { - "chn": "3", - "dev": "PORT28" - }, - { - "chn": "4", - "dev": "PORT29" - }, - { - "chn": "5", - "dev": "PORT30" - }, - { - "chn": "6", - "dev": "PORT31" - }, - { - "chn": "7", - "dev": "PORT32" - } - ] - } - }, - - "PORT1": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT1", - "device_parent": "PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "1" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT1-EEPROM" - }, { - "itf": "control", - "dev": "PORT1-CTRL" - }] - } - }, - - "PORT1-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT1-EEPROM", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x20", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT1-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT1-CTRL", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x20", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT2": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT2", - "device_parent": "PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "2" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT2-EEPROM" - }, { - "itf": "control", - "dev": "PORT2-CTRL" - }] - } - }, - - "PORT2-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT2-EEPROM", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x21", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT2-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT2-CTRL", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x21", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT3": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT3", - "device_parent": "PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "3" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT3-EEPROM" - }, { - "itf": "control", - "dev": "PORT3-CTRL" - }] - } - }, - - "PORT3-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT3-EEPROM", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x22", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT3-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT3-CTRL", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x22", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT4": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT4", - "device_parent": "PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "4" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT4-EEPROM" - }, { - "itf": "control", - "dev": "PORT4-CTRL" - }] - } - }, - - "PORT4-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT4-EEPROM", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x23", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT4-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT4-CTRL", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x23", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT5": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT5", - "device_parent": "PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "5" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT5-EEPROM" - }, { - "itf": "control", - "dev": "PORT5-CTRL" - }] - } - }, - - "PORT5-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT5-EEPROM", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT5" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x24", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT5-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT5-CTRL", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT5" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x24", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT6": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT6", - "device_parent": "PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "6" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT6-EEPROM" - }, { - "itf": "control", - "dev": "PORT6-CTRL" - }] - } - }, - - "PORT6-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT6-EEPROM", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x25", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT6-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT6-CTRL", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x25", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT7": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT7", - "device_parent": "PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "7" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT7-EEPROM" - }, { - "itf": "control", - "dev": "PORT7-CTRL" - }] - } - }, - - "PORT7-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT7-EEPROM", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x26", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT7-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT7-CTRL", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x26", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT8": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT8", - "device_parent": "PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "8" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT8-EEPROM" - }, { - "itf": "control", - "dev": "PORT8-CTRL" - }] - } - }, - - "PORT8-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT8-EEPROM", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT8" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x27", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT8-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT8-CTRL", - "device_parent": "PORT-MUX0", - "virt_parent": "PORT8" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x27", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT9": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT9", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "9" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT9-EEPROM" - }, { - "itf": "control", - "dev": "PORT9-CTRL" - }] - } - }, - - "PORT9-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT9-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT9" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x28", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT9-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT9-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT9" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x28", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT10": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT10", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "10" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT10-EEPROM" - }, { - "itf": "control", - "dev": "PORT10-CTRL" - }] - } - }, - - "PORT10-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT10-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x29", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT10-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT10-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x29", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT11": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT11", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "11" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT11-EEPROM" - }, { - "itf": "control", - "dev": "PORT11-CTRL" - }] - } - }, - - "PORT11-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT11-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT11" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2a", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT11-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT11-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT11" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT12": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT12", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "12" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT12-EEPROM" - }, { - "itf": "control", - "dev": "PORT12-CTRL" - }] - } - }, - - "PORT12-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT12-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT12" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2b", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT12-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT12-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT12" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT13": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT13", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "13" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT13-EEPROM" - }, { - "itf": "control", - "dev": "PORT13-CTRL" - }] - } - }, - - "PORT13-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT13-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT13" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2c", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT13-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT13-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT13" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT14": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT14", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "14" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT14-EEPROM" - }, { - "itf": "control", - "dev": "PORT14-CTRL" - }] - } - }, - - "PORT14-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT14-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT14" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2d", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT14-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT14-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT14" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT15": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT15", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "15" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT15-EEPROM" - }, { - "itf": "control", - "dev": "PORT15-CTRL" - }] - } - }, - - "PORT15-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT15-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT15" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2e", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT15-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT15-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT15" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT16": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT16", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "16" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT16-EEPROM" - }, { - "itf": "control", - "dev": "PORT16-CTRL" - }] - } - }, - - "PORT16-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT16-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT16" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2f", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT16-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT16-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT16" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT17": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT17", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "17" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT17-EEPROM" - }, { - "itf": "control", - "dev": "PORT17-CTRL" - }] - } - }, - - "PORT17-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT17-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT17" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x30", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT17-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT17-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT17" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x30", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT18": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT18", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "18" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT18-EEPROM" - }, { - "itf": "control", - "dev": "PORT18-CTRL" - }] - } - }, - - "PORT18-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT18-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT18" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x31", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT18-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT18-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT18" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x31", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT19": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT19", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "19" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT19-EEPROM" - }, { - "itf": "control", - "dev": "PORT19-CTRL" - }] - } - }, - - "PORT19-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT19-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT19" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x32", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT19-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT19-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT19" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x32", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT20": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT20", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "20" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT20-EEPROM" - }, { - "itf": "control", - "dev": "PORT20-CTRL" - }] - } - }, - - "PORT20-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT20-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT20" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x33", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT20-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT20-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT20" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x33", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT21": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT21", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "21" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT21-EEPROM" - }, { - "itf": "control", - "dev": "PORT21-CTRL" - }] - } - }, - - "PORT21-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT21-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT21" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x34", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT21-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT21-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT21" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x34", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT22": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT22", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "22" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT22-EEPROM" - }, { - "itf": "control", - "dev": "PORT22-CTRL" - }] - } - }, - - "PORT22-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT22-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT22" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x35", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT22-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT22-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT22" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x35", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT23": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT23", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "23" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT23-EEPROM" - }, { - "itf": "control", - "dev": "PORT23-CTRL" - }] - } - }, - - "PORT23-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT23-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT23" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x36", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT23-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT23-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT23" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x36", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT24": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT24", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "24" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT24-EEPROM" - }, { - "itf": "control", - "dev": "PORT24-CTRL" - }] - } - }, - - "PORT24-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT24-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT24" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x37", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT24-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT24-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT24" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x37", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT25": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT25", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "25" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT25-EEPROM" - }, { - "itf": "control", - "dev": "PORT25-CTRL" - }] - } - }, - - "PORT25-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT25-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT25" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x38", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT25-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT25-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT25" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x38", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT26": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT26", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "26" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT26-EEPROM" - }, { - "itf": "control", - "dev": "PORT26-CTRL" - }] - } - }, - - "PORT26-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT26-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT26" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x39", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT26-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT26-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT26" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x39", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT27": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT27", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "27" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT27-EEPROM" - }, { - "itf": "control", - "dev": "PORT27-CTRL" - }] - } - }, - - "PORT27-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT27-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT27" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3a", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT27-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT27-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT27" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT28": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT28", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "28" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT28-EEPROM" - }, { - "itf": "control", - "dev": "PORT28-CTRL" - }] - } - }, - - "PORT28-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT28-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT28" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3b", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT28-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT28-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT28" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT29": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT29", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "29" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT29-EEPROM" - }, { - "itf": "control", - "dev": "PORT29-CTRL" - }] - } - }, - - "PORT29-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT29-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT29" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3c", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT29-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT29-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT29" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT30": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT30", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "30" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT30-EEPROM" - }, { - "itf": "control", - "dev": "PORT30-CTRL" - }] - } - }, - - "PORT30-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT30-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT30" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3d", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT30-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT30-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT30" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT31": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT31", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "31" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT31-EEPROM" - }, { - "itf": "control", - "dev": "PORT31-CTRL" - }] - } - }, - - "PORT31-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT31-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT31" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3e", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT31-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT31-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT31" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT32": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT32", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "32" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT32-EEPROM" - }, { - "itf": "control", - "dev": "PORT32-CTRL" - }] - } - }, - - "PORT32-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT32-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT32" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3f", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT32-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT32-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT32" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "FPGA-OCORE11": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE11", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0xd" - }, - "DEVICES": [] - } - }, - - "FPGA-OCORE12": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE12", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0xe" - }, - "DEVICES": [] - } - }, - - "FPGA-OCORE13": { - "dev_info": { - "device_type": "FPGA-OCORE", - "device_name": "FPGA-OCORE13", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0xf" - }, - "DEVICES": [] - } - }, - - "FRONT_BOARD_CPU_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "SYS_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x972" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x972" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x972" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x972" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x972" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x972" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x972" - } - ] - } - }, - - "FRONT_BOARD_PSU_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "LOC_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x973" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x973" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x973" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x973" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x973" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x973" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x973" - } - ] - } - }, - - "FRONT_BOARD_FAN_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FAN_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x974" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x974" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x974" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x974" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x974" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x974" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x974" - } - ] - } - }, - - "FANTRAY1_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - } - ] - } - }, - - "FANTRAY2_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "1" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - } - ] - } - }, - - "FANTRAY3_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "2" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - } - ] - } - }, - - "FANTRAY4_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "3" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3e" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3e" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3e" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3e" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3e" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3e" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3e" - } - ] - } - }, - - "FANTRAY5_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "4" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3f" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3f" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3f" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3f" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3f" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3f" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3f" - } - ] - } - } -} diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/eeprom.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/eeprom.py deleted file mode 100644 index 3384c2cbd693..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/eeprom.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python - -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/bus/i2c/devices/1-0056/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/psuutil.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/psuutil.py deleted file mode 100644 index 6d1ef8710cea..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/psuutil.py +++ /dev/null @@ -1,63 +0,0 @@ -# -# psuutil.py -# Platform-specific PSU status interface for SONiC -# - -try: - from sonic_psu.psu_base import PsuBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class PsuUtil(PsuBase): - """Platform-specific PSUutil class""" - - def __init__(self): - PsuBase.__init__(self) - - def get_num_psus(self): - return 2 - - def get_psu_status(self, index): - if index != 1 and index != 2: - return False - - psu_path = "/sys/bus/i2c/devices/6-000d/psu_status" - - try: - data = open(psu_path, "rb") - except IOError: - return False - - result = int(data.read(2), 16) - data.close() - - if index == 1 and (result & 0x2): - return True - - if index == 2 and (result & 0x20): - return True - - return False - - def get_psu_presence(self, index): - if index != 1 and index != 2: - return False - - psu_path = "/sys/bus/i2c/devices/6-000d/psu_status" - - try: - data = open(psu_path, "rb") - except IOError: - return False - - result = int(data.read(2), 16) - data.close() - - if index == 1 and (result & 0x1) == 0: - return True - - if index == 2 and (result & 0x10) == 0: - return True - - return False diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/sfputil.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/sfputil.py index 51285b5401b7..df3799f314ce 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/sfputil.py +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/sfputil.py @@ -6,6 +6,7 @@ try: import time import os + import traceback from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -22,12 +23,8 @@ class SfpUtil(SfpUtilBase): QSFP_DEVICE_TYPE = "optoe1" I2C_MAX_ATTEMPT = 3 - SFP_STATUS_INSERTED = '1' - SFP_STATUS_REMOVED = '0' - _port_to_eeprom_mapping = {} port_to_i2cbus_mapping ={} - port_dict = {} @property def port_start(self): @@ -47,7 +44,7 @@ def port_to_eeprom_mapping(self): def __init__(self): for x in range(self.PORT_START, self.PORTS_IN_BLOCK): - self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) + self.port_to_i2cbus_mapping[x] = x + self.EEPROM_OFFSET SfpUtilBase.__init__(self) def _sfp_read_file_path(self, file_path, offset, num_bytes): @@ -59,8 +56,7 @@ def _sfp_read_file_path(self, file_path, offset, num_bytes): except Exception: attempts += 1 time.sleep(0.05) - else: - return True, read_buf + return True, read_buf return False, None def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): @@ -70,20 +66,18 @@ def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): return False - else: - with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: - rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) - return rv + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): try: sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path # Write device address to new_device file - nd_file = open(sysfs_nd_path, "w") nd_str = "%s %s" % (devtype, hex(devaddr)) - nd_file.write(nd_str) - nd_file.close() + with open(sysfs_nd_path, "w") as nd_file: + nd_file.write(nd_str) except Exception as err: print("Error writing to new device file: %s" % str(err)) @@ -94,7 +88,7 @@ def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): def _get_port_eeprom_path(self, port_num, devid): sysfs_i2c_adapter_base_path = "" - if port_num in self.port_to_eeprom_mapping.keys(): + if port_num in self.port_to_eeprom_mapping: sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] else: sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" @@ -139,12 +133,12 @@ def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): eeprom_raw.append("0x00") rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) - if rv == False: + if rv is False: return None try: for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) except Exception: return None @@ -154,41 +148,28 @@ 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.IDENTITY_EEPROM_ADDR, 256) + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256) def get_presence(self, port_num): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - if port_num <= 7: - presence_path = "/sys/bus/i2c/devices/8-0030/sfp_presence1" - elif port_num >= 8 and port_num <= 15: - presence_path = "/sys/bus/i2c/devices/8-0030/sfp_presence2" - elif port_num >= 16 and port_num <= 23: - presence_path = "/sys/bus/i2c/devices/8-0031/sfp_presence3" - elif port_num >= 24 and port_num <= 31: - presence_path = "/sys/bus/i2c/devices/8-0031/sfp_presence4" - else: - return False + #The sff number starts from 1 + presence_path = "/sys/wb_plat/sff/sff%d/present" % (port_num + 1) try: - data = open(presence_path, "rb") + with open(presence_path, "rb") as data: + presence_data = data.read(2) + if presence_data == "": + return False + result = int(presence_data, 16) except IOError: return False - presence_data = data.read(2) - if presence_data == "": - return False - result = int(presence_data, 16) - data.close() - - # ModPrsL is active low - if result & (1 << (port_num % 8)) == 0: + if result == 1: return True - return False def get_low_power_mode(self, port_num): @@ -209,47 +190,55 @@ def reset(self, port_num): return True def get_transceiver_change_event(self, timeout=0): + return False, {} - start_time = time.time() - currernt_port_dict = {} - forever = False + def get_highest_temperature(self): + offset = 0 + hightest_temperature = -9999 - if timeout == 0: - forever = True - elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs - else: - print ("get_transceiver_change_event:Invalid timeout value", timeout) - return False, {} + presence_flag = False + read_eeprom_flag = False + temperature_valid_flag = False - end_time = start_time + timeout - if start_time > end_time: - print ('get_transceiver_change_event:' \ - 'time wrap / invalid timeout value', timeout) + for port in range(0, self.PORTS_IN_BLOCK): + if self.get_presence(port) is False: + continue - return False, {} # Time wrap or possibly incorrect timeout + presence_flag = True - while timeout >= 0: - # Check for OIR events and return updated port_dict - for x in range(self.PORT_START, self.PORTS_IN_BLOCK): - if self.get_presence(x): - currernt_port_dict[x] = self.SFP_STATUS_INSERTED - else: - currernt_port_dict[x] = self.SFP_STATUS_REMOVED - if (currernt_port_dict == self.port_dict): - if forever: - time.sleep(1) - else: - timeout = end_time - time.time() - if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity - else: - if timeout > 0: - time.sleep(timeout) - return True, {} + if port in self.qsfp_ports: + offset = 22 else: - # Update reg value - self.port_dict = currernt_port_dict - return True, self.port_dict - print ("get_transceiver_change_event: Should not reach here.") - return False, {} + offset = 96 + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = float(result / 256.0) + if -50 <= result <= 200: + temperature_valid_flag = True + hightest_temperature = max(hightest_temperature, result) + except BaseException: + print(traceback.format_exc()) + + # all port not presence + if presence_flag is False: + hightest_temperature = -10000 + + # all port read eeprom fail + elif read_eeprom_flag is False: + hightest_temperature = -9999 + + # all port temperature invalid + elif read_eeprom_flag is True and temperature_valid_flag is False: + hightest_temperature = -10000 + + hightest_temperature = round(hightest_temperature, 2) + + return hightest_temperature diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py new file mode 100644 index 000000000000..e92782a0969b --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py @@ -0,0 +1,309 @@ +# +# ssd_util.py +# +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium + +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_ssd.ssd_base import SsdBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SMARTCTL = "smartctl {} -a" +INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + +NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 + +class SsdUtil(SsdBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE + + def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + + """ + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" + """ + self.model_attr = { + "ER2-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n231\s+(.+?)\n" } + } + + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = "[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" + + def _execute_shell(self, cmd): + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None + return output + + def _parse_re(self, pattern, buffer): + res_list = re.findall(pattern, str(buffer)) + return res_list[0] if res_list else NOT_AVAILABLE + + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re('Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re('Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re('Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re('Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re('\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re('SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re('Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re('Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + + def get_health(self): + """ + Retrieves current disk health in percentages + + Returns: + A float number of current ssd health + e.g. 83.5 + """ + return float(self.health) + + def get_temperature(self): + """ + Retrieves current disk temperature in Celsius + + Returns: + A float number of current temperature in Celsius + e.g. 40.1 + """ + return float(self.temperature) + + def get_model(self): + """ + Retrieves model for the given disk device + + Returns: + A string holding disk model as provided by the manufacturer + """ + return self.model + + def get_firmware(self): + """ + Retrieves firmware version for the given disk device + + Returns: + A string holding disk firmware version as provided by the manufacturer + """ + return self.firmware + + def get_serial(self): + """ + Retrieves serial number for the given disk device + + Returns: + A string holding disk serial number as provided by the manufacturer + """ + return self.serial + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life + def get_vendor_output(self): + """ + Retrieves vendor specific data for the given disk device + + Returns: + A string holding some vendor specific disk information + """ + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re('{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/sensors.conf b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/sensors.conf deleted file mode 100644 index 9b0569d1541d..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/sensors.conf +++ /dev/null @@ -1,21 +0,0 @@ -# libsensors configuration file -# ---------------------------------------------- -# - -bus "i2c-2" "i2c-0-mux (chan_id 0)" - -chip "lm75-i2c-2-48" - label temp1 "LM75_0 air_inlet" - set temp1_max 80 - set temp1_max_hyst 75 - -chip "lm75-i2c-2-49" - label temp1 "LM75_1 air_outlet" - set temp1_max 80 - set temp1_max_hyst 75 - -chip "lm75-i2c-2-4a" - label temp1 "LM75_2 hottest" - set temp1_max 80 - set temp1_max_hyst 75 - diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf_support b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/system_health_monitoring_config.json old mode 100644 new mode 100755 similarity index 100% rename from device/ragile/x86_64-ragile_ra-b6510-32c-r0/pddf_support rename to device/ragile/x86_64-ragile_ra-b6510-32c-r0/system_health_monitoring_config.json diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/systest.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/systest.py deleted file mode 100644 index b40bf45b2c19..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/systest.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/python -# -*- coding: UTF-8 -*- - -# * onboard interval check -# * FAN trays -# * PSU -# * temp -import time -import datetime -from monitor import status - -def doWork(): - a=[]; - ''' - return: [{'status': '1', 'hw_version': '1.00', 'errcode': 0, 'fan_type': 'M6510-FAN-F', 'errmsg': 'OK', 'Speed': '9778', 'id': 'fan1', 'present': '0', 'sn': '1000000000014'}, - {'id': 'fan2', 'errmsg': 'not present', 'errcode': -1}, - {'id': 'fan3', 'errmsg': 'not present', 'errcode': -1}, - {'id': 'fan4', 'errmsg': 'not present', 'errcode': -1} - ] - description: 1.get id - 2.errcode equal 0 : dev normal - not equal 0 : get errmsg - 3.other message add when all check success - ''' - status.checkFan(a) - #status.getTemp(a) - #status.getPsu(a) - - nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - print nowTime - print a -def run(interval): - while True: - try: - time_remaining = interval - time.time()%interval - time.sleep(time_remaining) - doWork() - except Exception as e: - print(e) - -if __name__ == '__main__': - interval = 1 - run(interval) diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/port_config.ini b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/port_config.ini index 823f53160c33..b71ad39648c9 100755 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/port_config.ini +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/port_config.ini @@ -1,57 +1,57 @@ -# name lanes alias index speed admin_status -Ethernet1 1 twentyfiveGigE0/1 0 25000 up -Ethernet2 2 twentyfiveGigE0/2 1 25000 up -Ethernet3 3 twentyfiveGigE0/3 2 25000 up -Ethernet4 4 twentyfiveGigE0/4 3 25000 up -Ethernet5 5 twentyfiveGigE0/5 4 25000 up -Ethernet6 6 twentyfiveGigE0/6 5 25000 up -Ethernet7 7 twentyfiveGigE0/7 6 25000 up -Ethernet8 8 twentyfiveGigE0/8 7 25000 up -Ethernet9 13 twentyfiveGigE0/9 8 25000 up -Ethernet10 14 twentyfiveGigE0/10 9 25000 up -Ethernet11 15 twentyfiveGigE0/11 10 25000 up -Ethernet12 16 twentyfiveGigE0/12 11 25000 up -Ethernet13 21 twentyfiveGigE0/13 12 25000 up -Ethernet14 22 twentyfiveGigE0/14 13 25000 up -Ethernet15 23 twentyfiveGigE0/15 14 25000 up -Ethernet16 24 twentyfiveGigE0/16 15 25000 up -Ethernet17 29 twentyfiveGigE0/17 16 25000 up -Ethernet18 30 twentyfiveGigE0/18 17 25000 up -Ethernet19 31 twentyfiveGigE0/19 18 25000 up -Ethernet20 32 twentyfiveGigE0/20 19 25000 up -Ethernet21 33 twentyfiveGigE0/21 20 25000 up -Ethernet22 34 twentyfiveGigE0/22 21 25000 up -Ethernet23 35 twentyfiveGigE0/23 22 25000 up -Ethernet24 36 twentyfiveGigE0/24 23 25000 up -Ethernet25 41 twentyfiveGigE0/25 24 25000 up -Ethernet26 42 twentyfiveGigE0/26 25 25000 up -Ethernet27 43 twentyfiveGigE0/27 26 25000 up -Ethernet28 44 twentyfiveGigE0/28 27 25000 up -Ethernet29 49 twentyfiveGigE0/29 28 25000 up -Ethernet30 50 twentyfiveGigE0/30 29 25000 up -Ethernet31 51 twentyfiveGigE0/31 30 25000 up -Ethernet32 52 twentyfiveGigE0/32 31 25000 up -Ethernet33 57 twentyfiveGigE0/33 32 25000 up -Ethernet34 58 twentyfiveGigE0/34 33 25000 up -Ethernet35 59 twentyfiveGigE0/35 34 25000 up -Ethernet36 60 twentyfiveGigE0/36 35 25000 up -Ethernet37 61 twentyfiveGigE0/37 36 25000 up -Ethernet38 62 twentyfiveGigE0/38 37 25000 up -Ethernet39 63 twentyfiveGigE0/39 38 25000 up -Ethernet40 64 twentyfiveGigE0/40 39 25000 up -Ethernet41 65 twentyfiveGigE0/41 40 25000 up -Ethernet42 66 twentyfiveGigE0/42 41 25000 up -Ethernet43 67 twentyfiveGigE0/43 42 25000 up -Ethernet44 68 twentyfiveGigE0/44 43 25000 up -Ethernet45 69 twentyfiveGigE0/45 44 25000 up -Ethernet46 70 twentyfiveGigE0/46 45 25000 up -Ethernet47 71 twentyfiveGigE0/47 46 25000 up -Ethernet48 72 twentyfiveGigE0/48 47 25000 up -Ethernet49 85,86,87,88 hundredGigE0/1 48 100000 up -Ethernet50 77,78,79,80 hundredGigE0/2 49 100000 up -Ethernet51 97,98,99,100 hundredGigE0/3 50 100000 up -Ethernet52 93,94,95,96 hundredGigE0/4 51 100000 up -Ethernet53 113,114,115,116 hundredGigE0/5 52 100000 up -Ethernet54 105,106,107,108 hundredGigE0/6 53 100000 up -Ethernet55 121,122,123,124 hundredGigE0/7 54 100000 up -Ethernet56 125,126,127,128 hundredGigE0/8 55 100000 up +# name lanes alias index speed admin_status +Ethernet1 57 twentyfiveGigE0/1 1 25000 up +Ethernet2 58 twentyfiveGigE0/2 2 25000 up +Ethernet3 59 twentyfiveGigE0/3 3 25000 up +Ethernet4 60 twentyfiveGigE0/4 4 25000 up +Ethernet5 61 twentyfiveGigE0/5 5 25000 up +Ethernet6 62 twentyfiveGigE0/6 6 25000 up +Ethernet7 63 twentyfiveGigE0/7 7 25000 up +Ethernet8 64 twentyfiveGigE0/8 8 25000 up +Ethernet9 1 twentyfiveGigE0/9 9 25000 up +Ethernet10 2 twentyfiveGigE0/10 10 25000 up +Ethernet11 3 twentyfiveGigE0/11 11 25000 up +Ethernet12 4 twentyfiveGigE0/12 12 25000 up +Ethernet13 5 twentyfiveGigE0/13 13 25000 up +Ethernet14 6 twentyfiveGigE0/14 14 25000 up +Ethernet15 7 twentyfiveGigE0/15 15 25000 up +Ethernet16 8 twentyfiveGigE0/16 16 25000 up +Ethernet17 13 twentyfiveGigE0/17 17 25000 up +Ethernet18 14 twentyfiveGigE0/18 18 25000 up +Ethernet19 15 twentyfiveGigE0/19 19 25000 up +Ethernet20 16 twentyfiveGigE0/20 20 25000 up +Ethernet21 21 twentyfiveGigE0/21 21 25000 up +Ethernet22 22 twentyfiveGigE0/22 22 25000 up +Ethernet23 23 twentyfiveGigE0/23 23 25000 up +Ethernet24 24 twentyfiveGigE0/24 24 25000 up +Ethernet25 29 twentyfiveGigE0/25 25 25000 up +Ethernet26 30 twentyfiveGigE0/26 26 25000 up +Ethernet27 31 twentyfiveGigE0/27 27 25000 up +Ethernet28 32 twentyfiveGigE0/28 28 25000 up +Ethernet29 33 twentyfiveGigE0/29 29 25000 up +Ethernet30 34 twentyfiveGigE0/30 30 25000 up +Ethernet31 35 twentyfiveGigE0/31 31 25000 up +Ethernet32 36 twentyfiveGigE0/32 32 25000 up +Ethernet33 41 twentyfiveGigE0/33 33 25000 up +Ethernet34 42 twentyfiveGigE0/34 34 25000 up +Ethernet35 43 twentyfiveGigE0/35 35 25000 up +Ethernet36 44 twentyfiveGigE0/36 36 25000 up +Ethernet37 49 twentyfiveGigE0/37 37 25000 up +Ethernet38 50 twentyfiveGigE0/38 38 25000 up +Ethernet39 51 twentyfiveGigE0/39 39 25000 up +Ethernet40 52 twentyfiveGigE0/40 40 25000 up +Ethernet41 65 twentyfiveGigE0/41 41 25000 up +Ethernet42 66 twentyfiveGigE0/42 42 25000 up +Ethernet43 67 twentyfiveGigE0/43 43 25000 up +Ethernet44 68 twentyfiveGigE0/44 44 25000 up +Ethernet45 69 twentyfiveGigE0/45 45 25000 up +Ethernet46 70 twentyfiveGigE0/46 46 25000 up +Ethernet47 71 twentyfiveGigE0/47 47 25000 up +Ethernet48 72 twentyfiveGigE0/48 48 25000 up +Ethernet49 85,86,87,88 hundredGigE0/1 49 100000 up +Ethernet50 77,78,79,80 hundredGigE0/2 50 100000 up +Ethernet51 97,98,99,100 hundredGigE0/3 51 100000 up +Ethernet52 93,94,95,96 hundredGigE0/4 52 100000 up +Ethernet53 113,114,115,116 hundredGigE0/5 53 100000 up +Ethernet54 105,106,107,108 hundredGigE0/6 54 100000 up +Ethernet55 121,122,123,124 hundredGigE0/7 55 100000 up +Ethernet56 125,126,127,128 hundredGigE0/8 56 100000 up diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/sai.profile b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/sai.profile index 042c8060d587..352e8c50b053 100755 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/sai.profile +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-b6510-48vs8cq-48x25G+8x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-b6510-48vs8cq-48x25G+8x100G.config.bcm b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm similarity index 65% rename from device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-b6510-48vs8cq-48x25G+8x100G.config.bcm rename to device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm index 69fd8c362987..e86eb1b9fa36 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-b6510-48vs8cq-48x25G+8x100G.config.bcm +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/RA-B6510-48V8C/td3-ra-b6510-48v8c-48x25G+8x100G.config.bcm @@ -1,8 +1,12 @@ +cancun_dir=/usr/share/sonic/platform/cancun/sdk_6.5.16/ l2_mem_entries=32768 +l3_mem_entries=16384 +l3_alpm_enable=2 +ipv6_lpm_128b_enable=0x1 l2xmsg_mode=0 l3_max_ecmp_mode=1 -l3_mem_entries=49152 -l3_alpm_enable=0 +svi_my_station_optimization=1 +sai_nbr_bcast_ifp_optimized=2 bcm_num_cos=8 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 @@ -10,7 +14,6 @@ core_clock_frequency=1525 dpp_clock_ratio=2:3 help_cli_enable=1 ifp_inports_support_enable=1 -ipv6_lpm_128b_enable=0x1 #lpm_scaling_enable=1 max_vp_lags=0 mem_cache_enable=0 @@ -21,208 +24,58 @@ oversubscribe_mode=1 parity_enable=1 pbmp_gport_stack.0=0x0000000000000000000000000000000000000000000000000000000000000000 #pbmp_xport_xe.0=0x00000000000000000000000000000000888ffffffffffff9fffffffffffffffe -pbmp_xport_xe=0x488080808808087f9fe1e1e1fe1e1e1fe -phy_chain_rx_lane_map_physical{1.0}=0x1032 +pbmp_xport_xe=0xffffffffffffffffffffffffffffffffffffffffe +port_flex_enable=1 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_tx_lane_map_physical{61.0}=0x0123 phy_chain_tx_lane_map_physical{1.0}=0x0123 -phy_chain_rx_lane_map_physical{5.0}=0x1032 phy_chain_tx_lane_map_physical{5.0}=0x0123 -phy_chain_rx_lane_map_physical{13.0}=0x1032 phy_chain_tx_lane_map_physical{13.0}=0x0123 -phy_chain_rx_lane_map_physical{21.0}=0x1032 phy_chain_tx_lane_map_physical{21.0}=0x0123 -phy_chain_rx_lane_map_physical{29.0}=0x1032 phy_chain_tx_lane_map_physical{29.0}=0x0123 -phy_chain_rx_lane_map_physical{33.0}=0x1032 phy_chain_tx_lane_map_physical{33.0}=0x0123 -phy_chain_rx_lane_map_physical{41.0}=0x1032 phy_chain_tx_lane_map_physical{41.0}=0x0123 -phy_chain_rx_lane_map_physical{49.0}=0x1032 phy_chain_tx_lane_map_physical{49.0}=0x0123 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_tx_lane_map_physical{69.0}=0x3210 +phy_chain_tx_lane_map_physical{85.0}=0x3210 +phy_chain_tx_lane_map_physical{77.0}=0x0213 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_tx_lane_map_physical{93.0}=0x0213 +phy_chain_tx_lane_map_physical{113.0}=0x3210 +phy_chain_tx_lane_map_physical{105.0}=0x0213 +phy_chain_tx_lane_map_physical{121.0}=0x3120 +phy_chain_tx_lane_map_physical{125.0}=0x1203 + phy_chain_rx_lane_map_physical{57.0}=0x1032 -phy_chain_tx_lane_map_physical{57.0}=0x0123 phy_chain_rx_lane_map_physical{61.0}=0x1032 -phy_chain_tx_lane_map_physical{61.0}=0x0123 +phy_chain_rx_lane_map_physical{1.0}=0x1032 +phy_chain_rx_lane_map_physical{5.0}=0x1032 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_rx_lane_map_physical{49.0}=0x1032 phy_chain_rx_lane_map_physical{65.0}=0x2301 -phy_chain_tx_lane_map_physical{65.0}=0x3210 phy_chain_rx_lane_map_physical{69.0}=0x2301 -phy_chain_tx_lane_map_physical{69.0}=0x3210 -phy_chain_rx_lane_map_physical{77.0}=0x1032 -phy_chain_tx_lane_map_physical{77.0}=0x3210 phy_chain_rx_lane_map_physical{85.0}=0x1032 -phy_chain_tx_lane_map_physical{85.0}=0x3210 -phy_chain_rx_lane_map_physical{93.0}=0x1032 -phy_chain_tx_lane_map_physical{93.0}=0x3210 +phy_chain_rx_lane_map_physical{77.0}=0x1032 phy_chain_rx_lane_map_physical{97.0}=0x1032 -phy_chain_tx_lane_map_physical{97.0}=0x3210 -phy_chain_rx_lane_map_physical{105.0}=0x1032 -phy_chain_tx_lane_map_physical{105.0}=0x3210 +phy_chain_rx_lane_map_physical{93.0}=0x1032 phy_chain_rx_lane_map_physical{113.0}=0x1032 -phy_chain_tx_lane_map_physical{113.0}=0x3210 +phy_chain_rx_lane_map_physical{105.0}=0x1032 phy_chain_rx_lane_map_physical{121.0}=0x2031 -phy_chain_tx_lane_map_physical{121.0}=0x3210 -phy_chain_rx_lane_map_physical{125.0}=0x1032 -phy_chain_tx_lane_map_physical{125.0}=0x1203 -phy_chain_tx_polarity_flip_physical{1.0}=0x1 -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}=0x0 -phy_chain_tx_polarity_flip_physical{3.0}=0x1 -phy_chain_rx_polarity_flip_physical{3.0}=0x0 -phy_chain_tx_polarity_flip_physical{4.0}=0x0 -phy_chain_rx_polarity_flip_physical{4.0}=0x0 -phy_chain_tx_polarity_flip_physical{5.0}=0x1 -phy_chain_rx_polarity_flip_physical{5.0}=0x0 -phy_chain_tx_polarity_flip_physical{6.0}=0x0 -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}=0x0 -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}=0x0 -phy_chain_tx_polarity_flip_physical{14.0}=0x0 -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}=0x0 -phy_chain_tx_polarity_flip_physical{16.0}=0x0 -phy_chain_rx_polarity_flip_physical{16.0}=0x0 -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}=0x0 -phy_chain_rx_polarity_flip_physical{22.0}=0x0 -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 -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}=0x0 -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}=0x0 -phy_chain_rx_polarity_flip_physical{32.0}=0x1 -phy_chain_tx_polarity_flip_physical{33.0}=0x0 -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}=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}=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}=0x0 -phy_chain_rx_polarity_flip_physical{42.0}=0x0 -phy_chain_tx_polarity_flip_physical{43.0}=0x0 -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}=0x0 -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}=0x0 -phy_chain_tx_polarity_flip_physical{51.0}=0x0 -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}=0x0 -phy_chain_tx_polarity_flip_physical{57.0}=0x0 -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}=0x0 -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}=0x0 -phy_chain_rx_polarity_flip_physical{60.0}=0x0 -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}=0x0 -phy_chain_rx_polarity_flip_physical{62.0}=0x1 -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}=0x1 -phy_chain_tx_polarity_flip_physical{65.0}=0x0 -phy_chain_rx_polarity_flip_physical{65.0}=0x1 -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}=0x0 -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}=0x1 -phy_chain_tx_polarity_flip_physical{69.0}=0x0 -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}=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}=0x0 -phy_chain_rx_polarity_flip_physical{72.0}=0x0 -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}=0x1 -phy_chain_tx_polarity_flip_physical{88.0}=0x0 -phy_chain_rx_polarity_flip_physical{88.0}=0x1 -phy_chain_tx_polarity_flip_physical{77.0}=0x1 -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}=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 -phy_chain_tx_polarity_flip_physical{97.0}=0x1 -phy_chain_rx_polarity_flip_physical{97.0}=0x0 -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}=0x0 -phy_chain_tx_polarity_flip_physical{100.0}=0x0 -phy_chain_rx_polarity_flip_physical{100.0}=0x0 -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}=0x0 -phy_chain_tx_polarity_flip_physical{95.0}=0x1 -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}=0x1 -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}=0x1 -phy_chain_tx_polarity_flip_physical{115.0}=0x1 -phy_chain_rx_polarity_flip_physical{115.0}=0x1 -phy_chain_tx_polarity_flip_physical{116.0}=0x0 -phy_chain_rx_polarity_flip_physical{116.0}=0x1 -phy_chain_tx_polarity_flip_physical{105.0}=0x1 -phy_chain_rx_polarity_flip_physical{105.0}=0x1 -phy_chain_tx_polarity_flip_physical{106.0}=0x1 -phy_chain_rx_polarity_flip_physical{106.0}=0x0 -phy_chain_tx_polarity_flip_physical{107.0}=0x1 -phy_chain_rx_polarity_flip_physical{107.0}=0x1 -phy_chain_tx_polarity_flip_physical{108.0}=0x1 -phy_chain_rx_polarity_flip_physical{108.0}=0x1 -phy_chain_tx_polarity_flip_physical{121.0}=0x1 -phy_chain_rx_polarity_flip_physical{121.0}=0x1 -phy_chain_tx_polarity_flip_physical{122.0}=0x0 -phy_chain_rx_polarity_flip_physical{122.0}=0x0 -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 -phy_chain_tx_polarity_flip_physical{125.0}=0x0 -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 -port_flex_enable=1 +phy_chain_rx_lane_map_physical{125.0}=0x1023 + +portmap_57=57:25 +portmap_58=58:25 +portmap_59=59:25 +portmap_60=60:25 +portmap_61=61:25 +portmap_62=62:25 +portmap_63=63:25 +portmap_64=64:25 portmap_1=1:25 portmap_2=2:25 portmap_3=3:25 @@ -255,14 +108,6 @@ portmap_49=49:25 portmap_50=50:25 portmap_51=51:25 portmap_52=52:25 -portmap_57=57:25 -portmap_58=58:25 -portmap_59=59:25 -portmap_60=60:25 -portmap_61=61:25 -portmap_62=62:25 -portmap_63=63:25 -portmap_64=64:25 portmap_67=65:25 portmap_68=66:25 portmap_69=67:25 @@ -271,55 +116,55 @@ portmap_71=69:25 portmap_72=70:25 portmap_73=71:25 portmap_74=72:25 -portmap_79=77:100 portmap_87=85:100 -portmap_95=93:100 +portmap_79=77:100 portmap_99=97:100 -portmap_107=105:100 +portmap_95=93:100 portmap_115=113:100 +portmap_107=105:100 portmap_123=121:100 portmap_127=125:100 -dport_map_port_1=1 -dport_map_port_2=2 -dport_map_port_3=3 -dport_map_port_4=4 -dport_map_port_5=5 -dport_map_port_6=6 -dport_map_port_7=7 -dport_map_port_8=8 -dport_map_port_13=9 -dport_map_port_14=10 -dport_map_port_15=11 -dport_map_port_16=12 -dport_map_port_21=13 -dport_map_port_22=14 -dport_map_port_23=15 -dport_map_port_24=16 -dport_map_port_29=17 -dport_map_port_30=18 -dport_map_port_31=19 -dport_map_port_32=20 -dport_map_port_33=21 -dport_map_port_34=22 -dport_map_port_35=23 -dport_map_port_36=24 -dport_map_port_41=25 -dport_map_port_42=26 -dport_map_port_43=27 -dport_map_port_44=28 -dport_map_port_49=29 -dport_map_port_50=30 -dport_map_port_51=31 -dport_map_port_52=32 -dport_map_port_57=33 -dport_map_port_58=34 -dport_map_port_59=35 -dport_map_port_60=36 -dport_map_port_61=37 -dport_map_port_62=38 -dport_map_port_63=39 -dport_map_port_64=40 +dport_map_port_57=1 +dport_map_port_58=2 +dport_map_port_59=3 +dport_map_port_60=4 +dport_map_port_61=5 +dport_map_port_62=6 +dport_map_port_63=7 +dport_map_port_64=8 +dport_map_port_1=9 +dport_map_port_2=10 +dport_map_port_3=11 +dport_map_port_4=12 +dport_map_port_5=13 +dport_map_port_6=14 +dport_map_port_7=15 +dport_map_port_8=16 +dport_map_port_13=17 +dport_map_port_14=18 +dport_map_port_15=19 +dport_map_port_16=20 +dport_map_port_21=21 +dport_map_port_22=22 +dport_map_port_23=23 +dport_map_port_24=24 +dport_map_port_29=25 +dport_map_port_30=26 +dport_map_port_31=27 +dport_map_port_32=28 +dport_map_port_33=29 +dport_map_port_34=30 +dport_map_port_35=31 +dport_map_port_36=32 +dport_map_port_41=33 +dport_map_port_42=34 +dport_map_port_43=35 +dport_map_port_44=36 +dport_map_port_49=37 +dport_map_port_50=38 +dport_map_port_51=39 +dport_map_port_52=40 dport_map_port_67=41 dport_map_port_68=42 dport_map_port_69=43 @@ -337,50 +182,244 @@ dport_map_port_107=54 dport_map_port_123=55 dport_map_port_127=56 +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 + +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 +phy_chain_rx_polarity_flip_physical{1.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +serdes_preemphasis_lane0_57=0x0f480d +serdes_preemphasis_lane1_57=0x0f480d +serdes_preemphasis_lane2_57=0x0f480d +serdes_preemphasis_lane3_57=0x0f480d +serdes_preemphasis_lane0_58=0x0f480d +serdes_preemphasis_lane1_58=0x0f480d +serdes_preemphasis_lane2_58=0x0f480d +serdes_preemphasis_lane3_58=0x0f480d +serdes_preemphasis_lane0_59=0x0f480d +serdes_preemphasis_lane1_59=0x0f480d +serdes_preemphasis_lane2_59=0x0f480d +serdes_preemphasis_lane3_59=0x0f480d +serdes_preemphasis_lane0_60=0x0f480d +serdes_preemphasis_lane1_60=0x0f480d +serdes_preemphasis_lane2_60=0x0f480d +serdes_preemphasis_lane3_60=0x0f480d +serdes_preemphasis_lane0_61=0x0f480d +serdes_preemphasis_lane1_61=0x0f480d +serdes_preemphasis_lane2_61=0x0f480d +serdes_preemphasis_lane3_61=0x0f480d +serdes_preemphasis_lane0_62=0x0f480d +serdes_preemphasis_lane1_62=0x0f480d +serdes_preemphasis_lane2_62=0x0f480d +serdes_preemphasis_lane3_62=0x0f480d +serdes_preemphasis_lane0_63=0x0f480d +serdes_preemphasis_lane1_63=0x0f480d +serdes_preemphasis_lane2_63=0x0f480d +serdes_preemphasis_lane3_63=0x0f480d +serdes_preemphasis_lane0_64=0x0f480d +serdes_preemphasis_lane1_64=0x0f480d +serdes_preemphasis_lane2_64=0x0f480d +serdes_preemphasis_lane3_64=0x0f480d serdes_preemphasis_lane0_1=0x0f480d serdes_preemphasis_lane1_1=0x0f480d serdes_preemphasis_lane2_1=0x0f480d serdes_preemphasis_lane3_1=0x0f480d -serdes_preemphasis_lane0_2=0x0f480d -serdes_preemphasis_lane1_2=0x0f480d -serdes_preemphasis_lane2_2=0x0f480d -serdes_preemphasis_lane3_2=0x0f480d +serdes_preemphasis_lane0_2=0x0d4b0c +serdes_preemphasis_lane1_2=0x0d4b0c +serdes_preemphasis_lane2_2=0x0d4b0c +serdes_preemphasis_lane3_2=0x0d4b0c serdes_preemphasis_lane0_3=0x0f480d serdes_preemphasis_lane1_3=0x0f480d serdes_preemphasis_lane2_3=0x0f480d serdes_preemphasis_lane3_3=0x0f480d -serdes_preemphasis_lane0_4=0x0f480d -serdes_preemphasis_lane1_4=0x0f480d -serdes_preemphasis_lane2_4=0x0f480d -serdes_preemphasis_lane3_4=0x0f480d +serdes_preemphasis_lane0_4=0x0d4b0c +serdes_preemphasis_lane1_4=0x0d4b0c +serdes_preemphasis_lane2_4=0x0d4b0c +serdes_preemphasis_lane3_4=0x0d4b0c serdes_preemphasis_lane0_5=0x0f480d serdes_preemphasis_lane1_5=0x0f480d serdes_preemphasis_lane2_5=0x0f480d serdes_preemphasis_lane3_5=0x0f480d -serdes_preemphasis_lane0_6=0x0f480d -serdes_preemphasis_lane1_6=0x0f480d -serdes_preemphasis_lane2_6=0x0f480d -serdes_preemphasis_lane3_6=0x0f480d -serdes_preemphasis_lane0_7=0x0d4b0c -serdes_preemphasis_lane1_7=0x0d4b0c -serdes_preemphasis_lane2_7=0x0d4b0c -serdes_preemphasis_lane3_7=0x0d4b0c +serdes_preemphasis_lane0_6=0x0d4b0c +serdes_preemphasis_lane1_6=0x0d4b0c +serdes_preemphasis_lane2_6=0x0d4b0c +serdes_preemphasis_lane3_6=0x0d4b0c +serdes_preemphasis_lane0_7=0x0f480d +serdes_preemphasis_lane1_7=0x0f480d +serdes_preemphasis_lane2_7=0x0f480d +serdes_preemphasis_lane3_7=0x0f480d serdes_preemphasis_lane0_8=0x0d4b0c serdes_preemphasis_lane1_8=0x0d4b0c serdes_preemphasis_lane2_8=0x0d4b0c serdes_preemphasis_lane3_8=0x0d4b0c -serdes_preemphasis_lane0_13=0x0d4b0c -serdes_preemphasis_lane1_13=0x0d4b0c -serdes_preemphasis_lane2_13=0x0d4b0c -serdes_preemphasis_lane3_13=0x0d4b0c +serdes_preemphasis_lane0_13=0x0f480d +serdes_preemphasis_lane1_13=0x0f480d +serdes_preemphasis_lane2_13=0x0f480d +serdes_preemphasis_lane3_13=0x0f480d serdes_preemphasis_lane0_14=0x0d4b0c serdes_preemphasis_lane1_14=0x0d4b0c serdes_preemphasis_lane2_14=0x0d4b0c serdes_preemphasis_lane3_14=0x0d4b0c -serdes_preemphasis_lane0_15=0x0d4b0c -serdes_preemphasis_lane1_15=0x0d4b0c -serdes_preemphasis_lane2_15=0x0d4b0c -serdes_preemphasis_lane3_15=0x0d4b0c +serdes_preemphasis_lane0_15=0x0f480d +serdes_preemphasis_lane1_15=0x0f480d +serdes_preemphasis_lane2_15=0x0f480d +serdes_preemphasis_lane3_15=0x0f480d serdes_preemphasis_lane0_16=0x0d4b0c serdes_preemphasis_lane1_16=0x0d4b0c serdes_preemphasis_lane2_16=0x0d4b0c @@ -449,54 +488,22 @@ serdes_preemphasis_lane0_44=0x0d4b0c serdes_preemphasis_lane1_44=0x0d4b0c serdes_preemphasis_lane2_44=0x0d4b0c serdes_preemphasis_lane3_44=0x0d4b0c -serdes_preemphasis_lane0_49=0x0d4b0c -serdes_preemphasis_lane1_49=0x0d4b0c -serdes_preemphasis_lane2_49=0x0d4b0c -serdes_preemphasis_lane3_49=0x0d4b0c +serdes_preemphasis_lane0_49=0x0f480d +serdes_preemphasis_lane1_49=0x0f480d +serdes_preemphasis_lane2_49=0x0f480d +serdes_preemphasis_lane3_49=0x0f480d serdes_preemphasis_lane0_50=0x0d4b0c serdes_preemphasis_lane1_50=0x0d4b0c serdes_preemphasis_lane2_50=0x0d4b0c serdes_preemphasis_lane3_50=0x0d4b0c -serdes_preemphasis_lane0_51=0x0d4b0c -serdes_preemphasis_lane1_51=0x0d4b0c -serdes_preemphasis_lane2_51=0x0d4b0c -serdes_preemphasis_lane3_51=0x0d4b0c +serdes_preemphasis_lane0_51=0x0f480d +serdes_preemphasis_lane1_51=0x0f480d +serdes_preemphasis_lane2_51=0x0f480d +serdes_preemphasis_lane3_51=0x0f480d serdes_preemphasis_lane0_52=0x0d4b0c serdes_preemphasis_lane1_52=0x0d4b0c serdes_preemphasis_lane2_52=0x0d4b0c serdes_preemphasis_lane3_52=0x0d4b0c -serdes_preemphasis_lane0_57=0x0d4b0c -serdes_preemphasis_lane1_57=0x0d4b0c -serdes_preemphasis_lane2_57=0x0d4b0c -serdes_preemphasis_lane3_57=0x0d4b0c -serdes_preemphasis_lane0_58=0x0d4b0c -serdes_preemphasis_lane1_58=0x0d4b0c -serdes_preemphasis_lane2_58=0x0d4b0c -serdes_preemphasis_lane3_58=0x0d4b0c -serdes_preemphasis_lane0_59=0x0d4b0c -serdes_preemphasis_lane1_59=0x0d4b0c -serdes_preemphasis_lane2_59=0x0d4b0c -serdes_preemphasis_lane3_59=0x0d4b0c -serdes_preemphasis_lane0_60=0x0d4b0c -serdes_preemphasis_lane1_60=0x0d4b0c -serdes_preemphasis_lane2_60=0x0d4b0c -serdes_preemphasis_lane3_60=0x0d4b0c -serdes_preemphasis_lane0_61=0x0d4b0c -serdes_preemphasis_lane1_61=0x0d4b0c -serdes_preemphasis_lane2_61=0x0d4b0c -serdes_preemphasis_lane3_61=0x0d4b0c -serdes_preemphasis_lane0_62=0x0d4b0c -serdes_preemphasis_lane1_62=0x0d4b0c -serdes_preemphasis_lane2_62=0x0d4b0c -serdes_preemphasis_lane3_62=0x0d4b0c -serdes_preemphasis_lane0_63=0x0d4b0c -serdes_preemphasis_lane1_63=0x0d4b0c -serdes_preemphasis_lane2_63=0x0d4b0c -serdes_preemphasis_lane3_63=0x0d4b0c -serdes_preemphasis_lane0_64=0x0d4b0c -serdes_preemphasis_lane1_64=0x0d4b0c -serdes_preemphasis_lane2_64=0x0d4b0c -serdes_preemphasis_lane3_64=0x0d4b0c serdes_preemphasis_lane0_67=0x0d4b0c serdes_preemphasis_lane1_67=0x0d4b0c serdes_preemphasis_lane2_67=0x0d4b0c @@ -545,25 +552,51 @@ serdes_preemphasis_lane0_95=0x0d4b0c serdes_preemphasis_lane1_95=0x0d4b0c serdes_preemphasis_lane2_95=0x0d4b0c serdes_preemphasis_lane3_95=0x0d4b0c -serdes_preemphasis_lane0_115=0x0f480d -serdes_preemphasis_lane1_115=0x0f480d -serdes_preemphasis_lane2_115=0x0f480d -serdes_preemphasis_lane3_115=0x0f480d -serdes_preemphasis_lane0_107=0x0f480d -serdes_preemphasis_lane1_107=0x0f480d -serdes_preemphasis_lane2_107=0x0f480d -serdes_preemphasis_lane3_107=0x0f480d -serdes_preemphasis_lane0_123=0x0f480d -serdes_preemphasis_lane1_123=0x0f480d -serdes_preemphasis_lane2_123=0x0f480d -serdes_preemphasis_lane3_123=0x0f480d -serdes_preemphasis_lane0_127=0x0f480d -serdes_preemphasis_lane1_127=0x0f480d -serdes_preemphasis_lane2_127=0x0f480d -serdes_preemphasis_lane3_127=0x0f480d +serdes_preemphasis_lane0_115=0x0d4b0c +serdes_preemphasis_lane1_115=0x0d4b0c +serdes_preemphasis_lane2_115=0x0d4b0c +serdes_preemphasis_lane3_115=0x0d4b0c +serdes_preemphasis_lane0_107=0x0d4b0c +serdes_preemphasis_lane1_107=0x0d4b0c +serdes_preemphasis_lane2_107=0x0d4b0c +serdes_preemphasis_lane3_107=0x0d4b0c +serdes_preemphasis_lane0_123=0x14460a +serdes_preemphasis_lane1_123=0x14460a +serdes_preemphasis_lane2_123=0x14460a +serdes_preemphasis_lane3_123=0x14460a +serdes_preemphasis_lane0_127=0x14460a +serdes_preemphasis_lane1_127=0x14460a +serdes_preemphasis_lane2_127=0x14460a +serdes_preemphasis_lane3_127=0x14460a + reglist_enable=1 -scache_filename=/tmp/scache +scache_filename=/var/warmboot/wbscache schan_intr_enable=0 -stable_size=0x5500000 +stable_size=0x55000000 +stable_location=3 +warmboot_knet_shutdown_mode=1 tdma_timeout_usec=3000000 + +#vxlan flex flow mode +flow_init_mode=1 + +riot_enable=1 +riot_overlay_l3_intf_mem_size=4096 +riot_overlay_l3_egress_mem_size=32768 +riot_overlay_ecmp_resilient_hash_size=16384 + +l3_ecmp_levels=2 + +use_all_splithorizon_groups=1 +sai_tunnel_support=1 + +#This property allows to enable L2 FDB entry to discard based on Source Mac +sai_fdb_entry_l2_discard_src_enable=1 + +#RDMA +sai_pfc_defaults_disable=1 +sai_optimized_mmu=1 + +#ACL wb count +ctr_evict_enable=0 diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/custom_led.bin b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/custom_led.bin index 1fe5585e07796a7e30facd1faf391c9969ab8b08..e02f94e7ed87ffe60524721f4aec68d661880e7c 100644 GIT binary patch delta 152 zcmV;J0B8TK0_*{Q@U>S)Mn=H23jiBR765QI03?7X10je;0wo7m zf?>j80Wkq$A2C5q?Rz^)mL`LwmgRlw!DNAr6j7FS903-q@5HW~GeK|TnlSUN) zY95tAsvQB6*+v?ORvxwh1!#6#g=nfqQbYkd5_q~p1u6v5LPjz|Cea5X4B$mZH9%@Y zYC)2+04)X3F+u~-O-2AM0MG#zlh diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml old mode 100755 new mode 100644 index f5e871564350..3be013889ce5 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev.xml @@ -7,116 +7,412 @@ --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev_exhaust.xml b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev_exhaust.xml new file mode 100644 index 000000000000..496a7dee80cc --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/dev_exhaust.xml @@ -0,0 +1,418 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/fru.py b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/fru.py new file mode 100644 index 000000000000..f95164e03601 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/fru.py @@ -0,0 +1,961 @@ +#!/usr/bin/python3 +import collections +from datetime import datetime, timedelta +from bitarray import bitarray + + +__DEBUG__ = "N" + + +class FruException(Exception): + def __init__(self, message='fruerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +def e_print(err): + print("ERROR: " + err) + + +def d_print(debug_info): + if __DEBUG__ == "Y": + print(debug_info) + + +class FruUtil(): + @staticmethod + def decodeLength(value): + a = bitarray(8) + a.setall(True) + a[0:1] = 0 + a[1:2] = 0 + x = ord(a.tobytes()) + return x & ord(value) + + @staticmethod + def minToData(): + starttime = datetime(1996, 1, 1, 0, 0, 0) + endtime = datetime.now() + seconds = (endtime - starttime).total_seconds() + mins = seconds // 60 + m = int(round(mins)) + return m + + @staticmethod + def getTimeFormat(): + return datetime.now().strftime('%Y-%m-%d') + + @staticmethod + def getTypeLength(value): + if value is None or len(value) == 0: + return 0 + a = bitarray(8) + a.setall(False) + a[0:1] = 1 + a[1:2] = 1 + x = ord(a.tobytes()) + return x | len(value) + + @staticmethod + def checksum(b): + result = 0 + for item in b: + result += ord(item) + return (0x100 - (result & 0xff)) & 0xff + + +class BaseArea(object): + SUGGESTED_SIZE_COMMON_HEADER = 8 + SUGGESTED_SIZE_INTERNAL_USE_AREA = 72 + SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32 + SUGGESTED_SIZE_BOARD_INFO_AREA = 80 + SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80 + + INITVALUE = b'\x00' + resultvalue = INITVALUE * 256 + COMMON_HEAD_VERSION = b'\x01' + __childList = None + + def __init__(self, name="", size=0, offset=0): + self.__childList = [] + self._offset = offset + self.name = name + self._size = size + self._isPresent = False + self._data = b'\x00' * size + + @property + def childList(self): + return self.__childList + + @childList.setter + def childList(self, value): + self.__childList = value + + @property + def offset(self): + return self._offset + + @offset.setter + def offset(self, value): + self._offset = value + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + self._size = value + + @property + def data(self): + return self._data + + @data.setter + def data(self, value): + self._data = value + + @property + def isPresent(self): + return self._isPresent + + @isPresent.setter + def isPresent(self, value): + self._isPresent = value + + +class InternalUseArea(BaseArea): + pass + + +class ChassisInfoArea(BaseArea): + pass + + +class BoardInfoArea(BaseArea): + _boardTime = None + _fields = None + _mfg_date = None + areaversion = None + _boardversion = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "mfg_date : %s \n" \ + "boardManufacturer : %s \n" \ + "boardProductName : %s \n" \ + "boardSerialNumber : %s \n" \ + "boardPartNumber : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.boardversion), self.size, + self.language, self.getMfgRealData(), + self.boardManufacturer, self.boardProductName, + self.boardSerialNumber, self.boardPartNumber, + self.fruFileId) + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "boardextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["boardversion"] = ord(self.boardversion) + dic["boardlength"] = self.size + dic["boardlanguage"] = self.language + dic["boardmfg_date"] = self.getMfgRealData() + dic["boardManufacturer"] = self.boardManufacturer + dic["boardProductName"] = self.boardProductName + dic["boardSerialNumber"] = self.boardSerialNumber + dic["boardPartNumber"] = self.boardPartNumber + dic["boardfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] + index += 1 + d_print("decode length :%d class size:%d" % + ((ord(self.data[index]) * 8), self.size)) + index += 2 + + timetmp = self.data[index: index + 3] + self.mfg_date = ord(timetmp[0]) | ( + ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16) + d_print("decode getMfgRealData :%s" % self.getMfgRealData()) + index += 3 + + templen = FruUtil.decodeLength(self.data[index]) + self.boardManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardManufacturer:%s" % self.boardManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardProductName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardProductName:%s" % self.boardProductName) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardSerialNumber:%s" % self.boardSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardPartNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardPartNumber:%s" % self.boardPartNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if self.data[index] != chr(0xc1): + templen = FruUtil.decodeLength(self.data[index]) + tmpval = self.data[index + 1: index + templen + 1] + setattr(self, valtmp, tmpval) + index += templen + 1 + d_print("decode boardextra%d:%s" % (i, tmpval)) + else: + break + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("boardInfoArea version:%x" % ord(self.boardversion)) + d_print("boardInfoArea length:%d" % self.size) + d_print("boardInfoArea language:%x" % self.language) + self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea mfg_date:%x" % self.mfg_date) + + self.data = chr(ord(self.boardversion)) + \ + chr(self.size // 8) + chr(self.language) + + self.data += chr(self.mfg_date & 0xFF) + self.data += chr((self.mfg_date >> 8) & 0xFF) + self.data += chr((self.mfg_date >> 16) & 0xFF) + + d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer) + typelength = FruUtil.getTypeLength(self.boardManufacturer) + self.data += chr(typelength) + self.data += self.boardManufacturer + + d_print("boardInfoArea boardProductName:%s" % self.boardProductName) + self.data += chr(FruUtil.getTypeLength(self.boardProductName)) + self.data += self.boardProductName + + d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber) + self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber)) + self.data += self.boardSerialNumber + + d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber) + self.data += chr(FruUtil.getTypeLength(self.boardPartNumber)) + self.data += self.boardPartNumber + + d_print("boardInfoArea fruFileId:%s" % self.fruFileId) + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + d_print("self data:%d" % len(self.data)) + d_print("self size:%d" % self.size) + d_print("adjust size:%d" % (self.size - len(self.data) - 1)) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + + # checksum + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + def getMfgRealData(self): + starttime = datetime(1996, 1, 1, 0, 0, 0) + mactime = starttime + timedelta(minutes=self.mfg_date) + return mactime + + @property + def language(self): + self._language = 25 + return self._language + + @property + def mfg_date(self): + return self._mfg_date + + @mfg_date.setter + def mfg_date(self, val): + self._mfg_date = val + + @property + def boardversion(self): + self._boardversion = self.COMMON_HEAD_VERSION + return self._boardversion + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, val): + self._FRUFileID = val + + @property + def boardPartNumber(self): + return self._boardPartNumber + + @boardPartNumber.setter + def boardPartNumber(self, val): + self._boardPartNumber = val + + @property + def boardSerialNumber(self): + return self._boardSerialNumber + + @boardSerialNumber.setter + def boardSerialNumber(self, val): + self._boardSerialNumber = val + + @property + def boardProductName(self): + return self._boradProductName + + @boardProductName.setter + def boardProductName(self, val): + self._boradProductName = val + + @property + def boardManufacturer(self): + return self._boardManufacturer + + @boardManufacturer.setter + def boardManufacturer(self, val): + self._boardManufacturer = val + + @property + def boardTime(self): + return self._boardTime + + @boardTime.setter + def boardTime(self, val): + self._boardTime = val + + @property + def fields(self): + return self._fields + + @fields.setter + def fields(self, val): + self._fields = val + + +class ProductInfoArea(BaseArea): + _productManufacturer = None + _productAssetTag = None + _FRUFileID = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "productAssetTag : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.areaversion), self.size, + self.language, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, + self.productAssetTag, self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "productextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["productversion"] = ord(self.areaversion) + dic["productlength"] = self.size + dic["productlanguage"] = self.language + dic["productManufacturer"] = self.productManufacturer + dic["productName"] = self.productName + dic["productPartModelName"] = self.productPartModelName + dic["productVersion"] = int(self.productVersion, 16) + dic["productSerialNumber"] = self.productSerialNumber + dic["productAssetTag"] = self.productAssetTag + dic["productfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] # 0 + index += 1 + d_print("decode length %d" % (ord(self.data[index]) * 8)) + d_print("class size %d" % self.size) + index += 2 + + templen = FruUtil.decodeLength(self.data[index]) + self.productManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productManufacturer:%s" % self.productManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.productName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productName:%s" % self.productName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productPartModelName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productPartModelName:%s" % self.productPartModelName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productVersion = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productVersion:%s" % self.productVersion) + + templen = FruUtil.decodeLength(self.data[index]) + self.productSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productSerialNumber:%s" % self.productSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.productAssetTag = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productAssetTag:%s" % self.productAssetTag) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if self.data[index] != chr(0xc1) and index < self.size - 1: + templen = FruUtil.decodeLength(self.data[index]) + if templen == 0: + break + tmpval = self.data[index + 1: index + templen + 1] + d_print("decode boardextra%d:%s" % (i, tmpval)) + setattr(self, valtmp, tmpval) + index += templen + 1 + else: + break + + @property + def productVersion(self): + return self._productVersion + + @productVersion.setter + def productVersion(self, name): + self._productVersion = name + + @property + def areaversion(self): + self._areaversion = self.COMMON_HEAD_VERSION + return self._areaversion + + @areaversion.setter + def areaversion(self, name): + self._areaversion = name + + @property + def language(self): + self._language = 25 + return self._language + + @property + def productManufacturer(self): + return self._productManufacturer + + @productManufacturer.setter + def productManufacturer(self, name): + self._productManufacturer = name + + @property + def productName(self): + return self._productName + + @productName.setter + def productName(self, name): + self._productName = name + + @property + def productPartModelName(self): + return self._productPartModelName + + @productPartModelName.setter + def productPartModelName(self, name): + self._productPartModelName = name + + @property + def productSerialNumber(self): + return self._productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, name): + self._productSerialNumber = name + + @property + def productAssetTag(self): + return self._productAssetTag + + @productAssetTag.setter + def productAssetTag(self, name): + self._productAssetTag = name + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, name): + self._FRUFileID = name + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("product version:%x" % ord(self.areaversion)) + d_print("product length:%d" % self.size) + d_print("product language:%x" % self.language) + self.data = chr(ord(self.areaversion)) + \ + chr(self.size // 8) + chr(self.language) + + typelength = FruUtil.getTypeLength(self.productManufacturer) + self.data += chr(typelength) + self.data += self.productManufacturer + + self.data += chr(FruUtil.getTypeLength(self.productName)) + self.data += self.productName + + self.data += chr(FruUtil.getTypeLength(self.productPartModelName)) + self.data += self.productPartModelName + + self.data += chr(FruUtil.getTypeLength(self.productVersion)) + self.data += self.productVersion + + self.data += chr(FruUtil.getTypeLength(self.productSerialNumber)) + self.data += self.productSerialNumber + + self.data += chr(FruUtil.getTypeLength(self.productAssetTag)) + if self.productAssetTag is not None: + self.data += self.productAssetTag + + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + d_print("self.data:%d" % len(self.data)) + d_print("self.size:%d" % self.size) + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + +class MultiRecordArea(BaseArea): + pass + + +class Field(object): + + def __init__(self, fieldType="ASCII", fieldData=""): + self.fieldData = fieldData + self.fieldType = fieldType + + @property + def fieldType(self): + return self.fieldType + + @property + def fieldData(self): + return self.fieldData + + +class ipmifru(BaseArea): + _BoardInfoArea = None + _ProductInfoArea = None + _InternalUseArea = None + _ChassisInfoArea = None + _multiRecordArea = None + _productinfoAreaOffset = BaseArea.INITVALUE + _boardInfoAreaOffset = BaseArea.INITVALUE + _internalUserAreaOffset = BaseArea.INITVALUE + _chassicInfoAreaOffset = BaseArea.INITVALUE + _multiRecordAreaOffset = BaseArea.INITVALUE + _bindata = None + _bodybin = None + _version = BaseArea.COMMON_HEAD_VERSION + _zeroCheckSum = None + _frusize = 256 + + def __str__(self): + tmpstr = "" + if self.boardInfoArea.isPresent: + tmpstr += "\nboardinfoarea: \n" + tmpstr += self.boardInfoArea.__str__() + if self.productInfoArea.isPresent: + tmpstr += "\nproductinfoarea: \n" + tmpstr += self.productInfoArea.__str__() + return tmpstr + + def decodeBin(self, eeprom): + commonHead = eeprom[0:8] + d_print("decode version %x" % ord(commonHead[0])) + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): + raise FruException("HEAD VERSION error,not Fru format!", -10) + if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): + strtemp = "check header checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) + raise FruException(strtemp, -3) + if ord(commonHead[1]) != ord(self.INITVALUE): + d_print("Internal Use Area is present") + self.internalUseArea = InternalUseArea( + name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) + self.internalUseArea.isPresent = True + self.internalUserAreaOffset = ord(commonHead[1]) + self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( + self.internalUserAreaOffset * 8 + self.internalUseArea.size)] + if ord(commonHead[2]) != ord(self.INITVALUE): + d_print("Chassis Info Area is present") + self.chassisInfoArea = ChassisInfoArea( + name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) + self.chassisInfoArea.isPresent = True + self.chassicInfoAreaOffset = ord(commonHead[2]) + self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( + self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] + if ord(commonHead[3]) != ord(self.INITVALUE): + self.boardInfoArea = BoardInfoArea( + name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) + self.boardInfoArea.isPresent = True + self.boardInfoAreaOffset = ord(commonHead[3]) + self.boardInfoArea.size = ord( + eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8 + d_print("Board Info Area is present size:%d" % + (self.boardInfoArea.size)) + self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( + self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] + if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + (FruUtil.checksum( + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.boardInfoArea.decodedata() + if ord(commonHead[4]) != ord(self.INITVALUE): + d_print("Product Info Area is present") + self.productInfoArea = ProductInfoArea( + name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) + self.productInfoArea.isPresent = True + self.productinfoAreaOffset = ord(commonHead[4]) + d_print("length offset value: %02x" % + ord(eeprom[self.productinfoAreaOffset * 8 + 1])) + self.productInfoArea.size = ord( + eeprom[self.productinfoAreaOffset * 8 + 1]) * 8 + d_print("Product Info Area is present size:%d" % + (self.productInfoArea.size)) + + self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: ( + self.productinfoAreaOffset * 8 + self.productInfoArea.size)] + if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]): + strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.productInfoArea.decodedata() + if ord(commonHead[5]) != ord(self.INITVALUE): + self.multiRecordArea = MultiRecordArea( + name="MultiRecord record Area ") + d_print("MultiRecord record present") + self.multiRecordArea.isPresent = True + self.multiRecordAreaOffset = ord(commonHead[5]) + self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: ( + self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)] + + def initDefault(self): + self.version = self.COMMON_HEAD_VERSION + self.internalUserAreaOffset = self.INITVALUE + self.chassicInfoAreaOffset = self.INITVALUE + self.boardInfoAreaOffset = self.INITVALUE + self.productinfoAreaOffset = self.INITVALUE + self.multiRecordAreaOffset = self.INITVALUE + self.zeroCheckSum = self.INITVALUE + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + self.productInfoArea = None + self.internalUseArea = None + self.boardInfoArea = None + self.chassisInfoArea = None + self.multiRecordArea = None + # self.recalcute() + + @property + def version(self): + return self._version + + @version.setter + def version(self, name): + self._version = name + + @property + def internalUserAreaOffset(self): + return self._internalUserAreaOffset + + @internalUserAreaOffset.setter + def internalUserAreaOffset(self, obj): + self._internalUserAreaOffset = obj + + @property + def chassicInfoAreaOffset(self): + return self._chassicInfoAreaOffset + + @chassicInfoAreaOffset.setter + def chassicInfoAreaOffset(self, obj): + self._chassicInfoAreaOffset = obj + + @property + def productinfoAreaOffset(self): + return self._productinfoAreaOffset + + @productinfoAreaOffset.setter + def productinfoAreaOffset(self, obj): + self._productinfoAreaOffset = obj + + @property + def boardInfoAreaOffset(self): + return self._boardInfoAreaOffset + + @boardInfoAreaOffset.setter + def boardInfoAreaOffset(self, obj): + self._boardInfoAreaOffset = obj + + @property + def multiRecordAreaOffset(self): + return self._multiRecordAreaOffset + + @multiRecordAreaOffset.setter + def multiRecordAreaOffset(self, obj): + self._multiRecordAreaOffset = obj + + @property + def zeroCheckSum(self): + return self._zeroCheckSum + + @zeroCheckSum.setter + def zeroCheckSum(self, obj): + self._zeroCheckSum = obj + + @property + def productInfoArea(self): + return self._ProductInfoArea + + @productInfoArea.setter + def productInfoArea(self, obj): + self._ProductInfoArea = obj + + @property + def internalUseArea(self): + return self._InternalUseArea + + @internalUseArea.setter + def internalUseArea(self, obj): + self.internalUseArea = obj + + @property + def boardInfoArea(self): + return self._BoardInfoArea + + @boardInfoArea.setter + def boardInfoArea(self, obj): + self._BoardInfoArea = obj + + @property + def chassisInfoArea(self): + return self._ChassisInfoArea + + @chassisInfoArea.setter + def chassisInfoArea(self, obj): + self._ChassisInfoArea = obj + + @property + def multiRecordArea(self): + return self._multiRecordArea + + @multiRecordArea.setter + def multiRecordArea(self, obj): + self._multiRecordArea = obj + + @property + def bindata(self): + return self._bindata + + @bindata.setter + def bindata(self, obj): + self._bindata = obj + + @property + def bodybin(self): + return self._bodybin + + @bodybin.setter + def bodybin(self, obj): + self._bodybin = obj + + def recalcuteCommonHead(self): + self.bindata = "" + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) + if self.internalUseArea is not None and self.internalUseArea.isPresent: + self.internalUserAreaOffset = self.offset // 8 + self.offset += self.internalUseArea.size + d_print("internalUseArea is present offset:%d" % self.offset) + + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + self.chassicInfoAreaOffset = self.offset // 8 + self.offset += self.chassisInfoArea.size + d_print("chassisInfoArea is present offset:%d" % self.offset) + + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + self.boardInfoAreaOffset = self.offset // 8 + self.offset += self.boardInfoArea.size + d_print("boardInfoArea is present offset:%d" % self.offset) + d_print("boardInfoArea is present size:%d" % + self.boardInfoArea.size) + + if self.productInfoArea is not None and self.productInfoArea.isPresent: + self.productinfoAreaOffset = self.offset // 8 + self.offset += self.productInfoArea.size + d_print("productInfoArea is present offset:%d" % self.offset) + + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + self.multiRecordAreaOffset = self.offset // 8 + d_print("multiRecordArea is present offset:%d" % self.offset) + + if self.internalUserAreaOffset == self.INITVALUE: + self.internalUserAreaOffset = 0 + if self.productinfoAreaOffset == self.INITVALUE: + self.productinfoAreaOffset = 0 + if self.chassicInfoAreaOffset == self.INITVALUE: + self.chassicInfoAreaOffset = 0 + if self.boardInfoAreaOffset == self.INITVALUE: + self.boardInfoAreaOffset = 0 + if self.multiRecordAreaOffset == self.INITVALUE: + self.multiRecordAreaOffset = 0 + + self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset + - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff + d_print("zerochecksum:%x" % self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) + + self.bindata = self.data + self.bodybin + totallen = len(self.bindata) + d_print("totallen %d" % totallen) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) + else: + raise FruException('bin data more than %d' % self._frusize, -2) + + def recalcutebin(self): + self.bodybin = "" + if self.internalUseArea is not None and self.internalUseArea.isPresent: + d_print("internalUseArea present") + self.bodybin += self.internalUseArea.data + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + d_print("chassisInfoArea present") + self.bodybin += self.chassisInfoArea.data + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + d_print("boardInfoArea present") + self.boardInfoArea.recalcute() + self.bodybin += self.boardInfoArea.data + if self.productInfoArea is not None and self.productInfoArea.isPresent: + d_print("productInfoAreapresent") + self.productInfoArea.recalcute() + self.bodybin += self.productInfoArea.data + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + d_print("multiRecordArea present") + self.bodybin += self.productInfoArea.data + + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size + self.recalcutebin() + self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py old mode 100755 new mode 100644 index f9cbb31be401..e300df137ef9 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/monitor.py @@ -1,113 +1,235 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- -""" -* onboard temperature sensors -* FAN trays -* PSU -""" +# * onboard temperature sensors +# * FAN trays +# * PSU +# import os import xml.etree.ElementTree as ET import glob +import json +from decimal import Decimal +from fru import ipmifru + MAILBOX_DIR = "/sys/bus/i2c/devices/" -PORTS_DIR = "/sys/class/net/" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + CONFIG_NAME = "dev.xml" -def getPMCreg(location): +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + return val + + +def get_board_id(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +boardid = get_board_id() +boardairflow = getboardairflow() + + +DEV_XML_FILE_LIST = [ + "dev_" + boardid + "_" + boardairflow + ".xml", + "dev_" + boardid + ".xml", + "dev_" + boardairflow + ".xml", +] + + +def dev_file_read(path, offset, read_len): retval = "ERR" + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + return False, "%s %s not found" % (retval, path) + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, "%s %s" % (retval, msg) + finally: + if fd > 0: + os.close(fd) + return True, val_list + + +def getPMCreg(location): + retval = 'ERR' if not os.path.isfile(location): return "%s %s notfound" % (retval, location) try: - with open(location, "r") as fd: + with open(location, 'r') as fd: retval = fd.read() - except Exception: - pass - # logging.error("Unable to open ", location, "file !") + except Exception as error: + return "ERR %s" % str(error) - retval = retval.rstrip("\r\n") + retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval # Get a mailbox register def get_pmc_register(reg_name): - retval = "ERR" - if reg_name[0:4] == "/rif" or reg_name[0:4] == "/ma1" or reg_name[0:4] == "/eth": - mb_reg_file = PORTS_DIR + reg_name - else: - mb_reg_file = MAILBOX_DIR + reg_name + retval = 'ERR' + mb_reg_file = reg_name filepath = glob.glob(mb_reg_file) if len(filepath) == 0: return "%s %s notfound" % (retval, mb_reg_file) - mb_reg_file = filepath[0] # use first found patch + mb_reg_file = filepath[0] if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' return "%s %s notfound" % (retval, mb_reg_file) try: - with open(mb_reg_file, "r") as fd: + with open(mb_reg_file, 'rb') as fd: retval = fd.read() - except Exception: - pass - # logging.error("Unable to open ", mb_reg_file, "file !") + retval = typeTostr(retval) + except Exception as error: + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) - retval = retval.rstrip("\r\n") + retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval -class checktype: +class checktype(): def __init__(self, test1): self.test1 = test1 @staticmethod - def check(name, location, bit, value, tips, err1): - psu_status = int(get_pmc_register(location), 16) - val = (psu_status & (1 << bit)) >> bit - if val != value: - err1["errmsg"] = tips - err1["code"] = -1 - return -1 - else: - err1["errmsg"] = "none" - err1["code"] = 0 - return 0 - - @staticmethod - def getValue(location, bit, type): - value_t = get_pmc_register(location) - if value_t.startswith("ERR"): + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) return value_t - if type == 1: - return float(value_t) / 1000 - elif type == 2: - return float(value_t) / 100 - elif type == 3: - psu_status = int(value_t, 16) - return (psu_status & (1 << bit)) >> bit - elif type == 4: - return int(value_t, 10) - else: + except Exception as e: + value_t = "ERR %s" % str(e) return value_t - # temperature + # fanFRU @staticmethod - def getTemp(self, name, location, ret_t): - ret2 = self.getValue(location + "temp1_input", " ", 1) - ret3 = self.getValue(location + "temp1_max", " ", 1) - ret4 = self.getValue(location + "temp1_max_hyst", " ", 1) - ret_t["temp1_input"] = ret2 - ret_t["temp1_max"] = ret3 - ret_t["temp1_max_hyst"] = ret4 + def decodeBinByValue(retval): + fru = ipmifru() + fru.decodeBin(retval) + return fru @staticmethod - def getLM75(name, location, result): - c1 = checktype - r1 = {} - c1.getTemp(c1, name, location, r1) - result[name] = r1 + def getfruValue(prob_t, root, val): + try: + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) + fanpro = {} + ret = checktype.decodeBinByValue(binval) + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = str(int(ret.productInfoArea.productVersion, 16)) + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] + return fanpro + except Exception as error: + return "ERR " + str(error) + @staticmethod + def getslotfruValue(val): + try: + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + slotpro = {} + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber + return slotpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getpsufruValue(prob_t, root, val): + try: + psu_match = False + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + psupro = {} + ret = checktype.decodeBinByValue(binval) + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name in psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro + except Exception as error: + return "ERR " + str(error) -class status: + +class status(): def __init__(self, productname): self.productname = productname @@ -119,10 +241,12 @@ def getETroot(filename): @staticmethod def getDecodValue(collection, decode): - decodes = collection.find("decode") + decodes = collection.find('decode') testdecode = decodes.find(decode) test = {} - for neighbor in testdecode.iter("code"): + if testdecode is None: + return test + for neighbor in testdecode.iter('code'): test[neighbor.attrib["key"]] = neighbor.attrib["value"] return test @@ -136,37 +260,67 @@ def getETValue(a, filename, tagname): for neighbor in root.iter(tagname): prob_t = {} prob_t = neighbor.attrib - prob_t["errcode"] = 0 - prob_t["errmsg"] = "" + prob_t['errcode'] = 0 + prob_t['errmsg'] = '' for pros in neighbor.iter("property"): - ret = dict(neighbor.attrib.items() + pros.attrib.items()) - if "type" not in ret.keys(): + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) + if ret.get('e2type') == 'fru' and ret.get("name") == "fru": + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break + prob_t.update(fruval) + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): val = "0" else: val = ret["type"] - if "bit" not in ret.keys(): + if 'bit' not in ret.keys(): bit = "0" else: bit = ret["bit"] - s = checktype.getValue(ret["location"], int(bit), int(val)) + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) if isinstance(s, str) and s.startswith("ERR"): - prob_t["errcode"] = -1 - prob_t["errmsg"] = s - if "default" in ret.keys(): - rt = status.getDecodValue(root, ret["decode"]) - prob_t["errmsg"] = rt[str(s)] + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] if str(s) != ret["default"]: - prob_t["errcode"] = -1 + prob_t['errcode'] = -1 break else: - if "decode" in ret.keys(): - rt = status.getDecodValue(root, ret["decode"]) - if ( - ret["decode"] == "psutype" - and s.replace("\x00", "").rstrip() not in rt.keys() - ): # PSU type detect - prob_t["errcode"] = -1 - prob_t["errmsg"] = "%s" % ("The power type does not match, please check whether the power is correct!") + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) else: s = rt[str(s).replace("\x00", "").rstrip()] name = ret["name"] @@ -187,46 +341,39 @@ def getCPUValue(a, filename, tagname): for i in range(len(L)): prob_t = {} prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) - prob_t["temp"] = ( - float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 - ) - prob_t["alarm"] = ( - float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 - ) - prob_t["crit"] = ( - float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 - ) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 a.append(prob_t) @staticmethod def getFileName(): - return os.path.dirname(os.path.realpath(__file__)) + "/" + CONFIG_NAME - - @staticmethod - def getFan(ret): - _filename = status.getFileName() - _tagname = "fan" - status.getvalue(ret, _filename, _tagname) + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME @staticmethod def checkFan(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "fan" status.getETValue(ret, _filename, _tagname) @staticmethod def getTemp(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "temp" status.getETValue(ret, _filename, _tagname) @staticmethod def getPsu(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "psu" status.getETValue(ret, _filename, _tagname) @@ -237,8 +384,19 @@ def getcputemp(ret): status.getCPUValue(ret, _filename, _tagname) @staticmethod - def getMgmtRx(ret): + def getDcdc(ret): + _filename = status.getFileName() + _tagname = "dcdc" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmacpower(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() - _tagname = "mgmt_rx" + _tagname = "macpower" status.getETValue(ret, _filename, _tagname) diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml index 90ebf1740641..7b026cec395e 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pcie.yaml @@ -82,6 +82,12 @@ 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: 1d fn: '0' @@ -109,9 +115,8 @@ - bus: '01' dev: '00' fn: '0' - id: '1533' - name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev - 03)' + id: b873 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b873 (rev 01)' - bus: '03' dev: '00' fn: '0' @@ -149,8 +154,14 @@ - bus: '07' dev: '00' fn: '0' - id: b873 - name: 'Ethernet controller: Broadcom Limited Device b873 (rev 01)' + id: '1537' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Backplane Connection + (rev 03)' +- bus: 08 + dev: '00' + fn: '0' + id: '7022' + name: 'Memory controller: Xilinx Corporation Device 7022' - bus: ff dev: 0b fn: '0' diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf/pd-plugin.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf/pd-plugin.json deleted file mode 100644 index ffa06ff74303..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf/pd-plugin.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "XCVR": { - "xcvr_present": { - "i2c": { - "valmap-SFP28": { - "1": true, - "0": false - }, - "valmap-QSFP28": { - "1": true, - "0": false - } - } - } - }, - - "PSU": { - "psu_present": { - "i2c": { - "valmap": { - "1": true, - "0": false - } - } - }, - - "psu_power_good": { - "i2c": { - "valmap": { - "1": true, - "0": false - } - } - }, - - "psu_fan_dir": { - "i2c": { - "valmap": { - "F2B": "EXHAUST", - "B2F": "INTAKE" - } - } - }, - "PSU_FAN_MAX_SPEED": "18000" - }, - - "FAN": { - "direction": { - "i2c": { - "valmap": { - "1": "INTAKE", - "0": "EXHAUST" - } - } - }, - "present": { - "i2c": { - "valmap": { - "1": true, - "0": false - } - } - }, - "duty_cycle_to_pwm": "lambda dc: dc*255/100", - "pwm_to_duty_cycle": "lambda pwm: pwm*100/255" - } -} diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf/pddf-device.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf/pddf-device.json deleted file mode 100644 index 4fa2582830f7..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf/pddf-device.json +++ /dev/null @@ -1,6332 +0,0 @@ -{ - "PLATFORM": { - "num_psus": 2, - "num_fantrays": 4, - "num_fans_pertray": 1, - "num_ports": 56, - "num_temps": 3, - "pddf_dev_types": { - "description": "RA-B6510-48v8c", - "CPLD": [ - "i2c_cpld" - ], - "PSU": [ - "psu_eeprom", - "psu_pmbus" - ], - "FAN": [ - "fan_ctrl", - "fan_cpld", - "fan_eeprom" - ], - "PORT_MODULE": [ - "pddf_xcvr", - "optoe1", - "optoe2" - ] - }, - "std_kos": [ - "i2c-ismt", - "i2c-i801", - "i2c_dev", - "i2c_gpio", - "i2c_algo_bit", - "i2c_mux_pca9641", - "i2c_mux_pca954x force_create_bus=1", - "lm75", - "optoe", - "at24", - "pmbus_core" - ], - "pddf_kos": [ - "pddf_client_module", - "pddf_cpld_module", - "pddf_cpld_driver", - "pddf_mux_module", - "pddf_xcvr_module", - "pddf_xcvr_driver_module", - "pddf_psu_driver_module", - "pddf_psu_module", - "pddf_fan_driver_module", - "pddf_fan_module", - "pddf_led_module", - "pddf_sysstatus_module" - ], - "custom_kos": [ - "ragile_platform", - "rg_cpld", - "rg_fan", - "rg_psu", - "rg_gpio_xeon", - "csu550" - ] - - }, - - "SYSTEM": { - "dev_info": { - "device_type": "CPU", - "device_name": "ROOT_COMPLEX", - "device_parent": null - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-0", - "dev": "SMBUS0" - }, { - "dev_name": "i2c-1", - "dev": "I2C-GPIO0" - }, { - "dev_name": "i2c-2", - "dev": "SMBUS1" - }] - } - }, - - "SMBUS0": { - "dev_info": { - "device_type": "SMBUS", - "device_name": "SMBUS0", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x0" - }, - "DEVICES": [{ - "dev": "CPU_CPLD" - }, - { - "dev": "CONNECT_BOARD_CPLD1" - } - ] - } - }, - - "CPU_CPLD": { - "dev_info": { - "device_type": "CPLD", - "device_name": "CPU_CPLD", - "device_parent": "SMBUS0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x0", - "dev_addr": "0x0d", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "CONNECT_BOARD_CPLD1": { - "dev_info": { - "device_type": "CPLD", - "device_name": "CONNECT_BOARD_CPLD1", - "device_parent": "SMBUS0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x0", - "dev_addr": "0x32", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "SMBUS1": { - "dev_info": { - "device_type": "SMBUS", - "device_name": "SMBUS1", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x2" - }, - "DEVICES": [{ - "dev": "MAC_BOARD_CPLD1_A" - }, - { - "dev": "MAC_BOARD_CPLD2_A" - }, - { - "dev": "CONNECT_BOARD_CPLD2" - }, - { - "dev": "FAN-CTRL" - }, - { - "dev": "TEMP1" - }, - { - "dev": "TEMP2" - }, - { - "dev": "TEMP3" - }, - { - "dev": "EEPROM1" - }, - { - "dev": "MUX1" - } - ] - } - }, - - "MAC_BOARD_CPLD1_A": { - "dev_info": { - "device_type": "CPLD", - "device_name": "MAC_BOARD_CPLD1_A", - "device_parent": "SMBUS1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x33", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "MAC_BOARD_CPLD2_A": { - "dev_info": { - "device_type": "CPLD", - "device_name": "MAC_BOARD_CPLD2_A", - "device_parent": "SMBUS1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x35", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "FAN-CTRL": { - "dev_info": { - "device_type": "FAN", - "device_name": "FAN-CTRL", - "device_parent": "SMBUS1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x66", - "dev_type": "fan_cpld" - }, - "dev_attr": { - "num_fantrays": "4" - }, - "attr_list": [{ - "attr_name": "fan1_present", - "attr_devtype": "cpld", - "attr_devaddr": "0x37", - "attr_offset": "0x30", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan2_present", - "attr_devtype": "cpld", - "attr_devaddr": "0x37", - "attr_offset": "0x30", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan3_present", - "attr_devtype": "cpld", - "attr_devaddr": "0x37", - "attr_offset": "0x30", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan4_present", - "attr_devtype": "cpld", - "attr_devaddr": "0x37", - "attr_offset": "0x30", - "attr_mask": "0x8", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan1_input", - "attr_devname": "CONNECT_BOARD_CPLD2", - "attr_devtype": "cpld", - "attr_devaddr": "0x37", - "attr_offset": "0x1b", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan2_input", - "attr_devname": "CONNECT_BOARD_CPLD2", - "attr_devtype": "cpld", - "attr_devaddr": "0x37", - "attr_offset": "0x1d", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan3_input", - "attr_devname": "CONNECT_BOARD_CPLD2", - "attr_devtype": "cpld", - "attr_devaddr": "0x37", - "attr_offset": "0x1f", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan4_input", - "attr_devname": "CONNECT_BOARD_CPLD2", - "attr_devtype": "cpld", - "attr_devaddr": "0x37", - "attr_offset": "0x21", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan1_pwm", - "attr_devtype": "cpld", - "attr_devaddr": "0x32", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan2_pwm", - "attr_devtype": "cpld", - "attr_devaddr": "0x32", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan3_pwm", - "attr_devtype": "cpld", - "attr_devaddr": "0x32", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan4_pwm", - "attr_devtype": "cpld", - "attr_devaddr": "0x32", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - } - ] - } - }, - - "CONNECT_BOARD_CPLD2": { - "dev_info": { - "device_type": "CPLD", - "device_name": "CONNECT_BOARD_CPLD2", - "device_parent": "SMBUS1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x37", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "TEMP1": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "MAC_TEMP_INLET", - "device_parent": "SMBUS1" - }, - "dev_attr": { - "display_name": "Temp_1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "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": "MAC_TEMP_OUTLET", - "device_parent": "SMBUS1" - }, - "dev_attr": { - "display_name": "Temp_2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "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": "MAC_TEMP_HOTEST", - "device_parent": "SMBUS1" - }, - "dev_attr": { - "display_name": "Temp_3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "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" - } - ] - } - }, - - "EEPROM1": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "EEPROM1", - "device_parent": "SMBUS1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x57", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "MUX1": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX1", - "device_parent": "SMBUS1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x70", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x3" - }, - "channel": [{ - "chn": "0", - "dev": "FAN1-EEPROM" - }, - { - "chn": "1", - "dev": "FAN2-EEPROM" - }, - { - "chn": "2", - "dev": "FAN3-EEPROM" - }, - { - "chn": "3", - "dev": "FAN4-EEPROM" - }, - { - "chn": "4", - "dev": "PSU1" - }, - { - "chn": "5", - "dev": "PSU2" - } - ] - } - }, - - "FAN1-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN1-EEPROM", - "device_parent": "MUX1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x53", - "dev_type": "rg_fan" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN2-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN2-EEPROM", - "device_parent": "MUX1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x53", - "dev_type": "rg_fan" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN3-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN3-EEPROM", - "device_parent": "MUX1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x53", - "dev_type": "rg_fan" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN4-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN4-EEPROM", - "device_parent": "MUX1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x53", - "dev_type": "rg_fan" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "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" - }, - { - "itf": "eeprom", - "dev": "PSU1-EEPROM" - } - ] - } - }, - - "PSU1-PMBUS": { - "dev_info": { - "device_type": "PSU-PMBUS", - "device_name": "PSU1-PMBUS", - "device_parent": "MUX1", - "virt_parent": "PSU1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7", - "dev_addr": "0x58", - "dev_type": "psu_pmbus" - }, - "attr_list": [{ - "attr_name": "psu_present", - "attr_devaddr": "0x37", - "attr_devtype": "cpld", - "attr_offset": "0x51", - "attr_mask": "0x1", - "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": "12" - }, - { - "attr_name": "psu_power_good", - "attr_devaddr": "0x37", - "attr_devtype": "cpld", - "attr_offset": "0x51", - "attr_mask": "0x2", - "attr_cmpval": "0x2", - "attr_len": "1" - }, - { - "attr_name": "psu_mfr_id", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0x99", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "10" - }, - { - "attr_name": "psu_fan_dir", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0xc3", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "5" - }, - { - "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_fan1_speed_rpm", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0x90", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "2" - } - ] - } - }, - - "PSU1-EEPROM": { - "dev_info": { - "device_type": "PSU-EEPROM", - "device_name": "PSU1-EEPROM", - "device_parent": "MUX1", - "virt_parent": "PSU1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7", - "dev_addr": "0x50", - "dev_type": "psu_eeprom" - }, - "attr_list": [{ - "attr_name": "psu_serial_num", - "attr_devaddr": "0x50", - "attr_devtype": "eeprom", - "attr_offset": "0x38", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "20" - }] - } - }, - - "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" - }, - { - "itf": "eeprom", - "dev": "PSU2-EEPROM" - } - ] - } - }, - - "PSU2-PMBUS": { - "dev_info": { - "device_type": "PSU-PMBUS", - "device_name": "PSU2-PMBUS", - "device_parent": "MUX1", - "virt_parent": "PSU2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8", - "dev_addr": "0x5b", - "dev_type": "psu_pmbus" - }, - "attr_list": [{ - "attr_name": "psu_present", - "attr_devaddr": "0x37", - "attr_devtype": "cpld", - "attr_offset": "0x51", - "attr_mask": "0x8", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "psu_model_name", - "attr_devaddr": "0x5b", - "attr_devtype": "pmbus", - "attr_offset": "0x35", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "12" - }, - { - "attr_name": "psu_power_good", - "attr_devaddr": "0x37", - "attr_devtype": "cpld", - "attr_offset": "0x51", - "attr_mask": "0x10", - "attr_cmpval": "0x10", - "attr_len": "1" - }, - { - "attr_name": "psu_mfr_id", - "attr_devaddr": "0x5b", - "attr_devtype": "pmbus", - "attr_offset": "0x99", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "10" - }, - { - "attr_name": "psu_fan_dir", - "attr_devaddr": "0x5b", - "attr_devtype": "pmbus", - "attr_offset": "0xc3", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "5" - }, - { - "attr_name": "psu_v_out", - "attr_devaddr": "0x5b", - "attr_devtype": "pmbus", - "attr_offset": "0x8b", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "2" - }, - { - "attr_name": "psu_i_out", - "attr_devaddr": "0x5b", - "attr_devtype": "pmbus", - "attr_offset": "0x8c", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "2" - }, - { - "attr_name": "psu_p_out", - "attr_devaddr": "0x5b", - "attr_devtype": "pmbus", - "attr_offset": "0x96", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "2" - }, - { - "attr_name": "psu_fan1_speed_rpm", - "attr_devaddr": "0x5b", - "attr_devtype": "pmbus", - "attr_offset": "0x90", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "2" - }, - { - "attr_name": "psu_temp1_input", - "attr_devaddr": "0x5b", - "attr_devtype": "pmbus", - "attr_offset": "0x8d", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "2" - } - ] - } - }, - - "PSU2-EEPROM": { - "dev_info": { - "device_type": "PSU-EEPROM", - "device_name": "PSU2-EEPROM", - "device_parent": "MUX1", - "virt_parent": "PSU2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8", - "dev_addr": "0x53", - "dev_type": "psu_eeprom" - }, - "attr_list": [{ - "attr_name": "psu_serial_num", - "attr_devaddr": "0x53", - "attr_devtype": "eeprom", - "attr_offset": "0x38", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "20" - }] - } - }, - - "I2C-GPIO0": { - "dev_info": { - "device_type": "I2C-GPIO", - "device_name": "I2C-GPIO0", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x1" - }, - "DEVICES": [{ - "dev": "MAC_BOARD_CPLD1_B" - }, - { - "dev": "MAC_BOARD_CPLD2_B" - }, - { - "dev": "PORT-MUX1" - }, - { - "dev": "PORT-MUX2" - }, - { - "dev": "PORT-MUX3" - }, - { - "dev": "PORT-MUX4" - }, - { - "dev": "PORT-MUX5" - }, - { - "dev": "PORT-MUX6" - }, - { - "dev": "PORT-MUX7" - }, - { - "dev": "PORT-MUX8" - } - ] - } - }, - - "MAC_BOARD_CPLD1_B": { - "dev_info": { - "device_type": "CPLD", - "device_name": "MAC_BOARD_CPLD1_B", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x34", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "MAC_BOARD_CPLD2_B": { - "dev_info": { - "device_type": "CPLD", - "device_name": "MAC_BOARD_CPLD2_B", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x36", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "PORT-MUX1": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX1", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x70", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0xb" - }, - "channel": [{ - "chn": "0", - "dev": "PORT1" - }, - { - "chn": "1", - "dev": "PORT2" - }, - { - "chn": "2", - "dev": "PORT3" - }, - { - "chn": "3", - "dev": "PORT4" - }, - { - "chn": "4", - "dev": "PORT5" - }, - { - "chn": "5", - "dev": "PORT6" - }, - { - "chn": "6", - "dev": "PORT7" - }, - { - "chn": "7", - "dev": "PORT8" - } - ] - } - }, - - "PORT-MUX2": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX2", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x71", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x13" - }, - "channel": [{ - "chn": "0", - "dev": "PORT9" - }, - { - "chn": "1", - "dev": "PORT10" - }, - { - "chn": "2", - "dev": "PORT11" - }, - { - "chn": "3", - "dev": "PORT12" - }, - { - "chn": "4", - "dev": "PORT13" - }, - { - "chn": "5", - "dev": "PORT14" - }, - { - "chn": "6", - "dev": "PORT15" - }, - { - "chn": "7", - "dev": "PORT16" - } - ] - } - }, - - "PORT-MUX3": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX3", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x72", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x1b" - }, - "channel": [{ - "chn": "0", - "dev": "PORT17" - }, - { - "chn": "1", - "dev": "PORT18" - }, - { - "chn": "2", - "dev": "PORT19" - }, - { - "chn": "3", - "dev": "PORT20" - }, - { - "chn": "4", - "dev": "PORT21" - }, - { - "chn": "5", - "dev": "PORT22" - }, - { - "chn": "6", - "dev": "PORT23" - }, - { - "chn": "7", - "dev": "PORT24" - } - ] - } - }, - - "PORT-MUX4": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX4", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x73", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x23" - }, - "channel": [{ - "chn": "0", - "dev": "PORT25" - }, - { - "chn": "1", - "dev": "PORT26" - }, - { - "chn": "2", - "dev": "PORT27" - }, - { - "chn": "3", - "dev": "PORT28" - }, - { - "chn": "4", - "dev": "PORT29" - }, - { - "chn": "5", - "dev": "PORT30" - }, - { - "chn": "6", - "dev": "PORT31" - }, - { - "chn": "7", - "dev": "PORT32" - } - ] - } - }, - - "PORT-MUX5": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX5", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x74", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x2b" - }, - "channel": [{ - "chn": "0", - "dev": "PORT33" - }, - { - "chn": "1", - "dev": "PORT34" - }, - { - "chn": "2", - "dev": "PORT35" - }, - { - "chn": "3", - "dev": "PORT36" - }, - { - "chn": "4", - "dev": "PORT37" - }, - { - "chn": "5", - "dev": "PORT38" - }, - { - "chn": "6", - "dev": "PORT39" - }, - { - "chn": "7", - "dev": "PORT40" - } - ] - } - }, - - "PORT-MUX6": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX6", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x75", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x33" - }, - "channel": [{ - "chn": "0", - "dev": "PORT41" - }, - { - "chn": "1", - "dev": "PORT42" - }, - { - "chn": "2", - "dev": "PORT43" - }, - { - "chn": "3", - "dev": "PORT44" - }, - { - "chn": "4", - "dev": "PORT45" - }, - { - "chn": "5", - "dev": "PORT46" - }, - { - "chn": "6", - "dev": "PORT47" - }, - { - "chn": "7", - "dev": "PORT48" - } - ] - } - }, - - "PORT-MUX7": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX7", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x76", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x3b" - }, - "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" - } - ] - } - }, - - "PORT-MUX8": { - "dev_info": { - "device_type": "MUX", - "device_name": "PORT-MUX8", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x43" - }, - "channel": [] - } - }, - - "PORT1": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT1", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "1" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT1-EEPROM" - }, { - "itf": "control", - "dev": "PORT1-CTRL" - }] - } - }, - - "PORT1-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT1-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT1-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT1-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT2": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT2", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "2" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT2-EEPROM" - }, { - "itf": "control", - "dev": "PORT2-CTRL" - }] - } - }, - - "PORT2-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT2-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT2-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT2-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT3": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT3", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "3" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT3-EEPROM" - }, { - "itf": "control", - "dev": "PORT3-CTRL" - }] - } - }, - - "PORT3-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT3-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xd", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT3-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT3-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xd", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT4": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT4", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "4" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT4-EEPROM" - }, { - "itf": "control", - "dev": "PORT4-CTRL" - }] - } - }, - - "PORT4-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT4-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xe", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT4-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT4-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xe", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x8", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x8", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x8", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT5": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT5", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "5" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT5-EEPROM" - }, { - "itf": "control", - "dev": "PORT5-CTRL" - }] - } - }, - - "PORT5-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT5-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT5" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xf", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT5-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT5-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT5" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xf", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT6": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT6", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "6" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT6-EEPROM" - }, { - "itf": "control", - "dev": "PORT6-CTRL" - }] - } - }, - - "PORT6-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT6-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x10", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT6-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT6-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x10", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT7": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT7", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "7" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT7-EEPROM" - }, { - "itf": "control", - "dev": "PORT7-CTRL" - }] - } - }, - - "PORT7-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT7-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x11", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT7-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT7-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x11", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT8": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT8", - "device_parent": "PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "8" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT8-EEPROM" - }, { - "itf": "control", - "dev": "PORT8-CTRL" - }] - } - }, - - "PORT8-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT8-EEPROM", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT8" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x12", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT8-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT8-CTRL", - "device_parent": "PORT-MUX1", - "virt_parent": "PORT8" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x12", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT9": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT9", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "9" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT9-EEPROM" - }, { - "itf": "control", - "dev": "PORT9-CTRL" - }] - } - }, - - "PORT9-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT9-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT9" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x13", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT9-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT9-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT9" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x13", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT10": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT10", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "10" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT10-EEPROM" - }, { - "itf": "control", - "dev": "PORT10-CTRL" - }] - } - }, - - "PORT10-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT10-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x14", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT10-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT10-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x14", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT11": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT11", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "11" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT11-EEPROM" - }, { - "itf": "control", - "dev": "PORT11-CTRL" - }] - } - }, - - "PORT11-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT11-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT11" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x15", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT11-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT11-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT11" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x15", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT12": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT12", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "12" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT12-EEPROM" - }, { - "itf": "control", - "dev": "PORT12-CTRL" - }] - } - }, - - "PORT12-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT12-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT12" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x16", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT12-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT12-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT12" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x16", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT13": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT13", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "13" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT13-EEPROM" - }, { - "itf": "control", - "dev": "PORT13-CTRL" - }] - } - }, - - "PORT13-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT13-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT13" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x17", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT13-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT13-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT13" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x17", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT14": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT14", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "14" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT14-EEPROM" - }, { - "itf": "control", - "dev": "PORT14-CTRL" - }] - } - }, - - "PORT14-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT14-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT14" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x18", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT14-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT14-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT14" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x18", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT15": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT15", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "15" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT15-EEPROM" - }, { - "itf": "control", - "dev": "PORT15-CTRL" - }] - } - }, - - "PORT15-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT15-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT15" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x19", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT15-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT15-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT15" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x19", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT16": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT16", - "device_parent": "PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "16" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT16-EEPROM" - }, { - "itf": "control", - "dev": "PORT16-CTRL" - }] - } - }, - - "PORT16-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT16-EEPROM", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT16" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1a", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT16-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT16-CTRL", - "device_parent": "PORT-MUX2", - "virt_parent": "PORT16" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT17": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT17", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "17" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT17-EEPROM" - }, { - "itf": "control", - "dev": "PORT17-CTRL" - }] - } - }, - - "PORT17-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT17-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT17" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1b", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT17-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT17-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT17" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT18": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT18", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "18" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT18-EEPROM" - }, { - "itf": "control", - "dev": "PORT18-CTRL" - }] - } - }, - - "PORT18-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT18-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT18" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1c", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT18-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT18-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT18" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT19": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT19", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "19" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT19-EEPROM" - }, { - "itf": "control", - "dev": "PORT19-CTRL" - }] - } - }, - - "PORT19-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT19-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT19" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1d", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT19-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT19-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT19" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT20": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT20", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "20" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT20-EEPROM" - }, { - "itf": "control", - "dev": "PORT20-CTRL" - }] - } - }, - - "PORT20-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT20-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT20" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1e", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT20-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT20-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT20" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT21": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT21", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "21" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT21-EEPROM" - }, { - "itf": "control", - "dev": "PORT21-CTRL" - }] - } - }, - - "PORT21-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT21-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT21" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1f", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT21-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT21-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT21" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT22": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT22", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "22" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT22-EEPROM" - }, { - "itf": "control", - "dev": "PORT22-CTRL" - }] - } - }, - - "PORT22-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT22-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT22" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x20", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT22-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT22-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT22" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x20", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT23": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT23", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "23" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT23-EEPROM" - }, { - "itf": "control", - "dev": "PORT23-CTRL" - }] - } - }, - - "PORT23-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT23-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT23" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x21", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT23-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT23-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT23" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x21", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT24": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT24", - "device_parent": "PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "24" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT24-EEPROM" - }, { - "itf": "control", - "dev": "PORT24-CTRL" - }] - } - }, - - "PORT24-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT24-EEPROM", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT24" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x22", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT24-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT24-CTRL", - "device_parent": "PORT-MUX3", - "virt_parent": "PORT24" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x22", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x34", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT25": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT25", - "device_parent": "PORT-MUX4" - }, - "dev_attr": { - "dev_idx": "25" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT25-EEPROM" - }, { - "itf": "control", - "dev": "PORT25-CTRL" - }] - } - }, - - "PORT25-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT25-EEPROM", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT25" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x23", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT25-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT25-CTRL", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT25" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x23", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT26": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT26", - "device_parent": "PORT-MUX4" - }, - "dev_attr": { - "dev_idx": "26" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT26-EEPROM" - }, { - "itf": "control", - "dev": "PORT26-CTRL" - }] - } - }, - - "PORT26-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT26-EEPROM", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT26" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x24", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT26-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT26-CTRL", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT26" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x24", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT27": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT27", - "device_parent": "PORT-MUX4" - }, - "dev_attr": { - "dev_idx": "27" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT27-EEPROM" - }, { - "itf": "control", - "dev": "PORT27-CTRL" - }] - } - }, - - "PORT27-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT27-EEPROM", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT27" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x25", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT27-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT27-CTRL", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT27" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x25", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT28": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT28", - "device_parent": "PORT-MUX4" - }, - "dev_attr": { - "dev_idx": "28" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT28-EEPROM" - }, { - "itf": "control", - "dev": "PORT28-CTRL" - }] - } - }, - - "PORT28-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT28-EEPROM", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT28" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x26", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT28-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT28-CTRL", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT28" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x26", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT29": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT29", - "device_parent": "PORT-MUX4" - }, - "dev_attr": { - "dev_idx": "29" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT29-EEPROM" - }, { - "itf": "control", - "dev": "PORT29-CTRL" - }] - } - }, - - "PORT29-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT29-EEPROM", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT29" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x27", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT29-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT29-CTRL", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT29" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x27", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT30": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT30", - "device_parent": "PORT-MUX4" - }, - "dev_attr": { - "dev_idx": "30" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT30-EEPROM" - }, { - "itf": "control", - "dev": "PORT30-CTRL" - }] - } - }, - - "PORT30-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT30-EEPROM", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT30" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x28", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT30-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT30-CTRL", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT30" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x28", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT31": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT31", - "device_parent": "PORT-MUX4" - }, - "dev_attr": { - "dev_idx": "31" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT31-EEPROM" - }, { - "itf": "control", - "dev": "PORT31-CTRL" - }] - } - }, - - "PORT31-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT31-EEPROM", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT31" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x29", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT31-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT31-CTRL", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT31" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x29", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT32": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT32", - "device_parent": "PORT-MUX4" - }, - "dev_attr": { - "dev_idx": "32" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT32-EEPROM" - }, { - "itf": "control", - "dev": "PORT32-CTRL" - }] - } - }, - - "PORT32-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT32-EEPROM", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT32" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2a", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT32-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT32-CTRL", - "device_parent": "PORT-MUX4", - "virt_parent": "PORT32" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x60", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x40", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT33": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT33", - "device_parent": "PORT-MUX5" - }, - "dev_attr": { - "dev_idx": "33" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT33-EEPROM" - }, { - "itf": "control", - "dev": "PORT33-CTRL" - }] - } - }, - - "PORT33-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT33-EEPROM", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT33" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2b", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT33-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT33-CTRL", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT33" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT34": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT34", - "device_parent": "PORT-MUX5" - }, - "dev_attr": { - "dev_idx": "34" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT34-EEPROM" - }, { - "itf": "control", - "dev": "PORT34-CTRL" - }] - } - }, - - "PORT34-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT34-EEPROM", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT34" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2c", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT34-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT34-CTRL", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT34" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT35": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT35", - "device_parent": "PORT-MUX5" - }, - "dev_attr": { - "dev_idx": "35" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT35-EEPROM" - }, { - "itf": "control", - "dev": "PORT35-CTRL" - }] - } - }, - - "PORT35-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT35-EEPROM", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT35" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2d", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT35-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT35-CTRL", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT35" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT36": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT36", - "device_parent": "PORT-MUX5" - }, - "dev_attr": { - "dev_idx": "36" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT36-EEPROM" - }, { - "itf": "control", - "dev": "PORT36-CTRL" - }] - } - }, - - "PORT36-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT36-EEPROM", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT36" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2e", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT36-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT36-CTRL", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT36" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT37": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT37", - "device_parent": "PORT-MUX5" - }, - "dev_attr": { - "dev_idx": "37" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT37-EEPROM" - }, { - "itf": "control", - "dev": "PORT37-CTRL" - }] - } - }, - - "PORT37-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT37-EEPROM", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT37" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2f", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT37-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT37-CTRL", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT37" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT38": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT38", - "device_parent": "PORT-MUX5" - }, - "dev_attr": { - "dev_idx": "38" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT38-EEPROM" - }, { - "itf": "control", - "dev": "PORT38-CTRL" - }] - } - }, - - "PORT38-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT38-EEPROM", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT38" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x30", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT38-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT38-CTRL", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT38" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x30", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT39": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT39", - "device_parent": "PORT-MUX5" - }, - "dev_attr": { - "dev_idx": "39" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT39-EEPROM" - }, { - "itf": "control", - "dev": "PORT39-CTRL" - }] - } - }, - - "PORT39-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT39-EEPROM", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT39" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x31", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT39-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT39-CTRL", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT39" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x31", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT40": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT40", - "device_parent": "PORT-MUX5" - }, - "dev_attr": { - "dev_idx": "40" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT40-EEPROM" - }, { - "itf": "control", - "dev": "PORT40-CTRL" - }] - } - }, - - "PORT40-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT40-EEPROM", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT40" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x32", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT40-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT40-CTRL", - "device_parent": "PORT-MUX5", - "virt_parent": "PORT40" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x32", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x31", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x61", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x41", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT41": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT41", - "device_parent": "PORT-MUX6" - }, - "dev_attr": { - "dev_idx": "41" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT41-EEPROM" - }, { - "itf": "control", - "dev": "PORT41-CTRL" - }] - } - }, - - "PORT41-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT41-EEPROM", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT41" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x33", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT41-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT41-CTRL", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT41" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x33", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT42": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT42", - "device_parent": "PORT-MUX6" - }, - "dev_attr": { - "dev_idx": "42" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT42-EEPROM" - }, { - "itf": "control", - "dev": "PORT42-CTRL" - }] - } - }, - - "PORT42-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT42-EEPROM", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT42" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x34", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT42-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT42-CTRL", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT42" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x34", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT43": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT43", - "device_parent": "PORT-MUX6" - }, - "dev_attr": { - "dev_idx": "43" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT43-EEPROM" - }, { - "itf": "control", - "dev": "PORT43-CTRL" - }] - } - }, - - "PORT43-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT43-EEPROM", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT43" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x35", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT43-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT43-CTRL", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT43" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x35", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT44": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT44", - "device_parent": "PORT-MUX6" - }, - "dev_attr": { - "dev_idx": "44" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT44-EEPROM" - }, { - "itf": "control", - "dev": "PORT44-CTRL" - }] - } - }, - - "PORT44-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT44-EEPROM", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT44" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x36", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT44-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT44-CTRL", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT44" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x36", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT45": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT45", - "device_parent": "PORT-MUX6" - }, - "dev_attr": { - "dev_idx": "45" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT45-EEPROM" - }, { - "itf": "control", - "dev": "PORT45-CTRL" - }] - } - }, - - "PORT45-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT45-EEPROM", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT45" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x37", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT45-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT45-CTRL", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT45" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x37", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT46": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT46", - "device_parent": "PORT-MUX6" - }, - "dev_attr": { - "dev_idx": "46" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT46-EEPROM" - }, { - "itf": "control", - "dev": "PORT46-CTRL" - }] - } - }, - - "PORT46-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT46-EEPROM", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT46" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x38", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT46-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT46-CTRL", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT46" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x38", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT47": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT47", - "device_parent": "PORT-MUX6" - }, - "dev_attr": { - "dev_idx": "47" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT47-EEPROM" - }, { - "itf": "control", - "dev": "PORT47-CTRL" - }] - } - }, - - "PORT47-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT47-EEPROM", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT47" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x39", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT47-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT47-CTRL", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT47" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x39", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT48": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT48", - "device_parent": "PORT-MUX6" - }, - "dev_attr": { - "dev_idx": "48" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT48-EEPROM" - }, { - "itf": "control", - "dev": "PORT48-CTRL" - }] - } - }, - - "PORT48-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT48-EEPROM", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT48" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3a", - "dev_addr": "0x50", - "dev_type": "optoe2" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT48-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT48-CTRL", - "device_parent": "PORT-MUX6", - "virt_parent": "PORT48" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x32", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_txdisable", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x62", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_intr_status", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x42", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT49": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT49", - "device_parent": "PORT-MUX7" - }, - "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": "PORT-MUX7", - "virt_parent": "PORT49" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3b", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT49-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT49-CTRL", - "device_parent": "PORT-MUX7", - "virt_parent": "PORT49" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x33", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0xb9", - "attr_mask": "0x01", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT50": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT50", - "device_parent": "PORT-MUX7" - }, - "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": "PORT-MUX7", - "virt_parent": "PORT50" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3c", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT50-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT50-CTRL", - "device_parent": "PORT-MUX7", - "virt_parent": "PORT50" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x33", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0xb9", - "attr_mask": "0x02", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT51": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT51", - "device_parent": "PORT-MUX7" - }, - "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": "PORT-MUX7", - "virt_parent": "PORT51" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3d", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT51-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT51-CTRL", - "device_parent": "PORT-MUX7", - "virt_parent": "PORT51" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x33", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0xb9", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT52": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT52", - "device_parent": "PORT-MUX7" - }, - "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": "PORT-MUX7", - "virt_parent": "PORT52" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3e", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT52-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT52-CTRL", - "device_parent": "PORT-MUX7", - "virt_parent": "PORT52" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x33", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0xb9", - "attr_mask": "0x08", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT53": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT53", - "device_parent": "PORT-MUX7" - }, - "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": "PORT-MUX7", - "virt_parent": "PORT53" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3f", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT53-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT53-CTRL", - "device_parent": "PORT-MUX7", - "virt_parent": "PORT53" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x33", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0xb9", - "attr_mask": "0x10", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT54": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT54", - "device_parent": "PORT-MUX7" - }, - "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": "PORT-MUX7", - "virt_parent": "PORT54" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x40", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT54-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT54-CTRL", - "device_parent": "PORT-MUX7", - "virt_parent": "PORT54" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x40", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x33", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0xb9", - "attr_mask": "0x20", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT55": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT55", - "device_parent": "PORT-MUX7" - }, - "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": "PORT-MUX7", - "virt_parent": "PORT55" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x41", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT55-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT55-CTRL", - "device_parent": "PORT-MUX7", - "virt_parent": "PORT55" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x41", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x33", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0xb9", - "attr_mask": "0x40", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT56": { - "dev_info": { - "device_type": "QSFP28", - "device_name": "PORT56", - "device_parent": "PORT-MUX7" - }, - "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": "PORT-MUX7", - "virt_parent": "PORT56" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x42", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT56-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT56-CTRL", - "device_parent": "PORT-MUX7", - "virt_parent": "PORT56" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x42", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0x33", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devaddr": "0x36", - "attr_devtype": "cpld", - "attr_offset": "0xb9", - "attr_mask": "0x80", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "FRONT_BOARD_BMC_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "DIAG_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb1" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb1" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb1" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb1" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb1" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb1" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb1" - } - ] - } - }, - - "FRONT_BOARD_CPU_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "SYS_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb2" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb2" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb2" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb2" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb2" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb2" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb2" - } - ] - } - }, - - "FRONT_BOARD_PSU_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "LOC_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb3" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb3" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb3" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb3" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb3" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb3" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb3" - } - ] - } - }, - - "FRONT_BOARD_FAN_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FAN_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb4" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb4" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb4" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb4" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb4" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb4" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x33", - "swpld_addr_offset": "0xb4" - } - ] - } - }, - - "FAN1_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "3:0", - "value": "0xa", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x23" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "3:0", - "value": "0xe", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x23" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "3:0", - "value": "0x9", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x23" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "3:0", - "value": "0xd", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x23" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "3:0", - "value": "0x3", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x23" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "3:0", - "value": "0x7", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x23" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "3:0", - "value": "0xb", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x23" - } - ] - } - }, - - "FAN2_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "1" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "3:0", - "value": "0xa", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x24" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "3:0", - "value": "0xe", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x24" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "3:0", - "value": "0x9", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x24" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "3:0", - "value": "0xd", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x24" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "3:0", - "value": "0x3", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x24" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "3:0", - "value": "0x7", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x24" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "3:0", - "value": "0xb", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x24" - } - ] - } - }, - - "FAN3_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "2" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "3:0", - "value": "0xa", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x25" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "3:0", - "value": "0xe", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x25" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "3:0", - "value": "0x9", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x25" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "3:0", - "value": "0xd", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x25" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "3:0", - "value": "0x3", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x25" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "3:0", - "value": "0x7", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x25" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "3:0", - "value": "0xb", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x25" - } - ] - } - }, - - "FAN4_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "3" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "3:0", - "value": "0xa", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x26" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "3:0", - "value": "0xe", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x26" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "3:0", - "value": "0x9", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x26" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "3:0", - "value": "0xd", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x26" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "3:0", - "value": "0x3", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x26" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "3:0", - "value": "0x7", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x26" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "3:0", - "value": "0xb", - "swpld_addr": "0x32", - "swpld_addr_offset": "0x26" - } - ] - } - } -} diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/sfputil.py b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/sfputil.py new file mode 100644 index 000000000000..5415a0930c89 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/sfputil.py @@ -0,0 +1,243 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import os + import traceback + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 56 + PORTS_IN_BLOCK = 57 + + EEPROM_OFFSET = 32 + SFP_DEVICE_TYPE = "optoe2" + QSFP_DEVICE_TYPE = "optoe1" + I2C_MAX_ATTEMPT = 3 + + _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(49, self.PORTS_IN_BLOCK) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + self.port_to_i2cbus_mapping[x] = x + self.EEPROM_OFFSET - 1 + SfpUtilBase.__init__(self) + + def _sfp_read_file_path(self, file_path, offset, num_bytes): + attempts = 0 + while attempts < self.I2C_MAX_ATTEMPT: + try: + file_path.seek(offset) + read_buf = file_path.read(num_bytes) + except: + attempts += 1 + time.sleep(0.05) + return True, read_buf + return False, None + + def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): + """Tries to read the eeprom file to determine if the + device/sfp is present or not. If sfp present, the read returns + valid bytes. If not, read returns error 'Connection timed out""" + + if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): + return False + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv + + def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): + try: + sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path + + # Write device address to new_device file + nd_str = "%s %s" % (devtype, hex(devaddr)) + with open(sysfs_nd_path, "w") as nd_file: + nd_file.write(nd_str) + + except Exception as err: + print("Error writing to new device file: %s" % str(err)) + return 1 + else: + return 0 + + def _get_port_eeprom_path(self, port_num, devid): + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + + if port_num in self.port_to_eeprom_mapping: + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] + else: + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + + i2c_adapter_id = self._get_port_i2c_adapter_id(port_num) + if i2c_adapter_id is None: + print("Error getting i2c bus num") + return None + + # Get i2c virtual bus path for the sfp + sysfs_sfp_i2c_adapter_path = "%s/i2c-%s" % (sysfs_i2c_adapter_base_path, + str(i2c_adapter_id)) + + # If i2c bus for port does not exist + if not os.path.exists(sysfs_sfp_i2c_adapter_path): + print("Could not find i2c bus %s. Driver not loaded?" % sysfs_sfp_i2c_adapter_path) + return None + + sysfs_sfp_i2c_client_path = "%s/%s-00%s" % (sysfs_sfp_i2c_adapter_path, + str(i2c_adapter_id), + hex(devid)[-2:]) + + # If sfp device is not present on bus, Add it + if not os.path.exists(sysfs_sfp_i2c_client_path): + if port_num in self.qsfp_ports: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DEVICE_TYPE) + else: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.SFP_DEVICE_TYPE) + if ret != 0: + print("Error adding sfp device") + return None + + sysfs_sfp_i2c_client_eeprom_path = "%s/eeprom" % sysfs_sfp_i2c_client_path + + return sysfs_sfp_i2c_client_eeprom_path + + def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) + if rv is False: + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + except: + return None + + return eeprom_raw + + 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 + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + presence_path = "/sys/wb_plat/sff/sff%d/present" % port_num + + try: + with open(presence_path, "rb") as data: + presence_data = data.read(2) + if presence_data == "": + return False + result = int(presence_data, 16) + except IOError: + return False + + if result == 1: + return True + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + + return True + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return True + + def get_transceiver_change_event(self, timeout=0): + return False, {} + + def get_highest_temperature(self): + offset = 0 + hightest_temperature = -9999 + + presence_flag = False + read_eeprom_flag = False + temperature_valid_flag = False + + for port in range(49, self.PORTS_IN_BLOCK): + if self.get_presence(port) is False: + continue + + presence_flag = True + + if port in self.qsfp_ports: + offset = 22 + else: + offset = 96 + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = float(result / 256.0) + if -50 <= result <= 200: + temperature_valid_flag = True + hightest_temperature = max(hightest_temperature, result) + except BaseException: + print(traceback.format_exc()) + + # all port not presence + if presence_flag is False: + hightest_temperature = -10000 + + # all port read eeprom fail + elif read_eeprom_flag is False: + hightest_temperature = -9999 + + # all port temperature invalid + elif read_eeprom_flag is True and temperature_valid_flag is False: + hightest_temperature = -10000 + + hightest_temperature = round(hightest_temperature, 2) + + return hightest_temperature diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/ssd_util.py b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/ssd_util.py new file mode 100755 index 000000000000..e92782a0969b --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/plugins/ssd_util.py @@ -0,0 +1,309 @@ +# +# ssd_util.py +# +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium + +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_ssd.ssd_base import SsdBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SMARTCTL = "smartctl {} -a" +INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + +NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 + +class SsdUtil(SsdBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE + + def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + + """ + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" + """ + self.model_attr = { + "ER2-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n231\s+(.+?)\n" } + } + + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = "[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" + + def _execute_shell(self, cmd): + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None + return output + + def _parse_re(self, pattern, buffer): + res_list = re.findall(pattern, str(buffer)) + return res_list[0] if res_list else NOT_AVAILABLE + + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re('Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re('Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re('Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re('Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re('\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re('SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re('Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re('Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + + def get_health(self): + """ + Retrieves current disk health in percentages + + Returns: + A float number of current ssd health + e.g. 83.5 + """ + return float(self.health) + + def get_temperature(self): + """ + Retrieves current disk temperature in Celsius + + Returns: + A float number of current temperature in Celsius + e.g. 40.1 + """ + return float(self.temperature) + + def get_model(self): + """ + Retrieves model for the given disk device + + Returns: + A string holding disk model as provided by the manufacturer + """ + return self.model + + def get_firmware(self): + """ + Retrieves firmware version for the given disk device + + Returns: + A string holding disk firmware version as provided by the manufacturer + """ + return self.firmware + + def get_serial(self): + """ + Retrieves serial number for the given disk device + + Returns: + A string holding disk serial number as provided by the manufacturer + """ + return self.serial + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life + def get_vendor_output(self): + """ + Retrieves vendor specific data for the given disk device + + Returns: + A string holding some vendor specific disk information + """ + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re('{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pmon_daemon_control.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pmon_daemon_control.json index 590def37b276..94592fa8cebc 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pmon_daemon_control.json +++ b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pmon_daemon_control.json @@ -1,5 +1,3 @@ -{ - "skip_ledd": true, - "skip_xcvrd": false, - "skip_psud": false -} \ No newline at end of file +{ + "skip_ledd": true +} diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sensors.conf b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sensors.conf deleted file mode 100755 index 9b0569d1541d..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sensors.conf +++ /dev/null @@ -1,21 +0,0 @@ -# libsensors configuration file -# ---------------------------------------------- -# - -bus "i2c-2" "i2c-0-mux (chan_id 0)" - -chip "lm75-i2c-2-48" - label temp1 "LM75_0 air_inlet" - set temp1_max 80 - set temp1_max_hyst 75 - -chip "lm75-i2c-2-49" - label temp1 "LM75_1 air_outlet" - set temp1_max 80 - set temp1_max_hyst 75 - -chip "lm75-i2c-2-4a" - label temp1 "LM75_2 hottest" - set temp1_max 80 - set temp1_max_hyst 75 - diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/chassis.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/chassis.json deleted file mode 100644 index c5ea46918ff2..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/chassis.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "eeprom": {"bus": 2, "loc": "0057"} -} \ No newline at end of file diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/component.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/component.json deleted file mode 100644 index 35f4b4586447..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/component.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "components": [ - { - "name": "CPLD1 (MAC Board A)", - "firmware_version": { - "bus": 2, - "addr": 51, - "offset": 0, - "size": 4, - "way": 1, - "format": 7, - "sep": "/" - }, - "desc": "Used for managing IO modules, SFP+ modules and system LEDs", - "slot": 0 - }, - { - "name": "CPLD2 (MAC Board B)", - "firmware_version": { - "bus": 2, - "addr": 53, - "offset": 0, - "size": 4, - "way": 1, - "format": 7, - "sep": "/" - }, - "desc": "Used for managing IO modules, SFP+ modules and system LEDs", - "slot": 0 - }, - { - "name": "CPLD3 (CONNECT Board A)", - "firmware_version": { - "bus": 2, - "addr": 55, - "offset": 0, - "size": 4, - "way": 1, - "format": 7, - "sep": "/" - }, - "desc": "Used for managing IO modules, SFP+ modules and system LEDs", - "slot": 0 - }, - { - "name": "CPLD4 (CPU Board)", - "firmware_version": { - "bus": 0, - "addr": 13, - "offset": 0, - "size": 4, - "way": 1, - "format": 7, - "sep": "/" - }, - "desc": "Used for managing IO modules, SFP+ modules and system LEDs", - "slot": 1 - } - ] -} \ No newline at end of file diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/fan.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/fan.json deleted file mode 100644 index de7030ec1f90..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/fan.json +++ /dev/null @@ -1,152 +0,0 @@ -{ - "fans": [ - { - "name": "fan1", - "e2loc": {"bus": 3, "addr": 83, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_present", - "format": 2, - "bit": 0 - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_status", - "format": 2, - "bit": 0 - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/3-0053/fan_hw_version"}, - "sn": {"loc": "/sys/bus/i2c/devices/3-0053/fan_sn"}, - "led": { - "loc": "/sys/bus/i2c/devices/0-0032/fan0_led", - "format": 6, - "mask": 11 - }, - "led_colors": { - "green": 9, - "red": 10, - "amber": 3 - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-0037/hwmon/*/fan1_input" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/0-0032/fan_speed_set" - }, - "speed_max": 23000 - } - ] - }, - { - "name": "fan2", - "e2loc": {"bus": 4, "addr": 83, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_present", - "format": 2, - "bit": 1 - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_status", - "format": 2, - "bit": 1 - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/4-0053/fan_hw_version"}, - "sn": {"loc": "/sys/bus/i2c/devices/4-0053/fan_sn"}, - "led": { - "loc": "/sys/bus/i2c/devices/0-0032/fan1_led", - "format": 6, - "mask": 11 - }, - "led_colors": { - "green": 9, - "red": 10, - "amber": 3 - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-0037/hwmon/*/fan2_input" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/0-0032/fan_speed_set" - }, - "speed_max": 23000 - } - ] - }, - { - "name": "fan3", - "e2loc": {"bus": 3, "addr": 83, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_present", - "format": 2, - "bit": 2 - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_status", - "format": 2, - "bit": 2 - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/5-0053/fan_hw_version"}, - "sn": {"loc": "/sys/bus/i2c/devices/5-0053/fan_sn"}, - "led": { - "loc": "/sys/bus/i2c/devices/0-0032/fan2_led", - "format": 6, - "mask": 11 - }, - "led_colors": { - "green": 9, - "red": 10, - "amber": 3 - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-0037/hwmon/*/fan3_input" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/0-0032/fan_speed_set" - }, - "speed_max": 23000 - } - ] - }, - { - "name": "fan4", - "e2loc": {"bus": 3, "addr": 83, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_present", - "format": 2, - "bit": 3 - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_status", - "format": 2, - "bit": 3 - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/6-0053/fan_hw_version"}, - "sn": {"loc": "/sys/bus/i2c/devices/6-0053/fan_sn"}, - "led": { - "loc": "/sys/bus/i2c/devices/0-0032/fan3_led", - "format": 6, - "mask": 11 - }, - "led_colors":{ - "green": 9, - "red": 10, - "amber": 3 - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-0037/hwmon/*/fan4_input" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/0-0032/fan_speed_set" - }, - "speed_max": 23000 - } - ] - } - ] -} \ No newline at end of file diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/psu.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/psu.json deleted file mode 100644 index c807b51fc4b6..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/psu.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "psus": [ - { - "name": "psu1", - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": 2, - "bit": 0 - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": 2, - "bit": 1 - }, - "sn": {"loc": "/sys/bus/i2c/devices/7-0050/psu_sn"}, - "in_current": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/curr1_input", - "format": 4 - }, - "in_voltage": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/in1_input", - "format": 4 - }, - "out_voltage": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/in2_input", - "format": 4 - }, - "out_current": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/curr2_input", - "format": 4 - }, - "temperature": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/temp1_input", - "format": 4 - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/7-0050/psu_hw"}, - "psu_type": {"loc": "/sys/bus/i2c/devices/7-0050/psu_type"}, - "fans": [ - { - "name": "psu_fan1", - "present": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/fan1_fault" - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": 2, - "bit": 1 - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/fan1_input" - }, - "speed_max": 28000 - } - ] - } - ], - "in_power": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/power1_input", - "format": 5 - }, - "out_power": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/power2_input", - "format": 5 - } - }, - { - "name": "psu2", - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": 2, - "bit": 4 - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": 2, - "bit": 5 - }, - "sn": {"loc": "/sys/bus/i2c/devices/8-0053/psu_sn"}, - "in_current": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/curr1_input", - "format": 4 - }, - "in_voltage": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/in1_input", - "format": 4 - }, - "out_voltage": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/in2_input", - "format": 4 - }, - "out_current": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/curr2_input", - "format": 4 - }, - "temperature": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/temp1_input", - "format": 4 - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/8-0053/psu_hw"}, - "psu_type": {"loc": "/sys/bus/i2c/devices/8-0053/psu_type"}, - "fans": [ - { - "name": "psu_fan1", - "present": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/fan1_fault" - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": 2, - "bit": 5 - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/fan1_input" - }, - "speed_max": 28000 - } - ] - } - ], - "in_power": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/power1_input", - "format": 5 - }, - "out_power": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/power2_input", - "format": 5 - } - } - ] -} \ No newline at end of file diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/thermal.json b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/thermal.json deleted file mode 100644 index 319336673534..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/sonic_platform_config/thermal.json +++ /dev/null @@ -1,130 +0,0 @@ -{"thermals": [ - { - "name": "INLET TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/2-0048/hwmon/*/temp1_max", - "format": 4 - }, - "low": null, - "crit_low": null, - "crit_high": null, - "temperature": { - "loc": "/sys/bus/i2c/devices/2-0048/hwmon/*/temp1_input", - "format": 4 - } - }, - { - "name": "OUTLET TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/2-0049/hwmon/*/temp1_max", - "format": 4 - }, - "low": null, - "crit_low": null, - "crit_high": null, - "temperature": { - "loc": "/sys/bus/i2c/devices/2-0049/hwmon/*/temp1_input", - "format": 4 - } - }, - { - "name": "BOARD TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/2-004a/hwmon/*/temp1_max", - "format": 4 - }, - "low": null, - "crit_low": null, - "crit_high": null, - "temperature": { - "loc": "/sys/bus/i2c/devices/2-004a/hwmon/*/temp1_input", - "format": 4 - } - }, - { - "name": "PHYSICAL ID 0", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp1_max", - "format": 4 - }, - "low": null, - "crit_low": null, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp1_crit", - "format": 4 - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp1_input", - "format": 4 - } - }, - { - "name": "CPU CORE 0", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp2_max", - "format": 4 - }, - "low": null, - "crit_low": null, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp2_crit", - "format": 4 - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp2_input", - "format": 4 - } - }, - { - "name": "CPU CORE 1", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp3_max", - "format": 4 - }, - "low": null, - "crit_low": null, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp3_crit", - "format": 4 - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp3_input", - "format": 4 - } - }, - { - "name": "CPU CORE 2", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp4_max", - "format": 4 - }, - "low": null, - "crit_low": null, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp4_crit", - "format": 4 - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp4_input", - "format": 4 - } - }, - { - "name": "CPU CORE 3", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp5_max", - "format": 4 - }, - "low": null, - "crit_low": null, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp5_crit", - "format": 4 - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp5_input", - "format": 4 - } - } - ] -} \ No newline at end of file diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf_support b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/system_health_monitoring_config.json old mode 100644 new mode 100755 similarity index 100% rename from device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/pddf_support rename to device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/system_health_monitoring_config.json diff --git a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/systest.py b/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/systest.py deleted file mode 100644 index 38e9ff6aa0c9..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6510-48v8c-r0/systest.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: UTF-8 -*- -""" -* onboard temperature sensors -* FAN trays -* PSU -""" -import time -import datetime -from monitor import status - -def doWork(): - a=[]; - ''' - return: [{'status': '1', 'hw_version': '1.00', 'errcode': 0, 'fan_type': 'M6510-FAN-F', 'errmsg': 'OK', 'Speed': '9778', 'id': 'fan1', 'present': '0', 'sn': '1000000000014'}, - {'id': 'fan2', 'errmsg': 'not present', 'errcode': -1}, - {'id': 'fan3', 'errmsg': 'not present', 'errcode': -1}, - {'id': 'fan4', 'errmsg': 'not present', 'errcode': -1} - ] - description: 1.get id - 2.errcode equal 0 : dev normal - not equal 0 : get errmsg - 3.other message add when all check success - ''' - status.checkFan(a) - #status.getTemp(a) - #status.getPsu(a) - - nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - print(nowTime) - print(a) -def run(interval): - while True: - try: - time_remaining = interval - time.time()%interval - time.sleep(time_remaining) - doWork() - except Exception as e: - print(e) - -if __name__ == '__main__': - interval = 1 - run(interval) diff --git a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/RA-B6910-64C/th2-ra-b6910-64c-64x100G.config.bcm b/device/ragile/x86_64-ragile_ra-b6910-64c-r0/RA-B6910-64C/th2-ra-b6910-64c-64x100G.config.bcm index 787c851bcc2e..4f8424684a10 100644 --- a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/RA-B6910-64C/th2-ra-b6910-64c-64x100G.config.bcm +++ b/device/ragile/x86_64-ragile_ra-b6910-64c-r0/RA-B6910-64C/th2-ra-b6910-64c-64x100G.config.bcm @@ -1,3 +1,8 @@ +scache_filename=/var/warmboot/wbscache +stable_size=0x55000000 +stable_location=3 +warmboot_knet_shutdown_mode=1 + core_clock_frequency=1700 dpp_clock_ratio=2:3 table_dma_enable=1 diff --git a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/bcm.rc b/device/ragile/x86_64-ragile_ra-b6910-64c-r0/bcm.rc deleted file mode 100644 index 7f69f10d3bda..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/bcm.rc +++ /dev/null @@ -1 +0,0 @@ -rcload /usr/share/sonic/platform/led_proc_init.soc diff --git a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/dev.xml b/device/ragile/x86_64-ragile_ra-b6910-64c-r0/dev.xml index 55d37fffd8eb..592658ab3af3 100644 --- a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/dev.xml +++ b/device/ragile/x86_64-ragile_ra-b6910-64c-r0/dev.xml @@ -8,28 +8,22 @@ - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - + + - - + + + - - + + - - + + + - - + + - - + + + - - + + - - + + + - - + + - - + + + - - + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + - - - - - - - + + + + - - - + + + + - - - - - - - + + + + - - - + + + + - - - - - - - + + + + - - - + + + + - - - - - - - + + + + - - + + + - - - - + + + - + + + - - - - + + + - + + + - - - - + + + - + + + - - - - + + + - + + + - + + - + + - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - - - - - - + + + + - - + + + + + diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/device_data.json b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/device_data.json deleted file mode 100644 index 6bf7042401b5..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/device_data.json +++ /dev/null @@ -1,3716 +0,0 @@ -{ - "PLATFORM": { - "fan_info": { - "drawer_num": 6, - "fans_per_drawer": 2, - "MAX_FAN_SPEED": 12300, - "MIN_FAN_SPEED": 3690, - "ALLOW-FAN-TYPES": { - "P2EFAN I-F": "exhaust" - } - }, - "psu_info": { - "psu_num": 4, - "fans_per_psu": 1, - "MAX_PSU_FAN_SPEED": 25100, - "MIN_PSU_FAN_SPEED": 6600, - "ALLOW-PSU-TYPES": { - "DPS-1300AB-6 S": "exhaust" - } - }, - "thermal_info": { - "temp_num": 9 - }, - "component_info": { - "comp_num": 13 - }, - "debug": { - "level": 0 - } - }, - "EEPROM-1": { - "eeprom": { - "codec": { - "name": "TLV", - "attrs": { - "path": "/sys/bus/i2c/devices/1-0056/eeprom" - } - } - } - }, - "THERMAL-1": { - "desc": "INLET TEMP", - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/29-004f/hwmon/*/temp1_input" - } - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000, - "nearest": 3 - } - } - }, - "h_thd": { - "default": 70 - }, - "h_crit": { - "default": 80 - } - }, - "THERMAL-2": { - "temp": { - "desc": "OUTLET TEMP", - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/28-004b/hwmon/*/temp1_input" - } - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000, - "nearest": 3 - } - } - }, - "h_thd": { - "default": 85 - }, - "h_crit": { - "default": 90 - } - }, - "THERMAL-3": { - "temp": { - "desc": "BOARD TEMP", - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/28-004c/hwmon/*/temp1_input" - } - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000, - "nearest": 3 - } - } - }, - "h_thd": { - "default": 85 - }, - "h_crit": { - "default": 90 - } - }, - "THERMAL-4": { - "desc": "CPU CORE 0", - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/class/hwmon/hwmon0/temp2_input" - } - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000, - "nearest": 3 - } - } - }, - "h_thd": { - "default": 85 - }, - "h_crit": { - "default": 100 - } - }, - "THERMAL-5": { - "desc": "CPU CORE 1", - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/class/hwmon/hwmon0/temp3_input" - } - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000, - "nearest": 3 - } - } - }, - "h_thd": { - "default": 85 - }, - "h_crit": { - "default": 100 - } - }, - "THERMAL-6": { - "desc": "CPU CORE 2", - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/class/hwmon/hwmon0/temp4_input" - } - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000, - "nearest": 3 - } - } - }, - "h_thd": { - "default": 85 - }, - "h_crit": { - "default": 100 - } - }, - "THERMAL-7": { - "desc": "CPU CORE 3", - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/class/hwmon/hwmon0/temp5_input" - } - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000, - "nearest": 3 - } - } - }, - "h_thd": { - "default": 85 - }, - "h_crit": { - "default": 100 - } - }, - "THERMAL-8": { - "desc": "MAC TEMP1", - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/28-004c/hwmon/*/temp2_input" - } - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000, - "nearest": 3 - } - } - }, - "h_thd": { - "default": 100 - }, - "h_crit": { - "default": 105 - } - }, - "THERMAL-9": { - "desc": "MAC TEMP2", - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/29-004c/hwmon/*/temp2_input" - } - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000, - "nearest": 3 - } - } - }, - "h_thd": { - "default": 100 - }, - "h_crit": { - "default": 105 - } - }, - "COMPONENT-1": { - "desc": { - "default": "FAN_CPLD_B" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "13", - "addr": "0x0d", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-2": { - "desc": { - "default": "FAN_CPLD_A" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "14", - "addr": "0x0d", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-3": { - "desc": { - "default": "LC1_CPLD_1" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "3", - "addr": "0x30", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-4": { - "desc": { - "default": "LC1_CPLD_2" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "3", - "addr": "0x31", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-5": { - "desc": { - "default": "LC2_CPLD_1" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "4", - "addr": "0x30", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-6": { - "desc": { - "default": "LC2_CPLD_2" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "4", - "addr": "0x31", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-7": { - "desc": { - "default": "LC3_CPLD_1" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "5", - "addr": "0x30", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-8": { - "desc": { - "default": "LC3_CPLD_2" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "5", - "addr": "0x31", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-9": { - "desc": { - "default": "LC4_CPLD_1" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "6", - "addr": "0x30", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-10": { - "desc": { - "default": "LC4_CPLD_2" - }, - "version": { - "codec": { - "name": "I2C", - "attrs": { - "bus": "6", - "addr": "0x31", - "offset": "0x0", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-11": { - "desc": { - "default": "X86_CPLD" - }, - "version": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0x700", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-12": { - "desc": { - "default": "MAC_CPLD_B" - }, - "version": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0x900", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "COMPONENT-13": { - "desc": { - "default": "MAC_CPLD_A" - }, - "version": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb00", - "size": 4 - } - }, - "post_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16, - "sep": "/" - } - } - } - }, - "PSU-1": { - "presence": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb27", - "size": "1" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb27", - "size": "1" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x02", - "mask": "0x02" - } - } - }, - "max_power_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/power1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "max_power_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/power2_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "v_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/in1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_in_h_thd": {}, - "v_in_l_thd": {}, - "i_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/curr1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_in_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/curr1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_in_l_thd": {}, - "v_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/in2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_out_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/in2_crit" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_out_l_thd": {}, - "i_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/curr2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_out_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/curr2_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_out_l_thd": {}, - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/temp1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "temp_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/temp1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "temp_l_thd": {}, - "power_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/power1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "power_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/power2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0050/psu_sn" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0050/psu_type" - } - } - }, - "revision": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0050/psu_hw" - } - } - }, - "led": {}, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0050/psu_type" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-PSU-TYPES" - } - } - } - }, - "PSU-2": { - "presence": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb28", - "size": 1 - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb28", - "size": 1 - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x02", - "mask": "0x02" - } - } - }, - "max_power_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/power1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "max_power_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/power2_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "v_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/in1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_in_h_thd": {}, - "v_in_l_thd": {}, - "i_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/curr1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_in_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/curr1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_in_l_thd": {}, - "v_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/in2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_out_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/in2_crit" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_out_l_thd": {}, - "i_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/curr2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_out_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/curr2_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_out_l_thd": {}, - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/temp1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "temp_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/temp1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "temp_l_thd": {}, - "power_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/power1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "power_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/power2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0050/psu_sn" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0050/psu_type" - } - } - }, - "revision": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0050/psu_hw" - } - } - }, - "led": {}, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0050/psu_type" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-PSU-TYPES" - } - } - } - }, - "PSU-3": { - "presence": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb29", - "size": 1 - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb29", - "size": 1 - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x02", - "mask": "0x02" - } - } - }, - "max_power_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/power1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "max_power_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/power2_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "v_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/in1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_in_h_thd": {}, - "v_in_l_thd": {}, - "i_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/curr1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_in_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/curr1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_in_l_thd": {}, - "v_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/in2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_out_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/in2_crit" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_out_l_thd": {}, - "i_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/curr2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_out_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/curr2_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_out_l_thd": {}, - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/temp1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "temp_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/temp1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "temp_l_thd": {}, - "power_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/power1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "power_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/power2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0050/psu_sn" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0050/psu_type" - } - } - }, - "revision": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0050/psu_hw" - } - } - }, - "led": {}, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0050/psu_type" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-PSU-TYPES" - } - } - } - }, - "PSU-4": { - "presence": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb2a", - "size": 1 - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb2a", - "size": 1 - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x02", - "mask": "0x02" - } - } - }, - "max_power_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/power1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "max_power_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/power2_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "v_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/in1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_in_h_thd": {}, - "v_in_l_thd": {}, - "i_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/curr1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_in_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/curr1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_in_l_thd": {}, - "v_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/in2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_out_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/in2_crit" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "v_out_l_thd": {}, - "i_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/curr2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_out_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/curr2_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "i_out_l_thd": {}, - "temp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/temp1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "temp_h_thd": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/temp1_max" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000 - } - } - }, - "temp_l_thd": {}, - "power_in": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/power1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "power_out": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/power2_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "DIVISION", - "attrs": { - "divisor": 1000000 - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0050/psu_sn" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0050/psu_type" - } - } - }, - "revision": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0050/psu_hw" - } - } - }, - "led": {}, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0050/psu_type" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-PSU-TYPES" - } - } - } - }, - "PSU-FAN-1": { - "presence": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb27", - "size": "1" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/fan1_input" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "opt": "GT" - } - } - }, - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/fan1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_PSU_FAN_SPEED", - "speed_rpm_l_thd": "MIN_PSU_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0058/hwmon/*/fan1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_PSU_FAN_SPEED" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/23-0050/psu_type" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-PSU-TYPES" - } - } - } - }, - "PSU-FAN-2": { - "presence": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb28", - "size": 1 - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/fan1_input" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "opt": "GT" - } - } - }, - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/fan1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_PSU_FAN_SPEED", - "speed_rpm_l_thd": "MIN_PSU_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0058/hwmon/*/fan1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_PSU_FAN_SPEED" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/25-0050/psu_type" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-PSU-TYPES" - } - } - } - }, - "PSU-FAN-3": { - "presence": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb29", - "size": 1 - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/fan1_input" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "opt": "GT" - } - } - }, - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/fan1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_PSU_FAN_SPEED", - "speed_rpm_l_thd": "MIN_PSU_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0058/hwmon/*/fan1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_PSU_FAN_SPEED" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/24-0050/psu_type" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-PSU-TYPES" - } - } - } - }, - "PSU-FAN-4": { - "presence": { - "codec": { - "name": "IO", - "attrs": { - "offset": "0xb2a", - "size": 1 - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/fan1_input" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "opt": "GT" - } - } - }, - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/fan1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_PSU_FAN_SPEED", - "speed_rpm_l_thd": "MIN_PSU_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0058/hwmon/*/fan1_input" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_PSU_FAN_SPEED" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/26-0050/psu_type" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-PSU-TYPES" - } - } - } - }, - "FAN-DRAWER-1": { - "fans": ["FAN-1", "FAN-2"], - "presence": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan_present" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan_status1" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x01", - "mask": "0x01" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/63-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.PN" - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/63-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.SN" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/63-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "led": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan1_led" - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - }, - "post": { - "name": "LED", - "attrs": { - "led_type": "Type1" - } - } - }, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/63-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "hw_ver": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/63-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.VERSION" - } - } - } - }, - "FAN-DRAWER-2": { - "fans": ["FAN-3", "FAN-4"], - "presence": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan_present" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x01" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan_status1" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x01", - "mask": "0x01" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/55-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.PN" - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/55-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.SN" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/55-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "led": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan2_led" - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - }, - "post": { - "name": "LED", - "attrs": { - "led_type": "Type1" - } - } - }, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/55-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "hw_ver": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/55-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.VERSION" - } - } - } - }, - "FAN-DRAWER-3": { - "fans": ["FAN-5", "FAN-6"], - "presence": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan_present" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x02" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan_status1" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x02", - "mask": "0x02" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/64-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.PN" - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/64-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.SN" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/64-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "led": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan3_led" - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - }, - "post": { - "name": "LED", - "attrs": { - "led_type": "Type1" - } - } - }, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/64-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "hw_ver": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/64-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.VERSION" - } - } - } - }, - "FAN-DRAWER-4": { - "fans": ["FAN-7", "FAN-8"], - "presence": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan_present" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x02" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan_status1" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x02", - "mask": "0x02" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/56-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.PN" - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/56-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.SN" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/56-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "led": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan4_led" - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - }, - "post": { - "name": "LED", - "attrs": { - "led_type": "Type1" - } - } - }, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/56-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "hw_ver": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/56-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.VERSION" - } - } - } - }, - "FAN-DRAWER-5": { - "fans": ["FAN-9", "FAN-10"], - "presence": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan_present" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x04" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan_status1" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x04", - "mask": "0x04" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/65-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.PN" - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/65-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.SN" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/65-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "led": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan5_led" - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - }, - "post": { - "name": "LED", - "attrs": { - "led_type": "Type1" - } - } - }, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/65-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "hw_ver": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/65-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.VERSION" - } - } - } - }, - "FAN-DRAWER-6": { - "fans": ["FAN-11", "FAN-12"], - "presence": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan_present" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": 0, - "mask": "0x04" - } - } - }, - "status": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan_status1" - } - }, - "post": { - "name": "CMP", - "attrs": { - "cmpval": "0x04", - "mask": "0x04" - } - } - }, - "pn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/57-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.PN" - } - } - }, - "sn": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/57-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.SN" - } - } - }, - "direction": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/57-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_DICT", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "led": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan6_led" - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - }, - "post": { - "name": "LED", - "attrs": { - "led_type": "Type1" - } - } - }, - "supp": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/57-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.NAME" - } - }, - "post": { - "name": "MATCH_LIST", - "attrs": { - "cmpitem": "ALLOW-FAN-TYPES" - } - } - }, - "hw_ver": { - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/57-0050/eeprom" - } - }, - "post_fmtter": { - "name": "FRU", - "attrs": { - "field": "PD.VERSION" - } - } - } - }, - "FAN-1": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan1_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan1_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan1_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-2": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan1_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan1_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan1_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-3": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan2_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan2_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan2_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-4": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan2_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan2_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan2_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-5": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan3_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan3_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan3_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-6": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan3_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan3_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan3_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-7": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan4_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan4_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan4_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-8": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan4_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan4_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan4_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-9": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan5_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan5_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan5_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-10": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan5_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan5_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/14-000d/fan5_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-11": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan6_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan6_1_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan6_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - }, - "FAN-12": { - "speed_rpm": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan6_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - } - }, - "speed_rpm_h_thd": "MAX_FAN_SPEED", - "speed_rpm_l_thd": "MIN_FAN_SPEED", - "speed": { - "default": 0, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan6_2_real_speed" - } - }, - "post_fmtter": { - "name": "TO_INT" - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": "MAX_FAN_SPEED" - } - } - }, - "pwm": { - "ro": false, - "pre": { - "name": "PROPORTION", - "attrs": { - "denomi": 100, - "total": 255 - } - }, - "pre_fmtter": { - "name": "TO_STR", - "attrs": { - "base": 16 - } - }, - "codec": { - "name": "SYSFS", - "attrs": { - "path": "/sys/bus/i2c/devices/13-000d/fan6_speed_set" - } - }, - "post": { - "name": "PROPORTION", - "attrs": { - "denomi": 255, - "total": 100 - } - }, - "post_fmtter": { - "name": "TO_INT", - "attrs": { - "base": 16 - } - } - }, - "tolerance": 30 - } -} diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/fru.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/fru.py new file mode 100755 index 000000000000..f95164e03601 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/fru.py @@ -0,0 +1,961 @@ +#!/usr/bin/python3 +import collections +from datetime import datetime, timedelta +from bitarray import bitarray + + +__DEBUG__ = "N" + + +class FruException(Exception): + def __init__(self, message='fruerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +def e_print(err): + print("ERROR: " + err) + + +def d_print(debug_info): + if __DEBUG__ == "Y": + print(debug_info) + + +class FruUtil(): + @staticmethod + def decodeLength(value): + a = bitarray(8) + a.setall(True) + a[0:1] = 0 + a[1:2] = 0 + x = ord(a.tobytes()) + return x & ord(value) + + @staticmethod + def minToData(): + starttime = datetime(1996, 1, 1, 0, 0, 0) + endtime = datetime.now() + seconds = (endtime - starttime).total_seconds() + mins = seconds // 60 + m = int(round(mins)) + return m + + @staticmethod + def getTimeFormat(): + return datetime.now().strftime('%Y-%m-%d') + + @staticmethod + def getTypeLength(value): + if value is None or len(value) == 0: + return 0 + a = bitarray(8) + a.setall(False) + a[0:1] = 1 + a[1:2] = 1 + x = ord(a.tobytes()) + return x | len(value) + + @staticmethod + def checksum(b): + result = 0 + for item in b: + result += ord(item) + return (0x100 - (result & 0xff)) & 0xff + + +class BaseArea(object): + SUGGESTED_SIZE_COMMON_HEADER = 8 + SUGGESTED_SIZE_INTERNAL_USE_AREA = 72 + SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32 + SUGGESTED_SIZE_BOARD_INFO_AREA = 80 + SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80 + + INITVALUE = b'\x00' + resultvalue = INITVALUE * 256 + COMMON_HEAD_VERSION = b'\x01' + __childList = None + + def __init__(self, name="", size=0, offset=0): + self.__childList = [] + self._offset = offset + self.name = name + self._size = size + self._isPresent = False + self._data = b'\x00' * size + + @property + def childList(self): + return self.__childList + + @childList.setter + def childList(self, value): + self.__childList = value + + @property + def offset(self): + return self._offset + + @offset.setter + def offset(self, value): + self._offset = value + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + self._size = value + + @property + def data(self): + return self._data + + @data.setter + def data(self, value): + self._data = value + + @property + def isPresent(self): + return self._isPresent + + @isPresent.setter + def isPresent(self, value): + self._isPresent = value + + +class InternalUseArea(BaseArea): + pass + + +class ChassisInfoArea(BaseArea): + pass + + +class BoardInfoArea(BaseArea): + _boardTime = None + _fields = None + _mfg_date = None + areaversion = None + _boardversion = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "mfg_date : %s \n" \ + "boardManufacturer : %s \n" \ + "boardProductName : %s \n" \ + "boardSerialNumber : %s \n" \ + "boardPartNumber : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.boardversion), self.size, + self.language, self.getMfgRealData(), + self.boardManufacturer, self.boardProductName, + self.boardSerialNumber, self.boardPartNumber, + self.fruFileId) + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "boardextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["boardversion"] = ord(self.boardversion) + dic["boardlength"] = self.size + dic["boardlanguage"] = self.language + dic["boardmfg_date"] = self.getMfgRealData() + dic["boardManufacturer"] = self.boardManufacturer + dic["boardProductName"] = self.boardProductName + dic["boardSerialNumber"] = self.boardSerialNumber + dic["boardPartNumber"] = self.boardPartNumber + dic["boardfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] + index += 1 + d_print("decode length :%d class size:%d" % + ((ord(self.data[index]) * 8), self.size)) + index += 2 + + timetmp = self.data[index: index + 3] + self.mfg_date = ord(timetmp[0]) | ( + ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16) + d_print("decode getMfgRealData :%s" % self.getMfgRealData()) + index += 3 + + templen = FruUtil.decodeLength(self.data[index]) + self.boardManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardManufacturer:%s" % self.boardManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardProductName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardProductName:%s" % self.boardProductName) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardSerialNumber:%s" % self.boardSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardPartNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardPartNumber:%s" % self.boardPartNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if self.data[index] != chr(0xc1): + templen = FruUtil.decodeLength(self.data[index]) + tmpval = self.data[index + 1: index + templen + 1] + setattr(self, valtmp, tmpval) + index += templen + 1 + d_print("decode boardextra%d:%s" % (i, tmpval)) + else: + break + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("boardInfoArea version:%x" % ord(self.boardversion)) + d_print("boardInfoArea length:%d" % self.size) + d_print("boardInfoArea language:%x" % self.language) + self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea mfg_date:%x" % self.mfg_date) + + self.data = chr(ord(self.boardversion)) + \ + chr(self.size // 8) + chr(self.language) + + self.data += chr(self.mfg_date & 0xFF) + self.data += chr((self.mfg_date >> 8) & 0xFF) + self.data += chr((self.mfg_date >> 16) & 0xFF) + + d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer) + typelength = FruUtil.getTypeLength(self.boardManufacturer) + self.data += chr(typelength) + self.data += self.boardManufacturer + + d_print("boardInfoArea boardProductName:%s" % self.boardProductName) + self.data += chr(FruUtil.getTypeLength(self.boardProductName)) + self.data += self.boardProductName + + d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber) + self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber)) + self.data += self.boardSerialNumber + + d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber) + self.data += chr(FruUtil.getTypeLength(self.boardPartNumber)) + self.data += self.boardPartNumber + + d_print("boardInfoArea fruFileId:%s" % self.fruFileId) + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + d_print("self data:%d" % len(self.data)) + d_print("self size:%d" % self.size) + d_print("adjust size:%d" % (self.size - len(self.data) - 1)) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + + # checksum + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + def getMfgRealData(self): + starttime = datetime(1996, 1, 1, 0, 0, 0) + mactime = starttime + timedelta(minutes=self.mfg_date) + return mactime + + @property + def language(self): + self._language = 25 + return self._language + + @property + def mfg_date(self): + return self._mfg_date + + @mfg_date.setter + def mfg_date(self, val): + self._mfg_date = val + + @property + def boardversion(self): + self._boardversion = self.COMMON_HEAD_VERSION + return self._boardversion + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, val): + self._FRUFileID = val + + @property + def boardPartNumber(self): + return self._boardPartNumber + + @boardPartNumber.setter + def boardPartNumber(self, val): + self._boardPartNumber = val + + @property + def boardSerialNumber(self): + return self._boardSerialNumber + + @boardSerialNumber.setter + def boardSerialNumber(self, val): + self._boardSerialNumber = val + + @property + def boardProductName(self): + return self._boradProductName + + @boardProductName.setter + def boardProductName(self, val): + self._boradProductName = val + + @property + def boardManufacturer(self): + return self._boardManufacturer + + @boardManufacturer.setter + def boardManufacturer(self, val): + self._boardManufacturer = val + + @property + def boardTime(self): + return self._boardTime + + @boardTime.setter + def boardTime(self, val): + self._boardTime = val + + @property + def fields(self): + return self._fields + + @fields.setter + def fields(self, val): + self._fields = val + + +class ProductInfoArea(BaseArea): + _productManufacturer = None + _productAssetTag = None + _FRUFileID = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "productAssetTag : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.areaversion), self.size, + self.language, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, + self.productAssetTag, self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "productextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["productversion"] = ord(self.areaversion) + dic["productlength"] = self.size + dic["productlanguage"] = self.language + dic["productManufacturer"] = self.productManufacturer + dic["productName"] = self.productName + dic["productPartModelName"] = self.productPartModelName + dic["productVersion"] = int(self.productVersion, 16) + dic["productSerialNumber"] = self.productSerialNumber + dic["productAssetTag"] = self.productAssetTag + dic["productfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] # 0 + index += 1 + d_print("decode length %d" % (ord(self.data[index]) * 8)) + d_print("class size %d" % self.size) + index += 2 + + templen = FruUtil.decodeLength(self.data[index]) + self.productManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productManufacturer:%s" % self.productManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.productName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productName:%s" % self.productName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productPartModelName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productPartModelName:%s" % self.productPartModelName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productVersion = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productVersion:%s" % self.productVersion) + + templen = FruUtil.decodeLength(self.data[index]) + self.productSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productSerialNumber:%s" % self.productSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.productAssetTag = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productAssetTag:%s" % self.productAssetTag) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if self.data[index] != chr(0xc1) and index < self.size - 1: + templen = FruUtil.decodeLength(self.data[index]) + if templen == 0: + break + tmpval = self.data[index + 1: index + templen + 1] + d_print("decode boardextra%d:%s" % (i, tmpval)) + setattr(self, valtmp, tmpval) + index += templen + 1 + else: + break + + @property + def productVersion(self): + return self._productVersion + + @productVersion.setter + def productVersion(self, name): + self._productVersion = name + + @property + def areaversion(self): + self._areaversion = self.COMMON_HEAD_VERSION + return self._areaversion + + @areaversion.setter + def areaversion(self, name): + self._areaversion = name + + @property + def language(self): + self._language = 25 + return self._language + + @property + def productManufacturer(self): + return self._productManufacturer + + @productManufacturer.setter + def productManufacturer(self, name): + self._productManufacturer = name + + @property + def productName(self): + return self._productName + + @productName.setter + def productName(self, name): + self._productName = name + + @property + def productPartModelName(self): + return self._productPartModelName + + @productPartModelName.setter + def productPartModelName(self, name): + self._productPartModelName = name + + @property + def productSerialNumber(self): + return self._productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, name): + self._productSerialNumber = name + + @property + def productAssetTag(self): + return self._productAssetTag + + @productAssetTag.setter + def productAssetTag(self, name): + self._productAssetTag = name + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, name): + self._FRUFileID = name + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("product version:%x" % ord(self.areaversion)) + d_print("product length:%d" % self.size) + d_print("product language:%x" % self.language) + self.data = chr(ord(self.areaversion)) + \ + chr(self.size // 8) + chr(self.language) + + typelength = FruUtil.getTypeLength(self.productManufacturer) + self.data += chr(typelength) + self.data += self.productManufacturer + + self.data += chr(FruUtil.getTypeLength(self.productName)) + self.data += self.productName + + self.data += chr(FruUtil.getTypeLength(self.productPartModelName)) + self.data += self.productPartModelName + + self.data += chr(FruUtil.getTypeLength(self.productVersion)) + self.data += self.productVersion + + self.data += chr(FruUtil.getTypeLength(self.productSerialNumber)) + self.data += self.productSerialNumber + + self.data += chr(FruUtil.getTypeLength(self.productAssetTag)) + if self.productAssetTag is not None: + self.data += self.productAssetTag + + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + d_print("self.data:%d" % len(self.data)) + d_print("self.size:%d" % self.size) + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + +class MultiRecordArea(BaseArea): + pass + + +class Field(object): + + def __init__(self, fieldType="ASCII", fieldData=""): + self.fieldData = fieldData + self.fieldType = fieldType + + @property + def fieldType(self): + return self.fieldType + + @property + def fieldData(self): + return self.fieldData + + +class ipmifru(BaseArea): + _BoardInfoArea = None + _ProductInfoArea = None + _InternalUseArea = None + _ChassisInfoArea = None + _multiRecordArea = None + _productinfoAreaOffset = BaseArea.INITVALUE + _boardInfoAreaOffset = BaseArea.INITVALUE + _internalUserAreaOffset = BaseArea.INITVALUE + _chassicInfoAreaOffset = BaseArea.INITVALUE + _multiRecordAreaOffset = BaseArea.INITVALUE + _bindata = None + _bodybin = None + _version = BaseArea.COMMON_HEAD_VERSION + _zeroCheckSum = None + _frusize = 256 + + def __str__(self): + tmpstr = "" + if self.boardInfoArea.isPresent: + tmpstr += "\nboardinfoarea: \n" + tmpstr += self.boardInfoArea.__str__() + if self.productInfoArea.isPresent: + tmpstr += "\nproductinfoarea: \n" + tmpstr += self.productInfoArea.__str__() + return tmpstr + + def decodeBin(self, eeprom): + commonHead = eeprom[0:8] + d_print("decode version %x" % ord(commonHead[0])) + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): + raise FruException("HEAD VERSION error,not Fru format!", -10) + if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): + strtemp = "check header checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) + raise FruException(strtemp, -3) + if ord(commonHead[1]) != ord(self.INITVALUE): + d_print("Internal Use Area is present") + self.internalUseArea = InternalUseArea( + name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) + self.internalUseArea.isPresent = True + self.internalUserAreaOffset = ord(commonHead[1]) + self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( + self.internalUserAreaOffset * 8 + self.internalUseArea.size)] + if ord(commonHead[2]) != ord(self.INITVALUE): + d_print("Chassis Info Area is present") + self.chassisInfoArea = ChassisInfoArea( + name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) + self.chassisInfoArea.isPresent = True + self.chassicInfoAreaOffset = ord(commonHead[2]) + self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( + self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] + if ord(commonHead[3]) != ord(self.INITVALUE): + self.boardInfoArea = BoardInfoArea( + name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) + self.boardInfoArea.isPresent = True + self.boardInfoAreaOffset = ord(commonHead[3]) + self.boardInfoArea.size = ord( + eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8 + d_print("Board Info Area is present size:%d" % + (self.boardInfoArea.size)) + self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( + self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] + if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + (FruUtil.checksum( + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.boardInfoArea.decodedata() + if ord(commonHead[4]) != ord(self.INITVALUE): + d_print("Product Info Area is present") + self.productInfoArea = ProductInfoArea( + name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) + self.productInfoArea.isPresent = True + self.productinfoAreaOffset = ord(commonHead[4]) + d_print("length offset value: %02x" % + ord(eeprom[self.productinfoAreaOffset * 8 + 1])) + self.productInfoArea.size = ord( + eeprom[self.productinfoAreaOffset * 8 + 1]) * 8 + d_print("Product Info Area is present size:%d" % + (self.productInfoArea.size)) + + self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: ( + self.productinfoAreaOffset * 8 + self.productInfoArea.size)] + if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]): + strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.productInfoArea.decodedata() + if ord(commonHead[5]) != ord(self.INITVALUE): + self.multiRecordArea = MultiRecordArea( + name="MultiRecord record Area ") + d_print("MultiRecord record present") + self.multiRecordArea.isPresent = True + self.multiRecordAreaOffset = ord(commonHead[5]) + self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: ( + self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)] + + def initDefault(self): + self.version = self.COMMON_HEAD_VERSION + self.internalUserAreaOffset = self.INITVALUE + self.chassicInfoAreaOffset = self.INITVALUE + self.boardInfoAreaOffset = self.INITVALUE + self.productinfoAreaOffset = self.INITVALUE + self.multiRecordAreaOffset = self.INITVALUE + self.zeroCheckSum = self.INITVALUE + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + self.productInfoArea = None + self.internalUseArea = None + self.boardInfoArea = None + self.chassisInfoArea = None + self.multiRecordArea = None + # self.recalcute() + + @property + def version(self): + return self._version + + @version.setter + def version(self, name): + self._version = name + + @property + def internalUserAreaOffset(self): + return self._internalUserAreaOffset + + @internalUserAreaOffset.setter + def internalUserAreaOffset(self, obj): + self._internalUserAreaOffset = obj + + @property + def chassicInfoAreaOffset(self): + return self._chassicInfoAreaOffset + + @chassicInfoAreaOffset.setter + def chassicInfoAreaOffset(self, obj): + self._chassicInfoAreaOffset = obj + + @property + def productinfoAreaOffset(self): + return self._productinfoAreaOffset + + @productinfoAreaOffset.setter + def productinfoAreaOffset(self, obj): + self._productinfoAreaOffset = obj + + @property + def boardInfoAreaOffset(self): + return self._boardInfoAreaOffset + + @boardInfoAreaOffset.setter + def boardInfoAreaOffset(self, obj): + self._boardInfoAreaOffset = obj + + @property + def multiRecordAreaOffset(self): + return self._multiRecordAreaOffset + + @multiRecordAreaOffset.setter + def multiRecordAreaOffset(self, obj): + self._multiRecordAreaOffset = obj + + @property + def zeroCheckSum(self): + return self._zeroCheckSum + + @zeroCheckSum.setter + def zeroCheckSum(self, obj): + self._zeroCheckSum = obj + + @property + def productInfoArea(self): + return self._ProductInfoArea + + @productInfoArea.setter + def productInfoArea(self, obj): + self._ProductInfoArea = obj + + @property + def internalUseArea(self): + return self._InternalUseArea + + @internalUseArea.setter + def internalUseArea(self, obj): + self.internalUseArea = obj + + @property + def boardInfoArea(self): + return self._BoardInfoArea + + @boardInfoArea.setter + def boardInfoArea(self, obj): + self._BoardInfoArea = obj + + @property + def chassisInfoArea(self): + return self._ChassisInfoArea + + @chassisInfoArea.setter + def chassisInfoArea(self, obj): + self._ChassisInfoArea = obj + + @property + def multiRecordArea(self): + return self._multiRecordArea + + @multiRecordArea.setter + def multiRecordArea(self, obj): + self._multiRecordArea = obj + + @property + def bindata(self): + return self._bindata + + @bindata.setter + def bindata(self, obj): + self._bindata = obj + + @property + def bodybin(self): + return self._bodybin + + @bodybin.setter + def bodybin(self, obj): + self._bodybin = obj + + def recalcuteCommonHead(self): + self.bindata = "" + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) + if self.internalUseArea is not None and self.internalUseArea.isPresent: + self.internalUserAreaOffset = self.offset // 8 + self.offset += self.internalUseArea.size + d_print("internalUseArea is present offset:%d" % self.offset) + + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + self.chassicInfoAreaOffset = self.offset // 8 + self.offset += self.chassisInfoArea.size + d_print("chassisInfoArea is present offset:%d" % self.offset) + + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + self.boardInfoAreaOffset = self.offset // 8 + self.offset += self.boardInfoArea.size + d_print("boardInfoArea is present offset:%d" % self.offset) + d_print("boardInfoArea is present size:%d" % + self.boardInfoArea.size) + + if self.productInfoArea is not None and self.productInfoArea.isPresent: + self.productinfoAreaOffset = self.offset // 8 + self.offset += self.productInfoArea.size + d_print("productInfoArea is present offset:%d" % self.offset) + + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + self.multiRecordAreaOffset = self.offset // 8 + d_print("multiRecordArea is present offset:%d" % self.offset) + + if self.internalUserAreaOffset == self.INITVALUE: + self.internalUserAreaOffset = 0 + if self.productinfoAreaOffset == self.INITVALUE: + self.productinfoAreaOffset = 0 + if self.chassicInfoAreaOffset == self.INITVALUE: + self.chassicInfoAreaOffset = 0 + if self.boardInfoAreaOffset == self.INITVALUE: + self.boardInfoAreaOffset = 0 + if self.multiRecordAreaOffset == self.INITVALUE: + self.multiRecordAreaOffset = 0 + + self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset + - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff + d_print("zerochecksum:%x" % self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) + + self.bindata = self.data + self.bodybin + totallen = len(self.bindata) + d_print("totallen %d" % totallen) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) + else: + raise FruException('bin data more than %d' % self._frusize, -2) + + def recalcutebin(self): + self.bodybin = "" + if self.internalUseArea is not None and self.internalUseArea.isPresent: + d_print("internalUseArea present") + self.bodybin += self.internalUseArea.data + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + d_print("chassisInfoArea present") + self.bodybin += self.chassisInfoArea.data + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + d_print("boardInfoArea present") + self.boardInfoArea.recalcute() + self.bodybin += self.boardInfoArea.data + if self.productInfoArea is not None and self.productInfoArea.isPresent: + d_print("productInfoAreapresent") + self.productInfoArea.recalcute() + self.bodybin += self.productInfoArea.data + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + d_print("multiRecordArea present") + self.bodybin += self.productInfoArea.data + + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size + self.recalcutebin() + self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/minigraph.xml b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/minigraph.xml deleted file mode 100644 index 4aa22016c11a..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/minigraph.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - switch2 - - - - - - - - - - - - - switch2 - RA-B6920-4S - - - - - - - switch2 - - - DhcpResources - - - - - NtpResources - - 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org - - - SyslogResources - - - - - ErspanDestinationIpv4 - - 2.2.2.2 - - - - - - - switch2 - RA-B6920-4S - diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/monitor.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/monitor.py index 3aa8fd3f2901..93332a92ad29 100644 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/monitor.py +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/monitor.py @@ -1,5 +1,4 @@ -#!/usr/bin/python -# -*- coding: UTF-8 -*- +#!/usr/bin/python3 # * onboard temperature sensors # * FAN trays # * PSU @@ -7,92 +6,154 @@ import os import xml.etree.ElementTree as ET import glob -from eepromutil.fru import * +import json +from decimal import Decimal +from fru import ipmifru + MAILBOX_DIR = "/sys/bus/i2c/devices/" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + CONFIG_NAME = "dev.xml" + +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + return val + + +def get_board_id(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +boardid = get_board_id() +boardairflow = getboardairflow() + + +DEV_XML_FILE_LIST = [ + "dev_" + boardid + "_" + boardairflow + ".xml", + "dev_" + boardid + ".xml", + "dev_" + boardairflow + ".xml", +] + + +def dev_file_read(path, offset, read_len): + retval = "ERR" + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + return False, "%s %s not found" % (retval, path) + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, "%s %s" % (retval, msg) + finally: + if fd > 0: + os.close(fd) + return True, val_list + + def getPMCreg(location): retval = 'ERR' - if (not os.path.isfile(location)): - return "%s %s notfound"% (retval , location) + if not os.path.isfile(location): + return "%s %s notfound" % (retval, location) try: with open(location, 'r') as fd: retval = fd.read() except Exception as error: - pass + return "ERR %s" % str(error) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval + + # Get a mailbox register def get_pmc_register(reg_name): retval = 'ERR' mb_reg_file = reg_name filepath = glob.glob(mb_reg_file) - if(len(filepath) == 0): - return "%s %s notfound"% (retval , mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) mb_reg_file = filepath[0] - if (not os.path.isfile(mb_reg_file)): - #print mb_reg_file, 'not found !' - return "%s %s notfound"% (retval , mb_reg_file) + if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' + return "%s %s notfound" % (retval, mb_reg_file) try: - with open(mb_reg_file, 'r') as fd: + with open(mb_reg_file, 'rb') as fd: retval = fd.read() + retval = typeTostr(retval) except Exception as error: - pass + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") return retval + class checktype(): def __init__(self, test1): self.test1 = test1 + @staticmethod - def check(name,location, bit, value, tips , err1): - psu_status = int(get_pmc_register(location),16) - val = (psu_status & (1<< bit)) >> bit - if (val != value): - err1["errmsg"] = tips - err1["code"] = -1 - return -1 - else: - err1["errmsg"] = "none" - err1["code"] = 0 - return 0 - @staticmethod - def getValue(location, bit , type): - value_t = get_pmc_register(location) - if value_t.startswith("ERR") : + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) + return value_t + except Exception as e: + value_t = "ERR %s" % str(e) return value_t - if (type == 1): - return float(value_t)/1000 - elif (type == 2): - return float(value_t)/100 - elif (type == 3): - psu_status = int(value_t,16) - return (psu_status & (1<< bit)) >> bit - elif (type == 4): - return int(value_t,10) - else: - return value_t; -#######temp - @staticmethod - def getTemp(self, name, location , ret_t): - ret2 = self.getValue(location + "temp1_input" ," " ,1); - ret3 = self.getValue(location + "temp1_max" ," ", 1); - ret4 = self.getValue(location + "temp1_max_hyst" ," ", 1); - ret_t["temp1_input"] = ret2 - ret_t["temp1_max"] = ret3 - ret_t["temp1_max_hyst"] = ret4 - @staticmethod - def getLM75(name, location, result): - c1=checktype - r1={} - c1.getTemp(c1, name, location, r1) - result[name] = r1 -##########fanFRU + + # fanFRU @staticmethod def decodeBinByValue(retval): fru = ipmifru() @@ -100,30 +161,72 @@ def decodeBinByValue(retval): return fru @staticmethod - def printbinvalue(b): - index = 0 - print " ", - for width in range(16): - print "%02x " % width, - print "" - for i in range(0, len(b)): - if index % 16 == 0: - print " " - print " %02x " % i, - print "%02x " % ord(b[i]), - index += 1 - print "" - - @staticmethod - def getfruValue(val): - binval = checktype.getValue(val, 0 , 0) - fanpro = {} - ret = checktype.decodeBinByValue(binval) - fanpro['fan_type'] = ret.productInfoArea.productName - fanpro['hw_version'] = int(ret.productInfoArea.productVersion, 16) - fanpro['sn'] = ret.productInfoArea.productSerialNumber - fanpro['fanid'] = ret.productInfoArea.productextra2 - return fanpro + def getfruValue(prob_t, root, val): + try: + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) + fanpro = {} + ret = checktype.decodeBinByValue(binval) + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = ret.productInfoArea.productVersion + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] + return fanpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getslotfruValue(val): + try: + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + slotpro = {} + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber + return slotpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getpsufruValue(prob_t, root, val): + try: + psu_match = False + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + psupro = {} + ret = checktype.decodeBinByValue(binval) + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name in psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro + except Exception as error: + return "ERR " + str(error) class status(): @@ -134,101 +237,148 @@ def __init__(self, productname): def getETroot(filename): tree = ET.parse(filename) root = tree.getroot() - return root; + return root @staticmethod def getDecodValue(collection, decode): decodes = collection.find('decode') testdecode = decodes.find(decode) - test={} + test = {} + if testdecode is None: + return test for neighbor in testdecode.iter('code'): - test[neighbor.attrib["key"]]=neighbor.attrib["value"] + test[neighbor.attrib["key"]] = neighbor.attrib["value"] return test + @staticmethod def getfileValue(location): - return checktype.getValue(location," "," ") + return checktype.getValue(location, " ", " ") + @staticmethod def getETValue(a, filename, tagname): root = status.getETroot(filename) for neighbor in root.iter(tagname): prob_t = {} prob_t = neighbor.attrib - prob_t['errcode']= 0 + prob_t['errcode'] = 0 prob_t['errmsg'] = '' for pros in neighbor.iter("property"): - ret = dict(neighbor.attrib.items() + pros.attrib.items()) + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) if ret.get('e2type') == 'fru' and ret.get("name") == "fru": - fruval = checktype.getfruValue(ret["location"]) + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break prob_t.update(fruval) - if ('type' not in ret.keys()): - val = "0"; + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("name") == "slot" and ret.get('e2type') == 'fru': + slotval = checktype.getslotfruValue( ret["location"]) + if isinstance(slotval, str) and slotval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = slotval + break + prob_t.update(slotval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): + val = "0" else: val = ret["type"] - if ('bit' not in ret.keys()): - bit = "0"; + if 'bit' not in ret.keys(): + bit = "0" else: bit = ret["bit"] - s = checktype.getValue(ret["location"], int(bit),int(val)) - if isinstance(s, str) and s.startswith("ERR"): - prob_t['errcode']= -1 - prob_t['errmsg']= s - if ('default' in ret.keys()): - rt = status.getDecodValue(root,ret['decode']) - prob_t['errmsg']= rt[str(s)] + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) + if isinstance(s, str) and s.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] if str(s) != ret["default"]: - prob_t['errcode']= -1 - break; + prob_t['errcode'] = -1 + break else: - if ('decode' in ret.keys()): - rt = status.getDecodValue(root,ret['decode']) - if(ret['decode'] == "psutype" and s.replace("\x00","").rstrip() not in rt.keys()): - prob_t['errcode']= -1 - prob_t['errmsg'] = '%s'% ("Not supported PSU") + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) else: - s = rt[str(s).replace("\x00","").rstrip()] + s = rt[str(s).replace("\x00", "").rstrip()] name = ret["name"] - prob_t[name]=str(s) + prob_t[name] = str(s) a.append(prob_t) + @staticmethod def getCPUValue(a, filename, tagname): root = status.getETroot(filename) for neighbor in root.iter(tagname): - location = neighbor.attrib["location"] - L=[] + location = neighbor.attrib["location"] + L = [] for dirpath, dirnames, filenames in os.walk(location): - for file in filenames : + for file in filenames: if file.endswith("input"): L.append(os.path.join(dirpath, file)) - L =sorted(L,reverse=False) + L = sorted(L, reverse=False) for i in range(len(L)): prob_t = {} - prob_t["name"] = getPMCreg("%s/temp%d_label"%(location,i+1)) - prob_t["temp"] = float(getPMCreg("%s/temp%d_input"%(location,i+1)))/1000 - prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm"%(location,i+1)))/1000 - prob_t["crit"] = float(getPMCreg("%s/temp%d_crit"%(location,i+1)))/1000 - prob_t["max"] = float(getPMCreg("%s/temp%d_max"%(location,i+1)))/1000 + prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 + prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 a.append(prob_t) @staticmethod def getFileName(): - return os.path.dirname(os.path.realpath(__file__)) + "/"+ CONFIG_NAME - @staticmethod - def getFan(ret): - _filename = status.getFileName() - _tagname = "fan" - status.getvalue(ret, _filename, _tagname) + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME + @staticmethod def checkFan(ret): _filename = status.getFileName() # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "fan" status.getETValue(ret, _filename, _tagname) + @staticmethod def getTemp(ret): _filename = status.getFileName() - #_filename = "/usr/local/bin/" + status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() _tagname = "temp" status.getETValue(ret, _filename, _tagname) + @staticmethod def getPsu(ret): _filename = status.getFileName() @@ -236,6 +386,13 @@ def getPsu(ret): _tagname = "psu" status.getETValue(ret, _filename, _tagname) + @staticmethod + def checkSlot(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "slot" + status.getETValue(ret, _filename, _tagname) + @staticmethod def getcputemp(ret): _filename = status.getFileName() @@ -243,10 +400,19 @@ def getcputemp(ret): status.getCPUValue(ret, _filename, _tagname) @staticmethod - def checkSlot(ret): + def getDcdc(ret): _filename = status.getFileName() - # _filename = "/usr/local/bin/" + status.getFileName() - _tagname = "slot" + _tagname = "dcdc" status.getETValue(ret, _filename, _tagname) + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + @staticmethod + def getmacpower(ret): + _filename = status.getFileName() + _tagname = "macpower" + status.getETValue(ret, _filename, _tagname) diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pcie.yaml b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pcie.yaml new file mode 100644 index 000000000000..0dcb12e3d354 --- /dev/null +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pcie.yaml @@ -0,0 +1,441 @@ +- 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: '01' + fn: '1' + id: 6f03 + 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: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: '16' + fn: '0' + id: 8c3a + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #1 (rev 04)' +- bus: '00' + dev: '16' + fn: '1' + id: 8c3b + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #2 (rev 04)' +- 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: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '04' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '04' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '06' + dev: '00' + fn: '0' + id: b980 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b980 (rev 11)' +- bus: '07' + dev: '00' + fn: '0' + id: '1537' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Backplane 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: 0c + fn: '2' + id: 6fe2 + 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: '3' + id: 6fe3 + 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/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf/pd-plugin.json b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf/pd-plugin.json deleted file mode 100644 index ffa06ff74303..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf/pd-plugin.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "XCVR": { - "xcvr_present": { - "i2c": { - "valmap-SFP28": { - "1": true, - "0": false - }, - "valmap-QSFP28": { - "1": true, - "0": false - } - } - } - }, - - "PSU": { - "psu_present": { - "i2c": { - "valmap": { - "1": true, - "0": false - } - } - }, - - "psu_power_good": { - "i2c": { - "valmap": { - "1": true, - "0": false - } - } - }, - - "psu_fan_dir": { - "i2c": { - "valmap": { - "F2B": "EXHAUST", - "B2F": "INTAKE" - } - } - }, - "PSU_FAN_MAX_SPEED": "18000" - }, - - "FAN": { - "direction": { - "i2c": { - "valmap": { - "1": "INTAKE", - "0": "EXHAUST" - } - } - }, - "present": { - "i2c": { - "valmap": { - "1": true, - "0": false - } - } - }, - "duty_cycle_to_pwm": "lambda dc: dc*255/100", - "pwm_to_duty_cycle": "lambda pwm: pwm*100/255" - } -} diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf/pddf-device.json b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf/pddf-device.json deleted file mode 100755 index 9e5c150527cc..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf/pddf-device.json +++ /dev/null @@ -1,13877 +0,0 @@ -{ - "PLATFORM": { - "num_psus": 4, - "num_fantrays": 6, - "num_fans_pertray": 2, - "num_ports": 128, - "num_temps": 18, - "pddf_dev_types": { - "description": "RA-B6920-4S", - "CPLD": [ - "i2c_cpld" - ], - "PSU": [ - "psu_eeprom", - "psu_pmbus" - ], - "FAN": [ - "fan_ctrl", - "fan_cpld", - "fan_eeprom" - ], - "PORT_MODULE": [ - "pddf_xcvr", - "optoe1", - "optoe2" - ] - }, - "std_kos": [ - "i2c-i801", - "i2c_dev", - "rg_i2c_gpio", - "rg_i2c_algo_bit", - "i2c_mux", - "i2c_mux_pca954x force_create_bus=1", - "lm75", - "tmp401", - "rg_gpio_xeon", - "ragile_common dfd_my_type=0x404d", - "lpc_dbg", - "lpc_cpld_i2c", - "lpc_cpld_i2c_ocores", - "rg_lpc_cpld", - "optoe", - "at24" - ], - "pddf_kos": [ - "pddf_client_module", - "pddf_cpld_module", - "pddf_cpld_driver", - "pddf_mux_module", - "pddf_xcvr_module", - "pddf_xcvr_driver_module", - "pddf_psu_driver_module", - "pddf_psu_module", - "pddf_fan_driver_module", - "pddf_fan_module", - "pddf_sysstatus_module" - ], - "custom_kos": [ - "pddf_custom_fan", - "pddf_custom_psu", - "pddf_custom_xcvr", - "pddf_custom_led_module" - ] - }, - - "SYSTEM": { - "dev_info": { - "device_type": "CPU", - "device_name": "ROOT_COMPLEX", - "device_parent": null - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-0", - "dev": "SMBUS0" - }, { - "dev_name": "i2c-1", - "dev": "I2C-GPIO0" - }, { - "dev_name": "i2c-2", - "dev": "CPLD-OCORE0" - }, { - "dev_name": "i2c-3", - "dev": "CPLD-OCORE1" - },{ - "dev_name": "i2c-4", - "dev": "CPLD-OCORE2" - },{ - "dev_name": "i2c-5", - "dev": "CPLD-OCORE3" - },{ - "dev_name": "i2c-6", - "dev": "CPLD-OCORE4" - }] - } - }, - - "SMBUS0": { - "dev_info": { - "device_type": "SMBUS", - "device_name": "SMBUS0", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x0" - }, - "DEVICES": [] - } - }, - - "I2C-GPIO0": { - "dev_info": { - "device_type": "I2C-GPIO", - "device_name": "I2C-GPIO0", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x1" - }, - "DEVICES": [{ - "dev": "EEPROM1" - } - ] - } - }, - - "EEPROM1": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "EEPROM1", - "device_parent": "I2C-GPIO0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1", - "dev_addr": "0x56", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "CPLD-OCORE0": { - "dev_info": { - "device_type": "CPLD-OCORE", - "device_name": "CPLD-OCORE0", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x2" - }, - "DEVICES": [{ - "dev": "MUX0" - }, { - "dev": "FAN-CTRL" - } - ] - } - }, - - "MUX0": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX0", - "device_parent": "CPLD-OCORE0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x76", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x07" - }, - "channel": [{ - "chn": "0", - "dev": "MUX1" - }, - { - "chn": "1", - "dev": "MUX2" - }, - { - "chn": "2", - "dev": "MUX3" - }, - { - "chn": "4", - "dev": "MUX4" - }, - { - "chn": "5", - "dev": "MUX5" - }, - { - "chn": "6", - "dev": "V-MUX-CONTROLLER0" - }, - { - "chn": "7", - "dev": "V-MUX-CONTROLLER1" - } - ] - } - }, - - "MUX1": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX1", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0xf" - }, - "channel": [ - { - "chn": "1", - "dev": "V-CONTROLLER0" - } - ] - } - }, - - "V-CONTROLLER0": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-CONTROLLER0", - "device_parent": "MUX1" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-16", - "dev": "TEMP-NODE0" - }] - } - }, - - "TEMP-NODE0": { - "dev_info": { - "device_type": "TEMP-NODE", - "device_name": "LC4-TEMP-NODE", - "device_parent": "MUX1" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x10", - "parent_bus": "0x7" - }, - "DEVICES": [{ - "dev": "TEMP1" - },{ - "dev": "TEMP2" - },{ - "dev": "TEMP3" - } - ] - } - }, - - "TEMP1": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC4-TEMP1", - "device_parent": "MUX1" - }, - "dev_attr": { - "display_name": "LC4-TEMP1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x10", - "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": "LC4-TEMP2", - "device_parent": "MUX1" - }, - "dev_attr": { - "display_name": "LC4-TEMP2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x10", - "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": "LC4-TEMP3", - "device_parent": "MUX1" - }, - "dev_attr": { - "display_name": "LC4-TEMP3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x10", - "dev_addr": "0x4d", - "dev_type": "lm75" - }, - "attr_list": [{ - "attr_name": "temp1_high_threshold", - "drv_attr_name": "temp1_max" - }, - { - "attr_name": "temp1_max_hyst" - }, - { - "attr_name": "temp1_input" - } - ] - } - }, - - "MUX2": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX2", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x17" - }, - "channel": [{ - "chn": "0", - "dev": "PSU1" - }, - { - "chn": "1", - "dev": "PSU2" - }, - { - "chn": "2", - "dev": "PSU3" - }, - { - "chn": "3", - "dev": "PSU4" - }, - { - "chn": "5", - "dev": "V-CONTROLLER1" - }, - { - "chn": "6", - "dev": "V-CONTROLLER2" - } - ] - } - }, - - "PSU1": { - "dev_info": { - "device_type": "PSU", - "device_name": "PSU1", - "device_parent": "MUX2" - }, - "dev_attr": { - "dev_idx": "1", - "num_psu_fans": "1" - }, - "i2c": { - "interface": [{ - "itf": "pmbus", - "dev": "PSU1-PMBUS" - }, - { - "itf": "eeprom", - "dev": "PSU1-EEPROM" - } - ] - } - }, - - "PSU1-PMBUS": { - "dev_info": { - "device_type": "PSU-PMBUS", - "device_name": "PSU1-PMBUS", - "device_parent": "MUX2", - "virt_parent": "PSU1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x17", - "dev_addr": "0x58", - "dev_type": "psu_pmbus" - }, - "attr_list": [{ - "attr_name": "psu_present", - "attr_devtype": "io", - "attr_offset": "0xb27", - "attr_mask": "0x1", - "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": "12" - }, - { - "attr_name": "psu_power_good", - "attr_devtype": "io", - "attr_offset": "0xb27", - "attr_mask": "0x2", - "attr_cmpval": "0x2", - "attr_len": "1" - }, - { - "attr_name": "psu_mfr_id", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0x99", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "10" - }, - { - "attr_name": "psu_fan_dir", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0xc3", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "5" - }, - { - "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_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" - } - ] - } - }, - - "PSU1-EEPROM": { - "dev_info": { - "device_type": "PSU-EEPROM", - "device_name": "PSU1-EEPROM", - "device_parent": "MUX2", - "virt_parent": "PSU1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x17", - "dev_addr": "0x50", - "dev_type": "psu_eeprom" - }, - "attr_list": [{ - "attr_name": "psu_serial_num", - "attr_devaddr": "0x50", - "attr_devtype": "eeprom", - "attr_offset": "0x38", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "20" - }] - } - }, - - "PSU2": { - "dev_info": { - "device_type": "PSU", - "device_name": "PSU2", - "device_parent": "MUX2" - }, - "dev_attr": { - "dev_idx": "2", - "num_psu_fans": "1" - }, - "i2c": { - "interface": [{ - "itf": "pmbus", - "dev": "PSU2-PMBUS" - }, - { - "itf": "eeprom", - "dev": "PSU2-EEPROM" - } - ] - } - }, - - "PSU2-PMBUS": { - "dev_info": { - "device_type": "PSU-PMBUS", - "device_name": "PSU2-PMBUS", - "device_parent": "MUX2", - "virt_parent": "PSU2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x18", - "dev_addr": "0x58", - "dev_type": "psu_pmbus" - }, - "attr_list": [{ - "attr_name": "psu_present", - "attr_devtype": "io", - "attr_offset": "0xb28", - "attr_mask": "0x01", - "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": "12" - }, - { - "attr_name": "psu_power_good", - "attr_devtype": "io", - "attr_offset": "0xb28", - "attr_mask": "0x02", - "attr_cmpval": "0x02", - "attr_len": "1" - }, - { - "attr_name": "psu_mfr_id", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0x99", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "10" - }, - { - "attr_name": "psu_fan_dir", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0xc3", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "5" - }, - { - "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_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-EEPROM": { - "dev_info": { - "device_type": "PSU-EEPROM", - "device_name": "PSU2-EEPROM", - "device_parent": "MUX2", - "virt_parent": "PSU2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x18", - "dev_addr": "0x50", - "dev_type": "psu_eeprom" - }, - "attr_list": [{ - "attr_name": "psu_serial_num", - "attr_devaddr": "0x50", - "attr_devtype": "eeprom", - "attr_offset": "0x38", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "20" - }] - } - }, - - "PSU3": { - "dev_info": { - "device_type": "PSU", - "device_name": "PSU3", - "device_parent": "MUX2" - }, - "dev_attr": { - "dev_idx": "3", - "num_psu_fans": "1" - }, - "i2c": { - "interface": [{ - "itf": "pmbus", - "dev": "PSU3-PMBUS" - }, - { - "itf": "eeprom", - "dev": "PSU3-EEPROM" - } - ] - } - }, - - "PSU3-PMBUS": { - "dev_info": { - "device_type": "PSU-PMBUS", - "device_name": "PSU3-PMBUS", - "device_parent": "MUX2", - "virt_parent": "PSU3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x19", - "dev_addr": "0x58", - "dev_type": "psu_pmbus" - }, - "attr_list": [{ - "attr_name": "psu_present", - "attr_devtype": "io", - "attr_offset": "0xb29", - "attr_mask": "0x01", - "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": "12" - }, - { - "attr_name": "psu_power_good", - "attr_devtype": "io", - "attr_offset": "0xb29", - "attr_mask": "0x02", - "attr_cmpval": "0x02", - "attr_len": "1" - }, - { - "attr_name": "psu_mfr_id", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0x99", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "10" - }, - { - "attr_name": "psu_fan_dir", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0xc3", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "5" - }, - { - "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_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" - } - ] - } - }, - - "PSU3-EEPROM": { - "dev_info": { - "device_type": "PSU-EEPROM", - "device_name": "PSU3-EEPROM", - "device_parent": "MUX2", - "virt_parent": "PSU3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x19", - "dev_addr": "0x50", - "dev_type": "psu_eeprom" - }, - "attr_list": [{ - "attr_name": "psu_serial_num", - "attr_devaddr": "0x50", - "attr_devtype": "eeprom", - "attr_offset": "0x38", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "20" - }] - } - }, - - "PSU4": { - "dev_info": { - "device_type": "PSU", - "device_name": "PSU4", - "device_parent": "MUX2" - }, - "dev_attr": { - "dev_idx": "4", - "num_psu_fans": "1" - }, - "i2c": { - "interface": [{ - "itf": "pmbus", - "dev": "PSU4-PMBUS" - }, - { - "itf": "eeprom", - "dev": "PSU4-EEPROM" - } - ] - } - }, - - "PSU4-PMBUS": { - "dev_info": { - "device_type": "PSU-PMBUS", - "device_name": "PSU4-PMBUS", - "device_parent": "MUX2", - "virt_parent": "PSU4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1a", - "dev_addr": "0x58", - "dev_type": "psu_pmbus" - }, - "attr_list": [{ - "attr_name": "psu_present", - "attr_devtype": "io", - "attr_offset": "0xb2a", - "attr_mask": "0x01", - "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": "12" - }, - { - "attr_name": "psu_power_good", - "attr_devtype": "io", - "attr_offset": "0xb2a", - "attr_mask": "0x02", - "attr_cmpval": "0x02", - "attr_len": "1" - }, - { - "attr_name": "psu_mfr_id", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0x99", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "10" - }, - { - "attr_name": "psu_fan_dir", - "attr_devaddr": "0x58", - "attr_devtype": "pmbus", - "attr_offset": "0xc3", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "5" - }, - { - "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_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" - } - ] - } - }, - - "PSU4-EEPROM": { - "dev_info": { - "device_type": "PSU-EEPROM", - "device_name": "PSU4-EEPROM", - "device_parent": "MUX2", - "virt_parent": "PSU4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1a", - "dev_addr": "0x50", - "dev_type": "psu_eeprom" - }, - "attr_list": [{ - "attr_name": "psu_serial_num", - "attr_devaddr": "0x50", - "attr_devtype": "eeprom", - "attr_offset": "0x38", - "attr_mask": "0x0", - "attr_cmpval": "0xff", - "attr_len": "20" - }] - } - }, - - "V-CONTROLLER1": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-CONTROLLER1", - "device_parent": "MUX2" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-28", - "dev": "TEMP-NODE1" - }] - } - }, - - "TEMP-NODE1": { - "dev_info": { - "device_type": "TEMP-NODE", - "device_name": "MAC-TEMP-NODE0", - "device_parent": "MUX2" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x1c", - "parent_bus": "0x8" - }, - "DEVICES": [{ - "dev": "TEMP4" - } - ] - } - }, - - "TEMP4": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "TEMP-MAC-OUTLET", - "device_parent": "MUX2" - }, - "dev_attr": { - "display_name": "Temp_MAC_OUTLET" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1c", - "dev_addr": "0x4b", - "dev_type": "lm75" - }, - "attr_list": [{ - "attr_name": "temp1_high_threshold", - "drv_attr_name": "temp1_max" - }, - { - "attr_name": "temp1_max_hyst" - }, - { - "attr_name": "temp1_input" - } - ] - } - }, - - "V-CONTROLLER2": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-CONTROLLER2", - "device_parent": "MUX2" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-29", - "dev": "TEMP-NODE2" - }] - } - }, - - "TEMP-NODE2": { - "dev_info": { - "device_type": "TEMP-NODE", - "device_name": "MAC-TEMP-NODE1", - "device_parent": "MUX2" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x1d", - "parent_bus": "0x8" - }, - "DEVICES": [{ - "dev": "TEMP5" - } - ] - } - }, - - "TEMP5": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "TEMP-MAC-INLET", - "device_parent": "MUX2" - }, - "dev_attr": { - "display_name": "Temp_MAC_INLET" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x1d", - "dev_addr": "0x4f", - "dev_type": "lm75" - }, - "attr_list": [{ - "attr_name": "temp1_high_threshold", - "drv_attr_name": "temp1_max" - }, - { - "attr_name": "temp1_max_hyst" - }, - { - "attr_name": "temp1_input" - } - ] - } - }, - - "MUX3": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX3", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x1f" - }, - "channel": [ - { - "chn": "1", - "dev": "V-CONTROLLER3" - } - ] - } - }, - - "V-CONTROLLER3": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-CONTROLLER3", - "device_parent": "MUX3" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-32", - "dev": "TEMP-NODE3" - }] - } - }, - - "TEMP-NODE3": { - "dev_info": { - "device_type": "TEMP-NODE", - "device_name": "LC1-TEMP-NODE", - "device_parent": "MUX3" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x20", - "parent_bus": "0x9" - }, - "DEVICES": [{ - "dev": "TEMP6" - },{ - "dev": "TEMP7" - },{ - "dev": "TEMP8" - } - ] - } - }, - - "TEMP6": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC1-TEMP0", - "device_parent": "MUX3" - }, - "dev_attr": { - "display_name": "Temp_LC1_A" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x20", - "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" - } - ] - } - }, - - "TEMP7": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC1-TEMP1", - "device_parent": "MUX3" - }, - "dev_attr": { - "display_name": "Temp_LC1_B" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x20", - "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" - } - ] - } - }, - - "TEMP8": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC1-TEMP2", - "device_parent": "MUX3" - }, - "dev_attr": { - "display_name": "Temp_LC1_C" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x20", - "dev_addr": "0x4d", - "dev_type": "lm75" - }, - "attr_list": [{ - "attr_name": "temp1_high_threshold", - "drv_attr_name": "temp1_max" - }, - { - "attr_name": "temp1_max_hyst" - }, - { - "attr_name": "temp1_input" - } - ] - } - }, - - "MUX4": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX4", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x27" - }, - "channel": [ - { - "chn": "1", - "dev": "V-CONTROLLER4" - } - ] - } - }, - - "V-CONTROLLER4": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-CONTROLLER4", - "device_parent": "MUX4" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-40", - "dev": "TEMP-NODE4" - }] - } - }, - - "TEMP-NODE4": { - "dev_info": { - "device_type": "TEMP-NODE", - "device_name": "LC3-TEMP-NODE", - "device_parent": "MUX4" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x28", - "parent_bus": "0xb" - }, - "DEVICES": [{ - "dev": "TEMP9" - },{ - "dev": "TEMP10" - },{ - "dev": "TEMP11" - } - ] - } - }, - - "TEMP9": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC3-TEMP0", - "device_parent": "MUX4" - }, - "dev_attr": { - "display_name": "Temp_LC3_A" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x28", - "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" - } - ] - } - }, - - "TEMP10": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC3-TEMP1", - "device_parent": "MUX4" - }, - "dev_attr": { - "display_name": "Temp_LC3_B" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x28", - "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" - } - ] - } - }, - - "TEMP11": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC3-TEMP2", - "device_parent": "MUX4" - }, - "dev_attr": { - "display_name": "Temp_LC3_C" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x28", - "dev_addr": "0x4d", - "dev_type": "lm75" - }, - "attr_list": [{ - "attr_name": "temp1_high_threshold", - "drv_attr_name": "temp1_max" - }, - { - "attr_name": "temp1_max_hyst" - }, - { - "attr_name": "temp1_input" - } - ] - } - }, - - "MUX5": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX5", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x2f" - }, - "channel": [ - { - "chn": "1", - "dev": "V-CONTROLLER5" - } - ] - } - }, - - "V-CONTROLLER5": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-CONTROLLER5", - "device_parent": "MUX5" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-48", - "dev": "TEMP-NODE5" - }] - } - }, - - "TEMP-NODE5": { - "dev_info": { - "device_type": "TEMP-NODE", - "device_name": "LC2-TEMP-NODE", - "device_parent": "MUX5" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x30", - "parent_bus": "0xc" - }, - "DEVICES": [{ - "dev": "TEMP12" - },{ - "dev": "TEMP13" - },{ - "dev": "TEMP14" - } - ] - } - }, - - "TEMP12": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC2-TEMP0", - "device_parent": "MUX5" - }, - "dev_attr": { - "display_name": "Temp_LC2_A" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x30", - "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" - } - ] - } - }, - - "TEMP13": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC2-TEMP1", - "device_parent": "MUX5" - }, - "dev_attr": { - "display_name": "Temp_LC2_B" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x30", - "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" - } - ] - } - }, - - "TEMP14": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "LC2-TEMP2", - "device_parent": "MUX5" - }, - "dev_attr": { - "display_name": "Temp_LC2_C" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x30", - "dev_addr": "0x4d", - "dev_type": "lm75" - }, - "attr_list": [{ - "attr_name": "temp1_high_threshold", - "drv_attr_name": "temp1_max" - }, - { - "attr_name": "temp1_max_hyst" - }, - { - "attr_name": "temp1_input" - } - ] - } - }, - - "V-MUX-CONTROLLER0": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-MUX-CONTROLLER0", - "device_parent": "MUX1" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-13", - "dev": "V-NODE0" - }] - } - }, - - "V-NODE0": { - "dev_info": { - "device_type": "NODE", - "device_name": "V-NODE0", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "dev_addr": "0xd" - }, - "DEVICES": [ - { - "dev": "MUX6" - }, - { - "dev": "FAN-CPLD-B" - } - ] - } - }, - - "MUX6": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX6", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xd", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x37" - }, - "channel": [{ - "chn": "0", - "dev": "FAN2-EEPROM" - }, - { - "chn": "1", - "dev": "FAN4-EEPROM" - }, - { - "chn": "2", - "dev": "FAN6-EEPROM" - }, - { - "chn": "5", - "dev": "V-CONTROLLER6" - } - ] - } - }, - - "FAN2-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN2-EEPROM", - "device_parent": "MUX6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x37", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN4-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN4-EEPROM", - "device_parent": "MUX6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x38", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN6-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN4-EEPROM", - "device_parent": "MUX6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x39", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "V-CONTROLLER6": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-CONTROLLER6", - "device_parent": "MUX6" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-60", - "dev": "TEMP-NODE6" - }] - } - }, - - "TEMP-NODE6": { - "dev_info": { - "device_type": "TEMP-NODE", - "device_name": "FAN-CONN-TEMP-NODE-B", - "device_parent": "MUX6" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x30", - "parent_bus": "0xd" - }, - "DEVICES": [{ - "dev": "TEMP15" - },{ - "dev": "TEMP16" - } - ] - } - }, - - "TEMP15": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "FAN-CONN-B-TEMP0", - "device_parent": "MUX6" - }, - "dev_attr": { - "display_name": "Temp_FAN_CONN_B_0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3c", - "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" - } - ] - } - }, - - "TEMP16": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "FAN-CONN-B-TEMP1", - "device_parent": "MUX6" - }, - "dev_attr": { - "display_name": "Temp_FAN_CONN_B_1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3c", - "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" - } - ] - } - }, - - "FAN-CPLD-B": { - "dev_info": { - "device_type": "CPLD", - "device_name": "FAN-CPLD-B", - "device_parent": "V-CONTROLLER6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xd", - "dev_addr": "0x0d", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "V-MUX-CONTROLLER1": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-MUX-CONTROLLER1", - "device_parent": "MUX1" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-14", - "dev": "V-NODE1" - }] - } - }, - - "V-NODE1": { - "dev_info": { - "device_type": "NODE", - "device_name": "V-NODE1", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "dev_addr": "0xe" - }, - "DEVICES": [ - { - "dev": "MUX7" - }, - { - "dev": "FAN-CPLD-A" - } - ] - } - }, - - "MUX7": { - "dev_info": { - "device_type": "MUX", - "device_name": "MUX7", - "device_parent": "MUX0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xe", - "dev_addr": "0x77", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x3f" - }, - "channel": [{ - "chn": "0", - "dev": "FAN1-EEPROM" - }, - { - "chn": "1", - "dev": "FAN3-EEPROM" - }, - { - "chn": "2", - "dev": "FAN5-EEPROM" - }, - { - "chn": "5", - "dev": "V-CONTROLLER7" - } - ] - } - }, - - "FAN1-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN1-EEPROM", - "device_parent": "MUX7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3f", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN3-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN3-EEPROM", - "device_parent": "MUX7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x40", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "FAN5-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "FAN5-EEPROM", - "device_parent": "MUX7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x41", - "dev_addr": "0x50", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "V-CONTROLLER7": { - "dev_info": { - "device_type": "CPU", - "device_name": "V-CONTROLLER7", - "device_parent": "MUX7" - }, - "i2c": { - "CONTROLLERS": [{ - "dev_name": "i2c-68", - "dev": "TEMP-NODE7" - }] - } - }, - - "TEMP-NODE7": { - "dev_info": { - "device_type": "TEMP-NODE", - "device_name": "FAN-CONN-TEMP-NODE-A", - "device_parent": "MUX7" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x44" - }, - "DEVICES": [{ - "dev": "TEMP17" - },{ - "dev": "TEMP18" - } - ] - } - }, - - "TEMP17": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "FAN-CONN-A-TEMP0", - "device_parent": "MUX7" - }, - "dev_attr": { - "display_name": "Temp_FAN_CONN_A_0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x44", - "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" - } - ] - } - }, - - "TEMP18": { - "dev_info": { - "device_type": "TEMP_SENSOR", - "device_name": "FAN-CONN-A-TEMP1", - "device_parent": "MUX7" - }, - "dev_attr": { - "display_name": "Temp_FAN_CONN_A_1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x44", - "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" - } - ] - } - }, - - "FAN-CPLD-A": { - "dev_info": { - "device_type": "CPLD", - "device_name": "FAN-CPLD-A", - "device_parent": "V-CONTROLLER7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xe", - "dev_addr": "0x0d", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "CPLD-OCORE1": { - "dev_info": { - "device_type": "CPLD-OCORE", - "device_name": "CPLD-OCORE1", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x3" - }, - "DEVICES": [ - { - "dev": "LC1-CPLD-A" - }, - { - "dev": "LC1-CPLD-B" - }, - { - "dev": "LC1-EEPROM" - }, - { - "dev": "LC1-TLV-EEPROM" - }, - { - "dev": "LC1-PORT-MUX0" - }, - { - "dev": "LC1-PORT-MUX1" - }, - { - "dev": "LC1-PORT-MUX2" - }, - { - "dev": "LC1-PORT-MUX3" - } - ] - } - }, - - "LC1-CPLD-A": { - "dev_info": { - "device_type": "CPLD", - "device_name": "LC1-CPLD-A", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x30", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "LC1-CPLD-B": { - "dev_info": { - "device_type": "CPLD", - "device_name": "LC1-CPLD-B", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x31", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "LC1-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "LC1-EEPROM", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x56", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "LC1-TLV-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "LC1-TLV-EEPROM", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x57", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "LC1-PORT-MUX0": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC1-PORT-MUX0", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x70", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x47" - }, - "channel": [{ - "chn": "0", - "dev": "PORT1" - }, - { - "chn": "1", - "dev": "PORT2" - }, - { - "chn": "2", - "dev": "PORT3" - }, - { - "chn": "3", - "dev": "PORT4" - }, - { - "chn": "4", - "dev": "PORT5" - }, - { - "chn": "5", - "dev": "PORT6" - }, - { - "chn": "6", - "dev": "PORT7" - }, - { - "chn": "7", - "dev": "PORT8" - } - ] - } - }, - - "PORT1": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT1", - "device_parent": "LC1-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "1" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT1-EEPROM" - }, { - "itf": "control", - "dev": "PORT1-CTRL" - }] - } - }, - - "PORT1-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT1-EEPROM", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x47", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT1-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT1-CTRL", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x47", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT2": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT2", - "device_parent": "LC1-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "2" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT2-EEPROM" - }, { - "itf": "control", - "dev": "PORT2-CTRL" - }] - } - }, - - "PORT2-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT2-EEPROM", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x48", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT2-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT2-CTRL", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x48", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT3": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT3", - "device_parent": "LC1-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "3" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT3-EEPROM" - }, { - "itf": "control", - "dev": "PORT3-CTRL" - }] - } - }, - - "PORT3-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT3-EEPROM", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x49", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT3-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT3-CTRL", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x49", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT4": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT4", - "device_parent": "LC1-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "4" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT4-EEPROM" - }, { - "itf": "control", - "dev": "PORT4-CTRL" - }] - } - }, - - "PORT4-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT4-EEPROM", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4a", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT4-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT4-CTRL", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT5": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT5", - "device_parent": "LC1-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "5" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT5-EEPROM" - }, { - "itf": "control", - "dev": "PORT5-CTRL" - }] - } - }, - - "PORT5-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT5-EEPROM", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT5" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4b", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT5-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT5-CTRL", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT5" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - - "PORT6": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT6", - "device_parent": "LC1-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "6" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT6-EEPROM" - }, { - "itf": "control", - "dev": "PORT6-CTRL" - }] - } - }, - - "PORT6-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT6-EEPROM", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4c", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT6-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT6-CTRL", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT6" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT7": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT7", - "device_parent": "LC1-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "7" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT7-EEPROM" - }, { - "itf": "control", - "dev": "PORT7-CTRL" - }] - } - }, - - "PORT7-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT7-EEPROM", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4d", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT7-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT7-CTRL", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT7" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT8": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT8", - "device_parent": "LC1-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "8" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT8-EEPROM" - }, { - "itf": "control", - "dev": "PORT8-CTRL" - }] - } - }, - - "PORT8-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT8-EEPROM", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT8" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4e", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT8-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT8-CTRL", - "device_parent": "LC1-PORT-MUX0", - "virt_parent": "PORT8" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC1-PORT-MUX1": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC1-PORT-MUX1", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x71", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x4f" - }, - "channel": [{ - "chn": "0", - "dev": "PORT9" - }, - { - "chn": "1", - "dev": "PORT10" - }, - { - "chn": "2", - "dev": "PORT11" - }, - { - "chn": "3", - "dev": "PORT12" - }, - { - "chn": "4", - "dev": "PORT13" - }, - { - "chn": "5", - "dev": "PORT14" - }, - { - "chn": "6", - "dev": "PORT15" - }, - { - "chn": "7", - "dev": "PORT16" - } - ] - } - }, - - "PORT9": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT9", - "device_parent": "LC1-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "9" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT9-EEPROM" - }, { - "itf": "control", - "dev": "PORT9-CTRL" - }] - } - }, - - "PORT9-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT9-EEPROM", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT9" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4f", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT9-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT9-CTRL", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT9" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT10": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT10", - "device_parent": "LC1-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "10" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT10-EEPROM" - }, { - "itf": "control", - "dev": "PORT10-CTRL" - }] - } - }, - - "PORT10-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT10-EEPROM", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x50", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT10-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT10-CTRL", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT10" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x50", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT11": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT11", - "device_parent": "LC1-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "11" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT11-EEPROM" - }, { - "itf": "control", - "dev": "PORT11-CTRL" - }] - } - }, - - "PORT11-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT11-EEPROM", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT11" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x51", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT11-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT11-CTRL", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT11" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x51", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT12": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT12", - "device_parent": "LC1-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "12" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT12-EEPROM" - }, { - "itf": "control", - "dev": "PORT12-CTRL" - }] - } - }, - - "PORT12-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT12-EEPROM", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT12" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x52", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT12-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT12-CTRL", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT12" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x52", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT13": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT13", - "device_parent": "LC1-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "13" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT13-EEPROM" - }, { - "itf": "control", - "dev": "PORT13-CTRL" - }] - } - }, - - "PORT13-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT13-EEPROM", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT13" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x53", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT13-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT13-CTRL", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT13" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x53", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT14": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT14", - "device_parent": "LC1-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "14" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT14-EEPROM" - }, { - "itf": "control", - "dev": "PORT14-CTRL" - }] - } - }, - - "PORT14-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT14-EEPROM", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT14" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x54", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT14-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT14-CTRL", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT14" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x54", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT15": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT15", - "device_parent": "LC1-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "15" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT15-EEPROM" - }, { - "itf": "control", - "dev": "PORT15-CTRL" - }] - } - }, - - "PORT15-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT15-EEPROM", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT15" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x55", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT15-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT15-CTRL", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT15" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x55", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT16": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT16", - "device_parent": "LC1-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "16" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT16-EEPROM" - }, { - "itf": "control", - "dev": "PORT16-CTRL" - }] - } - }, - - "PORT16-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT16-EEPROM", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT16" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x56", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT16-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT16-CTRL", - "device_parent": "LC1-PORT-MUX1", - "virt_parent": "PORT16" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x56", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC1-PORT-MUX2": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC1-PORT-MUX2", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x72", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x57" - }, - "channel": [{ - "chn": "0", - "dev": "PORT17" - }, - { - "chn": "1", - "dev": "PORT18" - }, - { - "chn": "2", - "dev": "PORT19" - }, - { - "chn": "3", - "dev": "PORT20" - }, - { - "chn": "4", - "dev": "PORT21" - }, - { - "chn": "5", - "dev": "PORT22" - }, - { - "chn": "6", - "dev": "PORT23" - }, - { - "chn": "7", - "dev": "PORT24" - } - ] - } - }, - - "PORT17": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT17", - "device_parent": "LC1-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "17" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT17-EEPROM" - }, { - "itf": "control", - "dev": "PORT17-CTRL" - }] - } - }, - - "PORT17-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT17-EEPROM", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT17" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x57", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT17-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT17-CTRL", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT17" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x57", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT18": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT18", - "device_parent": "LC1-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "18" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT18-EEPROM" - }, { - "itf": "control", - "dev": "PORT18-CTRL" - }] - } - }, - - "PORT18-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT18-EEPROM", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT18" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x58", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT18-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT18-CTRL", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT18" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x58", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT19": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT19", - "device_parent": "LC1-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "19" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT19-EEPROM" - }, { - "itf": "control", - "dev": "PORT19-CTRL" - }] - } - }, - - "PORT19-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT19-EEPROM", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT19" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x59", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT19-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT19-CTRL", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT19" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x59", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT20": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT20", - "device_parent": "LC1-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "20" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT20-EEPROM" - }, { - "itf": "control", - "dev": "PORT20-CTRL" - }] - } - }, - - "PORT20-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT20-EEPROM", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT20" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5a", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT20-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT20-CTRL", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT20" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT21": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT21", - "device_parent": "LC1-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "21" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT21-EEPROM" - }, { - "itf": "control", - "dev": "PORT21-CTRL" - }] - } - }, - - "PORT21-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT21-EEPROM", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT21" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5b", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT21-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT21-CTRL", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT21" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT22": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT22", - "device_parent": "LC1-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "22" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT22-EEPROM" - }, { - "itf": "control", - "dev": "PORT22-CTRL" - }] - } - }, - - "PORT22-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT22-EEPROM", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT22" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5c", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT22-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT22-CTRL", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT22" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT23": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT23", - "device_parent": "LC1-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "23" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT23-EEPROM" - }, { - "itf": "control", - "dev": "PORT23-CTRL" - }] - } - }, - - "PORT23-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT23-EEPROM", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT23" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5d", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT23-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT23-CTRL", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT23" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT24": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT24", - "device_parent": "LC1-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "24" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT24-EEPROM" - }, { - "itf": "control", - "dev": "PORT24-CTRL" - }] - } - }, - - "PORT24-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT24-EEPROM", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT24" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5e", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT24-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT24-CTRL", - "device_parent": "LC1-PORT-MUX2", - "virt_parent": "PORT24" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC1-PORT-MUX3": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC1-PORT-MUX3", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x3", - "dev_addr": "0x73", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x5f" - }, - "channel": [{ - "chn": "0", - "dev": "PORT25" - }, - { - "chn": "1", - "dev": "PORT26" - }, - { - "chn": "2", - "dev": "PORT27" - }, - { - "chn": "3", - "dev": "PORT28" - }, - { - "chn": "4", - "dev": "PORT29" - }, - { - "chn": "5", - "dev": "PORT30" - }, - { - "chn": "6", - "dev": "PORT31" - }, - { - "chn": "7", - "dev": "PORT32" - } - ] - } - }, - - "PORT25": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT25", - "device_parent": "LC1-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "25" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT25-EEPROM" - }, { - "itf": "control", - "dev": "PORT25-CTRL" - }] - } - }, - - "PORT25-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT25-EEPROM", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT25" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5f", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT25-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT25-CTRL", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT25" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT26": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT26", - "device_parent": "LC1-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "26" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT26-EEPROM" - }, { - "itf": "control", - "dev": "PORT26-CTRL" - }] - } - }, - - "PORT26-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT26-EEPROM", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT26" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x60", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT26-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT26-CTRL", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT26" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x60", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT27": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT27", - "device_parent": "LC1-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "27" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT27-EEPROM" - }, { - "itf": "control", - "dev": "PORT27-CTRL" - }] - } - }, - - "PORT27-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT27-EEPROM", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT27" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x61", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT27-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT27-CTRL", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT27" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x61", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT28": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT28", - "device_parent": "LC1-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "28" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT28-EEPROM" - }, { - "itf": "control", - "dev": "PORT28-CTRL" - }] - } - }, - - "PORT28-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT28-EEPROM", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT28" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x62", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT28-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT28-CTRL", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT28" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x62", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT29": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT29", - "device_parent": "LC1-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "29" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT29-EEPROM" - }, { - "itf": "control", - "dev": "PORT29-CTRL" - }] - } - }, - - "PORT29-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT29-EEPROM", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT29" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x63", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT29-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT29-CTRL", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT29" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x63", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT30": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT30", - "device_parent": "LC1-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "30" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT30-EEPROM" - }, { - "itf": "control", - "dev": "PORT30-CTRL" - }] - } - }, - - "PORT30-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT30-EEPROM", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT30" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x64", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT30-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT30-CTRL", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT30" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x64", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT31": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT31", - "device_parent": "LC1-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "31" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT31-EEPROM" - }, { - "itf": "control", - "dev": "PORT31-CTRL" - }] - } - }, - - "PORT31-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT31-EEPROM", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT31" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x65", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT31-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT31-CTRL", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT31" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x65", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT32": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT32", - "device_parent": "LC1-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "32" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT32-EEPROM" - }, { - "itf": "control", - "dev": "PORT32-CTRL" - }] - } - }, - - "PORT32-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT32-EEPROM", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT32" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x66", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT32-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT32-CTRL", - "device_parent": "LC1-PORT-MUX3", - "virt_parent": "PORT32" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x66", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC1-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "CPLD-OCORE2": { - "dev_info": { - "device_type": "CPLD-OCORE", - "device_name": "CPLD-OCORE2", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x4" - }, - "DEVICES": [ - { - "dev": "LC2-CPLD-A" - }, - { - "dev": "LC2-CPLD-B" - }, - { - "dev": "LC2-EEPROM" - }, - { - "dev": "LC2-TLV-EEPROM" - }, - { - "dev": "LC2-PORT-MUX0" - }, - { - "dev": "LC2-PORT-MUX1" - }, - { - "dev": "LC2-PORT-MUX2" - }, - { - "dev": "LC2-PORT-MUX3" - } - ] - } - }, - - "LC2-CPLD-A": { - "dev_info": { - "device_type": "CPLD", - "device_name": "LC2-CPLD-A", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x30", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "LC2-CPLD-B": { - "dev_info": { - "device_type": "CPLD", - "device_name": "LC2-CPLD-B", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x31", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "LC2-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "LC2-EEPROM", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x56", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "LC2-TLV-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "LC2-TLV-EEPROM", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x57", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "LC2-PORT-MUX0": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC2-PORT-MUX0", - "device_parent": "CPLD-OCORE2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x70", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x67" - }, - "channel": [{ - "chn": "0", - "dev": "PORT33" - }, - { - "chn": "1", - "dev": "PORT34" - }, - { - "chn": "2", - "dev": "PORT35" - }, - { - "chn": "3", - "dev": "PORT36" - }, - { - "chn": "4", - "dev": "PORT37" - }, - { - "chn": "5", - "dev": "PORT38" - }, - { - "chn": "6", - "dev": "PORT39" - }, - { - "chn": "7", - "dev": "PORT40" - } - ] - } - }, - - "PORT33": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT33", - "device_parent": "LC2-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "33" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT33-EEPROM" - }, { - "itf": "control", - "dev": "PORT33-CTRL" - }] - } - }, - - "PORT33-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT33-EEPROM", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT33" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x67", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT33-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT33-CTRL", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT33" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x67", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT34": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT34", - "device_parent": "LC2-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "34" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT34-EEPROM" - }, { - "itf": "control", - "dev": "PORT34-CTRL" - }] - } - }, - - "PORT34-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT34-EEPROM", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT34" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x68", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT34-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT34-CTRL", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT34" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x68", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT35": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT35", - "device_parent": "LC2-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "35" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT35-EEPROM" - }, { - "itf": "control", - "dev": "PORT35-CTRL" - }] - } - }, - - "PORT35-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT35-EEPROM", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT35" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x69", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT35-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT35-CTRL", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT35" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x69", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT36": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT36", - "device_parent": "LC2-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "36" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT36-EEPROM" - }, { - "itf": "control", - "dev": "PORT36-CTRL" - }] - } - }, - - "PORT36-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT36-EEPROM", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT36" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6a", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT36-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT36-CTRL", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT36" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT37": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT37", - "device_parent": "LC2-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "37" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT37-EEPROM" - }, { - "itf": "control", - "dev": "PORT37-CTRL" - }] - } - }, - - "PORT37-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT37-EEPROM", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT37" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6b", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT37-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT37-CTRL", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT37" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT38": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT38", - "device_parent": "LC2-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "38" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT38-EEPROM" - }, { - "itf": "control", - "dev": "PORT38-CTRL" - }] - } - }, - - "PORT38-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT38-EEPROM", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT38" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6c", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT38-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT38-CTRL", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT38" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT39": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT39", - "device_parent": "LC2-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "39" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT39-EEPROM" - }, { - "itf": "control", - "dev": "PORT39-CTRL" - }] - } - }, - - "PORT39-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT39-EEPROM", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT39" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6d", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT39-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT39-CTRL", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT39" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT40": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT40", - "device_parent": "LC2-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "40" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT40-EEPROM" - }, { - "itf": "control", - "dev": "PORT40-CTRL" - }] - } - }, - - "PORT40-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT40-EEPROM", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT40" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6e", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT40-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT40-CTRL", - "device_parent": "LC2-PORT-MUX0", - "virt_parent": "PORT40" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC2-PORT-MUX1": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC2-PORT-MUX1", - "device_parent": "CPLD-OCORE2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x71", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x6f" - }, - "channel": [{ - "chn": "0", - "dev": "PORT41" - }, - { - "chn": "1", - "dev": "PORT42" - }, - { - "chn": "2", - "dev": "PORT43" - }, - { - "chn": "3", - "dev": "PORT44" - }, - { - "chn": "4", - "dev": "PORT45" - }, - { - "chn": "5", - "dev": "PORT46" - }, - { - "chn": "6", - "dev": "PORT47" - }, - { - "chn": "7", - "dev": "PORT48" - } - ] - } - }, - - "PORT41": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT41", - "device_parent": "LC2-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "41" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT41-EEPROM" - }, { - "itf": "control", - "dev": "PORT41-CTRL" - }] - } - }, - - "PORT41-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT41-EEPROM", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT41" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6f", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT41-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT41-CTRL", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT41" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT42": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT42", - "device_parent": "LC2-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "42" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT42-EEPROM" - }, { - "itf": "control", - "dev": "PORT42-CTRL" - }] - } - }, - - "PORT42-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT42-EEPROM", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT42" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x70", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT42-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT42-CTRL", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT42" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x70", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT43": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT43", - "device_parent": "LC2-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "43" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT43-EEPROM" - }, { - "itf": "control", - "dev": "PORT43-CTRL" - }] - } - }, - - "PORT43-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT43-EEPROM", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT43" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x71", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT43-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT43-CTRL", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT43" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x71", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT44": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT44", - "device_parent": "LC2-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "44" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT44-EEPROM" - }, { - "itf": "control", - "dev": "PORT44-CTRL" - }] - } - }, - - "PORT44-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT44-EEPROM", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT44" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x72", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT44-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT44-CTRL", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT44" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x72", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT45": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT45", - "device_parent": "LC2-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "45" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT45-EEPROM" - }, { - "itf": "control", - "dev": "PORT45-CTRL" - }] - } - }, - - "PORT45-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT45-EEPROM", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT45" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x73", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT45-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT45-CTRL", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT45" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x73", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT46": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT46", - "device_parent": "LC2-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "46" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT46-EEPROM" - }, { - "itf": "control", - "dev": "PORT46-CTRL" - }] - } - }, - - "PORT46-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT46-EEPROM", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT46" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x74", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT46-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT46-CTRL", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT46" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x74", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT47": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT47", - "device_parent": "LC2-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "47" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT47-EEPROM" - }, { - "itf": "control", - "dev": "PORT47-CTRL" - }] - } - }, - - "PORT47-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT47-EEPROM", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT47" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x75", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT47-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT47-CTRL", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT47" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x75", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT48": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT48", - "device_parent": "LC2-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "48" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT48-EEPROM" - }, { - "itf": "control", - "dev": "PORT48-CTRL" - }] - } - }, - - "PORT48-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT48-EEPROM", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT48" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x76", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT48-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT48-CTRL", - "device_parent": "LC2-PORT-MUX1", - "virt_parent": "PORT48" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x76", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC2-PORT-MUX2": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC2-PORT-MUX2", - "device_parent": "CPLD-OCORE2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x72", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x77" - }, - "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" - } - ] - } - }, - - "PORT49": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT49", - "device_parent": "LC2-PORT-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": "LC2-PORT-MUX2", - "virt_parent": "PORT49" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x77", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT49-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT49-CTRL", - "device_parent": "LC2-PORT-MUX2", - "virt_parent": "PORT49" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x77", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT50": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT50", - "device_parent": "LC2-PORT-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": "LC2-PORT-MUX2", - "virt_parent": "PORT50" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x78", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT50-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT50-CTRL", - "device_parent": "LC2-PORT-MUX2", - "virt_parent": "PORT50" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x78", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT51": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT51", - "device_parent": "LC2-PORT-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": "LC2-PORT-MUX2", - "virt_parent": "PORT51" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x79", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT51-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT51-CTRL", - "device_parent": "LC2-PORT-MUX2", - "virt_parent": "PORT51" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x79", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT52": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT52", - "device_parent": "LC2-PORT-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": "LC2-PORT-MUX2", - "virt_parent": "PORT52" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7a", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT52-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT52-CTRL", - "device_parent": "LC2-PORT-MUX2", - "virt_parent": "PORT52" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT53": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT53", - "device_parent": "LC2-PORT-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": "LC2-PORT-MUX2", - "virt_parent": "PORT53" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7b", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT53-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT53-CTRL", - "device_parent": "LC2-PORT-MUX2", - "virt_parent": "PORT53" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT54": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT54", - "device_parent": "LC2-PORT-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": "LC2-PORT-MUX2", - "virt_parent": "PORT54" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7c", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT54-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT54-CTRL", - "device_parent": "LC2-PORT-MUX2", - "virt_parent": "PORT54" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT55": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT55", - "device_parent": "LC2-PORT-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": "LC2-PORT-MUX2", - "virt_parent": "PORT55" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7d", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT55-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT55-CTRL", - "device_parent": "LC2-PORT-MUX2", - "virt_parent": "PORT55" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT56": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT56", - "device_parent": "LC2-PORT-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": "LC2-PORT-MUX2", - "virt_parent": "PORT56" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7e", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT56-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT56-CTRL", - "device_parent": "LC2-PORT-MUX2", - "virt_parent": "PORT56" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC2-PORT-MUX3": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC2-PORT-MUX3", - "device_parent": "CPLD-OCORE2" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x4", - "dev_addr": "0x73", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x7f" - }, - "channel": [{ - "chn": "0", - "dev": "PORT57" - }, - { - "chn": "1", - "dev": "PORT58" - }, - { - "chn": "2", - "dev": "PORT59" - }, - { - "chn": "3", - "dev": "PORT60" - }, - { - "chn": "4", - "dev": "PORT61" - }, - { - "chn": "5", - "dev": "PORT62" - }, - { - "chn": "6", - "dev": "PORT63" - }, - { - "chn": "7", - "dev": "PORT64" - } - ] - } - }, - - "PORT57": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT57", - "device_parent": "LC2-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "57" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT57-EEPROM" - }, { - "itf": "control", - "dev": "PORT57-CTRL" - }] - } - }, - - "PORT57-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT57-EEPROM", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT57" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7f", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT57-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT57-CTRL", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT57" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x7f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT58": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT58", - "device_parent": "LC2-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "58" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT58-EEPROM" - }, { - "itf": "control", - "dev": "PORT58-CTRL" - }] - } - }, - - "PORT58-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT58-EEPROM", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT58" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x80", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT58-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT58-CTRL", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT58" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x80", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT59": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT59", - "device_parent": "LC2-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "59" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT59-EEPROM" - }, { - "itf": "control", - "dev": "PORT59-CTRL" - }] - } - }, - - "PORT59-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT59-EEPROM", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT59" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x81", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT59-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT59-CTRL", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT59" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x81", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT60": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT60", - "device_parent": "LC2-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "60" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT60-EEPROM" - }, { - "itf": "control", - "dev": "PORT60-CTRL" - }] - } - }, - - "PORT60-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT60-EEPROM", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT60" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x82", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT60-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT60-CTRL", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT60" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x82", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT61": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT61", - "device_parent": "LC2-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "61" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT61-EEPROM" - }, { - "itf": "control", - "dev": "PORT61-CTRL" - }] - } - }, - - "PORT61-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT61-EEPROM", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT61" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x83", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT61-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT61-CTRL", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT61" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x83", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT62": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT62", - "device_parent": "LC2-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "62" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT62-EEPROM" - }, { - "itf": "control", - "dev": "PORT62-CTRL" - }] - } - }, - - "PORT62-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT62-EEPROM", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT62" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x84", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT62-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT62-CTRL", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT62" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x84", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT63": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT63", - "device_parent": "LC2-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "63" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT63-EEPROM" - }, { - "itf": "control", - "dev": "PORT63-CTRL" - }] - } - }, - - "PORT63-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT63-EEPROM", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT63" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x85", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT63-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT63-CTRL", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT63" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x85", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT64": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT64", - "device_parent": "LC2-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "64" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT64-EEPROM" - }, { - "itf": "control", - "dev": "PORT64-CTRL" - }] - } - }, - - "PORT64-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT64-EEPROM", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT64" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x86", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT64-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT64-CTRL", - "device_parent": "LC2-PORT-MUX3", - "virt_parent": "PORT64" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x86", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC2-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "CPLD-OCORE3": { - "dev_info": { - "device_type": "CPLD-OCORE", - "device_name": "CPLD-OCORE3", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x5" - }, - "DEVICES": [ - { - "dev": "LC3-CPLD-A" - }, - { - "dev": "LC3-CPLD-B" - }, - { - "dev": "LC3-EEPROM" - }, - { - "dev": "LC3-TLV-EEPROM" - }, - { - "dev": "LC3-PORT-MUX0" - }, - { - "dev": "LC3-PORT-MUX1" - }, - { - "dev": "LC3-PORT-MUX2" - }, - { - "dev": "LC3-PORT-MUX3" - } - ] - } - }, - - "LC3-CPLD-A": { - "dev_info": { - "device_type": "CPLD", - "device_name": "LC3-CPLD-A", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x30", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "LC3-CPLD-B": { - "dev_info": { - "device_type": "CPLD", - "device_name": "LC3-CPLD-B", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x31", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "LC3-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "LC3-EEPROM", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x56", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "LC3-TLV-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "LC3-TLV-EEPROM", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x57", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "LC3-PORT-MUX0": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC3-PORT-MUX0", - "device_parent": "CPLD-OCORE3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x70", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x87" - }, - "channel": [{ - "chn": "0", - "dev": "PORT65" - }, - { - "chn": "1", - "dev": "PORT66" - }, - { - "chn": "2", - "dev": "PORT67" - }, - { - "chn": "3", - "dev": "PORT68" - }, - { - "chn": "4", - "dev": "PORT69" - }, - { - "chn": "5", - "dev": "PORT70" - }, - { - "chn": "6", - "dev": "PORT71" - }, - { - "chn": "7", - "dev": "PORT72" - } - ] - } - }, - - "PORT65": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT65", - "device_parent": "LC3-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "65" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT65-EEPROM" - }, { - "itf": "control", - "dev": "PORT65-CTRL" - }] - } - }, - - "PORT65-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT65-EEPROM", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT65" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x87", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT65-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT65-CTRL", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT65" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x87", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT66": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT66", - "device_parent": "LC3-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "66" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT66-EEPROM" - }, { - "itf": "control", - "dev": "PORT66-CTRL" - }] - } - }, - - "PORT66-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT66-EEPROM", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT66" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x88", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT66-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT66-CTRL", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT66" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x88", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT67": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT67", - "device_parent": "LC3-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "67" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT67-EEPROM" - }, { - "itf": "control", - "dev": "PORT67-CTRL" - }] - } - }, - - "PORT67-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT67-EEPROM", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT67" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x89", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT67-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT67-CTRL", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT67" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x89", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT68": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT68", - "device_parent": "LC3-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "68" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT68-EEPROM" - }, { - "itf": "control", - "dev": "PORT68-CTRL" - }] - } - }, - - "PORT68-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT68-EEPROM", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT68" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8a", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT68-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT68-CTRL", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT68" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT69": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT69", - "device_parent": "LC3-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "69" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT69-EEPROM" - }, { - "itf": "control", - "dev": "PORT69-CTRL" - }] - } - }, - - "PORT69-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT69-EEPROM", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT69" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8b", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT69-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT69-CTRL", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT69" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT70": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT70", - "device_parent": "LC3-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "70" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT70-EEPROM" - }, { - "itf": "control", - "dev": "PORT70-CTRL" - }] - } - }, - - "PORT70-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT70-EEPROM", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT70" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8c", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT70-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT70-CTRL", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT70" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT71": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT71", - "device_parent": "LC3-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "71" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT71-EEPROM" - }, { - "itf": "control", - "dev": "PORT71-CTRL" - }] - } - }, - - "PORT71-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT71-EEPROM", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT71" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8d", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT71-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT71-CTRL", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT71" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT72": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT72", - "device_parent": "LC3-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "72" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT72-EEPROM" - }, { - "itf": "control", - "dev": "PORT72-CTRL" - }] - } - }, - - "PORT72-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT72-EEPROM", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT72" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8e", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT72-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT72-CTRL", - "device_parent": "LC3-PORT-MUX0", - "virt_parent": "PORT72" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC3-PORT-MUX1": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC3-PORT-MUX1", - "device_parent": "CPLD-OCORE3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x71", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x8f" - }, - "channel": [{ - "chn": "0", - "dev": "PORT73" - }, - { - "chn": "1", - "dev": "PORT74" - }, - { - "chn": "2", - "dev": "PORT75" - }, - { - "chn": "3", - "dev": "PORT76" - }, - { - "chn": "4", - "dev": "PORT77" - }, - { - "chn": "5", - "dev": "PORT78" - }, - { - "chn": "6", - "dev": "PORT79" - }, - { - "chn": "7", - "dev": "PORT80" - } - ] - } - }, - - "PORT73": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT73", - "device_parent": "LC3-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "73" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT73-EEPROM" - }, { - "itf": "control", - "dev": "PORT73-CTRL" - }] - } - }, - - "PORT73-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT73-EEPROM", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT73" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8f", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT73-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT73-CTRL", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT73" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x8f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT74": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT74", - "device_parent": "LC3-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "74" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT74-EEPROM" - }, { - "itf": "control", - "dev": "PORT74-CTRL" - }] - } - }, - - "PORT74-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT74-EEPROM", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT74" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x90", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT74-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT74-CTRL", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT74" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x90", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT75": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT75", - "device_parent": "LC3-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "75" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT75-EEPROM" - }, { - "itf": "control", - "dev": "PORT75-CTRL" - }] - } - }, - - "PORT75-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT75-EEPROM", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT75" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x91", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT75-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT75-CTRL", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT75" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x91", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT76": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT76", - "device_parent": "LC3-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "76" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT76-EEPROM" - }, { - "itf": "control", - "dev": "PORT76-CTRL" - }] - } - }, - - "PORT76-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT76-EEPROM", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT76" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x92", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT76-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT76-CTRL", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT76" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x92", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT77": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT77", - "device_parent": "LC3-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "77" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT77-EEPROM" - }, { - "itf": "control", - "dev": "PORT77-CTRL" - }] - } - }, - - "PORT77-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT77-EEPROM", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT77" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x93", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT77-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT77-CTRL", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT77" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x93", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT78": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT78", - "device_parent": "LC3-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "78" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT78-EEPROM" - }, { - "itf": "control", - "dev": "PORT78-CTRL" - }] - } - }, - - "PORT78-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT78-EEPROM", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT78" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x94", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT78-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT78-CTRL", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT78" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x94", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT79": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT79", - "device_parent": "LC3-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "79" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT79-EEPROM" - }, { - "itf": "control", - "dev": "PORT79-CTRL" - }] - } - }, - - "PORT79-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT79-EEPROM", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT79" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x95", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT79-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT79-CTRL", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT79" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x95", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT80": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT80", - "device_parent": "LC3-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "80" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT80-EEPROM" - }, { - "itf": "control", - "dev": "PORT80-CTRL" - }] - } - }, - - "PORT80-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT80-EEPROM", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT80" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x96", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT80-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT80-CTRL", - "device_parent": "LC3-PORT-MUX1", - "virt_parent": "PORT80" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x96", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC3-PORT-MUX2": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC3-PORT-MUX2", - "device_parent": "CPLD-OCORE3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x72", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x97" - }, - "channel": [{ - "chn": "0", - "dev": "PORT81" - }, - { - "chn": "1", - "dev": "PORT82" - }, - { - "chn": "2", - "dev": "PORT83" - }, - { - "chn": "3", - "dev": "PORT84" - }, - { - "chn": "4", - "dev": "PORT85" - }, - { - "chn": "5", - "dev": "PORT86" - }, - { - "chn": "6", - "dev": "PORT87" - }, - { - "chn": "7", - "dev": "PORT88" - } - ] - } - }, - - "PORT81": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT81", - "device_parent": "LC3-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "81" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT81-EEPROM" - }, { - "itf": "control", - "dev": "PORT81-CTRL" - }] - } - }, - - "PORT81-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT81-EEPROM", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT81" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x97", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT81-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT81-CTRL", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT81" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x97", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT82": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT82", - "device_parent": "LC3-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "82" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT82-EEPROM" - }, { - "itf": "control", - "dev": "PORT82-CTRL" - }] - } - }, - - "PORT82-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT82-EEPROM", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT82" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x98", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT82-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT82-CTRL", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT82" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x98", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT83": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT83", - "device_parent": "LC3-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "83" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT83-EEPROM" - }, { - "itf": "control", - "dev": "PORT83-CTRL" - }] - } - }, - - "PORT83-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT83-EEPROM", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT83" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x99", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT83-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT83-CTRL", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT83" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x99", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT84": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT84", - "device_parent": "LC3-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "84" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT84-EEPROM" - }, { - "itf": "control", - "dev": "PORT84-CTRL" - }] - } - }, - - "PORT84-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT84-EEPROM", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT84" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9a", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT84-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT84-CTRL", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT84" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9a", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT85": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT85", - "device_parent": "LC3-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "85" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT85-EEPROM" - }, { - "itf": "control", - "dev": "PORT85-CTRL" - }] - } - }, - - "PORT85-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT85-EEPROM", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT85" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9b", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT85-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT85-CTRL", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT85" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9b", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT86": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT86", - "device_parent": "LC3-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "86" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT86-EEPROM" - }, { - "itf": "control", - "dev": "PORT86-CTRL" - }] - } - }, - - "PORT86-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT86-EEPROM", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT86" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9c", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT86-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT86-CTRL", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT86" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9c", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT87": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT87", - "device_parent": "LC3-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "87" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT87-EEPROM" - }, { - "itf": "control", - "dev": "PORT87-CTRL" - }] - } - }, - - "PORT87-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT87-EEPROM", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT87" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9d", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT87-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT87-CTRL", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT87" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9d", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT88": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT88", - "device_parent": "LC3-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "88" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT88-EEPROM" - }, { - "itf": "control", - "dev": "PORT88-CTRL" - }] - } - }, - - "PORT88-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT88-EEPROM", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT88" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9e", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT88-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT88-CTRL", - "device_parent": "LC3-PORT-MUX2", - "virt_parent": "PORT88" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9e", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC3-PORT-MUX3": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC3-PORT-MUX3", - "device_parent": "CPLD-OCORE3" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x5", - "dev_addr": "0x73", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0x9f" - }, - "channel": [{ - "chn": "0", - "dev": "PORT89" - }, - { - "chn": "1", - "dev": "PORT90" - }, - { - "chn": "2", - "dev": "PORT91" - }, - { - "chn": "3", - "dev": "PORT92" - }, - { - "chn": "4", - "dev": "PORT93" - }, - { - "chn": "5", - "dev": "PORT94" - }, - { - "chn": "6", - "dev": "PORT95" - }, - { - "chn": "7", - "dev": "PORT96" - } - ] - } - }, - - "PORT89": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT89", - "device_parent": "LC3-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "89" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT89-EEPROM" - }, { - "itf": "control", - "dev": "PORT89-CTRL" - }] - } - }, - - "PORT89-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT89-EEPROM", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT89" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9f", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT89-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT89-CTRL", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT89" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x9f", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT90": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT90", - "device_parent": "LC3-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "90" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT90-EEPROM" - }, { - "itf": "control", - "dev": "PORT90-CTRL" - }] - } - }, - - "PORT90-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT90-EEPROM", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT90" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa0", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT90-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT90-CTRL", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT90" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa0", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT91": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT91", - "device_parent": "LC3-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "91" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT91-EEPROM" - }, { - "itf": "control", - "dev": "PORT91-CTRL" - }] - } - }, - - "PORT91-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT91-EEPROM", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT91" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa1", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT91-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT91-CTRL", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT91" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa1", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT92": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT92", - "device_parent": "LC3-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "92" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT92-EEPROM" - }, { - "itf": "control", - "dev": "PORT92-CTRL" - }] - } - }, - - "PORT92-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT92-EEPROM", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT92" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa2", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT92-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT92-CTRL", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT92" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa2", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT93": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT93", - "device_parent": "LC3-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "93" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT93-EEPROM" - }, { - "itf": "control", - "dev": "PORT93-CTRL" - }] - } - }, - - "PORT93-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT93-EEPROM", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT93" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa3", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT93-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT93-CTRL", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT93" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa3", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT94": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT94", - "device_parent": "LC3-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "94" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT94-EEPROM" - }, { - "itf": "control", - "dev": "PORT94-CTRL" - }] - } - }, - - "PORT94-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT94-EEPROM", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT94" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa4", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT94-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT94-CTRL", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT94" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa4", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT95": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT95", - "device_parent": "LC3-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "95" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT95-EEPROM" - }, { - "itf": "control", - "dev": "PORT95-CTRL" - }] - } - }, - - "PORT95-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT95-EEPROM", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT95" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa5", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT95-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT95-CTRL", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT95" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa5", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT96": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT96", - "device_parent": "LC3-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "96" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT96-EEPROM" - }, { - "itf": "control", - "dev": "PORT96-CTRL" - }] - } - }, - - "PORT96-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT96-EEPROM", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT96" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa6", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT96-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT96-CTRL", - "device_parent": "LC3-PORT-MUX3", - "virt_parent": "PORT96" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa6", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC3-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "CPLD-OCORE4": { - "dev_info": { - "device_type": "CPLD-OCORE", - "device_name": "CPLD-OCORE4", - "device_parent": "SYSTEM" - }, - "i2c": { - "topo_info": { - "dev_addr": "0x6" - }, - "DEVICES": [ - { - "dev": "LC4-CPLD-A" - }, - { - "dev": "LC4-CPLD-B" - }, - { - "dev": "LC4-EEPROM" - }, - { - "dev": "LC4-TLV-EEPROM" - }, - { - "dev": "LC4-PORT-MUX0" - }, - { - "dev": "LC4-PORT-MUX1" - }, - { - "dev": "LC4-PORT-MUX2" - }, - { - "dev": "LC4-PORT-MUX3" - } - ] - } - }, - - "LC4-CPLD-A": { - "dev_info": { - "device_type": "CPLD", - "device_name": "LC4-CPLD-A", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x30", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "LC4-CPLD-B": { - "dev_info": { - "device_type": "CPLD", - "device_name": "LC4-CPLD-B", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x31", - "dev_type": "i2c_cpld" - }, - "dev_attr": {} - } - }, - - "LC4-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "LC4-EEPROM", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x56", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "LC4-TLV-EEPROM": { - "dev_info": { - "device_type": "EEPROM", - "device_name": "LC4-TLV-EEPROM", - "device_parent": "CPLD-OCORE1" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x57", - "dev_type": "24c02" - }, - "dev_attr": { - "access_mode": "BLOCK" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "LC4-PORT-MUX0": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC4-PORT-MUX0", - "device_parent": "CPLD-OCORE4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x70", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0xa7" - }, - "channel": [{ - "chn": "0", - "dev": "PORT97" - }, - { - "chn": "1", - "dev": "PORT98" - }, - { - "chn": "2", - "dev": "PORT99" - }, - { - "chn": "3", - "dev": "PORT100" - }, - { - "chn": "4", - "dev": "PORT101" - }, - { - "chn": "5", - "dev": "PORT102" - }, - { - "chn": "6", - "dev": "PORT103" - }, - { - "chn": "7", - "dev": "PORT104" - } - ] - } - }, - - "PORT97": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT97", - "device_parent": "LC4-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "97" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT97-EEPROM" - }, { - "itf": "control", - "dev": "PORT97-CTRL" - }] - } - }, - - "PORT97-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT97-EEPROM", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT97" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa7", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT97-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT97-CTRL", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT97" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa7", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT98": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT98", - "device_parent": "LC4-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "98" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT98-EEPROM" - }, { - "itf": "control", - "dev": "PORT98-CTRL" - }] - } - }, - - "PORT98-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT98-EEPROM", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT98" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa8", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT98-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT98-CTRL", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT98" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa8", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT99": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT99", - "device_parent": "LC4-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "99" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT99-EEPROM" - }, { - "itf": "control", - "dev": "PORT99-CTRL" - }] - } - }, - - "PORT99-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT99-EEPROM", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT99" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa9", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT99-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT99-CTRL", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT99" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xa9", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT100": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT100", - "device_parent": "LC4-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "100" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT100-EEPROM" - }, { - "itf": "control", - "dev": "PORT100-CTRL" - }] - } - }, - - "PORT100-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT100-EEPROM", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT100" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xaa", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT100-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT100-CTRL", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT100" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xaa", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT101": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT101", - "device_parent": "LC4-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "101" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT101-EEPROM" - }, { - "itf": "control", - "dev": "PORT101-CTRL" - }] - } - }, - - "PORT101-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT101-EEPROM", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT101" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xab", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT101-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT101-CTRL", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT101" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xab", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT102": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT102", - "device_parent": "LC4-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "102" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT102-EEPROM" - }, { - "itf": "control", - "dev": "PORT102-CTRL" - }] - } - }, - - "PORT102-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT102-EEPROM", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT102" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xac", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT102-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT102-CTRL", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT102" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xac", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT103": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT103", - "device_parent": "LC4-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "103" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT103-EEPROM" - }, { - "itf": "control", - "dev": "PORT103-CTRL" - }] - } - }, - - "PORT103-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT103-EEPROM", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT103" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xad", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT103-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT103-CTRL", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT103" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xad", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT104": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT104", - "device_parent": "LC4-PORT-MUX0" - }, - "dev_attr": { - "dev_idx": "104" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT104-EEPROM" - }, { - "itf": "control", - "dev": "PORT104-CTRL" - }] - } - }, - - "PORT104-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT104-EEPROM", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT104" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xae", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT104-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT104-CTRL", - "device_parent": "LC4-PORT-MUX0", - "virt_parent": "PORT104" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xae", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC4-PORT-MUX1": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC4-PORT-MUX1", - "device_parent": "CPLD-OCORE4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x71", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0xaf" - }, - "channel": [{ - "chn": "0", - "dev": "PORT105" - }, - { - "chn": "1", - "dev": "PORT106" - }, - { - "chn": "2", - "dev": "PORT107" - }, - { - "chn": "3", - "dev": "PORT108" - }, - { - "chn": "4", - "dev": "PORT109" - }, - { - "chn": "5", - "dev": "PORT110" - }, - { - "chn": "6", - "dev": "PORT111" - }, - { - "chn": "7", - "dev": "PORT112" - } - ] - } - }, - - "PORT105": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT105", - "device_parent": "LC4-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "105" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT105-EEPROM" - }, { - "itf": "control", - "dev": "PORT105-CTRL" - }] - } - }, - - "PORT105-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT105-EEPROM", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT105" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xaf", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT105-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT105-CTRL", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT105" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xaf", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT106": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT106", - "device_parent": "LC4-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "106" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT106-EEPROM" - }, { - "itf": "control", - "dev": "PORT106-CTRL" - }] - } - }, - - "PORT106-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT106-EEPROM", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT106" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb0", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT106-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT106-CTRL", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT106" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb0", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT107": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT107", - "device_parent": "LC4-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "107" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT107-EEPROM" - }, { - "itf": "control", - "dev": "PORT107-CTRL" - }] - } - }, - - "PORT107-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT107-EEPROM", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT107" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb1", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT107-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT107-CTRL", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT107" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb1", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT108": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT108", - "device_parent": "LC4-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "108" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT108-EEPROM" - }, { - "itf": "control", - "dev": "PORT108-CTRL" - }] - } - }, - - "PORT108-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT108-EEPROM", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT108" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb2", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT108-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT108-CTRL", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT108" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb2", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT109": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT109", - "device_parent": "LC4-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "109" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT109-EEPROM" - }, { - "itf": "control", - "dev": "PORT109-CTRL" - }] - } - }, - - "PORT109-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT109-EEPROM", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT109" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb3", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT109-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT109-CTRL", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT109" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb3", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT110": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT110", - "device_parent": "LC4-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "110" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT110-EEPROM" - }, { - "itf": "control", - "dev": "PORT110-CTRL" - }] - } - }, - - "PORT110-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT110-EEPROM", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT110" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb4", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT110-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT110-CTRL", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT110" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb4", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT111": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT111", - "device_parent": "LC4-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "111" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT111-EEPROM" - }, { - "itf": "control", - "dev": "PORT111-CTRL" - }] - } - }, - - "PORT111-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT111-EEPROM", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT111" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb5", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT111-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT111-CTRL", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT111" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb5", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT112": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT112", - "device_parent": "LC4-PORT-MUX1" - }, - "dev_attr": { - "dev_idx": "112" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT112-EEPROM" - }, { - "itf": "control", - "dev": "PORT112-CTRL" - }] - } - }, - - "PORT112-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT112-EEPROM", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT112" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb6", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT112-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT112-CTRL", - "device_parent": "LC4-PORT-MUX1", - "virt_parent": "PORT112" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb6", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-A", - "attr_devaddr": "0x30", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC4-PORT-MUX2": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC4-PORT-MUX2", - "device_parent": "CPLD-OCORE4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x72", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0xb7" - }, - "channel": [{ - "chn": "0", - "dev": "PORT113" - }, - { - "chn": "1", - "dev": "PORT114" - }, - { - "chn": "2", - "dev": "PORT115" - }, - { - "chn": "3", - "dev": "PORT116" - }, - { - "chn": "4", - "dev": "PORT117" - }, - { - "chn": "5", - "dev": "PORT118" - }, - { - "chn": "6", - "dev": "PORT119" - }, - { - "chn": "7", - "dev": "PORT120" - } - ] - } - }, - - "PORT113": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT113", - "device_parent": "LC4-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "113" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT113-EEPROM" - }, { - "itf": "control", - "dev": "PORT113-CTRL" - }] - } - }, - - "PORT113-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT113-EEPROM", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT113" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb7", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT113-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT113-CTRL", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT113" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb7", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT114": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT114", - "device_parent": "LC4-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "114" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT114-EEPROM" - }, { - "itf": "control", - "dev": "PORT114-CTRL" - }] - } - }, - - "PORT114-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT114-EEPROM", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT114" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb8", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT114-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT114-CTRL", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT114" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb8", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT115": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT115", - "device_parent": "LC4-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "115" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT115-EEPROM" - }, { - "itf": "control", - "dev": "PORT115-CTRL" - }] - } - }, - - "PORT115-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT115-EEPROM", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT115" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb9", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT115-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT115-CTRL", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT115" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xb9", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT116": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT116", - "device_parent": "LC4-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "116" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT116-EEPROM" - }, { - "itf": "control", - "dev": "PORT116-CTRL" - }] - } - }, - - "PORT116-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT116-EEPROM", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT116" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xba", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT116-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT116-CTRL", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT116" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xba", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT117": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT117", - "device_parent": "LC4-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "117" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT117-EEPROM" - }, { - "itf": "control", - "dev": "PORT117-CTRL" - }] - } - }, - - "PORT117-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT117-EEPROM", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT117" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbb", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT117-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT117-CTRL", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT117" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbb", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT118": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT118", - "device_parent": "LC4-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "118" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT118-EEPROM" - }, { - "itf": "control", - "dev": "PORT118-CTRL" - }] - } - }, - - "PORT118-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT118-EEPROM", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT118" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbc", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT118-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT118-CTRL", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT118" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbc", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT119": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT119", - "device_parent": "LC4-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "119" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT119-EEPROM" - }, { - "itf": "control", - "dev": "PORT119-CTRL" - }] - } - }, - - "PORT119-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT119-EEPROM", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT119" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbd", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT119-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT119-CTRL", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT119" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbd", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT120": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT120", - "device_parent": "LC4-PORT-MUX2" - }, - "dev_attr": { - "dev_idx": "120" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT120-EEPROM" - }, { - "itf": "control", - "dev": "PORT120-CTRL" - }] - } - }, - - "PORT120-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT120-EEPROM", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT120" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbe", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT120-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT120-CTRL", - "device_parent": "LC4-PORT-MUX2", - "virt_parent": "PORT120" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbe", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x10", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "LC4-PORT-MUX3": { - "dev_info": { - "device_type": "MUX", - "device_name": "LC4-PORT-MUX3", - "device_parent": "CPLD-OCORE4" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x6", - "dev_addr": "0x73", - "dev_type": "pca9548" - }, - "dev_attr": { - "virt_bus": "0xbf" - }, - "channel": [{ - "chn": "0", - "dev": "PORT121" - }, - { - "chn": "1", - "dev": "PORT122" - }, - { - "chn": "2", - "dev": "PORT123" - }, - { - "chn": "3", - "dev": "PORT124" - }, - { - "chn": "4", - "dev": "PORT125" - }, - { - "chn": "5", - "dev": "PORT126" - }, - { - "chn": "6", - "dev": "PORT127" - }, - { - "chn": "7", - "dev": "PORT128" - } - ] - } - }, - - "PORT121": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT121", - "device_parent": "LC4-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "121" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT121-EEPROM" - }, { - "itf": "control", - "dev": "PORT121-CTRL" - }] - } - }, - - "PORT121-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT121-EEPROM", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT121" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbf", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT121-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT121-CTRL", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT121" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xbf", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x0", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT122": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT122", - "device_parent": "LC4-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "122" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT122-EEPROM" - }, { - "itf": "control", - "dev": "PORT122-CTRL" - }] - } - }, - - "PORT122-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT122-EEPROM", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT122" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc0", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT122-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT122-CTRL", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT122" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc0", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT123": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT123", - "device_parent": "LC4-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "123" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT123-EEPROM" - }, { - "itf": "control", - "dev": "PORT123-CTRL" - }] - } - }, - - "PORT123-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT123-EEPROM", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT123" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc1", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT123-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT123-CTRL", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT123" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc1", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT124": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT124", - "device_parent": "LC4-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "124" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT124-EEPROM" - }, { - "itf": "control", - "dev": "PORT124-CTRL" - }] - } - }, - - "PORT124-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT124-EEPROM", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT124" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc2", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT124-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT124-CTRL", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT124" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc2", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x3", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT125": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT125", - "device_parent": "LC4-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "125" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT125-EEPROM" - }, { - "itf": "control", - "dev": "PORT125-CTRL" - }] - } - }, - - "PORT125-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT125-EEPROM", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT125" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc3", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT125-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT125-CTRL", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT125" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc3", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x4", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT126": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT126", - "device_parent": "LC4-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "126" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT126-EEPROM" - }, { - "itf": "control", - "dev": "PORT126-CTRL" - }] - } - }, - - "PORT126-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT126-EEPROM", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT126" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc4", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT126-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT126-CTRL", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT126" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc4", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x5", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT127": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT127", - "device_parent": "LC4-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "127" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT127-EEPROM" - }, { - "itf": "control", - "dev": "PORT127-CTRL" - }] - } - }, - - "PORT127-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT127-EEPROM", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT127" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc5", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT127-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT127-CTRL", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT127" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc5", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x6", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "PORT128": { - "dev_info": { - "device_type": "QSFP", - "device_name": "PORT128", - "device_parent": "LC4-PORT-MUX3" - }, - "dev_attr": { - "dev_idx": "128" - }, - "i2c": { - "interface": [{ - "itf": "eeprom", - "dev": "PORT128-EEPROM" - }, { - "itf": "control", - "dev": "PORT128-CTRL" - }] - } - }, - - "PORT128-EEPROM": { - "dev_info": { - "device_type": "", - "device_name": "PORT128-EEPROM", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT128" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc6", - "dev_addr": "0x50", - "dev_type": "optoe1" - }, - "attr_list": [{ - "attr_name": "eeprom" - }] - } - }, - - "PORT128-CTRL": { - "dev_info": { - "device_type": "", - "device_name": "PORT128-CTRL", - "device_parent": "LC4-PORT-MUX3", - "virt_parent": "PORT128" - }, - "i2c": { - "topo_info": { - "parent_bus": "0xc6", - "dev_addr": "0x53", - "dev_type": "pddf_xcvr" - }, - "attr_list": [{ - "attr_name": "xcvr_present", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x11", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }, { - "attr_name": "xcvr_reset", - "attr_devname": "LC4-CPLD-B", - "attr_devaddr": "0x31", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0x7", - "attr_cmpval": "0x0", - "attr_len": "1" - }] - } - }, - - "FAN-CTRL": { - "dev_info": { - "device_type": "FAN", - "device_name": "FAN-CTRL", - "device_parent": "CPLD-OCORE0" - }, - "i2c": { - "topo_info": { - "parent_bus": "0x2", - "dev_addr": "0x20", - "dev_type": "fan_cpld" - }, - "dev_attr": { - "num_fantrays": "5" - }, - "attr_list": [{ - "attr_name": "fan1_present", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan2_present", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan3_present", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan4_present", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan5_present", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan6_present", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan7_present", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan8_present", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan9_present", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan10_present", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan11_present", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan12_present", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x30", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan1_input", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x1b", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan2_input", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x25", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan3_input", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x1b", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan4_input", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x25", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan5_input", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x1d", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan6_input", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x27", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan7_input", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x1d", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan8_input", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x27", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan9_input", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x1f", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan10_input", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x29", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan11_input", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x1f", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan12_input", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x29", - "attr_mult": "1", - "attr_len": "2" - }, - { - "attr_name": "fan1_pwm", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan2_pwm", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan3_pwm", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan4_pwm", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x14", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan5_pwm", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan6_pwm", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan7_pwm", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan8_pwm", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x15", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan9_pwm", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x16", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan10_pwm", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x16", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan11_pwm", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x16", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan12_pwm", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x16", - "attr_mask": "0xff", - "attr_len": "1" - }, - { - "attr_name": "fan1_fault", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan2_fault", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan3_fault", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan4_fault", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x1", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan5_fault", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan6_fault", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan7_fault", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan8_fault", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x2", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan9_fault", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan10_fault", - "attr_devname": "FAN-CPLD-B", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan11_fault", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - }, - { - "attr_name": "fan12_fault", - "attr_devname": "FAN-CPLD-A", - "attr_devtype": "cpld", - "attr_offset": "0x1a", - "attr_mask": "0x04", - "attr_cmpval": "0x0", - "attr_len": "1" - } - ] - } - }, - - "FRONT_BOARD_CPU_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "SYS_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb21" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb21" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb21" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb21" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb21" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb21" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb21" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0xf", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb21" - } - ] - } - }, - - "FRONT_BOARD_PSU_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "SYS_LED" - }, - "dev_attr": { - "index": "1" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb22" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb22" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb22" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb22" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb22" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb22" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb22" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0xf", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb22" - } - ] - } - }, - - "FRONT_BOARD_FAN_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "SYS_LED" - }, - "dev_attr": { - "index": "2" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb23" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb23" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb23" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb23" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb23" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb23" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb23" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0xf", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0xb23" - } - ] - } - }, - - "FANTRAY1_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "0" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - } - ] - } - }, - - "FANTRAY2_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "1" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3b" - } - ] - } - }, - - "FANTRAY3_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "2" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - } - ] - } - }, - - "FANTRAY4_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "3" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3c" - } - ] - } - }, - - "FANTRAY5_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "4" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - } - ] - } - }, - - "FANTRAY6_LED": { - "dev_info": { - "device_type": "LED", - "device_name": "FANTRAY_LED" - }, - "dev_attr": { - "index": "5" - }, - "i2c": { - "attr_list": [{ - "attr_name": "STATUS_LED_COLOR_RED", - "descr": "Red", - "bits": "2:0", - "value": "0x2", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_RED_BLINK", - "descr": "Red Blinking", - "bits": "2:0", - "value": "0x1", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN", - "descr": "Green", - "bits": "2:0", - "value": "0x4", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_GREEN_BLINK", - "descr": "Green Blinking", - "bits": "2:0", - "value": "0x3", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER", - "descr": "Amber", - "bits": "2:0", - "value": "0x6", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_AMBER_BLINK", - "descr": "Amber Blinking", - "bits": "2:0", - "value": "0x5", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - }, - { - "attr_name": "STATUS_LED_COLOR_OFF", - "descr": "Off", - "bits": "2:0", - "value": "0x0", - "swpld_addr": "0x0d", - "swpld_addr_offset": "0x3d" - } - ] - } - } -} diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf_support b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/pddf_support deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/platform_components.json b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/platform_components.json deleted file mode 100644 index 80922c7b07ea..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/platform_components.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "chassis": { - "RA-B6510-32C": { - "component": { - "COMPONENT-1": {}, - "COMPONENT-2": {}, - "COMPONENT-3": {}, - "COMPONENT-4": {}, - "COMPONENT-5": {}, - "COMPONENT-6": {}, - "COMPONENT-7": {}, - "COMPONENT-8": {}, - "COMPONENT-9": {}, - "COMPONENT-10": {}, - "COMPONENT-11": {}, - "COMPONENT-12": {}, - "COMPONENT-13": {} - } - } - } -} diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/platform_env.conf b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/platform_env.conf deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/eeprom.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/eeprom.py deleted file mode 100644 index 3384c2cbd693..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/eeprom.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python - -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/bus/i2c/devices/1-0056/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/psuutil.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/psuutil.py deleted file mode 100644 index 25ec4dd6a947..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/psuutil.py +++ /dev/null @@ -1,59 +0,0 @@ -# -# psuutil.py -# Platform-specific PSU status interface for SONiC -# - -try: - from sonic_psu.psu_base import PsuBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class PsuUtil(PsuBase): - """Platform-specific PSUutil class""" - - def __init__(self): - PsuBase.__init__(self) - - def get_num_psus(self): - return 4 - - def get_psu_status(self, index): - if index < 1 or index > 4: - return False - - path_tmp = "/sys/devices/pci0000:00/0000:00:1f.0/psu_status_" - psu_path = "%s%d"%(path_tmp, index) - - try: - data = open(psu_path, "rb") - except IOError: - return False - - result = int(data.read(2), 16) - data.close() - - if (result & 0x2): - return True - - return False - - def get_psu_presence(self, index): - if index < 1 or index > 4: - return False - - path_tmp = "/sys/devices/pci0000:00/0000:00:1f.0/psu_status_" - psu_path = "%s%d"%(path_tmp, index) - - try: - data = open(psu_path, "rb") - except IOError: - return False - - result = int(data.read(2), 16) - data.close() - - if (result & 0x1) == 0: - return True - - return False diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/sfputil.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/sfputil.py index afa98329a25c..9926f1296a2d 100644 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/sfputil.py +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/sfputil.py @@ -6,17 +6,16 @@ try: import time import os + import traceback from sonic_sfp.sfputilbase import SfpUtilBase 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 = 127 - PORT_QSFP_START = 0 PORTS_IN_BLOCK = 128 EEPROM_OFFSET = 71 @@ -24,12 +23,8 @@ class SfpUtil(SfpUtilBase): QSFP_DEVICE_TYPE = "optoe1" I2C_MAX_ATTEMPT = 3 - SFP_STATUS_INSERTED = '1' - SFP_STATUS_REMOVED = '0' - _port_to_eeprom_mapping = {} port_to_i2cbus_mapping ={} - port_dict = {} @property def port_start(self): @@ -41,7 +36,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(self.PORT_QSFP_START, self.PORTS_IN_BLOCK) + return range(0, self.PORTS_IN_BLOCK) @property def port_to_eeprom_mapping(self): @@ -49,11 +44,7 @@ def port_to_eeprom_mapping(self): def __init__(self): for x in range(self.PORT_START, self.PORTS_IN_BLOCK): - self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) - if self.get_presence(x): - self.port_dict[x] = self.SFP_STATUS_INSERTED - else: - self.port_dict[x] = self.SFP_STATUS_REMOVED + self.port_to_i2cbus_mapping[x] = x + self.EEPROM_OFFSET SfpUtilBase.__init__(self) def _sfp_read_file_path(self, file_path, offset, num_bytes): @@ -65,8 +56,7 @@ def _sfp_read_file_path(self, file_path, offset, num_bytes): except Exception: attempts += 1 time.sleep(0.05) - else: - return True, read_buf + return True, read_buf return False, None def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): @@ -76,20 +66,18 @@ def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): return False - else: - with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: - rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) - return rv + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): try: sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path # Write device address to new_device file - nd_file = open(sysfs_nd_path, "w") nd_str = "%s %s" % (devtype, hex(devaddr)) - nd_file.write(nd_str) - nd_file.close() + with open(sysfs_nd_path, "w") as nd_file: + nd_file.write(nd_str) except Exception as err: print("Error writing to new device file: %s" % str(err)) @@ -100,7 +88,7 @@ def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): def _get_port_eeprom_path(self, port_num, devid): sysfs_i2c_adapter_base_path = "" - if port_num in self.port_to_eeprom_mapping.keys(): + if port_num in self.port_to_eeprom_mapping: sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] else: sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" @@ -145,12 +133,12 @@ def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): eeprom_raw.append("0x00") rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) - if rv == False: + if rv is False: return None try: for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) except Exception: return None @@ -160,35 +148,28 @@ 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.IDENTITY_EEPROM_ADDR, 256) + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256) def get_presence(self, port_num): # Check for invalid port_num - #return True if port_num < self.port_start or port_num > self.port_end: return False - PRESENCE_OFFSET = 3 - presence_path = "/sys/bus/i2c/devices/%d-003%d/sfp_presence%d" % ((PRESENCE_OFFSET + (port_num // 32)), - ((port_num % 32) // 16), (((port_num % 32) // 8) + 1)) + #The sff number starts from 1 + presence_path = "/sys/wb_plat/sff/sff%d/present" % (port_num + 1) + try: - data = open(presence_path, "rb") + with open(presence_path, "rb") as data: + presence_data = data.read(2) + if presence_data == "": + return False + result = int(presence_data, 16) except IOError: return False - presence_data = data.read(2) - if presence_data != "": - result = int(presence_data, 16) - else : - return False - data.close() - - # ModPrsL is active low - if result & (1 << (port_num % 8)) == 0: + if result == 1: return True - return False def get_low_power_mode(self, port_num): @@ -209,47 +190,55 @@ def reset(self, port_num): return True def get_transceiver_change_event(self, timeout=0): + return False, {} - start_time = time.time() - currernt_port_dict = {} - forever = False + def get_highest_temperature(self): + offset = 0 + hightest_temperature = -9999 - if timeout == 0: - forever = True - elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs - else: - print ("get_transceiver_change_event:Invalid timeout value", timeout) - return False, {} + presence_flag = False + read_eeprom_flag = False + temperature_valid_flag = False - end_time = start_time + timeout - if start_time > end_time: - print ('get_transceiver_change_event:' \ - 'time wrap / invalid timeout value', timeout) + for port in range(0, self.PORTS_IN_BLOCK): + if self.get_presence(port) is False: + continue - return False, {} # Time wrap or possibly incorrect timeout + presence_flag = True - while timeout >= 0: - # Check for OIR events and return updated port_dict - for x in range(self.PORT_START, self.PORTS_IN_BLOCK): - if self.get_presence(x): - currernt_port_dict[x] = self.SFP_STATUS_INSERTED - else: - currernt_port_dict[x] = self.SFP_STATUS_REMOVED - if (currernt_port_dict == self.port_dict): - if forever: - time.sleep(1) - else: - timeout = end_time - time.time() - if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity - else: - if timeout > 0: - time.sleep(timeout) - return True, {} + if port in self.qsfp_ports: + offset = 22 else: - # Update reg value - self.port_dict = currernt_port_dict - return True, self.port_dict - print ("get_transceiver_change_event: Should not reach here.") - return False, {} + offset = 96 + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = float(result / 256.0) + if -50 <= result <= 200: + temperature_valid_flag = True + hightest_temperature = max(hightest_temperature, result) + except BaseException: + print(traceback.format_exc()) + + # all port not presence + if presence_flag is False: + hightest_temperature = -10000 + + # all port read eeprom fail + elif read_eeprom_flag is False: + hightest_temperature = -9999 + + # all port temperature invalid + elif read_eeprom_flag is True and temperature_valid_flag is False: + hightest_temperature = -10000 + + hightest_temperature = round(hightest_temperature, 2) + + return hightest_temperature diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/ssd_util.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/ssd_util.py index b6e5d6d3dd46..e92782a0969b 100644 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/ssd_util.py +++ b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/plugins/ssd_util.py @@ -1,73 +1,222 @@ # -# ssd_health +# ssd_util.py # +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium -from sonic_platform_base.sonic_ssd.ssd_base import SsdBase -from subprocess import Popen, PIPE -from re import findall -from os.path import exists +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_ssd.ssd_base import SsdBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") +SMARTCTL = "smartctl {} -a" INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 class SsdUtil(SsdBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + """ - Constructor - Args: - diskdev: Linux device name to get parameters for + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" """ - if not isinstance(diskdev, str): - raise TypeError("disk dev type wrong {}".format(type(diskdev))) - - if not exists(diskdev): - raise RuntimeError("disk dev {} not found".format(diskdev)) - - self.model = NOT_AVAILABLE - self.serial = NOT_AVAILABLE - self.firmware = NOT_AVAILABLE - self.temperature = NOT_AVAILABLE - self.health = NOT_AVAILABLE + self.model_attr = { + "ER2-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n231\s+(.+?)\n" } + } - self.ssd_info = self._execute_shell(INNODISK.format(diskdev)) - - self.model = self._parse_re(r'Model Name:\s*(.+?)\n', self.ssd_info) - self.serial = self._parse_re(r'Serial Number:\s*(.+?)\n', self.ssd_info) - self.firmware = self._parse_re(r'FW Version:\s*(.+?)\n', self.ssd_info) - self.temperature = self._parse_re(r'Temperature\s*\[\s*(.+?)\]', self.ssd_info) - self.health = self._parse_re(r'Health:\s*(.+?)', self.ssd_info) + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = "[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" def _execute_shell(self, cmd): - process = Popen(cmd.split(), universal_newlines=True, stdout=PIPE) - output, _ = process.communicate() + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None return output def _parse_re(self, pattern, buffer): - res_list = findall(pattern, buffer) + res_list = re.findall(pattern, str(buffer)) return res_list[0] if res_list else NOT_AVAILABLE + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re('Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re('Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re('Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re('Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re('\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re('SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re('Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re('Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + def get_health(self): """ Retrieves current disk health in percentages + Returns: A float number of current ssd health e.g. 83.5 """ - return self.health + return float(self.health) def get_temperature(self): """ Retrieves current disk temperature in Celsius + Returns: A float number of current temperature in Celsius e.g. 40.1 """ - return self.temperature + return float(self.temperature) def get_model(self): """ Retrieves model for the given disk device + Returns: A string holding disk model as provided by the manufacturer """ @@ -76,6 +225,7 @@ def get_model(self): def get_firmware(self): """ Retrieves firmware version for the given disk device + Returns: A string holding disk firmware version as provided by the manufacturer """ @@ -84,15 +234,76 @@ def get_firmware(self): def get_serial(self): """ Retrieves serial number for the given disk device + Returns: A string holding disk serial number as provided by the manufacturer """ return self.serial - + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life def get_vendor_output(self): """ Retrieves vendor specific data for the given disk device + Returns: A string holding some vendor specific disk information """ - return self.ssd_info + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re('{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/sensors.conf b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/sensors.conf deleted file mode 100644 index 56b7eba72536..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/sensors.conf +++ /dev/null @@ -1,14 +0,0 @@ -chip "rg_cpld-*" - label fan1 "fan1_inlet" - label fan2 "fan1_outlet" - label fan3 "fan2_inlet" - label fan4 "fan2_outlet" - label fan5 "fan3_inlet" - label fan6 "fan3_outlet" - label fan7 "fan4_inlet" - label fan8 "fan4_outlet" - label fan9 "fan5_inlet" - label fan10 "fan5_outlet" - label fan11 "fan6_inlet" - label fan12 "fan6_outlet" - diff --git a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/bcm_pre.rc b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/system_health_monitoring_config.json old mode 100644 new mode 100755 similarity index 100% rename from device/ragile/x86_64-ragile_ra-b6910-64c-r0/bcm_pre.rc rename to device/ragile/x86_64-ragile_ra-b6920-4s-r0/system_health_monitoring_config.json diff --git a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/systest.py b/device/ragile/x86_64-ragile_ra-b6920-4s-r0/systest.py deleted file mode 100644 index b40bf45b2c19..000000000000 --- a/device/ragile/x86_64-ragile_ra-b6920-4s-r0/systest.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/python -# -*- coding: UTF-8 -*- - -# * onboard interval check -# * FAN trays -# * PSU -# * temp -import time -import datetime -from monitor import status - -def doWork(): - a=[]; - ''' - return: [{'status': '1', 'hw_version': '1.00', 'errcode': 0, 'fan_type': 'M6510-FAN-F', 'errmsg': 'OK', 'Speed': '9778', 'id': 'fan1', 'present': '0', 'sn': '1000000000014'}, - {'id': 'fan2', 'errmsg': 'not present', 'errcode': -1}, - {'id': 'fan3', 'errmsg': 'not present', 'errcode': -1}, - {'id': 'fan4', 'errmsg': 'not present', 'errcode': -1} - ] - description: 1.get id - 2.errcode equal 0 : dev normal - not equal 0 : get errmsg - 3.other message add when all check success - ''' - status.checkFan(a) - #status.getTemp(a) - #status.getPsu(a) - - nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - print nowTime - print a -def run(interval): - while True: - try: - time_remaining = interval - time.time()%interval - time.sleep(time_remaining) - doWork() - except Exception as e: - print(e) - -if __name__ == '__main__': - interval = 1 - run(interval) diff --git a/platform/broadcom/platform-modules-ragile.mk b/platform/broadcom/platform-modules-ragile.mk index 74ce1b04f475..12236b1e72ce 100644 --- a/platform/broadcom/platform-modules-ragile.mk +++ b/platform/broadcom/platform-modules-ragile.mk @@ -4,7 +4,7 @@ export RAGILE_RA_B6510_48V8C_PLATFORM_MODULE_VERSION RAGILE_RA_B6510_48V8C_PLATFORM_MODULE = platform-modules-ragile-ra-b6510-48v8c_$(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE_VERSION)_amd64.deb $(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-ragile -$(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(PDDF_PLATFORM_MODULE) $(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE)_PLATFORM = x86_64-ragile_ra-b6510-48v8c-r0 SONIC_DPKG_DEBS += $(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE) SONIC_STRETCH_DEBS += $(RAGILE_RA_B6510_48V8C_PLATFORM_MODULE) diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index 5f3172ca0305..938d741d188d 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -14,7 +14,7 @@ include $(PLATFORM_PATH)/platform-modules-cel.mk include $(PLATFORM_PATH)/platform-modules-juniper.mk #include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk #include $(PLATFORM_PATH)/platform-modules-ruijie.mk -#include $(PLATFORM_PATH)/platform-modules-ragile.mk +include $(PLATFORM_PATH)/platform-modules-ragile.mk include $(PLATFORM_PATH)/docker-syncd-brcm.mk include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk include $(PLATFORM_PATH)/docker-saiserver-brcm.mk diff --git a/platform/broadcom/sonic-platform-modules-ragile/LICENSE b/platform/broadcom/sonic-platform-modules-ragile/LICENSE old mode 100755 new mode 100644 index d37122689f3e..5681cac34476 --- a/platform/broadcom/sonic-platform-modules-ragile/LICENSE +++ b/platform/broadcom/sonic-platform-modules-ragile/LICENSE @@ -1,5 +1,4 @@ Copyright (C) 2016 Microsoft, Inc -Copyright (C) 2018 Ragile Network 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 2 diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/Makefile index 6daf3d2b2fd1..578d65b3bf3e 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/common/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/common/Makefile @@ -9,33 +9,34 @@ SUB_BUILD_DIR = $(PWD)/build DIR_KERNEL_SRC = $(PWD)/modules SCRIPT_DIR = $(PWD)/script SERVICE_DIR = $(PWD)/service -DEPMOD_CONF_DIR = $(PWD)/depmod_conf +BLACK_DRIVER_CONF_DIR = $(PWD)/modprobe_conf -KBUILD_EXTRA_SYMBOLS += $(DIR_KERNEL_SRC)/Module.symvers -export KBUILD_EXTRA_SYMBOLS +app_dir = $(PWD)/app +app_build_dir = $(app_dir)/build +modules_build_dir = $(DIR_KERNEL_SRC)/build INSTALL_MODULE_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system -INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3.7/dist-packages -INSTALL_DEPMOD_CONF = $(SUB_BUILD_DIR)/etc/depmod.d +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_BLACK_DRIVER = $(SUB_BUILD_DIR)/etc/modprobe.d all: - $(MAKE) -C $(KERNEL_SRC)/build M=$(DIR_KERNEL_SRC) modules + $(MAKE) -C $(app_dir) + $(MAKE) -C $(DIR_KERNEL_SRC) @if [ ! -d ${INSTALL_MODULE_DIR} ]; then mkdir -p ${INSTALL_MODULE_DIR} ;fi @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi @if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi @if [ -d $(PWD)/lib/ ]; then cp -r $(PWD)/lib/* ${INSTALL_LIB_DIR} ;fi - @if [ -d $(PWD)/lib/ ]; then cp -r $(PWD)/lib/* ${INSTALL_LIB_DIR2} ;fi - @if [ ! -d ${INSTALL_DEPMOD_CONF} ]; then mkdir -p ${INSTALL_DEPMOD_CONF} ;fi - cp -r $(DEPMOD_CONF_DIR)/* $(INSTALL_DEPMOD_CONF) - cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_MODULE_DIR) + @if [ -d $(PWD)/sonic_platform/ ]; then cp -rf $(PWD)/sonic_platform ${INSTALL_LIB_DIR} ;fi + cp -r $(app_build_dir)/module/*.ko $(INSTALL_MODULE_DIR) + cp -r $(modules_build_dir)/*.ko $(INSTALL_MODULE_DIR) + cp -r $(app_dir)/build/app/* $(INSTALL_SCRIPT_DIR) cp -r $(SCRIPT_DIR)/* $(INSTALL_SCRIPT_DIR) cp -r $(SERVICE_DIR)/* $(INSTALL_SERVICE_DIR) @if [ -d $(INSTALL_SCRIPT_DIR) ]; then chmod +x $(INSTALL_SCRIPT_DIR)/* ;fi + @if [ ! -d ${INSTALL_BLACK_DRIVER} ]; then mkdir -p ${INSTALL_BLACK_DRIVER} ;fi + cp -r $(BLACK_DRIVER_CONF_DIR)/* $(INSTALL_BLACK_DRIVER) clean: - rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd - rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order - rm -rf ${DIR_KERNEL_SRC}/.tmp_versions rm -rf $(SUB_BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/Makefile new file mode 100644 index 000000000000..25ba3c5a9156 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/Makefile @@ -0,0 +1,25 @@ +pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST)) +pes_parent_dir:=$(shell dirname $(pes_parent_dir)) + +SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "build") print $$9}') +INC = -I./inc + +COMMON_OUT_PUT := $(shell pwd)/build +common_out_put_dir := $(COMMON_OUT_PUT)/app +common_module_dir := $(COMMON_OUT_PUT)/module/ +export common_out_put_dir common_module_dir + +all : CHECK $(SUBDIRS) +CHECK : + @echo $(pes_parent_dir) + +$(SUBDIRS):ECHO + #@echo $@ + make -C $@ + +ECHO: + @echo $(SUBDIRS) + +.PHONY : clean +clean : + -rm -rf $(COMMON_OUT_PUT) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/Makefile new file mode 100644 index 000000000000..e4078716eb33 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/Makefile @@ -0,0 +1,30 @@ +top_srcdir:=$(shell pwd) +#include $(top_srcdir)/Rules.mk +DIR=$(shell pwd) +BUILD_OUTPUT=$(DIR)/tmp +SRCS=$(wildcard *.c) +OBJS=$(patsubst %.c, $(BUILD_OUTPUT)/%.o, $(SRCS)) +DEPS=$(patsubst %.o, %.d, $(OBJS)) +CFLAGS+=-Wall -W -g -I$(DIR)/include +LDFLAGS= +PROGRAM=dfd_debug + +.PHONY: all + +all:$(OBJS) + $(CC) $(OBJS) $(LDFLAGS) -o $(BUILD_OUTPUT)/$(PROGRAM) + @if [ ! -d ${common_out_put_dir} ]; then mkdir -p ${common_out_put_dir} ;fi + cp -p $(BUILD_OUTPUT)/$(PROGRAM) $(common_out_put_dir) + +$(OBJS):$(SRCS) + @if [ ! -d ${BUILD_OUTPUT} ]; then mkdir -p ${BUILD_OUTPUT} ;fi + $(CC) -c $(CFLAGS) $(INCLUDE) $(*F).c -o $@ + +.PHONY: install +install: + @mkdir -p $(common_out_put_dir) + cp -p $(BUILD_OUTPUT)/$(PROGRAM) $(common_out_put_dir) + +rebuild: clean all +clean: + @rm -rf $(BUILD_OUTPUT)/* diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_debug.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_debug.c new file mode 100644 index 000000000000..93ed6066efed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_debug.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "dfd_utest.h" + +int g_dfd_debug_sw = 0; +int g_dfd_debugpp_sw = 0; + +void dfd_debug_set_init(void) +{ + FILE *fp; + char buf[10]; + + mem_clear(buf, sizeof(buf)); + fp = fopen(DFD_DEBUGP_DEBUG_FILE, "r"); + if (fp != NULL) { + + g_dfd_debug_sw = 1; + fclose(fp); + } + + fp = fopen(DFD_DEBUGPP_DEBUG_FILE, "r"); + if (fp != NULL) { + + g_dfd_debugpp_sw = 1; + fclose(fp); + } + + return; +} + +int main(int argc, char* argv[]) +{ + dfd_debug_set_init(); + dfd_utest_cmd_main(argc, argv); + + return 0; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.c new file mode 100644 index 000000000000..9c711830958e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.c @@ -0,0 +1,1802 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dfd_utest.h" + +#define DFD_UTEST_MAX_RDWR_NUM (256) +#define DFD_UTEST_DEFAULT_WR_NUM (1) + +#define DEV_MEM_NAME "/dev/mem" +#define DEV_KMEM_NAME "/dev/kmem" + +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) +#define DFD_UTEST_MAX_BIT_WIDTH (4) + +#ifdef DFD_UTEST_ITEM +#undef DFD_UTEST_ITEM +#endif +#define DFD_UTEST_ITEM(_id, _type_str, _help_info, _help_info_detail) {_id, #_type_str, dfd_utest_##_type_str, _help_info, _help_info_detail}, +static dfd_utest_t g_dfd_unit_test[] = { + DFD_UTEST_ITEM_ALL +}; + +static int g_sys_page_size; +#define SYS_PAGE_SIZE g_sys_page_size +#define SYS_PAGE_MASK (~(SYS_PAGE_SIZE - 1)) + +void dfd_utest_print_cmd(int argc, char* argv[]) +{ + int i; + + for (i = 1; i < argc; i++) { + if (i != 1) { + printf(" "); + } + printf("%s", argv[i]); + } + return; +} + +void dfd_utest_print_all_help(void) +{ + int i, tbl_size; + + tbl_size = sizeof(g_dfd_unit_test) / sizeof(g_dfd_unit_test[0]); + + for (i = 0; i < tbl_size; i++) { + printf("%-20s\t\t\t%s\r\n", g_dfd_unit_test[i].type_str, g_dfd_unit_test[i].help_info); + } + + return; +} + +void dfd_utest_printf_single_help(int utest_type) +{ + int i, tbl_size; + + tbl_size = sizeof(g_dfd_unit_test) / sizeof(g_dfd_unit_test[0]); + for (i = 0; i < tbl_size; i++) { + if (g_dfd_unit_test[i].utest_type == utest_type) { + printf("%-20s\t\t\t%s\r\n", g_dfd_unit_test[i].type_str, g_dfd_unit_test[i].help_info_detail); + return; + } + } + + DFD_DEBUG_DBG("type: %d not match.\n", utest_type); + return; + +} + +void dfd_utest_printf_reg(uint8_t *buf, int buf_len, uint32_t offset_addr) +{ + int i, j, tmp; + + j = offset_addr % 16; + tmp = j; + offset_addr -= j; + printf("\n "); + + for (i = 0; i < 16; i++) { + printf("%2x ", i); + } + + for (i = 0; i < buf_len + j; i++) { + if ((i % 16) == 0) { + printf("\n0x%08x ", offset_addr); + offset_addr = offset_addr + 16; + } + if (tmp) { + printf(" "); + tmp--; + } else { + printf("%02x ", buf[i-j]); + } + } + + printf("\n"); + return; +} + +#define I2C_RETRIES 0x0701 +#define I2C_TIMEOUT 0x0702 +#define I2C_RDWR 0x0707 + +#define I2C_SLAVE 0x0703 /* Use this slave address */ + +#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it + is already in use by a driver! */ +#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */ +#define I2C_SMBUS 0x0720 /* SMBus transfer */ + +struct i2c_msg +{ + unsigned short addr; + unsigned short flags; +#define I2C_M_TEN 0x0010 +#define I2C_M_RD 0x0001 + unsigned short len; + unsigned char *buf; +}; + +struct i2c_rdwr_ioctl_data +{ + struct i2c_msg *msgs; + int nmsgs; + +}; + +#define DFD_I2C_SHORT_ADDR_TYPE 0 +#define DFD_I2C_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define DFD_I2C_RETRY_TIME (50000 / DFD_I2C_RETRY_SLEEP_TIME) +/* i2c_smbus_xfer read or write markers */ +#define I2C_SMBUS_READ 1 +#define I2C_SMBUS_WRITE 0 + +/* SMBus transaction types (size parameter in the above functions) + Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */ +#define I2C_SMBUS_QUICK 0 +#define I2C_SMBUS_BYTE 1 +#define I2C_SMBUS_BYTE_DATA 2 +#define I2C_SMBUS_WORD_DATA 3 +#define I2C_SMBUS_PROC_CALL 4 +#define I2C_SMBUS_BLOCK_DATA 5 +#define I2C_SMBUS_I2C_BLOCK_BROKEN 6 +#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS_I2C_BLOCK_DATA 8 + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,36) +/* fix tjm */ + +#ifndef __ASSEMBLY__ +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long __s64; +typedef unsigned long __u64; + +#endif /* __ASSEMBLY__ */ + +#else +/* do noting add tjm */ +#endif + +/* + * Data for SMBus Messages + */ +#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ +union i2c_smbus_data { + __u8 byte; + __u16 word; + __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ + /* and one more for user-space compatibility */ +}; + +/* This is the structure as used in the I2C_SMBUS ioctl call */ +struct i2c_smbus_ioctl_data { + __u8 read_write; + __u8 command; + __u32 size; + union i2c_smbus_data *data; +}; +int32_t dfd_read_port_i2c_one_time_smbus(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *recv_buf, int32_t size, int addr_type) +{ + union i2c_smbus_data data; + struct i2c_smbus_ioctl_data ioctl_data; + unsigned long addr = dev_addr; + int fd; + int rc; + int rv; + int i; + + mem_clear(&ioctl_data, sizeof(struct i2c_smbus_ioctl_data)); + if (i2c_name == NULL || recv_buf == NULL) { + DFD_DEBUG_ERROR("i2c_num = NULL, recv_buf = NULL\r\n"); + return -1; + } + + DFD_DEBUG_DBG("i2c name: %s, dev_addr: 0x%x, offset_addr: 0x%x, size: %d, addr_type: %d.\n", i2c_name, dev_addr, + offset_addr, size, addr_type); + + rv = 0; + fd = open(i2c_name, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd %d\n", fd); + rv = fd; + goto err; + } + if (ioctl(fd, I2C_SLAVE_FORCE , addr) < 0) { + DFD_DEBUG_ERROR("ioctl 2C_SLAVE_FORCE %d.\n", errno); + rv =-1; + goto fail; + } + for (i = 0 ;i < size; i++) { + data.byte = 0; + ioctl_data.read_write = I2C_SMBUS_READ; + ioctl_data.command = (offset_addr + i); + ioctl_data.size = I2C_SMBUS_BYTE_DATA; + ioctl_data.data= &data; + + rc = ioctl(fd, I2C_SMBUS, &ioctl_data); + if (rc < 0) { + DFD_DEBUG_ERROR("read, I2C_SMBUS failed: %d.\n", errno); + rv = -1; + goto fail; + } + *(recv_buf + i) = data.byte; + } + fail: + close(fd); + err: + return rv; + +} + +int32_t dfd_read_port_i2c_one_time(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *recv_buf, int32_t size, int addr_type) +{ + + int32_t fd, rv; + struct i2c_rdwr_ioctl_data ioctl_data; + struct i2c_msg msgs[2]; + uint8_t buf[2]; + + if (i2c_name == NULL || recv_buf == NULL) { + DFD_DEBUG_ERROR("i2c_num = NULL, recv_buf = NULL\r\n"); + return -1; + } + + DFD_DEBUG_DBG("i2c name %s, dev_addr 0x%x, offset_addr 0x%x, size %d, addr_type %d.\n", i2c_name, dev_addr, + offset_addr, size, addr_type); + + rv = 0; + fd = open(i2c_name, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd %d\n", fd); + return -1; + } + mem_clear(&ioctl_data, sizeof(ioctl_data)); + mem_clear(msgs, sizeof(msgs)); + mem_clear(buf, sizeof(buf)); + if (ioctl(fd, I2C_SLAVE, dev_addr) < 0) { + + DFD_DEBUG_ERROR("%s %dioctl fail(ret:%d, errno:%s)!\r\n", __func__ , __LINE__, rv, strerror(errno)); + rv = -1; + goto fail; + } + + buf[0] = (uint8_t)(offset_addr); + msgs[0].addr= dev_addr; + msgs[0].len= 2; + msgs[0].buf= buf; + msgs[1].addr= dev_addr; + msgs[1].flags|= I2C_M_RD; + msgs[1].len= 1; + msgs[1].buf= recv_buf; + ioctl_data.nmsgs= 1; + ioctl_data.msgs= msgs; + + rv = ioctl(fd, I2C_RDWR, &ioctl_data); + if(rv < 0) { + DFD_DEBUG_ERROR("%s %dioctl fail(ret:%d, errno:%s)!\r\n", __func__ , __LINE__, rv, strerror(errno)); + goto fail; + } + ioctl_data.msgs= &msgs[1]; + DFD_DEBUG_DBG("ioctlread, return :%d/n", ioctl(fd, I2C_RDWR, &ioctl_data)); + DFD_DEBUG_DBG("dfd_read_port_i2c addr: 0x%X, offset: 0x%X, value: 0x%X\n", dev_addr, offset_addr, *recv_buf); + fail: + close(fd); + return rv; + +} + +int32_t dfd_read_port_i2c(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *recv_buf, int32_t size) +{ + int i; + int rv; + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + rv = dfd_read_port_i2c_one_time_smbus(i2c_name, dev_addr, offset_addr, recv_buf, size, DFD_I2C_SHORT_ADDR_TYPE); + if (rv < 0) { + DFD_DEBUG_ERROR("(read times %d)i2c name %s, dev_addr 0x%X, offset_addr 0x%X, addr_type %d\n", i, i2c_name, dev_addr, offset_addr, DFD_I2C_SHORT_ADDR_TYPE); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + return rv; +} + +int32_t dfd_write_port_i2c_one_time(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *write_buf, int32_t size,int addr_type) +{ + int32_t fd, rv; + int index; + struct i2c_smbus_ioctl_data ioctl_data; + union i2c_smbus_data data; + uint8_t addr_buf[2]; + uint8_t write_buf_tmp[256]; + + if (i2c_name == NULL || write_buf == NULL ) { + DFD_DEBUG_ERROR("i2c_num = NULL \r\n"); + return -1; + } + + if (size <= 0) { + DFD_DEBUG_ERROR("error:size\n"); + return -1; + } + DFD_DEBUG_DBG("i2c name %s, dev_addr 0x%x, offset_addr 0x%x, size %d, addr_type %d\n",i2c_name, dev_addr, + offset_addr, size, addr_type); + mem_clear(&ioctl_data, sizeof(ioctl_data)); + mem_clear(addr_buf, sizeof(addr_buf)); + mem_clear(write_buf_tmp, sizeof(write_buf_tmp)); + + rv = 0; + + fd = open(i2c_name, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd %d\n", fd); + return -1; + } + + if (ioctl(fd, I2C_SLAVE_FORCE, dev_addr) < 0) { + DFD_DEBUG_ERROR("ioctl, I2C_SLAVE failed: %d.\n", errno); + rv = -1; + goto fail; + } + + for (index = 0; index < size; index++) { + data.byte = *(write_buf + index); + ioctl_data.read_write = I2C_SMBUS_WRITE; + ioctl_data.command = (offset_addr + index); + ioctl_data.size = I2C_SMBUS_BYTE_DATA; + ioctl_data.data= &data; + rv = ioctl(fd, I2C_SMBUS, (unsigned long)&ioctl_data); + if(rv < 0) { + DFD_DEBUG_ERROR("ioctl fail(ret:%d, errno:%s %d) !\r\n", rv, strerror(errno),errno); + break; + } + DFD_DEBUG_DBG("ret:%d value:0x%02x\n", rv, data.byte); + usleep(5000); + } + +fail: + close(fd); + return rv; +} + +int32_t dfd_write_port_i2c(char *i2c_name, uint16_t dev_addr, uint16_t offset_addr, + uint8_t *write_buf, int32_t size) +{ + int i; + int rv; + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + rv = dfd_write_port_i2c_one_time(i2c_name, dev_addr, offset_addr, write_buf,size, DFD_I2C_SHORT_ADDR_TYPE); + if (rv < 0) { + DFD_DEBUG_ERROR("(write times %d)i2c name %s, dev_addr 0x%X, offset_addr 0x%X, addr_type %d\n", + i, i2c_name, dev_addr, offset_addr, DFD_I2C_SHORT_ADDR_TYPE); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + return rv; +} + +static int dfd_read_io_port(uint16_t offset_addr, uint8_t *recv_buf, int32_t size) +{ + int fd; + int ret; + + fd = open("/dev/port", O_RDWR); + if (fd < 0) { + printf("open failed ret %d.\n", fd); + return -1; + } + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek failed ret %d.\n", ret); + goto exit; + } + + ret = read(fd, recv_buf, size); + if (ret != size) { + printf("read failed ret %d size %d.\n", ret, size); + ret = -1; + goto exit; + } + +exit: + close(fd); + return ret; +} + +static int dfd_write_io_port(uint16_t offset_addr, uint8_t *write_buf, int32_t size) +{ + int fd; + int ret; + + fd = open("/dev/port", O_RDWR); + if (fd < 0) { + printf("open failed ret %d.\n", fd); + return -1; + } + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek failed ret %d.\n", ret); + goto exit; + } + + ret = write(fd, write_buf, size); + if (ret != size) { + printf("write failed ret %d size %d.\n", ret, size); + ret = -1; + goto exit; + } + +exit: + close(fd); + return ret; +} + +static int dfd_process_mem(char *dev_name, char is_wr, char width, off_t offset, uint8_t *buf, int32_t size) +{ + int mfd, ret = 0; + void *base; + int i, j; + unsigned int val; + off_t map_offset; + size_t map_size; + + if (size & (width - 1)) { + printf("size %d invalid.\n", size); + return -1; + } + + mfd = open(dev_name, O_RDWR); + if (mfd < 0) { + printf("Cannot open %s.\n", dev_name); + return -1; + } + + g_sys_page_size = getpagesize(); + map_offset = offset & SYS_PAGE_MASK; + map_size = size + offset - map_offset; + base = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, map_offset); + if (base == MAP_FAILED) { + printf("mmap offset 0x%lx failed error(%s).\n", map_offset, strerror(errno)); + close(mfd); + return -1; + } + printf("width %d map_offset 0x%lx, offset 0x%lx, mmap base %p, g_sys_page_size %d\n", + width, map_offset, offset, base, g_sys_page_size); + + if (is_wr) { + for (i = 0; i < size; i = i + width) { + val = 0; + for (j = 0; j < width; j++) { + val |= buf[i + j] << (8 * j); + } + switch (width) { + case 1: + *((volatile unsigned char*)(base + i + offset - map_offset)) = val; + break; + case 2: + *((volatile unsigned short*)(base + i + offset - map_offset)) = val; + break; + case 4: + *((volatile unsigned int*)(base + i + offset - map_offset)) = val; + break; + default: + ret = -1; + printf("Not support width %d.\n", width); + goto exit; + } + } + } else { + for (i = 0; i < size; i = i + width) { + switch (width) { + case 1: + val = *((volatile unsigned char*)(base + i + offset - map_offset)); + break; + case 2: + val = *((volatile unsigned short*)(base + i + offset - map_offset)); + break; + case 4: + val = *((volatile unsigned int*)(base + i + offset - map_offset)); + break; + default: + ret = -1; + printf("Not support width %d.\n", width); + goto exit; + } + for (j = 0; j < width; j++) { + buf[i + j] = (val >> (8 * j)) & 0xff; + } + } + } +exit: + munmap(base, map_size); + close(mfd); + return ret; +} + +int32_t dfd_i2c_gen_read_one_time(char *i2c_path, uint32_t dev_addr, uint32_t addr_bitwidth, + uint32_t offset_addr, uint8_t *recv_buf, int32_t rd_len) +{ + int32_t fd, rv, i; + struct i2c_rdwr_ioctl_data ioctl_data; + struct i2c_msg msgs[2]; + uint8_t buf[DFD_UTEST_MAX_BIT_WIDTH]; + + fd = open(i2c_path, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd:%d\n", fd); + return -1; + } + mem_clear(&ioctl_data, sizeof(ioctl_data)); + mem_clear(msgs, sizeof(msgs)); + mem_clear(buf, sizeof(buf)); + + i = 0; + + switch (addr_bitwidth) { + case WIDTH_4Byte: + buf[i++] = (offset_addr >> 24) & 0xFF; + buf[i++] = (offset_addr >> 16) & 0xFF; + buf[i++] = (offset_addr >> 8) & 0xFF; + buf[i++] = offset_addr & 0xFF; + break; + case WIDTH_2Byte: + buf[i++] = (offset_addr >> 8) & 0xFF; + buf[i++] = offset_addr & 0xFF; + break; + case WIDTH_1Byte: + buf[i++] = offset_addr & 0xFF; + break; + default: + DFD_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set %u addr_bitwidth \n", addr_bitwidth); + rv = -1; + goto fail; + } + + msgs[0].addr = dev_addr; + msgs[0].flags = 0; + msgs[0].len = addr_bitwidth; + msgs[0].buf = buf; + msgs[1].addr = dev_addr; + msgs[1].flags |= I2C_M_RD; + msgs[1].len = rd_len; + msgs[1].buf = recv_buf; + ioctl_data.nmsgs = 2; + ioctl_data.msgs = msgs; + + rv = ioctl(fd, I2C_RDWR, &ioctl_data); + if(rv < 0) { + DFD_DEBUG_ERROR("%s %d Error: Sending messages failed:(ret:%d, errno:%s)!\n", __func__ , __LINE__, rv, strerror(errno)); + goto fail; + } + +fail: + close(fd); + return rv; +} + +int32_t dfd_i2c_gen_read(char *i2c_path, uint32_t dev_addr, uint32_t addr_bitwidth, + uint32_t offset_addr, uint8_t *recv_buf, int32_t rd_len) +{ + int i; + int rv; + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + rv = dfd_i2c_gen_read_one_time(i2c_path, dev_addr, addr_bitwidth, offset_addr, recv_buf, rd_len); + if (rv < 0) { + DFD_DEBUG_ERROR("(read times:%d) i2c_path:%s, dev_addr:0x%x, addr_bitwidth:%u, offset_addr:0x%x, rd_len:%u\n", + i, i2c_path, dev_addr, addr_bitwidth, offset_addr, rd_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + return rv; +} + +int dfd_utest_i2c_gen_rd(int argc, char* argv[]) +{ + int ret; + uint32_t i2c_bus, dev_addr, addr_bitwidth, offset_addr, data_bitwidth, rd_len, i, j; + char *stopstring; + char i2c_path[32]; + uint8_t tmp_value[DFD_UTEST_MAX_RDWR_NUM]; + uint8_t rd_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc != 8) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_GEN_RD); + goto exit; + } + + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + addr_bitwidth = strtol(argv[4], &stopstring, 10); + offset_addr = strtol(argv[5], &stopstring, 16); + data_bitwidth = strtol(argv[6], &stopstring, 10); + rd_len = strtol(argv[7], &stopstring, 10); + + if (rd_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", rd_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_GEN_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + mem_clear(tmp_value, sizeof(tmp_value)); + ret = dfd_i2c_gen_read(i2c_path, dev_addr, addr_bitwidth, offset_addr, tmp_value, rd_len); + if (ret < 0) { + printf("read failed. ret:%d\n", ret); + goto exit; + } + + mem_clear(rd_value, sizeof(rd_value)); + if (data_bitwidth == WIDTH_1Byte) { + memcpy(rd_value, tmp_value, rd_len); + } else { + for (i = 0; i < rd_len; i += data_bitwidth) { + for (j = 0; (j < data_bitwidth) && (i + j < rd_len); j++) { + rd_value[i + data_bitwidth - j - 1] = tmp_value[i + j]; + } + } + } + + dfd_utest_printf_reg(rd_value, rd_len, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int32_t dfd_i2c_gen_write_one_time(char *i2c_path, uint32_t dev_addr, uint32_t addr_bitwidth, + uint32_t offset_addr, uint8_t *wr_value, uint32_t wr_len) +{ + int32_t fd, rv, i; + struct i2c_rdwr_ioctl_data ioctl_data; + struct i2c_msg msgs[1]; + uint8_t buf[DFD_UTEST_MAX_BIT_WIDTH + DFD_UTEST_MAX_RDWR_NUM]; + + fd = open(i2c_path, O_RDWR | O_SYNC); + if (fd < 0) { + DFD_DEBUG_ERROR("i2c open fail fd %d\n", fd); + return -1; + } + mem_clear(&ioctl_data, sizeof(ioctl_data)); + mem_clear(msgs, sizeof(msgs)); + mem_clear(buf, sizeof(buf)); + + i = 0; + + switch (addr_bitwidth) { + case WIDTH_4Byte: + buf[i++] = (offset_addr >> 24) & 0xFF; + buf[i++] = (offset_addr >> 16) & 0xFF; + buf[i++] = (offset_addr >> 8) & 0xFF; + buf[i++] = offset_addr & 0xFF; + break; + case WIDTH_2Byte: + buf[i++] = (offset_addr >> 8) & 0xFF; + buf[i++] = offset_addr & 0xFF; + break; + case WIDTH_1Byte: + buf[i++] = offset_addr & 0xFF; + break; + default: + DFD_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set %u addr_bitwidth \r\n", addr_bitwidth); + rv = -1; + goto fail; + } + + memcpy(buf + addr_bitwidth, wr_value, wr_len); + + msgs[0].addr= dev_addr; + msgs[0].flags = 0; + msgs[0].len= addr_bitwidth + wr_len; + msgs[0].buf= buf; + + ioctl_data.nmsgs= 1; + ioctl_data.msgs= msgs; + + rv = ioctl(fd, I2C_RDWR, &ioctl_data); + if(rv < 0) { + DFD_DEBUG_ERROR("%s %dError: Sending messages failed:(ret:%d, errno:%s)!\n", __func__ , __LINE__, rv, strerror(errno)); + goto fail; + } else if (rv < ioctl_data.nmsgs) { + DFD_DEBUG_ERROR("%s %dWarning: only %d/%d messages were sent\n", __func__ , __LINE__, rv, ioctl_data.nmsgs); + } + +fail: + close(fd); + return rv; +} + +int32_t dfd_i2c_gen_write(char *i2c_path, uint32_t dev_addr, uint32_t addr_bitwidth, + uint32_t offset_addr, uint8_t *wr_value, uint32_t wr_len) +{ + int i; + int rv; + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + rv = dfd_i2c_gen_write_one_time(i2c_path, dev_addr, addr_bitwidth, offset_addr, wr_value, wr_len); + if (rv < 0) { + DFD_DEBUG_ERROR("(write times:%d)i2c_path:%s, dev_addr:0x%x, addr_bitwidth:%u, offset_addr:0x%x, wr_len:%u\n", + i, i2c_path, dev_addr, addr_bitwidth, offset_addr, wr_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + return rv; +} + +int dfd_utest_i2c_gen_wr(int argc, char* argv[]) +{ + int ret; + uint32_t i2c_bus, dev_addr, addr_bitwidth, offset_addr, data_bitwidth, wr_len, tmp_data, para_len, i, j; + char *stopstring; + char i2c_path[32]; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 8) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_GEN_WR); + goto exit; + } + + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + addr_bitwidth = strtol(argv[4], &stopstring, 10); + offset_addr = strtol(argv[5], &stopstring, 16); + data_bitwidth = strtol(argv[6], &stopstring, 10); + + para_len = argc - 7; + wr_len = para_len * data_bitwidth; + + if (wr_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", wr_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_GEN_WR); + goto exit; + } + + if (data_bitwidth == WIDTH_1Byte) { + for (i = 0; i < para_len; i++) { + wr_value[i] = strtol(argv[7 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value 0x%x\n", i , wr_value[i]); + } + } else { + for (i = 0; i < para_len; i++) { + tmp_data = strtol(argv[7 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value 0x%x\n", i , tmp_data); + for (j = 0; j < data_bitwidth; j++) { + tmp_data = strtol(argv[7 + i], &stopstring, 16); + wr_value[j + i * data_bitwidth] = (tmp_data >> (24 - 8 * j)) & 0xFF; + } + } + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + + ret = dfd_i2c_gen_write(i2c_path, dev_addr, addr_bitwidth, offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("write failed. ret:%d\n", ret); + } else { + printf("write success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_i2c_rd(int argc, char* argv[]) +{ + int ret; + uint8_t value[DFD_UTEST_MAX_RDWR_NUM]; + uint16_t dev_addr, offset_addr; + char *stopstring; + int num, i2c_bus; + char i2c_path[32]; + + if (argc != 6) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_RD); + goto exit; + } + + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + offset_addr = strtol(argv[4], &stopstring, 16); + num = strtol(argv[5], &stopstring, 10); + + if (num > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", num); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + mem_clear(value, sizeof(value)); + ret = dfd_read_port_i2c(i2c_path, dev_addr, offset_addr, value, num); + if (ret < 0) { + printf("failed ret %d\n", ret); + goto exit; + } + + dfd_utest_printf_reg(value, num, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; + +} + +int dfd_utest_i2c_wr(int argc, char* argv[]) +{ + int ret; + uint16_t dev_addr, offset_addr; + char *stopstring; + int i2c_bus; + char i2c_path[32]; + uint8_t wr_len,i; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 6) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_WR); + goto exit; + } + + wr_len = argc - 5; + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + offset_addr = strtol(argv[4], &stopstring, 16); + + for (i = 0; i < wr_len; i++) { + wr_value[i] = strtol(argv[5+i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value %x\n", i , wr_value[i]); + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + + ret = dfd_write_port_i2c(i2c_path, dev_addr, offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_io_rd(int argc, char* argv[]) +{ + int ret; + uint8_t value[DFD_UTEST_MAX_RDWR_NUM]; + uint16_t offset_addr; + char *stopstring; + int num; + + if (argc != 4) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_IO_RD); + goto exit; + } + + offset_addr = strtol(argv[2], &stopstring, 16); + num = strtol(argv[3], &stopstring, 10); + + if (num > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", num); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_IO_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + mem_clear(value, sizeof(value)); + ret = dfd_read_io_port(offset_addr, value, num); + if (ret < 0) { + printf("failed ret %d\n", ret); + goto exit; + } + + dfd_utest_printf_reg(value, num, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_io_wr(int argc, char* argv[]) +{ + int ret; + uint16_t offset_addr; + char *stopstring; + int32_t wr_len,i; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 4) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_IO_WR); + goto exit; + } + + wr_len = argc - 3; + if (wr_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", wr_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_IO_WR); + goto exit; + } + + offset_addr = strtol(argv[2], &stopstring, 16); + + for (i = 0; i < wr_len; i++) { + wr_value[i] = strtol(argv[3 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value %x\n", i , wr_value[i]); + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + ret = dfd_write_io_port(offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_phymem_rd(int argc, char* argv[]) +{ + int ret, width; + uint8_t value[DFD_UTEST_MAX_RDWR_NUM]; + off_t offset_addr; + char *stopstring; + int num; + + if (argc != 5) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_PHYMEM_RD); + goto exit; + } + + width = strtol(argv[2], &stopstring, 10); + offset_addr = strtol(argv[3], &stopstring, 16); + num = strtol(argv[4], &stopstring, 10); + + if (num > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", num); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_PHYMEM_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + mem_clear(value, sizeof(value)); + ret = dfd_process_mem(DEV_MEM_NAME, 0, width, offset_addr, value, num); + if (ret < 0) { + printf("failed ret %d\n", ret); + goto exit; + } + + dfd_utest_printf_reg(value, num, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_phymem_wr(int argc, char* argv[]) +{ + int ret, width; + off_t offset_addr; + char *stopstring; + int32_t wr_len,i; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 5) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_PHYMEM_WR); + goto exit; + } + + wr_len = argc - 4; + if (wr_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", wr_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_PHYMEM_WR); + goto exit; + } + + width = strtol(argv[2], &stopstring, 10); + offset_addr = strtol(argv[3], &stopstring, 16); + + for (i = 0; i < wr_len; i++) { + wr_value[i] = strtol(argv[4 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value %x\n", i , wr_value[i]); + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + ret = dfd_process_mem(DEV_MEM_NAME, 1, width, offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_kmem_rd(int argc, char* argv[]) +{ + int ret, width; + uint8_t value[DFD_UTEST_MAX_RDWR_NUM]; + uint16_t offset_addr; + char *stopstring; + int num; + + if (argc != 5) { + DFD_DEBUG_ERROR("params error\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_KMEM_RD); + goto exit; + } + + width = strtol(argv[2], &stopstring, 10); + offset_addr = strtol(argv[3], &stopstring, 16); + num = strtol(argv[4], &stopstring, 10); + + if (num > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", num); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_KMEM_RD); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + mem_clear(value, sizeof(value)); + ret = dfd_process_mem(DEV_KMEM_NAME, 0, width, offset_addr, value, num); + if (ret < 0) { + printf("failed ret %d\n", ret); + goto exit; + } + + dfd_utest_printf_reg(value, num, offset_addr); + +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_kmem_wr(int argc, char* argv[]) +{ + int ret; + uint16_t offset_addr, width; + char *stopstring; + int32_t wr_len,i; + uint8_t wr_value[DFD_UTEST_MAX_RDWR_NUM]; + + if (argc < 5) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_KMEM_WR); + goto exit; + } + + wr_len = argc - 4; + if (wr_len > DFD_UTEST_MAX_RDWR_NUM) { + DFD_DEBUG_ERROR("Input num %d exceed max.\n", wr_len); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_KMEM_WR); + goto exit; + } + + width = strtol(argv[2], &stopstring, 10); + offset_addr = strtol(argv[3], &stopstring, 16); + + for (i = 0; i < wr_len; i++) { + wr_value[i] = strtol(argv[4 + i], &stopstring, 16); + DFD_DEBUG_DBG(" index :%d value %x\n", i , wr_value[i]); + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + ret = dfd_process_mem(DEV_KMEM_NAME, 1, width, offset_addr, wr_value, wr_len); + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +static unsigned long dfd_utest_get_file_size(const char *path) +{ + unsigned long filesize; + struct stat statbuff; + + if (stat(path, &statbuff) < 0) { + filesize = -1; + } else { + filesize = statbuff.st_size; + } + + return filesize; +} + +int dfd_utest_i2c_file_wr(int argc, char* argv[]) +{ + int ret; + uint16_t dev_addr, offset_addr; + char *stopstring; + int i2c_bus; + char i2c_path[32]; + char *file_name; + unsigned long filesize; + int fd; + uint8_t wr_buf[DFD_UTEST_MAX_RDWR_NUM]; + int len; + int bpt; /* byte per times*/ + int page_left; + + if (argc != 7) { + printf("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_I2C_FILE_WR); + goto exit; + } + + i2c_bus = strtol(argv[2], &stopstring, 10); + dev_addr = strtol(argv[3], &stopstring, 16); + offset_addr = strtol(argv[4], &stopstring, 16); + bpt = strtol(argv[5], &stopstring, 10); + file_name = argv[6]; + + if ((bpt <= 0) || (bpt > DFD_UTEST_MAX_RDWR_NUM)) { + bpt = DFD_UTEST_MAX_RDWR_NUM; + } + + if ((bpt & (bpt - 1)) != 0) { + printf("Bytes per times %d isn't power of two.\n",bpt); + goto exit; + } + + filesize = dfd_utest_get_file_size(file_name); + if (filesize <= 0) { + printf("Input invalid file %s, filesize %lu.\n", file_name, filesize); + goto exit; + } + + fd = open(file_name, O_RDONLY); + if (fd < 0) { + printf("open file[%s] fail.\n", file_name); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_bus); + + while (filesize > 0) { + mem_clear(wr_buf, DFD_UTEST_MAX_RDWR_NUM); + len = bpt; + if (offset_addr & (bpt - 1)) { + page_left = bpt - (offset_addr & (bpt - 1)); + len = len > page_left ? page_left : len; + } + + len = read(fd, wr_buf, len); + + ret = dfd_write_port_i2c(i2c_path, dev_addr, offset_addr, wr_buf, len); + if (ret < 0) { + break; + } + offset_addr += len; + filesize -= len; + } + + close(fd); + + if (ret < 0) { + printf("failed ret %d\n", ret); + } else { + printf("success\n"); + } + +exit: + return DFD_RV_MODE_NOTSUPPORT; + +} + +/* compare with sys_flie_wr, One more step is read back verification */ +int dfd_utest_sysfs_file_upg(int argc, char* argv[]) +{ + int ret = 0; + uint32_t offset_addr; + char *file_name; + char *sysfs_loc; + char *stopstring; + unsigned long filesize; + int fd, file_fd; + uint8_t wr_buf[DFD_UTEST_MAX_RDWR_NUM]; + int len, write_len, per_wr_len; + int i; + uint8_t reread_buf[DFD_UTEST_MAX_RDWR_NUM]; + int reback_len, reread_len; + int j = 0; + + if (argc != 5 && argc != 6) { + printf("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_SYSFS_FILE_UPG); + goto exit; + } + + sysfs_loc = argv[2]; + offset_addr = strtol(argv[3], &stopstring, 16); + file_name = argv[4]; + + if (argc == 6) { + per_wr_len = strtol(argv[5], &stopstring, 10); + if (per_wr_len > DFD_UTEST_MAX_RDWR_NUM || per_wr_len <= 0) { + printf("per_wr_byte %d invalid, not in range (0, 256]\n", per_wr_len); + goto exit; + } + } else { + per_wr_len = DFD_UTEST_DEFAULT_WR_NUM; + } + DFD_DEBUG_DBG("per_wr_byte: %d\n", per_wr_len); + filesize = dfd_utest_get_file_size(file_name); + if (filesize <= 0) { + printf("Input invalid file %s, filesize %lu.\n", file_name, filesize); + goto exit; + } + + fd = open(sysfs_loc, O_RDWR | O_SYNC); + if (fd < 0) { + printf("open file[%s] fail.\n", sysfs_loc); + goto exit; + } + + file_fd = open(file_name, O_RDONLY); + if (file_fd < 0) { + printf("open file[%s] fail.\n", file_name); + goto open_dev_err; + } + + dfd_utest_print_cmd(argc, argv); + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek file[%s offset=%d] fail,\n", sysfs_loc, offset_addr); + goto fail; + } + + printf(":\n"); + while (filesize > 0) { + if (filesize > (unsigned long)per_wr_len) { + len = per_wr_len; + } else { + len = filesize; + } + + mem_clear(wr_buf, DFD_UTEST_MAX_RDWR_NUM); + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + len = read(file_fd, wr_buf, len); + if (len < 0) { + DFD_DEBUG_ERROR("read file[%s] fail, offset = 0x%x retrytimes = %d ret = %d\n", + sysfs_loc, offset_addr, i ,len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == DFD_I2C_RETRY_TIME) { + printf("read file[%s] fail, offset = 0x%x, ret = %d\n", sysfs_loc, offset_addr, len); + goto fail; + } + + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + write_len = write(fd, wr_buf, len); + if (write_len != len) { + DFD_DEBUG_ERROR("write file[%s] fail,offset = 0x%x retrytimes = %d len = %d,write_len =%d\n", + sysfs_loc, offset_addr, i ,len, write_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == DFD_I2C_RETRY_TIME) { + printf("write file[%s] fail, offset = 0x%x, len = %d,write_len =%d\n", + sysfs_loc, offset_addr, len, write_len); + goto fail; + } + + reback_len = write_len; + ret = lseek(fd, -reback_len, SEEK_CUR); + if (ret < 0) { + printf("reread lseek file[%s offset=%d] fail,lseek len=%d\n", + sysfs_loc, offset_addr, reback_len); + goto fail; + } + + mem_clear(reread_buf, DFD_UTEST_MAX_RDWR_NUM); + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + reread_len = read(fd, reread_buf, reback_len); + if (reread_len != reback_len) { + DFD_DEBUG_ERROR("reread file[%s] fail,offset = 0x%x retrytimes = %d reread_len = %d,reback_len =%d\n", + sysfs_loc, offset_addr, i ,reread_len, reback_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == DFD_I2C_RETRY_TIME) { + printf("reread file[%s] fail, offset = 0x%x, reread_len = %d,reback_len = %d\n", + sysfs_loc, offset_addr, reread_len, reback_len); + goto fail; + } + + if (memcmp(reread_buf, wr_buf, reread_len) != 0) { + if (j < DFD_I2C_RETRY_TIME) { + DFD_DEBUG_ERROR("memcmp file[%s] fail,offset = 0x%x retrytimes = %d\n", + sysfs_loc, offset_addr, j); + j++; + ret = lseek(file_fd, -len, SEEK_CUR); + if (ret < 0) { + printf("retry file_fd lseek fail,lseek len=%d\n", len); + goto fail; + } + ret = lseek(fd, -write_len, SEEK_CUR); + if (ret < 0) { + printf("retry fd lseek fail,lseek len=%d\n", write_len); + goto fail; + } + continue; + } + + printf("upgrade file[%s] fail, offset = 0x%x.\n", sysfs_loc, offset_addr); + printf("want to write buf :\n"); + for (i = 0; i < reread_len; i++) { + printf("0x%x ", wr_buf[i]); + } + printf("\n"); + + printf("actually reread buf :\n"); + for (i = 0; i < reread_len; i++) { + printf("0x%x ", reread_buf[i]); + } + printf("\n"); + + goto fail; + } + + offset_addr += len; + filesize -= len; + usleep(5000); + } + + printf("success\n"); + close(file_fd); + close(fd); + return DFD_RV_OK; + +fail: + close(file_fd); +open_dev_err: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_sysfs_file_wr(int argc, char* argv[]) +{ + int ret = 0; + uint32_t offset_addr; + char *file_name; + char *sysfs_loc; + char *stopstring; + unsigned long filesize; + int fd, file_fd; + uint8_t wr_buf[DFD_UTEST_MAX_RDWR_NUM]; + int len, write_len, per_wr_len; + int i; + + if (argc != 5 && argc != 6) { + printf("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_SYSFS_FILE_WR); + goto exit; + } + + sysfs_loc = argv[2]; + offset_addr = strtol(argv[3], &stopstring, 16); + file_name = argv[4]; + + if (argc == 6) { + per_wr_len = strtol(argv[5], &stopstring, 10); + if (per_wr_len > DFD_UTEST_MAX_RDWR_NUM || per_wr_len <= 0) { + printf("per_wr_byte %d invalid, not in range (0, 256]\n", per_wr_len); + goto exit; + } + } else { + per_wr_len = DFD_UTEST_DEFAULT_WR_NUM; + } + DFD_DEBUG_DBG("per_wr_byte: %d\n", per_wr_len); + filesize = dfd_utest_get_file_size(file_name); + if (filesize <= 0) { + printf("Input invalid file %s, filesize %lu.\n", file_name, filesize); + goto exit; + } + + fd = open(sysfs_loc, O_RDWR | O_SYNC); + if (fd < 0) { + printf("open file[%s] fail.\n", sysfs_loc); + goto exit; + } + + file_fd = open(file_name, O_RDONLY); + if (file_fd < 0) { + printf("open file[%s] fail.\n", file_name); + goto open_dev_err; + } + + dfd_utest_print_cmd(argc, argv); + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek file[%s offset=%d] fail,\n", sysfs_loc, offset_addr); + goto fail; + } + + printf(":\n"); + while (filesize > 0) { + if (filesize > (unsigned long)per_wr_len) { + len = per_wr_len; + } else { + len = filesize; + } + + mem_clear(wr_buf, DFD_UTEST_MAX_RDWR_NUM); + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + len = read(file_fd, wr_buf, len); + if (len < 0) { + DFD_DEBUG_ERROR("read file[%s] fail, offset = 0x%x retrytimes = %d ret = %d\n", + sysfs_loc, offset_addr, i ,len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == DFD_I2C_RETRY_TIME) { + printf("read file[%s] fail, offset = 0x%x, ret = %d\n", sysfs_loc, offset_addr, len); + goto fail; + } + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + write_len = write(fd, wr_buf, len); + if (write_len != len) { + DFD_DEBUG_ERROR("write file[%s] fail,offset = 0x%x retrytimes = %d len = %d,write_len =%d\n", sysfs_loc, offset_addr, i ,len, write_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + break; + } + + if(i == DFD_I2C_RETRY_TIME) { + printf("write file[%s] fail, offset = 0x%x, len = %d,write_len =%d\n", sysfs_loc, offset_addr, len, write_len); + ret = -1; + goto fail; + } + offset_addr += len; + filesize -= len; + usleep(5000); + } + + printf("success\n"); + close(file_fd); + close(fd); + return DFD_RV_OK; + +fail: + close(file_fd); +open_dev_err: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_sysfs_file_rd(int argc, char* argv[]) +{ + int ret = 0; + uint32_t offset_addr; + char *sysfs_loc; + char *stopstring; + int fd; + uint8_t rd_buf[DFD_UTEST_MAX_RDWR_NUM]; + int len, read_len;; + + if (argc != 5) { + printf("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_SYSFS_FILE_RD); + goto exit; + } + + sysfs_loc = argv[2]; + offset_addr = strtol(argv[3], &stopstring, 16); + len = strtol(argv[4], &stopstring, 10); + + if (len > DFD_UTEST_MAX_RDWR_NUM) { + printf("Input num %d exceed max 256.\n", len); + goto exit; + } + + fd = open(sysfs_loc, O_RDONLY); + if (fd < 0) { + printf("open file[%s] fail.\n", sysfs_loc); + goto exit; + } + dfd_utest_print_cmd(argc, argv); + + printf(":\n"); + + ret = lseek(fd, offset_addr, SEEK_SET); + if (ret < 0) { + printf("lseek failed ret %d.\n", ret); + goto fail; + } + + mem_clear(rd_buf, DFD_UTEST_MAX_RDWR_NUM); + read_len = read(fd, rd_buf, len); + if (read_len != len) { + printf("read failed read_len %d len %d.\n", read_len, len); + goto fail; + } + dfd_utest_printf_reg(rd_buf, read_len, offset_addr); + close(fd); + return DFD_RV_OK; + +fail: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_msr_rd(int argc, char* argv[]) +{ + int fd; + char msr_file_name[64]; + uint64_t data; + uint64_t read_result; + char *stopstring; + uint8_t cpu_index, width; + uint64_t offset; + + if (argc != 5) { + printf("rdmsr failed: Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_MSR_RD); + goto exit; + } + + cpu_index = strtol(argv[2], &stopstring, 10); + offset = strtol(argv[3], &stopstring, 16); + width = strtol(argv[4], &stopstring, 10); + + if (width != 8 && width != 16 && width != 32 && width != 64) { + printf("rdmsr failed: width:%u Input invalid.only support 8 16 32 64\n", width); + goto exit; + } + + mem_clear(msr_file_name, sizeof(msr_file_name)); + sprintf(msr_file_name, "/dev/cpu/%u/msr", cpu_index); + + fd = open(msr_file_name, O_RDONLY); + if (fd < 0) { + if (errno == ENXIO) { + fprintf(stderr, "rdmsr failed: No CPU %u\n", cpu_index); + } else if (errno == EIO) { + fprintf(stderr, "rdmsr failed: CPU %u doesn't support MSRs\n", cpu_index); + } else if (errno == ENOENT) { + fprintf(stderr, "rdmsr failed: can't find %s file, Please check if modprobe msr driver already\n", msr_file_name); + } else { + printf("rdmsr failed: %s open failed. errno:%d\n", msr_file_name, errno); + } + goto exit; + } + + if (pread(fd, &data, sizeof(data), offset) != sizeof(data)) { + fprintf(stderr, "rdmsr failed: CPU:%u offset:0x%lx read failed\n", cpu_index, offset); + goto fail; + } + + switch (width) { + case 8: + read_result = (volatile uint8_t)data; + break; + case 16: + read_result = (volatile uint16_t)data; + break; + case 32: + read_result = (volatile uint32_t)data; + break; + case 64: + read_result = (volatile uint64_t)data; + break; + default: + printf("rdmsr failed: width:%u illegal width.\n", width); + goto fail; + } + + printf("0x%lx\n", read_result); + close(fd); + return DFD_RV_OK; + +fail: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_utest_sysfs_data_wr(int argc, char* argv[]) +{ + uint32_t offset; + char *sysfs_loc; + char *stopstring; + uint8_t wr_buf[DFD_UTEST_MAX_RDWR_NUM]; + int ret, i; + int fd, len, write_len, index; + + if (argc < 5) { + DFD_DEBUG_ERROR("Input invalid.\n"); + dfd_utest_printf_single_help(DFD_UTEST_ITEM_SYSFS_DATA_WR); + goto exit; + } + + dfd_utest_print_cmd(argc, argv); + printf(":\n"); + + sysfs_loc = argv[2]; + offset = strtol(argv[3], &stopstring, 16); + len = argc - 4; + mem_clear(wr_buf, sizeof(wr_buf)); + for (i = 0; i < len; i++) { + wr_buf[i] = strtol(argv[4 + i], &stopstring, 16); + DFD_DEBUG_DBG("index :%d value %x\n", i , wr_buf[i]); + } + + fd = open(sysfs_loc, O_RDWR | O_SYNC); + if (fd < 0) { + printf("open file[%s] fail.\n", sysfs_loc); + goto exit; + } + + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) { + printf("lseek file[%s offset=%d] fail,\n", sysfs_loc, offset); + goto fail; + } + index = 0; + while (len > 0) { + for (i = 0; i < DFD_I2C_RETRY_TIME; i++) { + write_len = write(fd, &wr_buf[index], len); + if (write_len < 0) { + DFD_DEBUG_ERROR("write file[%s] fail, retrytimes: %d, offset: 0x%x, len: %d, write_len: %d\n", + sysfs_loc, offset, i, len, write_len); + usleep(DFD_I2C_RETRY_SLEEP_TIME); + continue; + } + if (write_len == 0) { + DFD_DEBUG_ERROR("write file[%s] EOF, offset: 0x%x, len: %d, write_len: %d\n", + sysfs_loc, offset, len, write_len); + goto fail; + } + break; + } + if(i == DFD_I2C_RETRY_TIME) { + printf("write file[%s] fail, offset: 0x%x, len: %d, write_len: %d\n", + sysfs_loc, offset, len, write_len); + goto fail; + } + offset += write_len; + index += write_len; + len -= write_len; + usleep(5000); + } + printf("success\n"); + close(fd); + return DFD_RV_OK; +fail: + close(fd); +exit: + return DFD_RV_MODE_NOTSUPPORT; +} + +dfd_utest_proc_fun dfd_utest_get_proc_func(char *type_str) +{ + int i, tbl_size; + + tbl_size = sizeof(g_dfd_unit_test) / sizeof(g_dfd_unit_test[0]); + + for (i = 0; i < tbl_size; i++) { + if (!strncmp(g_dfd_unit_test[i].type_str, type_str, strlen(g_dfd_unit_test[i].type_str))) { + return g_dfd_unit_test[i].utest_func; + } + } + DFD_DEBUG_DBG("type: %s not match.\n", type_str); + return NULL; +} + +void dfd_utest_cmd_main(int argc, char* argv[]) +{ + dfd_utest_proc_fun pfunc; + int ret; + + if (argc < 2) { + dfd_utest_print_all_help(); + return; + } + + pfunc = dfd_utest_get_proc_func(argv[1]); + if (pfunc == NULL) { + DFD_DEBUG_DBG("utest type %s in not support.\n", argv[1]); + dfd_utest_print_all_help(); + return; + } + ret = pfunc(argc, argv); + if ((ret != DFD_RV_MODE_NOTSUPPORT) && (ret != DFD_RV_INDEX_INVALID)) { + if (ret == DFD_RV_OK) { + DFD_DEBUG_DBG(" [SUCCESS]\n"); + } else { + DFD_DEBUG_DBG(" [FAIL(%d)]\n", ret); + } + } + + return; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.h new file mode 100644 index 000000000000..aa194a4dcdd7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/dev_util/dfd_utest.h @@ -0,0 +1,103 @@ +/* monitor_utest.h */ +#ifndef __DFD_UTEST_H__ +#define __DFD_UTEST_H__ + +#include + +extern int g_dfd_debug_sw; +extern int g_dfd_debugpp_sw; + +#define DFD_UTEST_TRUE_FALSE_STRING(flag) ((flag == true) ? "true" : "false") + +#define DFD_DEBUG_DBG(fmt, args...) do { \ + if (g_dfd_debug_sw) { \ + printf("" fmt,\ + ##args); \ + } \ +} while (0) + +#define DFD_DEBUG_ERROR(fmt, args...) do { \ + if (g_dfd_debugpp_sw) { \ + printf("" fmt,\ + ##args); \ + } \ +} while (0) + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef enum dfd_rv_s { + DFD_RV_OK = 0, + DFD_RV_INIT_ERR = 1, + DFD_RV_SLOT_INVALID = 2, + DFD_RV_MODE_INVALID = 3, + DFD_RV_MODE_NOTSUPPORT = 4, + DFD_RV_TYPE_ERR = 5, + DFD_RV_DEV_NOTSUPPORT = 6, + DFD_RV_DEV_FAIL = 7, + DFD_RV_INDEX_INVALID = 8, + DFD_RV_NO_INTF = 9, + DFD_RV_NO_NODE = 10, + DFD_RV_NODE_FAIL = 11, +} dfd_rv_t; + +#define DFD_DEBUG_BUF_LEN (32) +#define DFD_DEBUGP_DEBUG_FILE "/sbin/.dfd_debugp_flag" +#define DFD_DEBUGPP_DEBUG_FILE "/sbin/.dfd_debugpp_flag" + +#define DFD_UTEST_MAX_PARA_NUM (4) +#define DFD_UTEST_TYPE_STRING_LEN (64) +#define DFD_UTEST_MATCH_STRING_LEN (64) +#define DFD_UTEST_HELP_STRING_LEN (256) +#define DFD_UTEST_INVALID_PARA (-1) +#define DFD_UTEST_BUFF_LEN (64) + +typedef enum dfd_fpga_cpld_flag_e { + DFD_CPLD_RW_FLAG = 0x00, + DFD_FPGA_RW_FLAG = 0x01, +} dfd_fpga_cpld_flag_t; + +typedef int (* dfd_utest_proc_fun)(int argc, char* argv[]); + +#define DFD_UTEST_ITEM_ALL \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_RD, i2c_rd, "i2c_rd [i2c_bus] [slave_addr] [offset] [len]", "i2c_rd [i2c_bus] [slave_addr] [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_WR, i2c_wr, "i2c_wr [i2c_bus] [slave_addr] [offset] [data0] ... [dataN]", "i2c_wr [i2c_bus] [slave_addr] [offset] [data0] ... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_IO_RD, io_rd, "io_rd [offset] [len]", "io_rd [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_IO_WR, io_wr, "io_wr [offset] [data0]... [dataN]", "io_wr [offset] [data0]... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_PHYMEM_RD, phymem_rd, "phymem_rd [bit_width] [offset] [len]", "phymem_rd [bit_width] [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_PHYMEM_WR, phymem_wr, "phymem_wr [bit_width] [offset] [data0]... [dataN]", "phymem_wr [bit_width] [offset] [data0]... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_KMEM_RD, kmem_rd, "kmem_rd [bit_width] [offset] [len]", "kmem_rd [bit_width] [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_KMEM_WR, kmem_wr, "kmem_wr [bit_width][offset] [data0]... [dataN]", "kmem_wr [bit_width] [offset] [data0]... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_FILE_WR, i2c_file_wr, "i2c_file_wr [i2c_bus] [slave_addr] [offset] [bpt] [filename]", "i2c_file_wr [i2c_bus] [slave_addr] [offset] [bpt] [filename]\nbpt:bytes per times") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_SYSFS_FILE_WR, sysfs_file_wr, "sysfs_file_wr [sysfs_loc] [offset] [filename] [per_wr_byte]", "sysfs_file_wr [sysfs_loc] [offset] [filename] [per_wr_byte]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_SYSFS_FILE_RD, sysfs_file_rd, "sysfs_file_rd [sysfs_loc] [offset] [len]", "sysfs_file_rd [sysfs_loc] [offset] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_SYSFS_FILE_UPG, sysfs_file_upg, "sysfs_file_upg [sysfs_loc] [offset] [filename] [per_wr_byte]", "sysfs_file_upg [sysfs_loc] [offset] [filename] [per_wr_byte]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_GEN_RD, i2c_gen_rd, "i2c_gen_rd [i2c_bus] [slave_addr] [addr_bitwidth] [offset] [data_bitwidth] [len]", "i2c_gen_rd [i2c_bus] [slave_addr] [addr_bitwidth] [offset] [data_bitwidth] [len]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_I2C_GEN_WR, i2c_gen_wr, "i2c_gen_wr [i2c_bus] [slave_addr] [addr_bitwidth] [offset] [data_bitwidth] [data0]... [dataN]", "i2c_gen_wr [i2c_bus] [slave_addr] [addr_bitwidth] [offset] [data_bitwidth] [data0]... [dataN]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_MSR_RD, msr_rd, "msr_rd [cpu_index] [offset] [width]", "msr_rd [cpu_index] [offset] [width]") \ + DFD_UTEST_ITEM(DFD_UTEST_ITEM_SYSFS_DATA_WR, sysfs_data_wr, "sysfs_data_wr [sysfs_loc] [offset] [data0] ... [dataN]", "sysfs_data_wr [sysfs_loc] [offset] [data0] ... [dataN]]") \ + +#ifdef DFD_UTEST_ITEM +#undef DFD_UTEST_ITEM +#endif +#define DFD_UTEST_ITEM(_id, _type_str, _help_info, _help_info_detail) _id, +typedef enum dfd_utest_item_id_s { + DFD_UTEST_ITEM_ALL +} dfd_utest_item_id_t; + +typedef struct { + int utest_type; + char type_str[DFD_UTEST_TYPE_STRING_LEN]; + dfd_utest_proc_fun utest_func; + char help_info[DFD_UTEST_HELP_STRING_LEN]; + char help_info_detail[DFD_UTEST_HELP_STRING_LEN]; +} dfd_utest_t; + +void dfd_utest_cmd_main(int argc, char* argv[]); + +#ifdef DFD_UTEST_ITEM +#undef DFD_UTEST_ITEM +#endif +#define DFD_UTEST_ITEM(_id, _type_str, _help_info, _help_info_detail) int dfd_utest_##_type_str(int argc, char* argv[]); +DFD_UTEST_ITEM_ALL + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Makefile new file mode 100644 index 000000000000..62663efdbbd5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Makefile @@ -0,0 +1,19 @@ +top_srcdir:=$(shell pwd) +include $(top_srcdir)/Rules.mk + +firmware-y:= +firmware-y += firmware_driver +firmware-y += firmware_upgrade + +.PHONY: all +all: build + +.PHONY: build +build: $(firmware-y) +$(foreach dir,$(firmware-y),$(eval $(call compile_dirs,$(dir)))) + +.PHONY: rpmpkg +rpmpkg: +ifeq ("$(CONFIG_CPLD_UPGRADE_ISPVME)", "y") + #$(RPMPKG) $(install_cpld_dir) firmware-cpld-ispvme.spec git +endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Rules.mk b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Rules.mk new file mode 100644 index 000000000000..5fb5a09d34fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/Rules.mk @@ -0,0 +1,42 @@ +CC ?= $(CROSS)gcc +AR ?= $(CROSS)ar +AS ?= $(CROSS)as +LD ?= $(CROSS)ld +STRIP ?= $(CROSS)strip + +install_root:=${top_srcdir}/images + +install_header_dir:=${install_root}/header +install_adir:=$(install_root)/lib +install_symbol_dir:=$(install_root)/symbol +symbol_files:=$(shell find $(EXPORT_SYMBOL) -name 'Module.symvers') +# +# symbol_files += $(shell find $(install_symbol_dir) -name 'Module.symvers') +# KBUILD_EXTRA_SYMBOLS += $(symbol_files) +# export KBUILD_EXTRA_SYMBOLS + +# top root: install_rootfs_dir +install_rootfs_dir:=$(install_root)/rootfs + +install_sodir:=$(install_rootfs_dir)/$(INSTALL_SODIR) + +install_usr_bin_dir:=$(install_rootfs_dir)/usr/bin +install_sbin_dir:=$(install_rootfs_dir)/sbin +install_etc_dir:=$(install_rootfs_dir)/etc + +export INSTALL_MOD_PATH:=$(ROOT) + +BUILD_CFLAGS:=$(CFLAGS) -I$(install_header_dir) +BUILD_LDFLAGS:=$(LDFLAGS) -L/$(install_sodir) -L/$(install_adir) + +define compile_dirs +.PHONY: $(1) +$(1): + @echo;echo "building $(1)..." + @$(MAKE) -C ${1} +endef + +compile.c = $(CC) $(BUILD_CFLAGS) -d -c -o $@ $< +%.o: %.c + $(compile.c) + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/Makefile new file mode 100644 index 000000000000..e8879aeff5e7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/Makefile @@ -0,0 +1,19 @@ +include $(top_srcdir)/Rules.mk + +firmware-y:= +firmware-y += firmware_driver_ispvme +firmware-y += firmware_driver_cpld +firmware-y += firmware_driver_sysfs + +.PHONY: all +all: build + +.PHONY: build +build: $(firmware-y) +$(foreach dir,$(firmware-y),$(eval $(call compile_dirs,$(dir)))) + +.PHONY: rpmpkg +rpmpkg: +ifeq ("$(CONFIG_CPLD_UPGRADE_ISPVME)", "y") + #$(RPMPKG) $(install_cpld_dir) firmware-cpld-ispvme.spec git +endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/Makefile new file mode 100644 index 000000000000..0add28cb9056 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/Makefile @@ -0,0 +1,23 @@ +#include $(top_srcdir)/debian/rules +#KERNELDIR := ${KBUILD_OUTPUT} + +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../include) +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) +EXTRA_CFLAGS+= -Wall + +firmware_driver_cpld-objs := firmware.o +firmware_driver_cpld-objs += firmware_cpld.o firmware_cpld_upgrade.o +firmware_driver_cpld-objs += jbicomp.o jbijtag.o jbimain.o jbistub.o + +#ifndef CONFIG_FRM_PRODUCT_FILE + +$(warning $(firmware_driver_cpld-objs)) +obj-m := firmware_driver_cpld.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(common_module_dir) ]; then mkdir -p $(common_module_dir) ;fi + cp -p $(PWD)/*.ko $(common_module_dir) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware.c new file mode 100644 index 000000000000..db72b369465a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware.c @@ -0,0 +1,144 @@ +#include +#include +#include + +int g_firmware_driver_debug = 0; +module_param(g_firmware_driver_debug, int, S_IRUGO | S_IWUSR); + +static LIST_HEAD(drv_list); +static LIST_HEAD(dev_list); + +/** + * firmware_driver_register + * function:Registered Device Driver + * @fw_drv:param[in] Driver information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_driver_register(firmware_driver_t *fw_drv) +{ + int ret; + + if (fw_drv == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Parameter error.\n"); + return FIRMWARE_FAILED; + } + + ret = platform_driver_register(fw_drv->drv); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: failed to register firmware upgrade driver \n"); + return FIRMWARE_FAILED; + } + + /* Adds driver information to the driver list */ + list_add(&fw_drv->list, &drv_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware upgrade driver register sucess \n"); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_driver_unregister + * function:unregister Device Driver + * @fw_drv:param[in] Driver information + */ +void firmware_driver_unregister(firmware_driver_t *fw_drv) +{ + list_del_init(&fw_drv->list); + platform_driver_unregister(fw_drv->drv); +} + +/* + * firmware_get_device_by_minor + * function: Get device information based on minor + */ +firmware_device_t *firmware_get_device_by_minor(int minor) +{ + firmware_device_t *tmp; + + list_for_each_entry(tmp, &dev_list, list) { + if (tmp->dev.minor == minor) { + return tmp; + } + } + + return NULL; +} + +/** + * firmware_device_register + * function:Registered Driver Device + * @fw_dev: param[in] Driver information + * return value:success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_device_register(firmware_device_t *fw_dev) +{ + int ret; + firmware_device_t *tmp; + + if (fw_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Parameter error.\n"); + return FIRMWARE_FAILED; + } + /* Check whether the device file name already exists in the device linked list */ + list_for_each_entry(tmp, &dev_list, list) { + if (strcmp(tmp->name, fw_dev->name) == 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("devie %s already exists.\n", fw_dev->name); + return FIRMWARE_FAILED; + } + } + + /* Registere device */ + ret = misc_register(&fw_dev->dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("register misc error, ret=%d.\n", ret); + return FIRMWARE_FAILED; + } + + /* Adds a device to the device list */ + list_add(&fw_dev->list, &dev_list); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_device_unregister + * function: unregister Driver Device + */ +void firmware_device_unregister(firmware_device_t *fw_dev) +{ + list_del(&fw_dev->list); + misc_deregister(&fw_dev->dev); +} + +static int __init firmware_driver_init(void) +{ + int ret; + + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver init.\n"); + ret = firmware_cpld_init(); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware driver init failed.\n"); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +static void __exit firmware_driver_exit(void) +{ + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver exit.\n"); + firmware_cpld_exit(); + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + return; +} + +module_init(firmware_driver_init); +module_exit(firmware_driver_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Firmware upgrade driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld.c new file mode 100644 index 000000000000..18ec509d0f2e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld.c @@ -0,0 +1,384 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int firmware_cpld_open(struct inode *inode, struct file *file) +{ + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Open cpld device.\n"); + frm_dev = firmware_get_device_by_minor(MINOR(inode->i_rdev)); + if (frm_dev == NULL) { + return -ENXIO; + } + file->private_data = frm_dev; + + return FIRMWARE_SUCCESS; +} + +static ssize_t firmware_cpld_read (struct file *file, char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static ssize_t firmware_cpld_write (struct file *file, const char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static loff_t firmware_cpld_llseek(struct file *file, loff_t offset, int origin) +{ + return 0; +} + +/* + * firmware_cpld_ioctl + * function: ioctl command parsing function + * @file: param[in] device file name + * @cmd: param[in] command + * @arg: param[in] the parameters in the command + * return value: success-FIRMWARE_SUCCESS; fail:other value + */ +static long firmware_cpld_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + char *buf; + void __user *argp; + char version[FIRMWARE_NAME_LEN]; + char chip_name[FIRMWARE_NAME_LEN]; + cmd_info_t cmd_info; + firmware_device_t *frm_dev; + firmware_cpld_t *cpld_info; + + /* Get device private data */ + mem_clear(&cmd_info, sizeof(cmd_info_t)); + frm_dev = (firmware_device_t *)file->private_data; + cpld_info = NULL; + if (frm_dev != NULL) { + if (frm_dev->priv != NULL) { + cpld_info = (firmware_cpld_t *)frm_dev->priv; + } + } + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to frm_dev->priv sysfs info.\n"); + return FIRMWARE_FAILED; + } + argp = (void __user *)arg; + + switch (cmd) { + case FIRMWARE_GET_CHIPNAME: + /* get chip name */ + if (copy_from_user(&cmd_info, argp, sizeof(cmd_info_t))) { + return -EFAULT; + } + mem_clear(chip_name, FIRMWARE_NAME_LEN); + ret = fmw_cpld_upg_get_chip_name(frm_dev->chain, cpld_info, chip_name, FIRMWARE_NAME_LEN); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get chip name.\n"); + return -ENXIO; + } + if (copy_to_user(cmd_info.data, chip_name, cmd_info.size)) { + return -EFAULT; + } + break; + case FIRMWARE_PROGRAM: + case FIRMWARE_PROGRAM_JBI: + /* firmware upgrade */ + if (copy_from_user(&cmd_info, argp, sizeof(cmd_info_t))) { + return -EFAULT; + } + buf = (char *) kzalloc(cmd_info.size + 1, GFP_KERNEL); + if (buf == NULL) { + return -ENOMEM; + } + if (copy_from_user(buf, cmd_info.data, cmd_info.size)) { + kfree(buf); + return -EFAULT; + } + buf[cmd_info.size] = 0; + if (cmd == FIRMWARE_PROGRAM_JBI) { + /* JBI firmware upgrade */ + ret = fmw_cpld_upg_program_jbi(frm_dev->chain, cpld_info, buf, cmd_info.size); + } else { + /* ISC firmware upgrade */ + ret = fmw_cpld_upg_program(frm_dev->chain, cpld_info, buf, cmd_info.size); + } + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to program cpld.\n"); + kfree(buf); + return -ESRCH; + } + kfree(buf); + break; + case FIRMWARE_GET_VERSION: + /* get version */ + if (copy_from_user(&cmd_info, argp, sizeof(cmd_info_t))) { + return -EFAULT; + } + mem_clear(version, FIRMWARE_NAME_LEN); + ret = fmw_cpld_upg_get_version(frm_dev->chain, cpld_info, version, FIRMWARE_NAME_LEN); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get version.\n"); + return -ENXIO; + } + if (copy_to_user(cmd_info.data, version, cmd_info.size)) { + return -EFAULT; + } + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("not find cmd: %d\r\n", cmd); + return -ENOTTY; + } /* End of switch */ + + return FIRMWARE_SUCCESS; +} + +static int firmware_cpld_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations cpld_dev_fops = { + .owner = THIS_MODULE, + .llseek = firmware_cpld_llseek, + .read = firmware_cpld_read, + .write = firmware_cpld_write, + .unlocked_ioctl = firmware_cpld_ioctl, + .open = firmware_cpld_open, + .release = firmware_cpld_release, +}; + +static int of_firmware_upgrade_config_init(struct device *dev, firmware_cpld_t *cpld_info) +{ + int ret; + char *name; + int i; + char buf[64]; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_upgrade_config_init\r\n"); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + mem_clear(cpld_info, sizeof(firmware_cpld_t)); + ret = 0; + ret += of_property_read_string(dev->of_node, "type", (const char **)&name); + ret += of_property_read_u32(dev->of_node, "tdi", &cpld_info->tdi); + ret += of_property_read_u32(dev->of_node, "tck", &cpld_info->tck); + ret += of_property_read_u32(dev->of_node, "tms", &cpld_info->tms); + ret += of_property_read_u32(dev->of_node, "tdo", &cpld_info->tdo); + + ret += of_property_read_u32(dev->of_node, "chain", &cpld_info->chain); + ret += of_property_read_u32(dev->of_node, "chip_index", &cpld_info->chip_index); + + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config error, ret:%d.\n", ret); + return -ENXIO; + } + + strncpy(cpld_info->type, name, sizeof(cpld_info->type) - 1); + + ret = of_property_read_u32(dev->of_node, "tck_delay", &cpld_info->tck_delay); + if(ret != 0) { + cpld_info->tck_delay = 60; + } + + cpld_info->gpio_en_info_num = 0; + /* Enable through GPIO */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_gpio_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &cpld_info->gpio_en_info[i].en_gpio); + if(ret != 0) { + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_level_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &cpld_info->gpio_en_info[i].en_level); + if(ret != 0) { + break; + } + cpld_info->gpio_en_info_num++; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("type:%s, chain:%u, chip_index:%u, en_info_num:%u\n", + cpld_info->type, cpld_info->chain, cpld_info->chip_index, cpld_info->gpio_en_info_num); + FIRMWARE_DRIVER_DEBUG_VERBOSE("tdi:%u, tck:%u, tms:%u, tdo:%u tck_delay:%u.\n", + cpld_info->tdi, cpld_info->tck, cpld_info->tms, cpld_info->tdo, cpld_info->tck_delay); + + return 0; +} + +static int firmware_upgrade_config_init(struct device *dev, firmware_cpld_t *cpld_info) +{ + int i; + + firmware_upgrade_device_t *firmware_upgrade_device; + firmware_jtag_device_t jtag_upg_device; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_upgrade_config_init\r\n"); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + if (dev->platform_data == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("platform data config error.\n"); + return -1; + } + firmware_upgrade_device = dev->platform_data; + jtag_upg_device = firmware_upgrade_device->upg_type.jtag; + + mem_clear(cpld_info, sizeof(firmware_cpld_t)); + + strncpy(cpld_info->type, firmware_upgrade_device->type, sizeof(cpld_info->type) - 1); + cpld_info->tdi = jtag_upg_device.tdi; + cpld_info->tck = jtag_upg_device.tck; + cpld_info->tms = jtag_upg_device.tms; + cpld_info->tdo = jtag_upg_device.tdo; + cpld_info->chain = firmware_upgrade_device->chain; + cpld_info->chip_index = firmware_upgrade_device->chip_index; + + if (jtag_upg_device.tck_delay == 0) { + cpld_info->tck_delay = 60; + FIRMWARE_DRIVER_DEBUG_VERBOSE("no config tck_delay, use default value:%u\n", cpld_info->tck_delay); + } else { + cpld_info->tck_delay = jtag_upg_device.tck_delay; + } + + if (firmware_upgrade_device->en_gpio_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_gpio_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_gpio_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + cpld_info->gpio_en_info_num = firmware_upgrade_device->en_gpio_num; + /* Enable through GPIO */ + for (i = 0; i < cpld_info->gpio_en_info_num; i++) { + cpld_info->gpio_en_info[i].en_gpio = firmware_upgrade_device->en_gpio[i]; + cpld_info->gpio_en_info[i].en_level = firmware_upgrade_device->en_level[i]; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("type:%s, chain:%u, chip_index:%u, en_info_num:%u\n", + cpld_info->type, cpld_info->chain, cpld_info->chip_index, cpld_info->gpio_en_info_num); + FIRMWARE_DRIVER_DEBUG_VERBOSE("tdi:%u, tck:%u, tms:%u, tdo:%u tck_delay:%u.\n", + cpld_info->tdi, cpld_info->tck, cpld_info->tms, cpld_info->tdo, cpld_info->tck_delay); + + return 0; +} + +static int firmware_cpld_probe(struct platform_device *pdev) +{ + int ret; + firmware_cpld_t *cpld_info; + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_cpld_probe\r\n"); + /* Gets the information in the device tree */ + cpld_info = devm_kzalloc(&pdev->dev, sizeof(firmware_cpld_t), GFP_KERNEL); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc cpld device tree.\n"); + return -EPERM; + } + + if (pdev->dev.of_node) { + ret = of_firmware_upgrade_config_init(&pdev->dev, cpld_info); + } else { + ret = firmware_upgrade_config_init(&pdev->dev, cpld_info); + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("get config init from dts error.\n"); + return -EPERM; + } + + frm_dev = devm_kzalloc(&pdev->dev, sizeof(firmware_device_t), GFP_KERNEL); + if (frm_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc firmware device.\n"); + return -EPERM; + } + + /* Based on the link number, determine the name of the device file */ + frm_dev->chain = cpld_info->chain; + snprintf(frm_dev->name, FIRMWARE_NAME_LEN - 1, "firmware_cpld%d", frm_dev->chain); + strncpy(cpld_info->devname, frm_dev->name, strlen(frm_dev->name) + 1); + + INIT_LIST_HEAD(&frm_dev->list); + frm_dev->dev.minor = MISC_DYNAMIC_MINOR; + frm_dev->dev.name = frm_dev->name; + frm_dev->dev.fops = &cpld_dev_fops; + frm_dev->priv = cpld_info; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Register cpld firmware chain:%d, name:%s.\n", frm_dev->chain, frm_dev->name); + + ret = firmware_device_register(frm_dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to register firmware device.\n"); + return -EPERM; + } + + platform_set_drvdata(pdev, frm_dev); + return 0; +} + +static int __exit firmware_cpld_remove(struct platform_device *pdev) +{ + firmware_device_t *frm_dev; + + frm_dev = (firmware_device_t *)platform_get_drvdata(pdev); + firmware_device_unregister(frm_dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct of_device_id cpld_match[] = { + { + .compatible = "firmware_cpld", + }, + {}, +}; + +static struct platform_driver cpld_driver = { + .driver = { + .name = "firmware_cpld", + .owner = THIS_MODULE, + .of_match_table = cpld_match, + }, + .probe = firmware_cpld_probe, + .remove = firmware_cpld_remove, +}; + +static firmware_driver_t fmw_drv_cpld = { + .name = "firmware_cpld", + .drv = &cpld_driver, +}; + +int firmware_cpld_init(void) +{ + int ret; + + INIT_LIST_HEAD(&fmw_drv_cpld.list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("cpld upgrade driver register \n"); + ret = firmware_driver_register(&fmw_drv_cpld); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("cpld upgrade driver register failed.\n"); + return ret; + } + return 0; +} + +void firmware_cpld_exit(void) +{ + firmware_driver_unregister(&fmw_drv_cpld); + INIT_LIST_HEAD(&fmw_drv_cpld.list); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld_upgrade.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld_upgrade.c new file mode 100644 index 000000000000..8252c2a39bb2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/firmware_cpld_upgrade.c @@ -0,0 +1,1879 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* CPLD file parses the relevant parameters */ +#define CPLD_HEX 16 +#define DEC_VAL 10 +#define CPLD_INIT_CNT 4 +#define CPLD_UNIT_SZ 4 +#define CPLD_HEAD_KEYWORD "Header" +#define CPLD_NAME_KEYWORD "Entity" +#define CPLD_INIT_KEYWORD "INITIALIZE" +#define CPLD_REPEAT_KEYWORD "REPEAT" +#define CPLD_END_CHAR ',' + +/* TCK clock MAX 16MHz */ +#define TCK_DELAY (current_fmw_cpld->tck_delay) + +/* + * The instruction format of the MAX II CPLD is 10 bits + * For shift_ir state machine use + */ +#define BYPASS 0x3FF +#define EXTEST 0xF +#define SAMPLE 0x5 +#define IDCODE 0x6 +#define USERCODE 0x7 +#define CLAMP 0xA +#define HIGHZ 0xB + +/* Following 7 instructions are IEEE 1532 instructions */ +#define ISC_ENABLE 0x2CC +#define ISC_DISABLE 0x201 +#define ISC_PROGRAM 0x2F4 +#define ISC_ERASE 0x2F2 +#define ISC_ADDRESS_SHIFT 0x203 +#define ISC_READ 0x205 +#define ISC_NOOP 0x210 + +/* + * MAX II devices support the real-time in-system programmability (ISP) + * feature that allows you to program the device while it is still in operation. + * when there is either a power cycle to the device (powering down and powering + * up again) or with the execution of certain ISP instructions to start the SRAM + * download process when realtime ISP has completed. + */ +#define RT_ISC_ENABLE 0x199 +#define RT_ISC_DISABLE 0x166 + +/* Chip ID */ +#define EPM240_G 0x020A10DD +#define EPM570_G 0x020A20DD +#define EPM1270_G 0x020A30DD +#define EPM2210_G 0x020A40DD +#define EPM240_Z 0x020A50DD +#define EPM570_Z 0x020A60DD + +/* The size of the output data for ID validation */ +#define VERIFY_IDCODE_SIZE 0x5 + +/* Erasure and programmatic delay handling */ +#define ERASE_DELAY 0x1024 +#define PROGRAM_DELAY 0x5 + +/* Chip instruction register */ +#define CPLD_INSTRUCTION_SIZE 10 + +/* + * Currently, only two connectors are supported + * The size of the instruction register needs to be changed + * when more than two connectors are used + */ +#ifndef CPLD_MAX_CHIP +#define CPLD_MAX_CHIP 2 +#endif + +typedef struct cpld_chip_id { + char *name; + uint id; + int addr_register_length; + int data_register_length; + int eeprom_array_length; + int first_blank_check_length; + int second_blank_check_length; + int first_erase_addr; + int second_erase_addr; + int third_erase_addr; + int verify_idcode_addr; +} cpld_chip_id_t; + +static cpld_chip_id_t cpld_id_table[] = { + {"EPM240T100", EPM240_G, 13, 16, 4604, 3327, 511, 0x0, 0x1, 0x11, 0x89}, + {"EPM570T144", EPM570_G, 14, 16, 8700, 3327, 511, 0x0, 0x1, 0x21, 0x111}, + {"EPM1270F256", EPM1270_G, 15, 16, 16892, 16383, 511, 0x0, 0x1, 0x41, 0x221}, + {"5M240Z", EPM240_Z, 13, 16, 4604, 3327, 511, 0x0, 0x1, 0x11, 0x89}, + {"5M570Z", EPM570_Z, 14, 16, 8700, 3327, 511, 0x0, 0x1, 0x21, 0x111}, + {NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + +static cpld_chip_id_t *chip_cpld_info = NULL; + +/* The following variables are used when cascading multiple chips */ +static int chip_num, current_chip_index; +static firmware_cpld_t *current_fmw_cpld; + +static int TDI_PULL_UP(void); +static int TDI_PULL_DOWN(void); +static int TMS_PULL_UP(void); +static int TMS_PULL_DOWN(void); +static int TCK_PULL_UP(void); +static int TCK_PULL_DOWN(void); + +/* + * set_currrent_cpld_info + * function: Save the current device information + * @info: param[in] Information about the device to be updated + */ +static void set_currrent_cpld_info(firmware_cpld_t *info) +{ + current_fmw_cpld = info; +} + +/* + * firmware_upgrade_en + * function: Upgrade access enabling switch + * @flag: !0:enable 0:disable + */ +static int firmware_upgrade_en(int flag) +{ + int i; + int ret; + + for (i = 0; i < current_fmw_cpld->gpio_en_info_num; i++) { + if (flag) { + ret = gpio_request(current_fmw_cpld->gpio_en_info[i].en_gpio, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade EN[%d] GPIO[%d] failed!\n", + i, current_fmw_cpld->gpio_en_info[i].en_gpio); + goto free_gpio; + } + gpio_direction_output(current_fmw_cpld->gpio_en_info[i].en_gpio, current_fmw_cpld->gpio_en_info[i].en_level); + current_fmw_cpld->gpio_en_info[i].flag = 1; + } else { + gpio_set_value(current_fmw_cpld->gpio_en_info[i].en_gpio, !current_fmw_cpld->gpio_en_info[i].en_level); + gpio_free(current_fmw_cpld->gpio_en_info[i].en_gpio); + current_fmw_cpld->gpio_en_info[i].flag = 0; + } + } + return 0; +free_gpio: + for (i = 0; i < current_fmw_cpld->gpio_en_info_num; i++) { + if (current_fmw_cpld->gpio_en_info[i].flag == 1) { + gpio_set_value(current_fmw_cpld->gpio_en_info[i].en_gpio, !current_fmw_cpld->gpio_en_info[i].en_level); + gpio_free(current_fmw_cpld->gpio_en_info[i].en_gpio); + current_fmw_cpld->gpio_en_info[i].flag = 0; + } else { + break; + } + } + + return -1; +} + +/* + * init_cpld + * function:Initialize CPLD + * return value: 0 success ; -1 fail + */ +static int init_cpld(void) +{ + int ret; + + if (current_fmw_cpld == NULL) { + return -1; + } + mdelay(10); + ret = gpio_request(current_fmw_cpld->tdi, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_upgrade TDI GPIO failed!\n"); + return ret; + } + ret = gpio_request(current_fmw_cpld->tck, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_upgrade TCK GPIO failed!\n"); + goto free_tdi; + } + ret = gpio_request(current_fmw_cpld->tms, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_upgrade TMS GPIO failed!\n"); + goto free_tck; + } + ret = gpio_request(current_fmw_cpld->tdo, "cpld_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_upgrade TDO GPIO failed!\n"); + goto free_tms; + } + + gpio_direction_output(current_fmw_cpld->tdi, 1); + gpio_direction_output(current_fmw_cpld->tck, 1); + gpio_direction_output(current_fmw_cpld->tms, 1); + + gpio_direction_input(current_fmw_cpld->tdo); + ret = firmware_upgrade_en(1); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: open firmware upgrade en failed, ret %d.\n", ret); + goto free_tdo; + } + + /* test GPIO */ + if (TDI_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TDI_PULL_UP failed.\n"); + goto free_tdo; + } + if (TDI_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TDI_PULL_DOWN failed.\n"); + goto free_tdo; + } + if (TMS_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TMS_PULL_UP failed.\n"); + goto free_tdo; + } + if (TMS_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TMS_PULL_DOWN failed.\n"); + goto free_tdo; + } + if (TCK_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TCK_PULL_UP failed.\n"); + goto free_tdo; + } + if (TCK_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TCK_PULL_DOWN failed.\n"); + goto free_tdo; + } + + mdelay(10); + return 0; + +free_tdo: + gpio_free(current_fmw_cpld->tdo); +free_tms: + gpio_free(current_fmw_cpld->tms); +free_tck: + gpio_free(current_fmw_cpld->tck); +free_tdi: + gpio_free(current_fmw_cpld->tdi); + return ret; +} + +/* + * finish_cpld + * function: finish CPLD upgrade operation + * return value: 0 success ; -1 fail + */ +static int finish_cpld(void) +{ + int ret; + + if (current_fmw_cpld == NULL) { + return -1; + } + mdelay(10); + ret = firmware_upgrade_en(0); + if (ret < 0){ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: close firmware upgrade en failed, ret %d.\r\n", ret); + } + + gpio_free(current_fmw_cpld->tdi); + gpio_free(current_fmw_cpld->tck); + gpio_free(current_fmw_cpld->tms); + gpio_free(current_fmw_cpld->tdo); + mdelay(10); + return 0; +} + +/* Loop waiting for */ +static int pull_wait(int gpio, int value) { + int i, j; + /* Timeout time is two seconds */ + for (i = 0; i < 20; i++) { + for (j = 0; j < 100; j++) { + if (!!gpio_get_value(gpio) == !!value ) { + return 0; + } + /* The first loop does not delay, normally the first loop can immediately return the result */ + if (i) { + mdelay(1); + } + } + /* The CPU is released every 100ms */ + schedule(); + } + /* timeout */ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Wait gpio %d pull to %d failed.\n", gpio, value); + return -1; +} + +/* TDI pull-up */ +static int pull_tdi_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tdi, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tdi, 1); +} + +/* TDI pull-down */ +static int pull_tdi_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tdi, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tdi, 0); +} + +/* TCK pull-up */ +static int pull_tck_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tck, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tck, 1); +} + +/* TCK pull-down */ +static int pull_tck_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tck, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tck, 0); +} + +/* TMS pull-up */ +static int pull_tms_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tms, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tms, 1); +} + +/* TMS pull-down */ +static int pull_tms_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tms, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tms, 0); +} + +/* Read TDO */ +static int read_tdo(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + return gpio_get_value(current_fmw_cpld->tdo); +} + +static firmware_cpld_function_t function_fmw_cpld = { + .pull_tdi_up = pull_tdi_up, + .pull_tdi_down = pull_tdi_down, + .pull_tck_up = pull_tck_up, + .pull_tck_down = pull_tck_down, + .pull_tms_up = pull_tms_up, + .pull_tms_down = pull_tms_down, + .read_tdo = read_tdo, + .init_cpld = init_cpld, + .finish_cpld = finish_cpld, +}; + +/* + * TDI_PULL_DOWN + * function: Lower TDI + */ +static int TDI_PULL_DOWN(void) +{ + if ( function_fmw_cpld.pull_tdi_down != NULL) { + return function_fmw_cpld.pull_tdi_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDI_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TDI_PULL_UP + * function: High TDI + */ +static int TDI_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tdi_up != NULL) { + return function_fmw_cpld.pull_tdi_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDI_PULL_UP.\n"); + return -1; + } +} + +/* + * TCK_PULL_DOWN + * function: Lower TCK + */ +static int TCK_PULL_DOWN(void) +{ + if (function_fmw_cpld.pull_tck_down != NULL) { + return function_fmw_cpld.pull_tck_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TCK_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TCK_PULL_UP + * function: High TCK + */ +static int TCK_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tck_up != NULL) { + return function_fmw_cpld.pull_tck_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TCK_PULL_UP.\n"); + return -1; + } +} + +/* + * TMS_PULL_DOWN + * function: Lower TMS + */ +static int TMS_PULL_DOWN(void) +{ + if (function_fmw_cpld.pull_tms_down != NULL) { + return function_fmw_cpld.pull_tms_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TMS_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TMS_PULL_UP + * function: High TMS + */ +static int TMS_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tms_up != NULL) { + return function_fmw_cpld.pull_tms_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TMS_PULL_UP.\n"); + return -1; + } +} + +/* + * TDO_READ + * function:Read the TDO level + */ +static int TDO_READ(void) +{ + if (function_fmw_cpld.read_tdo != NULL) { + return function_fmw_cpld.read_tdo(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDO_READ.\n"); + return -1; + } +} + +/* + * tap_test_logic_reset + * function: reset JTAG + * No matter what the original state of the controoler, it will enter + * Test_Logic_Reset when TMS is held high for at least five rising + * edges of TCK (16MHz) + * The controller remains in this state while TMS is high + */ +static void tap_test_logic_reset(void) +{ + int i; + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + + for (i = 0; i < 5; i++) { + TCK_PULL_UP(); + ndelay(TCK_DELAY); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + } + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_run_test_idle + * function: A controller state between scan operations.Once entered, the controller + * will remain in the Run_Test/Idle state as long as TMS is held low. + */ +static void tap_run_test_idle(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_select_dr_scan + * function :This is a temporary controller state in which all test data registers + * selected by the current instruction retain their previous state. + */ +static void tap_select_dr_scan(void) +{ + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_capture_dr + * function : In this controller state data may be parallel-loaded into test data + * register selected by the current instruction on the rising edge of TCK + */ +static void tap_capture_dr(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_shift_dr + * function: In this controller state.the test data register connected between TDI + * and TDO as a result of the current instruction shifts one stage + * toward its serial output on each rising edge of TCK. + */ +static void tap_shift_dr(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_exit1_dr + * function: This is a temporary controller state. + */ +static void tap_exit1_dr(int data) +{ + int j; + if (data) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + + /* need to idle here */ + for (j = 1; j < current_chip_index; j++) { + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + } + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_update_dr + * function : Some test data registers may be provided with a latched parallel output to + * prevent changes at the parallel out-put while data is shifted in the + * associated whift-register path in response to certain instructions.Data is + * latched onto the parallel output of these test data registers from the + * shift-register path on the falling edge of TCK in the Update-DR controler state. + */ +static void tap_update_dr(void) +{ + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_select_ir_scan + * function:This is a temporarily controler state in which all test data register selected + * by the current instruction retain their previous state. + */ +static void tap_select_ir_scan(void) +{ + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_capture_ir + * function :In this controller state the shift-register contained in the instruction + * register loads a pattern of fixed logic values on the rising edge of + * TCK.design-specific data may be loaded into shift-register stages that + * are not required to be set to fixed values. + */ +static void tap_capture_ir(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_exit1_ir + * function : enter exit1 ir state. This is a temporary controller state. + */ +static void tap_exit1_ir(int data) +{ + if (data) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * tap_shift_ir + * function: In this controller state the shift-register contained in the instruction + * register is connected between TDI and TDO and shifts data one stage + * toward its serial output on each rising edge of TCK. + */ +static void tap_shift_ir(void) +{ + TMS_PULL_DOWN(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +/* + * The instruction shifted into the instruction register is latched onto the parallel output + * from the shift-register path on the falling edge of TCK in this controller state.Once the + * new instruction has been latched,it becomes the current instruction. + * + */ +static void tap_update_ir(void) +{ + TMS_PULL_UP(); + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); +} + +static void tap_send_instruction(int instruction, int ins_len) +{ + int i; + for (i = 0; i < (ins_len - 1); i++) { + if (instruction & 0x1) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + instruction = instruction >> 1; + } +} + +static void tap_send_data(int data, int data_len) +{ + int i; + for (i = 0; i < (data_len - 1); i++) { + if (data & 0x1) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + data = data >> 1; + } +} + +/* + * tap_rcv_byte + * function : Receive data from the device side + * @data : param[out] Received data */ +static void tap_rcv_byte(u8 *data) +{ + int i; + u8 rec_data = 0; + unsigned char tmp; + ndelay(TCK_DELAY); + for (i = 0; i < 8; i++) { + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + tmp = TDO_READ(); + rec_data |= (tmp << i); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + } + *data = rec_data; +} + +/* + * tap_idle + * function :Used for state machine idling + */ +static void tap_idle(void) +{ + int i; + for (i = 0; i < 0x100; i++) { + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + + /* Timely release of CPU */ + schedule(); + } +} + +/* + * jtag_read_data + * function :Read the JTAG output data + * @size: param[in] buffer size + * @data: param[out] read data buffer + */ +static void jtag_read_data(u8 *buf, int size) +{ + int i, j; + /* JTAG state switching */ + tap_run_test_idle(); + tap_select_dr_scan(); + tap_capture_dr(); + tap_shift_dr(); + for (j = current_chip_index; j < chip_num; j++) { + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + TCK_PULL_UP(); + ndelay(TCK_DELAY); + } + /* Receive data from the device side */ + for (i = 0; i < size; i++) { + tap_rcv_byte(&buf[i]); + } + /* JTAG state switching */ + tap_exit1_dr(0); + tap_update_dr(); + tap_run_test_idle(); +} + +/* + * jtag_send_instruction + * function :JTAG instruction sending interface + * @instruction: param[in] Instruction to be sent + * @ins_length: param[in] Instruction length + */ +static void jtag_send_instruction(int instruction, int ins_length) +{ + int i, j; + i = 1 << (ins_length - 1); + /* JTAG state switching */ + tap_run_test_idle(); + tap_select_dr_scan(); + tap_select_ir_scan(); + tap_capture_ir(); + tap_shift_ir(); + + for (j = chip_num; j > 1; j--) { + if (j == current_chip_index) { + tap_send_instruction(instruction, ins_length + 1); + } else { + tap_send_instruction(BYPASS, ins_length + 1); + } + } + + if (current_chip_index == 1) { + tap_send_instruction(instruction, ins_length); + /* Gets the highest bit of the instruction */ + tap_exit1_ir((instruction & i) >> (ins_length - 1)); + } else { + tap_send_instruction(BYPASS, ins_length); + /* Gets the highest bit of the instruction */ + tap_exit1_ir((BYPASS & i) >> (ins_length - 1)); + } + + /* JTAG state switching */ + tap_update_ir(); + tap_run_test_idle(); +} + +/* + * jtag_send_data + * function :JTAG data sending interface + * @buf : param[in] Data that needs to be sent + * @data_length: param[in] Data length + */ +static void jtag_send_data(unsigned int buf, int data_length) +{ + int i; + i = 1 << (data_length - 1); + + /* JTAG state switching */ + tap_run_test_idle(); + tap_select_dr_scan(); + tap_capture_dr(); + tap_shift_dr(); + tap_send_data(buf, data_length); + /* Gets the highest bit of the instruction */ + tap_exit1_dr((buf & i) >> (data_length - 1)); + tap_update_dr(); + tap_run_test_idle(); +} + +/* + * jtag_program_donebit + * JTAG programming end point */ +static void jtag_program_donebit(void) +{ + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + + switch (chip_cpld_info->id) { + case EPM240_G: + case EPM570_G: + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x7BFF, chip_cpld_info->data_register_length); + tap_idle(); + break; + case EPM1270_G: + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x7FFF, chip_cpld_info->data_register_length); + tap_idle(); + + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0xFFFF, chip_cpld_info->data_register_length); + tap_idle(); + + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0xFFBF, chip_cpld_info->data_register_length); + tap_idle(); + + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0xFFFF, chip_cpld_info->data_register_length); + tap_idle(); + break; + default: + break; + } /* End of switch */ +} + +/* + * jtag_rt_disable + * JTAG Disable state machine under Real-Time ISP + */ +static void jtag_rt_disable(void) +{ + jtag_send_instruction(RT_ISC_DISABLE, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_instruction(BYPASS, CPLD_INSTRUCTION_SIZE); + tap_idle(); +} + +/* + * jtag_verify_idcode + * function :JTAG internal ID reading + */ +static void jtag_verify_idcode(void) +{ + int data, i; + u8 buf[2]; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(chip_cpld_info->verify_idcode_addr, + chip_cpld_info->addr_register_length); + tap_idle(); + for (i = 0; i < VERIFY_IDCODE_SIZE; i++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + + /* When validating the ID, the data is compared to the corresponding chip value, + which is retrieved from the BSDL file*/ + data = (buf[1] << 8) | buf[0]; + } +} + +/* + * jtag_rt_enable + * Enter Real-Time ISP mode; JTAG Enable State Machine under Real-Time ISP + */ +static void jtag_rt_enable(void) +{ + jtag_send_instruction(RT_ISC_ENABLE, CPLD_INSTRUCTION_SIZE); + tap_idle(); +} + +/* + * jtag_erase + * JTAG erases the timing + */ +static void jtag_erase(void) +{ + int i; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(chip_cpld_info->first_erase_addr, + chip_cpld_info->addr_register_length); + tap_idle(); + jtag_send_instruction(ISC_ERASE, CPLD_INSTRUCTION_SIZE); + tap_idle(); + for (i = 0; i < ERASE_DELAY; i++) { + tap_idle(); + tap_idle(); + } + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(chip_cpld_info->second_erase_addr, + chip_cpld_info->addr_register_length); + tap_idle(); + jtag_send_instruction(ISC_ERASE, CPLD_INSTRUCTION_SIZE); + tap_idle(); + for (i = 0; i < ERASE_DELAY; i++) { + tap_idle(); + tap_idle(); + } + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(chip_cpld_info->third_erase_addr, + chip_cpld_info->addr_register_length); + tap_idle(); + jtag_send_instruction(ISC_ERASE, CPLD_INSTRUCTION_SIZE); + tap_idle(); + for (i = 0; i < ERASE_DELAY; i++) { + tap_idle(); + tap_idle(); + } +} + +/* + * jtag_blank_check + * JTAG blank detection */ +static void jtag_blank_check(void) +{ + int j; + int data; + u8 buf[2]; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < chip_cpld_info->first_blank_check_length; j++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + data = (buf[1] << 8) | buf[0]; + } + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x1, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < chip_cpld_info->second_blank_check_length; j++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + data = (buf[1] << 8) | buf[0]; + } +} + +/* + * jtag_verify1 + * function :JTAG content validation + * @buffer : param[in] original data + * return value 0 validation success; -1 validation failed + */ +static int jtag_verify1(unsigned int *buffer) +{ + int j, ret = 0; + unsigned int data; + u8 buf[2]; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < chip_cpld_info->eeprom_array_length; j++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + data = (buf[1] << 8) | buf[0]; + + if (data != buffer[j]) { + FIRMWARE_DRIVER_DEBUG_ERROR("%d: %02x, %02x.\n", j, data, buffer[j]); + ret = -1; + break; + } + } + return ret; +} + +/* + * jtag_read_buffer + * function:JTAG internal data reading + * @size: param[in] Read size + * @buffer: param[out] Pointer to read data + */ +static void jtag_read_buffer(unsigned int *buffer, int size) +{ + int j; + int data; + u8 buf[2]; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < size; j++) { + jtag_send_instruction(ISC_READ, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_read_data(buf, 2); + data = (buf[1] << 8) | buf[0]; + buffer[j] = data; + } +} + +/* + * jtag_program + * function:JTAG programming timing + * @buffer: param[in] data pointer to program + */ +static void jtag_program(unsigned int *buffer) +{ + int i, j; + + jtag_send_instruction(ISC_ADDRESS_SHIFT, CPLD_INSTRUCTION_SIZE); + tap_idle(); + jtag_send_data(0x0, chip_cpld_info->addr_register_length); + tap_idle(); + for (j = 0; j < chip_cpld_info->eeprom_array_length; j++) { + jtag_send_instruction(ISC_PROGRAM, CPLD_INSTRUCTION_SIZE); + tap_idle(); + + jtag_send_data(buffer[j], chip_cpld_info->data_register_length); + for (i = 0; i < PROGRAM_DELAY; i++) { + tap_idle(); + tap_idle(); + } + } +} + +/* + * cpld_read_id + * function: CPLD chip ID read + * @chip: param[in] chip index + * id : param[out] ID point */ +static void cpld_read_id(int chip, unsigned int *id) +{ + u8 data[sizeof(int)]; + if (!chip_num || chip > chip_num) { + return; + } + current_chip_index = chip; + /* Send instructions */ + jtag_send_instruction(IDCODE, CPLD_INSTRUCTION_SIZE); + /* Read Data */ + jtag_read_data(data, sizeof(int)); + *id = (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]; +} + +/* + * chip_num_init + * function:CPLD number of chips initialized */ +static void chip_num_init(void) +{ + unsigned int i, id; + unsigned char buf[sizeof(int) * CPLD_MAX_CHIP]; + chip_num = 0; + + /* JTAG state switching */ + tap_run_test_idle(); + tap_select_dr_scan(); + tap_capture_dr(); + tap_shift_dr(); + + for (i = 0; i < sizeof(int) * CPLD_MAX_CHIP; i++) { + tap_rcv_byte(&buf[i]); + } + + /* JTAG state switching */ + tap_exit1_dr(0); + tap_update_dr(); + tap_run_test_idle(); + + for (i = 0; i < sizeof(int) * CPLD_MAX_CHIP; i += 4) { + id = (buf[i + 3] << 24) | (buf[i + 2] << 16) | (buf[i + 1] << 8) | buf[i]; + FIRMWARE_DRIVER_DEBUG_VERBOSE("ID: %04x\n", id); + if (id != 0xFFFFFFFF && id != 0) { + chip_num++; + } + } +} + +/* + * cpld_reset + * function: reset JTAG + * @chip: param[in] chip index + */ +static void cpld_reset(int chip) +{ + unsigned int chip_type_id = 0; + int i; + /* JTAG enters the reset state */ + tap_test_logic_reset(); + /* Gets the number of chips in the CPLD */ + chip_num_init(); + if (!chip_num) { + pr_notice("There is no CPLD chip or the chip is not supported!!\r\n"); + FIRMWARE_DRIVER_DEBUG_ERROR("chip_num == NULL.\n"); + } else { + FIRMWARE_DRIVER_DEBUG_VERBOSE("enter cpld read id.\n"); + current_chip_index = chip; + /* Read chip ID */ + cpld_read_id(current_chip_index, &chip_type_id); + FIRMWARE_DRIVER_DEBUG_VERBOSE("get cpld id: 0x%x.\n", chip_type_id); + for (i = 0; cpld_id_table[i].name != NULL; i++) { + if (cpld_id_table[i].id == chip_type_id) { + chip_cpld_info = &cpld_id_table[i]; + break; + } + } + } + current_chip_index = -1; + tap_test_logic_reset(); +} + +/* + * cpld_program + * function: CPLD programming interface + * @chip: param[in] Chip serial number/chip index + * @buffer: param[in] data pointer to program + * return value: 0 success; -1 fail + */ +static int cpld_program(int chip, unsigned int *buffer) +{ + int ret; + int counte; + + if (!chip_num || chip > chip_num + || chip_cpld_info == NULL) { + return -1; + } + current_chip_index = chip; + + /* Enter Real-Time ISP mode */ + jtag_rt_enable(); + /* JTAG internal ID reading */ + jtag_verify_idcode(); + /* JTAG erases */ + jtag_erase(); + /* JTAG blank detection */ + jtag_blank_check(); + /* JTAG programming timing */ + jtag_program(buffer); + + /* In the process of upgrade, there is a problem with reading data, + * which may occur in the process of reading. Some bit reading fails, + * but the reason is not found. + * Avoidance resolution: perform multiple checks */ + for (counte = 0; counte < 4; counte++) { + ret = jtag_verify1(buffer); + if (counte > 0) { + pr_notice("Verify again(%d).\n", counte + 1); + } + + if (ret == 0) { + break; + } + } + pr_notice("Write chip %d cpld success(%d).\n", chip, ret); + jtag_program_donebit(); + + /* JTAG Disable state machine under Real-Time ISP */ + jtag_rt_disable(); + + return ret; +} + +static void cpld_read_buffer(int chip, unsigned int *buffer, unsigned int size) +{ + if (!chip_num || chip > chip_num + || chip_cpld_info == NULL) { + return; + } + current_chip_index = chip; + + /* Enter Real-Time ISP mode */ + jtag_rt_enable(); + + /* JTAG internal ID reading */ + jtag_verify_idcode(); + + /* JTAG internal data reading */ + jtag_read_buffer(buffer, size); + + jtag_rt_disable(); + +} + +/* + * cpld_eeprom_size + * function:CPLD chip capacity size + * return value :Returns chip capacity on success, or 0 on failure + */ +static int cpld_eeprom_size(void) +{ + int ret; + + if (!chip_num || chip_cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("chip_num:%d or chip_cpld_info == NULL.\n", chip_num); + ret = 0; + } else { + ret = chip_cpld_info->eeprom_array_length; + FIRMWARE_DRIVER_DEBUG_ERROR("chip_cpld_info->eeprom_array_length = %d.\n", + chip_cpld_info->eeprom_array_length); + } + + return ret; +} + +/* + * cpld_read_name + * function: Gets the CPLD chip name + * @chip: param[in] Chip serial number/chip index + * return value :chip name */ +static char *cpld_read_name(int chip) +{ + uint chip_type_id; + int i; + + chip_type_id = 0; + cpld_read_id(chip, &chip_type_id); + for (i = 0; cpld_id_table[i].name != NULL; i++) { + if (cpld_id_table[i].id == chip_type_id) { + return cpld_id_table[i].name; + } + } + + return NULL; +} + +/* + * cpld_upgrade_init + * function:Initialize GPIO and CPLD + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int cpld_upgrade_init(void) +{ + int ret; + + if (function_fmw_cpld.init_cpld != NULL) { + ret = function_fmw_cpld.init_cpld(); + if (ret != FIRMWARE_SUCCESS) { + return ret; + } + } + + return FIRMWARE_SUCCESS; +} + +/* + * cpld_upgrade_finish + * function:Release GPIO and CPLD + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int cpld_upgrade_finish(void) +{ + int ret; + + if (function_fmw_cpld.finish_cpld != NULL) { + ret = function_fmw_cpld.finish_cpld(); + if (ret != FIRMWARE_SUCCESS) { + return ret; + } + } + + return FIRMWARE_SUCCESS; +} + +static int cpld_str_hex_to_dec(char *str, char end_char) +{ + int i; + int result; + + if (str == NULL) { + return FIRMWARE_FAILED; + } + + i = 0; + result = 0; + while (str[i] != end_char) { + /* Check for hexadecimal characters:0123456789abcdef */ + if (!isxdigit(str[i]) || i >= CPLD_UNIT_SZ) { + return FIRMWARE_FAILED; + } + /* Check for a number between 0 and 9 */ + if (isdigit(str[i])) { + result = result * CPLD_HEX + str[i] - '0'; + } + /* Check if the character is uppercase */ + else if (isupper(str[i])) { + result = result * CPLD_HEX + str[i] - 'A' + DEC_VAL; + } else { + result = result * CPLD_HEX + str[i] - 'a' + DEC_VAL; + } + + i++; + } + + return result; +} + +static int cpld_check_upgrade_data(char *src, int src_len, int *dst, int dst_len) +{ + int i, init_lcnt, tmp; + char *ptr; + int ret; + + if (src == NULL || dst == NULL) { + return FIRMWARE_FAILED; + } + /* Pointers the ptr pointer to the data following the CPLD_INIT_KEYWORD */ + ret = FIRMWARE_SUCCESS; + ptr = strstr(src, CPLD_INIT_KEYWORD); + if (ptr == NULL) { + return FIRMWARE_FAILED; + } else { + ptr += strlen(CPLD_INIT_KEYWORD); + while (*ptr == '(' || *ptr == '\r' || *ptr == '\n') { + ptr++; + } + } + + /* Converts a hexadecimal string to decimal, with 4 groups of 4 bytes each */ + i = 0; + init_lcnt = 0; + for (init_lcnt = 0; init_lcnt < CPLD_INIT_CNT; init_lcnt++) { + tmp = cpld_str_hex_to_dec(ptr, CPLD_END_CHAR); + if (tmp < 0) { + ret = tmp; + return ret; + } + /* int type is 4 bytes */ + dst[i++] = tmp; + if (i >= dst_len) { + return FIRMWARE_SUCCESS; + } + + ptr += CPLD_UNIT_SZ + 1; + + while (*ptr == '\r' || *ptr == '\n') { + ptr++; + } + } + + /* Point the ptr pointer to the data after CPLD_REPEAT_KEYWORD */ + ptr = strstr(src, CPLD_REPEAT_KEYWORD); + if (ptr == NULL) { + return FIRMWARE_FAILED; + } else { + ptr += strlen(CPLD_REPEAT_KEYWORD); + while (*ptr == '(' || *ptr == '\r' || *ptr == '\n') { + ptr++; + } + } + + while (1) { + /* Converts the 4 bytes before ',' to base 10 */ + tmp = cpld_str_hex_to_dec(ptr, CPLD_END_CHAR); + if (tmp < 0) { + ret = tmp; + break; + } + dst[i++] = tmp; + if (i >= dst_len) { + return FIRMWARE_SUCCESS; + } + + ptr += CPLD_UNIT_SZ + 1; + + while (*ptr == '\r' || *ptr == '\n') { + ptr++; + } + } + + return FIRMWARE_SUCCESS; +} + +/** + * fmw_cpld_upg_get_chip_name + * function:get chip name + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @len: param[in] chip name length + * @info: param[out] chip name + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_get_chip_name(int chain, firmware_cpld_t *cpld, char *info, int len) +{ + int ret; + char *name; + + /* Check the input and output parameters */ + if (chain < 0 || info == NULL || len <= 0) { + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to get chip name.\n"); + + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit." + "(chain = %d, current chain = %d, current name: %s)\n", + chain, current_fmw_cpld->chain, current_fmw_cpld->devname); + } + + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error:Failed to get chip name when init upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + /* reset JTAG */ + cpld_reset(current_fmw_cpld->chip_index); + /* Read chip name */ + name = cpld_read_name(current_fmw_cpld->chip_index); + if (name == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to get chip name when read name.(chain %d, index %d)\n", + chain, current_fmw_cpld->chip_index); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + /* Release GPIO */ + ret = cpld_upgrade_finish( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to get chip name when finish upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + strncpy(info, name, len); + + return FIRMWARE_SUCCESS; +} + +/** + * fmw_cpld_upg_program + * function:Upgrade CPLD(ISC file format) + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @info: param[in] Data to be written + * @len: param[in] Length of data to be written + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_program(int chain, firmware_cpld_t *cpld, char *info, int len) +{ + int i; + int time; + int ret; + int target_len; + int *target_buf; + + /* Check the input parameters */ + if (chain < 0 || info == NULL || len <= 0) { + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to program chip.\n"); + + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit.(chain = %d, current chain = %d)\n", + chain, current_fmw_cpld->chain); + } + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program when init upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + /* reset JTAG */ + cpld_reset(current_fmw_cpld->chip_index); + /* CPLD chip capacity size */ + target_len = cpld_eeprom_size(); + if (target_len <= 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to get cpld size.(chain = %d)\n", + chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + target_buf = (int *) kzalloc(target_len * sizeof(int), GFP_KERNEL); + if (target_buf == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to malloc target buffer.(chain = %d)\n", + chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("cpld_check_upgrade_data start.(chain = %d, %d)\n", + chain, target_len); + /* Remove extraneous information */ + ret = cpld_check_upgrade_data(info, len, target_buf, target_len); + if (ret < 0){ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to check data.(chain = %d)\n", + chain); + kfree(target_buf); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + for (i = 0; i < 16 * 8; i += 8) { + FIRMWARE_DRIVER_DEBUG_VERBOSE(" %x %x %x %x %x %x %x %x\n", + target_buf[i], target_buf[i + 1], + target_buf[i + 2], target_buf[i + 3], + target_buf[i + 4], target_buf[i + 5], + target_buf[i + 6], target_buf[i + 7]); + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("cpld_check_upgrade_data finish.(chain = %d)\n", chain); + + /* CPLD device writing */ + for (time = 0; time < 10; time++) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("Start upgrade cpld: %d.(chain = %d)\n", time, chain); + ret = cpld_program(current_fmw_cpld->chip_index, target_buf); + if (ret >= 0) { + break; + } + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program.(chain = %d)\n", chain); + kfree(target_buf); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("SUCCESS PROGRAM.\n"); + + /* Release GPIO */ + ret = cpld_upgrade_finish(); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to program when finish upgrade.(chain = %d)\n", + chain); + } + + kfree(target_buf); + return FIRMWARE_SUCCESS; +} + +/** + * fmw_cpld_upg_program_jbi + * function: Upgrade CPLD(JBI file format) + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @info: param[in] Data to be written + * @len: param[in] Length of data to be written + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_program_jbi(int chain, firmware_cpld_t *cpld, char *info, int len) +{ + int time, ret; + int argc = 3; + char *argv[] = { + "-r", + "-aprogram", + "-ddo_real_time_isp=1" + }; + + /* Check the input parameters */ + if (chain < 0 || info == NULL || len <= 0) { + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to program chip %d(%p,%p,%d).\n", + chain, cpld, info, len); + + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit.(chain = %d, current chain = %d)\n", + chain, current_fmw_cpld->chain); + } + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program when init upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + /* reset JTAG */ + cpld_reset(current_fmw_cpld->chip_index); + + for (time = 0; time < 30; time++) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("Start upgrade cpld: %d.(chain = %d)\n", time, chain); + ret = jbi_main((unsigned char *) info, (unsigned long) len, argc, argv); + if (ret == 0) { + break; + } + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program.(chain = %d)\n", chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + FIRMWARE_DRIVER_DEBUG_VERBOSE("SUCCESS PROGRAM.\n"); + + /* Release GPIO and CPLD */ + ret = cpld_upgrade_finish( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to program when finish upgrade.(chain = %d)\n", + chain); + } + + return FIRMWARE_SUCCESS; +} + +/** + * fmw_cpld_upg_get_version + * function: get version + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @len: param[in] Data length + * @info: param[out] Version information buffer + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_get_version(int chain, firmware_cpld_t *cpld, char *info, int len) +{ + int ret; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to get version.\n"); + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit.(chain = %d, current chain = %d)\n", + chain, current_fmw_cpld->chain); + } + + /* CPLD device can't get version */ + if (function_fmw_cpld.get_version != NULL) { + ret = function_fmw_cpld.get_version(chain, info, len); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed get version in chain: %d.\n", chain); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("The get_version is NULL in chain: %d.\n", chain); + } + + return FIRMWARE_FAILED; +} + +/** + * fmw_cpld_upg_get_chip_info + * function: Get chip content + * @chain: param[in] chain + * @cpld: param[in] Device private data + * @len: param[in] Data length + * @info: param[out] Read Data Buffer + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int fmw_cpld_upg_get_chip_info(int chain, firmware_cpld_t *cpld, void *info, int len) +{ + int i; + int ret; + int target_len; + int *target_buf; + + /* Check input and output parameters */ + if (chain < 0 || info == NULL || len <= 0) { + return FIRMWARE_FAILED; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to read chip.\n"); + + if (cpld == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to get gpio info.(chain = %d)\n", chain); + } else { + set_currrent_cpld_info(cpld); + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Cpld driver to read chip: %s.\n",current_fmw_cpld->devname); + if (chain != current_fmw_cpld->chain) { + FIRMWARE_DRIVER_DEBUG_ERROR("The chain num is not fit.(chain = %d, current chain = %d)\n", + chain, current_fmw_cpld->chain); + } + + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to program when init upgrade.(chain = %d)\n", + chain); + return FIRMWARE_FAILED; + } + + /* reset JTAG*/ + cpld_reset(current_fmw_cpld->chip_index); + /* CPLD chip capacity size */ + target_len = cpld_eeprom_size(); + if (target_len <= 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to get cpld size.(chain = %d)\n", + chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + + target_buf = (int *) kzalloc(target_len * sizeof(int), GFP_KERNEL); + if (target_buf == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to malloc target buffer.(chain = %d)\n", + chain); + cpld_upgrade_finish( ); + return FIRMWARE_FAILED; + } + /* Read chip */ + cpld_read_buffer(current_fmw_cpld->chip_index, target_buf, target_len); + + for (i = 0; i < 16 * 8; i += 8) { + FIRMWARE_DRIVER_DEBUG_VERBOSE(" %x %x %x %x %x %x %x %x\n", + target_buf[i], target_buf[i + 1], + target_buf[i + 2], target_buf[i + 3], + target_buf[i + 4], target_buf[i + 5], + target_buf[i + 6], target_buf[i + 7]); + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Success Read.\n"); + + /* Release GPIO and CPLD */ + ret = cpld_upgrade_finish( ); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to program when finish upgrade.(chain = %d)\n", + chain); + } + + if (copy_to_user(info, target_buf, (len > target_len) ? target_len : len)) { + kfree(target_buf); + return FIRMWARE_FAILED; + } + + kfree(target_buf); + return FIRMWARE_SUCCESS; +} + +/** + * jbi_jtag_io_ + * function: JBI GPIO operation + * @tms: param[in] TMS signal level + * @tdi: param[in] TDI signal level + * @read_tdo: param[in] Whether to read the level of the TDO + * return value : tdo + */ +int __attribute__ ((weak)) jbi_jtag_io_(int tms, int tdi, int read_tdo) +{ + int tdo = 0; + + if (tms) { + TMS_PULL_UP(); + } else { + TMS_PULL_DOWN(); + } + + if (tdi) { + TDI_PULL_UP(); + } else { + TDI_PULL_DOWN(); + } + + TCK_PULL_UP(); + ndelay(TCK_DELAY); + + if (read_tdo) { + tdo = TDO_READ(); + } + + TCK_PULL_DOWN(); + ndelay(TCK_DELAY); + + return tdo; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware.h new file mode 100644 index 000000000000..3a6ab117df5d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware.h @@ -0,0 +1,82 @@ +#ifndef __FIRMWARE_H__ +#define __FIRMWARE_H__ + +#include +#include + +#include + +/* Debug switch level */ +typedef enum { + FIRWMARE_VERBOSE, + FIRWMARE_WARN, + FIRWMARE_ERROR, + FIRWMARE_END, +} firmware_debug_level_t; + +#define FIRMWARE_DRIVER_DEBUG_VERBOSE(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_VERBOSE)) { \ + printk(KERN_INFO "[FIRMWARW_DRIVER_CPLD][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_DRIVER_DEBUG_ERROR(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_ERROR)) { \ + printk(KERN_ERR "[FIRMWARW_DRIVER_CPLD][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_NAME_LEN 48 + +#define FIRMWARE_FAILED (-1) +#define FIRMWARE_SUCCESS 0 + +/* ioctl publi command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_COMMON_TYPE 'C' +#define FIRMWARE_GET_CHIPNAME _IOR(FIRMWARE_COMMON_TYPE, 0, char) /* get the chip name */ +#define FIRMWARE_GET_VERSION _IOR(FIRMWARE_COMMON_TYPE, 2, int) /* get version */ + +/* firmware cpld driver ioctl command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_TYPE 'J' +#define FIRMWARE_PROGRAM _IOW(FIRMWARE_TYPE, 1, char) /* firmware upgrade ISC */ +#define FIRMWARE_READ_CHIP _IOR(FIRMWARE_TYPE, 5, int) /* read the contents of the chip */ +#define FIRMWARE_PROGRAM_JBI _IOW(FIRMWARE_TYPE, 6, char) /* firmware upgrade JBI */ + +typedef struct cmd_info_s { + uint32_t size; + void __user *data; +} cmd_info_t; + +typedef struct firmware_device_s { + struct list_head list; /* device list */ + uint32_t chain; /* chain number */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct miscdevice dev; /* device */ + void *priv; /* private data */ +} firmware_device_t; + +typedef struct firmware_driver_s { + struct list_head list; /* list */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct platform_driver *drv; /* driver */ + void *priv; /* private data */ +} firmware_driver_t; + +extern int g_firmware_driver_debug; + +/* Get device information based on minor */ +extern firmware_device_t *firmware_get_device_by_minor(int minor); +/* Registere device */ +extern int firmware_device_register(firmware_device_t *fw_dev); +/* Unregister device */ +extern void firmware_device_unregister(firmware_device_t *fw_dev); +/* Registere driver */ +extern int firmware_driver_register(firmware_driver_t *fw_drv); +/* Unregister driver */ +extern void firmware_driver_unregister(firmware_driver_t *fw_drv); +/* CPLD upgrade initialized */ +extern int firmware_cpld_init(void); +/* CPLD unload function */ +extern void firmware_cpld_exit(void); + +#endif /* end of __FIRMWARE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware_cpld.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware_cpld.h new file mode 100644 index 000000000000..ef69655a4b2e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/firmware_cpld.h @@ -0,0 +1,64 @@ +#ifndef __FIRMWARE_CPLD_H__ +#define __FIRMWARE_CPLD_H__ + +#define FIRMWARE_DEV_NAME_LEN 32 +#define FIRMWARE_MAX_CPLD_NUM 16 +#define FIRMWARE_TYPE_LEN 10 +#define FIRMWARE_EN_INFO_MAX 16 +#define FIRMWARE_EN_INFO_BUF 128 + +typedef struct firmware_gpio_jtag_en_s { + uint32_t en_gpio; /* GPIO enable pin */ + uint32_t en_level; /* GPIO enable level */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_gpio_jtag_en_t; + +typedef struct firmware_cpld_s { + char devname[FIRMWARE_DEV_NAME_LEN]; /* Device name */ + char type[FIRMWARE_TYPE_LEN]; /* interface type */ + uint32_t tdi; /* TDI signal corresponding to GPIO pin information */ + uint32_t tck; /* TCK signal corresponding to GPIO pin information */ + uint32_t tms; /* TMS signal corresponding to GPIO pin information */ + uint32_t tdo; /* TDO signal corresponding to GPIO pin information */ + uint32_t chain; /* chain num */ + uint32_t chip_index; /* chip index */ + uint32_t tck_delay; /* Delay time */ + uint32_t gpio_en_info_num; /* GPIO Enable Number */ + firmware_gpio_jtag_en_t gpio_en_info[FIRMWARE_EN_INFO_MAX]; /* GPIO Enable Information */ +} firmware_cpld_t; + +typedef struct firmware_cpld_function_s{ + int (*pull_tdi_up)(void); /* TDI pull-up */ + int (*pull_tdi_down)(void); /* TDI pull-down */ + int (*pull_tck_up)(void); /* TCK pull-up */ + int (*pull_tck_down)(void); /* TCK pull-down */ + int (*pull_tms_up)(void); /* TMS pull-up */ + int (*pull_tms_down)(void); /* TCK pull-down */ + int (*read_tdo)(void); /* Read TDO */ + int (*init_cpld)(void); /* CPLD upgrade initializes the operation */ + int (*init_chip)(int chain); /* chip initializes the operation */ + int (*finish_chip)(int chain); /* chip completes the operation*/ + int (*finish_cpld)(void); /* CPLD upgrade completes the operation */ + int (*get_version)(int chain, char *ver, int len); /* get version */ +}firmware_cpld_function_t; + +/* get chip name */ +extern int fmw_cpld_upg_get_chip_name(int chain, firmware_cpld_t *cpld, char *info, int len); +/* ISC firmware upgrad */ +extern int fmw_cpld_upg_program(int chain, firmware_cpld_t *cpld, char *info, int len); +/* get version */ +extern int fmw_cpld_upg_get_version(int chain, firmware_cpld_t *cpld, char *info, int len); +/* Read the contents of Chip */ +extern int fmw_cpld_upg_get_chip_info(int chain, firmware_cpld_t *cpld, void *info, int len); +/* operate TDI */ +extern int fwm_cpld_tdi_op(int value); +/* operate TCK */ +extern int fwm_cpld_tck_op(int value); +/* operate TMS */ +extern int fwm_cpld_tms_op(int value); +/* operate TDO */ +extern int fwm_cpld_tdo_op(void); +/* JBI firmware upgrad */ +extern int fmw_cpld_upg_program_jbi(int chain, firmware_cpld_t *cpld, char *info, int len); + +#endif /* __FIRMWARE_CPLD_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/jbi.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/jbi.h new file mode 100644 index 000000000000..865c8d352174 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/include/jbi.h @@ -0,0 +1,15 @@ +#ifndef __JBI_H__ +#define __JBI_H__ + +#include + +/* JTAG operation interface*/ +extern int jbi_jtag_io_(int tms, int tdi, int read_tdo); +/* delay function */ +extern void jbi_jtag_udelay(unsigned long us); +/* Debug switch */ +extern int jbi_debug(int level); +/* JBI upgrade function */ +extern int jbi_main(unsigned char *addr, unsigned long size, int argc, char * const argv[]); + +#endif /* __JBI_JTAG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.c new file mode 100644 index 000000000000..064d0ae50ec4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.c @@ -0,0 +1,438 @@ +/****************************************************************************/ +/* */ +/* Module: jbicomp.c */ +/* */ +/* Copyright (C) Altera Corporation 1997-2001 */ +/* */ +/* Description: Contains the code for compressing and uncompressing */ +/* Boolean array data. */ +/* */ +/* This algorithm works by searching previous bytes in the */ +/* data that match the current data. If a match is found, */ +/* then the offset and length of the matching data can */ +/* replace the actual data in the output. */ +/* */ +/* Revisions: 2.2 fixed /W4 warnings */ +/* */ +/****************************************************************************/ + +#include "jbiport.h" +#include "jbiexprt.h" +#include "jbicomp.h" +#include "jbistub.h" + +#define SHORT_BITS 16 +#define CHAR_BITS 8 +#define DATA_BLOB_LENGTH 3 +#define MATCH_DATA_LENGTH 8192 +#define JBI_ACA_REQUEST_SIZE 1024 +#define JBI_ACA_BUFFER_SIZE (MATCH_DATA_LENGTH + JBI_ACA_REQUEST_SIZE) + +unsigned long jbi_in_length = 0L; +unsigned long jbi_in_index = 0L; /* byte index into compressed array */ +unsigned int jbi_bits_avail = CHAR_BITS; + +#if PORT == DOS +int jbi_current_variable_id = -1; +int jbi_current_page = -1; +int jbi_version = 0; +unsigned long jbi_out_length = 0L; +unsigned int jbi_out_index = 0; /* byte index into jbi_aca_out_buffer[] */ +unsigned long jbi_aca_in_offset = 0L; +unsigned char jbi_aca_out_buffer[JBI_ACA_BUFFER_SIZE]; +#endif + +/****************************************************************************/ +/* */ +/* The following functions implement incremental decompression of Boolean */ +/* array data, using a small memory window. */ +/* */ +/* This algorithm works by searching previous bytes in the data that match */ +/* the current data. If a match is found, then the offset and length of */ +/* the matching data can replace the actual data in the output. */ +/* */ +/* Memory usage is reduced by maintaining a "window" buffer which contains */ +/* the uncompressed data for one 8K page, plus some extra amount specified */ +/* by JBI_ACA_REQUEST_SIZE. The function jbi_uncompress_page() is used to */ +/* request a subrange of the uncompressed data, starting at a particular */ +/* bit position and extending a maximum of JBI_ACA_REQUEST_SIZE bytes. */ +/* */ +/****************************************************************************/ + +/****************************************************************************/ +/* */ + +unsigned int jbi_bits_required(unsigned int n) + +/* */ +/* Description: Calculate the minimum number of bits required to */ +/* represent n. */ +/* */ +/* Returns: Number of bits. */ +/* */ +/****************************************************************************/ +{ + unsigned int result = SHORT_BITS; + + if (n == 0) + { + result = 1; + } + else + { + /* Look for the highest non-zero bit position */ + while ((n & (1 << (SHORT_BITS - 1))) == 0) + { + n <<= 1; + --result; + } + } + + return (result); +} + +/****************************************************************************/ +/* */ + +unsigned int jbi_read_packed +( +#if PORT!=DOS + unsigned char *buffer, +#endif + unsigned int bits +) + +/* */ +/* Description: Read the next value from the input array "buffer". */ +/* Read only "bits" bits from the array. The amount of */ +/* bits that have already been read from "buffer" is */ +/* stored internally to this function. */ +/* */ +/* Returns: Up to 16 bit value. -1 if buffer overrun. */ +/* */ +/****************************************************************************/ +{ + unsigned int result = 0; + unsigned int shift = 0; + unsigned int databyte = 0; + + while (bits > 0) + { +#if PORT==DOS + databyte = GET_BYTE(jbi_aca_in_offset + jbi_in_index); +#else + databyte = buffer[jbi_in_index]; +#endif + result |= (((databyte >> (CHAR_BITS - jbi_bits_avail)) + & (0xFF >> (CHAR_BITS - jbi_bits_avail))) << shift); + + if (bits <= jbi_bits_avail) + { + result &= (0xFFFF >> (SHORT_BITS - (bits + shift))); + jbi_bits_avail -= bits; + bits = 0; + } + else + { + ++jbi_in_index; + shift += jbi_bits_avail; + bits -= jbi_bits_avail; + jbi_bits_avail = CHAR_BITS; + } + } + + return (result); +} + +#if PORT==DOS + +/****************************************************************************/ +/* */ + +void jbi_uncompress_next_page(int version) + +/* */ +/* Description: Uncompresses one page of compressed data, using */ +/* data page as reference for repeated sections. */ +/* Overwrites previous page of data in buffer. */ +/* */ +/* Returns: TRUE for success, FALSE if error encountered */ +/* */ +/****************************************************************************/ +{ + unsigned int i, j, offset, length; + unsigned int end_index; + unsigned long tmp_in_index = jbi_in_index; + unsigned int tmp_out_index = jbi_out_index; + unsigned int tmp_bits_avail = jbi_bits_avail; + unsigned int prev[3]; + unsigned long long_end; + unsigned int match_data_length = MATCH_DATA_LENGTH; + + if (version > 0) --match_data_length; + + if (jbi_current_page < 0) + { + /* this is the first page of the array */ + jbi_current_page = 0; + jbi_in_index = 4; /* skip over length field */ + jbi_out_index = 0; + end_index = (jbi_out_length < JBI_ACA_BUFFER_SIZE) ? + (unsigned int) jbi_out_length : JBI_ACA_BUFFER_SIZE; + } + else + { + /* this is not the first page */ + ++jbi_current_page; + jbi_out_index -= MATCH_DATA_LENGTH; + long_end = jbi_out_length - + ((long) jbi_current_page * (long) MATCH_DATA_LENGTH); + end_index = (long_end < JBI_ACA_BUFFER_SIZE) ? + (unsigned int) long_end : JBI_ACA_BUFFER_SIZE; + + /* copy extra data from end of circular buffer to beginning */ + for (i = 0; i < jbi_out_index; ++i) + { + jbi_aca_out_buffer[i] = jbi_aca_out_buffer[i + MATCH_DATA_LENGTH]; + } + } + + while (jbi_out_index < end_index) + { + /* save state so we can undo the last packet when we reach the end */ + tmp_in_index = jbi_in_index; + tmp_out_index = jbi_out_index; + tmp_bits_avail = jbi_bits_avail; + + /* A 0 bit indicates literal data. */ + if (jbi_read_packed(1) == 0) + { + for (i = 0; i < DATA_BLOB_LENGTH; ++i) + { + if (jbi_out_index < end_index) + { + if (version == 0) + { + prev[i] = jbi_aca_out_buffer[jbi_out_index] & 0xff; + } + jbi_aca_out_buffer[jbi_out_index++] = + (unsigned char) jbi_read_packed(CHAR_BITS); + } + } + } + else + { + /* A 1 bit indicates offset/length to follow. */ + offset = jbi_read_packed(jbi_bits_required( + (jbi_current_page > 0) ? match_data_length : + (jbi_out_index > match_data_length ? match_data_length : + jbi_out_index))); + length = jbi_read_packed(CHAR_BITS); + + if ((version == 0) && (offset == match_data_length + 3)) + { + jbi_aca_out_buffer[jbi_out_index++] = (unsigned char) prev[0]; + jbi_aca_out_buffer[jbi_out_index++] = (unsigned char) prev[1]; + jbi_aca_out_buffer[jbi_out_index++] = (unsigned char) prev[2]; + length -= 3; + } + + for (i = 0; i < length; ++i) + { + if (jbi_out_index < end_index) + { + if (offset > jbi_out_index) + { + j = jbi_out_index + MATCH_DATA_LENGTH - offset; + } + else j = jbi_out_index - offset; + jbi_aca_out_buffer[jbi_out_index] = jbi_aca_out_buffer[j]; + ++jbi_out_index; + } + } + + if (version == 0) + { + prev[0] = jbi_aca_out_buffer[jbi_out_index - 3] & 0xff; + prev[1] = jbi_aca_out_buffer[jbi_out_index - 2] & 0xff; + prev[2] = jbi_aca_out_buffer[jbi_out_index - 1] & 0xff; + } + } + } + + /* restore the state before the previous packet */ + jbi_in_index = tmp_in_index; + jbi_out_index = tmp_out_index; + jbi_bits_avail = tmp_bits_avail; +} + +/****************************************************************************/ +/* */ + +void jbi_uncompress_page +( + int variable_id, + int page, + int version +) + +/* */ +/* Description: Uncompress requested page of variable data. Stores */ +/* uncompressed data in jbi_aca_out_buffer[]. */ +/* */ +/* Returns: TRUE if successful, otherwise FALSE if: */ +/* 1) variable is not a compressed array */ +/* 2) compressed data is illegal or corrupted */ +/* 3) requested page is beyond the end of the array */ +/* 4) internal error in the code */ +/* */ +/****************************************************************************/ +{ + unsigned long symbol_table; + unsigned long data_section; + unsigned long offset; + unsigned long value; + int delta = version * 2; + + if (variable_id != jbi_current_variable_id) + { + /* initialize to uncompress the desired variable */ + symbol_table = GET_DWORD(16 + (version * 8)); + data_section = GET_DWORD(20 + (version * 8)); + offset = symbol_table + ((11 + delta) * variable_id); + value = GET_DWORD(offset + 3 + delta); + jbi_current_variable_id = variable_id; + jbi_current_page = -1; + jbi_bits_avail = CHAR_BITS; + jbi_in_length = GET_DWORD(offset + 7 + delta); + jbi_out_length = + (((unsigned long) GET_BYTE(data_section + value)) | + (((unsigned long) GET_BYTE(data_section + value + 1)) << 8) | + (((unsigned long) GET_BYTE(data_section + value + 2)) << 16) | + (((unsigned long) GET_BYTE(data_section + value + 3)) << 24)); + jbi_in_index = 4; /* skip over length field */ + jbi_out_index = 0; + jbi_aca_in_offset = data_section + value; + } + + /* to look back at an earlier page, start over at the beginning */ + if (page < jbi_current_page) + { + jbi_current_page = -1; + jbi_in_index = 4; /* skip over length field */ + jbi_bits_avail = CHAR_BITS; + } + + /* uncompress sequentially up to the desired page */ + while (page > jbi_current_page) + { + jbi_uncompress_next_page(version); + } +} + +#else + +/****************************************************************************/ +/* */ + +unsigned long jbi_uncompress +( + unsigned char *in, + unsigned long in_length, + unsigned char *out, + unsigned long out_length, + int version +) + +/* */ +/* Description: Uncompress data in "in" and write result to "out". */ +/* */ +/* Returns: Length of uncompressed data. -1 if: */ +/* 1) out_length is too small */ +/* 2) Internal error in the code */ +/* 3) in doesn't contain ACA compressed data. */ +/* */ +/****************************************************************************/ +{ +#ifdef CONFIG_64BIT + unsigned int data_length = 0; +#else + unsigned long data_length = 0L; +#endif + unsigned long i, j; + unsigned int offset, length; + unsigned int match_data_length = MATCH_DATA_LENGTH; + + if (version > 0) --match_data_length; + + jbi_in_length = in_length; + jbi_bits_avail = CHAR_BITS; + jbi_in_index = 0L; + for (i = 0; i < out_length; ++i) out[i] = 0; + + /* Read number of bytes in data. */ +#ifdef CONFIG_64BIT + for (i = 0; i < sizeof(unsigned int); ++i) + { + data_length = data_length | ((unsigned int) + jbi_read_packed(in, CHAR_BITS) << (i * CHAR_BITS)); + } +#else + for (i = 0; i < sizeof (in_length); ++i) + { + data_length = data_length | ((unsigned long) + jbi_read_packed(in, CHAR_BITS) << (i * CHAR_BITS)); + } +#endif + + if (data_length > out_length) + { +#ifdef CONFIG_64BIT + jbi_dbg(DEBUG_ERR, "data_length(0x%x,0x%lx)\n", + data_length, out_length); + data_length = 0; +#else + jbi_dbg(DEBUG_ERR, "data_length(0x%lx,0x%lx)\n", + data_length, out_length); + data_length = 0L; +#endif + } + else + { + i = 0; + while (i < data_length) + { + /* A 0 bit indicates literal data. */ + if (jbi_read_packed(in, 1) == 0) + { + for (j = 0; j < DATA_BLOB_LENGTH; ++j) + { + if (i < data_length) + { + out[i] = (unsigned char) jbi_read_packed(in, CHAR_BITS); + i++; + } + } + } + else + { + /* A 1 bit indicates offset/length to follow. */ + offset = jbi_read_packed(in, jbi_bits_required((short) (i > match_data_length ? match_data_length : i))); + length = jbi_read_packed(in, CHAR_BITS); + + for (j = 0; j < length; ++j) + { + if (i < data_length) + { + out[i] = out[i - offset]; + i++; + } + } + } + } + } + + return (data_length); +} + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.h new file mode 100644 index 000000000000..4dacdcd5d773 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbicomp.h @@ -0,0 +1,37 @@ +/****************************************************************************/ +/* */ +/* Module: jbicomp.h */ +/* */ +/* Copyright (C) Altera Corporation 1997-2001 */ +/* */ +/* Description: Contains the function prototypes for compressing */ +/* and uncompressing Boolean array data. */ +/* */ +/****************************************************************************/ + +#ifndef INC_JBICOMP_H +#define INC_JBICOMP_H + +#if PORT==DOS + +void jbi_uncompress_page +( + int variable_id, + int page, + int version +); + +#else + +unsigned long jbi_uncompress +( + unsigned char *in, + unsigned long in_length, + unsigned char *out, + unsigned long out_length, + int version +); + +#endif /* PORT==DOS */ + +#endif /* INC_JBICOMP_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiexprt.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiexprt.h new file mode 100644 index 000000000000..ef4699dd6db3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiexprt.h @@ -0,0 +1,224 @@ +/****************************************************************************/ +/* */ +/* Module: jbiexprt.h */ +/* */ +/* Copyright (C) Altera Corporation 1998-2001 */ +/* */ +/* Description: Jam STAPL ByteCode Player Export Header File */ +/* */ +/* Revisions: */ +/* */ +/****************************************************************************/ + +#ifndef INC_JBIEXPRT_H +#define INC_JBIEXPRT_H + +/****************************************************************************/ +/* */ +/* Return codes from most JBI functions */ +/* */ +/****************************************************************************/ + +#define JBI_RETURN_TYPE int + +#define JBIC_SUCCESS 0 +#define JBIC_OUT_OF_MEMORY 1 +#define JBIC_IO_ERROR 2 +/* #define JAMC_SYNTAX_ERROR 3 */ +#define JBIC_UNEXPECTED_END 4 +#define JBIC_UNDEFINED_SYMBOL 5 +/* #define JAMC_REDEFINED_SYMBOL 6 */ +#define JBIC_INTEGER_OVERFLOW 7 +#define JBIC_DIVIDE_BY_ZERO 8 +#define JBIC_CRC_ERROR 9 +#define JBIC_INTERNAL_ERROR 10 +#define JBIC_BOUNDS_ERROR 11 +/* #define JAMC_TYPE_MISMATCH 12 */ +/* #define JAMC_ASSIGN_TO_CONST 13 */ +/* #define JAMC_NEXT_UNEXPECTED 14 */ +/* #define JAMC_POP_UNEXPECTED 15 */ +/* #define JAMC_RETURN_UNEXPECTED 16 */ +/* #define JAMC_ILLEGAL_SYMBOL 17 */ +#define JBIC_VECTOR_MAP_FAILED 18 +#define JBIC_USER_ABORT 19 +#define JBIC_STACK_OVERFLOW 20 +#define JBIC_ILLEGAL_OPCODE 21 +/* #define JAMC_PHASE_ERROR 22 */ +/* #define JAMC_SCOPE_ERROR 23 */ +#define JBIC_ACTION_NOT_FOUND 24 + +/****************************************************************************/ +/* */ +/* Macro Definitions */ +/* */ +/****************************************************************************/ + +/* +* For DOS port, program data is stored in a set of 16K pages, accessed +* through a pointer table. For 32-bit version, the buffer is continuous. +* The macro GET_BYTE gets a single byte for either case. +*/ +#if PORT==DOS +#define PROGRAM_PTR unsigned char ** +#else +#define PROGRAM_PTR unsigned char * +#endif + +#if PORT==DOS +#define GET_BYTE(x) (jbi_program[(x) >> 14L][(x) & 0x3fffL]) +#else +#define GET_BYTE(x) (program[x]) +#endif + +#define GET_WORD(x) \ + (((((unsigned short) GET_BYTE(x)) << 8) & 0xFF00) | \ + (((unsigned short) GET_BYTE((x)+1)) & 0x00FF)) + +#define GET_DWORD(x) \ + (((((unsigned long) GET_BYTE(x)) << 24L) & 0xFF000000L) | \ + ((((unsigned long) GET_BYTE((x)+1)) << 16L) & 0x00FF0000L) | \ + ((((unsigned long) GET_BYTE((x)+2)) << 8L) & 0x0000FF00L) | \ + (((unsigned long) GET_BYTE((x)+3)) & 0x000000FFL)) + +/****************************************************************************/ +/* */ +/* Structured Types */ +/* */ +/****************************************************************************/ + +typedef struct JBI_PROCINFO_STRUCT +{ + char *name; + unsigned char attributes; + struct JBI_PROCINFO_STRUCT *next; +} +JBI_PROCINFO; + +/****************************************************************************/ +/* */ +/* Global Data Prototypes */ +/* */ +/****************************************************************************/ + +#if PORT==DOS +extern unsigned char jbi_aca_out_buffer[8192 + 1024]; +#endif + +extern PROGRAM_PTR jbi_program; + +extern char *jbi_workspace; + +extern long jbi_workspace_size; + +/****************************************************************************/ +/* */ +/* Function Prototypes */ +/* */ +/****************************************************************************/ + +JBI_RETURN_TYPE jbi_execute +( + PROGRAM_PTR program, + long program_size, + char *workspace, + long workspace_size, + char *action, + char **init_list, + int reset_jtag, + long *error_address, + int *exit_code, + int *format_version +); + +JBI_RETURN_TYPE jbi_get_note +( + PROGRAM_PTR program, + long program_size, + long *offset, + char *key, + char *value, + int length +); + +JBI_RETURN_TYPE jbi_check_crc +( + PROGRAM_PTR program, + long program_size, + unsigned short *expected_crc, + unsigned short *actual_crc +); + +JBI_RETURN_TYPE jbi_get_file_info +( + PROGRAM_PTR program, + long program_size, + int *format_version, + int *action_count, + int *procedure_count +); + +JBI_RETURN_TYPE jbi_get_action_info +( + PROGRAM_PTR program, + long program_size, + int index, + char **name, + char **description, + JBI_PROCINFO **procedure_list +); + +int jbi_jtag_io +( + int tms, + int tdi, + int read_tdo +); + +void jbi_message +( + char *message_text +); + +void jbi_export_integer +( + char *key, + long value +); + +void jbi_export_boolean_array +( + char *key, + unsigned char *data, + long count +); + +void jbi_delay +( + long microseconds +); + +int jbi_vector_map +( + int signal_count, + char **signals +); + +int jbi_vector_io +( + int signal_count, + long *dir_vect, + long *data_vect, + long *capture_vect +); + +void *jbi_malloc +( + unsigned int size +); + +void jbi_free +( + void *ptr +); + +#endif /* INC_JBIEXPRT_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.c new file mode 100644 index 000000000000..f013100eecb8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.c @@ -0,0 +1,1679 @@ +/****************************************************************************/ +/* */ +/* Module: jbijtag.c */ +/* */ +/* Copyright (C) Altera Corporation 1998-2001 */ +/* */ +/* Description: Contains JTAG interface functions */ +/* */ +/* Revisions: 2.2 updated state transition paths */ +/* 2.0 added multi-page scan code for 16-bit PORT */ +/* */ +/****************************************************************************/ + +#include "jbiport.h" +#include "jbiexprt.h" +#include "jbicomp.h" +#include "jbijtag.h" + +#define NULL 0 + +char *jbi_workspace = NULL; +long jbi_workspace_size = 0L; + +/****************************************************************************/ +/* */ +/* Enumerated Types */ +/* */ +/****************************************************************************/ + +/* maximum JTAG IR and DR lengths (in bits) */ +#define JBIC_MAX_JTAG_IR_PREAMBLE 256 +#define JBIC_MAX_JTAG_IR_POSTAMBLE 256 +#define JBIC_MAX_JTAG_IR_LENGTH 512 +#define JBIC_MAX_JTAG_DR_PREAMBLE 1024 +#define JBIC_MAX_JTAG_DR_POSTAMBLE 1024 +#define JBIC_MAX_JTAG_DR_LENGTH 2048 + +/* +* Global variable to store the current JTAG state +*/ +JBIE_JTAG_STATE jbi_jtag_state = JBI_ILLEGAL_JTAG_STATE; + +/* +* Store current stop-state for DR and IR scan commands +*/ +JBIE_JTAG_STATE jbi_drstop_state = IDLE; +JBIE_JTAG_STATE jbi_irstop_state = IDLE; + +/* +* Store current padding values +*/ +unsigned int jbi_dr_preamble = 0; +unsigned int jbi_dr_postamble = 0; +unsigned int jbi_ir_preamble = 0; +unsigned int jbi_ir_postamble = 0; +unsigned int jbi_dr_length = 0; +unsigned int jbi_ir_length = 0; +unsigned char *jbi_dr_preamble_data = NULL; +unsigned char *jbi_dr_postamble_data = NULL; +unsigned char *jbi_ir_preamble_data = NULL; +unsigned char *jbi_ir_postamble_data = NULL; +unsigned char *jbi_dr_buffer = NULL; +unsigned char *jbi_ir_buffer = NULL; + +/* +* This structure shows, for each JTAG state, which state is reached after +* a single TCK clock cycle with TMS high or TMS low, respectively. This +* describes all possible state transitions in the JTAG state machine. +*/ +struct JBIS_JTAG_MACHINE +{ + JBIE_JTAG_STATE tms_high; + JBIE_JTAG_STATE tms_low; +} jbi_jtag_state_transitions[] = +{ +/* RESET */ { RESET, IDLE }, +/* IDLE */ { DRSELECT, IDLE }, +/* DRSELECT */ { IRSELECT, DRCAPTURE }, +/* DRCAPTURE */ { DREXIT1, DRSHIFT }, +/* DRSHIFT */ { DREXIT1, DRSHIFT }, +/* DREXIT1 */ { DRUPDATE, DRPAUSE }, +/* DRPAUSE */ { DREXIT2, DRPAUSE }, +/* DREXIT2 */ { DRUPDATE, DRSHIFT }, +/* DRUPDATE */ { DRSELECT, IDLE }, +/* IRSELECT */ { RESET, IRCAPTURE }, +/* IRCAPTURE */ { IREXIT1, IRSHIFT }, +/* IRSHIFT */ { IREXIT1, IRSHIFT }, +/* IREXIT1 */ { IRUPDATE, IRPAUSE }, +/* IRPAUSE */ { IREXIT2, IRPAUSE }, +/* IREXIT2 */ { IRUPDATE, IRSHIFT }, +/* IRUPDATE */ { DRSELECT, IDLE } +}; + +/* +* This table contains the TMS value to be used to take the NEXT STEP on +* the path to the desired state. The array index is the current state, +* and the bit position is the desired endstate. To find out which state +* is used as the intermediate state, look up the TMS value in the +* jbi_jtag_state_transitions[] table. +*/ +unsigned short jbi_jtag_path_map[16] = +{ +/* RST RTI SDRS CDR SDR E1DR PDR E2DR */ + 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF, +/* UDR SIRS CIR SIR E1IR PIR E2IR UIR */ + 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD +}; + +/* +* Flag bits for jbi_jtag_io() function +*/ +#define TMS_HIGH 1 +#define TMS_LOW 0 +#define TDI_HIGH 1 +#define TDI_LOW 0 +#define READ_TDO 1 +#define IGNORE_TDO 0 + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_init_jtag() + +/* */ +/****************************************************************************/ +{ + /* initial JTAG state is unknown */ + jbi_jtag_state = JBI_ILLEGAL_JTAG_STATE; + + /* initialize global variables to default state */ + jbi_drstop_state = IDLE; + jbi_irstop_state = IDLE; + jbi_dr_preamble = 0; + jbi_dr_postamble = 0; + jbi_ir_preamble = 0; + jbi_ir_postamble = 0; + jbi_dr_length = 0; + jbi_ir_length = 0; + + if (jbi_workspace != NULL) + { + jbi_dr_preamble_data = (unsigned char *) jbi_workspace; + jbi_dr_postamble_data = &jbi_dr_preamble_data[JBIC_MAX_JTAG_DR_PREAMBLE / 8]; + jbi_ir_preamble_data = &jbi_dr_postamble_data[JBIC_MAX_JTAG_DR_POSTAMBLE / 8]; + jbi_ir_postamble_data = &jbi_ir_preamble_data[JBIC_MAX_JTAG_IR_PREAMBLE / 8]; + jbi_dr_buffer = &jbi_ir_postamble_data[JBIC_MAX_JTAG_IR_POSTAMBLE / 8]; + jbi_ir_buffer = &jbi_dr_buffer[JBIC_MAX_JTAG_DR_LENGTH / 8]; + } + else + { + jbi_dr_preamble_data = NULL; + jbi_dr_postamble_data = NULL; + jbi_ir_preamble_data = NULL; + jbi_ir_postamble_data = NULL; + jbi_dr_buffer = NULL; + jbi_ir_buffer = NULL; + } + + return (JBIC_SUCCESS); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_drstop_state +( + JBIE_JTAG_STATE state +) + +/* */ +/****************************************************************************/ +{ + jbi_drstop_state = state; + + return (JBIC_SUCCESS); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_irstop_state +( + JBIE_JTAG_STATE state +) + +/* */ +/****************************************************************************/ +{ + jbi_irstop_state = state; + + return (JBIC_SUCCESS); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_dr_preamble +( + unsigned int count, + unsigned int start_index, + unsigned char *preamble_data +) + +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int i; + unsigned int j; + + if (jbi_workspace != NULL) + { + if (count > JBIC_MAX_JTAG_DR_PREAMBLE) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_preamble = count; + } + } + else + { + if (count > jbi_dr_preamble) + { + jbi_free(jbi_dr_preamble_data); + jbi_dr_preamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3); + + if (jbi_dr_preamble_data == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_preamble = count; + } + } + else + { + jbi_dr_preamble = count; + } + } + + if (status == JBIC_SUCCESS) + { + for (i = 0; i < count; ++i) + { + j = i + start_index; + + if (preamble_data == NULL) + { + jbi_dr_preamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + if (preamble_data[j >> 3] & (1 << (j & 7))) + { + jbi_dr_preamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + jbi_dr_preamble_data[i >> 3] &= + ~(unsigned int) (1 << (i & 7)); + } + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_ir_preamble +( + unsigned int count, + unsigned int start_index, + unsigned char *preamble_data +) + +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int i; + unsigned int j; + + if (jbi_workspace != NULL) + { + if (count > JBIC_MAX_JTAG_IR_PREAMBLE) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_preamble = count; + } + } + else + { + if (count > jbi_ir_preamble) + { + jbi_free(jbi_ir_preamble_data); + jbi_ir_preamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3); + + if (jbi_ir_preamble_data == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_preamble = count; + } + } + else + { + jbi_ir_preamble = count; + } + } + + if (status == JBIC_SUCCESS) + { + for (i = 0; i < count; ++i) + { + j = i + start_index; + + if (preamble_data == NULL) + { + jbi_ir_preamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + if (preamble_data[j >> 3] & (1 << (j & 7))) + { + jbi_ir_preamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + jbi_ir_preamble_data[i >> 3] &= + ~(unsigned int) (1 << (i & 7)); + } + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_dr_postamble +( + unsigned int count, + unsigned int start_index, + unsigned char *postamble_data +) + +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int i; + unsigned int j; + + if (jbi_workspace != NULL) + { + if (count > JBIC_MAX_JTAG_DR_POSTAMBLE) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_postamble = count; + } + } + else + { + if (count > jbi_dr_postamble) + { + jbi_free(jbi_dr_postamble_data); + jbi_dr_postamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3); + + if (jbi_dr_postamble_data == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_postamble = count; + } + } + else + { + jbi_dr_postamble = count; + } + } + + if (status == JBIC_SUCCESS) + { + for (i = 0; i < count; ++i) + { + j = i + start_index; + + if (postamble_data == NULL) + { + jbi_dr_postamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + if (postamble_data[j >> 3] & (1 << (j & 7))) + { + jbi_dr_postamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + jbi_dr_postamble_data[i >> 3] &= + ~(unsigned int) (1 << (i & 7)); + } + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_set_ir_postamble +( + unsigned int count, + unsigned int start_index, + unsigned char *postamble_data +) + +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int i; + unsigned int j; + + if (jbi_workspace != NULL) + { + if (count > JBIC_MAX_JTAG_IR_POSTAMBLE) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_postamble = count; + } + } + else + { + if (count > jbi_ir_postamble) + { + jbi_free(jbi_ir_postamble_data); + jbi_ir_postamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3); + + if (jbi_ir_postamble_data == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_postamble = count; + } + } + else + { + jbi_ir_postamble = count; + } + } + + if (status == JBIC_SUCCESS) + { + for (i = 0; i < count; ++i) + { + j = i + start_index; + + if (postamble_data == NULL) + { + jbi_ir_postamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + if (postamble_data[j >> 3] & (1 << (j & 7))) + { + jbi_ir_postamble_data[i >> 3] |= (1 << (i & 7)); + } + else + { + jbi_ir_postamble_data[i >> 3] &= + ~(unsigned int) (1 << (i & 7)); + } + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +void jbi_jtag_reset_idle(void) + +/* */ +/****************************************************************************/ +{ + int i; + + /* + * Go to Test Logic Reset (no matter what the starting state may be) + */ + for (i = 0; i < 5; ++i) + { + jbi_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO); + } + + /* + * Now step to Run Test / Idle + */ + jbi_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO); + + jbi_jtag_state = IDLE; +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_goto_jtag_state +( + JBIE_JTAG_STATE state +) + +/* */ +/****************************************************************************/ +{ + int tms; + int count = 0; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned int tmp_state; + + if (jbi_jtag_state == JBI_ILLEGAL_JTAG_STATE) + { + /* initialize JTAG chain to known state */ + jbi_jtag_reset_idle(); + } + + if (jbi_jtag_state == state) + { + /* + * We are already in the desired state. If it is a stable state, + * loop here. Otherwise do nothing (no clock cycles). + */ + if ((state == IDLE) || + (state == DRSHIFT) || + (state == DRPAUSE) || + (state == IRSHIFT) || + (state == IRPAUSE)) + { + jbi_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO); + } + else if (state == RESET) + { + jbi_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO); + } + } + else + { + while ((jbi_jtag_state != state) && (count < 9)) + { + /* + * Get TMS value to take a step toward desired state + */ + if (state < 0) { + tmp_state = 0; + } else { + tmp_state = state; + } + tms = (jbi_jtag_path_map[jbi_jtag_state] & (1 << tmp_state)) ? + TMS_HIGH : TMS_LOW; + + /* + * Take a step + */ + jbi_jtag_io(tms, TDI_LOW, IGNORE_TDO); + + if (tms) + { + jbi_jtag_state = + jbi_jtag_state_transitions[jbi_jtag_state].tms_high; + } + else + { + jbi_jtag_state = + jbi_jtag_state_transitions[jbi_jtag_state].tms_low; + } + + ++count; + } + } + + if (jbi_jtag_state != state) + { + status = JBIC_INTERNAL_ERROR; + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_wait_cycles +( + long cycles, + JBIE_JTAG_STATE wait_state +) + +/* */ +/* Description: Causes JTAG hardware to loop in the specified stable */ +/* state for the specified number of TCK clock cycles. */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int tms; + long count; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + + if (jbi_jtag_state != wait_state) + { + status = jbi_goto_jtag_state(wait_state); + } + + if (status == JBIC_SUCCESS) + { + /* + * Set TMS high to loop in RESET state + * Set TMS low to loop in any other stable state + */ + tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW; + + for (count = 0L; count < cycles; count++) + { + jbi_jtag_io(tms, TDI_LOW, IGNORE_TDO); + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_wait_microseconds +( + long microseconds, + JBIE_JTAG_STATE wait_state +) + +/* */ +/* Description: Causes JTAG hardware to sit in the specified stable */ +/* state for the specified duration of real time. If */ +/* no JTAG operations have been performed yet, then only */ +/* a delay is performed. This permits the WAIT USECS */ +/* statement to be used in VECTOR programs without causing */ +/* any JTAG operations. */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + + if ((jbi_jtag_state != JBI_ILLEGAL_JTAG_STATE) && + (jbi_jtag_state != wait_state)) + { + status = jbi_goto_jtag_state(wait_state); + } + + if (status == JBIC_SUCCESS) + { + /* + * Wait for specified time interval + */ + jbi_delay(microseconds); + } + + return (status); +} + +/****************************************************************************/ +/* */ + +void jbi_jtag_concatenate_data +( + unsigned char *buffer, + unsigned char *preamble_data, + unsigned int preamble_count, + unsigned char *target_data, + unsigned long start_index, + unsigned int target_count, + unsigned char *postamble_data, + unsigned int postamble_count +) + +/* */ +/* Description: Copies preamble data, target data, and postamble data */ +/* into one buffer for IR or DR scans. */ +/* */ +/* Returns: nothing */ +/* */ +/****************************************************************************/ +{ + unsigned long i; + unsigned long j; + unsigned long k; + + for (i = 0L; i < preamble_count; ++i) + { + if (preamble_data[i >> 3L] & (1L << (i & 7L))) + { + buffer[i >> 3L] |= (1L << (i & 7L)); + } + else + { + buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L)); + } + } + + j = start_index; + k = preamble_count + target_count; + for (; i < k; ++i, ++j) + { + if (target_data[j >> 3L] & (1L << (j & 7L))) + { + buffer[i >> 3L] |= (1L << (i & 7L)); + } + else + { + buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L)); + } + } + + j = 0L; + k = preamble_count + target_count + postamble_count; + for (; i < k; ++i, ++j) + { + if (postamble_data[j >> 3L] & (1L << (j & 7L))) + { + buffer[i >> 3L] |= (1L << (i & 7L)); + } + else + { + buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L)); + } + } +} + +int jbi_jtag_drscan +( + int start_state, + int count, + unsigned char *tdi, + unsigned char *tdo +) +{ + int i = 0; + int tdo_bit = 0; + int status = 1; + + /* + * First go to DRSHIFT state + */ + switch (start_state) + { + case 0: /* IDLE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(0, 0, 0); /* DRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* DRSHIFT */ + break; + + case 1: /* DRPAUSE */ + jbi_jtag_io(1, 0, 0); /* DREXIT2 */ + jbi_jtag_io(1, 0, 0); /* DRUPDATE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(0, 0, 0); /* DRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* DRSHIFT */ + break; + + case 2: /* IRPAUSE */ + jbi_jtag_io(1, 0, 0); /* IREXIT2 */ + jbi_jtag_io(1, 0, 0); /* IRUPDATE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(0, 0, 0); /* DRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* DRSHIFT */ + break; + + default: + status = 0; + } + + if (status) + { + /* loop in the SHIFT-DR state */ + for (i = 0; i < count; i++) + { + tdo_bit = jbi_jtag_io( + (i == count - 1), + tdi[i >> 3] & (1 << (i & 7)), + (tdo != NULL)); + + if (tdo != NULL) + { + if (tdo_bit) + { + tdo[i >> 3] |= (1 << (i & 7)); + } + else + { + tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7)); + } + } + } + + jbi_jtag_io(0, 0, 0); /* DRPAUSE */ + } + + return (status); +} + +int jbi_jtag_irscan +( + int start_state, + int count, + unsigned char *tdi, + unsigned char *tdo +) +{ + int i = 0; + int tdo_bit = 0; + int status = 1; + + /* + * First go to IRSHIFT state + */ + switch (start_state) + { + case 0: /* IDLE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(1, 0, 0); /* IRSELECT */ + jbi_jtag_io(0, 0, 0); /* IRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* IRSHIFT */ + break; + + case 1: /* DRPAUSE */ + jbi_jtag_io(1, 0, 0); /* DREXIT2 */ + jbi_jtag_io(1, 0, 0); /* DRUPDATE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(1, 0, 0); /* IRSELECT */ + jbi_jtag_io(0, 0, 0); /* IRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* IRSHIFT */ + break; + + case 2: /* IRPAUSE */ + jbi_jtag_io(1, 0, 0); /* IREXIT2 */ + jbi_jtag_io(1, 0, 0); /* IRUPDATE */ + jbi_jtag_io(1, 0, 0); /* DRSELECT */ + jbi_jtag_io(1, 0, 0); /* IRSELECT */ + jbi_jtag_io(0, 0, 0); /* IRCAPTURE */ + jbi_jtag_io(0, 0, 0); /* IRSHIFT */ + break; + + default: + status = 0; + } + + if (status) + { + /* loop in the SHIFT-IR state */ + for (i = 0; i < count; i++) + { + tdo_bit = jbi_jtag_io( + (i == count - 1), + tdi[i >> 3] & (1 << (i & 7)), + (tdo != NULL)); + + if (tdo != NULL) + { + if (tdo_bit) + { + tdo[i >> 3] |= (1 << (i & 7)); + } + else + { + tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7)); + } + } + } + + jbi_jtag_io(0, 0, 0); /* IRPAUSE */ + } + + return (status); +} + +/****************************************************************************/ +/* */ + +void jbi_jtag_extract_target_data +( + unsigned char *buffer, + unsigned char *target_data, + unsigned int start_index, + unsigned int preamble_count, + unsigned int target_count +) + +/* */ +/* Description: Copies target data from scan buffer, filtering out */ +/* preamble and postamble data. */ +/* */ +/* Returns: nothing */ +/* */ +/****************************************************************************/ +{ + unsigned int i; + unsigned int j; + unsigned int k; + + j = preamble_count; + k = start_index + target_count; + for (i = start_index; i < k; ++i, ++j) + { + if (buffer[j >> 3] & (1 << (j & 7))) + { + target_data[i >> 3] |= (1 << (i & 7)); + } + else + { + target_data[i >> 3] &= ~(unsigned int) (1 << (i & 7)); + } + } +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_irscan +( + unsigned int count, + unsigned char *tdi_data, + unsigned int start_index +) + +/* */ +/* Description: Shifts data into instruction register */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int start_code = 0; + unsigned int alloc_chars = 0; + unsigned int shift_count = jbi_ir_preamble + count + jbi_ir_postamble; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE; + + switch (jbi_jtag_state) + { + case JBI_ILLEGAL_JTAG_STATE: + case RESET: + case IDLE: + start_code = 0; + start_state = IDLE; + break; + + case DRSELECT: + case DRCAPTURE: + case DRSHIFT: + case DREXIT1: + case DRPAUSE: + case DREXIT2: + case DRUPDATE: + start_code = 1; + start_state = DRPAUSE; + break; + + case IRSELECT: + case IRCAPTURE: + case IRSHIFT: + case IREXIT1: + case IRPAUSE: + case IREXIT2: + case IRUPDATE: + start_code = 2; + start_state = IRPAUSE; + break; + + default: + status = JBIC_INTERNAL_ERROR; + break; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_jtag_state != start_state) + { + status = jbi_goto_jtag_state(start_state); + } + } + + if (status == JBIC_SUCCESS) + { + if (jbi_workspace != NULL) + { + if (shift_count > JBIC_MAX_JTAG_IR_LENGTH) + { + status = JBIC_OUT_OF_MEMORY; + } + } + else if (shift_count > jbi_ir_length) + { + alloc_chars = (shift_count + 7) >> 3; + jbi_free(jbi_ir_buffer); + jbi_ir_buffer = (unsigned char *) jbi_malloc(alloc_chars); + + if (jbi_ir_buffer == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_length = alloc_chars * 8; + } + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Copy preamble data, IR data, and postamble data into a buffer + */ + jbi_jtag_concatenate_data + ( + jbi_ir_buffer, + jbi_ir_preamble_data, + jbi_ir_preamble, + tdi_data, + start_index, + count, + jbi_ir_postamble_data, + jbi_ir_postamble + ); + + /* + * Do the IRSCAN + */ + jbi_jtag_irscan + ( + start_code, + shift_count, + jbi_ir_buffer, + NULL + ); + + /* jbi_jtag_irscan() always ends in IRPAUSE state */ + jbi_jtag_state = IRPAUSE; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_irstop_state != IRPAUSE) + { + status = jbi_goto_jtag_state(jbi_irstop_state); + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_swap_ir +( + unsigned int count, + unsigned char *in_data, + unsigned int in_index, + unsigned char *out_data, + unsigned int out_index +) + +/* */ +/* Description: Shifts data into instruction register, capturing output */ +/* data */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int start_code = 0; + unsigned int alloc_chars = 0; + unsigned int shift_count = jbi_ir_preamble + count + jbi_ir_postamble; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE; + + switch (jbi_jtag_state) + { + case JBI_ILLEGAL_JTAG_STATE: + case RESET: + case IDLE: + start_code = 0; + start_state = IDLE; + break; + + case DRSELECT: + case DRCAPTURE: + case DRSHIFT: + case DREXIT1: + case DRPAUSE: + case DREXIT2: + case DRUPDATE: + start_code = 1; + start_state = DRPAUSE; + break; + + case IRSELECT: + case IRCAPTURE: + case IRSHIFT: + case IREXIT1: + case IRPAUSE: + case IREXIT2: + case IRUPDATE: + start_code = 2; + start_state = IRPAUSE; + break; + + default: + status = JBIC_INTERNAL_ERROR; + break; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_jtag_state != start_state) + { + status = jbi_goto_jtag_state(start_state); + } + } + + if (status == JBIC_SUCCESS) + { + if (jbi_workspace != NULL) + { + if (shift_count > JBIC_MAX_JTAG_IR_LENGTH) + { + status = JBIC_OUT_OF_MEMORY; + } + } + else if (shift_count > jbi_ir_length) + { + alloc_chars = (shift_count + 7) >> 3; + jbi_free(jbi_ir_buffer); + jbi_ir_buffer = (unsigned char *) jbi_malloc(alloc_chars); + + if (jbi_ir_buffer == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_ir_length = alloc_chars * 8; + } + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Copy preamble data, IR data, and postamble data into a buffer + */ + jbi_jtag_concatenate_data + ( + jbi_ir_buffer, + jbi_ir_preamble_data, + jbi_ir_preamble, + in_data, + in_index, + count, + jbi_ir_postamble_data, + jbi_ir_postamble + ); + + /* + * Do the IRSCAN + */ + jbi_jtag_irscan + ( + start_code, + shift_count, + jbi_ir_buffer, + jbi_ir_buffer + ); + + /* jbi_jtag_irscan() always ends in IRPAUSE state */ + jbi_jtag_state = IRPAUSE; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_irstop_state != IRPAUSE) + { + status = jbi_goto_jtag_state(jbi_irstop_state); + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Now extract the returned data from the buffer + */ + jbi_jtag_extract_target_data + ( + jbi_ir_buffer, + out_data, + out_index, + jbi_ir_preamble, + count + ); + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_drscan +( + unsigned int count, + unsigned char *tdi_data, + unsigned long start_index +) + +/* */ +/* Description: Shifts data into data register (ignoring output data) */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int start_code = 0; + unsigned int alloc_chars = 0; + unsigned int shift_count = jbi_dr_preamble + count + jbi_dr_postamble; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE; + + switch (jbi_jtag_state) + { + case JBI_ILLEGAL_JTAG_STATE: + case RESET: + case IDLE: + start_code = 0; + start_state = IDLE; + break; + + case DRSELECT: + case DRCAPTURE: + case DRSHIFT: + case DREXIT1: + case DRPAUSE: + case DREXIT2: + case DRUPDATE: + start_code = 1; + start_state = DRPAUSE; + break; + + case IRSELECT: + case IRCAPTURE: + case IRSHIFT: + case IREXIT1: + case IRPAUSE: + case IREXIT2: + case IRUPDATE: + start_code = 2; + start_state = IRPAUSE; + break; + + default: + status = JBIC_INTERNAL_ERROR; + break; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_jtag_state != start_state) + { + status = jbi_goto_jtag_state(start_state); + } + } + + if (status == JBIC_SUCCESS) + { + if (jbi_workspace != NULL) + { + if (shift_count > JBIC_MAX_JTAG_DR_LENGTH) + { + status = JBIC_OUT_OF_MEMORY; + } + } + else if (shift_count > jbi_dr_length) + { + alloc_chars = (shift_count + 7) >> 3; + jbi_free(jbi_dr_buffer); + jbi_dr_buffer = (unsigned char *) jbi_malloc(alloc_chars); + + if (jbi_dr_buffer == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_length = alloc_chars * 8; + } + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Copy preamble data, DR data, and postamble data into a buffer + */ + jbi_jtag_concatenate_data + ( + jbi_dr_buffer, + jbi_dr_preamble_data, + jbi_dr_preamble, + tdi_data, + start_index, + count, + jbi_dr_postamble_data, + jbi_dr_postamble + ); + + /* + * Do the DRSCAN + */ + jbi_jtag_drscan + ( + start_code, + shift_count, + jbi_dr_buffer, + NULL + ); + + /* jbi_jtag_drscan() always ends in DRPAUSE state */ + jbi_jtag_state = DRPAUSE; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_drstop_state != DRPAUSE) + { + status = jbi_goto_jtag_state(jbi_drstop_state); + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_swap_dr +( + unsigned int count, + unsigned char *in_data, + unsigned long in_index, + unsigned char *out_data, + unsigned int out_index +) + +/* */ +/* Description: Shifts data into data register, capturing output data */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + int start_code = 0; + unsigned int alloc_chars = 0; + unsigned int shift_count = jbi_dr_preamble + count + jbi_dr_postamble; + JBI_RETURN_TYPE status = JBIC_SUCCESS; + JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE; + + switch (jbi_jtag_state) + { + case JBI_ILLEGAL_JTAG_STATE: + case RESET: + case IDLE: + start_code = 0; + start_state = IDLE; + break; + + case DRSELECT: + case DRCAPTURE: + case DRSHIFT: + case DREXIT1: + case DRPAUSE: + case DREXIT2: + case DRUPDATE: + start_code = 1; + start_state = DRPAUSE; + break; + + case IRSELECT: + case IRCAPTURE: + case IRSHIFT: + case IREXIT1: + case IRPAUSE: + case IREXIT2: + case IRUPDATE: + start_code = 2; + start_state = IRPAUSE; + break; + + default: + status = JBIC_INTERNAL_ERROR; + break; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_jtag_state != start_state) + { + status = jbi_goto_jtag_state(start_state); + } + } + + if (status == JBIC_SUCCESS) + { + if (jbi_workspace != NULL) + { + if (shift_count > JBIC_MAX_JTAG_DR_LENGTH) + { + status = JBIC_OUT_OF_MEMORY; + } + } + else if (shift_count > jbi_dr_length) + { + alloc_chars = (shift_count + 7) >> 3; + jbi_free(jbi_dr_buffer); + jbi_dr_buffer = (unsigned char *) jbi_malloc(alloc_chars); + + if (jbi_dr_buffer == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + jbi_dr_length = alloc_chars * 8; + } + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Copy preamble data, DR data, and postamble data into a buffer + */ + jbi_jtag_concatenate_data + ( + jbi_dr_buffer, + jbi_dr_preamble_data, + jbi_dr_preamble, + in_data, + in_index, + count, + jbi_dr_postamble_data, + jbi_dr_postamble + ); + + /* + * Do the DRSCAN + */ + jbi_jtag_drscan + ( + start_code, + shift_count, + jbi_dr_buffer, + jbi_dr_buffer + ); + + /* jbi_jtag_drscan() always ends in DRPAUSE state */ + jbi_jtag_state = DRPAUSE; + } + + if (status == JBIC_SUCCESS) + { + if (jbi_drstop_state != DRPAUSE) + { + status = jbi_goto_jtag_state(jbi_drstop_state); + } + } + + if (status == JBIC_SUCCESS) + { + /* + * Now extract the returned data from the buffer + */ + jbi_jtag_extract_target_data + ( + jbi_dr_buffer, + out_data, + out_index, + jbi_dr_preamble, + count + ); + } + + return (status); +} + +/****************************************************************************/ +/* */ + +void jbi_free_jtag_padding_buffers(int reset_jtag) + +/* */ +/* Description: Frees memory allocated for JTAG IR and DR buffers */ +/* */ +/* Returns: nothing */ +/* */ +/****************************************************************************/ +{ + /* + * If the JTAG interface was used, reset it to TLR + */ + if (reset_jtag && (jbi_jtag_state != JBI_ILLEGAL_JTAG_STATE)) + { + jbi_jtag_reset_idle(); + } + + if (jbi_workspace == NULL) + { + if (jbi_dr_preamble_data != NULL) + { + jbi_free(jbi_dr_preamble_data); + jbi_dr_preamble_data = NULL; + } + + if (jbi_dr_postamble_data != NULL) + { + jbi_free(jbi_dr_postamble_data); + jbi_dr_postamble_data = NULL; + } + + if (jbi_dr_buffer != NULL) + { + jbi_free(jbi_dr_buffer); + jbi_dr_buffer = NULL; + } + + if (jbi_ir_preamble_data != NULL) + { + jbi_free(jbi_ir_preamble_data); + jbi_ir_preamble_data = NULL; + } + + if (jbi_ir_postamble_data != NULL) + { + jbi_free(jbi_ir_postamble_data); + jbi_ir_postamble_data = NULL; + } + + if (jbi_ir_buffer != NULL) + { + jbi_free(jbi_ir_buffer); + jbi_ir_buffer = NULL; + } + } +} + +#if PORT==DOS + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_do_drscan_multi_page +( + unsigned int variable_id, + unsigned long count, + unsigned long start_index, + int version +) + +/* */ +/* Description: Shifts data into data register (ignoring output data) */ +/* Scan data comes from compressed Boolean array. */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned long shift_count = jbi_dr_preamble + count + jbi_dr_postamble; + unsigned long i; + unsigned long j; + unsigned long k; + unsigned int bi; + + if (status == JBIC_SUCCESS) + { + status = jbi_goto_jtag_state(DRSHIFT); + } + + if (status == JBIC_SUCCESS) + { + /* + * Get preamble data, DR data, and postamble data one bit at a time + * and immediately scan it into the JTAG chain + */ + + for (i = 0L; i < jbi_dr_preamble; ++i) + { + jbi_jtag_io((i == shift_count - 1), + (int) (jbi_dr_preamble_data[i >> 3L] & (1L << (i & 7L))), 0); + } + + j = start_index; + k = jbi_dr_preamble + count; + + jbi_uncompress_page(variable_id, (unsigned int) (j >> 16L), version); + + for (; i < k; ++i, ++j) + { + bi = (unsigned int) (j & 0x0000ffffL); + + /* check for page boundary - load next page if necessary */ + if (bi == 0) + { + jbi_uncompress_page(variable_id, (unsigned int) (j >> 16L), version); + } + + jbi_jtag_io((i == shift_count - 1), + (int) (jbi_aca_out_buffer[bi >> 3] & (1 << (bi & 7))), 0); + } + + j = 0L; + k = jbi_dr_preamble + count + jbi_dr_postamble; + for (; i < k; ++i, ++j) + { + jbi_jtag_io((i == shift_count - 1), + (int) (jbi_dr_postamble_data[j >> 3L] & (1L << (j & 7L))), 0); + } + + jbi_jtag_io(0, 0, 0); /* DRPAUSE */ + + /* jbi_jtag_drscan() always ends in DRPAUSE state */ + jbi_jtag_state = DRPAUSE; + + if (jbi_drstop_state != DRPAUSE) + { + status = jbi_goto_jtag_state(jbi_drstop_state); + } + } + + return (status); +} + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.h new file mode 100644 index 000000000000..fab2dac0266a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbijtag.h @@ -0,0 +1,146 @@ +/****************************************************************************/ +/* */ +/* Module: jbijtag.h */ +/* */ +/* Copyright (C) Altera Corporation 1998-2001 */ +/* */ +/* Description: Definitions of JTAG constants, types, and functions */ +/* */ +/****************************************************************************/ + +#ifndef INC_JBIJTAG_H +#define INC_JBIJTAG_H + +/****************************************************************************/ +/* */ +/* Function Prototypes */ +/* */ +/****************************************************************************/ +typedef enum +{ + JBI_ILLEGAL_JTAG_STATE = -1, + RESET = 0, + IDLE = 1, + DRSELECT = 2, + DRCAPTURE = 3, + DRSHIFT = 4, + DREXIT1 = 5, + DRPAUSE = 6, + DREXIT2 = 7, + DRUPDATE = 8, + IRSELECT = 9, + IRCAPTURE = 10, + IRSHIFT = 11, + IREXIT1 = 12, + IRPAUSE = 13, + IREXIT2 = 14, + IRUPDATE = 15 + +} JBIE_JTAG_STATE; + +JBI_RETURN_TYPE jbi_init_jtag +( + void +); + +JBI_RETURN_TYPE jbi_set_drstop_state +( + JBIE_JTAG_STATE state +); + +JBI_RETURN_TYPE jbi_set_irstop_state +( + JBIE_JTAG_STATE state +); + +JBI_RETURN_TYPE jbi_set_dr_preamble +( + unsigned int count, + unsigned int start_index, + unsigned char *preamble_data +); + +JBI_RETURN_TYPE jbi_set_ir_preamble +( + unsigned int count, + unsigned int start_index, + unsigned char *preamble_data +); + +JBI_RETURN_TYPE jbi_set_dr_postamble +( + unsigned int count, + unsigned int start_index, + unsigned char *postamble_data +); + +JBI_RETURN_TYPE jbi_set_ir_postamble +( + unsigned int count, + unsigned int start_index, + unsigned char *postamble_data +); + +JBI_RETURN_TYPE jbi_goto_jtag_state +( + JBIE_JTAG_STATE state +); + +JBI_RETURN_TYPE jbi_do_wait_cycles +( + long cycles, + JBIE_JTAG_STATE wait_state +); + +JBI_RETURN_TYPE jbi_do_wait_microseconds +( + long microseconds, + JBIE_JTAG_STATE wait_state +); + +JBI_RETURN_TYPE jbi_do_irscan +( + unsigned int count, + unsigned char *tdi_data, + unsigned int start_index +); + +JBI_RETURN_TYPE jbi_swap_ir +( + unsigned int count, + unsigned char *in_data, + unsigned int in_index, + unsigned char *out_data, + unsigned int out_index +); + +JBI_RETURN_TYPE jbi_do_drscan +( + unsigned int count, + unsigned char *tdi_data, + unsigned long start_index +); + +JBI_RETURN_TYPE jbi_swap_dr +( + unsigned int count, + unsigned char *in_data, + unsigned long in_index, + unsigned char *out_data, + unsigned int out_index +); + +void jbi_free_jtag_padding_buffers +( + int reset_jtag +); + +JBI_RETURN_TYPE jbi_do_drscan_multi_page +( + unsigned int variable_id, + unsigned long long_count, + unsigned long long_index, + int version +); + +#endif /* INC_JBIJTAG_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbimain.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbimain.c new file mode 100644 index 000000000000..b8cab4857074 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbimain.c @@ -0,0 +1,3362 @@ +/****************************************************************************/ +/* */ +/* Module: jbimain.c */ +/* */ +/* Copyright (C) Altera Corporation 1998-2001 */ +/* */ +/* Description: Jam STAPL ByteCode Player (Interpreter) */ +/* */ +/* Revisions: 2.2 fixed /W4 warnings */ +/* 2.0 added support for STAPL ByteCode format */ +/* */ +/****************************************************************************/ + +#include "jbiport.h" +#include "jbiexprt.h" +#include "jbijtag.h" +#include "jbicomp.h" +#include "jbistub.h" + +/****************************************************************************/ +/* */ +/* MACROS */ +/* */ +/****************************************************************************/ + +#ifndef NULL +#define NULL 0 +#endif + +#define JBI_STACK_SIZE 128 + +#define JBIC_MESSAGE_LENGTH 1024 + +/* +* This macro checks if enough parameters are available on the stack. The +* argument is the number of parameters needed. +*/ +#define IF_CHECK_STACK(x) \ + if (stack_ptr < (int) (x)) \ + { \ + status = JBIC_STACK_OVERFLOW; \ + } \ + else + +/* +* This macro checks if a code address is inside the code section +*/ +#define CHECK_PC \ + if ((pc < code_section) || (pc >= debug_section)) \ + { \ + status = JBIC_BOUNDS_ERROR; \ + } + +/****************************************************************************/ +/* */ +/* GLOBAL VARIABLES */ +/* */ +/****************************************************************************/ + +#if PORT==DOS +/* +* jbi_program is a global pointer used by macros GET_BYTE, GET_WORD, and +* GET_DWORD to read data from the JBC file +*/ +PROGRAM_PTR jbi_program; +#endif + +/****************************************************************************/ +/* */ +/* UTILITY FUNCTIONS */ +/* */ +/****************************************************************************/ + +int jbi_strlen(char *string) +{ + int len = 0; + + while (string[len] != '\0') ++len; + + return (len); +} + +long jbi_atol(char *buffer) +{ + long result = 0L; + int index = 0; + + while ((buffer[index] >= '0') && (buffer[index] <= '9')) + { + result = (result * 10) + (buffer[index] - '0'); + ++index; + } + + return (result); +} + +void jbi_ltoa(char *buffer, long number) +{ + int index = 0; + int rev_index = 0; + char reverse[32]; + + if (number < 0L) + { + buffer[index++] = '-'; + number = 0 - number; + } + else if (number == 0) + { + buffer[index++] = '0'; + } + + while (number != 0) + { + reverse[rev_index++] = (char) ((number % 10) + '0'); + number /= 10; + } + + while (rev_index > 0) + { + buffer[index++] = reverse[--rev_index]; + } + + buffer[index] = '\0'; +} + +char jbi_toupper(char ch) +{ + return ((char) (((ch >= 'a') && (ch <= 'z')) ? (ch + 'A' - 'a') : ch)); +} + +int jbi_stricmp(char *left, char *right) +{ + int result = 0; + char l, r; + + do + { + l = jbi_toupper(*left); + r = jbi_toupper(*right); + result = l - r; + ++left; + ++right; + } + while ((result == 0) && (l != '\0') && (r != '\0')); + + return (result); +} + +void jbi_strncpy(char *left, char *right, int count) +{ + char ch; + + do + { + *left = *right; + ch = *right; + ++left; + ++right; + --count; + } + while ((ch != '\0') && (count != 0)); +} + +void jbi_make_dword(unsigned char *buf, unsigned long num) +{ + buf[0] = (unsigned char) num; + buf[1] = (unsigned char) (num >> 8L); + buf[2] = (unsigned char) (num >> 16L); + buf[3] = (unsigned char) (num >> 24L); +} + +unsigned long jbi_get_dword(unsigned char *buf) +{ + return + (((unsigned long) buf[0]) | + (((unsigned long) buf[1]) << 8L) | + (((unsigned long) buf[2]) << 16L) | + (((unsigned long) buf[3]) << 24L)); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_execute +( + PROGRAM_PTR program, + long program_size, + char *workspace, + long workspace_size, + char *action, + char **init_list, + int reset_jtag, + long *error_address, + int *exit_code, + int *format_version +) + +/* */ +/* Description: */ +/* */ +/* Returns: */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned long first_word = 0L; + unsigned long action_table = 0L; + unsigned long proc_table = 0L; + unsigned long string_table = 0L; + unsigned long symbol_table = 0L; + unsigned long data_section = 0L; + unsigned long code_section = 0L; + unsigned long debug_section = 0L; + unsigned long action_count = 0L; + unsigned long proc_count = 0L; + unsigned long symbol_count = 0L; + /*char message_buffer[JBIC_MESSAGE_LENGTH + 1];*/ + char *message_buffer; + addr_t *variables = NULL; + long *variable_size = NULL; + char *attributes = NULL; + unsigned char *proc_attributes = NULL; + unsigned long pc; + unsigned long opcode_address; + unsigned long args[3]; + unsigned int opcode; + unsigned long name_id; + addr_t stack[JBI_STACK_SIZE] = {0}; + unsigned char charbuf[4]; + long long_temp; + unsigned int variable_id; + unsigned char *charptr_temp; + unsigned char *charptr_temp2; + long *longptr_temp; + int version = 0; + int delta = 0; + int stack_ptr = 0; + unsigned int arg_count; + int done = 0; + int bad_opcode = 0; + unsigned int count; + unsigned int index; + unsigned int index2; + long long_count; + long long_index; + long long_index2; + unsigned int i; + unsigned int j; + unsigned long uncompressed_size, uncompressed_result; + unsigned int offset; + unsigned long value; + int current_proc = 0; + char *equal_ptr; + int length; + int reverse; + + unsigned long debug_cnt = 0; + +#if PORT==DOS + char name[33]; +#else + char *name; +#endif + + jbi_workspace = workspace; + jbi_workspace_size = workspace_size; + +#if PORT==DOS + jbi_program = program; +#endif + + /* Resolve compilation warnings: the frame size of 1664 bytes is larger than 1024 bytes */ + message_buffer = (char *) kzalloc(JBIC_MESSAGE_LENGTH + 1, GFP_KERNEL); + if (message_buffer == NULL) { + jbi_dbg(DEBUG_DETAIL, "Memory not enough jbi_execute \n"); + return JBIC_OUT_OF_MEMORY; + } + + /* + * Read header information + */ + if (program_size > 52L) + { + first_word = GET_DWORD(0); + version = (int) (first_word & 1L); + *format_version = version + 1; + delta = version * 8; + + action_table = GET_DWORD(4); + proc_table = GET_DWORD(8); + string_table = GET_DWORD(4 + delta); + symbol_table = GET_DWORD(16 + delta); + data_section = GET_DWORD(20 + delta); + code_section = GET_DWORD(24 + delta); + debug_section = GET_DWORD(28 + delta); + action_count = GET_DWORD(40 + delta); + proc_count = GET_DWORD(44 + delta); + symbol_count = GET_DWORD(48 + (2 * delta)); + + jbi_dbg(DEBUG_DETAIL, "version: %d\n", version); + jbi_dbg(DEBUG_DETAIL, "delta: %d\n", delta); + jbi_dbg(DEBUG_DETAIL, "action_table: 0x%08lx\n", action_table); + jbi_dbg(DEBUG_DETAIL, "proc_table: 0x%08lx\n", proc_table); + jbi_dbg(DEBUG_DETAIL, "string_table: 0x%08lx\n", string_table); + jbi_dbg(DEBUG_DETAIL, "symbol_table: 0x%08lx\n", symbol_table); + jbi_dbg(DEBUG_DETAIL, "data_section: 0x%08lx\n", data_section); + jbi_dbg(DEBUG_DETAIL, "code_section: 0x%08lx\n", code_section); + jbi_dbg(DEBUG_DETAIL, "debug_section: 0x%08lx\n", debug_section); + jbi_dbg(DEBUG_DETAIL, "action_count: 0x%08lx\n", action_count); + jbi_dbg(DEBUG_DETAIL, "proc_count: 0x%08lx\n", proc_count); + jbi_dbg(DEBUG_DETAIL, "symbol_count: 0x%08lx\n", symbol_count); + jbi_dbg(DEBUG_DETAIL, "\n"); + } + + if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) + { + jbi_dbg(DEBUG_ERR, "first_word 0x%lx\n", first_word); + done = 1; + status = JBIC_IO_ERROR; + } + + if ((status == JBIC_SUCCESS) && (symbol_count > 0)) + { + variables = (addr_t *) jbi_malloc( + (unsigned int) symbol_count * sizeof(long)); + + if (variables == NULL) status = JBIC_OUT_OF_MEMORY; + + if (status == JBIC_SUCCESS) + { + variable_size = (long *) jbi_malloc( + (unsigned int) symbol_count * sizeof(long)); + + if (variable_size == NULL) status = JBIC_OUT_OF_MEMORY; + } + + if (status == JBIC_SUCCESS) + { + attributes = (char *) jbi_malloc((unsigned int) symbol_count); + + if (attributes == NULL) status = JBIC_OUT_OF_MEMORY; + } + + if ((status == JBIC_SUCCESS) && (version > 0)) + { + proc_attributes = (unsigned char *) jbi_malloc((unsigned int) proc_count); + + if (proc_attributes == NULL) status = JBIC_OUT_OF_MEMORY; + } + + if (status == JBIC_SUCCESS) + { + delta = version * 2; + + for (i = 0; i < (unsigned int) symbol_count; ++i) + { + offset = (unsigned int) (symbol_table + ((11 + delta) * i)); + + value = GET_DWORD(offset + 3 + delta); + + attributes[i] = GET_BYTE(offset); + + /* use bit 7 of attribute byte to indicate that this buffer */ + /* was dynamically allocated and should be freed later */ + attributes[i] &= 0x7f; + + variable_size[i] = GET_DWORD(offset + 7 + delta); + + jbi_dbg(DEBUG_NOISY, "symbol %03d: 0x%02x,0x%08lx,0x%08lx\n", + i, attributes[i], value, variable_size[i]); + + /* + * Attribute bits: + * bit 0: 0 = read-only, 1 = read-write + * bit 1: 0 = not compressed, 1 = compressed + * bit 2: 0 = not initialized, 1 = initialized + * bit 3: 0 = scalar, 1 = array + * bit 4: 0 = Boolean, 1 = integer + * bit 5: 0 = declared variable, + * 1 = compiler created temporary variable + */ + + if ((attributes[i] & 0x0c) == 0x04) + { + /* initialized scalar variable */ + variables[i] = value; + } + else if ((attributes[i] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ +#if PORT==DOS + /* for DOS port, get the size but do not uncompress */ + long_index = data_section + value; + uncompressed_size = + (((unsigned long) GET_BYTE(long_index)) | + (((unsigned long) GET_BYTE(long_index + 1L)) << 8L) | + (((unsigned long) GET_BYTE(long_index + 2L)) << 16L) | + (((unsigned long) GET_BYTE(long_index + 3L)) << 24L)); + variable_size[i] = uncompressed_size; +#else + uncompressed_size = jbi_get_dword( + &program[data_section + value]); + + /* allocate a buffer for the uncompressed data */ + variables[i] = (addr_t) jbi_malloc(uncompressed_size); + + if (variables[i] == (addr_t) 0L) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + /* set flag so buffer will be freed later */ + attributes[i] |= 0x80; + + /* uncompress the data */ + uncompressed_result = + jbi_uncompress( + &program[data_section + value], + variable_size[i], + (unsigned char *) variables[i], + uncompressed_size, + version); + if (uncompressed_result != uncompressed_size) + { + /* decompression failed */ + jbi_dbg(DEBUG_ERR, "uncompress fail(0x%lx,0x%lx,0x%lx)(0x%lx)\n", + variable_size[i], uncompressed_result, uncompressed_size, value); + status = JBIC_IO_ERROR; + } + else + { + variable_size[i] = uncompressed_size * 8L; + } + } +#endif + } + else if ((attributes[i] & 0x1e) == 0x0c) + { + /* initialized Boolean array */ +#if PORT==DOS + /* flag attributes so that memory is freed */ + attributes[i] |= 0x80; + + if (variable_size[i] > 0) + { + unsigned int size = (unsigned int) + ((variable_size[i] + 7L) / 8L); + + variables[i] = (long) jbi_malloc(size); + + if (variables[i] == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + unsigned char *p = (unsigned char *) variables[i]; + /* copy array values into buffer */ + for (j = 0; j < size; ++j) + { + p[j] = GET_BYTE(data_section + value + j); + } + } + } + else + { + variables[i] = 0; + } +#else + variables[i] = value + data_section + (addr_t) program; +#endif + } + else if ((attributes[i] & 0x1c) == 0x1c) + { + /* initialized integer array */ + variables[i] = value + data_section; + } + else if ((attributes[i] & 0x0c) == 0x08) + { + /* uninitialized array */ + + /* flag attributes so that memory is freed */ + attributes[i] |= 0x80; + + if (variable_size[i] > 0) + { + unsigned int size; + + if (attributes[i] & 0x10) + { + /* integer array */ + size = (unsigned int) + (variable_size[i] * sizeof(long)); + } + else + { + /* Boolean array */ + size = (unsigned int) + ((variable_size[i] + 7L) / 8L); + } + + variables[i] = (addr_t) jbi_malloc(size); + + if (variables[i] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + /* zero out memory */ + for (j = 0; j < size; ++j) + { + ((unsigned char *)(variables[i]))[j] = 0; + } + } + } + else + { + variables[i] = 0; + } + } + else + { + variables[i] = 0; + } + + jbi_dbg(DEBUG_NOISY, " variables: 0x%08lx,0x%016llx\n", + variable_size[i], (long long) variables[i]); + } + } + + jbi_dbg(DEBUG_NOISY, "\n"); + } + + /* + * Initialize variables listed in init_list + */ + if ((status == JBIC_SUCCESS) && (init_list != NULL) && (version == 0)) + { + delta = version * 2; + count = 0; + while (init_list[count] != NULL) + { + equal_ptr = init_list[count]; + length = 0; + while ((*equal_ptr != '=') && (*equal_ptr != '\0')) + { + ++equal_ptr; + ++length; + } + if (*equal_ptr == '=') + { + ++equal_ptr; + value = jbi_atol(equal_ptr); + jbi_strncpy(message_buffer, init_list[count], length); + message_buffer[length] = '\0'; + for (i = 0; i < (unsigned int) symbol_count; ++i) + { + offset = (unsigned int) (symbol_table + ((11 + delta) * i)); + name_id = (version == 0) ? GET_WORD(offset + 1) : + GET_DWORD(offset + 1); +#if PORT==DOS + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + name_id]; +#endif + + if (jbi_stricmp(message_buffer, name) == 0) + { + variables[i] = value; + } + + jbi_dbg(DEBUG_NOISY, "init_list %03d: 0x%08lx,%s,0x%016llx\n", + i, name_id, name, (long long) variables[i]); + } + } + + ++count; + } + + jbi_dbg(DEBUG_NOISY, "\n"); + } + + if (status != JBIC_SUCCESS) done = 1; + + jbi_init_jtag(); + + pc = code_section; + message_buffer[0] = '\0'; + + /* + * For JBC version 2, we will execute the procedures corresponding to + * the selected ACTION + */ + if (version > 0) + { + if (action == NULL) + { + status = JBIC_ACTION_NOT_FOUND; + done = 1; + } + else + { + int action_found = 0; + + for (i = 0; (i < action_count) && !action_found; ++i) + { + name_id = GET_DWORD(action_table + (12 * i)); + +#if PORT==DOS + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + name_id]; +#endif + + if (jbi_stricmp(action, name) == 0) + { + action_found = 1; + current_proc = (int) GET_DWORD(action_table + (12 * i) + 8); + } + + jbi_dbg(DEBUG_NOISY, "action %03d: 0x%08lx,%s, %d,%d\n", + i, name_id, name, action_found, current_proc); + } + + if (!action_found) + { + status = JBIC_ACTION_NOT_FOUND; + done = 1; + } + } + + if (status == JBIC_SUCCESS) + { + int first_time = 1; + i = current_proc; + while ((i != 0) || first_time) + { + first_time = 0; + /* check procedure attribute byte */ + proc_attributes[i] = (unsigned char) + (GET_BYTE(proc_table + (13 * i) + 8) & 0x03); + + jbi_dbg(DEBUG_NOISY, " proc_attributes %03d: 0x%02x\n", + i, proc_attributes[i]); + + if (proc_attributes[i] != 0) + { + /* + * BIT0 - OPTIONAL + * BIT1 - RECOMMENDED + * BIT6 - FORCED OFF + * BIT7 - FORCED ON + */ + if (init_list != NULL) + { + name_id = GET_DWORD(proc_table + (13 * i)); +#if PORT==DOS + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + name_id]; +#endif + + jbi_dbg(DEBUG_NOISY, " init_list %03d: 0x%08lx,%s\n", + i, name_id, name); + + count = 0; + while (init_list[count] != NULL) + { + equal_ptr = init_list[count]; + length = 0; + while ((*equal_ptr != '=') && (*equal_ptr != '\0')) + { + ++equal_ptr; + ++length; + } + if (*equal_ptr == '=') + { + ++equal_ptr; + jbi_strncpy(message_buffer, init_list[count], length); + message_buffer[length] = '\0'; + + if (jbi_stricmp(message_buffer, name) == 0) + { + if (jbi_atol(equal_ptr) == 0) + { + proc_attributes[i] |= 0x40; + } + else + { + proc_attributes[i] |= 0x80; + } + } + } + + jbi_dbg(DEBUG_NOISY, " proc_attributes %03d: 0x%02x\n", + i, proc_attributes[i]); + + ++count; + } + } + } + + i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4); + } + + /* + * Set current_proc to the first procedure to be executed + */ + i = current_proc; + while ((i != 0) && + ((proc_attributes[i] == 1) || + ((proc_attributes[i] & 0xc0) == 0x40))) + { + i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4); + } + + if ((i != 0) || ((i == 0) && (current_proc == 0) && + ((proc_attributes[0] != 1) && + ((proc_attributes[0] & 0xc0) != 0x40)))) + { + current_proc = i; + pc = code_section + GET_DWORD(proc_table + (13 * i) + 9); + CHECK_PC; + } + else + { + /* there are no procedures to execute! */ + done = 1; + } + } + + jbi_dbg(DEBUG_NOISY, "\n"); + } + + message_buffer[0] = '\0'; + + jbi_dbg(DEBUG_NOISY, "excute pc: 0x%lx,%d\n", pc, current_proc); + while (!done) + { + opcode = (unsigned int) (GET_BYTE(pc) & 0xff); + debug_cnt++; + jbi_dbg(DEBUG_NOISY, "op: 0x%02x(%03d:0x%08lx,%08lx)", + opcode, stack_ptr, pc, debug_cnt); + opcode_address = pc; + ++pc; + + arg_count = (opcode >> 6) & 3; + jbi_dbg(DEBUG_NOISY, " - %u:", arg_count); + for (i = 0; i < arg_count; ++i) + { + args[i] = GET_DWORD(pc); + jbi_dbg(DEBUG_NOISY, " 0x%08lx", args[i]); + pc += 4; + } + jbi_dbg(DEBUG_NOISY, "\n"); + + switch (opcode) + { + case 0x00: /* NOP */ + /* do nothing */ + break; + + case 0x01: /* DUP */ + IF_CHECK_STACK(1) + { + stack[stack_ptr] = stack[stack_ptr - 1]; + ++stack_ptr; + } + break; + + case 0x02: /* SWP */ + IF_CHECK_STACK(2) + { + long_temp = stack[stack_ptr - 2]; + stack[stack_ptr - 2] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + break; + + case 0x03: /* ADD */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] += stack[stack_ptr]; + } + break; + + case 0x04: /* SUB */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] -= stack[stack_ptr]; + } + break; + + case 0x05: /* MULT */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] *= stack[stack_ptr]; + } + break; + + case 0x06: /* DIV */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] /= stack[stack_ptr]; + } + break; + + case 0x07: /* MOD */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] %= stack[stack_ptr]; + } + break; + + case 0x08: /* SHL */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] <<= stack[stack_ptr]; + } + break; + + case 0x09: /* SHR */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] >>= stack[stack_ptr]; + } + break; + + case 0x0A: /* NOT */ + IF_CHECK_STACK(1) + { + stack[stack_ptr - 1] ^= (-1L); + } + break; + + case 0x0B: /* AND */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] &= stack[stack_ptr]; + } + break; + + case 0x0C: /* OR */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] |= stack[stack_ptr]; + } + break; + + case 0x0D: /* XOR */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] ^= stack[stack_ptr]; + } + break; + + case 0x0E: /* INV */ + IF_CHECK_STACK(1) + { + stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L; + } + break; + + case 0x0F: /* GT */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] = + (stack[stack_ptr - 1] > stack[stack_ptr]) ? 1L : 0L; + } + break; + + case 0x10: /* LT */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] = + (stack[stack_ptr - 1] < stack[stack_ptr]) ? 1L : 0L; + } + break; + + case 0x11: /* RET */ + if ((version > 0) && (stack_ptr == 0)) + { + /* + * We completed one of the main procedures of an ACTION. + * Find the next procedure to be executed and jump to it. + * If there are no more procedures, then EXIT. + */ + i = (unsigned int) GET_DWORD(proc_table + (13 * current_proc) + 4); + while ((i != 0) && + ((proc_attributes[i] == 1) || + ((proc_attributes[i] & 0xc0) == 0x40))) + { + i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4); + } + + if (i == 0) + { + /* there are no procedures to execute! */ + done = 1; + *exit_code = 0; /* success */ + } + else + { + current_proc = i; + pc = code_section + GET_DWORD(proc_table + (13 * i) + 9); + CHECK_PC; + } + } + else IF_CHECK_STACK(1) + { + pc = stack[--stack_ptr] + code_section; + CHECK_PC; + if (pc == code_section) + { + status = JBIC_BOUNDS_ERROR; + } + } + break; + + case 0x12: /* CMPS */ + /* + * Array short compare + * ...stack 0 is source 1 value + * ...stack 1 is source 2 value + * ...stack 2 is mask value + * ...stack 3 is count + */ + IF_CHECK_STACK(4) + { + long a = stack[--stack_ptr]; + long b = stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[stack_ptr - 1]; + + if ((count < 1) || (count > 32)) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + long_temp &= ((-1L) >> (32 - count)); + + stack[stack_ptr - 1] = + ((a & long_temp) == (b & long_temp)) ? 1L : 0L; + } + } + break; + + case 0x13: /* PINT */ + /* + * PRINT add integer + * ...stack 0 is integer value + */ + IF_CHECK_STACK(1) + { + jbi_ltoa(&message_buffer[jbi_strlen(message_buffer)], + stack[--stack_ptr]); + } + break; + + case 0x14: /* PRNT */ + /* + * PRINT finish + */ + jbi_message(message_buffer); + message_buffer[0] = '\0'; + break; + + case 0x15: /* DSS */ + /* + * DRSCAN short + * ...stack 0 is scan data + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_do_drscan(count, charbuf, 0); + } + break; + + case 0x16: /* DSSC */ + /* + * DRSCAN short with capture + * ...stack 0 is scan data + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[stack_ptr - 1]; + jbi_make_dword(charbuf, long_temp); + status = jbi_swap_dr(count, charbuf, 0, charbuf, 0); + stack[stack_ptr - 1] = jbi_get_dword(charbuf); + } + break; + + case 0x17: /* ISS */ + /* + * IRSCAN short + * ...stack 0 is scan data + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_do_irscan(count, charbuf, 0); + } + break; + + case 0x18: /* ISSC */ + /* + * IRSCAN short with capture + * ...stack 0 is scan data + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + count = (unsigned int) stack[stack_ptr - 1]; + jbi_make_dword(charbuf, long_temp); + status = jbi_swap_ir(count, charbuf, 0, charbuf, 0); + stack[stack_ptr - 1] = jbi_get_dword(charbuf); + } + break; + + case 0x19: /* VSS */ + /* + * VECTOR short + * ...stack 0 is scan data + * ...stack 1 is count + */ + bad_opcode = 1; + break; + + case 0x1A: /* VSSC */ + /* + * VECTOR short with capture + * ...stack 0 is scan data + * ...stack 1 is count + */ + bad_opcode = 1; + break; + + case 0x1B: /* VMPF */ + /* + * VMAP finish + */ + bad_opcode = 1; + break; + + case 0x1C: /* DPR */ + IF_CHECK_STACK(1) + { + count = (unsigned int) stack[--stack_ptr]; + status = jbi_set_dr_preamble(count, 0, NULL); + } + break; + + case 0x1D: /* DPRL */ + /* + * DRPRE with literal data + * ...stack 0 is count + * ...stack 1 is literal data + */ + IF_CHECK_STACK(2) + { + count = (unsigned int) stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_set_dr_preamble(count, 0, charbuf); + } + break; + + case 0x1E: /* DPO */ + /* + * DRPOST + * ...stack 0 is count + */ + IF_CHECK_STACK(1) + { + count = (unsigned int) stack[--stack_ptr]; + status = jbi_set_dr_postamble(count, 0, NULL); + } + break; + + case 0x1F: /* DPOL */ + /* + * DRPOST with literal data + * ...stack 0 is count + * ...stack 1 is literal data + */ + IF_CHECK_STACK(2) + { + count = (unsigned int) stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_set_dr_postamble(count, 0, charbuf); + } + break; + + case 0x20: /* IPR */ + IF_CHECK_STACK(1) + { + count = (unsigned int) stack[--stack_ptr]; + status = jbi_set_ir_preamble(count, 0, NULL); + } + break; + + case 0x21: /* IPRL */ + /* + * IRPRE with literal data + * ...stack 0 is count + * ...stack 1 is literal data + */ + IF_CHECK_STACK(2) + { + count = (unsigned int) stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_set_ir_preamble(count, 0, charbuf); + } + break; + + case 0x22: /* IPO */ + /* + * IRPOST + * ...stack 0 is count + */ + IF_CHECK_STACK(1) + { + count = (unsigned int) stack[--stack_ptr]; + status = jbi_set_ir_postamble(count, 0, NULL); + } + break; + + case 0x23: /* IPOL */ + /* + * IRPOST with literal data + * ...stack 0 is count + * ...stack 1 is literal data + */ + IF_CHECK_STACK(2) + { + count = (unsigned int) stack[--stack_ptr]; + long_temp = stack[--stack_ptr]; + jbi_make_dword(charbuf, long_temp); + status = jbi_set_ir_postamble(count, 0, charbuf); + } + break; + + case 0x24: /* PCHR */ + IF_CHECK_STACK(1) + { + unsigned char ch; + count = jbi_strlen(message_buffer); + ch = (char) stack[--stack_ptr]; + if ((ch < 1) || (ch > 127)) + { + /* character code out of range */ + /* instead of flagging an error, force the value to 127 */ + ch = 127; + } + message_buffer[count] = ch; + message_buffer[count + 1] = '\0'; + } + break; + + case 0x25: /* EXIT */ + IF_CHECK_STACK(1) + { + *exit_code = (int) stack[--stack_ptr]; + } + done = 1; + break; + + case 0x26: /* EQU */ + IF_CHECK_STACK(2) + { + --stack_ptr; + stack[stack_ptr - 1] = + (stack[stack_ptr - 1] == stack[stack_ptr]) ? 1L : 0L; + } + break; + + case 0x27: /* POPT */ + IF_CHECK_STACK(1) + { + --stack_ptr; + } + break; + + case 0x28: /* TRST */ + bad_opcode = 1; + break; + + case 0x29: /* FRQ */ + bad_opcode = 1; + break; + + case 0x2A: /* FRQU */ + bad_opcode = 1; + break; + + case 0x2B: /* PD32 */ + bad_opcode = 1; + break; + + case 0x2C: /* ABS */ + IF_CHECK_STACK(1) + { + if (stack[stack_ptr - 1] < 0) + { + stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1]; + } + } + break; + + case 0x2D: /* BCH0 */ + /* + * Batch operation 0 + * SWP + * SWPN 7 + * SWP + * SWPN 6 + * DUPN 8 + * SWPN 2 + * SWP + * DUPN 6 + * DUPN 6 + */ + + /* SWP */ + IF_CHECK_STACK(2) + { + long_temp = stack[stack_ptr - 2]; + stack[stack_ptr - 2] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* SWPN 7 */ + index = 7 + 1; + IF_CHECK_STACK(index) + { + long_temp = stack[stack_ptr - index]; + stack[stack_ptr - index] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* SWP */ + IF_CHECK_STACK(2) + { + long_temp = stack[stack_ptr - 2]; + stack[stack_ptr - 2] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* SWPN 6 */ + index = 6 + 1; + IF_CHECK_STACK(index) + { + long_temp = stack[stack_ptr - index]; + stack[stack_ptr - index] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* DUPN 8 */ + index = 8 + 1; + IF_CHECK_STACK(index) + { + stack[stack_ptr] = stack[stack_ptr - index]; + ++stack_ptr; + } + + /* SWPN 2 */ + index = 2 + 1; + IF_CHECK_STACK(index) + { + long_temp = stack[stack_ptr - index]; + stack[stack_ptr - index] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* SWP */ + IF_CHECK_STACK(2) + { + long_temp = stack[stack_ptr - 2]; + stack[stack_ptr - 2] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + + /* DUPN 6 */ + index = 6 + 1; + IF_CHECK_STACK(index) + { + stack[stack_ptr] = stack[stack_ptr - index]; + ++stack_ptr; + } + + /* DUPN 6 */ + index = 6 + 1; + IF_CHECK_STACK(index) + { + stack[stack_ptr] = stack[stack_ptr - index]; + ++stack_ptr; + } + break; + + case 0x2E: /* BCH1 */ + /* + * Batch operation 1 + * SWPN 8 + * SWP + * SWPN 9 + * SWPN 3 + * SWP + * SWPN 2 + * SWP + * SWPN 7 + * SWP + * SWPN 6 + * DUPN 5 + * DUPN 5 + */ + bad_opcode = 1; + break; + + case 0x2F: /* PSH0 */ + stack[stack_ptr++] = 0; + break; + + case 0x40: /* PSHL */ + stack[stack_ptr++] = (long) args[0]; + break; + + case 0x41: /* PSHV */ + stack[stack_ptr++] = variables[args[0]]; + break; + + case 0x42: /* JMP */ + pc = args[0] + code_section; + CHECK_PC; + break; + + case 0x43: /* CALL */ + stack[stack_ptr++] = pc; + pc = args[0] + code_section; + CHECK_PC; + break; + + case 0x44: /* NEXT */ + /* + * Process FOR / NEXT loop + * ...argument 0 is variable ID + * ...stack 0 is step value + * ...stack 1 is end value + * ...stack 2 is top address + */ + IF_CHECK_STACK(3) + { + long step = stack[stack_ptr - 1]; + long end = stack[stack_ptr - 2]; + long top = stack[stack_ptr - 3]; + long iterator = variables[args[0]]; + int break_out = 0; + + if (step < 0) + { + if (iterator <= end) break_out = 1; + } + else + { + if (iterator >= end) break_out = 1; + } + + if (break_out) + { + stack_ptr -= 3; + } + else + { + variables[args[0]] = iterator + step; + pc = top + code_section; + CHECK_PC; + } + } + break; + + case 0x45: /* PSTR */ + /* + * PRINT add string + * ...argument 0 is string ID + */ +#if PORT==DOS + long_index = string_table + args[0]; + index2 = jbi_strlen(message_buffer); + + do + { + i = GET_BYTE(long_index); + message_buffer[index2] = (char) i; + ++long_index; + ++index2; + } + while ((i != '\0') && (index2 < JBIC_MESSAGE_LENGTH)); +#else + count = jbi_strlen(message_buffer); + jbi_strncpy(&message_buffer[count], + (char *) &program[string_table + args[0]], + JBIC_MESSAGE_LENGTH - count); +#endif + message_buffer[JBIC_MESSAGE_LENGTH] = '\0'; + break; + + case 0x46: /* VMAP */ + /* + * VMAP add signal name + * ...argument 0 is string ID + */ + bad_opcode = 1; + break; + + case 0x47: /* SINT */ + /* + * STATE intermediate state + * ...argument 0 is state code + */ + status = jbi_goto_jtag_state((int) args[0]); + break; + + case 0x48: /* ST */ + /* + * STATE final state + * ...argument 0 is state code + */ + status = jbi_goto_jtag_state((int) args[0]); + break; + + case 0x49: /* ISTP */ + /* + * IRSTOP state + * ...argument 0 is state code + */ + status = jbi_set_irstop_state((int) args[0]); + break; + + case 0x4A: /* DSTP */ + /* + * DRSTOP state + * ...argument 0 is state code + */ + status = jbi_set_drstop_state((int) args[0]); + break; + + case 0x4B: /* SWPN */ + /* + * Exchange top with Nth stack value + * ...argument 0 is 0-based stack entry to swap with top element + */ + index = ((int) args[0]) + 1; + IF_CHECK_STACK(index) + { + long_temp = stack[stack_ptr - index]; + stack[stack_ptr - index] = stack[stack_ptr - 1]; + stack[stack_ptr - 1] = long_temp; + } + break; + + case 0x4C: /* DUPN */ + /* + * Duplicate Nth stack value + * ...argument 0 is 0-based stack entry to duplicate + */ + index = ((int) args[0]) + 1; + IF_CHECK_STACK(index) + { + stack[stack_ptr] = stack[stack_ptr - index]; + ++stack_ptr; + } + break; + + case 0x4D: /* POPV */ + /* + * Pop stack into scalar variable + * ...argument 0 is variable ID + * ...stack 0 is value + */ + IF_CHECK_STACK(1) + { + variables[args[0]] = stack[--stack_ptr]; + } + break; + + case 0x4E: /* POPE */ + /* + * Pop stack into integer array element + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is value + */ + IF_CHECK_STACK(2) + { + variable_id = (unsigned int) args[0]; + + /* + * If variable is read-only, convert to writable array + */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x1c)) + { + /* + * Allocate a writable buffer for this array + */ + count = (unsigned int) variable_size[variable_id]; + long_temp = variables[variable_id]; + longptr_temp = (long *) jbi_malloc(count * sizeof(long)); + variables[variable_id] = (addr_t) longptr_temp; + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + /* copy previous contents into buffer */ + for (i = 0; i < count; ++i) + { + longptr_temp[i] = GET_DWORD(long_temp); + long_temp += 4L; + } + + /* set bit 7 - buffer was dynamically allocated */ + attributes[variable_id] |= 0x80; + + /* clear bit 2 - variable is writable */ + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } + } + +#if PORT==DOS + /* for 16-bit version, allow writing in allocated buffers */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x9c)) + { + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } +#endif + + /* check that variable is a writable integer array */ + if ((attributes[variable_id] & 0x1c) != 0x18) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + longptr_temp = (long *) variables[variable_id]; + + /* pop the array index */ + index = (unsigned int) stack[--stack_ptr]; + + /* pop the value and store it into the array */ + longptr_temp[index] = stack[--stack_ptr]; + } + } + break; + + case 0x4F: /* POPA */ + /* + * Pop stack into Boolean array + * ...argument 0 is variable ID + * ...stack 0 is count + * ...stack 1 is array index + * ...stack 2 is value + */ + IF_CHECK_STACK(3) + { + variable_id = (unsigned int) args[0]; + + /* + * If variable is read-only, convert to writable array + */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x0c)) + { + /* + * Allocate a writable buffer for this array + */ + long_temp = (variable_size[variable_id] + 7L) >> 3L; + charptr_temp2 = (unsigned char *) variables[variable_id]; + charptr_temp = jbi_malloc((unsigned int) long_temp); + variables[variable_id] = (addr_t) charptr_temp; + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + /* zero the buffer */ + for (long_index = 0L; + long_index < long_temp; + ++long_index) + { + charptr_temp[long_index] = 0; + } + + /* copy previous contents into buffer */ + for (long_index = 0L; + long_index < variable_size[variable_id]; + ++long_index) + { +#if PORT==DOS + if ((attributes[variable_id] & 0x02) && + ((long_index & 0x0000FFFF) == 0L)) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + charptr_temp = jbi_aca_out_buffer; + long_index2 = long_index & 0xFFFF; + } +#else + long_index2 = long_index; +#endif + + if (charptr_temp2[long_index2 >> 3] & + (1 << (long_index2 & 7))) + { + charptr_temp[long_index >> 3] |= + (1 << (long_index & 7)); + } + } + + /* set bit 7 - buffer was dynamically allocated */ + attributes[variable_id] |= 0x80; + + /* clear bit 2 - variable is writable */ + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } + } + +#if PORT==DOS + /* for 16-bit version, allow writing in allocated buffers */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x8c)) + { + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } +#endif + + /* check that variable is a writable Boolean array */ + if ((attributes[variable_id] & 0x1c) != 0x08) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + charptr_temp = (unsigned char *) variables[variable_id]; + + /* pop the count (number of bits to copy) */ + long_count = stack[--stack_ptr]; + + /* pop the array index */ + long_index = stack[--stack_ptr]; + + reverse = 0; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + + if (long_index > long_count) + { + reverse = 1; + long_temp = long_count; + long_count = 1 + long_index - long_count; + long_index = long_temp; + + /* reverse POPA is not supported */ + status = JBIC_BOUNDS_ERROR; + break; + } + else + { + long_count = 1 + long_count - long_index; + } + } + + /* pop the data */ + long_temp = stack[--stack_ptr]; + + if (long_count < 1) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + for (i = 0; i < (unsigned int) long_count; ++i) + { + if (long_temp & (1L << (long) i)) + { + charptr_temp[long_index >> 3L] |= + (1L << (long_index & 7L)); + } + else + { + charptr_temp[long_index >> 3L] &= + ~ (unsigned int) (1L << (long_index & 7L)); + } + ++long_index; + } + } + } + } + break; + + case 0x50: /* JMPZ */ + /* + * Pop stack and branch if zero + * ...argument 0 is address + * ...stack 0 is condition value + */ + IF_CHECK_STACK(1) + { + if (stack[--stack_ptr] == 0) + { + pc = args[0] + code_section; + CHECK_PC; + } + } + break; + + case 0x51: /* DS */ + case 0x52: /* IS */ + /* + * DRSCAN + * IRSCAN + * ...argument 0 is scan data variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + long_index = stack[--stack_ptr]; + long_count = stack[--stack_ptr]; + + reverse = 0; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + /* stack 2 = count */ + long_temp = long_count; + long_count = stack[--stack_ptr]; + + if (long_index > long_temp) + { + reverse = 1; + long_index = long_temp; + } + } + +#if PORT==DOS + if (((long_index & 0xFFFF0000) == 0) && + ((long_count & 0xFFFF0000) == 0)) + { + variable_id = (unsigned int) args[0]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + long_index &= 0x0000ffff; + charptr_temp = jbi_aca_out_buffer; + } + else + { + charptr_temp = (unsigned char *) variables[variable_id]; + } + + if (reverse) + { + /* allocate a buffer and reverse the data order */ + charptr_temp2 = charptr_temp; + charptr_temp = jbi_malloc((unsigned int) + ((long_count >> 3L) + 1L)); + + if (charptr_temp == NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + long_temp = long_index + long_count - 1; + long_index2 = 0; + while (long_index2 < long_count) + { + if (charptr_temp2[long_temp >> 3] & + (1 << (long_temp & 7))) + { + charptr_temp[long_index2 >> 3] |= + (1 << (long_index2 & 7)); + } + else + { + charptr_temp[long_index2 >> 3] &= + ~(1 << (long_index2 & 7)); + } + + --long_temp; + ++long_index2; + } + } + } + + if (opcode == 0x51) /* DS */ + { + status = jbi_do_drscan((unsigned int) long_count, + charptr_temp, (unsigned long) long_index); + } + else /* IS */ + { + status = jbi_do_irscan((unsigned int) long_count, + charptr_temp, (unsigned int) long_index); + } + + if (reverse) jbi_free(charptr_temp); + } + else if ((opcode == 0x51) && !reverse) + { + status = jbi_do_drscan_multi_page( + (unsigned int) args[0], + (unsigned long) long_count, + (unsigned long) long_index, version); + } + else + { + /* reverse multi-page scans are not supported */ + /* multi-page IR scans are not supported */ + status = JBIC_BOUNDS_ERROR; + } +#else + charptr_temp = (unsigned char *) variables[args[0]]; + + if (reverse) + { + /* allocate a buffer and reverse the data order */ + charptr_temp2 = charptr_temp; + charptr_temp = jbi_malloc((long_count >> 3) + 1); + if (charptr_temp == NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + long_temp = long_index + long_count - 1; + long_index2 = 0; + while (long_index2 < long_count) + { + if (charptr_temp2[long_temp >> 3] & + (1 << (long_temp & 7))) + { + charptr_temp[long_index2 >> 3] |= + (1 << (long_index2 & 7)); + } + else + { + charptr_temp[long_index2 >> 3] &= + ~(1 << (long_index2 & 7)); + } + + --long_temp; + ++long_index2; + } + } + } + + if (opcode == 0x51) /* DS */ + { + status = jbi_do_drscan((unsigned int) long_count, + charptr_temp, (unsigned long) long_index); + } + else /* IS */ + { + status = jbi_do_irscan((unsigned int) long_count, + charptr_temp, (unsigned int) long_index); + } +#endif + + if (reverse && (charptr_temp != NULL)) + { + jbi_free(charptr_temp); + } + } + break; + + case 0x53: /* DPRA */ + /* + * DRPRE with array data + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + index = (unsigned int) stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + charptr_temp = (unsigned char *) variables[args[0]]; + status = jbi_set_dr_preamble(count, index, charptr_temp); + } + break; + + case 0x54: /* DPOA */ + /* + * DRPOST with array data + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + index = (unsigned int) stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + charptr_temp = (unsigned char *) variables[args[0]]; + status = jbi_set_dr_postamble(count, index, charptr_temp); + } + break; + + case 0x55: /* IPRA */ + /* + * IRPRE with array data + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + index = (unsigned int) stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + charptr_temp = (unsigned char *) variables[args[0]]; + status = jbi_set_ir_preamble(count, index, charptr_temp); + } + break; + + case 0x56: /* IPOA */ + /* + * IRPOST with array data + * ...argument 0 is variable ID + * ...stack 0 is array index + * ...stack 1 is count + */ + IF_CHECK_STACK(2) + { + index = (unsigned int) stack[--stack_ptr]; + count = (unsigned int) stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + charptr_temp = (unsigned char *) variables[args[0]]; + status = jbi_set_ir_postamble(count, index, charptr_temp); + } + break; + + case 0x57: /* EXPT */ + /* + * EXPORT + * ...argument 0 is string ID + * ...stack 0 is integer expression + */ + IF_CHECK_STACK(1) + { +#if PORT==DOS + name_id = args[0]; + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + args[0]]; +#endif + long_temp = stack[--stack_ptr]; + jbi_export_integer(name, long_temp); + } + break; + + case 0x58: /* PSHE */ + /* + * Push integer array element + * ...argument 0 is variable ID + * ...stack 0 is array index + */ + IF_CHECK_STACK(1) + { + variable_id = (unsigned int) args[0]; + index = (unsigned int) stack[stack_ptr - 1]; + + /* check variable type */ + if ((attributes[variable_id] & 0x1f) == 0x19) + { + /* writable integer array */ + longptr_temp = (long *) variables[variable_id]; + stack[stack_ptr - 1] = longptr_temp[index]; + } + else if ((attributes[variable_id] & 0x1f) == 0x1c) + { + /* read-only integer array */ + long_temp = variables[variable_id] + (4L * index); + stack[stack_ptr - 1] = GET_DWORD(long_temp); + } + else + { + status = JBIC_BOUNDS_ERROR; + } + } + break; + + case 0x59: /* PSHA */ + /* + * Push Boolean array + * ...argument 0 is variable ID + * ...stack 0 is count + * ...stack 1 is array index + */ + IF_CHECK_STACK(2) + { + variable_id = (unsigned int) args[0]; + + /* check that variable is a Boolean array */ + if ((attributes[variable_id] & 0x18) != 0x08) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + charptr_temp = (unsigned char *) variables[variable_id]; + + /* pop the count (number of bits to copy) */ + count = (unsigned int) stack[--stack_ptr]; + + /* pop the array index */ + index = (unsigned int) stack[stack_ptr - 1]; + + if (version > 0) + { + /* stack 0 = array right index */ + /* stack 1 = array left index */ + count = 1 + count - index; + } + + if ((count < 1) || (count > 32)) + { + status = JBIC_BOUNDS_ERROR; + } + else + { +#if PORT==DOS + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (stack[stack_ptr - 1] >> 16), version); + charptr_temp = jbi_aca_out_buffer; + } +#endif + long_temp = 0L; + + for (i = 0; i < count; ++i) + { + if (charptr_temp[(i + index) >> 3] & + (1 << ((i + index) & 7))) + { + long_temp |= (1L << i); + } + } + + stack[stack_ptr - 1] = long_temp; + } + } + } + break; + + case 0x5A: /* DYNA */ + /* + * Dynamically change size of array + * ...argument 0 is variable ID + * ...stack 0 is new size + */ + IF_CHECK_STACK(1) + { + variable_id = (unsigned int) args[0]; + long_temp = stack[--stack_ptr]; + + if (long_temp > variable_size[variable_id]) + { + variable_size[variable_id] = long_temp; + + if (attributes[variable_id] & 0x10) + { + /* allocate integer array */ + long_temp *= 4; + } + else + { + /* allocate Boolean array */ + long_temp = (long_temp + 7) >> 3; + } + + /* + * If the buffer was previously allocated, free it + */ + if ((attributes[variable_id] & 0x80) && + (variables[variable_id] != (addr_t) NULL)) + { + jbi_free((void *) variables[variable_id]); + variables[variable_id] = (addr_t) NULL; + } + + /* + * Allocate a new buffer of the requested size + */ + variables[variable_id] = (addr_t) + jbi_malloc((unsigned int) long_temp); + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + /* + * Set the attribute bit to indicate that this buffer + * was dynamically allocated and should be freed later + */ + attributes[variable_id] |= 0x80; + + /* zero out memory */ + count = (unsigned int) + ((variable_size[variable_id] + 7L) / 8L); + charptr_temp = (unsigned char *) + (variables[variable_id]); + for (index = 0; index < count; ++index) + { + charptr_temp[index] = 0; + } + } + } + } + break; + + case 0x5B: /* EXPR */ + bad_opcode = 1; + break; + + case 0x5C: /* EXPV */ + /* + * Export Boolean array + * ...argument 0 is string ID + * ...stack 0 is variable ID + * ...stack 1 is array right index + * ...stack 2 is array left index + */ + IF_CHECK_STACK(3) + { + if (version == 0) + { + /* EXPV is not supported in JBC 1.0 */ + bad_opcode = 1; + break; + } +#if PORT==DOS + name_id = args[0]; + for (j = 0; j < 32; ++j) + { + name[j] = GET_BYTE(string_table + name_id + j); + } + name[32] = '\0'; +#else + name = (char *) &program[string_table + args[0]]; +#endif + variable_id = (unsigned int) stack[--stack_ptr]; + long_index = stack[--stack_ptr]; /* right index */ + long_index2 = stack[--stack_ptr]; /* left index */ + + if (long_index > long_index2) + { + /* reverse indices not supported */ + status = JBIC_BOUNDS_ERROR; + break; + } + + long_count = 1 + long_index2 - long_index; + + charptr_temp = (unsigned char *) variables[variable_id]; + charptr_temp2 = NULL; + +#if PORT==DOS + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + charptr_temp = jbi_aca_out_buffer; + long_index &= 0x0000FFFF; + } +#endif + + if ((long_index & 7L) != 0) + { + charptr_temp2 = jbi_malloc((unsigned int) + ((long_count + 7L) / 8L)); + if (charptr_temp2 == NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + long k = long_index; + for (i = 0; i < (unsigned int) long_count; ++i) + { + if (charptr_temp[k >> 3] & (1 << (k & 7))) + { + charptr_temp2[i >> 3] |= (1 << (i & 7)); + } + else + { + charptr_temp2[i >> 3] &= ~(1 << (i & 7)); + } + + ++k; + } + charptr_temp = charptr_temp2; + } + } + else if (long_index != 0) + { + charptr_temp = &charptr_temp[long_index >> 3]; + } + + jbi_export_boolean_array(name, charptr_temp, long_count); + + /* free allocated buffer */ + if (((long_index & 7L) != 0) && (charptr_temp2 != NULL)) + { + jbi_free(charptr_temp2); + } + } + break; + + case 0x80: /* COPY */ + /* + * Array copy + * ...argument 0 is dest ID + * ...argument 1 is source ID + * ...stack 0 is count + * ...stack 1 is dest index + * ...stack 2 is source index + */ + IF_CHECK_STACK(3) + { + long copy_count = stack[--stack_ptr]; + long copy_index = stack[--stack_ptr]; + long copy_index2 = stack[--stack_ptr]; + long destleft; + long src_count; + long dest_count; + int src_reverse = 0; + int dest_reverse = 0; + + reverse = 0; + + if (version > 0) + { + /* stack 0 = source right index */ + /* stack 1 = source left index */ + /* stack 2 = destination right index */ + /* stack 3 = destination left index */ + destleft = stack[--stack_ptr]; + + if (copy_count > copy_index) + { + src_reverse = 1; + reverse = 1; + src_count = 1 + copy_count - copy_index; + /* copy_index = source start index */ + } + else + { + src_count = 1 + copy_index - copy_count; + copy_index = copy_count; /* source start index */ + } + + if (copy_index2 > destleft) + { + dest_reverse = 1; + reverse = !reverse; + dest_count = 1 + copy_index2 - destleft; + copy_index2 = destleft; /* destination start index */ + } + else + { + dest_count = 1 + destleft - copy_index2; + /* copy_index2 = destination start index */ + } + + copy_count = (src_count < dest_count) ? src_count : dest_count; + + if ((src_reverse || dest_reverse) && + (src_count != dest_count)) + { + /* If either the source or destination is reversed, */ + /* we can't tolerate a length mismatch, because we */ + /* "left justify" the arrays when copying. This */ + /* won't work correctly with reversed arrays. */ + status = JBIC_BOUNDS_ERROR; + } + } + + count = (unsigned int) copy_count; + index = (unsigned int) copy_index; + index2 = (unsigned int) copy_index2; + + /* + * If destination is a read-only array, allocate a buffer + * and convert it to a writable array + */ + variable_id = (unsigned int) args[1]; + if ((version > 0) && ((attributes[variable_id] & 0x9c) == 0x0c)) + { + /* + * Allocate a writable buffer for this array + */ + long_temp = (variable_size[variable_id] + 7L) >> 3L; + charptr_temp2 = (unsigned char *) variables[variable_id]; + charptr_temp = jbi_malloc((unsigned int) long_temp); + variables[variable_id] = (addr_t) charptr_temp; + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + /* zero the buffer */ + for (long_index = 0L; + long_index < long_temp; + ++long_index) + { + charptr_temp[long_index] = 0; + } + + /* copy previous contents into buffer */ + for (long_index = 0L; + long_index < variable_size[variable_id]; + ++long_index) + { +#if PORT==DOS + if ((attributes[variable_id] & 0x02) && + ((long_index & 0x0000FFFF) == 0L)) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + charptr_temp = jbi_aca_out_buffer; + long_index2 = long_index & 0xFFFF; + } +#else + long_index2 = long_index; +#endif + + if (charptr_temp2[long_index2 >> 3] & + (1 << (long_index2 & 7))) + { + charptr_temp[long_index >> 3] |= + (1 << (long_index & 7)); + } + } + + /* set bit 7 - buffer was dynamically allocated */ + attributes[variable_id] |= 0x80; + + /* clear bit 2 - variable is writable */ + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } + } + +#if PORT==DOS + /* for 16-bit version, allow writing in allocated buffers */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x8c)) + { + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } +#endif + + charptr_temp = (unsigned char *) variables[args[1]]; + charptr_temp2 = (unsigned char *) variables[args[0]]; + +#if PORT==DOS + variable_id = (unsigned int) args[0]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (copy_index >> 16), version); + charptr_temp2 = jbi_aca_out_buffer; + } +#endif + + /* check that destination is a writable Boolean array */ + if ((attributes[args[1]] & 0x1c) != 0x08) + { + status = JBIC_BOUNDS_ERROR; + break; + } + + if (count < 1) + { + status = JBIC_BOUNDS_ERROR; + } + else + { + if (reverse) + { + index2 += (count - 1); + } + + for (i = 0; i < count; ++i) + { + if (charptr_temp2[index >> 3] & (1 << (index & 7))) + { + charptr_temp[index2 >> 3] |= (1 << (index2 & 7)); + } + else + { + charptr_temp[index2 >> 3] &= + ~(unsigned int) (1 << (index2 & 7)); + } + ++index; + if (reverse) --index2; else ++index2; + } + } + } + break; + + case 0x81: /* REVA */ + /* + * ARRAY COPY reversing bit order + * ...argument 0 is dest ID + * ...argument 1 is source ID + * ...stack 0 is dest index + * ...stack 1 is source index + * ...stack 2 is count + */ + bad_opcode = 1; + break; + + case 0x82: /* DSC */ + case 0x83: /* ISC */ + /* + * DRSCAN with capture + * IRSCAN with capture + * ...argument 0 is scan data variable ID + * ...argument 1 is capture variable ID + * ...stack 0 is capture index + * ...stack 1 is scan data index + * ...stack 2 is count + */ + IF_CHECK_STACK(3) + { + long scan_right, scan_left; + long capture_count = 0; + long scan_count = 0; + long capture_index = stack[--stack_ptr]; + long scan_index = stack[--stack_ptr]; + if (version > 0) + { + /* stack 0 = capture right index */ + /* stack 1 = capture left index */ + /* stack 2 = scan right index */ + /* stack 3 = scan left index */ + /* stack 4 = count */ + scan_right = stack[--stack_ptr]; + scan_left = stack[--stack_ptr]; + capture_count = 1 + scan_index - capture_index; + scan_count = 1 + scan_left - scan_right; + scan_index = scan_right; + } + long_count = stack[--stack_ptr]; + + /* + * If capture array is read-only, allocate a buffer + * and convert it to a writable array + */ + variable_id = (unsigned int) args[1]; + if ((version > 0) && ((attributes[variable_id] & 0x9c) == 0x0c)) + { + /* + * Allocate a writable buffer for this array + */ + long_temp = (variable_size[variable_id] + 7L) >> 3L; + charptr_temp2 = (unsigned char *) variables[variable_id]; + charptr_temp = jbi_malloc((unsigned int) long_temp); + variables[variable_id] = (addr_t) charptr_temp; + + if (variables[variable_id] == (addr_t) NULL) + { + status = JBIC_OUT_OF_MEMORY; + break; + } + else + { + /* zero the buffer */ + for (long_index = 0L; + long_index < long_temp; + ++long_index) + { + charptr_temp[long_index] = 0; + } + + /* copy previous contents into buffer */ + for (long_index = 0L; + long_index < variable_size[variable_id]; + ++long_index) + { +#if PORT==DOS + if ((attributes[variable_id] & 0x02) && + ((long_index & 0x0000FFFF) == 0L)) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (long_index >> 16), version); + charptr_temp = jbi_aca_out_buffer; + long_index2 = long_index & 0xFFFF; + } +#else + long_index2 = long_index; +#endif + + if (charptr_temp2[long_index2 >> 3] & + (1 << (long_index2 & 7))) + { + charptr_temp[long_index >> 3] |= + (1 << (long_index & 7)); + } + } + + /* set bit 7 - buffer was dynamically allocated */ + attributes[variable_id] |= 0x80; + + /* clear bit 2 - variable is writable */ + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } + } + +#if PORT==DOS + /* for 16-bit version, allow writing in allocated buffers */ + if ((version > 0) && + ((attributes[variable_id] & 0x9c) == 0x8c)) + { + attributes[variable_id] &= ~0x04; + attributes[variable_id] |= 0x01; + } +#endif + + charptr_temp = (unsigned char *) variables[args[0]]; + charptr_temp2 = (unsigned char *) variables[args[1]]; + +#if PORT==DOS + variable_id = (unsigned int) args[0]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + /* initialized compressed Boolean array */ + jbi_uncompress_page(variable_id, + (int) (scan_index >> 16), version); + scan_index &= 0x0000ffff; + charptr_temp = jbi_aca_out_buffer; + } +#endif + + if ((version > 0) && + ((long_count > capture_count) || (long_count > scan_count))) + { + status = JBIC_BOUNDS_ERROR; + } + + /* check that capture array is a writable Boolean array */ + if ((attributes[args[1]] & 0x1c) != 0x08) + { + status = JBIC_BOUNDS_ERROR; + } + + if (status == JBIC_SUCCESS) + { + if (opcode == 0x82) /* DSC */ + { + status = jbi_swap_dr((unsigned int) long_count, + charptr_temp, (unsigned long) scan_index, + charptr_temp2, (unsigned int) capture_index); + } + else /* ISC */ + { + status = jbi_swap_ir((unsigned int) long_count, + charptr_temp, (unsigned int) scan_index, + charptr_temp2, (unsigned int) capture_index); + } + } + } + break; + + case 0x84: /* WAIT */ + /* + * WAIT + * ...argument 0 is wait state + * ...argument 1 is end state + * ...stack 0 is cycles + * ...stack 1 is microseconds + */ + IF_CHECK_STACK(2) + { + long_temp = stack[--stack_ptr]; + + if (long_temp != 0L) + { + status = jbi_do_wait_cycles(long_temp, (unsigned int) args[0]); + } + + long_temp = stack[--stack_ptr]; + + if ((status == JBIC_SUCCESS) && (long_temp != 0L)) + { + status = jbi_do_wait_microseconds(long_temp, (unsigned int) args[0]); + } + + if ((status == JBIC_SUCCESS) && (args[1] != args[0])) + { + status = jbi_goto_jtag_state((unsigned int) args[1]); + } + + if (version > 0) + { + --stack_ptr; /* throw away MAX cycles */ + --stack_ptr; /* throw away MAX microseconds */ + } + } + break; + + case 0x85: /* VS */ + /* + * VECTOR + * ...argument 0 is dir data variable ID + * ...argument 1 is scan data variable ID + * ...stack 0 is dir array index + * ...stack 1 is scan array index + * ...stack 2 is count + */ + bad_opcode = 1; + break; + + case 0xC0: /* CMPA */ + /* + * Array compare + * ...argument 0 is source 1 ID + * ...argument 1 is source 2 ID + * ...argument 2 is mask ID + * ...stack 0 is source 1 index + * ...stack 1 is source 2 index + * ...stack 2 is mask index + * ...stack 3 is count + */ + IF_CHECK_STACK(4) + { + long a, b; + unsigned char *source1 = (unsigned char *) variables[args[0]]; + unsigned char *source2 = (unsigned char *) variables[args[1]]; + unsigned char *mask = (unsigned char *) variables[args[2]]; + unsigned long index1 = stack[--stack_ptr]; + unsigned long index2 = stack[--stack_ptr]; + unsigned long mask_index = stack[--stack_ptr]; + long_count = stack[--stack_ptr]; + + if (version > 0) + { + /* stack 0 = source 1 right index */ + /* stack 1 = source 1 left index */ + /* stack 2 = source 2 right index */ + /* stack 3 = source 2 left index */ + /* stack 4 = mask right index */ + /* stack 5 = mask left index */ + long mask_right = stack[--stack_ptr]; + long mask_left = stack[--stack_ptr]; + a = 1 + index2 - index1; /* source 1 count */ + b = 1 + long_count - mask_index; /* source 2 count */ + a = (a < b) ? a : b; + b = 1 + mask_left - mask_right; /* mask count */ + a = (a < b) ? a : b; + index2 = mask_index; /* source 2 start index */ + mask_index = mask_right; /* mask start index */ + long_count = a; + } + + long_temp = 1L; + + if (long_count < 1) + { + status = JBIC_BOUNDS_ERROR; + } + else + { +#if PORT==DOS + variable_id = (unsigned int) args[0]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + jbi_uncompress_page(variable_id, + (int) (index1 >> 16), version); + index1 &= 0x0000ffff; + source1 = jbi_aca_out_buffer; + } + + variable_id = (unsigned int) args[1]; + if ((attributes[variable_id] & 0x1e) == 0x0e) + { + jbi_uncompress_page(variable_id, + (int) (index2 >> 16), version); + index2 &= 0x0000ffff; + source2 = jbi_aca_out_buffer; + } +#endif + count = (unsigned int) long_count; + + for (i = 0; i < count; ++i) + { + if (mask[mask_index >> 3] & (1 << (mask_index & 7))) + { + a = source1[index1 >> 3] & (1 << (index1 & 7)) + ? 1 : 0; + b = source2[index2 >> 3] & (1 << (index2 & 7)) + ? 1 : 0; + + if (a != b) long_temp = 0L; /* failure */ + } + ++index1; + ++index2; + ++mask_index; + } + } + + stack[stack_ptr++] = long_temp; + } + break; + + case 0xC1: /* VSC */ + /* + * VECTOR with capture + * ...argument 0 is dir data variable ID + * ...argument 1 is scan data variable ID + * ...argument 2 is capture variable ID + * ...stack 0 is capture index + * ...stack 1 is scan data index + * ...stack 2 is dir data index + * ...stack 3 is count + */ + bad_opcode = 1; + break; + + default: + /* + * Unrecognized opcode -- ERROR! + */ + bad_opcode = 1; + break; + } + + if (bad_opcode) + { + status = JBIC_ILLEGAL_OPCODE; + } + + if ((stack_ptr < 0) || (stack_ptr >= JBI_STACK_SIZE)) + { + status = JBIC_STACK_OVERFLOW; + } + + if (status != JBIC_SUCCESS) + { + done = 1; + *error_address = (long) (opcode_address - code_section); + } + } + jbi_dbg(DEBUG_DETAIL, "debug_cnt(total): 0x%lx\n", debug_cnt); + + jbi_dbg(DEBUG_NOISY, "jbi_free_jtag_padding_buffers\n"); + jbi_free_jtag_padding_buffers(reset_jtag); + + /* + * Free all dynamically allocated arrays + */ + jbi_dbg(DEBUG_NOISY, "jbi_free_attributes\n"); + if ((attributes != NULL) && (variables != NULL)) + { + for (i = 0; i < (unsigned int) symbol_count; ++i) + { + if ((attributes[i] & 0x80) && (variables[i] != (addr_t) NULL) + && (variables[i] != (addr_t) 1)) + { + jbi_free((void *) variables[i]); + } + } + } + + if (variables != NULL) jbi_free(variables); + + if (variable_size != NULL) jbi_free(variable_size); + + if (attributes != NULL) jbi_free(attributes); + + if (proc_attributes != NULL) jbi_free(proc_attributes); + + jbi_dbg(DEBUG_NOISY, "return status %d\n", status); + kfree(message_buffer); + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_get_note +( + PROGRAM_PTR program, + long program_size, + long *offset, + char *key, + char *value, + int length +) + +/* */ +/* Description: Gets key and value of NOTE fields in the JBC file. */ +/* Can be called in two modes: if offset pointer is NULL, */ +/* then the function searches for note fields which match */ +/* the key string provided. If offset is not NULL, then */ +/* the function finds the next note field of any key, */ +/* starting at the offset specified by the offset pointer. */ +/* */ +/* Returns: JBIC_SUCCESS for success, else appropriate error code */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_UNEXPECTED_END; + unsigned long note_strings = 0L; + unsigned long note_table = 0L; + unsigned long note_count = 0L; + unsigned long first_word = 0L; + int version = 0; + int delta = 0; + char *key_ptr; + char *value_ptr; + int i; + +#if PORT==DOS + int count = 0; + int done = 0; + long long_index = 0; + char key_buffer[256]; + char value_buffer[256]; + + jbi_program = program; +#endif + + /* + * Read header information + */ + if (program_size > 52L) + { + first_word = GET_DWORD(0); + version = (int) (first_word & 1L); + delta = version * 8; + + note_strings = GET_DWORD(8 + delta); + note_table = GET_DWORD(12 + delta); + note_count = GET_DWORD(44 + (2 * delta)); + } + + if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) + { + status = JBIC_IO_ERROR; + } + else if (note_count > 0L) + { + if (offset == NULL) + { + /* + * We will search for the first note with a specific key, and + * return only the value + */ + for (i = 0; (i < (int) note_count) && (status != JBIC_SUCCESS); ++i) + { +#if PORT==DOS + done = 0; + count = 0; + long_index = note_strings + GET_DWORD(note_table + (8 * i)); + while ((count < 255) && !done) + { + key_buffer[count] = GET_BYTE(long_index); + if (key_buffer[count] == '\0') done = 1; + ++long_index; + ++count; + } + key_buffer[255] = '\0'; + key_ptr = key_buffer; +#else + key_ptr = (char *) &program[note_strings + + GET_DWORD(note_table + (8 * i))]; +#endif + if ((key != NULL) && (jbi_stricmp(key, key_ptr) == 0)) + { + status = JBIC_SUCCESS; + +#if PORT==DOS + done = 0; + count = 0; + long_index = note_strings + GET_DWORD(note_table + (8 * i) + 4); + while ((count < 255) && !done) + { + value_buffer[count] = GET_BYTE(long_index); + if (value_buffer[count] == '\0') done = 1; + ++long_index; + ++count; + } + value_buffer[255] = '\0'; + value_ptr = value_buffer; +#else + value_ptr = (char *) &program[note_strings + + GET_DWORD(note_table + (8 * i) + 4)]; +#endif + + if (value != NULL) + { + jbi_strncpy(value, value_ptr, length); + } + } + } + } + else + { + /* + * We will search for the next note, regardless of the key, and + * return both the value and the key + */ + + i = (int) *offset; + + if ((i >= 0) && (i < (int) note_count)) + { + status = JBIC_SUCCESS; + + if (key != NULL) + { +#if PORT==DOS + done = 0; + count = 0; + long_index = note_strings + + GET_DWORD(note_table + (8 * i)); + + while ((count < length) && !done) + { + key[count] = GET_BYTE(long_index); + if (key[count] == '\0') done = 1; + ++long_index; + ++count; + } +#else + jbi_strncpy(key, (char *) &program[note_strings + + GET_DWORD(note_table + (8 * i))], length); +#endif + } + + if (value != NULL) + { +#if PORT==DOS + done = 0; + count = 0; + long_index = note_strings + + GET_DWORD(note_table + (8 * i) + 4); + + while ((count < length) && !done) + { + value[count] = GET_BYTE(long_index); + if (value[count] == '\0') done = 1; + ++long_index; + ++count; + } +#else + jbi_strncpy(value, (char *) &program[note_strings + + GET_DWORD(note_table + (8 * i) + 4)], length); +#endif + } + + *offset = i + 1; + } + } + } + + return (status); +} + +/****************************************************************************/ +/* */ + +JBI_RETURN_TYPE jbi_check_crc +( + PROGRAM_PTR program, + long program_size, + unsigned short *expected_crc, + unsigned short *actual_crc +) + +/* */ +/* Description: This function reads the entire input file and computes */ +/* the CRC of everything up to the CRC field. */ +/* */ +/* Returns: JBIC_SUCCESS for success, JBIC_CRC_ERROR for failure */ +/* */ +/****************************************************************************/ +{ + JBI_RETURN_TYPE status = JBIC_SUCCESS; + unsigned short local_expected, local_actual, shift_reg = 0xffff; + int bit, feedback; + unsigned char databyte; + unsigned long i; + unsigned long crc_section = 0L; + unsigned long first_word = 0L; + int version = 0; + int delta = 0; + +#if PORT==DOS + jbi_program = program; +#endif + + if (program_size > 52L) + { + first_word = GET_DWORD(0); + version = (int) (first_word & 1L); + delta = version * 8; + + crc_section = GET_DWORD(32 + delta); + } + + if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) + { + status = JBIC_IO_ERROR; + } + + if (crc_section >= (unsigned long) program_size) + { + status = JBIC_IO_ERROR; + } + + if (status == JBIC_SUCCESS) + { + local_expected = (unsigned short) GET_WORD(crc_section); + if (expected_crc != NULL) *expected_crc = local_expected; + + for (i = 0; i < crc_section; ++i) + { + databyte = GET_BYTE(i); + for (bit = 0; bit < 8; bit++) /* compute for each bit */ + { + feedback = (databyte ^ shift_reg) & 0x01; + shift_reg >>= 1; /* shift the shift register */ + if (feedback) shift_reg ^= 0x8408; /* invert selected bits */ + databyte >>= 1; /* get the next bit of input_byte */ + } + } + + local_actual = (unsigned short) ~shift_reg; + if (actual_crc != NULL) *actual_crc = local_actual; + + if (local_expected != local_actual) + { + status = JBIC_CRC_ERROR; + } + } + + return (status); +} + +JBI_RETURN_TYPE jbi_get_file_info +( + PROGRAM_PTR program, + long program_size, + int *format_version, + int *action_count, + int *procedure_count +) +{ + JBI_RETURN_TYPE status = JBIC_IO_ERROR; + unsigned long first_word = 0; + int version = 0; + +#if PORT==DOS + jbi_program = program; +#endif + + /* + * Read header information + */ + if (program_size > 52L) + { + first_word = GET_DWORD(0); + + if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) + { + status = JBIC_SUCCESS; + + version = (int) (first_word & 1L); + *format_version = version + 1; + + if (version > 0) + { + *action_count = (int) GET_DWORD(48); + *procedure_count = (int) GET_DWORD(52); + } + } + + } + + return (status); +} + +JBI_RETURN_TYPE jbi_get_action_info +( + PROGRAM_PTR program, + long program_size, + int index, + char **name, + char **description, + JBI_PROCINFO **procedure_list +) +{ + JBI_RETURN_TYPE status = JBIC_IO_ERROR; + JBI_PROCINFO *procptr = NULL; + JBI_PROCINFO *tmpptr = NULL; + unsigned long first_word = 0L; + unsigned long action_table = 0L; + unsigned long proc_table = 0L; + unsigned long string_table = 0L; + unsigned long note_strings = 0L; + unsigned long action_count = 0L; + unsigned long proc_count = 0L; + unsigned long act_name_id = 0L; + unsigned long act_desc_id = 0L; + unsigned long act_proc_id = 0L; + unsigned long act_proc_name = 0L; + unsigned char act_proc_attribute = 0; + +#if PORT==DOS + int i, length; + jbi_program = program; +#endif + + /* + * Read header information + */ + if (program_size > 52L) + { + first_word = GET_DWORD(0); + + if (first_word == 0x4A414D01L) + { + action_table = GET_DWORD(4); + proc_table = GET_DWORD(8); + string_table = GET_DWORD(12); + note_strings = GET_DWORD(16); + action_count = GET_DWORD(48); + proc_count = GET_DWORD(52); + + if (index < (int) action_count) + { + act_name_id = GET_DWORD(action_table + (12 * index)); + act_desc_id = GET_DWORD(action_table + (12 * index) + 4); + act_proc_id = GET_DWORD(action_table + (12 * index) + 8); + +#if PORT==DOS + length = 0; + while (GET_BYTE(string_table + act_name_id + length) != 0) ++length; + *name = jbi_malloc(length + 1); + if (*name == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + for (i = 0; i < length; ++i) + { + (*name)[i] = GET_BYTE(string_table + act_name_id + i); + } + (*name)[length] = '\0'; + } +#else + *name = (char *) &program[string_table + act_name_id]; +#endif + + if (act_desc_id < (note_strings - string_table)) + { +#if PORT==DOS + length = 0; + while (GET_BYTE(string_table + act_desc_id + length) != 0) ++length; + *description = jbi_malloc(length + 1); + if (*description == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + for (i = 0; i < length; ++i) + { + (*description)[i] = GET_BYTE(string_table + act_desc_id + i); + } + (*description)[length] = '\0'; + } +#else + *description = (char *) &program[string_table + act_desc_id]; +#endif + } + + do + { + act_proc_name = GET_DWORD(proc_table + (13 * act_proc_id)); + act_proc_attribute = (unsigned char) + (GET_BYTE(proc_table + (13 * act_proc_id) + 8) & 0x03); + + procptr = (JBI_PROCINFO *) jbi_malloc(sizeof(JBI_PROCINFO)); + + if (procptr == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { +#if PORT==DOS + length = 0; + while (GET_BYTE(string_table + act_proc_name + length) != 0) ++length; + procptr->name = jbi_malloc(length + 1); + if (procptr->name == NULL) + { + status = JBIC_OUT_OF_MEMORY; + } + else + { + for (i = 0; i < length; ++i) + { + procptr->name[i] = + GET_BYTE(string_table + act_proc_name + i); + } + procptr->name[length] = '\0'; + } +#else + procptr->name = (char *) + &program[string_table + act_proc_name]; +#endif + procptr->attributes = act_proc_attribute; + procptr->next = NULL; + + /* add record to end of linked list */ + if (*procedure_list == NULL) + { + *procedure_list = procptr; + } + else + { + tmpptr = *procedure_list; + while (tmpptr->next != NULL) tmpptr = tmpptr->next; + tmpptr->next = procptr; + } + } + + act_proc_id = + GET_DWORD(proc_table + (13 * act_proc_id) + 4); + } + while ((act_proc_id != 0) && (act_proc_id < proc_count)); + } + } + + } + + return (status); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiport.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiport.h new file mode 100644 index 000000000000..28669dc81ff6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbiport.h @@ -0,0 +1,45 @@ +/****************************************************************************/ +/* */ +/* Module: jbiport.h */ +/* */ +/* Copyright (C) Altera Corporation 2000-2001 */ +/* */ +/* Description: Defines porting macros */ +/* */ +/****************************************************************************/ + +#ifndef INC_JBIPORT_H +#define INC_JBIPORT_H + +/* +* PORT defines the target platform: DOS, WINDOWS, UNIX, or EMBEDDED +* +* PORT = DOS means a 16-bit DOS console-mode application +* +* PORT = WINDOWS means a 32-bit WIN32 console-mode application for +* Windows 95, 98, 2000, ME or NT. On NT this will use the +* DeviceIoControl() API to access the Parallel Port. +* +* PORT = UNIX means any UNIX system. BitBlaster access is support via +* the standard ANSI system calls open(), read(), write(). +* The ByteBlaster is not supported. +* +* PORT = EMBEDDED means all DOS, WINDOWS, and UNIX code is excluded. +* Remaining code supports 16 and 32-bit compilers. +* Additional porting steps may be necessary. See readme +* file for more details. +*/ + +#define DOS 2 +#define WINDOWS 3 +#define UNIX 4 +#define EMBEDDED 5 + +#define PORT EMBEDDED + +#ifndef PORT +/* change this line to build a different port */ +#define PORT WINDOWS +#endif + +#endif /* INC_JBIPORT_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.c new file mode 100644 index 000000000000..396c92caca2b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.c @@ -0,0 +1,2518 @@ +/****************************************************************************/ +/* */ +/* Module: jbistub.c */ +/* */ +/* Copyright (C) Altera Corporation 1997-2001 */ +/* */ +/* Description: Jam STAPL ByteCode Player main source file */ +/* */ +/* Supports Altera ByteBlaster hardware download cable */ +/* on Windows 95 and Windows NT operating systems. */ +/* (A device driver is required for Windows NT.) */ +/* */ +/* Also supports BitBlaster hardware download cable on */ +/* Windows 95, Windows NT, and UNIX platforms. */ +/* */ +/* Revisions: 1.1 fixed control port initialization for ByteBlaster */ +/* 2.0 added support for STAPL bytecode format, added code */ +/* to get printer port address from Windows registry */ +/* 2.1 improved messages, fixed delay-calibration bug in */ +/* 16-bit DOS port, added support for "alternative */ +/* cable X", added option to control whether to reset */ +/* the TAP after execution, moved porting macros into */ +/* jbiport.h */ +/* 2.2 added support for static memory */ +/* fixed /W4 warnings */ +/* */ +/****************************************************************************/ + +#ifndef NO_ALTERA_STDIO +#define NO_ALTERA_STDIO +#endif + +#if 0 +#if ( _MSC_VER >= 800 ) +#pragma warning(disable:4115) +#pragma warning(disable:4201) +#pragma warning(disable:4214) +#pragma warning(disable:4514) +#endif +#endif + +#include "jbiport.h" + +#if PORT == WINDOWS +#include +#else +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +#if PORT == EMBEDDED +typedef unsigned int DWORD; +#else +typedef unsigned long DWORD; +#endif +#define TRUE 1 +#define FALSE 0 +#endif + +#if PORT != EMBEDDED +#include +#include +#include +#include +#include +#include +#endif + +#include + +#include "jbiexprt.h" +#include "jbistub.h" + +#if defined(USE_STATIC_MEMORY) + #define N_STATIC_MEMORY_KBYTES ((unsigned int) USE_STATIC_MEMORY) + #define N_STATIC_MEMORY_BYTES (N_STATIC_MEMORY_KBYTES * 1024) + #define POINTER_ALIGNMENT sizeof(DWORD) +#else /* USE_STATIC_MEMORY */ + /* #include */ + #define POINTER_ALIGNMENT sizeof(BYTE) +#endif /* USE_STATIC_MEMORY */ + +#if PORT != EMBEDDED +#include +#include +#include +#include +#include +#endif + +#if PORT == DOS +#include +#endif + +int jbi_debug_level = DEBUG_NONE; +static long jbi_delay_us = 0, jbi_delay_count = 0, jbi_peak_us = 0; + +void __jbi_jtag_udelay(unsigned long us) +{ + udelay(us); +} +void jbi_jtag_udelay(unsigned long us) __attribute__((weak, alias("__jbi_jtag_udelay"))); + +#if PORT == WINDOWS +#define PGDC_IOCTL_GET_DEVICE_INFO_PP 0x00166A00L +#define PGDC_IOCTL_READ_PORT_PP 0x00166A04L +#define PGDC_IOCTL_WRITE_PORT_PP 0x0016AA08L +#define PGDC_IOCTL_PROCESS_LIST_PP 0x0016AA1CL +#define PGDC_READ_INFO 0x0a80 +#define PGDC_READ_PORT 0x0a81 +#define PGDC_WRITE_PORT 0x0a82 +#define PGDC_PROCESS_LIST 0x0a87 +#define PGDC_HDLC_NTDRIVER_VERSION 2 +#define PORT_IO_BUFFER_SIZE 256 +#endif + +#if PORT == WINDOWS +#ifdef __BORLANDC__ +/* create dummy inp() and outp() functions for Borland 32-bit compile */ +WORD inp(WORD address) { address = address; return(0); } +void outp(WORD address, WORD data) { address = address; data = data; } +#else +#pragma intrinsic (inp, outp) +#endif +#endif + +/* +* For Borland C compiler (16-bit), set the stack size +*/ +#if PORT == DOS +#ifdef __BORLANDC__ +extern unsigned int _stklen = 50000; +#endif +#endif + +/************************************************************************ +* +* Global variables +*/ + +/* file buffer for Jam STAPL ByteCode input file */ +#if PORT == DOS +unsigned char **file_buffer = NULL; +#else +unsigned char *file_buffer = NULL; +#endif +long file_pointer = 0L; +long file_length = 0L; + +/* delay count for one millisecond delay */ +long one_ms_delay = 0L; + +/* serial port interface available on all platforms */ +BOOL jtag_hardware_initialized = FALSE; +char *serial_port_name = NULL; +BOOL specified_com_port = FALSE; +int com_port = -1; +void initialize_jtag_hardware(void); +void close_jtag_hardware(void); + +#if defined(USE_STATIC_MEMORY) + unsigned char static_memory_heap[N_STATIC_MEMORY_BYTES] = { 0 }; +#endif /* USE_STATIC_MEMORY */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + unsigned int n_bytes_allocated = 0; +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(MEM_TRACKER) + unsigned int peak_memory_usage = 0; + unsigned int peak_allocations = 0; + unsigned int n_allocations = 0; +#if defined(USE_STATIC_MEMORY) + unsigned int n_bytes_not_recovered = 0; +#endif /* USE_STATIC_MEMORY */ + const DWORD BEGIN_GUARD = 0x01234567; + const DWORD END_GUARD = 0x76543210; +#endif /* MEM_TRACKER */ + +#if PORT == WINDOWS || PORT == DOS +/* parallel port interface available on PC only */ +BOOL specified_lpt_port = FALSE; +BOOL specified_lpt_addr = FALSE; +int lpt_port = 1; +int initial_lpt_ctrl = 0; +WORD lpt_addr = 0x3bc; +WORD lpt_addr_table[3] = { 0x3bc, 0x378, 0x278 }; +BOOL alternative_cable_l = FALSE; +BOOL alternative_cable_x = FALSE; +void write_byteblaster(int port, int data); +int read_byteblaster(int port); +#endif + +#if PORT==WINDOWS +#ifndef __BORLANDC__ +WORD lpt_addresses_from_registry[4] = { 0 }; +#endif +#endif + +#if PORT == WINDOWS +/* variables to manage cached I/O under Windows NT */ +BOOL windows_nt = FALSE; +int port_io_count = 0; +HANDLE nt_device_handle = INVALID_HANDLE_VALUE; +struct PORT_IO_LIST_STRUCT +{ + USHORT command; + USHORT data; +} port_io_buffer[PORT_IO_BUFFER_SIZE]; +extern void flush_ports(void); +BOOL initialize_nt_driver(void); +#endif + +/* function prototypes to allow forward reference */ +extern void delay_loop(long count); + +/* +* This structure stores information about each available vector signal +*/ +struct VECTOR_LIST_STRUCT +{ + char *signal_name; + int hardware_bit; + int vector_index; +}; + +struct VECTOR_LIST_STRUCT vector_list[] = +{ + /* add a record here for each vector signal */ + { "", 0, -1 } +}; + +#define VECTOR_SIGNAL_COUNT ((int)(sizeof(vector_list)/sizeof(vector_list[0]))) + +BOOL verbose = FALSE; + +/************************************************************************ +* +* Customized interface functions for Jam STAPL ByteCode Player I/O: +* +* jbi_jtag_io() +* jbi_message() +* jbi_delay() +*/ + +int jbi_jtag_io(int tms, int tdi, int read_tdo) +{ +#if PORT == WINDOWS || PORT == DOS + int data = 0; +#endif + int tdo = 0; + int i = 0; + int result = 0; + char ch_data = 0; + + if (!jtag_hardware_initialized) + { + initialize_jtag_hardware(); + jtag_hardware_initialized = TRUE; + } + + if (specified_com_port) + { + ch_data = (char) + ((tdi ? 0x01 : 0) | (tms ? 0x02 : 0) | 0x60); + + write(com_port, &ch_data, 1); + + if (read_tdo) + { + ch_data = 0x7e; + write(com_port, &ch_data, 1); + for (i = 0; (i < 100) && (result != 1); ++i) + { + result = read(com_port, &ch_data, 1); + } + if (result == 1) + { + tdo = ch_data & 0x01; + } + else + { + fprintf(stderr, "Error: BitBlaster not responding\n"); + } + } + + ch_data = (char) + ((tdi ? 0x01 : 0) | (tms ? 0x02 : 0) | 0x64); + + write(com_port, &ch_data, 1); + } + else + { +#if PORT == WINDOWS || PORT == DOS + data = (alternative_cable_l ? ((tdi ? 0x01 : 0) | (tms ? 0x04 : 0)) : + (alternative_cable_x ? ((tdi ? 0x01 : 0) | (tms ? 0x04 : 0) | 0x10) : + ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0)))); + + write_byteblaster(0, data); + + if (read_tdo) + { + tdo = read_byteblaster(1); + tdo = (alternative_cable_l ? ((tdo & 0x40) ? 1 : 0) : + (alternative_cable_x ? ((tdo & 0x10) ? 1 : 0) : + ((tdo & 0x80) ? 0 : 1))); + } + + write_byteblaster(0, data | (alternative_cable_l ? 0x02 : (alternative_cable_x ? 0x02: 0x01))); + + write_byteblaster(0, data); +#elif PORT == EMBEDDED + /* Output variables TDI, TMS to the corresponding pin; As read_tdo, return the corresponding pin to the variable tdo */ + tdo = jbi_jtag_io_(tms, tdi, read_tdo); +#else + /* parallel port interface not available */ + tdo = 0; +#endif + } + + return (tdo); +} + +void jbi_message(char *message_text) +{ + puts(message_text); + puts("\n"); + fflush(stdout); +} + +void jbi_export_integer(char *key, long value) +{ + if (verbose) + { + printf("Export: key = \"%s\", value = %ld\n", key, value); + fflush(stdout); + } +} + +#define HEX_LINE_CHARS 72 +#define HEX_LINE_BITS (HEX_LINE_CHARS * 4) + +char conv_to_hex(unsigned long value) +{ + char c; + + if (value > 9) + { + c = (char) (value + ('A' - 10)); + } + else + { + c = (char) (value + '0'); + } + + return (c); +} + +void jbi_export_boolean_array(char *key, unsigned char *data, long count) +{ + char string[HEX_LINE_CHARS + 1]; + long i, offset; + unsigned long size, line, lines, linebits, value, j, k; + + if (verbose) + { + if (count > HEX_LINE_BITS) + { + printf("Export: key = \"%s\", %ld bits, value = HEX\n", key, count); + lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS; + + for (line = 0; line < lines; ++line) + { + if (line < (lines - 1)) + { + linebits = HEX_LINE_BITS; + size = HEX_LINE_CHARS; + offset = count - ((line + 1) * HEX_LINE_BITS); + } + else + { + linebits = count - ((lines - 1) * HEX_LINE_BITS); + size = (linebits + 3) / 4; + offset = 0L; + } + + string[size] = '\0'; + j = size - 1; + value = 0; + + for (k = 0; k < linebits; ++k) + { + i = k + offset; + if (data[i >> 3] & (1 << (i & 7))) value |= (1 << (i & 3)); + if ((i & 3) == 3) + { + string[j] = conv_to_hex(value); + value = 0; + --j; + } + } + if ((k & 3) > 0) string[j] = conv_to_hex(value); + + printf("%s\n", string); + } + + fflush(stdout); + } + else + { + size = (count + 3) / 4; + string[size] = '\0'; + j = size - 1; + value = 0; + + for (i = 0; i < count; ++i) + { + if (data[i >> 3] & (1 << (i & 7))) value |= (1 << (i & 3)); + if ((i & 3) == 3) + { + string[j] = conv_to_hex(value); + value = 0; + --j; + } + } + if ((i & 3) > 0) string[j] = conv_to_hex(value); + + printf("Export: key = \"%s\", %ld bits, value = HEX %s\n", + key, count, string); + fflush(stdout); + } + } +} + +void jbi_delay(long microseconds) +{ + if (jbi_peak_us < microseconds) { + jbi_peak_us = microseconds; + } + jbi_delay_us += microseconds; + jbi_delay_count++; + +#if PORT == WINDOWS + /* if Windows NT, flush I/O cache buffer before delay loop */ + if (windows_nt && (port_io_count > 0)) flush_ports(); +#endif + +#if PORT == EMBEDDED + udelay(microseconds); +#else + delay_loop(microseconds * + ((one_ms_delay / 1000L) + ((one_ms_delay % 1000L) ? 1 : 0))); +#endif +} + +int jbi_vector_map +( + int signal_count, + char **signals +) +{ + int signal, vector, ch_index, diff; + int matched_count = 0; + char l, r; + + for (vector = 0; (vector < VECTOR_SIGNAL_COUNT); ++vector) + { + vector_list[vector].vector_index = -1; + } + + for (signal = 0; signal < signal_count; ++signal) + { + diff = 1; + for (vector = 0; (diff != 0) && (vector < VECTOR_SIGNAL_COUNT); + ++vector) + { + if (vector_list[vector].vector_index == -1) + { + ch_index = 0; + do + { + l = signals[signal][ch_index]; + r = vector_list[vector].signal_name[ch_index]; + diff = (((l >= 'a') && (l <= 'z')) ? (l - ('a' - 'A')) : l) + - (((r >= 'a') && (r <= 'z')) ? (r - ('a' - 'A')) : r); + ++ch_index; + } + while ((diff == 0) && (l != '\0') && (r != '\0')); + + if (diff == 0) + { + vector_list[vector].vector_index = signal; + ++matched_count; + } + } + } + } + + return (matched_count); +} + +int jbi_vector_io +( + int signal_count, + long *dir_vect, + long *data_vect, + long *capture_vect +) +{ + int signal, vector, bit; + int matched_count = 0; + int data = 0; + int mask = 0; + int dir = 0; + int i = 0; + int result = 0; + char ch_data = 0; + + if (!jtag_hardware_initialized) + { + initialize_jtag_hardware(); + jtag_hardware_initialized = TRUE; + } + + /* + * Collect information about output signals + */ + for (vector = 0; vector < VECTOR_SIGNAL_COUNT; ++vector) + { + signal = vector_list[vector].vector_index; + + if ((signal >= 0) && (signal < signal_count)) + { + bit = (1 << vector_list[vector].hardware_bit); + + mask |= bit; + if (data_vect[signal >> 5] & (1L << (signal & 0x1f))) data |= bit; + if (dir_vect[signal >> 5] & (1L << (signal & 0x1f))) dir |= bit; + + ++matched_count; + } + } + + /* + * Write outputs to hardware interface, if any + */ + if (dir != 0) + { + if (specified_com_port) + { + ch_data = (char) (((data >> 6) & 0x01) | (data & 0x02) | + ((data << 2) & 0x04) | ((data << 3) & 0x08) | 0x60); + write(com_port, &ch_data, 1); + } + else + { +#if PORT == WINDOWS || PORT == DOS + + write_byteblaster(0, data); + +#endif + } + } + + /* + * Read the input signals and save information in capture_vect[] + */ + if ((dir != mask) && (capture_vect != NULL)) + { + if (specified_com_port) + { + ch_data = 0x7e; + write(com_port, &ch_data, 1); + for (i = 0; (i < 100) && (result != 1); ++i) + { + result = read(com_port, &ch_data, 1); + } + if (result == 1) + { + data = ((ch_data << 7) & 0x80) | ((ch_data << 3) & 0x10); + } + else + { + fprintf(stderr, "Error: BitBlaster not responding\n"); + } + } + else + { +#if PORT == WINDOWS || PORT == DOS + + data = read_byteblaster(1) ^ 0x80; /* parallel port inverts bit 7 */ + +#endif + } + + for (vector = 0; vector < VECTOR_SIGNAL_COUNT; ++vector) + { + signal = vector_list[vector].vector_index; + + if ((signal >= 0) && (signal < signal_count)) + { + bit = (1 << vector_list[vector].hardware_bit); + + if ((dir & bit) == 0) /* if it is an input signal... */ + { + if (data & bit) + { + capture_vect[signal >> 5] |= (1L << (signal & 0x1f)); + } + else + { + capture_vect[signal >> 5] &= ~(unsigned long) + (1L << (signal & 0x1f)); + } + } + } + } + } + + return (matched_count); +} + +void *jbi_malloc(unsigned int size) +{ + unsigned int n_bytes_to_allocate = +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + sizeof(unsigned int) + +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ +#if defined(MEM_TRACKER) + (2 * sizeof(DWORD)) + +#endif /* MEM_TRACKER */ + (POINTER_ALIGNMENT * ((size + POINTER_ALIGNMENT - 1) / POINTER_ALIGNMENT)); + + unsigned char *ptr = 0; + +#if defined(MEM_TRACKER) + if ((n_bytes_allocated + n_bytes_to_allocate) > peak_memory_usage) + { + peak_memory_usage = n_bytes_allocated + n_bytes_to_allocate; + } + if ((n_allocations + 1) > peak_allocations) + { + peak_allocations = n_allocations + 1; + } +#endif /* MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) + if ((n_bytes_allocated + n_bytes_to_allocate) <= N_STATIC_MEMORY_BYTES) + { + ptr = (&(static_memory_heap[n_bytes_allocated])); + } +#else /* USE_STATIC_MEMORY */ + ptr = (unsigned char *) malloc(n_bytes_to_allocate); +#endif /* USE_STATIC_MEMORY */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + if (ptr != 0) + { + unsigned int i = 0; + +#if defined(MEM_TRACKER) + for (i = 0; i < sizeof(DWORD); ++i) + { + *ptr = (unsigned char) (BEGIN_GUARD >> (8 * i)); + ++ptr; + } +#endif /* MEM_TRACKER */ + + for (i = 0; i < sizeof(unsigned int); ++i) + { + *ptr = (unsigned char) (size >> (8 * i)); + ++ptr; + } + +#if defined(MEM_TRACKER) + for (i = 0; i < sizeof(DWORD); ++i) + { + *(ptr + size + i) = (unsigned char) (END_GUARD >> (8 * i)); + /* don't increment ptr */ + } + + ++n_allocations; +#endif /* MEM_TRACKER */ + + n_bytes_allocated += n_bytes_to_allocate; + } +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + + jbi_dbg(DEBUG_MM, "malloc 0x%p(%d,%d)\n", ptr, size, n_bytes_to_allocate); + + return ptr; +} + +void jbi_free(void *ptr) +{ + jbi_dbg(DEBUG_MM, "free 0x%p\n", ptr); + + if + ( +#if defined(MEM_TRACKER) + (n_allocations > 0) && +#endif /* MEM_TRACKER */ + (ptr != 0) + ) + { + unsigned char *tmp_ptr = (unsigned char *) ptr; + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + unsigned int n_bytes_to_free = 0; + unsigned int i = 0; + unsigned int size = 0; +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ +#if defined(MEM_TRACKER) + DWORD begin_guard = 0; + DWORD end_guard = 0; + + tmp_ptr -= sizeof(DWORD); +#endif /* MEM_TRACKER */ +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + tmp_ptr -= sizeof(unsigned int); +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + ptr = tmp_ptr; + +#if defined(MEM_TRACKER) + for (i = 0; i < sizeof(DWORD); ++i) + { + begin_guard |= (((DWORD)(*tmp_ptr)) << (8 * i)); + ++tmp_ptr; + } +#endif /* MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + for (i = 0; i < sizeof(unsigned int); ++i) + { + size |= (((unsigned int)(*tmp_ptr)) << (8 * i)); + ++tmp_ptr; + } +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(MEM_TRACKER) + tmp_ptr += size; + + for (i = 0; i < sizeof(DWORD); ++i) + { + end_guard |= (((DWORD)(*tmp_ptr)) << (8 * i)); + ++tmp_ptr; + } + + if ((begin_guard != BEGIN_GUARD) || (end_guard != END_GUARD)) + { + fprintf(stderr, "Error: memory corruption detected for allocation #%d... bad %s guard\n", + n_allocations, (begin_guard != BEGIN_GUARD) ? "begin" : "end"); + } + + --n_allocations; +#endif /* MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + n_bytes_to_free = +#if defined(MEM_TRACKER) + (2 * sizeof(DWORD)) + +#endif /* MEM_TRACKER */ + sizeof(unsigned int) + + (POINTER_ALIGNMENT * ((size + POINTER_ALIGNMENT - 1) / POINTER_ALIGNMENT)); +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) + if ((((unsigned long) ptr - (unsigned long) static_memory_heap) + n_bytes_to_free) == (unsigned long) n_bytes_allocated) + { + n_bytes_allocated -= n_bytes_to_free; + } +#if defined(MEM_TRACKER) + else + { + n_bytes_not_recovered += n_bytes_to_free; + } +#endif /* MEM_TRACKER */ +#else /* USE_STATIC_MEMORY */ +#if defined(MEM_TRACKER) + n_bytes_allocated -= n_bytes_to_free; +#endif /* MEM_TRACKER */ + free(ptr); +#endif /* USE_STATIC_MEMORY */ + } +#if defined(MEM_TRACKER) + else + { + if (ptr != 0) + { + fprintf(stderr, "Error: attempt to free unallocated memory\n"); + } + } +#endif /* MEM_TRACKER */ +} + +#if PORT == WINDOWS || PORT == DOS +/************************************************************************ +* +* get_tick_count() -- Get system tick count in milliseconds +* +* for DOS, use BIOS function _bios_timeofday() +* for WINDOWS use GetTickCount() function +* for UNIX use clock() system function +*/ +DWORD get_tick_count(void) +{ + DWORD tick_count = 0L; + +#if PORT == WINDOWS + tick_count = GetTickCount(); +#elif PORT == DOS + _bios_timeofday(_TIME_GETCLOCK, (long *)&tick_count); + tick_count *= 55L; /* convert to milliseconds */ +#else + /* assume clock() function returns microseconds */ + tick_count = (DWORD) (clock() / 1000L); +#endif + + return (tick_count); +} +#endif + +#define DELAY_SAMPLES 10 +#define DELAY_CHECK_LOOPS 10000 + +void calibrate_delay(void) +{ +#if PORT == WINDOWS || PORT == DOS + int sample = 0; + int count = 0; + DWORD tick_count1 = 0L; + DWORD tick_count2 = 0L; +#endif + + one_ms_delay = 0L; + +#if PORT == WINDOWS || PORT == DOS + for (sample = 0; sample < DELAY_SAMPLES; ++sample) + { + count = 0; + tick_count1 = get_tick_count(); + while ((tick_count2 = get_tick_count()) == tick_count1) {}; + do { delay_loop(DELAY_CHECK_LOOPS); count++; } while + ((tick_count1 = get_tick_count()) == tick_count2); + one_ms_delay += ((DELAY_CHECK_LOOPS * (DWORD)count) / + (tick_count1 - tick_count2)); + } + + one_ms_delay /= DELAY_SAMPLES; +#else + /* This is system-dependent! Update this number for target system */ + one_ms_delay = 1000L; +#endif +} + +char *error_text[] = +{ +/* JBIC_SUCCESS 0 */ "success", +/* JBIC_OUT_OF_MEMORY 1 */ "out of memory", +/* JBIC_IO_ERROR 2 */ "file access error", +/* JAMC_SYNTAX_ERROR 3 */ "syntax error", +/* JBIC_UNEXPECTED_END 4 */ "unexpected end of file", +/* JBIC_UNDEFINED_SYMBOL 5 */ "undefined symbol", +/* JAMC_REDEFINED_SYMBOL 6 */ "redefined symbol", +/* JBIC_INTEGER_OVERFLOW 7 */ "integer overflow", +/* JBIC_DIVIDE_BY_ZERO 8 */ "divide by zero", +/* JBIC_CRC_ERROR 9 */ "CRC mismatch", +/* JBIC_INTERNAL_ERROR 10 */ "internal error", +/* JBIC_BOUNDS_ERROR 11 */ "bounds error", +/* JAMC_TYPE_MISMATCH 12 */ "type mismatch", +/* JAMC_ASSIGN_TO_CONST 13 */ "assignment to constant", +/* JAMC_NEXT_UNEXPECTED 14 */ "NEXT unexpected", +/* JAMC_POP_UNEXPECTED 15 */ "POP unexpected", +/* JAMC_RETURN_UNEXPECTED 16 */ "RETURN unexpected", +/* JAMC_ILLEGAL_SYMBOL 17 */ "illegal symbol name", +/* JBIC_VECTOR_MAP_FAILED 18 */ "vector signal name not found", +/* JBIC_USER_ABORT 19 */ "execution cancelled", +/* JBIC_STACK_OVERFLOW 20 */ "stack overflow", +/* JBIC_ILLEGAL_OPCODE 21 */ "illegal instruction code", +/* JAMC_PHASE_ERROR 22 */ "phase error", +/* JAMC_SCOPE_ERROR 23 */ "scope error", +/* JBIC_ACTION_NOT_FOUND 24 */ "action not found", +}; + +#define MAX_ERROR_CODE (int)(sizeof(error_text)/sizeof(error_text[0])) + +/************************************************************************/ + +#if 0 +int main(int argc, char **argv) +{ + BOOL help = FALSE; + BOOL error = FALSE; + char *filename = NULL; + long offset = 0L; + long error_address = 0L; + JBI_RETURN_TYPE crc_result = JBIC_SUCCESS; + JBI_RETURN_TYPE exec_result = JBIC_SUCCESS; + unsigned short expected_crc = 0; + unsigned short actual_crc = 0; + char key[33] = {0}; + char value[257] = {0}; + int exit_status = 0; + int arg = 0; + int exit_code = 0; + int format_version = 0; + time_t start_time = 0; + time_t end_time = 0; + int time_delta = 0; + char *workspace = NULL; + char *action = NULL; + char *init_list[10]; + int init_count = 0; + FILE *fp = NULL; + struct stat sbuf; + long workspace_size = 0; + char *exit_string = NULL; + int reset_jtag = 1; + int execute_program = 1; + int action_count = 0; + int procedure_count = 0; + int index = 0; + char *action_name = NULL; + char *description = NULL; + JBI_PROCINFO *procedure_list = NULL; + JBI_PROCINFO *procptr = NULL; + + verbose = FALSE; + + init_list[0] = NULL; + + /* print out the version string and copyright message */ + fprintf(stderr, "Jam STAPL ByteCode Player Version 2.2\nCopyright (C) 1998-2001 Altera Corporation\n\n"); + + for (arg = 1; arg < argc; arg++) + { +#if PORT == UNIX + if (argv[arg][0] == '-') +#else + if ((argv[arg][0] == '-') || (argv[arg][0] == '/')) +#endif + { + switch(toupper(argv[arg][1])) + { + case 'A': /* set action name */ + if (action == NULL) + { + action = &argv[arg][2]; + } + else + { + error = TRUE; + } + break; + +#if PORT == WINDOWS || PORT == DOS + case 'C': /* Use alternative ISP download cable */ + if(toupper(argv[arg][2]) == 'L') + alternative_cable_l = TRUE; + else if(toupper(argv[arg][2]) == 'X') + alternative_cable_x = TRUE; + break; +#endif + + case 'D': /* initialization list */ + if (argv[arg][2] == '"') + { + init_list[init_count] = &argv[arg][3]; + } + else + { + init_list[init_count] = &argv[arg][2]; + } + init_list[++init_count] = NULL; + break; + +#if PORT == WINDOWS || PORT == DOS + case 'P': /* set LPT port address */ + specified_lpt_port = TRUE; + if (sscanf(&argv[arg][2], "%d", &lpt_port) != 1) error = TRUE; + if ((lpt_port < 1) || (lpt_port > 3)) error = TRUE; + if (error) + { + if (sscanf(&argv[arg][2], "%x", &lpt_port) == 1) + { + if ((lpt_port == 0x3bc) || + (lpt_port == 0x378) || + (lpt_port == 0x278)) + { + error = FALSE; + specified_lpt_addr = TRUE; + lpt_addr = (WORD) lpt_port; + lpt_port = 1; + } + } + } + break; +#endif + + case 'R': /* don't reset the JTAG chain after use */ + reset_jtag = 0; + break; + + case 'S': /* set serial port address */ + serial_port_name = &argv[arg][2]; + specified_com_port = TRUE; + break; + + case 'M': /* set memory size */ + if (sscanf(&argv[arg][2], "%ld", &workspace_size) != 1) + error = TRUE; + if (workspace_size == 0) error = TRUE; + break; + + case 'H': /* help */ + help = TRUE; + break; + + case 'V': /* verbose */ + verbose = TRUE; + break; + + case 'I': /* show info only, do not execute */ + verbose = TRUE; + execute_program = 0; + break; + + default: + error = TRUE; + break; + } + } + else + { + /* it's a filename */ + if (filename == NULL) + { + filename = argv[arg]; + } + else + { + /* error -- we already found a filename */ + error = TRUE; + } + } + + if (error) + { + fprintf(stderr, "Illegal argument: \"%s\"\n", argv[arg]); + help = TRUE; + error = FALSE; + } + } + +#if PORT == WINDOWS || PORT == DOS + if (specified_lpt_port && specified_com_port) + { + fprintf(stderr, "Error: -s and -p options may not be used together\n\n"); + help = TRUE; + } +#endif + + if (help || (filename == NULL)) + { + fprintf(stderr, "Usage: jbi [options] \n"); + fprintf(stderr, "\nAvailable options:\n"); + fprintf(stderr, " -h : show help message\n"); + fprintf(stderr, " -v : show verbose messages\n"); + fprintf(stderr, " -i : show file info only - does not execute any action\n"); + fprintf(stderr, " -a : specify an action name (Jam STAPL)\n"); + fprintf(stderr, " -d : initialize variable to specified value (Jam 1.1)\n"); + fprintf(stderr, " -d : enable optional procedure (Jam STAPL)\n"); + fprintf(stderr, " -d : disable recommended procedure (Jam STAPL)\n"); +#if PORT == WINDOWS || PORT == DOS + fprintf(stderr, " -p : parallel port number or address (for ByteBlaster)\n"); + fprintf(stderr, " -c : alternative download cable compatibility: -cl or -cx\n"); +#endif + fprintf(stderr, " -s : serial port name (for BitBlaster)\n"); + fprintf(stderr, " -r : don't reset JTAG TAP after use\n"); + exit_status = 1; + } + else if ((workspace_size > 0) && + ((workspace = (char *) jbi_malloc((size_t) workspace_size)) == NULL)) + { + fprintf(stderr, "Error: can't allocate memory (%d Kbytes)\n", + (int) (workspace_size / 1024L)); + exit_status = 1; + } + else if (access(filename, 0) != 0) + { + fprintf(stderr, "Error: can't access file \"%s\"\n", filename); + exit_status = 1; + } + else + { + /* get length of file */ + if (stat(filename, &sbuf) == 0) file_length = sbuf.st_size; + + if ((fp = fopen(filename, "rb")) == NULL) + { + fprintf(stderr, "Error: can't open file \"%s\"\n", filename); + exit_status = 1; + } + else + { + /* + * Read entire file into a buffer + */ +#if PORT == DOS + int pages = 1 + (int) (file_length >> 14L); + int page; + file_buffer = (unsigned char **) jbi_malloc( + (size_t) (pages * sizeof(char *))); + + for (page = 0; page < pages; ++page) + { + /* allocate enough 16K blocks to store the file */ + file_buffer[page] = (unsigned char *) jbi_malloc (0x4000); + if (file_buffer[page] == NULL) + { + /* flag error and break out of loop */ + file_buffer = NULL; + page = pages; + } + } +#else + file_buffer = (unsigned char *) jbi_malloc((size_t) file_length); +#endif + + if (file_buffer == NULL) + { + fprintf(stderr, "Error: can't allocate memory (%d Kbytes)\n", + (int) (file_length / 1024L)); + exit_status = 1; + } + else + { +#if PORT == DOS + int pages = 1 + (int) (file_length >> 14L); + int page; + size_t page_size = 0x4000; + for (page = 0; (page < pages) && (exit_status == 0); ++page) + { + if (page == (pages - 1)) + { + /* last page may not be full 16K bytes */ + page_size = (size_t) (file_length & 0x3fffL); + } + if (fread(file_buffer[page], 1, page_size, fp) != page_size) + { + fprintf(stderr, "Error reading file \"%s\"\n", filename); + exit_status = 1; + } + } +#else + if (fread(file_buffer, 1, (size_t) file_length, fp) != + (size_t) file_length) + { + fprintf(stderr, "Error reading file \"%s\"\n", filename); + exit_status = 1; + } +#endif + } + + fclose(fp); + } + + if (exit_status == 0) + { + /* + * Get Operating System type + */ +#if PORT == WINDOWS + windows_nt = !(GetVersion() & 0x80000000); +#endif + + /* + * Calibrate the delay loop function + */ + calibrate_delay(); + + /* + * Check CRC + */ + crc_result = jbi_check_crc(file_buffer, file_length, + &expected_crc, &actual_crc); + + if (verbose || (crc_result == JBIC_CRC_ERROR)) + { + switch (crc_result) + { + case JBIC_SUCCESS: + printf("CRC matched: CRC value = %04X\n", actual_crc); + break; + + case JBIC_CRC_ERROR: + printf("CRC mismatch: expected %04X, actual %04X\n", + expected_crc, actual_crc); + break; + + case JBIC_UNEXPECTED_END: + printf("Expected CRC not found, actual CRC value = %04X\n", + actual_crc); + break; + + case JBIC_IO_ERROR: + printf("Error: File format is not recognized.\n"); + exit(1); + break; + + default: + printf("CRC function returned error code %d\n", crc_result); + break; + } + } + + if (verbose) + { + /* + * Display file format version + */ + jbi_get_file_info(file_buffer, file_length, + &format_version, &action_count, &procedure_count); + + printf("File format is %s ByteCode format\n", + (format_version == 2) ? "Jam STAPL" : "pre-standardized Jam 1.1"); + + /* + * Dump out NOTE fields + */ + while (jbi_get_note(file_buffer, file_length, + &offset, key, value, 256) == 0) + { + printf("NOTE \"%s\" = \"%s\"\n", key, value); + } + + /* + * Dump the action table + */ + if ((format_version == 2) && (action_count > 0)) + { + printf("\nActions available in this file:\n"); + + for (index = 0; index < action_count; ++index) + { + jbi_get_action_info(file_buffer, file_length, + index, &action_name, &description, &procedure_list); + + if (description == NULL) + { + printf("%s\n", action_name); + } + else + { + printf("%s \"%s\"\n", action_name, description); + } + +#if PORT == DOS + if (action_name != NULL) jbi_free(action_name); + if (description != NULL) jbi_free(description); +#endif + + procptr = procedure_list; + while (procptr != NULL) + { + if (procptr->attributes != 0) + { + printf(" %s (%s)\n", procptr->name, + (procptr->attributes == 1) ? + "optional" : "recommended"); + } + +#if PORT == DOS + if (procptr->name != NULL) jbi_free(procptr->name); +#endif + + procedure_list = procptr->next; + jbi_free(procptr); + procptr = procedure_list; + } + } + + /* add a blank line before execution messages */ + if (execute_program) printf("\n"); + } + } + + if (execute_program) + { + /* + * Execute the Jam STAPL ByteCode program + */ + time(&start_time); + exec_result = jbi_execute(file_buffer, file_length, workspace, + workspace_size, action, init_list, reset_jtag, + &error_address, &exit_code, &format_version); + time(&end_time); + + if (exec_result == JBIC_SUCCESS) + { + if (format_version == 2) + { + switch (exit_code) + { + case 0: exit_string = "Success"; break; + case 1: exit_string = "Checking chain failure"; break; + case 2: exit_string = "Reading IDCODE failure"; break; + case 3: exit_string = "Reading USERCODE failure"; break; + case 4: exit_string = "Reading UESCODE failure"; break; + case 5: exit_string = "Entering ISP failure"; break; + case 6: exit_string = "Unrecognized device"; break; + case 7: exit_string = "Device revision is not supported"; break; + case 8: exit_string = "Erase failure"; break; + case 9: exit_string = "Device is not blank"; break; + case 10: exit_string = "Device programming failure"; break; + case 11: exit_string = "Device verify failure"; break; + case 12: exit_string = "Read failure"; break; + case 13: exit_string = "Calculating checksum failure"; break; + case 14: exit_string = "Setting security bit failure"; break; + case 15: exit_string = "Querying security bit failure"; break; + case 16: exit_string = "Exiting ISP failure"; break; + case 17: exit_string = "Performing system test failure"; break; + default: exit_string = "Unknown exit code"; break; + } + } + else + { + switch (exit_code) + { + case 0: exit_string = "Success"; break; + case 1: exit_string = "Illegal initialization values"; break; + case 2: exit_string = "Unrecognized device"; break; + case 3: exit_string = "Device revision is not supported"; break; + case 4: exit_string = "Device programming failure"; break; + case 5: exit_string = "Device is not blank"; break; + case 6: exit_string = "Device verify failure"; break; + case 7: exit_string = "SRAM configuration failure"; break; + default: exit_string = "Unknown exit code"; break; + } + } + + printf("Exit code = %d... %s\n", exit_code, exit_string); + } + else if ((format_version == 2) && + (exec_result == JBIC_ACTION_NOT_FOUND)) + { + if ((action == NULL) || (*action == '\0')) + { + printf("Error: no action specified for Jam STAPL file.\nProgram terminated.\n"); + } + else + { + printf("Error: action \"%s\" is not supported for this Jam STAPL file.\nProgram terminated.\n", action); + } + } + else if (exec_result < MAX_ERROR_CODE) + { + printf("Error at address %ld: %s.\nProgram terminated.\n", + error_address, error_text[exec_result]); + } + else + { + printf("Unknown error code %ld\n", exec_result); + } + + /* + * Print out elapsed time + */ + if (verbose) + { + time_delta = (int) (end_time - start_time); + printf("Elapsed time = %02u:%02u:%02u\n", + time_delta / 3600, /* hours */ + (time_delta % 3600) / 60, /* minutes */ + time_delta % 60); /* seconds */ + } + } + } + } + + if (jtag_hardware_initialized) close_jtag_hardware(); + + if (workspace != NULL) jbi_free(workspace); + if (file_buffer != NULL) jbi_free(file_buffer); + +#if defined(MEM_TRACKER) + if (verbose) + { +#if defined(USE_STATIC_MEMORY) + fprintf(stdout, "Memory Usage Info: static memory size = %ud (%dKB)\n", N_STATIC_MEMORY_BYTES, N_STATIC_MEMORY_KBYTES); +#endif /* USE_STATIC_MEMORY */ + fprintf(stdout, "Memory Usage Info: peak memory usage = %ud (%dKB)\n", peak_memory_usage, (peak_memory_usage + 1023) / 1024); + fprintf(stdout, "Memory Usage Info: peak allocations = %d\n", peak_allocations); +#if defined(USE_STATIC_MEMORY) + if ((n_bytes_allocated - n_bytes_not_recovered) != 0) + { + fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", (n_bytes_allocated - n_bytes_not_recovered), ((n_bytes_allocated - n_bytes_not_recovered) + 1023) / 1024); + } +#else /* USE_STATIC_MEMORY */ + if (n_bytes_allocated != 0) + { + fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", n_bytes_allocated, (n_bytes_allocated + 1023) / 1024); + } +#endif /* USE_STATIC_MEMORY */ + if (n_allocations != 0) + { + fprintf(stdout, "Memory Usage Info: allocations not freed = %d\n", n_allocations); + } + } +#endif /* MEM_TRACKER */ + + return (exit_status); +} +#endif + +#if PORT==WINDOWS +#ifndef __BORLANDC__ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* SEARCH_DYN_DATA +* +* Searches recursively in Windows 95/98 Registry for parallel port info +* under HKEY_DYN_DATA registry key. Called by search_local_machine(). +*/ +void search_dyn_data +( + char *dd_path, + char *hardware_key, + int lpt +) +{ + DWORD index; + DWORD size; + DWORD type; + LONG result; + HKEY key; + int length; + WORD address; + char buffer[1024]; + FILETIME last_write = {0}; + WORD *word_ptr; + int i; + + length = strlen(dd_path); + + if (RegOpenKeyEx( + HKEY_DYN_DATA, + dd_path, + 0L, + KEY_READ, + &key) + == ERROR_SUCCESS) + { + size = 1023; + + if (RegQueryValueEx( + key, + "HardWareKey", + NULL, + &type, + (unsigned char *) buffer, + &size) + == ERROR_SUCCESS) + { + if ((type == REG_SZ) && (stricmp(buffer, hardware_key) == 0)) + { + size = 1023; + + if (RegQueryValueEx( + key, + "Allocation", + NULL, + &type, + (unsigned char *) buffer, + &size) + == ERROR_SUCCESS) + { + /* + * By "inspection", I have found five cases: size 32, 48, + * 56, 60, and 80 bytes. The port address seems to be + * located at different offsets in the buffer for these + * five cases, as shown below. If a valid port address + * is not found, or the size is not one of these known + * sizes, then I search through the entire buffer and + * look for a value which is a valid port address. + */ + + word_ptr = (WORD *) buffer; + + if ((type == REG_BINARY) && (size == 32)) + { + address = word_ptr[10]; + } + else if ((type == REG_BINARY) && (size == 48)) + { + address = word_ptr[18]; + } + else if ((type == REG_BINARY) && (size == 56)) + { + address = word_ptr[22]; + } + else if ((type == REG_BINARY) && (size == 60)) + { + address = word_ptr[24]; + } + else if ((type == REG_BINARY) && (size == 80)) + { + address = word_ptr[24]; + } + else address = 0; + + /* if not found, search through entire buffer */ + i = 0; + while ((i < (int) (size / 2)) && + (address != 0x278) && + (address != 0x27C) && + (address != 0x378) && + (address != 0x37C) && + (address != 0x3B8) && + (address != 0x3BC)) + { + if ((word_ptr[i] == 0x278) || + (word_ptr[i] == 0x27C) || + (word_ptr[i] == 0x378) || + (word_ptr[i] == 0x37C) || + (word_ptr[i] == 0x3B8) || + (word_ptr[i] == 0x3BC)) + { + address = word_ptr[i]; + } + ++i; + } + + if ((address == 0x278) || + (address == 0x27C) || + (address == 0x378) || + (address == 0x37C) || + (address == 0x3B8) || + (address == 0x3BC)) + { + lpt_addresses_from_registry[lpt] = address; + } + } + } + } + + index = 0; + + do + { + size = 1023; + + result = RegEnumKeyEx( + key, + index++, + buffer, + &size, + NULL, + NULL, + NULL, + &last_write); + + if (result == ERROR_SUCCESS) + { + dd_path[length] = '\\'; + dd_path[length + 1] = '\0'; + strcpy(&dd_path[length + 1], buffer); + + search_dyn_data(dd_path, hardware_key, lpt); + + dd_path[length] = '\0'; + } + } + while (result == ERROR_SUCCESS); + + RegCloseKey(key); + } +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* SEARCH_LOCAL_MACHINE +* +* Searches recursively in Windows 95/98 Registry for parallel port info +* under HKEY_LOCAL_MACHINE\Enum. When parallel port is found, calls +* search_dyn_data() to get the port address. +*/ +void search_local_machine +( + char *lm_path, + char *dd_path +) +{ + DWORD index; + DWORD size; + DWORD type; + LONG result; + HKEY key; + int length; + char buffer[1024]; + FILETIME last_write = {0}; + + length = strlen(lm_path); + + if (RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + lm_path, + 0L, + KEY_READ, + &key) + == ERROR_SUCCESS) + { + size = 1023; + + if (RegQueryValueEx( + key, + "PortName", + NULL, + &type, + (unsigned char *) buffer, + &size) + == ERROR_SUCCESS) + { + if ((type == REG_SZ) && + (size == 5) && + (buffer[0] == 'L') && + (buffer[1] == 'P') && + (buffer[2] == 'T') && + (buffer[3] >= '1') && + (buffer[3] <= '4') && + (buffer[4] == '\0')) + { + /* we found the entry in HKEY_LOCAL_MACHINE, now we need to */ + /* find the corresponding entry under HKEY_DYN_DATA. */ + /* add 5 to lm_path to skip over "Enum" and backslash */ + search_dyn_data(dd_path, &lm_path[5], (buffer[3] - '1')); + } + } + + index = 0; + + do + { + size = 1023; + + result = RegEnumKeyEx( + key, + index++, + buffer, + &size, + NULL, + NULL, + NULL, + &last_write); + + if (result == ERROR_SUCCESS) + { + lm_path[length] = '\\'; + lm_path[length + 1] = '\0'; + strcpy(&lm_path[length + 1], buffer); + + search_local_machine(lm_path, dd_path); + + lm_path[length] = '\0'; + } + } + while (result == ERROR_SUCCESS); + + RegCloseKey(key); + } +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* GET_LPT_ADDRESSES_FROM_REGISTRY +* +* Searches Win95/98 registry recursively to get I/O port addresses for +* parallel ports. +*/ +void get_lpt_addresses_from_registry() +{ + char lm_path[1024]; + char dd_path[1024]; + + strcpy(lm_path, "Enum"); + strcpy(dd_path, "Config Manager"); + search_local_machine(lm_path, dd_path); +} +#endif +#endif + +void initialize_jtag_hardware() +{ + if (specified_com_port) + { + com_port = open(serial_port_name, O_RDWR); + if (com_port == -1) + { + fprintf(stderr, "Error: can't open serial port \"%s\"\n", + serial_port_name); + } + else + { + int i = 0, result = 0; + char data = 0; + + data = 0x7e; + write(com_port, &data, 1); + + for (i = 0; (i < 100) && (result != 1); ++i) + { + result = read(com_port, &data, 1); + } + + if (result == 1) + { + data = 0x70; write(com_port, &data, 1); /* TDO echo off */ + data = 0x72; write(com_port, &data, 1); /* auto LEDs off */ + data = 0x74; write(com_port, &data, 1); /* ERROR LED off */ + data = 0x76; write(com_port, &data, 1); /* DONE LED off */ + data = 0x60; write(com_port, &data, 1); /* signals low */ + } + else + { + fprintf(stderr, "Error: BitBlaster is not responding on %s\n", + serial_port_name); + close(com_port); + com_port = -1; + } + } + } + else + { +#if PORT == WINDOWS || PORT == DOS + +#if PORT == WINDOWS + if (windows_nt) + { + initialize_nt_driver(); + } + else + { +#ifdef __BORLANDC__ + fprintf(stderr, "Error: parallel port access is not available\n"); +#else + if (!specified_lpt_addr) + { + get_lpt_addresses_from_registry(); + + lpt_addr = 0; + + if (specified_lpt_port) + { + lpt_addr = lpt_addresses_from_registry[lpt_port - 1]; + } + + if (lpt_addr == 0) + { + if (lpt_addresses_from_registry[3] != 0) + lpt_addr = lpt_addresses_from_registry[3]; + if (lpt_addresses_from_registry[2] != 0) + lpt_addr = lpt_addresses_from_registry[2]; + if (lpt_addresses_from_registry[1] != 0) + lpt_addr = lpt_addresses_from_registry[1]; + if (lpt_addresses_from_registry[0] != 0) + lpt_addr = lpt_addresses_from_registry[0]; + } + + if (lpt_addr == 0) + { + if (specified_lpt_port) + { + lpt_addr = lpt_addr_table[lpt_port - 1]; + } + else + { + lpt_addr = lpt_addr_table[0]; + } + } + } + initial_lpt_ctrl = windows_nt ? 0x0c : read_byteblaster(2); +#endif + } +#endif + +#if PORT == DOS + /* + * Read word at specific memory address to get the LPT port address + */ + WORD *bios_address = (WORD *) 0x00400008; + + if (!specified_lpt_addr) + { + lpt_addr = bios_address[lpt_port - 1]; + + if ((lpt_addr != 0x278) && + (lpt_addr != 0x27c) && + (lpt_addr != 0x378) && + (lpt_addr != 0x37c) && + (lpt_addr != 0x3b8) && + (lpt_addr != 0x3bc)) + { + lpt_addr = lpt_addr_table[lpt_port - 1]; + } + } + initial_lpt_ctrl = read_byteblaster(2); +#endif + + /* set AUTO-FEED low to enable ByteBlaster (value to port inverted) */ + /* set DIRECTION low for data output from parallel port */ + write_byteblaster(2, (initial_lpt_ctrl | 0x02) & 0xDF); +#endif + } +} + +void close_jtag_hardware() +{ + if (specified_com_port) + { + if (com_port != -1) close(com_port); + } + else + { +#if PORT == WINDOWS || PORT == DOS + /* set AUTO-FEED high to disable ByteBlaster */ + write_byteblaster(2, initial_lpt_ctrl & 0xfd); + +#if PORT == WINDOWS + if (windows_nt && (nt_device_handle != INVALID_HANDLE_VALUE)) + { + if (port_io_count > 0) flush_ports(); + + CloseHandle(nt_device_handle); + } +#endif +#endif + } +} + +#if PORT == WINDOWS +/**************************************************************************/ +/* */ + +BOOL initialize_nt_driver() + +/* */ +/* Uses CreateFile() to open a connection to the Windows NT device */ +/* driver. */ +/* */ +/**************************************************************************/ +{ + BOOL status = FALSE; + + ULONG buffer[1]; + ULONG returned_length = 0; + char nt_lpt_str[] = { '\\', '\\', '.', '\\', + 'A', 'L', 'T', 'L', 'P', 'T', '1', '\0' }; + + nt_lpt_str[10] = (char) ('1' + (lpt_port - 1)); + + nt_device_handle = CreateFile( + nt_lpt_str, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (nt_device_handle == INVALID_HANDLE_VALUE) + { + fprintf(stderr, + "I/O error: cannot open device %s\nCheck port number and device driver installation", + nt_lpt_str); + } + else + { + if (DeviceIoControl( + nt_device_handle, /* Handle to device */ + PGDC_IOCTL_GET_DEVICE_INFO_PP, /* IO Control code */ + (ULONG *)NULL, /* Buffer to driver. */ + 0, /* Length of buffer in bytes. */ + &buffer, /* Buffer from driver. */ + sizeof(ULONG), /* Length of buffer in bytes. */ + &returned_length, /* Bytes placed in data_buffer. */ + NULL)) /* Wait for operation to complete */ + { + if (returned_length == sizeof(ULONG)) + { + if (buffer[0] == PGDC_HDLC_NTDRIVER_VERSION) + { + status = TRUE; + } + else + { + fprintf(stderr, + "I/O error: device driver %s is not compatible\n(Driver version is %lu, expected version %lu.\n", + nt_lpt_str, + (unsigned long) buffer[0], + (unsigned long) PGDC_HDLC_NTDRIVER_VERSION); + } + } + else + { + fprintf(stderr, "I/O error: device driver %s is not compatible.\n", + nt_lpt_str); + } + } + + if (!status) + { + CloseHandle(nt_device_handle); + nt_device_handle = INVALID_HANDLE_VALUE; + } + } + + if (!status) + { + /* error message already given */ + exit(1); + } + + return (status); +} +#endif + +#if PORT == WINDOWS || PORT == DOS +/**************************************************************************/ +/* */ + +void write_byteblaster +( + int port, + int data +) + +/* */ +/**************************************************************************/ +{ +#if PORT == WINDOWS + BOOL status = FALSE; + + int returned_length = 0; + int buffer[2]; + + if (windows_nt) + { + /* + * On Windows NT, access hardware through device driver + */ + if (port == 0) + { + port_io_buffer[port_io_count].data = (USHORT) data; + port_io_buffer[port_io_count].command = PGDC_WRITE_PORT; + ++port_io_count; + + if (port_io_count >= PORT_IO_BUFFER_SIZE) flush_ports(); + } + else + { + if (port_io_count > 0) flush_ports(); + + buffer[0] = port; + buffer[1] = data; + + status = DeviceIoControl( + nt_device_handle, /* Handle to device */ + PGDC_IOCTL_WRITE_PORT_PP, /* IO Control code for write */ + (ULONG *)&buffer, /* Buffer to driver. */ + 2 * sizeof(int), /* Length of buffer in bytes. */ + (ULONG *)NULL, /* Buffer from driver. Not used. */ + 0, /* Length of buffer in bytes. */ + (ULONG *)&returned_length, /* Bytes returned. Should be zero. */ + NULL); /* Wait for operation to complete */ + + if ((!status) || (returned_length != 0)) + { + fprintf(stderr, "I/O error: Cannot access ByteBlaster hardware\n"); + CloseHandle(nt_device_handle); + exit(1); + } + } + } + else +#endif + { + /* + * On Windows 95, access hardware directly + */ + outp((WORD)(port + lpt_addr), (WORD)data); + } +} + +/**************************************************************************/ +/* */ + +int read_byteblaster +( + int port +) + +/* */ +/**************************************************************************/ +{ + int data = 0; + +#if PORT == WINDOWS + + BOOL status = FALSE; + + int returned_length = 0; + + if (windows_nt) + { + /* flush output cache buffer before reading from device */ + if (port_io_count > 0) flush_ports(); + + /* + * On Windows NT, access hardware through device driver + */ + status = DeviceIoControl( + nt_device_handle, /* Handle to device */ + PGDC_IOCTL_READ_PORT_PP, /* IO Control code for Read */ + (ULONG *)&port, /* Buffer to driver. */ + sizeof(int), /* Length of buffer in bytes. */ + (ULONG *)&data, /* Buffer from driver. */ + sizeof(int), /* Length of buffer in bytes. */ + (ULONG *)&returned_length, /* Bytes placed in data_buffer. */ + NULL); /* Wait for operation to complete */ + + if ((!status) || (returned_length != sizeof(int))) + { + fprintf(stderr, "I/O error: Cannot access ByteBlaster hardware\n"); + CloseHandle(nt_device_handle); + exit(1); + } + } + else +#endif + { + /* + * On Windows 95, access hardware directly + */ + data = inp((WORD)(port + lpt_addr)); + } + + return (data & 0xff); +} + +#if PORT == WINDOWS +void flush_ports(void) +{ + ULONG n_writes = 0L; + BOOL status; + + status = DeviceIoControl( + nt_device_handle, /* handle to device */ + PGDC_IOCTL_PROCESS_LIST_PP, /* IO control code */ + (LPVOID)port_io_buffer, /* IN buffer (list buffer) */ + port_io_count * sizeof(struct PORT_IO_LIST_STRUCT),/* length of IN buffer in bytes */ + (LPVOID)port_io_buffer, /* OUT buffer (list buffer) */ + port_io_count * sizeof(struct PORT_IO_LIST_STRUCT),/* length of OUT buffer in bytes */ + &n_writes, /* number of writes performed */ + 0); /* wait for operation to complete */ + + if ((!status) || ((port_io_count * sizeof(struct PORT_IO_LIST_STRUCT)) != n_writes)) + { + fprintf(stderr, "I/O error: Cannot access ByteBlaster hardware\n"); + CloseHandle(nt_device_handle); + exit(1); + } + + port_io_count = 0; +} +#endif /* PORT == WINDOWS */ +#endif /* PORT == WINDOWS || PORT == DOS */ + +#if 0 +#if !defined (DEBUG) +#pragma optimize ("ceglt", off) +#endif +#endif + +void delay_loop(long count) +{ + while (count != 0L) count--; +} + +#if PORT == EMBEDDED + +static void jbi_init_mm(void) +{ +#if defined(USE_STATIC_MEMORY) + int i; +#endif /* USE_STATIC_MEMORY */ + +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + n_bytes_allocated = 0; +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(MEM_TRACKER) + peak_memory_usage = 0; + peak_allocations = 0; + n_allocations = 0; +#if defined(USE_STATIC_MEMORY) + n_bytes_not_recovered = 0; +#endif /* USE_STATIC_MEMORY */ +#endif /* MEM_TRACKER */ + +#if defined(USE_STATIC_MEMORY) + jbi_dbg(DEBUG_DETAIL, "static_memory_heap: 0x%p(0x%x)\n", + static_memory_heap, N_STATIC_MEMORY_BYTES); + for (i = 0; i < N_STATIC_MEMORY_BYTES; i++) { + static_memory_heap[i] = 0; + } +#endif /* USE_STATIC_MEMORY */ + + jbi_delay_us = 0; + jbi_delay_count = 0; + jbi_peak_us = 0; +} + +static void jbi_exit_mm(void) +{ +#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER) + jbi_dbg(DEBUG_DETAIL, "n_bytes_allocated: %u\n", n_bytes_allocated); + n_bytes_allocated = 0; +#endif /* USE_STATIC_MEMORY || MEM_TRACKER */ + +#if defined(MEM_TRACKER) + jbi_dbg(DEBUG_DETAIL, "peak_memory_usage: %u\n", peak_memory_usage); + jbi_dbg(DEBUG_DETAIL, "peak_allocations: %u\n", peak_allocations); + jbi_dbg(DEBUG_DETAIL, "n_allocations: %u\n", n_allocations); + peak_memory_usage = 0; + peak_allocations = 0; + n_allocations = 0; +#if defined(USE_STATIC_MEMORY) + jbi_dbg(DEBUG_DETAIL, "n_bytes_not_recovered: %u\n", n_bytes_not_recovered); + n_bytes_not_recovered = 0; +#endif /* USE_STATIC_MEMORY */ +#endif /* MEM_TRACKER */ + + jbi_dbg(DEBUG_DETAIL, "jbi_delay: %ld us, %ld count, peak %ld us\n", + jbi_delay_us, jbi_delay_count, jbi_peak_us); +} + +static char *get_exit_string(int format_version, int exit_code) +{ + char *exit_string = NULL; + + if (format_version == 2){ + switch (exit_code) { + case 0: + exit_string = "Success"; + break; + case 1: + exit_string = "Checking chain failure"; + break; + case 2: + exit_string = "Reading IDCODE failure"; + break; + case 3: + exit_string = "Reading USERCODE failure"; + break; + case 4: + exit_string = "Reading UESCODE failure"; + break; + case 5: + exit_string = "Entering ISP failure"; + break; + case 6: + exit_string = "Unrecognized device"; + break; + case 7: + exit_string = "Device revision is not supported"; + break; + case 8: + exit_string = "Erase failure"; + break; + case 9: + exit_string = "Device is not blank"; + break; + case 10: + exit_string = "Device programming failure"; + break; + case 11: + exit_string = "Device verify failure"; + break; + case 12: + exit_string = "Read failure"; break; + case 13: + exit_string = "Calculating checksum failure"; + break; + case 14: + exit_string = "Setting security bit failure"; + break; + case 15: + exit_string = "Querying security bit failure"; + break; + case 16: + exit_string = "Exiting ISP failure"; + break; + case 17: + exit_string = "Performing system test failure"; + break; + default: + exit_string = "Unknown exit code"; + break; + } + } else { + switch (exit_code) { + case 0: + exit_string = "Success"; + break; + case 1: + exit_string = "Illegal initialization values"; + break; + case 2: + exit_string = "Unrecognized device"; + break; + case 3: + exit_string = "Device revision is not supported"; + break; + case 4: + exit_string = "Device programming failure"; + break; + case 5: + exit_string = "Device is not blank"; + break; + case 6: + exit_string = "Device verify failure"; + break; + case 7: + exit_string = "SRAM configuration failure"; + break; + default: + exit_string = "Unknown exit code"; + break; + } + } + + return exit_string; +} + +static void jbi_help(void) +{ + fprintf(stderr, "Usage: jbi [options]\n"); + fprintf(stderr, "\nAvailable options:\n"); + fprintf(stderr, " -h : show help message\n"); + fprintf(stderr, " -v : show verbose messages\n"); + fprintf(stderr, " -i : show file info only - does not execute any action\n"); + fprintf(stderr, " -a : specify an action name (Jam STAPL)\n"); + fprintf(stderr, " -d : initialize variable to specified value (Jam 1.1)\n"); + fprintf(stderr, " -d : enable optional procedure (Jam STAPL)\n"); + fprintf(stderr, " -d : disable recommended procedure (Jam STAPL)\n"); + fprintf(stderr, " -r : don't reset JTAG TAP after use\n"); +} + +int jbi_debug(int level) +{ + jbi_debug_level = level; + + return 0; +} + +int jbi_main(unsigned char *addr, unsigned long size, int argc, char * const argv[]) +{ + BOOL help = FALSE; + BOOL error = FALSE; + long offset = 0L; + long error_address = 0L; + JBI_RETURN_TYPE crc_result = JBIC_SUCCESS; + JBI_RETURN_TYPE exec_result = JBIC_SUCCESS; + unsigned short expected_crc = 0; + unsigned short actual_crc = 0; + char key[33] = {0}; + char value[257] = {0}; + int exit_status = 0; + int arg = 0; + int exit_code = 0; + int format_version = 0; + char *workspace = NULL; + char *action = NULL; + char *init_list[10]; + int init_count = 0; + long workspace_size = 0; + char *exit_string = NULL; + int reset_jtag = 1; + int execute_program = 1; + int action_count = 0; + int procedure_count = 0; + int index = 0; + char *action_name = NULL; + char *description = NULL; + JBI_PROCINFO *procedure_list = NULL; + JBI_PROCINFO *procptr = NULL; + char *endp = NULL; + + verbose = FALSE; + + init_list[0] = NULL; + + /* print out the version string and copyright message */ + printf("Jam STAPL ByteCode Player Version 2.2\n"); + printf("Copyright (C) 1998-2001 Altera Corporation\n\n"); + + for (arg = 0; arg < argc; arg++) { + if (argv[arg][0] == '-') { + switch (toupper(argv[arg][1])) { + case 'A': /* set action name */ + if (action == NULL) { + action = &argv[arg][2]; + } else { + error = TRUE; + } + break; + case 'D': /* initialization list */ + if (argv[arg][2] == '"') { + init_list[init_count] = &argv[arg][3]; + } else { + init_list[init_count] = &argv[arg][2]; + } + init_list[++init_count] = NULL; + break; + case 'R': /* don't reset the JTAG chain after use */ + reset_jtag = 0; + break; + case 'M': /* set memory size */ + workspace = (char *) simple_strtoul(&argv[arg][2], &endp, 16); + if (workspace == NULL) { + printf("Error workspace\n"); + error = TRUE; + } else { + if (*endp == '.') { + workspace_size = simple_strtoul(endp + 1, &endp, 16); + if (*endp != '\0') { + printf("Error workspace size end\n"); + error = TRUE; + } + } else { + printf("No workspace size\n"); + error = TRUE; + } + } + break; + case 'H': /* help */ + help = TRUE; + break; + case 'V': /* verbose */ + verbose = TRUE; + break; + case 'I': /* show info only, do not execute */ + verbose = TRUE; + execute_program = 0; + break; + default: + error = TRUE; + break; + } + } else { + error = TRUE; + } + + if (error) { + fprintf(stderr, "Illegal argument: \"%s\"\n", argv[arg]); + help = TRUE; + error = FALSE; + } + } + + if (help) { + jbi_help(); + return 0; + } + + /* Calibrate the delay loop function */ + calibrate_delay(); + + jbi_init_mm(); + + /* Check CRC */ + crc_result = jbi_check_crc(addr, size, &expected_crc, &actual_crc); + if (verbose || (crc_result == JBIC_CRC_ERROR)) { + switch (crc_result) { + case JBIC_SUCCESS: + printf("CRC matched: CRC value = %04X\n", actual_crc); + break; + case JBIC_CRC_ERROR: + printf("CRC mismatch: expected %04X, actual %04X\n", expected_crc, actual_crc); + return -1; + case JBIC_UNEXPECTED_END: + printf("Expected CRC not found, actual CRC value = %04X\n", actual_crc); + return -1; + case JBIC_IO_ERROR: + printf("Error: File format is not recognized.\n"); + return -1; + default: + printf("CRC function returned error code %d\n", crc_result); + return -1; + } + } + + if (verbose) { + /* Display file format version */ + jbi_get_file_info(addr, size, &format_version, + &action_count, &procedure_count); + + printf("File format is %s ByteCode format\n", + (format_version == 2) ? "Jam STAPL" : "pre-standardized Jam 1.1"); + + /* Dump out NOTE fields */ + while (jbi_get_note(addr, size, &offset, key, value, 256) == 0) { + printf("NOTE \"%s\" = \"%s\"\n", key, value); + } + + /* Dump the action table */ + if ((format_version == 2) && (action_count > 0)) { + printf("\nActions available in this file:\n"); + + for (index = 0; index < action_count; ++index) { + jbi_get_action_info(addr, size, + index, &action_name, &description, &procedure_list); + + if (description == NULL) { + printf("%s\n", action_name); + } else { + printf("%s \"%s\"\n", action_name, description); + } + + procptr = procedure_list; + while (procptr != NULL) { + if (procptr->attributes != 0) { + printf(" %s (%s)\n", procptr->name, + (procptr->attributes == 1) ? "optional" : "recommended"); + } + + procedure_list = procptr->next; + jbi_free(procptr); + procptr = procedure_list; + } + } + + /* add a blank line before execution messages */ + if (execute_program) + printf("\n"); + } + } + + if (execute_program) { + /* Execute the Jam STAPL ByteCode program */ + exec_result = jbi_execute(addr, size, workspace, + workspace_size, action, init_list, reset_jtag, + &error_address, &exit_code, &format_version); + if (exec_result == JBIC_SUCCESS) { + exit_string = get_exit_string(format_version, exit_code); + printf("Exit code = %d... %s\n", exit_code, exit_string); + } else if ((format_version == 2) && (exec_result == JBIC_ACTION_NOT_FOUND)) { + if ((action == NULL) || (*action == '\0')) { + printf("Error: no action specified for Jam STAPL file.\n" + "Program terminated.\n"); + } else { + printf("Error: action \"%s\" is not supported for this Jam STAPL file.\n" + "Program terminated.\n", action); + } + } else if (exec_result < MAX_ERROR_CODE) { + printf("Error at address %ld: %s.\nProgram terminated.\n", + error_address, error_text[exec_result]); + } else { + printf("Unknown error code %d\n", exec_result); + } + } + + if (jtag_hardware_initialized) { + close_jtag_hardware(); + jtag_hardware_initialized = FALSE; + } + +#if defined(MEM_TRACKER) + if (verbose) { +#if defined(USE_STATIC_MEMORY) + fprintf(stdout, "Memory Usage Info: static memory size = %uBytes (%dKB)\n", + N_STATIC_MEMORY_BYTES, N_STATIC_MEMORY_KBYTES); +#endif /* USE_STATIC_MEMORY */ + fprintf(stdout, "Memory Usage Info: peak memory usage = %uBytes (%dKB)\n", + peak_memory_usage, (peak_memory_usage + 1023) / 1024); + fprintf(stdout, "Memory Usage Info: peak allocations = %u\n", + peak_allocations); +#if defined(USE_STATIC_MEMORY) + if ((n_bytes_allocated - n_bytes_not_recovered) != 0) { + fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", + (n_bytes_allocated - n_bytes_not_recovered), + ((n_bytes_allocated - n_bytes_not_recovered) + 1023) / 1024); + } +#else /* USE_STATIC_MEMORY */ + if (n_bytes_allocated != 0) { + fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", + n_bytes_allocated, (n_bytes_allocated + 1023) / 1024); + } +#endif /* USE_STATIC_MEMORY */ + if (n_allocations != 0) { + fprintf(stdout, "Memory Usage Info: allocations not freed = %d\n", n_allocations); + } + } +#endif /* MEM_TRACKER */ + + jbi_exit_mm(); + + if (exec_result != JBIC_SUCCESS) { + return (-exec_result); + } + + if (exit_code != 0) { + return (exit_code); + } + + return (exit_status); +} + +#endif /* PORT == EMBEDDED */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.h new file mode 100644 index 000000000000..5e5c5332f385 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_cpld/jbistub.h @@ -0,0 +1,95 @@ +#ifndef __JBISTUB_H__ +#define __JBISTUB_H__ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_64BIT +typedef s64 addr_t; +#else +typedef s32 addr_t; +#endif +/* typedef long addr_t; */ + +/* #define USE_STATIC_MEMORY 100 */ +/* #define MEM_TRACKER */ + +/* #define O_RDWR 1 */ + +#define stdout (1) +#define stderr (2) + +#define puts printk +#define printf printk + +#define fprintf(std, fmt, arg...) \ + do { \ + printf(fmt, ##arg); \ + } while (0) + +#define DEBUG_NONE 0 +#define DEBUG_ERR 1 +#define DEBUG_DETAIL 2 +#define DEBUG_NOISY 3 +#define DEBUG_MM 4 + +#define jbi_dbg(level, fmt, arg...) \ + do { \ + if (level <= jbi_debug_level) { \ + printf(fmt, ##arg); \ + } \ + } while (0) + +extern int jbi_debug_level; + +static inline int open(char *path, int flag) +{ + return 0; +} + +static inline int close(int fd) +{ + return 0; +} + +static inline int read(int fd, char *buf, int count) +{ + return 0; +} + +static inline int write(int fd, char *buf, int count) +{ + return 0; +} + +static inline int fflush(int fd) +{ + return 0; +} + +static inline int clock(void) +{ + return 0; +} + +static inline int atoi(const char *nptr) +{ + return (int) simple_strtol(nptr, (char **) NULL, 10); +} + +static inline void *malloc(size_t size) +{ + return kmalloc(size, GFP_KERNEL); +} + +static inline void free(void *ptr) +{ + kfree(ptr); +} + +#endif /* __JBISTUB_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/Makefile new file mode 100644 index 000000000000..caad44948030 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/Makefile @@ -0,0 +1,22 @@ +#include $(top_srcdir)/debian/rules +#KERNELDIR := ${KBUILD_OUTPUT} + +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../include) +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) +EXTRA_CFLAGS+= -Wall + +firmware_driver_ispvme-objs := firmware_ispvme.o +firmware_driver_ispvme-objs += firmware_cpld_ispvme.o firmware_cpld_upgrade_ispvme.o + +#ifndef CONFIG_FRM_PRODUCT_FILE + +$(warning $(firmware_driver_ispvme-objs)) +obj-m := firmware_driver_ispvme.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(common_module_dir) ]; then mkdir -p $(common_module_dir) ;fi + cp -p $(PWD)/*.ko $(common_module_dir) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_ispvme.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_ispvme.c new file mode 100644 index 000000000000..9841782290c1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_ispvme.c @@ -0,0 +1,450 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int firmware_cpld_open(struct inode *inode, struct file *file) +{ + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Open cpld device.\n"); + frm_dev = firmware_get_device_by_minor(MINOR(inode->i_rdev)); + if (frm_dev == NULL) { + return -ENXIO; + } + file->private_data = frm_dev; + + return FIRMWARE_SUCCESS; +} + +static ssize_t firmware_cpld_read (struct file *file, char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static ssize_t firmware_cpld_write (struct file *file, const char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static loff_t firmware_cpld_llseek(struct file *file, loff_t offset, int origin) +{ + return 0; +} + +/* + * firmware_cpld_ioctl + * function: ispvme driver ioctl command parsing function + * @file: param[in] device file name + * @cmd: param[in] command + * @arg: param[in] the parameters in the command + * return value: success-FIRMWARE_SUCCESS; fail:other value + */ +static long firmware_cpld_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + void __user *argp; + firmware_device_t *frm_dev; + firmware_cpld_t *cpld_info; + char value; + + /* Get device private data */ + frm_dev = (firmware_device_t *)file->private_data; + cpld_info = NULL; + if (frm_dev != NULL) { + if (frm_dev->priv != NULL) { + cpld_info = (firmware_cpld_t *)frm_dev->priv; + } + } + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to frm_dev->priv sysfs info.\n"); + return FIRMWARE_FAILED; + } + argp = (void __user *)arg; + + switch (cmd) { + case FIRMWARE_JTAG_TDI: + /* Set the TDI signal */ + if (copy_from_user(&value, argp, sizeof(value))) { + return -EFAULT; + } + if (fwm_cpld_tdi_op(value) < 0 ) { + return -EFAULT; + } + break; + case FIRMWARE_JTAG_TCK: + /* Set the TCK signal */ + if (copy_from_user(&value, argp, sizeof(value))) { + return -EFAULT; + } + if (fwm_cpld_tck_op(value) < 0) { + return -EFAULT; + } + break; + case FIRMWARE_JTAG_TMS: + /* Set the TMS signal */ + if (copy_from_user(&value, argp, sizeof(value))) { + return -EFAULT; + } + if (fwm_cpld_tms_op(value) < 0) { + return -EFAULT; + } + break; + case FIRMWARE_JTAG_TDO: + /* Read the TDO signal */ + value = fwm_cpld_tdo_op(); + if (copy_to_user(argp, &value, sizeof(value))) { + return -EFAULT; + } + break; + case FIRMWARE_JTAG_INIT: + /* The VME upgrade mode initializes the operation */ + ret=firmware_init_vme(cpld_info); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to init upgrade.(chain = %d)\n", + frm_dev != NULL ? frm_dev->chain : -1); + return FIRMWARE_FAILED; + } + break; + case FIRMWARE_JTAG_FINISH: + /* The VME upgrade mode completes the operation */ + ret=firmware_finish_vme(cpld_info); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to release upgrade.(chain = %d)\n", + frm_dev != NULL ? frm_dev->chain : -1); + return FIRMWARE_FAILED; + } + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("not find cmd: %d\r\n", cmd); + return -ENOTTY; + } /* End of switch */ + + return FIRMWARE_SUCCESS; +} + +static int firmware_cpld_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations cpld_dev_fops = { + .owner = THIS_MODULE, + .llseek = firmware_cpld_llseek, + .read = firmware_cpld_read, + .write = firmware_cpld_write, + .unlocked_ioctl = firmware_cpld_ioctl, + .open = firmware_cpld_open, + .release = firmware_cpld_release, +}; + +static int of_firmware_upgrade_config_init(struct device *dev, firmware_cpld_t *cpld_info) +{ + int ret; + char *name; + int i; + char buf[64]; + firmware_logic_dev_en_t *firmware_logic_dev_en_point; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_upgrade_config_init\r\n"); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + mem_clear(cpld_info, sizeof(firmware_cpld_t)); + ret = 0; + ret += of_property_read_string(dev->of_node, "type", (const char **)&name); + ret += of_property_read_u32(dev->of_node, "tdi", &cpld_info->tdi); + ret += of_property_read_u32(dev->of_node, "tck", &cpld_info->tck); + ret += of_property_read_u32(dev->of_node, "tms", &cpld_info->tms); + ret += of_property_read_u32(dev->of_node, "tdo", &cpld_info->tdo); + + ret += of_property_read_u32(dev->of_node, "chain", &cpld_info->chain); + ret += of_property_read_u32(dev->of_node, "chip_index", &cpld_info->chip_index); + + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config error, ret:%d.\n", ret); + return -ENXIO; + } + + strncpy(cpld_info->type, name, sizeof(cpld_info->type) - 1); + + ret = of_property_read_u32(dev->of_node, "tck_delay", &cpld_info->tck_delay); + if(ret != 0) { + cpld_info->tck_delay = 60; + } + + cpld_info->gpio_en_info_num = 0; + /* Enable through GPIO */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_gpio_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &cpld_info->gpio_en_info[i].en_gpio); + if(ret != 0) { + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_level_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &cpld_info->gpio_en_info[i].en_level); + if(ret != 0) { + break; + } + cpld_info->gpio_en_info_num++; + } + + cpld_info->logic_dev_en_num = 0; + /* Enable through register */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + firmware_logic_dev_en_point = &cpld_info->logic_dev_en_info[i]; + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_dev_%d", i); + ret = 0; + ret += of_property_read_string(dev->of_node, buf, (const char **)&name); + if(ret != 0) { + /* Failure to resolve to EN_LOGIC_DEV means no logical device is enabled. No failure is returned */ + ret = 0; + break; + } + strncpy(firmware_logic_dev_en_point->dev_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_addr_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->addr); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_addr_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_mask_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->mask); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_mask_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_en_val_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->en_val); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_en_val_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_dis_val_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->dis_val); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_dis_val_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_width_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->width); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_width_%d ret =%d.\n", i, ret); + break; + } + + cpld_info->logic_dev_en_num++; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("type:%s, chain:%u, chip_index:%u, gpio_en_info_num:%u logic_dev_en_num:%u\n", + cpld_info->type, cpld_info->chain, cpld_info->chip_index, cpld_info->gpio_en_info_num, cpld_info->logic_dev_en_num); + FIRMWARE_DRIVER_DEBUG_VERBOSE("tdi:%u, tck:%u, tms:%u, tdo:%u tck_delay:%u.\n", + cpld_info->tdi, cpld_info->tck, cpld_info->tms, cpld_info->tdo, cpld_info->tck_delay); + + return 0; +} + +static int firmware_upgrade_config_init(struct device *dev, firmware_cpld_t *cpld_info) +{ + int i; + + firmware_logic_dev_en_t *firmware_logic_dev_en_point; + firmware_upgrade_device_t *firmware_upgrade_device; + firmware_jtag_device_t jtag_upg_device; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_upgrade_config_init\r\n"); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + if (dev->platform_data == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("platform data config error.\n"); + return -1; + } + firmware_upgrade_device = dev->platform_data; + jtag_upg_device = firmware_upgrade_device->upg_type.jtag; + + mem_clear(cpld_info, sizeof(firmware_cpld_t)); + strncpy(cpld_info->type, firmware_upgrade_device->type, sizeof(cpld_info->type) - 1); + cpld_info->tdi = jtag_upg_device.tdi; + cpld_info->tck = jtag_upg_device.tck; + cpld_info->tms = jtag_upg_device.tms; + cpld_info->tdo = jtag_upg_device.tdo; + cpld_info->chain = firmware_upgrade_device->chain; + cpld_info->chip_index = firmware_upgrade_device->chip_index; + + if (jtag_upg_device.tck_delay == 0) { + cpld_info->tck_delay = 60; + FIRMWARE_DRIVER_DEBUG_VERBOSE("no config tck_delay, use default value:%u\n", cpld_info->tck_delay); + } else { + cpld_info->tck_delay = jtag_upg_device.tck_delay; + } + + if (firmware_upgrade_device->en_gpio_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_gpio_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_gpio_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + cpld_info->gpio_en_info_num = firmware_upgrade_device->en_gpio_num; + /* Enable through GPIO */ + for (i = 0; i < cpld_info->gpio_en_info_num; i++) { + cpld_info->gpio_en_info[i].en_gpio = firmware_upgrade_device->en_gpio[i]; + cpld_info->gpio_en_info[i].en_level = firmware_upgrade_device->en_level[i]; + } + + if (firmware_upgrade_device->en_logic_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_logic_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_logic_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + cpld_info->logic_dev_en_num = firmware_upgrade_device->en_logic_num; + /* Enable through register */ + for (i = 0; i < cpld_info->logic_dev_en_num; i++) { + firmware_logic_dev_en_point = &cpld_info->logic_dev_en_info[i]; + strncpy(firmware_logic_dev_en_point->dev_name, firmware_upgrade_device->en_logic_dev[i], + FIRMWARE_DEV_NAME_LEN - 1); + firmware_logic_dev_en_point->addr = firmware_upgrade_device->en_logic_addr[i]; + firmware_logic_dev_en_point->mask = firmware_upgrade_device->en_logic_mask[i]; + firmware_logic_dev_en_point->en_val = firmware_upgrade_device->en_logic_en_val[i]; + firmware_logic_dev_en_point->dis_val = firmware_upgrade_device->en_logic_dis_val[i]; + firmware_logic_dev_en_point->width = firmware_upgrade_device->en_logic_width[i]; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("type:%s, chain:%u, chip_index:%u, gpio_en_info_num:%u logic_dev_en_num:%u\n", + cpld_info->type, cpld_info->chain, cpld_info->chip_index, cpld_info->gpio_en_info_num, cpld_info->logic_dev_en_num); + FIRMWARE_DRIVER_DEBUG_VERBOSE("tdi:%u, tck:%u, tms:%u, tdo:%u tck_delay:%u.\n", + cpld_info->tdi, cpld_info->tck, cpld_info->tms, cpld_info->tdo, cpld_info->tck_delay); + + return 0; +} + +static int firmware_cpld_probe(struct platform_device *pdev) +{ + int ret; + firmware_cpld_t *cpld_info; + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_cpld_probe\r\n"); + /* Gets the information in the device tree */ + cpld_info = devm_kzalloc(&pdev->dev, sizeof(firmware_cpld_t), GFP_KERNEL); + if (cpld_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc cpld device tree.\n"); + return -EPERM; + } + + if (pdev->dev.of_node) { + ret = of_firmware_upgrade_config_init(&pdev->dev, cpld_info); + } else { + ret = firmware_upgrade_config_init(&pdev->dev, cpld_info); + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("get config init from dts error.\n"); + return -EPERM; + } + + frm_dev = devm_kzalloc(&pdev->dev, sizeof(firmware_device_t), GFP_KERNEL); + if (frm_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc firmware device.\n"); + return -EPERM; + } + + /* Based on the link number, determine the name of the device file */ + frm_dev->chain = cpld_info->chain; + snprintf(frm_dev->name, FIRMWARE_NAME_LEN - 1, "firmware_cpld_ispvme%d", frm_dev->chain); + strncpy(cpld_info->devname, frm_dev->name, strlen(frm_dev->name) + 1); + + INIT_LIST_HEAD(&frm_dev->list); + frm_dev->dev.minor = MISC_DYNAMIC_MINOR; + frm_dev->dev.name = frm_dev->name; + frm_dev->dev.fops = &cpld_dev_fops; + frm_dev->priv = cpld_info; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Register cpld firmware chain:%d, name:%s.\n", frm_dev->chain, frm_dev->name); + + ret = firmware_device_register(frm_dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to register firmware device.\n"); + return -EPERM; + } + + platform_set_drvdata(pdev, frm_dev); + return 0; +} + +static int __exit firmware_cpld_remove(struct platform_device *pdev) +{ + firmware_device_t *frm_dev; + + frm_dev = (firmware_device_t *)platform_get_drvdata(pdev); + firmware_device_unregister(frm_dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct of_device_id cpld_match[] = { + { + .compatible = "firmware_cpld_ispvme", + }, + {}, +}; + +static struct platform_driver cpld_driver = { + .driver = { + .name = "firmware_cpld_ispvme", + .owner = THIS_MODULE, + .of_match_table = cpld_match, + }, + .probe = firmware_cpld_probe, + .remove = firmware_cpld_remove, +}; + +static firmware_driver_t fmw_drv_cpld = { + .name = "firmware_cpld_ispvme", + .drv = &cpld_driver, +}; + +int firmware_cpld_init(void) +{ + int ret; + + INIT_LIST_HEAD(&fmw_drv_cpld.list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("ispvme upgrade driver register \n"); + ret = firmware_driver_register(&fmw_drv_cpld); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("ispvme upgrade driver register failed\n"); + return ret; + } + return 0; +} + +void firmware_cpld_exit(void) +{ + firmware_driver_unregister(&fmw_drv_cpld); + INIT_LIST_HEAD(&fmw_drv_cpld.list); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_upgrade_ispvme.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_upgrade_ispvme.c new file mode 100644 index 000000000000..b8896ed75f38 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_cpld_upgrade_ispvme.c @@ -0,0 +1,691 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* TCK clock MAX 16MHz */ +#define TCK_DELAY (current_fmw_cpld->tck_delay) + +#if 0 +static firmware_cpld_t default_fmw_cpld; +#endif + +static firmware_cpld_t *current_fmw_cpld; + +static int TDI_PULL_UP(void); +static int TDI_PULL_DOWN(void); +static int TMS_PULL_UP(void); +static int TMS_PULL_DOWN(void); +static int TCK_PULL_UP(void); +static int TCK_PULL_DOWN(void); + +/* + * set_currrent_cpld_info + * function: Save the current device information + * @info: param[in] Information about the device to be updated + */ +static void set_currrent_cpld_info(firmware_cpld_t *info) +{ + current_fmw_cpld = info; +} + +static int firmware_file_read(const char *path, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + FIRMWARE_DRIVER_DEBUG_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + pos = (loff_t)addr; + ret = kernel_read(filp, val, size, &pos); + if (ret != size) { + FIRMWARE_DRIVER_DEBUG_ERROR("read kernel_read failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, addr, size, ret); + goto exit; + } + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int firmware_file_write(const char *path, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + FIRMWARE_DRIVER_DEBUG_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + pos = (loff_t)addr; + ret = kernel_write(filp, (void*)val, size, &pos); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("write kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, addr, size, ret); + goto exit; + } + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +/* + * firmware_file_do_work + * function: Sets logical register values + * @path:param[in] Logic device descriptor + * @addr:param[in] Logic device address + * @value:param[in] the register value needs to be set + * @mask:param[in] register mask + * @width:param[in] register bit width + * return: 0:success, <0:failed + */ +static int firmware_file_do_work(char *path, uint32_t addr, uint32_t value, uint32_t mask, + int32_t width) +{ + int ret; + uint8_t read_value[4], write_value[4]; + uint8_t tmp_read8, tmp_write8, tmp_mask8; + uint32_t tmp_read32, tmp_write32; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("path=%s, addr=0x%x, value=0x%x mask=0x%x\r\n", path, addr, value, mask); + if ((width > 4) || (width < 0)) { + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + } + ret = 0; + mem_clear(read_value, sizeof(read_value)); + mem_clear(write_value, sizeof(write_value)); + ret = firmware_file_read(path, addr, read_value, width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware sysfs read.\r\n"); + return -1; + } + + switch (width) { + case 1: + tmp_read8 = read_value[0]; + tmp_mask8 = (uint8_t)(mask) & 0xFF; + tmp_write8 = (uint8_t)value & 0xFF; + write_value[0] = (tmp_read8 & tmp_mask8) | tmp_write8; + FIRMWARE_DRIVER_DEBUG_VERBOSE("1 byte write val[0]:0x%x", write_value[0]); + break; + case 2: + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + case 4: + memcpy((uint8_t *)&tmp_read32, read_value, 4); + tmp_write32 = (tmp_read32 & mask) | value; + memcpy(write_value, (uint8_t *)&tmp_write32, 4); + FIRMWARE_DRIVER_DEBUG_VERBOSE("4 byte write val[0]:0x%x, val[1]:0x%x, val[2]:0x%x, val[3]:0x%x", + write_value[0], write_value[1], write_value[2], write_value[3]); + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("write logic dev[%s] addr[0x%x].\r\n", path, addr); + ret = firmware_file_write(path, addr, write_value, width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware_file_write %s addr 0x%x failed, ret=%d.\r\n", path, addr, ret); + return -1; + } + + return 0; +} + +/* + * firmware_upgrade_en + * function: Upgrade access enabling switch + * @flag: !0:enable 0:disable + */ +static int firmware_upgrade_en(int flag) +{ + int i; + firmware_logic_dev_en_t *firmware_logic_dev_en_info; + int ret, rv; + char *dev_name; + + ret = 0; + FIRMWARE_DRIVER_DEBUG_VERBOSE("%s en switch: gpio en num %d, logic reg en num %d.\n", + flag ? "Open" : "Close", current_fmw_cpld->gpio_en_info_num, current_fmw_cpld->logic_dev_en_num); + for (i = 0; i < current_fmw_cpld->gpio_en_info_num; i++) { + if (flag) { + ret = gpio_request(current_fmw_cpld->gpio_en_info[i].en_gpio, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade EN[%d] GPIO[%d] failed!\n", + i, current_fmw_cpld->gpio_en_info[i].en_gpio); + goto free_gpio; + } + gpio_direction_output(current_fmw_cpld->gpio_en_info[i].en_gpio, current_fmw_cpld->gpio_en_info[i].en_level); + current_fmw_cpld->gpio_en_info[i].flag = 1; + } else { + gpio_set_value(current_fmw_cpld->gpio_en_info[i].en_gpio, !current_fmw_cpld->gpio_en_info[i].en_level); + gpio_free(current_fmw_cpld->gpio_en_info[i].en_gpio); + current_fmw_cpld->gpio_en_info[i].flag = 0; + } + } + + for (i = 0; i < current_fmw_cpld->logic_dev_en_num; i++) { + firmware_logic_dev_en_info = ¤t_fmw_cpld->logic_dev_en_info[i]; + dev_name = firmware_logic_dev_en_info->dev_name; + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware sysfs [%d] dev_name[%s] addr[0x%x] mask[0x%x]" + " en_val[0x%x] dis_val[0x%x] width[%d]\n", + i , firmware_logic_dev_en_info->dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->mask, firmware_logic_dev_en_info->en_val, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->width); + if (flag) { + ret = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->en_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Open logic register [%d] EN failed, ret %d.\n", i, ret); + goto free_logic_dev; + } else { + firmware_logic_dev_en_info->flag = 1; + } + } else { + rv = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (rv < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Close logic register [%d] EN failed, ret %d.\n", i, rv); + ret = -1; + } + firmware_logic_dev_en_info->flag = 0; + } + } + + return ret; +free_logic_dev: + for (i = 0; i < current_fmw_cpld->logic_dev_en_num; i++) { + firmware_logic_dev_en_info = ¤t_fmw_cpld->logic_dev_en_info[i]; + dev_name = firmware_logic_dev_en_info->dev_name; + if (firmware_logic_dev_en_info->flag == 1) { + ret = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Close logic register [%d] EN failed, ret %d.\n", i, ret); + } + firmware_logic_dev_en_info->flag = 0; + } else { + break; + } + } +free_gpio: + for (i = 0; i < current_fmw_cpld->gpio_en_info_num; i++) { + if (current_fmw_cpld->gpio_en_info[i].flag == 1) { + gpio_set_value(current_fmw_cpld->gpio_en_info[i].en_gpio, !current_fmw_cpld->gpio_en_info[i].en_level); + gpio_free(current_fmw_cpld->gpio_en_info[i].en_gpio); + current_fmw_cpld->gpio_en_info[i].flag = 0; + } else { + break; + } + } + + return -1; +} + +/* + * init_cpld + * function:Initialize CPLD + * return value: 0 success ; -1 fail + */ +static int init_cpld(void) +{ + int ret; + if (current_fmw_cpld == NULL) { + return -1; + } + mdelay(10); + ret = 0; + ret = gpio_request(current_fmw_cpld->tdi, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade TDI GPIO failed!\n"); + return ret; + } + ret = gpio_request(current_fmw_cpld->tck, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade TCK GPIO failed!\n"); + goto free_tdi; + } + ret = gpio_request(current_fmw_cpld->tms, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade TMS GPIO failed!\n"); + goto free_tck; + } + ret = gpio_request(current_fmw_cpld->tdo, "cpld_ispvme_upgrade"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade TDO GPIO failed!\n"); + goto free_tms; + } + + gpio_direction_output(current_fmw_cpld->tdi, 1); + gpio_direction_output(current_fmw_cpld->tck, 1); + gpio_direction_output(current_fmw_cpld->tms, 1); + + gpio_direction_input(current_fmw_cpld->tdo); + ret = firmware_upgrade_en(1); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: open firmware upgrade en failed, ret %d.\n", ret); + goto free_tdo; + } +#if 0 + /* test GPIO */ + if (TDI_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TDI_PULL_UP failed.\n"); + goto free_tdo; + } + if (TDI_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TDI_PULL_DOWN failed.\n"); + goto free_tdo; + } + if (TMS_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TMS_PULL_UP failed.\n"); + goto free_tdo; + } + if (TMS_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TMS_PULL_DOWN failed.\n"); + goto free_tdo; + } + if (TCK_PULL_UP() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TCK_PULL_UP failed.\n"); + goto free_tdo; + } + if (TCK_PULL_DOWN() < 0 ) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: TCK_PULL_DOWN failed.\n"); + goto free_tdo; + } +#endif + mdelay(10); + return 0; + +free_tdo: + gpio_free(current_fmw_cpld->tdo); +free_tms: + gpio_free(current_fmw_cpld->tms); +free_tck: + gpio_free(current_fmw_cpld->tck); +free_tdi: + gpio_free(current_fmw_cpld->tdi); + return ret; +} + +/* + * finish_cpld + * function: finish CPLD upgrade operation + * return value: 0 success ; -1 fail + */ +static int finish_cpld(void) +{ + int ret; + + if (current_fmw_cpld == NULL) { + return -1; + } + mdelay(10); + ret = firmware_upgrade_en(0); + if (ret < 0){ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: close firmware upgrade en failed, ret %d.\r\n", ret); + } + + gpio_free(current_fmw_cpld->tdi); + gpio_free(current_fmw_cpld->tck); + gpio_free(current_fmw_cpld->tms); + gpio_free(current_fmw_cpld->tdo); + mdelay(10); + return 0; +} + +/* Loop waiting for */ +static int pull_wait(int gpio, int value) { + int i, j; + /* Timeout time is two seconds */ + for (i = 0; i < 20; i++) { + for (j = 0; j < 100; j++) { + if (!!gpio_get_value(gpio) == !!value ) { + return 0; + } + /* The first loop does not delay, normally the first loop can immediately return the result */ + if (i) { + mdelay(1); + } + } + /* The CPU is released every 100ms */ + schedule(); + } + /* timeout */ + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Wait gpio %d pull to %d failed.\n", gpio, value); + return -1; +} + +/* TDI pull-up */ +static int pull_tdi_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tdi, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tdi, 1); +} + +/* TDI pull-down */ +static int pull_tdi_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tdi, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tdi, 0); +} + +/* TCK pull-up */ +static int pull_tck_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tck, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tck, 1); +} + +/* TCK pull-down */ +static int pull_tck_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tck, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tck, 0); +} + +/* TMS pull-up */ +static int pull_tms_up(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tms, 1); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tms, 1); +} + +/* TMS pull-down */ +static int pull_tms_down(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + gpio_set_value(current_fmw_cpld->tms, 0); + + /* Wait for the GPIO value to be set successfully */ + return pull_wait(current_fmw_cpld->tms, 0); +} + +/* Read TDO */ +static int read_tdo(void) +{ + if (current_fmw_cpld == NULL) { + return -1; + } + return gpio_get_value(current_fmw_cpld->tdo); +} + +static firmware_cpld_function_t function_fmw_cpld = { + .pull_tdi_up = pull_tdi_up, + .pull_tdi_down = pull_tdi_down, + .pull_tck_up = pull_tck_up, + .pull_tck_down = pull_tck_down, + .pull_tms_up = pull_tms_up, + .pull_tms_down = pull_tms_down, + .read_tdo = read_tdo, + .init_cpld = init_cpld, + .finish_cpld = finish_cpld, +}; + +/* + * TDI_PULL_DOWN + * function: Lower TDI + */ +static int TDI_PULL_DOWN(void) +{ + if ( function_fmw_cpld.pull_tdi_down != NULL) { + return function_fmw_cpld.pull_tdi_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDI_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TDI_PULL_UP + * function: High TDI + */ +static int TDI_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tdi_up != NULL) { + return function_fmw_cpld.pull_tdi_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDI_PULL_UP.\n"); + return -1; + } +} + +/* + * TCK_PULL_DOWN + * function: Lower TCK + */ +static int TCK_PULL_DOWN(void) +{ + if (function_fmw_cpld.pull_tck_down != NULL) { + return function_fmw_cpld.pull_tck_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TCK_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TCK_PULL_UP + * function: High TCK + */ +static int TCK_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tck_up != NULL) { + return function_fmw_cpld.pull_tck_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TCK_PULL_UP.\n"); + return -1; + } +} + +/* + * TMS_PULL_DOWN + * function: Lower TMS + */ +static int TMS_PULL_DOWN(void) +{ + if (function_fmw_cpld.pull_tms_down != NULL) { + return function_fmw_cpld.pull_tms_down(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TMS_PULL_DOWN.\n"); + return -1; + } +} + +/* + * TMS_PULL_UP + * function: High TMS + */ +static int TMS_PULL_UP(void) +{ + if (function_fmw_cpld.pull_tms_up != NULL) { + return function_fmw_cpld.pull_tms_up(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TMS_PULL_UP.\n"); + return -1; + } +} + +/* + * TDO_READ + * function:Read the TDO level + */ +static int TDO_READ(void) +{ + if (function_fmw_cpld.read_tdo != NULL) { + return function_fmw_cpld.read_tdo(); + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("NO support TDO_READ.\n"); + return -1; + } +} + +/* + * cpld_upgrade_init + * function:Initialize GPIO and CPLD + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int cpld_upgrade_init(void) +{ + int ret; + + if (function_fmw_cpld.init_cpld != NULL) { + ret = function_fmw_cpld.init_cpld(); + if (ret != FIRMWARE_SUCCESS) { + return ret; + } + } + + return FIRMWARE_SUCCESS; +} + +/* + * cpld_upgrade_finish + * function:Release GPIO and CPLD + * return value: success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int cpld_upgrade_finish(void) +{ + int ret; + + if (function_fmw_cpld.finish_cpld != NULL) { + ret = function_fmw_cpld.finish_cpld(); + if (ret != FIRMWARE_SUCCESS) { + return ret; + } + } + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_init_vme + * function: Initialize GPIO, + * @cpld_info: param[in] Information about the device to be written to + */ +int firmware_init_vme(firmware_cpld_t *cpld_info){ + int ret; + set_currrent_cpld_info(cpld_info); + /* Initialize GPIO and CPLD */ + ret = cpld_upgrade_init(); + return ret; +} + +/** + * firmware_finish_vme + * function: Release GPIO + * @cpld_info: param[in] Information about the device to be written to + */ +int firmware_finish_vme(firmware_cpld_t *cpld_info){ + int ret; + set_currrent_cpld_info(cpld_info); + ret = cpld_upgrade_finish(); + return ret; +} + +/** + * fwm_cpld_tdi_op + * function: Operate TDI + * @value: param[in] TDI level */ +int fwm_cpld_tdi_op(int value) +{ + if (value) { + return TDI_PULL_UP(); + } else { + return TDI_PULL_DOWN(); + } +} + +/** + * fwm_cpld_tck_op + * function: Operate TCK + * @value: param[in] TCK level */ +int fwm_cpld_tck_op(int value) +{ + if (value) { + return TCK_PULL_UP(); + } else { + return TCK_PULL_DOWN(); + } +} + +/** + * fwm_cpld_tms_op + * function: Operate TMS + * value: param[in] TMS level */ +int fwm_cpld_tms_op(int value) +{ + if (value) { + return TMS_PULL_UP(); + } else { + return TMS_PULL_DOWN(); + } +} + +/** + * fwm_cpld_tdo_op + * function: Read TDO + */ +int fwm_cpld_tdo_op() +{ + return TDO_READ(); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_ispvme.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_ispvme.c new file mode 100644 index 000000000000..e8f75844ae34 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/firmware_ispvme.c @@ -0,0 +1,140 @@ +#include +#include +#include + +int g_firmware_driver_debug = 0; +module_param(g_firmware_driver_debug, int, S_IRUGO | S_IWUSR); + +static LIST_HEAD(drv_list); +static LIST_HEAD(dev_list); + +/** + * firmware_driver_register + * function:Registered Device Driver + * @fw_drv:param[in] Driver information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_driver_register(firmware_driver_t *fw_drv) +{ + int ret; + + if (fw_drv == NULL) { + return FIRMWARE_FAILED; + } + + ret = platform_driver_register(fw_drv->drv); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: failed to register firmware upgrade driver \n"); + return FIRMWARE_FAILED; + } + + /* Adds driver information to the driver list */ + list_add(&fw_drv->list, &drv_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware upgrade driver register sucess \n"); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_driver_unregister + * function:unregister Device Driver + * @fw_drv:param[in] Driver information + */ +void firmware_driver_unregister(firmware_driver_t *fw_drv) +{ + list_del_init(&fw_drv->list); + platform_driver_unregister(fw_drv->drv); +} + +/* + * firmware_get_device_by_minor + * function: Get device information based on minor + */ +firmware_device_t *firmware_get_device_by_minor(int minor) +{ + firmware_device_t *tmp; + + list_for_each_entry(tmp, &dev_list, list) { + if (tmp->dev.minor == minor) { + return tmp; + } + } + + return NULL; +} + +/** + * firmware_device_register + * function:Registered Driver Device + * @fw_dev: param[in] Driver information + * return value:success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_device_register(firmware_device_t *fw_dev) +{ + int ret; + firmware_device_t *tmp; + + if (fw_dev == NULL) { + return FIRMWARE_FAILED; + } + /* Check whether the device file name already exists in the device linked list */ + list_for_each_entry(tmp, &dev_list, list) { + if (strcmp(tmp->name, fw_dev->name) == 0) { + return FIRMWARE_FAILED; + } + } + + /* Registere device */ + ret = misc_register(&fw_dev->dev); + if (ret < 0) { + return FIRMWARE_FAILED; + } + + /* Adds a device to the device list */ + list_add(&fw_dev->list, &dev_list); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_device_unregister + * function: unregister Driver Device + */ +void firmware_device_unregister(firmware_device_t *fw_dev) +{ + list_del(&fw_dev->list); + misc_deregister(&fw_dev->dev); +} + +static int __init firmware_driver_init(void) +{ + int ret; + + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver ispvme init.\n"); + ret = firmware_cpld_init(); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware driver ispvme init failed.\n"); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +static void __exit firmware_driver_exit(void) +{ + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver ispvme exit.\n"); + firmware_cpld_exit(); + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + return; +} + +module_init(firmware_driver_init); +module_exit(firmware_driver_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Firmware upgrade ispvme driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_cpld_ispvme.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_cpld_ispvme.h new file mode 100644 index 000000000000..eb737d3a56ed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_cpld_ispvme.h @@ -0,0 +1,70 @@ +#ifndef __FIRMWARE_CPLD_H__ +#define __FIRMWARE_CPLD_H__ + +#define FIRMWARE_DEV_NAME_LEN 32 +#define FIRMWARE_MAX_CPLD_NUM 16 +#define FIRMWARE_TYPE_LEN 10 +#define FIRMWARE_EN_INFO_MAX 16 +#define FIRMWARE_EN_INFO_BUF 128 + +typedef struct firmware_gpio_jtag_en_s { + uint32_t en_gpio; /* GPIO enable pin */ + uint32_t en_level; /* GPIO enable level */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_gpio_jtag_en_t; + +typedef struct firmware_logic_dev_en_s { + char dev_name[FIRMWARE_DEV_NAME_LEN]; /* Logical device name */ + uint32_t addr; /* Enable register address */ + uint32_t mask; /* mask */ + uint32_t en_val; /* Enable value */ + uint32_t dis_val; /* Disable value*/ + uint32_t width; /* width */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_logic_dev_en_t; + +typedef struct firmware_cpld_s { + char devname[FIRMWARE_DEV_NAME_LEN]; /* Device name */ + char type[FIRMWARE_TYPE_LEN]; /* interface type */ + uint32_t tdi; /* TDI signal corresponding to GPIO pin information */ + uint32_t tck; /* TCK signal corresponding to GPIO pin information */ + uint32_t tms; /* TMS signal corresponding to GPIO pin information */ + uint32_t tdo; /* TDO signal corresponding to GPIO pin information */ + uint32_t chain; /* chain num */ + uint32_t chip_index; /* chip index */ + uint32_t tck_delay; /* Delay time */ + uint32_t gpio_en_info_num; /* GPIO Enable Number */ + firmware_gpio_jtag_en_t gpio_en_info[FIRMWARE_EN_INFO_MAX]; /* GPIO Enable Information */ + uint32_t logic_dev_en_num; /* Register Enable Number */ + firmware_logic_dev_en_t logic_dev_en_info[FIRMWARE_EN_INFO_MAX]; /* Register Enable Information */ +} firmware_cpld_t; + +typedef struct firmware_cpld_function_s{ + int (*pull_tdi_up)(void); /* TDI pull-up */ + int (*pull_tdi_down)(void); /* TDI pull-down */ + int (*pull_tck_up)(void); /* TCK pull-up */ + int (*pull_tck_down)(void); /* TCK pull-down */ + int (*pull_tms_up)(void); /* TMS pull-up */ + int (*pull_tms_down)(void); /* TCK pull-down */ + int (*read_tdo)(void); /* Read TDO */ + int (*init_cpld)(void); /* CPLD upgrade initializes the operation */ + int (*init_chip)(int chain); /* chip initializes the operation */ + int (*finish_chip)(int chain); /* chip completes the operation*/ + int (*finish_cpld)(void); /* CPLD upgrade completes the operation */ + int (*get_version)(int chain, char *ver, int len); /* get version */ +}firmware_cpld_function_t; + +/* operate TDI */ +extern int fwm_cpld_tdi_op(int value); +/* operate TCK */ +extern int fwm_cpld_tck_op(int value); +/* operate TMS */ +extern int fwm_cpld_tms_op(int value); +/* operate TDO */ +extern int fwm_cpld_tdo_op(void); +/* VME upgrade mode completes the operation*/ +extern int firmware_finish_vme(firmware_cpld_t *cpld_info); +/* VME upgrade mode initializes the operation*/ +extern int firmware_init_vme(firmware_cpld_t *cpld_info); + +#endif /* __FIRMWARE_CPLD_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_ispvme.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_ispvme.h new file mode 100644 index 000000000000..39baf3f30717 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_ispvme/include/firmware_ispvme.h @@ -0,0 +1,86 @@ +#ifndef __FIRMWARE_H__ +#define __FIRMWARE_H__ + +#include +#include + +#include + +/* Debug switch level */ +typedef enum { + FIRWMARE_VERBOSE, + FIRWMARE_WARN, + FIRWMARE_ERROR, + FIRWMARE_END, +} firmware_debug_level_t; + +#define FIRMWARE_DRIVER_DEBUG_VERBOSE(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_VERBOSE)) { \ + printk(KERN_INFO "[FIRMWARW_DRIVER_ISPVME][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_DRIVER_DEBUG_ERROR(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_ERROR)) { \ + printk(KERN_ERR "[FIRMWARW_DRIVER_ISPVME][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_NAME_LEN 48 + +#define FIRMWARE_FAILED (-1) +#define FIRMWARE_SUCCESS 0 + +/* ioctl publi command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_COMMON_TYPE 'C' +#define FIRMWARE_GET_CHIPNAME _IOR(FIRMWARE_COMMON_TYPE, 0, char) /* get the chip name */ +#define FIRMWARE_GET_VERSION _IOR(FIRMWARE_COMMON_TYPE, 2, int) /* get version */ + +/* firmware cpld ispvme driver ioctl command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_VME_TYPE 'V' +#define FIRMWARE_JTAG_TDI _IOR(FIRMWARE_VME_TYPE, 0, char) +#define FIRMWARE_JTAG_TDO _IOR(FIRMWARE_VME_TYPE, 1, char) +#define FIRMWARE_JTAG_TCK _IOR(FIRMWARE_VME_TYPE, 2, char) +#define FIRMWARE_JTAG_TMS _IOR(FIRMWARE_VME_TYPE, 3, char) +#define FIRMWARE_JTAG_EN _IOR(FIRMWARE_VME_TYPE, 4, char) +#define FIRMWARE_JTAG_INIT _IOR(FIRMWARE_VME_TYPE, 7, char) /* enable upgrade access */ +#define FIRMWARE_JTAG_FINISH _IOR(FIRMWARE_VME_TYPE, 8, char) /* disable upgrade access */ + +typedef struct cmd_info_s { + uint32_t size; + void __user *data; +} cmd_info_t; + +typedef struct firmware_device_s { + struct list_head list; /* device list */ + uint32_t chain; /* chain number */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct miscdevice dev; /* device */ + void *priv; /* private data */ +} firmware_device_t; + +typedef struct firmware_driver_s { + struct list_head list; /* list */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct platform_driver *drv; /* driver */ + void *priv; /* private data */ +} firmware_driver_t; + +extern int g_firmware_driver_debug; + +/* Get device information based on minor */ +extern firmware_device_t *firmware_get_device_by_minor(int minor); +/* Registere device */ +extern int firmware_device_register(firmware_device_t *fw_dev); +/* Unregister device */ +extern void firmware_device_unregister(firmware_device_t *fw_dev); +/* Registere driver */ +extern int firmware_driver_register(firmware_driver_t *fw_drv); +/* Unregister driver */ +extern void firmware_driver_unregister(firmware_driver_t *fw_drv); +/* CPLD upgrade initialized */ +extern int firmware_cpld_init(void); +/* CPLD unload function */ +extern void firmware_cpld_exit(void); + +#endif /* end of __FIRMWARE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/Makefile new file mode 100644 index 000000000000..a1d6d2e2ef68 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/Makefile @@ -0,0 +1,22 @@ +#include $(top_srcdir)/debian/rules +#KERNELDIR := ${KBUILD_OUTPUT} + +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../include) +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) +EXTRA_CFLAGS+= -Wall + +firmware_driver_sysfs-objs := firmware.o +firmware_driver_sysfs-objs += firmware_sysfs.o firmware_sysfs_upgrade.o + +#ifndef CONFIG_FRM_PRODUCT_FILE + +$(warning $(firmware_driver_sysfs-objs)) +obj-m := firmware_driver_sysfs.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(common_module_dir) ]; then mkdir -p $(common_module_dir) ;fi + cp -p $(PWD)/*.ko $(common_module_dir) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware.c new file mode 100644 index 000000000000..fec51d6238a6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware.c @@ -0,0 +1,143 @@ +#include +#include +#include + +int g_firmware_driver_debug = 0; +module_param(g_firmware_driver_debug, int, S_IRUGO | S_IWUSR); + +static LIST_HEAD(drv_list); +static LIST_HEAD(dev_list); + +/** + * firmware_driver_register + * function:Registered Device Driver + * @fw_drv:param[in] Driver information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_driver_register(firmware_driver_t *fw_drv) +{ + int ret; + + if (fw_drv == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Parameter error.\n"); + return FIRMWARE_FAILED; + } + + ret = platform_driver_register(fw_drv->drv); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: failed to register firmware upgrade driver \n"); + return FIRMWARE_FAILED; + } + + /* Adds driver information to the driver list */ + list_add(&fw_drv->list, &drv_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware upgrade driver register sucess \n"); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_driver_unregister + * function:unregister Device Driver + * @fw_drv:param[in] Driver information + */ +void firmware_driver_unregister(firmware_driver_t *fw_drv) +{ + list_del_init(&fw_drv->list); + platform_driver_unregister(fw_drv->drv); +} + +/* + * firmware_get_device_by_minor + * function: Get device information based on minor + */ +firmware_device_t *firmware_get_device_by_minor(int minor) +{ + firmware_device_t *tmp; + + list_for_each_entry(tmp, &dev_list, list) { + if (tmp->dev.minor == minor) { + return tmp; + } + } + + return NULL; +} + +/** + * firmware_device_register + * function:Registered Driver Device + * @fw_dev: param[in] Driver information + * return value:success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_device_register(firmware_device_t *fw_dev) +{ + int ret; + firmware_device_t *tmp; + + if (fw_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Parameter error.\n"); + return FIRMWARE_FAILED; + } + /* Check whether the device file name already exists in the device linked list */ + list_for_each_entry(tmp, &dev_list, list) { + if (strcmp(tmp->name, fw_dev->name) == 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("devie %s already exists.\n", fw_dev->name); + return FIRMWARE_FAILED; + } + } + + ret = misc_register(&fw_dev->dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("register misc error, ret=%d.\n", ret); + return FIRMWARE_FAILED; + } + + /* Adds driver information to the driver list */ + list_add(&fw_dev->list, &dev_list); + + return FIRMWARE_SUCCESS; +} + +/** + * firmware_device_unregister + * function: unregister Driver Device + */ +void firmware_device_unregister(firmware_device_t *fw_dev) +{ + list_del(&fw_dev->list); + misc_deregister(&fw_dev->dev); +} + +static int __init firmware_driver_init(void) +{ + int ret; + + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver sysfs init.\n"); + ret = firmware_sysfs_init(); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware driver sysfs init failed.\n"); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +static void __exit firmware_driver_exit(void) +{ + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware driver sysfs exit.\n"); + firmware_sysfs_exit(); + INIT_LIST_HEAD(&drv_list); + INIT_LIST_HEAD(&dev_list); + return; +} + +module_init(firmware_driver_init); +module_exit(firmware_driver_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Firmware upgrade driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs.c new file mode 100644 index 000000000000..a823cdc4f294 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs.c @@ -0,0 +1,495 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int firmware_sysfs_open(struct inode *inode, struct file *file) +{ + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Open device.\n"); + frm_dev = firmware_get_device_by_minor(MINOR(inode->i_rdev)); + if (frm_dev == NULL) { + return -ENXIO; + } + file->private_data = frm_dev; + + return FIRMWARE_SUCCESS; +} + +static ssize_t firmware_sysfs_read (struct file *file, char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static ssize_t firmware_sysfs_write (struct file *file, const char __user *buf, size_t count, + loff_t *offset) +{ + return 0; +} + +static loff_t firmware_sysfs_llseek(struct file *file, loff_t offset, int origin) +{ + return 0; +} + +/* firmware_sysfs_ioctl +* function:ioctl command parsing function +* @file: param[in] device file name +* @cmd: param[in] command +* @arg: param[in] the parameters in the command +* return value: success-FIRMWARE_SUCCESS; fail:other value +*/ +static long firmware_sysfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + void __user *argp; + firmware_device_t *frm_dev; + firmware_sysfs_t *sysfs_info; + int ret; + + /* Get device private data */ + frm_dev = (firmware_device_t *)file->private_data; + sysfs_info = NULL; + if (frm_dev != NULL) { + if (frm_dev->priv != NULL) { + sysfs_info = (firmware_sysfs_t *)frm_dev->priv; + } + } + if (sysfs_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to frm_dev->priv sysfs info.\n"); + return FIRMWARE_FAILED; + } + argp = (void __user *)arg; + + switch (cmd) { + case FIRMWARE_SYSFS_INIT: + /* enable upgrade access */ + ret = firmware_init_dev_loc(sysfs_info); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to init upgrade.(chain = %d)\n", + frm_dev != NULL ? frm_dev->chain : -1); + return FIRMWARE_FAILED; + } + break; + case FIRMWARE_SYSFS_FINISH: + /* disable upgrade access */ + ret = firmware_finish_dev_loc(sysfs_info); + if (ret != FIRMWARE_SUCCESS) { + FIRMWARE_DRIVER_DEBUG_ERROR("Error: Failed to release upgrade.(chain = %d)\n", + frm_dev != NULL ? frm_dev->chain : -1); + return FIRMWARE_FAILED; + } + break; + case FIRMWARE_SYSFS_SPI_INFO: + /* Get SPI logic device information */ + if (copy_to_user(argp, &sysfs_info->info.spi_logic_info, sizeof(firmware_spi_logic_info_t))) { + return -EFAULT; + } + break; + case FIRMWARE_SYSFS_DEV_FILE_INFO: + /*Get logic device information */ + if (copy_to_user(argp, &sysfs_info->info.dev_file_info, sizeof(firmware_dev_file_info_t))) { + return -EFAULT; + } + break; + case FIRMWARE_SYSFS_MTD_INFO: + /*Get logic device information */ + if (copy_to_user(argp, &sysfs_info->info.mtd_info, sizeof(firmware_mtd_info_t))) { + return -EFAULT; + } + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("not find cmd: %d\r\n", cmd); + return -ENOTTY; + } /* End of switch */ + + return FIRMWARE_SUCCESS; +} + +static int firmware_sysfs_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations sysfs_dev_fops = { + .owner = THIS_MODULE, + .llseek = firmware_sysfs_llseek, + .read = firmware_sysfs_read, + .write = firmware_sysfs_write, + .unlocked_ioctl = firmware_sysfs_ioctl, + .open = firmware_sysfs_open, + .release = firmware_sysfs_release, +}; + +/* Gets the information in the device tree */ +static int of_firmware_upgrade_config_init(struct device *dev, firmware_sysfs_t *sysfs_info) +{ + int ret; + char *name; + int8_t buf[64]; + int i; + firmware_logic_dev_en_t *firmware_logic_dev_en_point; + uint32_t test_base, test_size; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_dev_loc_config_init\r\n"); + if (sysfs_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + mem_clear(sysfs_info, sizeof(firmware_sysfs_t)); + ret = 0; + ret += of_property_read_string(dev->of_node, "type", (const char **)&name); + + ret += of_property_read_u32(dev->of_node, "chain", &sysfs_info->chain); + ret += of_property_read_u32(dev->of_node, "chip_index", &sysfs_info->chip_index); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config error, ret:%d.\n", ret); + return -ENXIO; + } + strncpy(sysfs_info->type, name, sizeof(sysfs_info->type) - 1); + + ret = of_property_read_u32(dev->of_node, "test_base", &test_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config test_base, ret:%d.\n", ret); + test_base = 0; + } + + ret = of_property_read_u32(dev->of_node, "test_size", &test_size); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config test_size, ret:%d.\n", ret); + test_size = 0; + } + + if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_SPI_LOGIC) == 0) { + ret = of_property_read_string(dev->of_node, "dev_name", (const char **)&name); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config dev_name error, ret:%d.\n", ret); + return -ENXIO; + } + strncpy(sysfs_info->info.spi_logic_info.dev_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + ret = of_property_read_u32(dev->of_node, "flash_base", &sysfs_info->info.spi_logic_info.flash_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config flash_base error, ret:%d.\n", ret); + return -ENXIO; + } + + ret = of_property_read_u32(dev->of_node, "ctrl_base", &sysfs_info->info.spi_logic_info.ctrl_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config ctrl_base error, ret:%d.\n", ret); + return -ENXIO; + } + sysfs_info->info.spi_logic_info.test_base = test_base; + sysfs_info->info.spi_logic_info.test_size = test_size; + } else if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_SYSFS) == 0) { + ret = of_property_read_string(dev->of_node, "sysfs_name", (const char **)&name); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config sysfs_name error, ret:%d.\n", ret); + return -ENXIO; + } + strncpy(sysfs_info->info.dev_file_info.sysfs_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + ret = of_property_read_u32(dev->of_node, "dev_base", &sysfs_info->info.dev_file_info.dev_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("dts don't config dev_base, dev_base is 0.\n"); + sysfs_info->info.dev_file_info.dev_base = 0; + } + + ret = of_property_read_u32(dev->of_node, "per_len", &sysfs_info->info.dev_file_info.per_len); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("dts don't config per_len, per_len is 0.\n"); + sysfs_info->info.dev_file_info.per_len = 0; + } + sysfs_info->info.dev_file_info.test_base = test_base; + sysfs_info->info.dev_file_info.test_size = test_size; + } else if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_MTD) == 0) { + ret = of_property_read_string(dev->of_node, "mtd_name", (const char **)&name); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config mtd_name error, ret:%d.\n", ret); + return -ENXIO; + } + strncpy(sysfs_info->info.mtd_info.mtd_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + ret = of_property_read_u32(dev->of_node, "flash_base", &sysfs_info->info.mtd_info.flash_base); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config flash_base error, ret:%d.\n", ret); + return -ENXIO; + } + sysfs_info->info.mtd_info.test_base = test_base; + sysfs_info->info.mtd_info.test_size = test_size; + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("dts config sysfs type[%s] is not support, ret:%d.\n", sysfs_info->type, ret); + return -ENXIO; + } + + sysfs_info->gpio_en_info_num = 0; + /* Enable through GPIO */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_gpio_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &sysfs_info->gpio_en_info[i].en_gpio); + if(ret != 0) { + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_level_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &sysfs_info->gpio_en_info[i].en_level); + if(ret != 0) { + break; + } + sysfs_info->gpio_en_info_num++; + } + + sysfs_info->logic_dev_en_num = 0; + /* Enable through register */ + for (i = 0; i < FIRMWARE_EN_INFO_MAX; i++) { + firmware_logic_dev_en_point = &sysfs_info->logic_dev_en_info[i]; + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_dev_%d", i); + ret = 0; + ret += of_property_read_string(dev->of_node, buf, (const char **)&name); + if(ret != 0) { + /* Failure to resolve to EN_LOGIC_DEV means no logical device is enabled. No failure is returned */ + ret = 0; + break; + } + strncpy(firmware_logic_dev_en_point->dev_name, name, FIRMWARE_DEV_NAME_LEN - 1); + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_addr_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->addr); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_addr_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_mask_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->mask); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_mask_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_en_val_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->en_val); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_en_val_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_dis_val_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->dis_val); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_dis_val_%d ret =%d.\n", i, ret); + break; + } + + mem_clear(buf, sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "en_logic_width_%d", i); + ret = of_property_read_u32(dev->of_node, buf, &firmware_logic_dev_en_point->width); + if (ret != 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to config en en_logic_width_%d ret =%d.\n", i, ret); + break; + } + + sysfs_info->logic_dev_en_num++; + } + + return ret; +} + +static int firmware_upgrade_config_init(struct device *dev, firmware_sysfs_t *sysfs_info) +{ + int i; + firmware_logic_dev_en_t *firmware_logic_dev_en_point; + firmware_upgrade_device_t *firmware_upgrade_device; + firmware_sysfs_device_t sysfs_upg_device; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_dev_loc_config_init\r\n"); + if (sysfs_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("info is null\r\n"); + return -1; + } + + if (dev->platform_data == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("platform data config error.\n"); + return -1; + } + firmware_upgrade_device = dev->platform_data; + sysfs_upg_device = firmware_upgrade_device->upg_type.sysfs; + + mem_clear(sysfs_info, sizeof(firmware_sysfs_t)); + strncpy(sysfs_info->type, firmware_upgrade_device->type, sizeof(sysfs_info->type) - 1); + sysfs_info->chain = firmware_upgrade_device->chain; + sysfs_info->chip_index = firmware_upgrade_device->chip_index; + + if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_SPI_LOGIC) == 0) { + strncpy(sysfs_info->info.spi_logic_info.dev_name, sysfs_upg_device.dev_name, FIRMWARE_DEV_NAME_LEN - 1); + sysfs_info->info.spi_logic_info.flash_base = sysfs_upg_device.flash_base; + sysfs_info->info.spi_logic_info.ctrl_base = sysfs_upg_device.ctrl_base; + sysfs_info->info.spi_logic_info.test_base = sysfs_upg_device.test_base; + sysfs_info->info.spi_logic_info.test_size = sysfs_upg_device.test_size; + } else if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_SYSFS) == 0) { + strncpy(sysfs_info->info.dev_file_info.sysfs_name, sysfs_upg_device.sysfs_name, FIRMWARE_DEV_NAME_LEN - 1); + sysfs_info->info.dev_file_info.dev_base = sysfs_upg_device.dev_base; + sysfs_info->info.dev_file_info.per_len = sysfs_upg_device.per_len; + sysfs_info->info.dev_file_info.test_base = sysfs_upg_device.test_base; + sysfs_info->info.dev_file_info.test_size = sysfs_upg_device.test_size; + } else if (strcmp(sysfs_info->type, FIRMWARE_SYSFS_TYPE_MTD) == 0) { + strncpy(sysfs_info->info.mtd_info.mtd_name, sysfs_upg_device.mtd_name, FIRMWARE_DEV_NAME_LEN - 1); + sysfs_info->info.mtd_info.flash_base = sysfs_upg_device.flash_base; + sysfs_info->info.mtd_info.test_base = sysfs_upg_device.test_base; + sysfs_info->info.mtd_info.test_size = sysfs_upg_device.test_size; + } else { + FIRMWARE_DRIVER_DEBUG_ERROR("config sysfs type[%s] is not support.\n", sysfs_info->type); + return -ENXIO; + } + + if (firmware_upgrade_device->en_gpio_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_gpio_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_gpio_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + sysfs_info->gpio_en_info_num = firmware_upgrade_device->en_gpio_num; + /* Enable through GPIO */ + for (i = 0; i < sysfs_info->gpio_en_info_num; i++) { + sysfs_info->gpio_en_info[i].en_gpio = firmware_upgrade_device->en_gpio[i]; + sysfs_info->gpio_en_info[i].en_level = firmware_upgrade_device->en_level[i]; + } + + if (firmware_upgrade_device->en_logic_num > FIRMWARE_EN_INFO_MAX) { + FIRMWARE_DRIVER_DEBUG_ERROR("The number of en_logic_num:%u configurations exceeds the maximum limit:%u.\n", + firmware_upgrade_device->en_logic_num, FIRMWARE_EN_INFO_MAX); + return -ENXIO; + } + sysfs_info->logic_dev_en_num = firmware_upgrade_device->en_logic_num; + /* Enable through register */ + for (i = 0; i < sysfs_info->logic_dev_en_num; i++) { + firmware_logic_dev_en_point = &sysfs_info->logic_dev_en_info[i]; + strncpy(firmware_logic_dev_en_point->dev_name, firmware_upgrade_device->en_logic_dev[i], FIRMWARE_DEV_NAME_LEN - 1); + firmware_logic_dev_en_point->addr = firmware_upgrade_device->en_logic_addr[i]; + firmware_logic_dev_en_point->mask = firmware_upgrade_device->en_logic_mask[i]; + firmware_logic_dev_en_point->en_val = firmware_upgrade_device->en_logic_en_val[i]; + firmware_logic_dev_en_point->dis_val = firmware_upgrade_device->en_logic_dis_val[i]; + firmware_logic_dev_en_point->width = firmware_upgrade_device->en_logic_width[i]; + } + + return 0; +} + +static int firmware_sysfs_probe(struct platform_device *pdev) +{ + int ret; + firmware_sysfs_t *sysfs_info; + firmware_device_t *frm_dev; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Enter firmware_sysfs_probe\r\n"); + sysfs_info = devm_kzalloc(&pdev->dev, sizeof(firmware_sysfs_t), GFP_KERNEL); + if (sysfs_info == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc device tree.\n"); + return -EPERM; + } + + if (pdev->dev.of_node) { + ret = of_firmware_upgrade_config_init(&pdev->dev, sysfs_info); + } else { + ret = firmware_upgrade_config_init(&pdev->dev, sysfs_info); + } + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("get config init from dts error.\n"); + return -EPERM; + } + + frm_dev = devm_kzalloc(&pdev->dev, sizeof(firmware_device_t), GFP_KERNEL); + if (frm_dev == NULL) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to kzalloc firmware device.\n"); + return -EPERM; + } + + /* Based on the link number, determine the name of the device file */ + frm_dev->chain = sysfs_info->chain; + snprintf(frm_dev->name, FIRMWARE_NAME_LEN - 1, "firmware_sysfs%d", frm_dev->chain); + strncpy(sysfs_info->devname, frm_dev->name, strlen(frm_dev->name) + 1); + + INIT_LIST_HEAD(&frm_dev->list); + frm_dev->dev.minor = MISC_DYNAMIC_MINOR; + frm_dev->dev.name = frm_dev->name; + frm_dev->dev.fops = &sysfs_dev_fops; + frm_dev->priv = sysfs_info; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("Register sysfs firmware chain:%d, name:%s.\n", frm_dev->chain, frm_dev->name); + + ret = firmware_device_register(frm_dev); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Failed to register firmware device.\n"); + return -EPERM; + } + + platform_set_drvdata(pdev, frm_dev); + return 0; +} + +static int __exit firmware_sysfs_remove(struct platform_device *pdev) +{ + firmware_device_t *frm_dev; + + frm_dev = (firmware_device_t *)platform_get_drvdata(pdev); + firmware_device_unregister(frm_dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct of_device_id sysfs_match[] = { + { + .compatible = "firmware_sysfs", + }, + {}, +}; + +static struct platform_driver sysfs_driver = { + .driver = { + .name = "firmware_sysfs", + .owner = THIS_MODULE, + .of_match_table = sysfs_match, + }, + .probe = firmware_sysfs_probe, + .remove = firmware_sysfs_remove, +}; + +static firmware_driver_t fmw_drv_sysfs = { + .name = "firmware_sysfs", + .drv = &sysfs_driver, +}; + +int firmware_sysfs_init(void) +{ + int ret; + + INIT_LIST_HEAD(&fmw_drv_sysfs.list); + FIRMWARE_DRIVER_DEBUG_VERBOSE("sysfs upgrade driver register \n"); + ret = firmware_driver_register(&fmw_drv_sysfs); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("sysfs upgrade driver register failed\n"); + return ret; + } + return 0; +} + +void firmware_sysfs_exit(void) +{ + firmware_driver_unregister(&fmw_drv_sysfs); + INIT_LIST_HEAD(&fmw_drv_sysfs.list); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs_upgrade.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs_upgrade.c new file mode 100644 index 000000000000..8b883006de53 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/firmware_sysfs_upgrade.c @@ -0,0 +1,258 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int firmware_file_read(const char *path, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + FIRMWARE_DRIVER_DEBUG_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + pos = (loff_t)addr; + ret = kernel_read(filp, val, size, &pos); + if (ret != size) { + FIRMWARE_DRIVER_DEBUG_ERROR("read kernel_read failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, addr, size, ret); + goto exit; + } + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int firmware_file_write(const char *path, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + FIRMWARE_DRIVER_DEBUG_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + pos = (loff_t)addr; + ret = kernel_write(filp, (void*)val, size, &pos); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("write kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, addr, size, ret); + goto exit; + } + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +/* + * firmware_file_do_work + * function: Sets logical register values + * @path:param[in] Logic device descriptor + * @addr:param[in] Logic device address + * @value:param[in] the register value needs to be set + * @mask:param[in] register mask + * @width:param[in] register bit width + * return: 0:success, <0:failed + */ +static int firmware_file_do_work(char *path, uint32_t addr, uint32_t value, uint32_t mask, + int32_t width) +{ + int ret; + uint8_t read_value[4], write_value[4]; + uint8_t tmp_read8, tmp_write8, tmp_mask8; + uint32_t tmp_read32, tmp_write32; + + FIRMWARE_DRIVER_DEBUG_VERBOSE("path=%s, addr=0x%x, value=0x%x mask=0x%x\r\n", path, addr, value, mask); + if ((width > 4) || (width < 0)) { + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + } + ret = 0; + mem_clear(read_value, sizeof(read_value)); + mem_clear(write_value, sizeof(write_value)); + ret = firmware_file_read(path, addr, read_value, width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware sysfs read.\r\n"); + return -1; + } + + switch (width) { + case 1: + tmp_read8 = read_value[0]; + tmp_mask8 = (uint8_t)(mask) & 0xFF; + tmp_write8 = (uint8_t)value & 0xFF; + write_value[0] = (tmp_read8 & tmp_mask8) | tmp_write8; + FIRMWARE_DRIVER_DEBUG_VERBOSE("1 byte write val[0]:0x%x", write_value[0]); + break; + case 2: + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + case 4: + memcpy((uint8_t *)&tmp_read32, read_value, 4); + tmp_write32 = (tmp_read32 & mask) | value; + memcpy(write_value, (uint8_t *)&tmp_write32, 4); + FIRMWARE_DRIVER_DEBUG_VERBOSE("4 byte write val[0]:0x%x, val[1]:0x%x, val[2]:0x%x, val[3]:0x%x", + write_value[0], write_value[1], write_value[2], write_value[3]); + break; + default: + FIRMWARE_DRIVER_DEBUG_ERROR("width %d is not support.\r\n", width); + return -1; + } + + FIRMWARE_DRIVER_DEBUG_VERBOSE("write logic dev[%s] addr[0x%x].\r\n", path, addr); + ret = firmware_file_write(path, addr, write_value, width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("firmware_file_write %s addr 0x%x failed, ret=%d.\r\n", path, addr, ret); + return -1; + } + + return 0; +} + +/* + * firmware_upgrade_en + * function:param[in] Upgrade access enabling switch + * @flag:param[in] !0:enable 0:disable + * return: 0:success, <0:failed + */ +static int firmware_upgrade_en(firmware_sysfs_t *sysfs_info, int flag) +{ + int i; + firmware_logic_dev_en_t *firmware_logic_dev_en_info; + int ret, rv; + char *dev_name; + + ret = 0; + FIRMWARE_DRIVER_DEBUG_VERBOSE("%s en switch: gpio en num %d, logic reg en num %d.\n", + flag ? "Open" : "Close", sysfs_info->gpio_en_info_num, sysfs_info->logic_dev_en_num); + for (i = 0; i < sysfs_info->gpio_en_info_num; i++) { + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware sysfs [%d] gpio[%d] en_level[%d]\n", + i, sysfs_info->gpio_en_info[i].en_gpio, sysfs_info->gpio_en_info[i].en_level); + if (flag) { + ret = gpio_request(sysfs_info->gpio_en_info[i].en_gpio, "sysfs_upgrade_gpio_en"); + if (ret) { + FIRMWARE_DRIVER_DEBUG_ERROR("Requesting cpld_ispvme_upgrade EN[%d] GPIO[%d] failed!\n", + i, sysfs_info->gpio_en_info[i].en_gpio); + goto free_gpio; + } + gpio_direction_output(sysfs_info->gpio_en_info[i].en_gpio, sysfs_info->gpio_en_info[i].en_level); + sysfs_info->gpio_en_info[i].flag = 1; + } else { + gpio_set_value(sysfs_info->gpio_en_info[i].en_gpio, !sysfs_info->gpio_en_info[i].en_level); + gpio_free(sysfs_info->gpio_en_info[i].en_gpio); + sysfs_info->gpio_en_info[i].flag = 0; + } + } + + for (i = 0; i < sysfs_info->logic_dev_en_num; i++) { + firmware_logic_dev_en_info = &sysfs_info->logic_dev_en_info[i]; + dev_name = firmware_logic_dev_en_info->dev_name; + FIRMWARE_DRIVER_DEBUG_VERBOSE("firmware sysfs [%d] dev_name[%s] addr[0x%x] mask[0x%x]" + " en_val[0x%x] dis_val[0x%x] width[%d]\n", + i , firmware_logic_dev_en_info->dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->mask, firmware_logic_dev_en_info->en_val, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->width); + if (flag) { + ret = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->en_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Open logic register [%d] EN failed, ret %d.\n", i, ret); + goto free_logic_dev; + } else { + firmware_logic_dev_en_info->flag = 1; + } + } else { + rv = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (rv < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Close logic register [%d] EN failed, ret %d.\n", i, rv); + ret = -1; + } + firmware_logic_dev_en_info->flag = 0; + } + } + + return ret; +free_logic_dev: + for (i = 0; i < sysfs_info->logic_dev_en_num; i++) { + firmware_logic_dev_en_info = &sysfs_info->logic_dev_en_info[i]; + dev_name = firmware_logic_dev_en_info->dev_name; + if (firmware_logic_dev_en_info->flag == 1) { + ret = firmware_file_do_work(dev_name, firmware_logic_dev_en_info->addr, + firmware_logic_dev_en_info->dis_val, firmware_logic_dev_en_info->mask, + firmware_logic_dev_en_info->width); + if (ret < 0) { + FIRMWARE_DRIVER_DEBUG_ERROR("Close logic register [%d] EN failed, ret %d.\n", i, ret); + } + firmware_logic_dev_en_info->flag = 0; + } else { + break; + } + } +free_gpio: + for (i = 0; i < sysfs_info->gpio_en_info_num; i++) { + if (sysfs_info->gpio_en_info[i].flag == 1) { + gpio_set_value(sysfs_info->gpio_en_info[i].en_gpio, !sysfs_info->gpio_en_info[i].en_level); + gpio_free(sysfs_info->gpio_en_info[i].en_gpio); + sysfs_info->gpio_en_info[i].flag = 0; + } else { + break; + } + } + + return -1; +} + +/* + * firmware_init_dev_loc + * function: init logic device, enable upgrade access + * return: 0:success, <0:failed + */ +int firmware_init_dev_loc(firmware_sysfs_t *sysfs_info) +{ + int ret; + + ret = firmware_upgrade_en(sysfs_info, 1); + return ret; +} + +/* + * firmware_finish_dev_loc + * function: finish logic device, disable upgrade access + * return: 0:success, <0:failed + */ +int firmware_finish_dev_loc(firmware_sysfs_t *sysfs_info){ + int ret; + ret = firmware_upgrade_en(sysfs_info, 0); + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs.h new file mode 100644 index 000000000000..9da2303c7c00 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs.h @@ -0,0 +1,88 @@ +#ifndef __FIRMWARE_SYSFS_H__ +#define __FIRMWARE_SYSFS_H__ + +#include +#include + +#include + +/* Debug switch level */ +typedef enum { + FIRWMARE_VERBOSE, + FIRWMARE_WARN, + FIRWMARE_ERROR, + FIRWMARE_END, +} firmware_debug_level_t; + +#define FIRMWARE_DRIVER_DEBUG_VERBOSE(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_VERBOSE)) { \ + printk(KERN_INFO "[FIRMWARW_DRIVER_SYSFS][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_DRIVER_DEBUG_ERROR(fmt, args...) do { \ + if ((g_firmware_driver_debug) & (1U << FIRWMARE_ERROR)) { \ + printk(KERN_ERR "[FIRMWARW_DRIVER_SYSFS][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FIRMWARE_NAME_LEN 48 + +#define FIRMWARE_FAILED (-1) +#define FIRMWARE_SUCCESS 0 + +/* ioctl publi command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_COMMON_TYPE 'C' +#define FIRMWARE_GET_CHIPNAME _IOR(FIRMWARE_COMMON_TYPE, 0, char) /* get the chip name */ +#define FIRMWARE_GET_VERSION _IOR(FIRMWARE_COMMON_TYPE, 2, int) /* get version */ + +/* firmware sysfs driver ioctl command, the same as "firmware_upgrade\include\firmware_app.h" */ +#define FIRMWARE_SYSFS_TYPE 'S' +#define FIRMWARE_SYSFS_INIT _IOR(FIRMWARE_SYSFS_TYPE, 0, char) /* enable upgrade access */ +#define FIRMWARE_SYSFS_FINISH _IOR(FIRMWARE_SYSFS_TYPE, 1, char) /* disable upgrade access */ +#define FIRMWARE_SYSFS_SPI_INFO _IOR(FIRMWARE_SYSFS_TYPE, 2, char) /* spi flash upgrade */ +#define FIRMWARE_SYSFS_DEV_FILE_INFO _IOR(FIRMWARE_SYSFS_TYPE, 3, char) /* sysfs upgrade */ +#define FIRMWARE_SYSFS_MTD_INFO _IOR(FIRMWARE_SYSFS_TYPE, 4, char) /* sysfs mtd upgrade */ + +#define FIRMWARE_SYSFS_TYPE_SPI_LOGIC "SPI_LOGIC" +#define FIRMWARE_SYSFS_TYPE_SYSFS "SYSFS" +#define FIRMWARE_SYSFS_TYPE_MTD "MTD_DEV" + +typedef struct cmd_info_s { + uint32_t size; + void __user *data; +} cmd_info_t; + +typedef struct firmware_device_s { + struct list_head list; /* device list */ + uint32_t chain; /* chain number */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct miscdevice dev; /* device */ + void *priv; /* private data */ +} firmware_device_t; + +typedef struct firmware_driver_s { + struct list_head list; /* list */ + char name[FIRMWARE_NAME_LEN]; /* name */ + struct platform_driver *drv; /* driver */ + void *priv; /* private data */ +} firmware_driver_t; + +extern int g_firmware_driver_debug; + +/* Get device information based on minor */ +extern firmware_device_t *firmware_get_device_by_minor(int minor); +/* Registere device */ +extern int firmware_device_register(firmware_device_t *fw_dev); +/* Unregister device */ +extern void firmware_device_unregister(firmware_device_t *fw_dev); +/* Registere driver */ +extern int firmware_driver_register(firmware_driver_t *fw_drv); +/* Unregister driver */ +extern void firmware_driver_unregister(firmware_driver_t *fw_drv); +/* SYSFS upgrade initialized */ +extern int firmware_sysfs_init(void); +/* SYSFS unload function */ +extern void firmware_sysfs_exit(void); + +#endif /* end of __FIRMWARE_SYSFS_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs_upgrade.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs_upgrade.h new file mode 100644 index 000000000000..9c6b970274b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/firmware_driver_sysfs/include/firmware_sysfs_upgrade.h @@ -0,0 +1,72 @@ +#ifndef __FIRMWARE_SYSFS_UPGRADE_H__ +#define __FIRMWARE_SYSFS_UPGRADE_H__ + +#define FIRMWARE_DEV_NAME_LEN 64 /* the macro definition needs to same as app space define */ +#define FIRMWARE_TYPE_LEN 10 +#define FIRMWARE_EN_INFO_MAX 16 + +typedef struct firmware_spi_logic_info_s { + char dev_name[FIRMWARE_DEV_NAME_LEN]; /* Logical device name */ + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t ctrl_base; /* SPI upgrade control register base address */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_spi_logic_info_t; + +typedef struct firmware_dev_file_info_s { + char sysfs_name[FIRMWARE_DEV_NAME_LEN]; /* sysfs name */ + uint32_t dev_base; /* device upgrade base address */ + uint32_t per_len; /* The length of bytes per operation */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_dev_file_info_t; + +typedef struct firmware_mtd_info_s { + char mtd_name[FIRMWARE_DEV_NAME_LEN]; /* sysfs name */ + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_mtd_info_t; + +typedef struct firmware_gpio_jtag_en_s { + uint32_t en_gpio; /* GPIO enable pin */ + uint32_t en_level; /* GPIO enable level */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_gpio_jtag_en_t; + +typedef struct firmware_logic_dev_en_s { + char dev_name[FIRMWARE_DEV_NAME_LEN]; /* Logical device name */ + uint32_t addr; /* Enable register address */ + uint32_t mask; /* mask */ + uint32_t en_val; /* Enable value */ + uint32_t dis_val; /* Disable value*/ + uint32_t width; /* width */ + int flag; /* init flag; 1-init 0-not init */ +} firmware_logic_dev_en_t; + +typedef struct firmware_sysfs_s { + char devname[FIRMWARE_DEV_NAME_LEN]; /* Device name */ + char type[FIRMWARE_TYPE_LEN]; /* interface type */ + uint32_t chain; /* chain num */ + uint32_t chip_index; /* chip index */ + union { + firmware_spi_logic_info_t spi_logic_info; /* SPI logic Information */ + firmware_dev_file_info_t dev_file_info; /* device file Information */ + firmware_mtd_info_t mtd_info; /* mtd device Information */ + } info; + uint32_t gpio_en_info_num; /* GPIO Enable Number */ + firmware_gpio_jtag_en_t gpio_en_info[FIRMWARE_EN_INFO_MAX]; /* GPIO Enable Information */ + uint32_t logic_dev_en_num; /* Register Enable Number */ + firmware_logic_dev_en_t logic_dev_en_info[FIRMWARE_EN_INFO_MAX]; /* Register Enable Information */ +} firmware_sysfs_t; + +typedef struct firmware_sysfs_function_s{ + int (*init_dev)(void); /* upgrade initializes the operation */ + int (*finish_dev)(void); /* upgrade completes the operation */ +}firmware_sysfs_function_t; + +extern void firmware_set_sysfs_info(firmware_sysfs_t *sysfs_info); +extern int firmware_init_dev_loc(firmware_sysfs_t *sysfs_info); +extern int firmware_finish_dev_loc(firmware_sysfs_t *sysfs_info); + +#endif /* __FIRMWARE_SYSFS_UPGRADE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/include/firmware_upgrade.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/include/firmware_upgrade.h new file mode 100644 index 000000000000..600c69646b1b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_driver/include/firmware_upgrade.h @@ -0,0 +1,57 @@ +#ifndef __FIRMWARE_UPGRADE_H__ +#define __FIRMWARE_UPGRADE_H__ + +#include + +#define TYPE_LEN (10) +#define DEV_NAME_LEN (64) +#define ENABLE_NUM (16) + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef struct firmware_jtag_device_s { + uint32_t tdi; + uint32_t tck; + uint32_t tms; + uint32_t tdo; + uint32_t tck_delay; +} firmware_jtag_device_t; + +typedef struct firmware_sysfs_device_s { + uint32_t test_base; + uint32_t test_size; + char dev_name[DEV_NAME_LEN]; + uint32_t flash_base; + uint32_t ctrl_base; + char sysfs_name[DEV_NAME_LEN]; + uint32_t dev_base; + uint32_t per_len; + char mtd_name[DEV_NAME_LEN]; +} firmware_sysfs_device_t; + +typedef struct firmware_upgrade_device_s { + char type[TYPE_LEN]; + uint32_t chain; + uint32_t chip_index; + + uint32_t en_gpio_num; /* the number of en_gpio */ + uint32_t en_gpio[ENABLE_NUM]; + uint32_t en_level[ENABLE_NUM]; + + uint32_t en_logic_num; /* the number of en_logic */ + char en_logic_dev[ENABLE_NUM][DEV_NAME_LEN]; + uint32_t en_logic_addr[ENABLE_NUM]; + uint32_t en_logic_mask[ENABLE_NUM]; + uint32_t en_logic_en_val[ENABLE_NUM]; + uint32_t en_logic_dis_val[ENABLE_NUM]; + uint32_t en_logic_width[ENABLE_NUM]; + + int device_flag; + union { + firmware_jtag_device_t jtag; + firmware_sysfs_device_t sysfs; + } upg_type; + +} firmware_upgrade_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/Makefile new file mode 100644 index 000000000000..176d44d2abd9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/Makefile @@ -0,0 +1,33 @@ +include $(top_srcdir)/Rules.mk + +#OBJ = firmware_app.o debug.o hardware.o ispvm_ui.o ivm_core.o crc32.o +PWD = $(shell pwd) +SRC := +SRC += $(shell find $(PWD) -name '*.c') + +OBJ := $(SRC:%.c=%.o) +LIB += $(BUILD_CFALGS) $(BUILD_LDFLAGS) -lpthread -lreadline -lncurses +INCLUDE = -Iinclude +INCLUDE+= -Wall +APP = firmware_upgrade +ELF_FILE = $(APP) +MAP_FILE = $(APP).map.sym + +.PHONY: build +build:$(OBJ) + $(CC) $^ -o $(ELF_FILE) $(LINKFLAGS) $(LIB) + $(NM) $(ELF_FILE) | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' \ + | sort > $(MAP_FILE) + cp -p $(ELF_FILE) $(common_out_put_dir) + +%.o:%.c + $(CC) -c $(CFLAGS) $(INCLUDE) $< -o $@ + +.PHONY: install +install: + echo "firmware_upgrade install success." + cp -p $(ELF_FILE) $(common_out_put_dir) + +.PHONY: clean +clean: + rm -rf $(BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/crc32.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/crc32.c new file mode 100644 index 000000000000..5b60b40ad1ba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/crc32.c @@ -0,0 +1,216 @@ +/* + * This file is derived from crc32.c from the zlib-1.1.3 distribution + * by Jean-loup Gailly and Mark Adler. + */ + +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ +/* xxxx: by chihl for compile error */ +#if 1 + +#ifndef FAR +#define FAR +#endif + +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef Byte FAR Bytef; +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifndef OF /* function prototypes */ +#ifdef STDC +#define OF(args) args +#else +#define OF(args) () +#endif +#endif + +#endif + +#define local static +#define ZEXPORT /* empty */ +unsigned long crc32 (unsigned long, const unsigned char *, unsigned int); + +#define DYNAMIC_CRC_TABLE + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local uLongf crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +local void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local const uLongf crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +#endif + +#if 0 +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const uLongf * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (const uLongf *)crc_table; +} +#endif + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len) +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} + +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) + +/* No ones complement version. JFFS2 (and other things ?) + * don't use ones compliment in their CRC calculations. + */ +uLong ZEXPORT crc32_no_comp(uLong crc, const Bytef *buf, uInt len) +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + + return crc; +} + +#endif /* CFG_CMD_JFFS2 */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/debug.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/debug.c new file mode 100644 index 000000000000..dc1b1ccfc70a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/debug.c @@ -0,0 +1,60 @@ +/* + * debug.c + * firmware upgrade debug switch control + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int is_debug_on = DEBUG_IGNORE; + +/* + * firmware_upgrade_debug + * function: Debug switch + * Parses the file "/var/tmp/.firmware_upgrade_debug" and returns the corresponding debug level + * return:off--DEBUG_OFF, app debug on---DEBUG_APP_ON, kernel debug on--DEBUG_KERN_ON, + * all debug on--DEBUG_ALL_ON, other--DEBUG_IGNORE + */ +int firmware_upgrade_debug(void) +{ + int size; + FILE *fp; + char debug_info[DEBUG_INFO_LEN]; + + fp = fopen(DEBUG_FILE, "r"); + if (fp == NULL) { + return DEBUG_IGNORE; + } + + mem_clear(debug_info, DEBUG_INFO_LEN); + size = fread(debug_info, DEBUG_INFO_LEN - 1, 1, fp); + if (size < 0) { + fclose(fp); + return DEBUG_IGNORE; + } + + if (strncmp(debug_info, DEBUG_ON_INFO, 1) == 0) { + fclose(fp); + return DEBUG_APP_ON; + } + + if (strncmp(debug_info, DEBUG_ON_ALL, 1) == 0) { + fclose(fp); + return DEBUG_ALL_ON; + } + + if (strncmp(debug_info, DEBUG_OFF_INFO, 1) == 0) { + fclose(fp); + return DEBUG_OFF; + } + + fclose(fp); + return DEBUG_IGNORE; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/firmware_app.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/firmware_app.c new file mode 100644 index 000000000000..ecdc37ef350f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/firmware_app.c @@ -0,0 +1,985 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int header_offset; + +static firmware_file_name_t firmware_file_str[] = { + {"VME", FIRMWARE_VME}, + {"ISC", FIRMWARE_ISC}, + {"JBI", FIRMWARE_JBI}, + {"SPI-LOGIC-DEV", FIRMWARE_SPI_LOGIC_DEV}, + {"SYSFS", FIRMWARE_SYSFS_DEV}, + {"MTD", FIRMWARE_MTD}, +}; + +/** + * firmware_error_type + * function:set error code + * @action: param[in] The stage where the error occurs + * @info: param[in] Upgrade file information + * return value: error code + */ +int firmware_error_type(int action, name_info_t *info) +{ + if (info == NULL) { + return ERR_FW_UPGRADE; + } + + if((info->type <= FIRMWARE_UNDEF_TYPE) || (info->type > FIRMWARE_OTHER)) { + return ERR_FW_UPGRADE; + } + + if (info->type == FIRMWARE_CPLD) { + switch (action) { + case FIRMWARE_ACTION_CHECK: + return ERR_FW_CHECK_CPLD_UPGRADE; + case FIRMWARE_ACTION_MATCH: + return ERR_FW_MATCH_CPLD_UPGRADE; + case FIRMWARE_ACTION_VERCHECK: + return ERR_FW_SAMEVER_CPLD_UPGRADE; + case FIRMWARE_ACTION_UPGRADE: + return ERR_FW_DO_CPLD_UPGRADE; + case FIRMWARE_ACTION_SUPPORT: + return ERR_FW_DO_UPGRADE_NOT_SUPPORT; + default: + return ERR_FW_UPGRADE; + } + } else if (info->type == FIRMWARE_FPGA) { + switch (action) { + case FIRMWARE_ACTION_CHECK: + return ERR_FW_CHECK_FPGA_UPGRADE; + case FIRMWARE_ACTION_MATCH: + return ERR_FW_MATCH_FPGA_UPGRADE; + case FIRMWARE_ACTION_VERCHECK: + return ERR_FW_SAMEVER_FPGA_UPGRADE; + case FIRMWARE_ACTION_UPGRADE: + return ERR_FW_DO_FPGA_UPGRADE; + case FIRMWARE_ACTION_SUPPORT: + return ERR_FW_DO_UPGRADE_NOT_SUPPORT; + default: + return ERR_FW_UPGRADE; + } + } else { + switch (action) { + case FIRMWARE_ACTION_CHECK: + return ERR_FW_CHECK_UPGRADE; + case FIRMWARE_ACTION_MATCH: + return ERR_FW_MATCH_UPGRADE; + case FIRMWARE_ACTION_VERCHECK: + return ERR_FW_SAMEVER_UPGRADE; + case FIRMWARE_ACTION_UPGRADE: + return ERR_FW_DO_UPGRADE; + case FIRMWARE_ACTION_SUPPORT: + return ERR_FW_DO_UPGRADE_NOT_SUPPORT; + default: + return ERR_FW_UPGRADE; + } + } + +} + +/* + * firmware_check_file_info + * function:Check the file information to determine that the file is available for use on the device + * @info: param[in] Upgrade file information + * @main_type : param[in] main type + * @sub_type : param[in] sub type + * @slot : param[in] 0--main, sub slot starts at 1 + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_check_file_info(name_info_t *info, int main_type, int sub_type, int slot) +{ + int i; + + dbg_print(is_debug_on, "Check file info.\n"); + /* Check the mainboard type */ + for (i = 0; i < MAX_DEV_NUM; i++) { + if (main_type == info->card_type[i]) { + dbg_print(is_debug_on, "main type is 0x%x \n", main_type); + break; + } + } + if (i == MAX_DEV_NUM) { + dbg_print(is_debug_on, "Error: The main type[0x%x] is not matched \n", main_type); + return firmware_error_type(FIRMWARE_ACTION_MATCH, info); + } + + /* Check the sub board type, if firwmare upgrade sub board, then sub_type must be 0 */ + for (i = 0; i < MAX_DEV_NUM; i++) { + if (sub_type == info->sub_type[i]) { + dbg_print(is_debug_on, "sub type is 0x%x \n", sub_type); + break; + } + } + if (i == MAX_DEV_NUM) { + dbg_print(is_debug_on, "Error: The sub type[0x%x] is not matched \n", sub_type); + return firmware_error_type(FIRMWARE_ACTION_MATCH, info); + } + + /* if firwmare upgrade main board, then sub_type must be 0 and slot must be 0 + * if firwmare upgrade sub board, then sub_type must not be 0 and slot must not be 0 */ + if (((sub_type != 0) && (slot < 1)) || ((sub_type == 0) && (slot != 0))) { + dbg_print(is_debug_on, "Error: The sub type[0x%x] is not match slot %d error.\n", sub_type, slot); + return firmware_error_type(FIRMWARE_ACTION_MATCH, info); + } + + dbg_print(is_debug_on, "Success check file info.\n"); + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_get_dev_file_name + * function:Gets the name of the device file + * @info: param[in] Upgrade file information + * @len: param[in] Device file name length + * @file_name: param[out] Device file name + */ +static int firmware_get_dev_file_name(name_info_t *info, char *file_name, int len) +{ + int ret; + + ret = FIRMWARE_SUCCESS; + switch(info->file_type) { + case FIRMWARE_VME: + snprintf(file_name, len, "/dev/firmware_cpld_ispvme%d", info->chain); + break; + case FIRMWARE_ISC: + case FIRMWARE_JBI: + snprintf(file_name, len, "/dev/firmware_cpld%d", info->chain); + break; + case FIRMWARE_SPI_LOGIC_DEV: + case FIRMWARE_SYSFS_DEV: + case FIRMWARE_MTD: + snprintf(file_name, len, "/dev/firmware_sysfs%d", info->chain); + break; + default: + ret = FIRMWARE_FAILED; + break; + } + + return ret; + } + +/** + * firmware_check_chip_verison + * function: Check chip version + * @fd: param[in] Device file descriptor + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +int firmware_check_chip_verison(int fd, name_info_t *info) +{ + int ret; + cmd_info_t cmd_info; + char version[FIRMWARE_NAME_LEN + 1]; + + dbg_print(is_debug_on, "Check chip version.\n"); + mem_clear(version, FIRMWARE_NAME_LEN); + cmd_info.size = FIRMWARE_NAME_LEN; + cmd_info.data = (void *) version; + + /* Ignore version checking */ + if (strncmp("v", info->version, 1) == 0) { + dbg_print(is_debug_on, "Skip check chip version.\n"); + return FIRMWARE_SUCCESS; + } + + /* Get the program version from the device file */ + ret = ioctl(fd, FIRMWARE_GET_VERSION, &cmd_info); + if (ret < 0) { + dbg_print(is_debug_on, "Error: Failed to get version(chain %d, version %s).\n", + info->chain, info->version); + return firmware_error_type(FIRMWARE_ACTION_CHECK, NULL); + } + dbg_print(is_debug_on, "Chip verion: %s, file chip verion: %s.\n", version, info->version); + + /* The device version is the same and does not upgrade */ + if (strcmp(version, info->version) == 0) { + dbg_print(is_debug_on, "the file program version is same as the firmware version %s \n", + info->version); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + dbg_print(is_debug_on, "Check version pass.\n"); + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_get_file_size + * function: Gets the upgrade file size + * @file_name: param[in] Upgrade file name + * @size: param[out] Upgrade file size + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int firmware_get_file_size(char *file_name, uint32_t *size) +{ + int ret; + struct stat buf; + + ret = stat(file_name, &buf); + if (ret < 0) { + return FIRMWARE_FAILED; + } + + if (buf.st_size < 0 || buf.st_size - header_offset < 0) { + return FIRMWARE_FAILED; + } + /* Remove the upgrade file header information to actually upgrade the content size */ + *size = buf.st_size - header_offset; + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_get_file_info + * function: Gets the contents of the upgrade file + * @file_name: param[in] Upgrade file name + * @size: param[in] Upgrade file size + * @buf: param[out] Upgrade the file content + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int firmware_get_file_info(char *file_name, uint8_t *buf, uint32_t size) +{ + FILE *fp; + int len; + int ret; + + fp = fopen(file_name, "r"); + if (fp == NULL) { + return FIRMWARE_FAILED; + } + /* Removes the contents of the upgrade file header information */ + ret = fseek(fp, header_offset, SEEK_SET); + if (ret < 0) { + fclose(fp); + return FIRMWARE_FAILED; + } + + len = fread(buf, size, 1, fp); + if (len < 0) { + fclose(fp); + return FIRMWARE_FAILED; + } + fclose(fp); + + return FIRMWARE_SUCCESS; +} + +/* +* firmware_upgrade +* function: firmware upgrade +* @file_name: param[in] Upgrade file name +* @info: param[in] Upgrade file information +* return value : success--FIRMWARE_SUCCESS, other fail return error code +*/ +static int firmware_upgrade(char *file_name, name_info_t *info) +{ + int ret; + int fd; + uint32_t upg_size; + uint8_t *upg_buf; + char dev_file_name[FIRMWARE_NAME_LEN]; + unsigned long crc; + + dbg_print(is_debug_on, "Upgrade firmware: %s.\n", file_name); + mem_clear(dev_file_name, FIRMWARE_NAME_LEN); + ret = firmware_get_dev_file_name(info, dev_file_name, FIRMWARE_NAME_LEN - 1); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to get dev file name.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + fd = open(dev_file_name, O_RDWR); + if (fd < 0) { + dbg_print(is_debug_on, "Error: Failed to open %s.\n", dev_file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + +#if 0 + /* check chip name */ + ret = firmware_check_chip_name(fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip name: %s.\n", dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } +#endif + + /* Check chip version */ + ret = firmware_check_chip_verison(fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip version: %s.\n", dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* Gets the upgrade file size */ + ret = firmware_get_file_size(file_name, &upg_size); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to get file size: %s.\n", file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + if (upg_size == 0) { + dbg_print(is_debug_on, "Error: The upgrade file is empty \n"); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + upg_buf = (uint8_t *) malloc(upg_size + 1); + if (upg_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for upgrade file info: %s.\n", + dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* Gets the contents of the upgrade file */ + mem_clear(upg_buf, upg_size + 1); + ret = firmware_get_file_info(file_name, upg_buf, upg_size); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to read file info: %s.\n", file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* file crc32 check */ + crc = crc32(0, (const unsigned char *)upg_buf, (unsigned int)upg_size); + if (crc != info->crc32) { + dbg_print(is_debug_on, "Error: Failed to check file crc: %s.\n", file_name); + dbg_print(is_debug_on, "the crc value is : %#08x.\n", (unsigned int)crc); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + dbg_print(is_debug_on, "Start upgrading firmware, wait...\n"); + + /* Start firmware upgrade */ + switch (info->file_type) { + case FIRMWARE_VME: + dbg_print(is_debug_on, "start to ispvme upgrade: %s.\n", file_name); + ret = firmware_upgrade_ispvme(fd, file_name, info); + break; + case FIRMWARE_ISC: + case FIRMWARE_JBI: + dbg_print(is_debug_on, "start to upgrade: %s.\n", file_name); + ret = firmware_upgrade_jtag(fd, upg_buf, upg_size, info); + break; + case FIRMWARE_SPI_LOGIC_DEV: + dbg_print(is_debug_on, "start to spi logic dev upgrade: %s.\n", file_name); + ret = firmware_upgrade_spi_logic_dev(fd, upg_buf, upg_size, info); + break; + case FIRMWARE_SYSFS_DEV: + dbg_print(is_debug_on, "start to sysfs upgrade: %s.\n", file_name); + ret = firmware_upgrade_sysfs(fd, upg_buf, upg_size, info); + break; + case FIRMWARE_MTD: + dbg_print(is_debug_on, "start to mtd device upgrade: %s.\n", file_name); + ret = firmware_upgrade_mtd(fd, upg_buf, upg_size, info); + break; + default: + dbg_print(is_debug_on, "Error: file type is not support: %s.\n", file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_UPGRADE, info); + } + + dbg_print(is_debug_on, "Completed.\n"); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to upgrade: %s.\n", dev_file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_UPGRADE, info); + } + + free(upg_buf); + close(fd); + + return FIRMWARE_SUCCESS; +} + +/* +* firmware_upgrade_test +* function: firmware upgrade test +* @file_name: param[in] Upgrade file name +* @info: param[in] Upgrade file information +* return value : success--FIRMWARE_SUCCESS, other fail return error code +*/ +static int firmware_upgrade_test(char *file_name, name_info_t *info) +{ + int ret; + int fd; + uint32_t upg_size; + uint8_t *upg_buf; + char dev_file_name[FIRMWARE_NAME_LEN]; + unsigned long crc; + + dbg_print(is_debug_on, "Upgrade firmware test: %s.\n", file_name); + mem_clear(dev_file_name, FIRMWARE_NAME_LEN); + ret = firmware_get_dev_file_name(info, dev_file_name, FIRMWARE_NAME_LEN - 1); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to get dev file name.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + fd = open(dev_file_name, O_RDWR); + if (fd < 0) { + dbg_print(is_debug_on, "Error: Failed to open %s.\n", dev_file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + +#if 0 + /* check chip name */ + ret = firmware_check_chip_name(fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip name: %s.\n", dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } +#endif + + /* Check chip version */ + ret = firmware_check_chip_verison(fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip version: %s.\n", dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* Gets the upgrade file size */ + ret = firmware_get_file_size(file_name, &upg_size); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to get file size: %s.\n", file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + upg_buf = (uint8_t *) malloc(upg_size + 1); + if (upg_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for upgrade file info: %s.\n", + dev_file_name); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* Gets the contents of the upgrade file */ + mem_clear(upg_buf, upg_size + 1); + ret = firmware_get_file_info(file_name, upg_buf, upg_size); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to read file info: %s.\n", file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + /* file crc32 check */ + crc = crc32(0, (const unsigned char *)upg_buf, (unsigned int)upg_size); + if (crc != info->crc32) { + dbg_print(is_debug_on, "Error: Failed to check file crc: %s.\n", file_name); + dbg_print(is_debug_on, "the crc value is : %#08x.\n", (unsigned int)crc); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + dbg_print(is_debug_on, "Start upgrading firmware test, wait...\n"); + + /* Start firmware upgrade */ + switch (info->file_type) { + case FIRMWARE_VME: + dbg_print(is_debug_on, "start to ispvme upgrade test: %s.\n", file_name); + /* WME upgrade link testing is the same as upgrading, using vme test file. */ + ret = firmware_upgrade_ispvme(fd, file_name, info); + break; + case FIRMWARE_ISC: + case FIRMWARE_JBI: + dbg_print(is_debug_on, "start to upgrade test: %s.\n", file_name); + ret = firmware_upgrade_jtag_test(fd, upg_buf, upg_size, info); + break; + case FIRMWARE_SPI_LOGIC_DEV: + dbg_print(is_debug_on, "start to spi logic dev upgrade test: %s.\n", file_name); + ret = firmware_upgrade_spi_logic_dev_test(fd,info); + break; + case FIRMWARE_SYSFS_DEV: + dbg_print(is_debug_on, "start to sysfs upgrade test: %s.\n", file_name); + ret = firmware_upgrade_sysfs_test(fd, info); + break; + case FIRMWARE_MTD: + dbg_print(is_debug_on, "start to mtd device upgrade test: %s.\n", file_name); + ret = firmware_upgrade_mtd_test(fd, info); + break; + default: + dbg_print(is_debug_on, "Error: test file type is not support: %s.\n", file_name); + free(upg_buf); + close(fd); + return firmware_error_type(FIRMWARE_ACTION_UPGRADE, info); + } + + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to upgrade test: %s ret=%d.\n", dev_file_name, ret); + free(upg_buf); + close(fd); + if (ret == FIRMWARE_NOT_SUPPORT) { + return firmware_error_type(FIRMWARE_ACTION_SUPPORT, info); + } else { + return firmware_error_type(FIRMWARE_ACTION_UPGRADE, info); + } + } + + free(upg_buf); + close(fd); + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_file_type_map + * function:Gets the corresponding upgrade file type from the upgrade file type list + * @value : param[in] file type name + * return value : file type, firmware_file_type_t + */ +static firmware_file_type_t firmware_upgrade_file_type_map(char *type_str) +{ + int type_num; + int i; + + type_num = (sizeof(firmware_file_str) /sizeof(firmware_file_str[0])); + for (i = 0; i < type_num; i++) { + if (!strncmp(firmware_file_str[i].firmware_file_name_str, type_str, + strlen(firmware_file_str[i].firmware_file_name_str))) { + return firmware_file_str[i].firmware_file_type; + } + } + + dbg_print(is_debug_on, "firmware file type unknown\n"); + return FIRMWARE_NONE; +} + +/* + * firmware_upgrade_parse_kv + * function:Parses the header information of the upgrade file based on the key and value + * @key: param[in] key + * @value : param[in] value + * @info : param[out] Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_parse_kv(const char *key, const char *value, name_info_t *info) +{ + int i; + if (key == NULL || value == NULL) { + dbg_print(is_debug_on, "Error: failed to get ther key or value.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } else if (strcmp(key, FILEHEADER_DEVTYPE) == 0) { + /* main board type */ + for (i = 0; i < MAX_DEV_NUM && info->card_type[i]; i++); + if (i == MAX_DEV_NUM) { + dbg_print(is_debug_on, "Error: card type is full for %s. \n", value); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + info->card_type[i] = strtoul(value, NULL, 0); + } else if (strcmp(key, FILEHEADER_SUBTYPE) == 0) { + /* sub board type */ + for (i = 0; i < MAX_DEV_NUM && info->sub_type[i]; i++); + if (i == MAX_DEV_NUM) { + dbg_print(is_debug_on, "Error: sub type is full for %s. \n", value); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + info->sub_type[i] = strtoul(value, NULL, 0); + } else if (strcmp(key, FILEHEADER_TYPE) == 0) { + /* Device type */ + if (strcmp(value, FIRMWARE_CPLD_NAME) == 0) { + info->type = FIRMWARE_CPLD; + } else if (strcmp(value, FIRMWARE_FPGA_NAME) == 0) { + info->type = FIRMWARE_FPGA; + } else { + info->type = FIRMWARE_OTHER; + } + } else if (strcmp(key, FILEHEADER_CHAIN) == 0) { + /* link num */ + info->chain = strtoul(value, NULL, 10); + } else if (strcmp(key, FILEHEADER_CHIPNAME) == 0) { + /* chip name */ + if (strlen(value) >= FIRMWARE_NAME_LEN) { + dbg_print(is_debug_on, "Error: '%s' is too long for a chipname.\n", value); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + mem_clear(info->chip_name, sizeof(info->chip_name)); + snprintf(info->chip_name, sizeof(info->chip_name) - 1, "%s", value); + } else if (strcmp(key, FILEHEADER_VERSION) == 0) { + /* version */ + if (strlen(value) >= FIRMWARE_NAME_LEN) { + dbg_print(is_debug_on, "Error: '%s' is too long for a version.\n", value); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + mem_clear(info->version, sizeof(info->version)); + snprintf(info->version, sizeof(info->version) - 1, "%s", value); + } else if (strcmp(key, FILEHEADER_FILETYPE) == 0) { + /* file type */ + info->file_type = firmware_upgrade_file_type_map((char *)value); + } else if (strcmp(key, FILEHEADER_CRC) == 0) { + /* file crc32 */ + info->crc32 = strtoul(value, NULL, 0); + } else { + dbg_print(is_debug_on, "Warning: key '%s' is unknown. Continue anyway.\n", key); + return FIRMWARE_SUCCESS; + } + dbg_print(is_debug_on, "key %s is matched.\n", key); + return FIRMWARE_SUCCESS; + } + +/* + * firmware_upgrade_parse_check + * function:Check the results of header parsing + * @file_name: Upgrade file name + * @info : Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_parse_check(char *file_name, name_info_t *info) +{ + int i; + if (info->card_type[0] == 0) { + dbg_print(is_debug_on, "Error: %s card type is missing.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if ((info->type <= FIRMWARE_UNDEF_TYPE) || (info->type > FIRMWARE_OTHER)) { + dbg_print(is_debug_on, "Error: %s type is unknown.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if (strlen(info->chip_name) == 0) { + dbg_print(is_debug_on, "Error: %s chip_name is empty.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if (strlen(info->version) == 0) { + dbg_print(is_debug_on, "Error: %s version is empty.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if ((info->file_type <= FIRMWARE_UNDEF_FILE_TYPE) || (info->file_type > FIRMWARE_NONE)) { + dbg_print(is_debug_on, "Error: %s file type is unknown.\n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + dbg_print(is_debug_on, "The file header parse:(%s) \n" , file_name); + dbg_print(is_debug_on, " card type: "); + for (i = 0; i < MAX_DEV_NUM && info->card_type[i]; i++){ + dbg_print(is_debug_on, "0x%x, ", info->card_type[i]); + } + dbg_print(is_debug_on, "\n" + " sub type : "); + for (i = 0; i < MAX_DEV_NUM && info->sub_type[i]; i++){ + dbg_print(is_debug_on, "0x%x, ", info->sub_type[i]); + } + dbg_print(is_debug_on, "\n" + " type : %d, \n" + " chain : %d, \n" + " chip name: %s \n" + " version : %s \n" + " file type: %d \n" + " the crc32 value: %#x \n", + info->type, info->chain, info->chip_name, info->version, info->file_type, info->crc32); + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_read_header + * function:Read the header information of the upgrade file + * @file_name: param[in] Upgrade file name + * @info : param[out] Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_read_header( char *file_name, name_info_t *info) +{ + FILE *fp; + char *charp; + char *charn; + char header_buffer[MAX_HEADER_SIZE]; + char header_key[MAX_HEADER_KV_SIZE]; + char header_var[MAX_HEADER_KV_SIZE]; + int ret; + int len; + + fp = fopen(file_name, "r"); + if (fp == NULL) { + dbg_print(is_debug_on, "Error: Failed to open file: %s. \n", file_name); + perror("fopen"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + mem_clear(header_buffer, sizeof(header_buffer)); + len = fread(header_buffer, MAX_HEADER_SIZE - 1, 1, fp); + fclose(fp); + if (len < 0) { + dbg_print(is_debug_on, "Error: Failed to read header : %s. \n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + header_buffer[MAX_HEADER_SIZE - 1] = 0; + + charp = strstr(header_buffer, "FILEHEADER(\n"); + if (charp == NULL) { + dbg_print(is_debug_on, "Error: The file format %s is wrong. \n", file_name); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + charp += strlen("FILEHEADER(\n"); + + dbg_print(is_debug_on, "File parse start.\n"); + mem_clear(info, sizeof(name_info_t)); + ret = 0; + charn = charp; + mem_clear(header_key, sizeof(header_key)); + while (*charn != ')') { + charn = strpbrk(charp, "=,)\n"); + if (charn == NULL) { + dbg_print(is_debug_on, "Error: The parser can't find mark.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + if (charn - charp >= MAX_HEADER_KV_SIZE) { + dbg_print(is_debug_on, "Error: The parser find a overflow mark.\n"); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + switch (*charn) { + case '=': + mem_clear(header_key, sizeof(header_key)); + memcpy(header_key, charp, charn - charp); + break; + case '\n': + case ',': + mem_clear(header_var, sizeof(header_var)); + memcpy(header_var, charp, charn - charp); + dbg_print(is_debug_on, "Parser: %s = %s .\n", header_key, header_var); + firmware_upgrade_parse_kv(header_key, header_var, info); + break; + case ')': + break; + default: + dbg_print(is_debug_on, "Error: The parser get unexpected mark '%c(0x%02X)'.\n", *charn, *charn); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + charp = (charn + 1); + } + + ret = firmware_upgrade_parse_check(file_name, info); + if (ret != FIRMWARE_SUCCESS) { + return FIRMWARE_FAILED; + } + + header_offset = charp + 1 - header_buffer; /* charp at '\n' */ + dbg_print(is_debug_on,"the header offset is %d \n", header_offset); + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_one_file + * function: upgrade file + * @file_name: Upgrade file name + * @main_type: main board type + * @sub_type: sub board type + * @slot: 0--main, sub slot starts at 1 + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_one_file(char *file_name, int main_type, int sub_type, int slot) +{ + int ret; + name_info_t info; + + if ((slot < 0) || (file_name == NULL)) { + dbg_print(is_debug_on, "Failed firmware_upgrade_one_file parameter err.\n"); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "firmware upgrade %s 0x%x 0x%x %d\n", file_name, main_type, sub_type, slot); + /* Read the header information of the upgrade file */ + ret = firmware_upgrade_read_header(file_name, &info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to get file header: %s\n", file_name); + return ret; + } + + /* Check the file information to determine that the file is available for use on the device */ + ret = firmware_check_file_info(&info, main_type, sub_type, slot); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "File is not match with the device: %s.\n", file_name); + return ret; + } + + /* The link number corresponding to the upgrade file is calculated based on the slot number. + 16 links are reserved for each slot. main boade slot is 0. */ + info.chain += slot * FIRMWARE_SLOT_MAX_NUM; + ret = firmware_upgrade(file_name, &info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to upgrade: %s.\n", file_name); + return ret; + } + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_file_test + * function: upgrade file + * @file_name: Upgrade file name + * @main_type: main board type + * @sub_type: sub board type + * @slot: 0--main, sub slot starts at 1 + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +static int firmware_upgrade_file_test(char *file_name, int main_type, int sub_type, int slot) +{ + int ret; + name_info_t info; + + if ((slot < 0) || (file_name == NULL)) { + dbg_print(is_debug_on, "Failed firmware_upgrade_one_file parameter err.\n"); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "firmware upgrade %s 0x%x 0x%x %d\n", file_name, main_type, sub_type, slot); + /* Read the header information of the upgrade file */ + ret = firmware_upgrade_read_header(file_name, &info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to get file header: %s, ret=%d\n", file_name, ret); + return ret; + } + + /* Check the file information to determine that the file is available for use on the device */ + ret = firmware_check_file_info(&info, main_type, sub_type, slot); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "File is not match with the device: %s, ret=%d.\n", file_name, ret); + return ret; + } + + /* The link number corresponding to the upgrade file is calculated based on the slot number. + 16 links are reserved for each slot. main boade slot is 0. */ + info.chain += slot * FIRMWARE_SLOT_MAX_NUM; + ret = firmware_upgrade_test(file_name, &info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to upgrade: %s, ret=%d\n", file_name, ret); + return ret; + } + + return FIRMWARE_SUCCESS; +} + +static int firmware_upgrade_data_dump(char *argv[]) +{ + int ret; + uint32_t offset, len; + + /* dump by type */ + if (strcmp(argv[2], "spi_logic_dev") == 0) { + /* usag: firmware_upgrade dump spi_logic_dev dev_path offset size print/record_file_path */ + offset = strtoul(argv[4], NULL, 0); + len = strtoul(argv[5], NULL, 0); + /* offset needs align by 256 bytes */ + if ((offset & 0xff) || (len == 0)) { + dbg_print(is_debug_on,"only support offset align by 256 bytes.\n"); + return FIRMWARE_FAILED; + } + dbg_print(is_debug_on, "start to dump %s data. offset:0x%x, len:0x%x\n", argv[2], offset, len); + ret = firmware_upgrade_spi_logic_dev_dump(argv[3], offset, len, argv[6]); + } else { + dbg_print(is_debug_on, "Error: %s not support dump data.\n", argv[2]); + return FIRMWARE_FAILED; + } + + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to dump %s data. ret:%d\n", argv[3], ret); + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +int main(int argc, char *argv[]) +{ + int ret; + int main_type, sub_type, slot; + + is_debug_on = firmware_upgrade_debug(); + + signal(SIGTERM, SIG_IGN); /* ignore kill signal */ + signal(SIGINT, SIG_IGN); /* ignore ctrl+c signal */ + signal(SIGTSTP, SIG_IGN); /* ignore ctrl+z signal */ + + if ((argc != 5) && (argc != 6) && (argc != 7)) { + printf("Use:\n"); + printf(" upgrade file : firmware_upgrade file main_type sub_type slot\n"); + printf(" upgrade test : firmware_upgrade test file main_type sub_type slot\n"); + printf(" spi_logic_dev dump : firmware_upgrade dump spi_logic_dev dev_path offset size print/record_file_path\n"); + dbg_print(is_debug_on, "Failed to upgrade the number of argv: %d.\n", argc); + return ERR_FW_UPGRADE; + } + + if (argc == 5) { + main_type = strtoul(argv[2], NULL, 16); + sub_type = strtoul(argv[3], NULL, 16); + slot = strtoul(argv[4], NULL, 10); + printf("+================================+\n"); + printf("|Begin to upgrade, please wait...|\n"); + ret = firmware_upgrade_one_file(argv[1], main_type, sub_type, slot); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Failed to upgrade a firmware file: %s. (%d)\n", argv[1], ret); + printf("| Upgrade failed! |\n"); + printf("+================================+\n"); + return ret; + } + + printf("| Upgrade succeeded! |\n"); + printf("+================================+\n"); + dbg_print(is_debug_on, "Sucess to upgrade a firmware file: %s.\n", argv[1]); + return FIRMWARE_SUCCESS; + } else if ((argc == 6) && (strcmp(argv[1], "test") == 0)) { + main_type = strtoul(argv[3], NULL, 16); + sub_type = strtoul(argv[4], NULL, 16); + slot = strtoul(argv[5], NULL, 10); + printf("+=====================================+\n"); + printf("|Begin to upgrade test, please wait...|\n"); + ret = firmware_upgrade_file_test(argv[2], main_type, sub_type, slot); + if (ret == FIRMWARE_SUCCESS) { + printf("| Upgrade test succeeded! |\n"); + printf("+=====================================+\n"); + dbg_print(is_debug_on, "Sucess to upgrade test a firmware file: %s.\n", argv[2]); + return FIRMWARE_SUCCESS; + } else if (ret == ERR_FW_DO_UPGRADE_NOT_SUPPORT) { + dbg_print(is_debug_on, "do not support to upgrade test a firmware file: %s. (%d)\n", argv[2], ret); + printf("| Not support to upgrade test! |\n"); + printf("+=====================================+\n"); + return ret; + } else { + dbg_print(is_debug_on, "Failed to upgrade test a firmware file: %s. (%d)\n", argv[2], ret); + printf("| Upgrade test failed! |\n"); + printf("+=====================================+\n"); + return ret; + } + } else if (strcmp(argv[1], "dump") == 0) { + /* print device data */ + ret = firmware_upgrade_data_dump(argv); + if (ret == FIRMWARE_SUCCESS) { + printf("dump data succeeded.\n"); + return FIRMWARE_SUCCESS; + } else { + printf("dump data failed. ret:%d\n", ret); + return ret; + } + } + + printf("+=================+\n"); + printf("| UPGRADE FAIL! |\n"); + printf("+=================+\n"); + + return ERR_FW_UPGRADE; + } diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/hardware.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/hardware.c new file mode 100644 index 000000000000..c43c9095fda6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/hardware.c @@ -0,0 +1,263 @@ +/********************************************************************************* +* Lattice Semiconductor Corp. Copyright 2000-2008 +* +* This is the hardware.c of ispVME V12.1 for JTAG programmable devices. +* All the functions requiring customization are organized into this file for +* the convinience of porting. +*********************************************************************************/ +/********************************************************************************* +* Revision History: +* +* 09/11/07 NN Type cast mismatch variables +* 09/24/07 NN Added calibration function. +* Calibration will help to determine the system clock frequency +* and the count value for one micro-second delay of the target +* specific hardware. +* Modified the ispVMDelay function +* Removed Delay Percent support +* Moved the sclock() function from ivm_core.c to hardware.c +*********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/******************************************************************************** +* Declaration of global variables +* +*********************************************************************************/ + +unsigned char g_siIspPins = 0x00; /*Keeper of JTAG pin state*/ +unsigned short g_usInPort = 0x379; /*Address of the TDO pin*/ +unsigned short g_usOutPort = 0x378; /*Address of TDI, TMS, TCK pin*/ +unsigned short g_usCpu_Frequency = 1000; /*Enter your CPU frequency here, unit in MHz.*/ + +/********************************************************************************* +* This is the definition of the bit locations of each respective +* signal in the global variable g_siIspPins. +* +* NOTE: Users must add their own implementation here to define +* the bit location of the signal to target their hardware. +* The example below is for the Lattice download cable on +* on the parallel port. +* +*********************************************************************************/ + +#if 0 +const unsigned char g_ucPinTDI = JTAG_TDI; /* Bit address of TDI */ +const unsigned char g_ucPinTCK = JTAG_TCK; /* Bit address of TCK */ +const unsigned char g_ucPinTMS = JTAG_TMS; /* Bit address of TMS */ +const unsigned char g_ucPinENABLE = JTAG_ENABLE; /* Bit address of ENABLE */ +const unsigned char g_ucPinTRST = JTAG_TRST; /* Bit address of TRST */ +const unsigned char g_ucPinTDO = JTAG_TDO; /* Bit address of TDO*/ +#endif +int g_file_fd = -1; +/*************************************************************** +* +* Functions declared in hardware.c module. +* +***************************************************************/ +void writePort(unsigned char a_ucPins, unsigned char a_ucValue); +unsigned char readPort(); +void sclock(); +void ispVMDelay(unsigned short a_usTimeDelay); +void calibration(void); + +/******************************************************************************** +* writePort +* To apply the specified value to the pins indicated. This routine will +* be modified for specific systems. +* As an example, this code uses the IBM-PC standard Parallel port, along with the +* schematic shown in Lattice documentation, to apply the signals to the +* JTAG pins. +* +* PC Parallel port pin Signal name Port bit address +* 2 g_ucPinTDI 1 +* 3 g_ucPinTCK 2 +* 4 g_ucPinTMS 4 +* 5 g_ucPinENABLE 8 +* 6 g_ucPinTRST 16 +* 10 g_ucPinTDO 64 +* +* Parameters: +* - a_ucPins, which is actually a set of bit flags (defined above) +* that correspond to the bits of the data port. Each of the I/O port +* bits that drives an isp programming pin is assigned a flag +* (through a #define) corresponding to the signal it drives. To +* change the value of more than one pin at once, the flags are added +* together, much like file access flags are. +* +* The bit flags are only set if the pin is to be changed. Bits that +* do not have their flags set do not have their levels changed. The +* state of the port is always manintained in the static global +* variable g_siIspPins, so that each pin can be addressed individually +* without disturbing the others. +* +* - a_ucValue, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two +* values are valid. Any non-zero number sets the pin(s) high. +* +*********************************************************************************/ + +void writePort(unsigned char a_ucPins, unsigned char a_ucValue) +{ + switch (a_ucPins) { + case JTAG_TCK: + ioctl(g_file_fd, FIRMWARE_JTAG_TCK, &a_ucValue); + break; + case JTAG_TDI: + ioctl(g_file_fd, FIRMWARE_JTAG_TDI, &a_ucValue); + break; + case JTAG_TMS: + ioctl(g_file_fd, FIRMWARE_JTAG_TMS, &a_ucValue); + break; + case JTAG_ENABLE: + ioctl(g_file_fd, FIRMWARE_JTAG_EN, &a_ucValue); + break; + case JTAG_TRST: + //ioctl(g_file_fd, FIRMWARE_JTAG_TRST, &a_ucValue); + break; + default: + break; + } +} + +/********************************************************************************* +* +* readPort +* +* Returns the value of the TDO from the device. +* +**********************************************************************************/ +unsigned char readPort() +{ + unsigned char ucRet = 0; + + ioctl(g_file_fd, FIRMWARE_JTAG_TDO, &ucRet); + return (ucRet); +} + +/********************************************************************************* +* sclock +* +* Apply a pulse to TCK. +* +* This function is located here so that users can modify to slow down TCK if +* it is too fast (> 25MHZ). Users can change the IdleTime assignment from 0 to +* 1, 2... to effectively slowing down TCK by half, quarter... +* +*********************************************************************************/ +void sclock() +{ + unsigned short IdleTime = 0; //change to > 0 if need to slow down TCK + unsigned short usIdleIndex = 0; + IdleTime++; + for (usIdleIndex = 0; usIdleIndex < IdleTime; usIdleIndex++) { + writePort(JTAG_TCK, 0x01); + } + for (usIdleIndex = 0; usIdleIndex < IdleTime; usIdleIndex++) { + writePort(JTAG_TCK, 0x00); + } +} +/******************************************************************************** +* +* ispVMDelay +* +* +* Users must implement a delay to observe a_usTimeDelay, where +* bit 15 of the a_usTimeDelay defines the unit. +* 1 = milliseconds +* 0 = microseconds +* Example: +* a_usTimeDelay = 0x0001 = 1 microsecond delay. +* a_usTimeDelay = 0x8001 = 1 millisecond delay. +* +* This subroutine is called upon to provide a delay from 1 millisecond to a few +* hundreds milliseconds each time. +* It is understood that due to a_usTimeDelay is defined as unsigned short, a 16 bits +* integer, this function is restricted to produce a delay to 64000 micro-seconds +* or 32000 milli-second maximum. The VME file will never pass on to this function +* a delay time > those maximum number. If it needs more than those maximum, the VME +* file will launch the delay function several times to realize a larger delay time +* cummulatively. +* It is perfectly alright to provide a longer delay than required. It is not +* acceptable if the delay is shorter. +* +* Delay function example--using the machine clock signal of the native CPU------ +* When porting ispVME to a native CPU environment, the speed of CPU or +* the system clock that drives the CPU is usually known. +* The speed or the time it takes for the native CPU to execute one for loop +* then can be calculated as follows: +* The for loop usually is compiled into the ASSEMBLY code as shown below: +* LOOP: DEC RA; +* JNZ LOOP; +* If each line of assembly code needs 4 machine cycles to execute, +* the total number of machine cycles to execute the loop is 2 x 4 = 8. +* Usually system clock = machine clock (the internal CPU clock). +* Note: Some CPU has a clock multiplier to double the system clock for + the machine clock. +* +* Let the machine clock frequency of the CPU be F, or 1 machine cycle = 1/F. +* The time it takes to execute one for loop = (1/F ) x 8. +* Or one micro-second = F(MHz)/8; +* +* Example: The CPU internal clock is set to 100Mhz, then one micro-second = 100/8 = 12 +* +* The C code shown below can be used to create the milli-second accuracy. +* Users only need to enter the speed of the cpu. +* +**********************************************************************************/ +void ispVMDelay(unsigned short a_usTimeDelay) +{ + struct timespec ts; + + if (a_usTimeDelay & 0x8000) { + /* milliseconds */ + a_usTimeDelay &= 0x7FFF; + ts.tv_sec = (long int) (a_usTimeDelay / 1000); + ts.tv_nsec = (long int) (a_usTimeDelay % 1000) * 1000000ul; + } else { + /* microseconds */ + ts.tv_sec = 0; + ts.tv_nsec = (long int) a_usTimeDelay * 1000ul; + } + + nanosleep(&ts, NULL); +} + +/********************************************************************************* +* +* calibration +* +* It is important to confirm if the delay function is indeed providing +* the accuracy required. Also one other important parameter needed +* checking is the clock frequency. +* Calibration will help to determine the system clock frequency +* and the loop_per_micro value for one micro-second delay of the target +* specific hardware. +* +**********************************************************************************/ +void calibration(void) +{ + /*Apply 2 pulses to TCK.*/ + writePort(JTAG_TCK, 0x00); + writePort(JTAG_TCK, 0x01); + writePort(JTAG_TCK, 0x00); + writePort(JTAG_TCK, 0x01); + writePort(JTAG_TCK, 0x00); + + /*Delay for 1 millisecond. Pass on 1000 or 0x8001 both = 1ms delay.*/ + ispVMDelay(0x8001); + + /*Apply 2 pulses to TCK*/ + writePort(JTAG_TCK, 0x01); + writePort(JTAG_TCK, 0x00); + writePort(JTAG_TCK, 0x01); + writePort(JTAG_TCK, 0x00); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ispvm_ui.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ispvm_ui.c new file mode 100644 index 000000000000..69a8e53852b5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ispvm_ui.c @@ -0,0 +1,837 @@ +/************************************************************** +* +* Lattice Semiconductor Corp. Copyright 2008 +* +* ispVME Embedded allows programming of Lattice's suite of FPGA +* devices on embedded systems through the JTAG port. The software +* is distributed in source code form and is open to re - distribution +* and modification where applicable. +* +* ispVME Embedded C Source comprised with 3 modules: +* ispvm_ui.c is the module provides input and output support. +* ivm_core.c is the module interpret the VME file(s). +* hardware.c is the module access the JTAG port of the device(s). +* +* The optional module cable.c is for supporting Lattice's parallel +* port ispDOWNLOAD cable on DOS and Windows 95/98 O/S. It can be +* requested from Lattice's ispVMSupport. +* +***************************************************************/ + +/************************************************************** +* +* Revision History of ispvm_ui.c +* +* 3/6/07 ht Added functions vme_out_char(),vme_out_hex(), +* vme_out_string() to provide output resources. +* Consolidate all printf() calls into the added output +* functions. +* +* 09/11/07 NN Added Global variables initialization +* 09/24/07 NN Added a switch allowing users to do calibration. +* Calibration will help to determine the system clock frequency +* and the count value for one micro-second delay of the target +* specific hardware. +* Removed Delay Percent support +* 11/15/07 NN moved the checking of the File CRC to the end of processing +* 08/28/08 NN Added Calculate checksum support. +***************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*************************************************************** +* +* File pointer to the VME file. +* +***************************************************************/ + +FILE *g_pVMEFile = NULL; + +/*************************************************************** +* +* Functions declared in this ispvm_ui.c module +* +***************************************************************/ +unsigned char GetByte(void); +void vme_out_char(unsigned char charOut); +void vme_out_hex(unsigned char hexOut); +void vme_out_string(char *stringOut); +void ispVMMemManager(signed char cTarget, unsigned short usSize); +void ispVMFreeMem(void); +void error_handler(short a_siRetCode, char *pszMessage); +signed char ispVM(const char *a_pszFilename); + +/*************************************************************** +* +* Global variables. +* +***************************************************************/ +unsigned short g_usPreviousSize = 0; +unsigned short g_usExpectedCRC = 0; + +/*************************************************************** +* +* External variables and functions declared in ivm_core.c module. +* +***************************************************************/ +extern signed char ispVMCode(); +extern void ispVMCalculateCRC32(unsigned char a_ucData); +extern void ispVMStart(); +extern void ispVMEnd(); +extern unsigned short g_usCalculatedCRC; +extern unsigned short g_usDataType; +extern unsigned char *g_pucOutMaskData, +*g_pucInData, +*g_pucOutData, +*g_pucHIRData, +*g_pucTIRData, +*g_pucHDRData, +*g_pucTDRData, +*g_pucOutDMaskData, +*g_pucIntelBuffer; +extern unsigned char *g_pucHeapMemory; +extern unsigned short g_iHeapCounter; +extern unsigned short g_iHEAPSize; +extern unsigned short g_usIntelDataIndex; +extern unsigned short g_usIntelBufferSize; +extern LVDSPair *g_pLVDSList; +//08/28/08 NN Added Calculate checksum support. +extern unsigned long g_usChecksum; +extern unsigned int g_uiChecksumIndex; + +/* Added reinit for call ispvme more than once */ +extern void ivm_core_reinit(); +/*************************************************************** +* +* External variables and functions declared in hardware.c module. +* +***************************************************************/ +extern void calibration(void); +extern unsigned short g_usCpu_Frequency; +extern int g_file_fd; + +/*************************************************************** +* +* Supported VME versions. +* +***************************************************************/ + +const char *const g_szSupportedVersions[] = { "__VME2.0", "__VME3.0", "____12.0", "____12.1", 0 }; + +/*************************************************************** +* +* GetByte +* +* Returns a byte to the caller. The returned byte depends on the +* g_usDataType register. If the HEAP_IN bit is set, then the byte +* is returned from the HEAP. If the LHEAP_IN bit is set, then +* the byte is returned from the intelligent buffer. Otherwise, +* the byte is returned directly from the VME file. +* +***************************************************************/ + +char* strlwr(char *str) +{ + char *orig = str; +// process the string + for (; *str != '\0'; str++) + *str = tolower(*str); + return orig; +} + +unsigned char GetByte() +{ + unsigned char ucData = 0; + + if (g_usDataType & HEAP_IN) { + + /*************************************************************** + * + * Get data from repeat buffer. + * + ***************************************************************/ + + if (g_iHeapCounter > g_iHEAPSize) { + + /*************************************************************** + * + * Data over-run. + * + ***************************************************************/ + + return 0xFF; + } + + ucData = g_pucHeapMemory[g_iHeapCounter++]; + } + else if ( g_usDataType & LHEAP_IN ) { + + /*************************************************************** + * + * Get data from intel buffer. + * + ***************************************************************/ + + if (g_usIntelDataIndex >= g_usIntelBufferSize) { + + /*************************************************************** + * + * Data over-run. + * + ***************************************************************/ + + return 0xFF; + } + + ucData = g_pucIntelBuffer[g_usIntelDataIndex++]; + } + else { + + /*************************************************************** + * + * Get data from file. + * + ***************************************************************/ + + ucData = (unsigned char)fgetc(g_pVMEFile); + + if (feof(g_pVMEFile)) { + + /*************************************************************** + * + * Reached EOF. + * + ***************************************************************/ + + return 0xFF; + } + /*************************************************************** + * + * Calculate the 32-bit CRC if the expected CRC exist. + * + ***************************************************************/ + if( g_usExpectedCRC != 0) + { + ispVMCalculateCRC32(ucData); + } + } + + return (ucData); +} + +/*************************************************************** +* +* vme_out_char +* +* Send a character out to the output resource if available. +* The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_char(unsigned char charOut) +{ + dbg_print(is_debug_on, "%c", charOut); +} +/*************************************************************** +* +* vme_out_hex +* +* Send a character out as in hex format to the output resource +* if available. The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_hex(unsigned char hexOut) +{ + dbg_print(is_debug_on, "%.2X", hexOut); +} +/*************************************************************** +* +* vme_out_string +* +* Send a text string out to the output resource if available. +* The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_string(char *stringOut) +{ + dbg_print(is_debug_on,"%s",stringOut); +} +/*************************************************************** +* +* ispVMMemManager +* +* Allocate memory based on cTarget. The memory size is specified +* by usSize. +* +***************************************************************/ + +void ispVMMemManager(signed char cTarget, unsigned short usSize) +{ + switch (cTarget) { + case XTDI: + case TDI: + if (g_pucInData != NULL) { + if (g_usPreviousSize == usSize) { /*memory exist*/ + break; + } + else { + free(g_pucInData); + g_pucInData = NULL; + } + } + g_pucInData = (unsigned char *)malloc(usSize / 8 + 2); + g_usPreviousSize = usSize; + case XTDO: + case TDO: + if (g_pucOutData != NULL) { + if (g_usPreviousSize == usSize) { /*already exist*/ + break; + } + else { + free(g_pucOutData); + g_pucOutData = NULL; + } + } + g_pucOutData = (unsigned char *)malloc(usSize / 8 + 2); + g_usPreviousSize = usSize; + break; + case MASK: + if (g_pucOutMaskData != NULL) { + if (g_usPreviousSize == usSize) { /*already allocated*/ + break; + } + else { + free(g_pucOutMaskData); + g_pucOutMaskData = NULL; + } + } + g_pucOutMaskData = (unsigned char *)malloc(usSize / 8 + 2); + g_usPreviousSize = usSize; + break; + case HIR: + if (g_pucHIRData != NULL) { + free(g_pucHIRData); + g_pucHIRData = NULL; + } + g_pucHIRData = (unsigned char *)malloc(usSize / 8 + 2); + break; + case TIR: + if (g_pucTIRData != NULL) { + free(g_pucTIRData); + g_pucTIRData = NULL; + } + g_pucTIRData = (unsigned char *)malloc(usSize / 8 + 2); + break; + case HDR: + if (g_pucHDRData != NULL) { + free(g_pucHDRData); + g_pucHDRData = NULL; + } + g_pucHDRData = (unsigned char *)malloc(usSize / 8 + 2); + break; + case TDR: + if (g_pucTDRData != NULL) { + free(g_pucTDRData); + g_pucTDRData = NULL; + } + g_pucTDRData = (unsigned char *)malloc(usSize / 8 + 2); + break; + case HEAP: + if (g_pucHeapMemory != NULL) { + free(g_pucHeapMemory); + g_pucHeapMemory = NULL; + } + g_pucHeapMemory = (unsigned char *)malloc(usSize + 2); + break; + case DMASK: + if (g_pucOutDMaskData != NULL) { + if (g_usPreviousSize == usSize) { /*already allocated*/ + break; + } + else { + free(g_pucOutDMaskData); + g_pucOutDMaskData = NULL; + } + } + g_pucOutDMaskData = (unsigned char *)malloc(usSize / 8 + 2); + g_usPreviousSize = usSize; + break; + case LHEAP: + if (g_pucIntelBuffer != NULL) { + free(g_pucIntelBuffer); + g_pucIntelBuffer = NULL; + } + g_pucIntelBuffer = (unsigned char *)malloc(usSize + 2); + break; + case LVDS: + if (g_pLVDSList != NULL) { + free(g_pLVDSList); + g_pLVDSList = NULL; + } + g_pLVDSList = (LVDSPair * )calloc(usSize, sizeof(LVDSPair)); + break; + default: + return; + } +} + +/*************************************************************** +* +* ispVMFreeMem +* +* Free memory that were dynamically allocated. +* +***************************************************************/ + +void ispVMFreeMem() +{ + if (g_pucHeapMemory != NULL) { + free(g_pucHeapMemory); + g_pucHeapMemory = NULL; + } + + if (g_pucOutMaskData != NULL) { + free(g_pucOutMaskData); + g_pucOutMaskData = NULL; + } + + if (g_pucInData != NULL) { + free(g_pucInData); + g_pucInData = NULL; + } + + if (g_pucOutData != NULL) { + free(g_pucOutData); + g_pucOutData = NULL; + } + + if (g_pucHIRData != NULL) { + free(g_pucHIRData); + g_pucHIRData = NULL; + } + + if (g_pucTIRData != NULL) { + free(g_pucTIRData); + g_pucTIRData = NULL; + } + + if (g_pucHDRData != NULL) { + free(g_pucHDRData); + g_pucHDRData = NULL; + } + + if (g_pucTDRData != NULL) { + free(g_pucTDRData); + g_pucTDRData = NULL; + } + + if (g_pucOutDMaskData != NULL) { + free(g_pucOutDMaskData); + g_pucOutDMaskData = NULL; + } + + if (g_pucIntelBuffer != NULL) { + free(g_pucIntelBuffer); + g_pucIntelBuffer = NULL; + } + + if (g_pLVDSList != NULL) { + free(g_pLVDSList); + g_pLVDSList = NULL; + } +} + +/*************************************************************** +* +* error_handler +* +* Reports the error message. +* +***************************************************************/ + +void error_handler(short a_siRetCode, char *pszMessage) +{ + const char *pszErrorMessage[] = { "pass", + "verification fail", + "can't find the file", + "wrong file type", + "file error", + "option error", + "crc verification error" }; + + strcpy(pszMessage, pszErrorMessage[-a_siRetCode]); +} +/*************************************************************** +* +* ispVM +* +* The entry point of the ispVM embedded. If the version and CRC +* are verified, then the VME will be processed. +* +***************************************************************/ +signed char ispVM(const char *a_pszFilename) +{ + char szFileVersion[9] = { 0 }; + signed char cRetCode = 0; + signed char cIndex = 0; + signed char cVersionIndex = 0; + unsigned char ucReadByte = 0; + int ret; + /*************************************************************** + * + * Global variables initialization. + * + * 09/11/07 NN Added + ***************************************************************/ + g_pucHeapMemory = NULL; + g_iHeapCounter = 0; + g_iHEAPSize = 0; + g_usIntelDataIndex = 0; + g_usIntelBufferSize = 0; + g_usPreviousSize = 0; + + /*************************************************************** + * + * Open a file pointer to the VME file. + * + ***************************************************************/ + + if ((g_pVMEFile = fopen(a_pszFilename, "rb")) == NULL) { + return VME_FILE_READ_FAILURE; + } + /* Skip the contents of the file header */ + ret=fseek(g_pVMEFile, header_offset, SEEK_SET); + if (ret < 0) { + vme_out_string("Failed to skip header.\n"); + fclose(g_pVMEFile); + g_pVMEFile = NULL; + return VME_ARGUMENT_FAILURE; + } + + g_usCalculatedCRC = 0; + g_usExpectedCRC = 0; + ucReadByte = GetByte(); + switch (ucReadByte) { + case FILE_CRC: + + /*************************************************************** + * + * Read and store the expected CRC to do the comparison at the end. + * Only versions 3.0 and higher support CRC protection. + * + ***************************************************************/ + + g_usExpectedCRC = (unsigned char)fgetc(g_pVMEFile); + g_usExpectedCRC <<= 8; + g_usExpectedCRC |= fgetc(g_pVMEFile); + + /*************************************************************** + * + * Read and store the version of the VME file. + * + ***************************************************************/ + + for (cIndex = 0; cIndex < 8; cIndex++) { + szFileVersion[cIndex] = GetByte(); + } + break; + default: + + /*************************************************************** + * + * Read and store the version of the VME file. Must be version 2.0. + * + ***************************************************************/ + + szFileVersion[0] = (signed char)ucReadByte; + for (cIndex = 1; cIndex < 8; cIndex++) { + szFileVersion[cIndex] = GetByte(); + } + + break; + } + + /*************************************************************** + * + * Compare the VME file version against the supported version. + * + ***************************************************************/ + for (cVersionIndex = 0; g_szSupportedVersions[cVersionIndex] != 0; cVersionIndex++) { + for (cIndex = 0; cIndex < 8; cIndex++) { + if (szFileVersion[cIndex] != g_szSupportedVersions[cVersionIndex][cIndex]) { + cRetCode = VME_VERSION_FAILURE; + break; + } + cRetCode = 0; + } + + if (cRetCode == 0) { + + /*************************************************************** + * + * Found matching version, break. + * + ***************************************************************/ + + break; + } + } + + if (cRetCode < 0) { + + /*************************************************************** + * + * VME file version failed to match the supported versions. + * + ***************************************************************/ + + fclose(g_pVMEFile); + g_pVMEFile = NULL; + return VME_VERSION_FAILURE; + } + + /*************************************************************** + * + * Enable the JTAG port to communicate with the device. + * Set the JTAG state machine to the Test-Logic/Reset State. + * + ***************************************************************/ + ispVMStart(); + + /*************************************************************** + * + * Process the VME file. + * + ***************************************************************/ + + cRetCode = ispVMCode(); + + /*************************************************************** + * + * Set the JTAG State Machine to Test-Logic/Reset state then disable + * the communication with the JTAG port. + * + ***************************************************************/ + + ispVMEnd(); + + fclose(g_pVMEFile); + g_pVMEFile = NULL; + + ispVMFreeMem(); + + /*************************************************************** + * + * Compare the expected CRC versus the calculated CRC. + * + ***************************************************************/ + + if (cRetCode == 0 && g_usExpectedCRC != 0 && (g_usExpectedCRC != g_usCalculatedCRC)) { + printf("Expected CRC: 0x%.4X\n", g_usExpectedCRC); + printf("Calculated CRC: 0x%.4X\n", g_usCalculatedCRC); + return VME_CRC_FAILURE; + } + + return (cRetCode); +} + +/*************************************************************** +* +* ispvme_reinit +* +* Reinit ispvm_ui variables. +* +***************************************************************/ +static void ispvm_ui_reinit() +{ + g_pVMEFile = NULL; + g_usPreviousSize = 0; + g_usExpectedCRC = 0; +} + +/*************************************************************** +* +* main +* +***************************************************************/ + +int ispvme_main(int argc, char *argv[], int file_fd, name_info_t *info) +{ + unsigned short iCommandLineIndex = 0; + short siRetCode = 0; + char szExtension[5] = { 0 }; + char szCommandLineArg[300] = { 0 }; + short sicalibrate = 0; + + ispvm_ui_reinit(); + ivm_core_reinit(); + + //08/28/08 NN Added Calculate checksum support. + g_usChecksum = 0; + g_uiChecksumIndex = 0; + + if (file_fd < 0) { + dbg_print(is_debug_on, "Error:firmware upgrade ispvme dev parameters failed.\r\n"); + return -1; + } else { + g_file_fd = file_fd; + } + +#if 0 + ret = firmware_check_chip_name(g_file_fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip name: %s.\n", file_name); + close(g_file_fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } + + ret = firmware_check_chip_verison(g_file_fd, info); + if (ret != FIRMWARE_SUCCESS) { + dbg_print(is_debug_on, "Error: Failed to check chip version: %s.\n", file_name); + close(g_file_fd); + return firmware_error_type(FIRMWARE_ACTION_CHECK, info); + } +#endif + + vme_out_string(" Lattice Semiconductor Corp.\n"); + vme_out_string("\n ispVME(tm) V"); + vme_out_string(VME_VERSION_NUMBER); + vme_out_string(" Copyright 1998-2011.\n"); + vme_out_string("\nFor daisy chain programming of all in-system programmable devices\n\n"); + + if (argc < 2) { + vme_out_string("\nUsage: vme [option] vme_file [vme_file]\n"); + vme_out_string("Example: vme vme_file1.vme vme_file2.vme\n"); + vme_out_string("option -c: do the calibration.\n"); + vme_out_string("Example: vme -c\n"); + vme_out_string("Example: vme -c vme_file1.vme vme_file2.vme\n"); + vme_out_string("\n\n"); + g_file_fd = -1; + /* Change return to determine whether the upgrade was successful */ + return -1; + } + for (iCommandLineIndex = 1; iCommandLineIndex < argc; iCommandLineIndex++) { + strncpy(szCommandLineArg, argv[iCommandLineIndex], sizeof(szCommandLineArg) - 1); + if (!strcmp(strlwr(szCommandLineArg), "-c") && (iCommandLineIndex == 1)) { + sicalibrate = 1; + } else if (!strcmp(strlwr(szCommandLineArg), "-c") && (iCommandLineIndex != 1)) { + vme_out_string("Error: calibrate option -c must be the first argument\n\n"); + g_file_fd = -1; + /* Change return to determine whether the upgrade was successful */ + return -1; + //exit(1); + } else { + strcpy(szExtension, &szCommandLineArg[strlen(szCommandLineArg) - 4]); + strlwr(szExtension); + if (strcmp(szExtension, ".vme")) { + vme_out_string("Error: VME files must end with the extension *.vme\n\n"); + g_file_fd = -1; + /* Change return to determine whether the upgrade was successful */ + return -1; + //exit(1); + } + } + } + siRetCode = 0; + + if (sicalibrate) { + calibration(); + } + for (iCommandLineIndex = 1; iCommandLineIndex < argc; iCommandLineIndex++) { /* Process all VME files sequentially */ + strcpy(szCommandLineArg, argv[iCommandLineIndex]); + if (!strcmp(strlwr(szCommandLineArg), "-c") && (iCommandLineIndex == 1)) { + + } else if (!strcmp(strlwr(szCommandLineArg), "-checksum")) { + + } else { + vme_out_string("Processing virtual machine file ("); + vme_out_string(szCommandLineArg); + vme_out_string(")......\n\n"); + siRetCode = ispVM(argv[iCommandLineIndex]); + if (siRetCode < 0) { + break; + } + } + } + + if (siRetCode < 0) { + error_handler(siRetCode, szCommandLineArg); + vme_out_string("Failed due to "); + vme_out_string(szCommandLineArg); + vme_out_string("\n\n"); + vme_out_string("+=======+\n"); + vme_out_string("| FAIL! |\n"); + vme_out_string("+=======+\n\n"); + } else { + vme_out_string("+=======+\n"); + vme_out_string("| PASS! |\n"); + vme_out_string("+=======+\n\n"); + //08/28/08 NN Added Calculate checksum support. + if (g_usChecksum != 0) { + g_usChecksum &= 0xFFFF; + printf("Data Checksum: %.4X\n\n", (unsigned int)g_usChecksum); + g_usChecksum = 0; + } + } + g_file_fd = -1; + /* Change return to determine whether the upgrade was successful */ + return siRetCode; + //exit(siRetCode); +} + +/* + * firmware_upgrade_ispvme + * function: ispvme firmware upgrade + * @file_fd: param[in] Upgrade devices fd + * @upgrade_file_name: param[in] Upgrade file name + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS, other fail return error code + */ +int firmware_upgrade_ispvme(int file_fd, char *upgrade_file_name, name_info_t *info) +{ + char *argv[2]; + int ret, rv, i, retry; + + argv[1] = upgrade_file_name; + + /* Initialize and enable */ + rv = ioctl(file_fd, FIRMWARE_JTAG_INIT,NULL); + if (rv < 0) { + vme_out_string("Failed to init GPIO.\n"); + return VME_ARGUMENT_FAILURE; + } + + i = 0; + retry = FIRMWARE_UPGRADE_RETRY_CNT; + + ret = 0; + while(i < retry) { + ret = ispvme_main(2, argv, file_fd, info); + if (ret < 0) { + i++; + dbg_print(is_debug_on, "%d times ispvme upgrade failed. ret %d.\n", i, ret); + continue; + } else { + dbg_print(is_debug_on, "ispvme upgrade success.\n"); + break; + } + } + + /* Upgrade completed, release */ + rv = ioctl(file_fd, FIRMWARE_JTAG_FINISH, NULL); + if (rv < 0) { + vme_out_string("Failed to release GPIO.\n"); + return VME_ARGUMENT_FAILURE; + } + + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ivm_core.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ivm_core.c new file mode 100644 index 000000000000..540be481d35e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_gpio_vme/ivm_core.c @@ -0,0 +1,3097 @@ +/*************************************************************** +* +* Lattice Semiconductor Corp. Copyright 2009 +* +* ispVME Embedded allows programming of Lattice's suite of FPGA +* devices on embedded systems through the JTAG port. The software +* is distributed in source code form and is open to re - distribution +* and modification where applicable. +* +* Revision History of ivm_core.c module: +* 4/25/06 ht Change some variables from unsigned short or int +* to long int to make the code compiler independent. +* 5/24/06 ht Support using RESET (TRST) pin as a special purpose +* control pin such as triggering the loading of known +* state exit. +* 3/6/07 ht added functions to support output to terminals +* +* 09/24/07 NN Type cast mismatch variables +* Moved the sclock() function to hardware.c +* 08/28/08 NN Added Calculate checksum support. +* 4/1/09 Nguyen replaced the recursive function call codes on +* the ispVMLCOUNT function +* +***************************************************************/ + +#include +#include +#include +#include + +/*************************************************************** +* +* Global variables used to specify the flow control and data type. +* +* g_usFlowControl: flow control register. Each bit in the +* register can potentially change the +* personality of the embedded engine. +* g_usDataType: holds the data type of the current row. +* +***************************************************************/ + +unsigned short g_usFlowControl = 0x0000; +unsigned short g_usDataType = 0x0000; + +/*************************************************************** +* +* Global variables used to specify the ENDDR and ENDIR. +* +* g_ucEndDR: the state that the device goes to after SDR. +* g_ucEndIR: the state that the device goes to after SIR. +* +***************************************************************/ + +unsigned char g_ucEndDR = DRPAUSE; +unsigned char g_ucEndIR = IRPAUSE; + +/*************************************************************** +* +* Global variables used to support header/trailer. +* +* g_usHeadDR: the number of lead devices in bypass. +* g_usHeadIR: the sum of IR length of lead devices. +* g_usTailDR: the number of tail devices in bypass. +* g_usTailIR: the sum of IR length of tail devices. +* +***************************************************************/ + +unsigned short g_usHeadDR = 0; +unsigned short g_usHeadIR = 0; +unsigned short g_usTailDR = 0; +unsigned short g_usTailIR = 0; + +/*************************************************************** +* +* Global variable to store the number of bits of data or instruction +* to be shifted into or out from the device. +* +***************************************************************/ + +unsigned short g_usiDataSize = 0; + +/*************************************************************** +* +* Stores the frequency. Default to 1 MHz. +* +***************************************************************/ + +int g_iFrequency = 1000; + +/*************************************************************** +* +* Stores the maximum amount of ram needed to hold a row of data. +* +***************************************************************/ + +unsigned short g_usMaxSize = 0; + +/*************************************************************** +* +* Stores the LSH or RSH value. +* +***************************************************************/ + +unsigned short g_usShiftValue = 0; + +/*************************************************************** +* +* Stores the current repeat loop value. +* +***************************************************************/ + +unsigned short g_usRepeatLoops = 0; + +/*************************************************************** +* +* Stores the current vendor. +* +***************************************************************/ + +signed char g_cVendor = LATTICE; + +/*************************************************************** +* +* Stores the VME file CRC. +* +***************************************************************/ + +unsigned short g_usCalculatedCRC = 0; + +/*************************************************************** +* +* Stores the Device Checksum. +* +***************************************************************/ +//08/28/08 NN Added Calculate checksum support. +unsigned long g_usChecksum = 0; +unsigned int g_uiChecksumIndex = 0; + +/*************************************************************** +* +* Stores the current state of the JTAG state machine. +* +***************************************************************/ + +signed char g_cCurrentJTAGState = 0; + +/*************************************************************** +* +* Global variables used to support looping. +* +* g_pucHeapMemory: holds the entire repeat loop. +* g_iHeapCounter: points to the current byte in the repeat loop. +* g_iHEAPSize: the current size of the repeat in bytes. +* +***************************************************************/ + +unsigned char *g_pucHeapMemory = NULL; +unsigned short g_iHeapCounter = 0; +unsigned short g_iHEAPSize = 0; + +/*************************************************************** +* +* Global variables used to support intelligent programming. +* +* g_usIntelDataIndex: points to the current byte of the +* intelligent buffer. +* g_usIntelBufferSize: holds the size of the intelligent +* buffer. +* +***************************************************************/ + +unsigned short g_usIntelDataIndex = 0; +unsigned short g_usIntelBufferSize = 0; + +/**************************************************************************** +* +* Holds the maximum size of each respective buffer. These variables are used +* to write the HEX files when converting VME to HEX. +* +*****************************************************************************/ + +unsigned short g_usTDOSize = 0; +unsigned short g_usMASKSize = 0; +unsigned short g_usTDISize = 0; +unsigned short g_usDMASKSize = 0; +unsigned short g_usLCOUNTSize = 0; +unsigned short g_usHDRSize = 0; +unsigned short g_usTDRSize = 0; +unsigned short g_usHIRSize = 0; +unsigned short g_usTIRSize = 0; +unsigned short g_usHeapSize = 0; + +/*************************************************************** +* +* Global variables used to store data. +* +* g_pucOutMaskData: local RAM to hold one row of MASK data. +* g_pucInData: local RAM to hold one row of TDI data. +* g_pucOutData: local RAM to hold one row of TDO data. +* g_pucHIRData: local RAM to hold the current SIR header. +* g_pucTIRData: local RAM to hold the current SIR trailer. +* g_pucHDRData: local RAM to hold the current SDR header. +* g_pucTDRData: local RAM to hold the current SDR trailer. +* g_pucIntelBuffer: local RAM to hold the current intelligent buffer. +* g_pucOutDMaskData: local RAM to hold one row of DMASK data. +* +***************************************************************/ + +unsigned char *g_pucOutMaskData = NULL, +*g_pucInData = NULL, +*g_pucOutData = NULL, +*g_pucHIRData = NULL, +*g_pucTIRData = NULL, +*g_pucHDRData = NULL, +*g_pucTDRData = NULL, +*g_pucIntelBuffer = NULL, +*g_pucOutDMaskData = NULL; + +/*************************************************************** +* +* JTAG state machine transition table. +* +***************************************************************/ + +struct { + unsigned char CurState; /* From this state */ + unsigned char NextState; /* Step to this state */ + unsigned char Pattern; /* The tragetory of TMS */ + unsigned char Pulses; /* The number of steps */ +} g_JTAGTransistions[25] = { + { RESET, RESET, 0xFC, 6 }, /* Transitions from RESET */ + { RESET, IDLE, 0x00, 1 }, + { RESET, DRPAUSE, 0x50, 5 }, + { RESET, IRPAUSE, 0x68, 6 }, + { IDLE, RESET, 0xE0, 3 }, /* Transitions from IDLE */ + { IDLE, DRPAUSE, 0xA0, 4 }, + { IDLE, IRPAUSE, 0xD0, 5 }, + { DRPAUSE, RESET, 0xF8, 5 }, /* Transitions from DRPAUSE */ + { DRPAUSE, IDLE, 0xC0, 3 }, + { DRPAUSE, IRPAUSE, 0xF4, 7 }, + { DRPAUSE, DRPAUSE, 0xE8, 6 }, /* 06/14/06 Support POLING STATUS LOOP*/ + { IRPAUSE, RESET, 0xF8, 5 }, /* Transitions from IRPAUSE */ + { IRPAUSE, IDLE, 0xC0, 3 }, + { IRPAUSE, DRPAUSE, 0xE8, 6 }, + { DRPAUSE, SHIFTDR, 0x80, 2 }, /* Extra transitions using SHIFTDR */ + { IRPAUSE, SHIFTDR, 0xE0, 5 }, + { SHIFTDR, DRPAUSE, 0x80, 2 }, + { SHIFTDR, IDLE, 0xC0, 3 }, + { IRPAUSE, SHIFTIR, 0x80, 2 }, /* Extra transitions using SHIFTIR */ + { SHIFTIR, IRPAUSE, 0x80, 2 }, + { SHIFTIR, IDLE, 0xC0, 3 }, + { DRPAUSE, DRCAPTURE, 0xE0, 4 }, /* 11/15/05 Support DRCAPTURE*/ + { DRCAPTURE, DRPAUSE, 0x80, 2 }, + { IDLE, DRCAPTURE, 0x80, 2 }, + { IRPAUSE, DRCAPTURE, 0xE0, 4 } +}; + +/*************************************************************** +* +* List to hold all LVDS pairs. +* +***************************************************************/ + +LVDSPair *g_pLVDSList = NULL; +unsigned short g_usLVDSPairCount = 0; + +/*************************************************************** +* +* Function prototypes. +* +***************************************************************/ + +signed char ispVMCode(); +signed char ispVMDataCode(); +long int ispVMDataSize(); +void ispVMData(unsigned char *Data); +signed char ispVMShift(signed char Code); +signed char ispVMAmble(signed char Code); +signed char ispVMLoop(unsigned short a_usLoopCount); +signed char ispVMBitShift(signed char mode, unsigned short bits); +void ispVMComment(unsigned short a_usCommentSize); +void ispVMHeader(unsigned short a_usHeaderSize); +signed char ispVMLCOUNT(unsigned short a_usCountSize); +void ispVMClocks(unsigned short Clocks); +void ispVMBypass(signed char ScanType, unsigned short Bits); +void ispVMStateMachine(signed char NextState); +void ispVMStart(); +void ispVMEnd(); +signed char ispVMSend(unsigned short int); +signed char ispVMRead(unsigned short int); +signed char ispVMReadandSave(unsigned short int); +signed char ispVMProcessLVDS(unsigned short a_usLVDSCount); + +/*************************************************************** +* +* External variables and functions in ispvm_ui.c module +* +***************************************************************/ +extern void vme_out_char(unsigned char charOut); +extern void vme_out_hex(unsigned char hexOut); +extern void vme_out_string(char *stringOut); +extern unsigned char GetByte(); +extern void ispVMMemManager(signed char types, unsigned short size); + +/*************************************************************** +* +* External variables and functions in hardware.c module +* +***************************************************************/ +extern void ispVMDelay(unsigned short int a_usMicroSecondDelay); +extern unsigned char readPort(); +extern void writePort(unsigned char pins, unsigned char value); +extern void sclock(); +extern signed char g_cCurrentJTAGState; +#ifdef VME_DEBUG + +/*************************************************************** +* +* GetState +* +* Returns the state as a string based on the opcode. Only used +* for debugging purposes. +* +***************************************************************/ + +const char* GetState(unsigned char a_ucState) +{ + switch (a_ucState) { + case RESET: + return ("RESET"); + case IDLE: + return ("IDLE"); + case IRPAUSE: + return ("IRPAUSE"); + case DRPAUSE: + return ("DRPAUSE"); + case SHIFTIR: + return ("SHIFTIR"); + case SHIFTDR: + return ("SHIFTDR"); + case DRCAPTURE: /* 11/15/05 support DRCAPTURE*/ + return ("DRCAPTURE"); + default: + break; + } + + return 0; +} + +/*************************************************************** +* +* PrintData +* +* Prints the data. Only used for debugging purposes. +* +***************************************************************/ + +void PrintData(unsigned short a_iDataSize, unsigned char *a_pucData) +{ + //09/11/07 NN added local variables initialization + unsigned short usByteSize = 0; + unsigned short usBitIndex = 0; + signed short usByteIndex = 0; + unsigned char ucByte = 0; + unsigned char ucFlipByte = 0; + + if (a_iDataSize % 8) { + //09/11/07 NN Type cast mismatch variables + usByteSize = (unsigned short)(a_iDataSize / 8 + 1); + } else { + //09/11/07 NN Type cast mismatch variables + usByteSize = (unsigned short)(a_iDataSize / 8);// 4 + } + printf("("); + //09/11/07 NN Type cast mismatch variables + for (usByteIndex = (signed short)(usByteSize - 1); usByteIndex >= 0; usByteIndex--) { + ucByte = a_pucData[usByteIndex]; + ucFlipByte = 0x00; + + /*************************************************************** + * + * Flip each byte. + * + ***************************************************************/ + + for (usBitIndex = 0; usBitIndex < 8; usBitIndex++) { + ucFlipByte <<= 1; + if (ucByte & 0x1) { + ucFlipByte |= 0x1; + } + + ucByte >>= 1; + } + + /*************************************************************** + * + * Print the flipped byte. + * + ***************************************************************/ + + printf("%.02X", ucFlipByte); + if ((usByteSize - usByteIndex) % 40 == 39) { + printf("\n\t\t"); + } + if (usByteIndex < 0) + break; + } + printf(")"); +} +#endif //VME_DEBUG + +/*************************************************************** +* +* ispVMDataSize +* +* Returns a VME-encoded number, usually used to indicate the +* bit length of an SIR/SDR command. +* +***************************************************************/ + +long int ispVMDataSize() +{ + //09/11/07 NN added local variables initialization + long int iSize = 0; + signed char cCurrentByte = 0; + signed char cIndex = 0; + cIndex = 0; + + while ((cCurrentByte = GetByte()) & 0x80) { + iSize |= ((long int)(cCurrentByte & 0x7F)) << cIndex; + cIndex += 7; + } + iSize |= ((long int)(cCurrentByte & 0x7F)) << cIndex; + + return iSize; +} + +/*************************************************************** +* +* ispVMCode +* +* This is the heart of the embedded engine. All the high-level opcodes +* are extracted here. Once they have been identified, then it +* will call other functions to handle the processing. +* +***************************************************************/ + +signed char ispVMCode() +{ + //09/11/07 NN added local variables initialization + unsigned short iRepeatSize = 0; + signed char cOpcode = 0; + signed char cRetCode = 0; + unsigned char ucState = 0; + unsigned short usDelay = 0; + unsigned short usToggle = 0; + unsigned char usByte = 0; + + /*************************************************************** + * + * Check the compression flag only if this is the first time + * this function is entered. Do not check the compression flag if + * it is being called recursively from other functions within + * the embedded engine. + * + ***************************************************************/ + + if (!(g_usDataType & LHEAP_IN) && !(g_usDataType & HEAP_IN)) { + usByte = GetByte(); + if (usByte == 0xf1) { + g_usDataType |= COMPRESS; + } else if (usByte == 0xf2) { + g_usDataType &= ~COMPRESS; + } else { + return VME_INVALID_FILE; + } + } + + /*************************************************************** + * + * Begin looping through all the VME opcodes. + * + ***************************************************************/ + while ((cOpcode = GetByte()) >= 0) { + switch (cOpcode) { + case STATE: + + /*************************************************************** + * + * Step the JTAG state machine. + * + ***************************************************************/ + + ucState = GetByte(); + /*************************************************************** + * + * Step the JTAG state machine to DRCAPTURE to support Looping. + * + ***************************************************************/ + + if ((g_usDataType & LHEAP_IN) && + (ucState == DRPAUSE) && + (g_cCurrentJTAGState == ucState)) { + ispVMStateMachine(DRCAPTURE); + } + + ispVMStateMachine(ucState); + +#ifdef VME_DEBUG + if (g_usDataType & LHEAP_IN) { + printf("LDELAY %s ", GetState(ucState)); + } else { + printf("STATE %s;\n", GetState(ucState)); + } +#endif //VME_DEBUG + break; + case SIR: + case SDR: + case XSDR: + +#ifdef VME_DEBUG + switch (cOpcode) { + case SIR: + printf("SIR "); + break; + case SDR: + case XSDR: + if (g_usDataType & LHEAP_IN) { + printf("LSDR "); + } else { + printf("SDR "); + } + break; + } +#endif //VME_DEBUG + /*************************************************************** + * + * Shift in data into the device. + * + ***************************************************************/ + cRetCode = ispVMShift(cOpcode); + if (cRetCode != 0) { + return (cRetCode); + } + break; + case WAIT: + + /*************************************************************** + * + * Observe delay. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + usDelay = (unsigned short)ispVMDataSize(); + ispVMDelay(usDelay); + +#ifdef VME_DEBUG + if (usDelay & 0x8000) { + + /*************************************************************** + * + * Since MSB is set, the delay time must be decoded to + * millisecond. The SVF2VME encodes the MSB to represent + * millisecond. + * + ***************************************************************/ + + usDelay &= ~0x8000; + if (g_usDataType & LHEAP_IN) { + printf("%.2E SEC;\n", (float)usDelay / 1000); + } else { + printf("RUNTEST %.2E SEC;\n", (float)usDelay / 1000); + } + } else { + + /*************************************************************** + * + * Since MSB is not set, the delay time is given as microseconds. + * + ***************************************************************/ + + if (g_usDataType & LHEAP_IN) { + printf("%.2E SEC;\n", (float)usDelay / 1000000); + } else { + printf("RUNTEST %.2E SEC;\n", (float)usDelay / 1000000); + } + } +#endif //VME_DEBUG + break; + case TCK: + + /*************************************************************** + * + * Issue clock toggles. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + usToggle = (unsigned short)ispVMDataSize(); + ispVMClocks(usToggle); + +#ifdef VME_DEBUG + printf("RUNTEST %d TCK;\n", usToggle); +#endif //VME_DEBUG + break; + case ENDDR: + + /*************************************************************** + * + * Set the ENDDR. + * + ***************************************************************/ + + g_ucEndDR = GetByte(); + +#ifdef VME_DEBUG + printf("ENDDR %s;\n", GetState(g_ucEndDR)); +#endif //VME_DEBUG + break; + case ENDIR: + + /*************************************************************** + * + * Set the ENDIR. + * + ***************************************************************/ + + g_ucEndIR = GetByte(); + +#ifdef VME_DEBUG + printf("ENDIR %s;\n", GetState(g_ucEndIR)); +#endif //VME_DEBUG + break; + case HIR: + case TIR: + case HDR: + case TDR: + +#ifdef VME_DEBUG + switch (cOpcode) { + case HIR: + printf("HIR "); + break; + case TIR: + printf("TIR "); + break; + case HDR: + printf("HDR "); + break; + case TDR: + printf("TDR "); + break; + } +#endif //VME_DEBUG + + /*************************************************************** + * + * Set the header/trailer of the device in order to bypass + * successfully. + * + ***************************************************************/ + + cRetCode = ispVMAmble(cOpcode); + if (cRetCode != 0) { + return (cRetCode); + } + +#ifdef VME_DEBUG + printf(";\n"); +#endif //VME_DEBUG + break; + case MEM: + + /*************************************************************** + * + * The maximum RAM required to support processing one row of the + * VME file. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_usMaxSize = (unsigned short)ispVMDataSize(); + +#ifdef VME_DEBUG + printf("// MEMSIZE %d\n", g_usMaxSize); +#endif //VME_DEBUG + break; + case VENDOR: + + /*************************************************************** + * + * Set the VENDOR type. + * + ***************************************************************/ + + cOpcode = GetByte(); + switch (cOpcode) { + case LATTICE: +#ifdef VME_DEBUG + printf("// VENDOR LATTICE\n"); +#endif //VME_DEBUG + g_cVendor = LATTICE; + break; + case ALTERA: +#ifdef VME_DEBUG + printf("// VENDOR ALTERA\n"); +#endif //VME_DEBUG + g_cVendor = ALTERA; + break; + case XILINX: +#ifdef VME_DEBUG + printf("// VENDOR XILINX\n"); +#endif //VME_DEBUG + g_cVendor = XILINX; + break; + default: + break; + } + break; + case SETFLOW: + + /*************************************************************** + * + * Set the flow control. Flow control determines the personality + * of the embedded engine. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_usFlowControl |= (unsigned short)ispVMDataSize(); + break; + case RESETFLOW: + + /*************************************************************** + * + * Unset the flow control. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_usFlowControl &= (unsigned short)~(ispVMDataSize()); + break; + case HEAP: + + /*************************************************************** + * + * Allocate heap size to store loops. + * + ***************************************************************/ + + cRetCode = GetByte(); + if (cRetCode != SECUREHEAP) { + return VME_INVALID_FILE; + } + //09/11/07 NN Type cast mismatch variables + g_iHEAPSize = (unsigned short)ispVMDataSize(); + + /**************************************************************************** + * + * Store the maximum size of the HEAP buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_iHEAPSize > g_usHeapSize) { + g_usHeapSize = g_iHEAPSize; + } + + ispVMMemManager(HEAP, (unsigned short)g_iHEAPSize); + break; + case REPEAT: + + /*************************************************************** + * + * Execute loops. + * + ***************************************************************/ + + g_usRepeatLoops = 0; + + //09/11/07 NN Type cast mismatch variables + iRepeatSize = (unsigned short)ispVMDataSize(); + + cRetCode = ispVMLoop((unsigned short)iRepeatSize); + if (cRetCode != 0) { + return (cRetCode); + } + break; + case ENDLOOP: + + /*************************************************************** + * + * Exit point from processing loops. + * + ***************************************************************/ + + return (cRetCode); + case ENDVME: + + /*************************************************************** + * + * The only valid exit point that indicates end of programming. + * + ***************************************************************/ + + return (cRetCode); + case SHR: + + /*************************************************************** + * + * Right-shift address. + * + ***************************************************************/ + + g_usFlowControl |= SHIFTRIGHT; + + //09/11/07 NN Type cast mismatch variables + g_usShiftValue = (unsigned short)(g_usRepeatLoops * (unsigned short)GetByte()); + break; + case SHL: + + /*************************************************************** + * + * Left-shift address. + * + ***************************************************************/ + + g_usFlowControl |= SHIFTLEFT; + + //09/11/07 NN Type cast mismatch variables + g_usShiftValue = (unsigned short)(g_usRepeatLoops * (unsigned short)GetByte()); + break; + case FREQUENCY: + + /*************************************************************** + * + * Set the frequency. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_iFrequency = (int)(ispVMDataSize()); + //10/23/08 NN changed to check if the frequency smaller than 1000 + if (g_iFrequency >= 1000) { + g_iFrequency = g_iFrequency / 1000; + if (g_iFrequency == 1) + g_iFrequency = 1000; +#ifdef VME_DEBUG + printf("FREQUENCY %.2E HZ;\n", (float)g_iFrequency * 1000); +#endif //VME_DEBUG + } else { + if (g_iFrequency == 0) + g_iFrequency = 1000; +#ifdef VME_DEBUG + printf("FREQUENCY %.2E HZ;\n", (float)g_iFrequency); +#endif //VME_DEBUG + } + break; + case LCOUNT: + + /*************************************************************** + * + * Process LCOUNT command. + * + ***************************************************************/ + + cRetCode = ispVMLCOUNT((unsigned short)ispVMDataSize()); + if (cRetCode != 0) { + return (cRetCode); + } + break; + case VUES: + + /*************************************************************** + * + * Set the flow control to verify USERCODE. + * + ***************************************************************/ + + g_usFlowControl |= VERIFYUES; + break; + case COMMENT: + + /*************************************************************** + * + * Display comment. + * + ***************************************************************/ + + ispVMComment((unsigned short)ispVMDataSize()); + break; + case LVDS: + + /*************************************************************** + * + * Process LVDS command. + * + ***************************************************************/ + + ispVMProcessLVDS((unsigned short)ispVMDataSize()); + break; + case HEADER: + + /*************************************************************** + * + * Discard header. + * + ***************************************************************/ + + ispVMHeader((unsigned short)ispVMDataSize()); + break; + /* 03/14/06 Support Toggle ispENABLE signal*/ + case ispEN: + ucState = GetByte(); + if ((ucState == ON) || (ucState == 0x01)) + writePort(JTAG_ENABLE, 0x01); + else + writePort(JTAG_ENABLE, 0x00); + ispVMDelay(1); + break; + /* 05/24/06 support Toggle TRST pin*/ + case TRST: + ucState = GetByte(); + if (ucState == 0x01) + writePort(JTAG_TRST, 0x01); + else + writePort(JTAG_TRST, 0x00); + ispVMDelay(1); + break; + default: + + /*************************************************************** + * + * Invalid opcode encountered. + * + ***************************************************************/ + +#ifdef VME_DEBUG + printf("\nINVALID OPCODE: 0x%.2X\n", cOpcode); +#endif //VME_DEBUG + + return VME_INVALID_FILE; + } + } + + /*************************************************************** + * + * Invalid exit point. Processing the token 'ENDVME' is the only + * valid way to exit the embedded engine. + * + ***************************************************************/ + + return (VME_INVALID_FILE); +} + +/*************************************************************** +* +* ispVMDataCode +* +* Processes the TDI/TDO/MASK/DMASK etc of an SIR/SDR command. +* +***************************************************************/ + +signed char ispVMDataCode() +{ + //09/11/07 NN added local variables initialization + signed char cDataByte = 0; + signed char siDataSource = 0; /*source of data from file by default*/ + + if (g_usDataType & HEAP_IN) { + siDataSource = 1; /*the source of data from memory*/ + } + + /**************************************************************************** + * + * Clear the data type register. + * + *****************************************************************************/ + + g_usDataType &= ~(MASK_DATA + TDI_DATA + TDO_DATA + DMASK_DATA + CMASK_DATA); + + /**************************************************************************** + * + * Iterate through SIR/SDR command and look for TDI, TDO, MASK, etc. + * + *****************************************************************************/ + + while ((cDataByte = GetByte()) >= 0) { + + ispVMMemManager(cDataByte, g_usMaxSize); + switch (cDataByte) { + case TDI: + + /**************************************************************************** + * + * Store the maximum size of the TDI buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTDISize) { + g_usTDISize = g_usiDataSize; + } + /**************************************************************************** + * + * Updated data type register to indicate that TDI data is currently being + * used. Process the data in the VME file into the TDI buffer. + * + *****************************************************************************/ + + g_usDataType |= TDI_DATA; + ispVMData(g_pucInData); + break; + case XTDO: + + /**************************************************************************** + * + * Store the maximum size of the TDO buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTDOSize) { + g_usTDOSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that TDO data is currently being + * used. + * + *****************************************************************************/ + + g_usDataType |= TDO_DATA; + break; + case TDO: + + /**************************************************************************** + * + * Store the maximum size of the TDO buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTDOSize) { + g_usTDOSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that TDO data is currently being + * used. Process the data in the VME file into the TDO buffer. + * + *****************************************************************************/ + + g_usDataType |= TDO_DATA; + ispVMData(g_pucOutData); + break; + case MASK: + + /**************************************************************************** + * + * Store the maximum size of the MASK buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usMASKSize) { + g_usMASKSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that MASK data is currently being + * used. Process the data in the VME file into the MASK buffer. + * + *****************************************************************************/ + + g_usDataType |= MASK_DATA; + ispVMData(g_pucOutMaskData); + break; + case DMASK: + + /**************************************************************************** + * + * Store the maximum size of the DMASK buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usDMASKSize) { + g_usDMASKSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that DMASK data is currently being + * used. Process the data in the VME file into the DMASK buffer. + * + *****************************************************************************/ + + g_usDataType |= DMASK_DATA; + ispVMData(g_pucOutDMaskData); + break; + case CMASK: + + /**************************************************************************** + * + * Updated data type register to indicate that CMASK data is currently being + * used. Process the data in the VME file into the CMASK buffer. + * + *****************************************************************************/ + + g_usDataType |= CMASK_DATA; + ispVMData(g_pucOutMaskData); + break; + case CONTINUE: + return (0); + default: + + /**************************************************************************** + * + * Encountered invalid opcode. + * + *****************************************************************************/ + + return (VME_INVALID_FILE); + } + + switch (cDataByte) { + case TDI: + + /**************************************************************************** + * + * Left bit shift. Used when performing algorithm looping. + * + *****************************************************************************/ + + if (g_usFlowControl & SHIFTLEFT) { + ispVMBitShift(SHL, g_usShiftValue); + g_usFlowControl &= ~SHIFTLEFT; + } + + /**************************************************************************** + * + * Right bit shift. Used when performing algorithm looping. + * + *****************************************************************************/ + + if (g_usFlowControl & SHIFTRIGHT) { + ispVMBitShift(SHR, g_usShiftValue); + g_usFlowControl &= ~SHIFTRIGHT; + } + default: + break; + } + + if (siDataSource) { + g_usDataType |= HEAP_IN; /*restore data from memory*/ + } + } + + if (siDataSource) { /*fetch data from heap memory upon return*/ + g_usDataType |= HEAP_IN; + } + + if (cDataByte < 0) { + + /**************************************************************************** + * + * Encountered invalid opcode. + * + *****************************************************************************/ + + return (VME_INVALID_FILE); + } else { + return (0); + } +} + +/*************************************************************** +* +* ispVMData +* Extract one row of data operand from the current data type opcode. Perform +* the decompression if necessary. Extra RAM is not required for the +* decompression process. The decompression scheme employed in this module +* is on row by row basis. The format of the data stream: +* [compression code][compressed data stream] +* 0x00 --No compression +* 0x01 --Compress by 0x00. +* Example: +* Original stream: 0x000000000000000000000001 +* Compressed stream: 0x01000901 +* Detail: 0x01 is the code, 0x00 is the key, +* 0x09 is the count of 0x00 bytes, +* 0x01 is the uncompressed byte. +* 0x02 --Compress by 0xFF. +* Example: +* Original stream: 0xFFFFFFFFFFFFFFFFFFFFFF01 +* Compressed stream: 0x02FF0901 +* Detail: 0x02 is the code, 0xFF is the key, +* 0x09 is the count of 0xFF bytes, +* 0x01 is the uncompressed byte. +* 0x03 +* : : +* 0xFE -- Compress by nibble blocks. +* Example: +* Original stream: 0x84210842108421084210 +* Compressed stream: 0x0584210 +* Detail: 0x05 is the code, means 5 nibbles block. +* 0x84210 is the 5 nibble blocks. +* The whole row is 80 bits given by g_usiDataSize. +* The number of times the block repeat itself +* is found by g_usiDataSize/(4*0x05) which is 4. +* 0xFF -- Compress by the most frequently happen byte. +* Example: +* Original stream: 0x04020401030904040404 +* Compressed stream: 0xFF04(0,1,0x02,0,1,0x01,1,0x03,1,0x09,0,0,0) +* or: 0xFF044090181C240 +* Detail: 0xFF is the code, 0x04 is the key. +* a bit of 0 represent the key shall be put into +* the current bit position and a bit of 1 +* represent copying the next of 8 bits of data +* in. +* +***************************************************************/ + +void ispVMData(unsigned char *ByteData) +{ + //09/11/07 NN added local variables initialization + unsigned short size = 0; + unsigned short i, j, m, getData = 0; + unsigned char cDataByte = 0; + unsigned char compress = 0; + unsigned short FFcount = 0; + unsigned char compr_char = 0xFF; + unsigned short index = 0; + signed char compression = 0; + + /*convert number in bits to bytes*/ + if (g_usiDataSize % 8 > 0) { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize / 8 + 1); + } else { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize / 8); + } + + /* If there is compression, then check if compress by key of 0x00 or 0xFF + or by other keys or by nibble blocks*/ + + if (g_usDataType & COMPRESS) { + compression = 1; + if (((compress = GetByte()) == VAR) && (g_usDataType & HEAP_IN)) { + getData = 1; + g_usDataType &= ~(HEAP_IN); + compress = GetByte(); + } + + switch (compress) { + case 0x00: + /* No compression */ + compression = 0; + break; + case 0x01: + /* Compress by byte 0x00 */ + compr_char = 0x00; + break; + case 0x02: + /* Compress by byte 0xFF */ + compr_char = 0xFF; + break; + case 0xFF: + /* Huffman encoding */ + compr_char = GetByte(); + i = 8; + for (index = 0; index < size; index++) { + ByteData[index] = 0x00; + if (i > 7) { + cDataByte = GetByte(); + i = 0; + } + if ((cDataByte << i++) & 0x80) + m = 8; + else { + ByteData[index] = compr_char; + m = 0; + } + + for (j = 0; j < m; j++) { + if (i > 7) { + cDataByte = GetByte(); + i = 0; + } + ByteData[index] |= ((cDataByte << i++) & 0x80) >> j; + } + } + size = 0; + break; + default: + for (index = 0; index < size; index++) + ByteData[index] = 0x00; + for (index = 0; index < compress; index++) { + if (index % 2 == 0) + cDataByte = GetByte(); + for (i = 0; i < size * 2 / compress; i++) { + //09/11/07 NN Type cast mismatch variables + j = (unsigned short)(index + (i * (unsigned short)compress)); + /*clear the nibble to zero first*/ + if (j % 2) { + if (index % 2) + ByteData[j / 2] |= cDataByte & 0x0F; + else + ByteData[j / 2] |= cDataByte >> 4; + } else { + if (index % 2) + ByteData[j / 2] |= cDataByte << 4; + else + ByteData[j / 2] |= cDataByte & 0xF0; + } + } + } + size = 0; + break; + } + } + + FFcount = 0; + + /* Decompress by byte 0x00 or 0xFF */ + for (index = 0; index < size; index++) { + if (FFcount <= 0) { + cDataByte = GetByte(); + if ((cDataByte == VAR) && (g_usDataType & HEAP_IN) && !getData && !(g_usDataType & COMPRESS)) { + getData = 1; + g_usDataType &= ~(HEAP_IN); + cDataByte = GetByte(); + } + ByteData[index] = cDataByte; + if ((compression) && (cDataByte == compr_char)) /*decompression is on*/ + //09/11/07 NN Type cast mismatch variables + FFcount = (unsigned short)ispVMDataSize(); /*The number of 0xFF or 0x00 bytes*/ + } else { + FFcount--; /*Use up the 0xFF chain first*/ + ByteData[index] = compr_char; + } + } + + if (getData) { + g_usDataType |= HEAP_IN; + getData = 0; + } +} + +/*************************************************************** +* +* ispVMShift +* +* Processes the SDR/XSDR/SIR commands. +* +***************************************************************/ + +signed char ispVMShift(signed char a_cCode) +{ + //09/11/07 NN added local variables initialization + unsigned short iDataIndex = 0; + unsigned short iReadLoop = 0; + signed char cRetCode = 0; + + cRetCode = 0; + //09/11/07 NN Type cast mismatch variables + g_usiDataSize = (unsigned short)ispVMDataSize(); + + g_usDataType &= ~(SIR_DATA + EXPRESS + SDR_DATA); /*clear the flags first*/ + + switch (a_cCode) { + case SIR: + g_usDataType |= SIR_DATA; + /* 1/15/04 If performing cascading, then go directly to SHIFTIR. Else, + go to IRPAUSE before going to SHIFTIR */ + if (g_usFlowControl & CASCADE) { + ispVMStateMachine(SHIFTIR); + } else { + ispVMStateMachine(IRPAUSE); + ispVMStateMachine(SHIFTIR); + if (g_usHeadIR > 0) { + ispVMBypass(HIR, g_usHeadIR); + sclock(); + } + } + break; + case XSDR: + g_usDataType |= EXPRESS; /*mark simultaneous in and out*/ + case SDR: + g_usDataType |= SDR_DATA; + /* 1/15/04 If already in SHIFTDR, then do not move state or shift in header. + This would imply that the previously shifted frame was a cascaded frame. */ + if (g_cCurrentJTAGState != SHIFTDR) { + /* 1/15/04 If performing cascading, then go directly to SHIFTDR. Else, + go to DRPAUSE before going to SHIFTDR */ + if (g_usFlowControl & CASCADE) { + if (g_cCurrentJTAGState == DRPAUSE) { + ispVMStateMachine(SHIFTDR); + /* 1/15/04 If cascade flag has been set and the current state is + DRPAUSE, this implies that the first cascaded frame is about to + be shifted in. The header must be shifted prior to shifting + the first cascaded frame. */ + if (g_usHeadDR > 0) { + ispVMBypass(HDR, g_usHeadDR); + sclock(); + } + } else { + ispVMStateMachine(SHIFTDR); + } + } else { + ispVMStateMachine(DRPAUSE); + ispVMStateMachine(SHIFTDR); + if (g_usHeadDR > 0) { + ispVMBypass(HDR, g_usHeadDR); + sclock(); + } + } + } + break; + default: + return (VME_INVALID_FILE); + } + + cRetCode = ispVMDataCode(); + if (cRetCode != 0) { + return (VME_INVALID_FILE); + } + +#ifdef VME_DEBUG + if (g_usDataType & TDI_DATA) { + printf("\n\t\tTDI "); + PrintData(g_usiDataSize, g_pucInData); + } + + if (g_usDataType & TDO_DATA) { + printf("\n\t\tTDO "); + PrintData(g_usiDataSize, g_pucOutData); + } + + if (g_usDataType & MASK_DATA) { + printf("\n\t\tMASK "); + PrintData(g_usiDataSize, g_pucOutMaskData); + } + + if (g_usDataType & DMASK_DATA) { + printf("\n\t\tDMASK "); + PrintData(g_usiDataSize, g_pucOutDMaskData); + } + + printf(";\n"); +#endif //VME_DEBUG + if (g_usDataType & TDO_DATA || g_usDataType & DMASK_DATA) { + if (g_usDataType & DMASK_DATA) { + + cRetCode = ispVMReadandSave(g_usiDataSize); + + if (!cRetCode) { + if (g_usTailDR > 0) { + sclock(); + ispVMBypass(TDR, g_usTailDR); + } + ispVMStateMachine(DRPAUSE); + ispVMStateMachine(SHIFTDR); + if (g_usHeadDR > 0) { + ispVMBypass(HDR, g_usHeadDR); + sclock(); + } + for (iDataIndex = 0; iDataIndex < g_usiDataSize / 8 + 1; iDataIndex++) + g_pucInData[iDataIndex] = g_pucOutData[iDataIndex]; + g_usDataType &= ~(TDO_DATA + DMASK_DATA); + cRetCode = ispVMSend(g_usiDataSize); + } + } else { + + cRetCode = ispVMRead(g_usiDataSize); + if (cRetCode == -1 && g_cVendor == XILINX) { + for (iReadLoop = 0; iReadLoop < 30; iReadLoop++) { + cRetCode = ispVMRead(g_usiDataSize); + if (!cRetCode) { + break; + } else { + ispVMStateMachine(DRPAUSE); /*Always DRPAUSE*/ + /*Bypass other devices when appropriate*/ + ispVMBypass(TDR, g_usTailDR); + ispVMStateMachine(g_ucEndDR); + ispVMStateMachine(IDLE); + ispVMDelay(1000); + } + } + } + } + } else { /*TDI only*/ + cRetCode = ispVMSend(g_usiDataSize); + + } + + /*transfer the input data to the output buffer for the next verify*/ + if ((g_usDataType & EXPRESS) || (a_cCode == SDR)) { + if (g_pucOutData) { + for (iDataIndex = 0; iDataIndex < g_usiDataSize / 8 + 1; iDataIndex++) + g_pucOutData[iDataIndex] = g_pucInData[iDataIndex]; + } + } + + switch (a_cCode) { + case SIR: + /* 1/15/04 If not performing cascading, then shift ENDIR */ + if (!(g_usFlowControl & CASCADE)) { + if (g_usTailIR > 0) { + sclock(); + ispVMBypass(TIR, g_usTailIR); + } + ispVMStateMachine(g_ucEndIR); + } + break; + case XSDR: + case SDR: + /* 1/15/04 If not performing cascading, then shift ENDDR */ + if (!(g_usFlowControl & CASCADE)) { + if (g_usTailDR > 0) { + sclock(); + ispVMBypass(TDR, g_usTailDR); + } + ispVMStateMachine(g_ucEndDR); + } + break; + default: + break; + } + + return (cRetCode); +} + +/*************************************************************** +* +* ispVMAmble +* +* This routine is to extract Header and Trailer parameter for SIR and +* SDR operations. +* +* The Header and Trailer parameter are the pre-amble and post-amble bit +* stream need to be shifted into TDI or out of TDO of the devices. Mostly +* is for the purpose of bypassing the leading or trailing devices. ispVM +* supports only shifting data into TDI to bypass the devices. +* +* For a single device, the header and trailer parameters are all set to 0 +* as default by ispVM. If it is for multiple devices, the header and trailer +* value will change as specified by the VME file. +* +***************************************************************/ + +signed char ispVMAmble(signed char Code) +{ + signed char compress = 0; + //09/11/07 NN Type cast mismatch variables + g_usiDataSize = (unsigned short)ispVMDataSize(); + +#ifdef VME_DEBUG + printf("%d", g_usiDataSize); +#endif //VME_DEBUG + + if (g_usiDataSize) { + + /**************************************************************************** + * + * Discard the TDI byte and set the compression bit in the data type register + * to false if compression is set because TDI data after HIR/HDR/TIR/TDR is not + * compressed. + * + *****************************************************************************/ + + GetByte(); + if (g_usDataType & COMPRESS) { + g_usDataType &= ~(COMPRESS); + compress = 1; + } + } + + switch (Code) { + case HIR: + + /**************************************************************************** + * + * Store the maximum size of the HIR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usHIRSize) { + g_usHIRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the HIR value and allocate memory. + * + *****************************************************************************/ + + g_usHeadIR = g_usiDataSize; + if (g_usHeadIR) { + ispVMMemManager(HIR, g_usHeadIR); + ispVMData(g_pucHIRData); + +#ifdef VME_DEBUG + printf(" TDI "); + PrintData(g_usHeadIR, g_pucHIRData); +#endif //VME_DEBUG + } + break; + case TIR: + + /**************************************************************************** + * + * Store the maximum size of the TIR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTIRSize) { + g_usTIRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the TIR value and allocate memory. + * + *****************************************************************************/ + + g_usTailIR = g_usiDataSize; + if (g_usTailIR) { + ispVMMemManager(TIR, g_usTailIR); + ispVMData(g_pucTIRData); + +#ifdef VME_DEBUG + printf(" TDI "); + PrintData(g_usTailIR, g_pucTIRData); +#endif //VME_DEBUG + } + break; + case HDR: + + /**************************************************************************** + * + * Store the maximum size of the HDR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usHDRSize) { + g_usHDRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the HDR value and allocate memory. + * + *****************************************************************************/ + + g_usHeadDR = g_usiDataSize; + if (g_usHeadDR) { + ispVMMemManager(HDR, g_usHeadDR); + ispVMData(g_pucHDRData); + +#ifdef VME_DEBUG + printf(" TDI "); + PrintData(g_usHeadDR, g_pucHDRData); +#endif //VME_DEBUG + } + break; + case TDR: + + /**************************************************************************** + * + * Store the maximum size of the TDR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usiDataSize > g_usTDRSize) { + g_usTDRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the TDR value and allocate memory. + * + *****************************************************************************/ + + g_usTailDR = g_usiDataSize; + if (g_usTailDR) { + ispVMMemManager(TDR, g_usTailDR); + ispVMData(g_pucTDRData); + +#ifdef VME_DEBUG + printf(" TDI "); + PrintData(g_usTailDR, g_pucTDRData); +#endif //VME_DEBUG + } + break; + default: + break; + } + + /**************************************************************************** + * + * Re-enable compression if it was previously set. + * + *****************************************************************************/ + + if (compress) { + g_usDataType |= COMPRESS; + } + + if (g_usiDataSize) { + Code = GetByte(); + if (Code == CONTINUE) { + return 0; + } else { + + /**************************************************************************** + * + * Encountered invalid opcode. + * + *****************************************************************************/ + + return VME_INVALID_FILE; + } + } + + return 0; +} + +/*************************************************************** +* +* ispVMLoop +* +* Perform the function call upon by the REPEAT opcode. +* Memory is to be allocated to store the entire loop from REPEAT to ENDLOOP. +* After the loop is stored then execution begin. The REPEATLOOP flag is set +* on the g_usFlowControl register to indicate the repeat loop is in session +* and therefore fetch opcode from the memory instead of from the file. +* +***************************************************************/ + +signed char ispVMLoop(unsigned short a_usLoopCount) +{ + //09/11/07 NN added local variables initialization + signed char cRetCode = 0; + unsigned short iHeapIndex = 0; + unsigned short iLoopIndex = 0; + + g_usShiftValue = 0; + for (iHeapIndex = 0; iHeapIndex < g_iHEAPSize; iHeapIndex++) { + g_pucHeapMemory[iHeapIndex] = GetByte(); + } + + if (g_pucHeapMemory[iHeapIndex - 1] != ENDLOOP) { + return (VME_INVALID_FILE); + } + + g_usFlowControl |= REPEATLOOP; + g_usDataType |= HEAP_IN; + + for (iLoopIndex = 0; iLoopIndex < a_usLoopCount; iLoopIndex++) { + g_iHeapCounter = 0; + cRetCode = ispVMCode(); + g_usRepeatLoops++; + if (cRetCode < 0) { + break; + } + } + + g_usDataType &= ~(HEAP_IN); + g_usFlowControl &= ~(REPEATLOOP); + return (cRetCode); +} + +/*************************************************************** +* +* ispVMBitShift +* +* Shift the TDI stream left or right by the number of bits. The data in +* *g_pucInData is of the VME format, so the actual shifting is the reverse of +* IEEE 1532 or SVF format. +* +***************************************************************/ + +signed char ispVMBitShift(signed char mode, unsigned short bits) +{ + //09/11/07 NN added local variables initialization + unsigned short i = 0; + unsigned short size = 0; + unsigned short tmpbits = 0; + + if (g_usiDataSize % 8 > 0) { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize / 8 + 1); + } else { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize / 8); + } + + switch (mode) { + case SHR: + for (i = 0; i < size; i++) { + if (g_pucInData[i] != 0) { + tmpbits = bits; + while (tmpbits > 0) { + g_pucInData[i] <<= 1; + if (g_pucInData[i] == 0) { + i--; + g_pucInData[i] = 1; + } + tmpbits--; + } + } + } + break; + case SHL: + for (i = 0; i < size; i++) { + if (g_pucInData[i] != 0) { + tmpbits = bits; + while (tmpbits > 0) { + g_pucInData[i] >>= 1; + if (g_pucInData[i] == 0) { + i--; + g_pucInData[i] = 8; + } + tmpbits--; + } + } + } + break; + default: + return (VME_INVALID_FILE); + } + + return (0); +} + +/*************************************************************** +* +* ispVMComment +* +* Displays the SVF comments. +* +***************************************************************/ + +void ispVMComment(unsigned short a_usCommentSize) +{ + char cCurByte = 0; + for (; a_usCommentSize > 0; a_usCommentSize--) { + /**************************************************************************** + * + * Print character to the terminal. + * + *****************************************************************************/ + cCurByte = GetByte(); + vme_out_char(cCurByte); + } + cCurByte = '\n'; + vme_out_char(cCurByte); +} + +/*************************************************************** +* +* ispVMHeader +* +* Iterate the length of the header and discard it. +* +***************************************************************/ + +void ispVMHeader(unsigned short a_usHeaderSize) +{ + for (; a_usHeaderSize > 0; a_usHeaderSize--) { + GetByte(); + } +} + +/*************************************************************** +* +* ispVMCalculateCRC32 +* +* Calculate the 32-bit CRC. +* +***************************************************************/ + +void ispVMCalculateCRC32(unsigned char a_ucData) +{ + //09/11/07 NN added local variables initialization + unsigned char ucIndex = 0; + unsigned char ucFlipData = 0; + unsigned short usCRCTableEntry = 0; + unsigned int crc_table[16] = { + 0x0000, 0xCC01, 0xD801, + 0x1400, 0xF001, 0x3C00, + 0x2800, 0xE401, 0xA001, + 0x6C00, 0x7800, 0xB401, + 0x5000, 0x9C01, 0x8801, + 0x4400 + }; + + for (ucIndex = 0; ucIndex < 8; ucIndex++) { + ucFlipData <<= 1; + if (a_ucData & 0x01) { + ucFlipData |= 0x01; + } + a_ucData >>= 1; + } + + //09/11/07 NN Type cast mismatch variables + usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]); + g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF); + g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ usCRCTableEntry ^ crc_table[ucFlipData & 0xF]); + usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]); + g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF); + g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ usCRCTableEntry ^ crc_table[(ucFlipData >> 4) & 0xF]); +} + +/*************************************************************** +* +* ispVMLCOUNT +* +* Process the intelligent programming loops. +* +***************************************************************/ + +signed char ispVMLCOUNT(unsigned short a_usCountSize) +{ + unsigned short usContinue = 1; + unsigned short usIntelBufferIndex = 0; + unsigned short usCountIndex = 0; + signed char cRetCode = 0; + signed char cRepeatHeap = 0; + signed char cOpcode = 0; + unsigned char ucState = 0; + unsigned short usDelay = 0; + unsigned short usToggle = 0; + + g_usIntelBufferSize = (unsigned short)ispVMDataSize(); + + /**************************************************************************** + * + * Allocate memory for intel buffer. + * + *****************************************************************************/ + + ispVMMemManager(LHEAP, g_usIntelBufferSize); + + /**************************************************************************** + * + * Store the maximum size of the intelligent buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if (g_usIntelBufferSize > g_usLCOUNTSize) { + g_usLCOUNTSize = g_usIntelBufferSize; + } + + /**************************************************************************** + * + * Copy intel data to the buffer. + * + *****************************************************************************/ + + for (usIntelBufferIndex = 0; usIntelBufferIndex < g_usIntelBufferSize; usIntelBufferIndex++) { + g_pucIntelBuffer[usIntelBufferIndex] = GetByte(); + } + + /**************************************************************************** + * + * Set the data type register to get data from the intelligent data buffer. + * + *****************************************************************************/ + + g_usDataType |= LHEAP_IN; + + /**************************************************************************** + * + * If the HEAP_IN flag is set, temporarily unset the flag so data will be + * retrieved from the status buffer. + * + *****************************************************************************/ + + if (g_usDataType & HEAP_IN) { + g_usDataType &= ~HEAP_IN; + cRepeatHeap = 1; + } + +#ifdef VME_DEBUG + printf("LCOUNT %d;\n", a_usCountSize); +#endif //VME_DEBUG + + /**************************************************************************** + * + * Iterate through the intelligent programming command. + * + *****************************************************************************/ + + for (usCountIndex = 0; usCountIndex < a_usCountSize; usCountIndex++) { + + /**************************************************************************** + * + * Initialize the intel data index to 0 before each iteration. + * + *****************************************************************************/ + + g_usIntelDataIndex = 0; + cOpcode = 0; + ucState = 0; + usDelay = 0; + usToggle = 0; + usContinue = 1; + + /*************************************************************** + * + * Begin looping through all the VME opcodes. + * + ***************************************************************/ + /*************************************************************** + * 4/1/09 Nguyen replaced the recursive function call codes on + * the ispVMLCOUNT function + * + ***************************************************************/ + while (usContinue) { + cOpcode = GetByte(); + switch (cOpcode) { + case HIR: + case TIR: + case HDR: + case TDR: + /*************************************************************** + * + * Set the header/trailer of the device in order to bypass + * successfully. + * + ***************************************************************/ + + ispVMAmble(cOpcode); + break; + case STATE: + + /*************************************************************** + * + * Step the JTAG state machine. + * + ***************************************************************/ + + ucState = GetByte(); + /*************************************************************** + * + * Step the JTAG state machine to DRCAPTURE to support Looping. + * + ***************************************************************/ + + if ((g_usDataType & LHEAP_IN) && + (ucState == DRPAUSE) && + (g_cCurrentJTAGState == ucState)) { + ispVMStateMachine(DRCAPTURE); + } + ispVMStateMachine(ucState); +#ifdef VME_DEBUG + printf("LDELAY %s ", GetState(ucState)); +#endif //VME_DEBUG + break; + case SIR: +#ifdef VME_DEBUG + printf("SIR "); +#endif //VME_DEBUG + /*************************************************************** + * + * Shift in data into the device. + * + ***************************************************************/ + + cRetCode = ispVMShift(cOpcode); + break; + case SDR: + +#ifdef VME_DEBUG + printf("LSDR "); +#endif //VME_DEBUG + /*************************************************************** + * + * Shift in data into the device. + * + ***************************************************************/ + + cRetCode = ispVMShift(cOpcode); + break; + case WAIT: + + /*************************************************************** + * + * Observe delay. + * + ***************************************************************/ + + usDelay = (unsigned short)ispVMDataSize(); + ispVMDelay(usDelay); + +#ifdef VME_DEBUG + if (usDelay & 0x8000) { + + /*************************************************************** + * + * Since MSB is set, the delay time must be decoded to + * millisecond. The SVF2VME encodes the MSB to represent + * millisecond. + * + ***************************************************************/ + + usDelay &= ~0x8000; + printf("%.2E SEC;\n", (float)usDelay / 1000); + } else { + + /*************************************************************** + * + * Since MSB is not set, the delay time is given as microseconds. + * + ***************************************************************/ + + printf("%.2E SEC;\n", (float)usDelay / 1000000); + } +#endif //VME_DEBUG + break; + case TCK: + + /*************************************************************** + * + * Issue clock toggles. + * + ***************************************************************/ + + usToggle = (unsigned short)ispVMDataSize(); + ispVMClocks(usToggle); + +#ifdef VME_DEBUG + printf("RUNTEST %d TCK;\n", usToggle); +#endif //VME_DEBUG + break; + case ENDLOOP: + + /*************************************************************** + * + * Exit point from processing loops. + * + ***************************************************************/ + usContinue = 0; + break; + + case COMMENT: + + /*************************************************************** + * + * Display comment. + * + ***************************************************************/ + + ispVMComment((unsigned short)ispVMDataSize()); + break; + case ispEN: + ucState = GetByte(); + if ((ucState == ON) || (ucState == 0x01)) + writePort(JTAG_ENABLE, 0x01); + else + writePort(JTAG_ENABLE, 0x00); + ispVMDelay(1); + break; + case TRST: + if (GetByte() == 0x01) + writePort(JTAG_TRST, 0x01); + else + writePort(JTAG_TRST, 0x00); + ispVMDelay(1); + break; + default: + + /*************************************************************** + * + * Invalid opcode encountered. + * + ***************************************************************/ + +#ifdef VME_DEBUG + printf("\nINVALID OPCODE: 0x%.2X\n", cOpcode); +#endif //VME_DEBUG + + return VME_INVALID_FILE; + } + } + if (cRetCode >= 0) { + /**************************************************************************** + * + * Break if intelligent programming is successful. + * + *****************************************************************************/ + + break; + } + + } + /**************************************************************************** + * + * If HEAP_IN flag was temporarily disabled, re-enable it before exiting. + * + *****************************************************************************/ + + if (cRepeatHeap) { + g_usDataType |= HEAP_IN; + } + + /**************************************************************************** + * + * Set the data type register to not get data from the intelligent data buffer. + * + *****************************************************************************/ + + g_usDataType &= ~LHEAP_IN; + return cRetCode; +} + +/*************************************************************** +* +* ispVMClocks +* +* Applies the specified number of pulses to TCK. +* +***************************************************************/ + +void ispVMClocks(unsigned short Clocks) +{ + unsigned short iClockIndex = 0; + for (iClockIndex = 0; iClockIndex < Clocks; iClockIndex++) { + sclock(); + } +} + +/*************************************************************** +* +* ispVMBypass +* +* This procedure takes care of the HIR, HDR, TIR, TDR for the +* purpose of putting the other devices into Bypass mode. The +* current state is checked to find out if it is at DRPAUSE or +* IRPAUSE. If it is at DRPAUSE, perform bypass register scan. +* If it is at IRPAUSE, scan into instruction registers the bypass +* instruction. +* +***************************************************************/ + +void ispVMBypass(signed char ScanType, unsigned short Bits) +{ + //09/11/07 NN added local variables initialization + unsigned short iIndex = 0; + unsigned short iSourceIndex = 0; + unsigned char cBitState = 0; + unsigned char cCurByte = 0; + unsigned char *pcSource = NULL; + + if (Bits <= 0) { + return; + } + + switch (ScanType) { + case HIR: + pcSource = g_pucHIRData; + break; + case TIR: + pcSource = g_pucTIRData; + break; + case HDR: + pcSource = g_pucHDRData; + break; + case TDR: + pcSource = g_pucTDRData; + break; + default: + break; + } + if (pcSource) { + iSourceIndex = 0; + cBitState = 0; + for (iIndex = 0; iIndex < Bits - 1; iIndex++) { + /* Scan instruction or bypass register */ + if (iIndex % 8 == 0) { + cCurByte = pcSource[iSourceIndex++]; + } + cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00); + writePort(JTAG_TDI, cBitState); + sclock(); + } + + if (iIndex % 8 == 0) { + cCurByte = pcSource[iSourceIndex++]; + } + + cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00); + writePort(JTAG_TDI, cBitState); + } +} + +/*************************************************************** +* +* ispVMStateMachine +* +* This procedure steps all devices in the daisy chain from a given +* JTAG state to the next desirable state. If the next state is TLR, +* the JTAG state machine is brute forced into TLR by driving TMS +* high and pulse TCK 6 times. +* +***************************************************************/ + +void ispVMStateMachine(signed char cNextJTAGState) +{ + //09/11/07 NN added local variables initialization + signed char cPathIndex = 0; + signed char cStateIndex = 0; + short int found = 0; + + if ((g_cCurrentJTAGState == cNextJTAGState) && (cNextJTAGState != RESET)) { + return; + } + + for (cStateIndex = 0; cStateIndex < 25; cStateIndex++) { + if ((g_cCurrentJTAGState == g_JTAGTransistions[cStateIndex].CurState) && (cNextJTAGState == g_JTAGTransistions[cStateIndex].NextState)) { + found = 1; + break; + } + } + if (found) { + g_cCurrentJTAGState = cNextJTAGState; + for (cPathIndex = 0; cPathIndex < g_JTAGTransistions[cStateIndex].Pulses; cPathIndex++) { + if ((g_JTAGTransistions[cStateIndex].Pattern << cPathIndex) & 0x80) { + writePort(JTAG_TMS, (unsigned char)0x01); + } else { + writePort(JTAG_TMS, (unsigned char)0x00); + } + sclock(); + } + + writePort(JTAG_TDI, 0x00); + writePort(JTAG_TMS, 0x00); + } +} + +/*************************************************************** +* +* ispVMStart +* +* Enable the port to the device and set the state to RESET (TLR). +* +***************************************************************/ + +void ispVMStart() +{ +#ifdef VME_DEBUG + printf("// ISPVM EMBEDDED ADDED\n"); + printf("STATE RESET;\n"); +#endif + + ispVMStateMachine(RESET); /*step devices to RESET state*/ + +} + +/*************************************************************** +* +* ispVMEnd +* +* Set the state of devices to RESET to enable the devices and disable +* the port. +* +***************************************************************/ + +void ispVMEnd() +{ +#ifdef VME_DEBUG + printf("// ISPVM EMBEDDED ADDED\n"); + printf("STATE RESET;\n"); + printf("RUNTEST 1.00E-001 SEC;\n"); +#endif + + ispVMStateMachine(RESET); /*step devices to RESET state */ + ispVMDelay(1000); /*wake up devices*/ +} + +/*************************************************************** +* +* ispVMSend +* +* Send the TDI data stream to devices. The data stream can be +* instructions or data. +* +***************************************************************/ + +signed char ispVMSend(unsigned short a_usiDataSize) +{ + //09/11/07 NN added local variables initialization + unsigned short iIndex = 0; + unsigned short iInDataIndex = 0; + unsigned char cCurByte = 0; + unsigned char cBitState = 0; + + for (iIndex = 0; iIndex < a_usiDataSize - 1; iIndex++) { + if (iIndex % 8 == 0) { + cCurByte = g_pucInData[iInDataIndex++]; + } + cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00); + writePort(JTAG_TDI, cBitState); + sclock(); + } + + if (iIndex % 8 == 0) { + /* Take care of the last bit */ + cCurByte = g_pucInData[iInDataIndex]; + } + + cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00); + + writePort(JTAG_TDI, cBitState); + if (g_usFlowControl & CASCADE) { + /* 1/15/04 Clock in last bit for the first n-1 cascaded frames */ + sclock(); + } + + return 0; +} + +/*************************************************************** +* +* ispVMRead +* +* Read the data stream from devices and verify. +* +***************************************************************/ + +signed char ispVMRead(unsigned short a_usiDataSize) //32 +{ + //09/11/07 NN added local variables initialization + unsigned short usDataSizeIndex = 0; + unsigned short usErrorCount = 0; + unsigned short usLastBitIndex = 0; + unsigned char cDataByte = 0; + unsigned char cMaskByte = 0; + unsigned char cInDataByte = 0; + unsigned char cCurBit = 0; + unsigned char cByteIndex = 0; + unsigned short usBufferIndex = 0; + unsigned char ucDisplayByte = 0x00; + unsigned char ucDisplayFlag = 0x01; + char StrChecksum[256] = { 0 }; + unsigned char g_usCalculateChecksum = 0x00; + + //09/11/07 NN Type cast mismatch variables + usLastBitIndex = (unsigned short)(a_usiDataSize - 1); + + /**************************************************************************** + * + * If mask is not all zeros, then set the display flag to 0x00, otherwise + * it shall be set to 0x01 to indicate that data read from the device shall + * be displayed. If VME_DEBUG is defined, always display data. + * + *****************************************************************************/ + + for (usDataSizeIndex = 0; usDataSizeIndex < (a_usiDataSize + 7) / 8; usDataSizeIndex++) { + + if (g_usDataType & MASK_DATA) { + if (g_pucOutMaskData[usDataSizeIndex] != 0x00) { + ucDisplayFlag = 0x00; + break; + } + } else if (g_usDataType & CMASK_DATA) { + g_usCalculateChecksum = 0x01; + ucDisplayFlag = 0x00; + break; + } else { + ucDisplayFlag = 0x00; + break; + } + } + + /**************************************************************************** + * + * Begin shifting data in and out of the device. + * + *****************************************************************************/ + for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; usDataSizeIndex++) { + if (cByteIndex == 0) { + + /*************************************************************** + * + * Grab byte from TDO buffer. + * + ***************************************************************/ + + if (g_usDataType & TDO_DATA) { + cDataByte = g_pucOutData[usBufferIndex]; + } + + /*************************************************************** + * + * Grab byte from MASK buffer. + * + ***************************************************************/ + + if (g_usDataType & MASK_DATA) { + cMaskByte = g_pucOutMaskData[usBufferIndex]; + } else { + cMaskByte = 0xFF; + } + + /*************************************************************** + * + * Grab byte from CMASK buffer. + * + ***************************************************************/ + + if (g_usDataType & CMASK_DATA) { + cMaskByte = 0x00; + g_usCalculateChecksum = 0x01; + } + + /*************************************************************** + * + * Grab byte from TDI buffer. + * + ***************************************************************/ + + if (g_usDataType & TDI_DATA) { + cInDataByte = g_pucInData[usBufferIndex]; + } + + usBufferIndex++; + } + + cCurBit = readPort(); + + if (ucDisplayFlag) { + ucDisplayByte <<= 1; + ucDisplayByte |= cCurBit; + } + + /**************************************************************************** + * + * Check if data read from port matches with expected TDO. + * + *****************************************************************************/ + + if (g_usDataType & TDO_DATA) { + //08/28/08 NN Added Calculate checksum support. + if (g_usCalculateChecksum) { + if (cCurBit == 0x01) + g_usChecksum += (1 << (g_uiChecksumIndex % 8)); + g_uiChecksumIndex++; + } else { + if ((((cMaskByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) { + if (cCurBit != (unsigned char)(((cDataByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) { + usErrorCount++; + } + } + } + } + + /**************************************************************************** + * + * Write TDI data to the port. + * + *****************************************************************************/ + + writePort(JTAG_TDI, (unsigned char)(((cInDataByte << cByteIndex) & 0x80) ? 0x01 : 0x00)); + + if (usDataSizeIndex < usLastBitIndex) { + + /**************************************************************************** + * + * Clock data out from the data shift register. + * + *****************************************************************************/ + + sclock(); + } else if (g_usFlowControl & CASCADE) { + + /**************************************************************************** + * + * Clock in last bit for the first N - 1 cascaded frames. + * + *****************************************************************************/ + + sclock(); + } + + /*************************************************************** + * + * Increment the byte index. If it exceeds 7, then reset it back + * to zero. + * + ***************************************************************/ + + cByteIndex++; + if (cByteIndex >= 8) { + if (ucDisplayFlag) { + + /*************************************************************** + * + * Store displayed data in the TDO buffer. By reusing the TDO + * buffer to store displayed data, there is no need to allocate + * a buffer simply to hold display data. This will not cause any + * false verification errors because the true TDO byte has already + * been consumed. + * + ***************************************************************/ + + g_pucOutData[usBufferIndex - 1] = ucDisplayByte; + ucDisplayByte = 0; + } + + cByteIndex = 0; + } + //09/12/07 Nguyen changed to display the 1 bit expected data + else if (a_usiDataSize == 1) { + if (ucDisplayFlag) { + + /*************************************************************** + * + * Store displayed data in the TDO buffer. By reusing the TDO + * buffer to store displayed data, there is no need to allocate + * a buffer simply to hold display data. This will not cause any + * false verification errors because the true TDO byte has already + * been consumed. + * + ***************************************************************/ + + /**************************************************************************** + * + * Flip ucDisplayByte and store it in cDataByte. + * + *****************************************************************************/ + cDataByte = 0x00; + for (usBufferIndex = 0; usBufferIndex < 8; usBufferIndex++) { + cDataByte <<= 1; + if (ucDisplayByte & 0x01) { + cDataByte |= 0x01; + } + ucDisplayByte >>= 1; + } + g_pucOutData[0] = cDataByte; + ucDisplayByte = 0; + } + + cByteIndex = 0; + } + } + if (ucDisplayFlag) { + + /**************************************************************************** + * + * Display data read from the device. + * + *****************************************************************************/ + +#ifdef VME_DEBUG + printf("RECIEVED TDO ("); +#else + vme_out_string("Display Data: 0x"); +#endif //VME_DEBUG + + //09/11/07 NN Type cast mismatch variables + for (usDataSizeIndex = (unsigned short)((a_usiDataSize + 7) / 8); usDataSizeIndex > 0; usDataSizeIndex--) { + cMaskByte = g_pucOutData[usDataSizeIndex - 1]; + cDataByte = 0x00; + + /**************************************************************************** + * + * Flip cMaskByte and store it in cDataByte. + * + *****************************************************************************/ + + for (usBufferIndex = 0; usBufferIndex < 8; usBufferIndex++) { + cDataByte <<= 1; + if (cMaskByte & 0x01) { + cDataByte |= 0x01; + } + cMaskByte >>= 1; + } +#ifdef VME_DEBUG + printf("%.2X", cDataByte); + if ((((a_usiDataSize + 7) / 8) - usDataSizeIndex) % 40 == 39) { + printf("\n\t\t"); + } +#else + vme_out_hex(cDataByte); +#endif //VME_DEBUG + } + +#ifdef VME_DEBUG + printf(")\n\n"); +#else + vme_out_string("\n\n"); +#endif //VME_DEBUG + //09/02/08 Nguyen changed to display the data Checksum + vme_out_string("g_usChecksum:"); + sprintf(StrChecksum, "%.4X\n\n", (unsigned int)g_usChecksum); + vme_out_string(StrChecksum); + vme_out_string("\n\n"); + if (g_usChecksum != 0) { + g_usChecksum &= 0xFFFF; + sprintf(StrChecksum, "Data Checksum: %.4X\n\n", (unsigned int)g_usChecksum); + vme_out_string(StrChecksum); + g_usChecksum = 0; + } + } + + if (usErrorCount > 0) { + + if (g_usFlowControl & VERIFYUES) { + vme_out_string("USERCODE verification failed. Continue programming......\n\n"); + g_usFlowControl &= ~(VERIFYUES); + return 0; + } else { + +#ifdef VME_DEBUG + printf("TOTAL ERRORS: %d\n", usErrorCount); +#endif //VME_DEBUG + + return VME_VERIFICATION_FAILURE; + } + } else { + if (g_usFlowControl & VERIFYUES) { + vme_out_string("USERCODE verification passed. Programming aborted. \n\n"); + g_usFlowControl &= ~(VERIFYUES); + return 1; + } else { + return 0; + } + } +} + +/*************************************************************** +* +* ispVMReadandSave +* +* Support dynamic I/O. +* +***************************************************************/ + +signed char ispVMReadandSave(unsigned short int a_usiDataSize) +{ + //09/11/07 NN added local variables initialization + unsigned short int usDataSizeIndex = 0; + unsigned short int usLastBitIndex = 0; + unsigned short int usBufferIndex = 0; + unsigned short int usOutBitIndex = 0; + unsigned short int usLVDSIndex = 0; + unsigned char cDataByte = 0; + unsigned char cDMASKByte = 0; + unsigned char cInDataByte = 0; + unsigned char cCurBit = 0; + unsigned char cByteIndex = 0; + signed char cLVDSByteIndex = 0; + + //09/11/07 NN Type cast mismatch variables + usLastBitIndex = (unsigned short)(a_usiDataSize - 1); + + /*************************************************************** + * + * Iterate through the data bits. + * + ***************************************************************/ + + for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; usDataSizeIndex++) { + if (cByteIndex == 0) { + + /*************************************************************** + * + * Grab byte from DMASK buffer. + * + ***************************************************************/ + + if (g_usDataType & DMASK_DATA) { + cDMASKByte = g_pucOutDMaskData[usBufferIndex]; + } else { + cDMASKByte = 0x00; + } + + /*************************************************************** + * + * Grab byte from TDI buffer. + * + ***************************************************************/ + + if (g_usDataType & TDI_DATA) { + cInDataByte = g_pucInData[usBufferIndex]; + } + + usBufferIndex++; + } + + cCurBit = readPort(); + cDataByte = (unsigned char)(((cInDataByte << cByteIndex) & 0x80) ? 0x01 : 0x00); + + /*************************************************************** + * + * Initialize the byte to be zero. + * + ***************************************************************/ + + if (usOutBitIndex % 8 == 0) { + g_pucOutData[usOutBitIndex / 8] = 0x00; + } + + /*************************************************************** + * + * Use TDI, DMASK, and device TDO to create new TDI (actually + * stored in g_pucOutData). + * + ***************************************************************/ + + if ((((cDMASKByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) { + + if (g_pLVDSList) { + for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) { + if (g_pLVDSList[usLVDSIndex].usNegativeIndex == usDataSizeIndex) { + g_pLVDSList[usLVDSIndex].ucUpdate = 0x01; + break; + } + } + } + + /*************************************************************** + * + * DMASK bit is 1, use TDI. + * + ***************************************************************/ + + g_pucOutData[usOutBitIndex / 8] |= (unsigned char)(((cDataByte & 0x1) ? 0x01 : 0x00) << (7 - usOutBitIndex % 8)); + } else { + + /*************************************************************** + * + * DMASK bit is 0, use device TDO. + * + ***************************************************************/ + + g_pucOutData[usOutBitIndex / 8] |= (unsigned char)(((cCurBit & 0x1) ? 0x01 : 0x00) << (7 - usOutBitIndex % 8)); + } + + /*************************************************************** + * + * Shift in TDI in order to get TDO out. + * + ***************************************************************/ + + usOutBitIndex++; + writePort(JTAG_TDI, cDataByte); + if (usDataSizeIndex < usLastBitIndex) { + sclock(); + } + + /*************************************************************** + * + * Increment the byte index. If it exceeds 7, then reset it back + * to zero. + * + ***************************************************************/ + + cByteIndex++; + if (cByteIndex >= 8) { + cByteIndex = 0; + } + } + + /*************************************************************** + * + * If g_pLVDSList exists and pairs need updating, then update + * the negative-pair to receive the flipped positive-pair value. + * + ***************************************************************/ + + if (g_pLVDSList) { + for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) { + if (g_pLVDSList[usLVDSIndex].ucUpdate) { + + /*************************************************************** + * + * Read the positive value and flip it. + * + ***************************************************************/ + + cDataByte = (unsigned char)(((g_pucOutData[g_pLVDSList[usLVDSIndex].usPositiveIndex / 8] << (g_pLVDSList[usLVDSIndex].usPositiveIndex % 8)) & 0x80) ? 0x01 : 0x00); + //09/11/07 NN Type cast mismatch variables + cDataByte = (unsigned char)(!cDataByte); + + /*************************************************************** + * + * Get the byte that needs modification. + * + ***************************************************************/ + + cInDataByte = g_pucOutData[g_pLVDSList[usLVDSIndex].usNegativeIndex / 8]; + + if (cDataByte) { + + /*************************************************************** + * + * Copy over the current byte and set the negative bit to 1. + * + ***************************************************************/ + + cDataByte = 0x00; + for (cLVDSByteIndex = 7; cLVDSByteIndex >= 0; cLVDSByteIndex--) { + cDataByte <<= 1; + if (7 - (g_pLVDSList[usLVDSIndex].usNegativeIndex % 8) == cLVDSByteIndex) { + + /*************************************************************** + * + * Set negative bit to 1. + * + ***************************************************************/ + + cDataByte |= 0x01; + } else if (cInDataByte & 0x80) { + cDataByte |= 0x01; + } + + cInDataByte <<= 1; + } + + /*************************************************************** + * + * Store the modified byte. + * + ***************************************************************/ + + g_pucOutData[g_pLVDSList[usLVDSIndex].usNegativeIndex / 8] = cDataByte; + } else { + + /*************************************************************** + * + * Copy over the current byte and set the negative bit to 0. + * + ***************************************************************/ + + cDataByte = 0x00; + for (cLVDSByteIndex = 7; cLVDSByteIndex >= 0; cLVDSByteIndex--) { + cDataByte <<= 1; + if (7 - (g_pLVDSList[usLVDSIndex].usNegativeIndex % 8) == cLVDSByteIndex) { + + /*************************************************************** + * + * Set negative bit to 0. + * + ***************************************************************/ + + cDataByte |= 0x00; + } else if (cInDataByte & 0x80) { + cDataByte |= 0x01; + } + + cInDataByte <<= 1; + } + + /*************************************************************** + * + * Store the modified byte. + * + ***************************************************************/ + + g_pucOutData[g_pLVDSList[usLVDSIndex].usNegativeIndex / 8] = cDataByte; + } + + break; + } + } + } + + return (0); +} + +signed char ispVMProcessLVDS(unsigned short a_usLVDSCount) +{ + unsigned short usLVDSIndex = 0; + + /*************************************************************** + * + * Allocate memory to hold LVDS pairs. + * + ***************************************************************/ + + ispVMMemManager(LVDS, a_usLVDSCount); + g_usLVDSPairCount = a_usLVDSCount; + +#ifdef VME_DEBUG + printf("LVDS %d (", a_usLVDSCount); +#endif //VME_DEBUG + + /*************************************************************** + * + * Iterate through each given LVDS pair. + * + ***************************************************************/ + + for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) { + + /*************************************************************** + * + * Assign the positive and negative indices of the LVDS pair. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_pLVDSList[usLVDSIndex].usPositiveIndex = (unsigned short)ispVMDataSize(); + //09/11/07 NN Type cast mismatch variables + g_pLVDSList[usLVDSIndex].usNegativeIndex = (unsigned short)ispVMDataSize(); + +#ifdef VME_DEBUG + if (usLVDSIndex < g_usLVDSPairCount - 1) { + printf("%d:%d, ", g_pLVDSList[usLVDSIndex].usPositiveIndex, g_pLVDSList[usLVDSIndex].usNegativeIndex); + } else { + printf("%d:%d", g_pLVDSList[usLVDSIndex].usPositiveIndex, g_pLVDSList[usLVDSIndex].usNegativeIndex); + } +#endif //VME_DEBUG + + } + +#ifdef VME_DEBUG + printf(") -- %d;\n", a_usLVDSCount); +#endif //VME_DEBUG + + return (0); +} + +/*************************************************************** +* +* ivm_core_reinit +* +* Reinit ivm_core variables. +* +***************************************************************/ +void ivm_core_reinit() +{ + g_usFlowControl = 0x0000; + g_usDataType = 0x0000; + + g_ucEndDR = DRPAUSE; + g_ucEndIR = IRPAUSE; + + g_usHeadDR = 0; + g_usHeadIR = 0; + g_usTailDR = 0; + g_usTailIR = 0; + + g_usiDataSize = 0; + + g_iFrequency = 1000; + + g_usMaxSize = 0; + + g_usShiftValue = 0; + + g_usRepeatLoops = 0; + + g_cVendor = LATTICE; + + g_usCalculatedCRC = 0; + + g_usChecksum = 0; + g_uiChecksumIndex = 0; + + g_cCurrentJTAGState = 0; + + g_pucHeapMemory = NULL; + g_iHeapCounter = 0; + g_iHEAPSize = 0; + + g_usIntelDataIndex = 0; + g_usIntelBufferSize = 0; + + g_usTDOSize = 0; + g_usMASKSize = 0; + g_usTDISize = 0; + g_usDMASKSize = 0; + g_usLCOUNTSize = 0; + g_usHDRSize = 0; + g_usTDRSize = 0; + g_usHIRSize = 0; + g_usTIRSize = 0; + g_usHeapSize = 0; + + g_pucOutMaskData = NULL; + g_pucInData = NULL; + g_pucOutData = NULL; + g_pucHIRData = NULL; + g_pucTIRData = NULL; + g_pucHDRData = NULL; + g_pucTDRData = NULL; + g_pucIntelBuffer = NULL; + g_pucOutDMaskData = NULL; + + g_pLVDSList = NULL; + g_usLVDSPairCount = 0; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_isc/firmware_upgrade_isc.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_isc/firmware_upgrade_isc.c new file mode 100644 index 000000000000..c252dfde7c57 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_isc/firmware_upgrade_isc.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * firmware_upgrade_jtag + * function: Determine whether to upgrade ISC or JBI + * @fd: param[in] Device file descriptor + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_jtag(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + int ret; + cmd_info_t cmd_info; + + cmd_info.size = size; + cmd_info.data = buf; + ret = 0; + + if (info->type == FIRMWARE_CPLD) { + /* 0x4A,0x41,0x4D,0x01 is JBI file */ + if (buf[0] == 0x4A && buf[1] == 0x41 && buf[2] == 0x4D && buf[3] == 0x01) { + dbg_print(is_debug_on, "Use jbi file.\n"); + ret = ioctl(fd, FIRMWARE_PROGRAM_JBI, &cmd_info); + } else { + dbg_print(is_debug_on, "Use isc file.\n"); + ret = ioctl(fd, FIRMWARE_PROGRAM, &cmd_info); + } + } + + if (info->type == FIRMWARE_FPGA) { + ret = ioctl(fd, FIRMWARE_PROGRAM, &cmd_info); + } + + if (ret < 0) { + return FIRMWARE_FAILED; + } + + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_jtag_test + * function: Determine whether to upgrade ISC or JBI + * @fd: param[in] Device file descriptor + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_jtag_test(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + return FIRMWARE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.c new file mode 100644 index 000000000000..0a7659f0e428 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.c @@ -0,0 +1,446 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "firmware_upgrade_mtd.h" +#include "mtd-abi.h" + +static int get_mtdnum_from_name(char *name, int *mtdnum) +{ + FILE *fp; + int ret; + char buf[PATH_LEN]; + char *start; + char *end; + char *key_w = "mtd"; + + if (name == NULL || mtdnum == NULL) { + dbg_print(is_debug_on, "Input invalid error.\n"); + return -EINVAL; + } + ret = 0; + *mtdnum = -1; + fp = fopen("/proc/mtd", "r"); + if (fp == NULL) { + dbg_print(is_debug_on, "Not find mtd device.\n"); + return -FIRWMARE_MTD_PART_INFO_ERR; + } + + mem_clear(buf, sizeof(buf)); + while(fgets(buf, sizeof(buf), fp)) { + if (strstr(buf, name) != NULL) { + start = strstr(buf, key_w); + if (start == NULL) { + dbg_print(is_debug_on, "/proc/mtd don't find %s.\n", key_w); + ret = -FIRWMARE_MTD_PART_INFO_ERR; + goto exit; + } + start += strlen(key_w); + end = strchr(start, ':'); + if (end == NULL) { + dbg_print(is_debug_on, "/proc/mtd don't find %c.\n", ':'); + ret = -FIRWMARE_MTD_PART_INFO_ERR; + goto exit; + } + + *end = '\0'; + *mtdnum = atoi(start); + if (*mtdnum < 0) { + dbg_print(is_debug_on, "Not get mtd num.\n"); + ret = -FIRWMARE_MTD_PART_INFO_ERR; + goto exit; + } + } + } + + if (*mtdnum == -1) { + ret = -FIRWMARE_MTD_PART_INFO_ERR; + goto exit; + } +exit: + if (fp != NULL) { + fclose(fp); + } + + return ret; +} + +static int firmware_sysfs_get_dev_info(int fd, firmware_mtd_info_t *dev_info) +{ + int ret; + + ret = ioctl(fd, FIRMWARE_SYSFS_MTD_INFO, dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to get upg device file info.\n"); + return ret; + } + + dbg_print(is_debug_on, "mtd_name=%s flash_base=0x%x test_base=0x%x test_size=%d.\n", + dev_info->mtd_name, dev_info->flash_base, dev_info->test_base, dev_info->test_size); + return 0; +} + +/* + * MEMGETINFO + */ +static int getmeminfo(int fd, struct mtd_info_user *mtd) +{ + return ioctl(fd, MEMGETINFO, mtd); +} + +/* + * MEMERASE + */ +static int memerase(int fd, struct erase_info_user *erase) +{ + return ioctl(fd, MEMERASE, erase); +} + +static int erase_flash(int fd, uint32_t offset, uint32_t bytes) +{ + int err; + struct erase_info_user erase; + erase.start = offset; + erase.length = bytes; + err = memerase(fd, &erase); + if (err < 0) { + dbg_print(is_debug_on, "Error: memerase failed, err=%d\n", err); + return -FIRWMARE_MTD_MEMERASE; + } + dbg_print(is_debug_on, "Erased %d bytes from address 0x%.8x in flash\n", bytes, offset); + return 0; +} + +/* + * firmware_upgrade_mtd_block + * function: upgrade mtd device block + * @dev_info: param[in] Device file descriptor + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int firmware_upgrade_mtd_block(int mtd_fd, uint32_t offset, + uint8_t *buf, uint32_t size, uint32_t erasesize) +{ + int ret; + int i; + uint8_t *reread_buf; + uint32_t cmp_retry, reread_len, write_len; + + /* Read back data */ + reread_buf = (uint8_t *) malloc(size); + if (reread_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for read back data buf, size=%d.\n", size); + return FIRMWARE_FAILED; + } + + for (cmp_retry = 0; cmp_retry < FW_SYSFS_RETRY_TIME; cmp_retry++) { + for (i = 0; i < FW_SYSFS_RETRY_TIME; i++) { + if (offset != lseek(mtd_fd, offset, SEEK_SET)) { + dbg_print(is_debug_on, "Error:lseek mtd offset=%x retrytimes=%d failed.\n", offset, i); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + + dbg_print(is_debug_on, "erase mtd offset=0x%x erasesize=%d retrytimes=%d.\n", + offset, erasesize, i); + ret = erase_flash(mtd_fd, offset, erasesize); + if (ret < 0) { + dbg_print(is_debug_on, "Error:erase mtd offset=%x size=%d retrytimes=%d failed, ret=%d\n", + offset, size, i, ret); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + + dbg_print(is_debug_on, "write mtd offset=0x%x size=%d retrytimes=%d.\n", + offset, size, i); + write_len = write(mtd_fd, buf, size); + if (write_len != size) { + dbg_print(is_debug_on, "Error:write mtd offset=0x%x size=%d write_len=%d retrytimes=%d.\n", + offset, size, write_len, i); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "Error: upgrade mtd fail, offset = 0x%x, size = %d\n", offset, size); + free(reread_buf); + return FIRMWARE_FAILED; + } + + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + dbg_print(is_debug_on, "Reread mtd offset=0x%x size=%d\n", offset, size); + for (i = 0; i < FW_SYSFS_RETRY_TIME; i++) { + if (offset != lseek(mtd_fd, offset, SEEK_SET)) { + dbg_print(is_debug_on, "Error:lseek mtd offset=%x retrytimes=%d failed.\n", offset, i); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + + reread_len = read(mtd_fd, reread_buf, size); + if (reread_len != size) { + dbg_print(is_debug_on, "Error:reread mtd offset=0x%x size=%d reread_len=%d retrytimes=%d.\n", + offset, size, reread_len, i); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "Error: reread mtd fail, offset = 0x%x size = %d\n", offset, size); + free(reread_buf); + return FIRMWARE_FAILED; + } + + /* Check data */ + if (memcmp(reread_buf, buf, size) != 0) { + dbg_print(is_debug_on, "memcmp mtd fail,offset = 0x%x retrytimes = %d\n", offset, cmp_retry); + } else { + break; + } + } + if (cmp_retry >= FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "upgrade mtd fail, offset = 0x%x.\n", offset); + dbg_print(is_debug_on, "want to write buf :\n"); + for (i = 0; i < size; i++) { + dbg_print(is_debug_on, "0x%x ", buf[i]); + if (((i + 1) % 16) == 0) { + dbg_print(is_debug_on, "\n"); + } + } + dbg_print(is_debug_on, "\n"); + + dbg_print(is_debug_on, "actually reread buf :\n"); + for (i = 0; i < size; i++) { + dbg_print(is_debug_on, "0x%x ", reread_buf[i]); + if (((i + 1) % 16) == 0) { + dbg_print(is_debug_on, "\n"); + } + } + dbg_print(is_debug_on, "\n"); + + free(reread_buf); + return FIRMWARE_FAILED; + } + + free(reread_buf); + dbg_print(is_debug_on, "firmware upgrade mtd block offset[0x%.8x] success.\n", offset); + return FIRMWARE_SUCCESS; +} + +/* + * firmware_upgrade_mtd_program + * function: upgrade mtd device + * @dev_info: param[in] Device file descriptor + * @flash_base: param[in] Upgrade the flash start address + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +static int firmware_upgrade_mtd_program(firmware_mtd_info_t *dev_info, + int flash_base, uint8_t *buf, uint32_t size) +{ + int ret; + int mtdnum; + char dev_mtd[PATH_LEN]; + int mtd_fd; + uint32_t offset, len, block_size; + struct mtd_info_user mtd_info; + uint8_t *data_point; + + ret = get_mtdnum_from_name(dev_info->mtd_name, &mtdnum); + if (ret < 0) { + dbg_print(is_debug_on, "Error:not find %s mtd num.\n", dev_info->mtd_name); + return FIRMWARE_FAILED; + } + + mem_clear(dev_mtd, sizeof(dev_mtd)); + snprintf(dev_mtd, sizeof(dev_mtd) - 1, "/dev/mtd%d", mtdnum); + + mtd_fd = open(dev_mtd, O_SYNC | O_RDWR); + if (mtd_fd < 0) { + dbg_print(is_debug_on, "Error:open %s failed.\n", dev_mtd); + goto err; + } + + ret = getmeminfo(mtd_fd, &mtd_info); + if (ret < 0) { + dbg_print(is_debug_on, "Error:get mtd info failed, ret=%d.\n", ret); + goto failed; + } + + offset = flash_base; + if (offset >= mtd_info.size) { + dbg_print(is_debug_on, "Error: offset[0x%.8x] over size[0x%.8x]\n", offset, size); + goto failed; + } + + len = size; + data_point = buf; + while ((offset < mtd_info.size) && (len > 0)) { + if (len > mtd_info.erasesize) { + block_size = mtd_info.erasesize; + } else { + block_size = len; + } + dbg_print(is_debug_on, "upgrade mtd[%s] block offset[0x%.8x] size[%d] relen[%d].\n", dev_mtd, offset, size, len); + ret = firmware_upgrade_mtd_block(mtd_fd, offset, data_point, block_size, mtd_info.erasesize); + if (ret < 0) { + dbg_print(is_debug_on, "Error: mt block offset[0x%.8x] size[0x%.8x] failed.\n", offset, block_size); + goto failed; + } + len -= block_size; + data_point += block_size; + offset += block_size; + usleep(FW_MTD_BLOCK_SLEEP_TIME); + } + + if (close(mtd_fd) < 0) { + dbg_print(is_debug_on, "Error:close %s failed.\n", dev_mtd); + } + dbg_print(is_debug_on, "firmware upgrade mtd device success.\n"); + return FIRMWARE_SUCCESS; + +failed: + if (close(mtd_fd) < 0) { + dbg_print(is_debug_on, "Error:close %s failed.\n", dev_mtd); + } + +err: + dbg_print(is_debug_on, "firmware upgrade mtd device fail.\n"); + return FIRMWARE_FAILED; +} + +/* + * firmware_upgrade_mtd + * function: Determine whether to upgrade ISC or JBI + * @fd: param[in] Device file descriptor + * @buf: param[in] Upgrade the file content + * @size: param[in] Upgrade file size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_mtd(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + int ret; + firmware_mtd_info_t dev_info; + + if ((buf == NULL) || (info == NULL)) { + dbg_print(is_debug_on, "Input invalid error.\n"); + return FIRMWARE_FAILED; + } + + /* get sysfs information*/ + ret = firmware_sysfs_get_dev_info(fd, &dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_sysfs_get_dev_info failed, ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + /* enable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + return FIRMWARE_FAILED; + } + + ret = firmware_upgrade_mtd_program(&dev_info, dev_info.flash_base, buf, size); + if (ret < 0) { + dbg_print(is_debug_on, "Error:mtd device program failed, ret=%d.\n", ret); + goto failed; + } + + /* disable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + + return FIRMWARE_SUCCESS; + +failed: + /* disable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH,NULL); + if (ret < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + + return FIRMWARE_FAILED; +} + +/* + * firmware_upgrade_mtd_test + * function: Determine whether to upgrade ISC or JBI + * @fd: param[in] Device file descriptor + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_mtd_test(int fd, name_info_t *info) +{ + int ret, rv; + firmware_mtd_info_t dev_info; + uint8_t *data_buf; + uint8_t num; + int j; + + if (info == NULL) { + dbg_print(is_debug_on, "Input invalid error.\n"); + return FIRMWARE_FAILED; + } + + /* get sysfs information*/ + ret = firmware_sysfs_get_dev_info(fd, &dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_sysfs_get_dev_info failed, ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + if (dev_info.test_size == 0) { + dbg_print(is_debug_on, "Error: get flash size:%d, not support.\n", dev_info.test_size); + return FIRMWARE_NOT_SUPPORT; + } + + data_buf = (uint8_t *) malloc(dev_info.test_size); + if (data_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for test data buf, size=%d.\n", dev_info.test_size); + return FIRMWARE_FAILED; + } + + /* Get random data */ + for (j = 0; j < dev_info.test_size; j++) { + num = (uint8_t) rand() % 256; + data_buf[j] = num & 0xff; + } + + /* enable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + free(data_buf); + return FIRMWARE_FAILED; + } + + ret = firmware_upgrade_mtd_program(&dev_info, dev_info.test_base, data_buf, dev_info.test_size); + /* disable upgrade access */ + rv = ioctl(fd, FIRMWARE_SYSFS_FINISH, NULL); + if (rv < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + free(data_buf); + if (ret < 0) { + dbg_print(is_debug_on, "Error:mtd device program failed, ret=%d.\n", ret); + return FIRMWARE_FAILED; + } + return FIRMWARE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.h new file mode 100644 index 000000000000..06e36b3149d5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/firmware_upgrade_mtd.h @@ -0,0 +1,32 @@ +#ifndef __FIRMWARE_UPGRADE_MTD_H__ +#define __FIRMWARE_UPGRADE_MTD_H__ + +#include + +#define FIRMWARE_DEV_NAME_LEN 64 /* the macro definition needs to same as FIRMWARE_DEV_NAME_LEN in firmware_sysfs_upgrade.h */ +#define PATH_LEN (256) +#define FW_MTD_BLOCK_SLEEP_TIME (10000) /* 10ms */ +#define FW_SYSFS_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define FW_SYSFS_RETRY_TIME (5) /* retry 5 times, 50ms = FW_SYSFS_RETRY_TIME *FW_SYSFS_RETRY_SLEEP_TIME; */ + +/* Debug switch level */ +typedef enum { + FIRWMARE_MTD_SUCCESS = 0, + FIRWMARE_MTD_PART_INFO_ERR, + FIRWMARE_MTD_MEMERASE, + FIRWMARE_MTD_MEMGETINFO, + FIRWMARE_END, +} firmware_debug_level_t; + +#define debug(fmt, argv...) do { \ + dbg_print(is_debug_on, ""fmt , ##argv);\ + } while(0) + +typedef struct firmware_mtd_info_s { + char mtd_name[FIRMWARE_DEV_NAME_LEN]; /* sysfs name */ + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_mtd_info_t; + +#endif /* End of __FIRMWARE_UPGRADE_MTD_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/mtd-abi.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/mtd-abi.h new file mode 100644 index 000000000000..f326d23e732e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_mtd/mtd-abi.h @@ -0,0 +1,259 @@ + +#ifndef __MTD_ABI_H__ +#define __MTD_ABI_H__ + +#include + +struct erase_info_user { + __u32 start; + __u32 length; +}; + +struct erase_info_user64 { + __u64 start; + __u64 length; +}; + +struct mtd_oob_buf { + __u32 start; + __u32 length; + unsigned char *ptr; +}; + +struct mtd_oob_buf64 { + __u64 start; + __u32 pad; + __u32 length; + __u64 usr_ptr; +}; + +/** + * MTD operation modes + * + * @MTD_OPS_PLACE_OOB: OOB data are placed at the given offset (default) + * @MTD_OPS_AUTO_OOB: OOB data are automatically placed at the free areas + * which are defined by the internal ecclayout + * @MTD_OPS_RAW: data are transferred as-is, with no error correction; + * this mode implies %MTD_OPS_PLACE_OOB + * + * These modes can be passed to ioctl(MEMWRITE) and are also used internally. + * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs. + * %MTD_FILE_MODE_RAW. + */ +enum { + MTD_OPS_PLACE_OOB = 0, + MTD_OPS_AUTO_OOB = 1, + MTD_OPS_RAW = 2, +}; + +/** + * struct mtd_write_req - data structure for requesting a write operation + * + * @start: start address + * @len: length of data buffer + * @ooblen: length of OOB buffer + * @usr_data: user-provided data buffer + * @usr_oob: user-provided OOB buffer + * @mode: MTD mode (see "MTD operation modes") + * @padding: reserved, must be set to 0 + * + * This structure supports ioctl(MEMWRITE) operations, allowing data and/or OOB + * writes in various modes. To write to OOB-only, set @usr_data == NULL, and to + * write data-only, set @usr_oob == NULL. However, setting both @usr_data and + * @usr_oob to NULL is not allowed. + */ +struct mtd_write_req { + __u64 start; + __u64 len; + __u64 ooblen; + __u64 usr_data; + __u64 usr_oob; + __u8 mode; + __u8 padding[7]; +}; + +#define MTD_ABSENT 0 +#define MTD_RAM 1 +#define MTD_ROM 2 +#define MTD_NORFLASH 3 +#define MTD_NANDFLASH 4 +#define MTD_DATAFLASH 6 +#define MTD_UBIVOLUME 7 +#define MTD_MLCNANDFLASH 8 + +#define MTD_WRITEABLE 0x400 /* Device is writeable */ +#define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */ +#define MTD_NO_ERASE 0x1000 /* No erase necessary */ +#define MTD_POWERUP_LOCK 0x2000 /* Always locked after reset */ + +/* Some common devices / combinations of capabilities */ +#define MTD_CAP_ROM 0 +#define MTD_CAP_RAM (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE) +#define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE) +#define MTD_CAP_NANDFLASH (MTD_WRITEABLE) + +/* Obsolete ECC byte placement modes (used with obsolete MEMGETOOBSEL) */ +#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended) +#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode) +#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme +#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read) +#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default + +/* OTP mode selection */ +#define MTD_OTP_OFF 0 +#define MTD_OTP_FACTORY 1 +#define MTD_OTP_USER 2 + +typedef struct mtd_info_user { + __u8 type; + __u32 flags; + __u32 size; /* Total size of the MTD */ + __u32 erasesize; + __u32 writesize; + __u32 oobsize; /* Amount of OOB data per block (e.g. 16) */ + __u64 padding; /* Old obsolete field; do not use */ +} mtd_info_user_t; + +struct region_info_user { + __u32 offset; /* At which this region starts, + * from the beginning of the MTD */ + __u32 erasesize; /* For this region */ + __u32 numblocks; /* Number of blocks in this region */ + __u32 regionindex; +}; + +struct otp_info { + __u32 start; + __u32 length; + __u32 locked; +}; + +/* + * Note, the following ioctl existed in the past and was removed: + * #define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) + * Try to avoid adding a new ioctl with the same ioctl number. + */ + +/* Get basic MTD characteristics info (better to use sysfs) */ +#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) +/* Erase segment of MTD */ +#define MEMERASE _IOW('M', 2, struct erase_info_user) +/* Write out-of-band data from MTD */ +#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) +/* Read out-of-band data from MTD */ +#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) +/* Lock a chip (for MTD that supports it) */ +#define MEMLOCK _IOW('M', 5, struct erase_info_user) +/* Unlock a chip (for MTD that supports it) */ +#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) +/* Get the number of different erase regions */ +#define MEMGETREGIONCOUNT _IOR('M', 7, int) +/* Get information about the erase region for a specific index */ +#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) +/* Get info about OOB modes (e.g., RAW, PLACE, AUTO) - legacy interface */ +#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) +/* Check if an eraseblock is bad */ +#define MEMGETBADBLOCK _IOW('M', 11, __kernel_loff_t) +/* Mark an eraseblock as bad */ +#define MEMSETBADBLOCK _IOW('M', 12, __kernel_loff_t) +/* Set OTP (One-Time Programmable) mode (factory vs. user) */ +#define OTPSELECT _IOR('M', 13, int) +/* Get number of OTP (One-Time Programmable) regions */ +#define OTPGETREGIONCOUNT _IOW('M', 14, int) +/* Get all OTP (One-Time Programmable) info about MTD */ +#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) +/* Lock a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */ +#define OTPLOCK _IOR('M', 16, struct otp_info) +/* Get ECC layout (deprecated) */ +#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout_user) +/* Get statistics about corrected/uncorrected errors */ +#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats) +/* Set MTD mode on a per-file-descriptor basis (see "MTD file modes") */ +#define MTDFILEMODE _IO('M', 19) +/* Erase segment of MTD (supports 64-bit address) */ +#define MEMERASE64 _IOW('M', 20, struct erase_info_user64) +/* Write data to OOB (64-bit version) */ +#define MEMWRITEOOB64 _IOWR('M', 21, struct mtd_oob_buf64) +/* Read data from OOB (64-bit version) */ +#define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64) +/* Check if chip is locked (for MTD that supports it) */ +#define MEMISLOCKED _IOR('M', 23, struct erase_info_user) +/* + * Most generic write interface; can write in-band and/or out-of-band in various + * modes (see "struct mtd_write_req") + */ +#define MEMWRITE _IOWR('M', 24, struct mtd_write_req) + +/* + * Obsolete legacy interface. Keep it in order not to break userspace + * interfaces + */ +struct nand_oobinfo { + __u32 useecc; + __u32 eccbytes; + __u32 oobfree[8][2]; + __u32 eccpos[32]; +}; + +struct nand_oobfree { + __u32 offset; + __u32 length; +}; + +#define MTD_MAX_OOBFREE_ENTRIES 8 +#define MTD_MAX_ECCPOS_ENTRIES 64 +/* + * OBSOLETE: ECC layout control structure. Exported to user-space via ioctl + * ECCGETLAYOUT for backwards compatbility and should not be mistaken as a + * complete set of ECC information. The ioctl truncates the larger internal + * structure to retain binary compatibility with the static declaration of the + * ioctl. Note that the "MTD_MAX_..._ENTRIES" macros represent the max size of + * the user struct, not the MAX size of the internal struct nand_ecclayout. + */ +struct nand_ecclayout_user { + __u32 eccbytes; + __u32 eccpos[MTD_MAX_ECCPOS_ENTRIES]; + __u32 oobavail; + struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; +}; + +/** + * struct mtd_ecc_stats - error correction stats + * + * @corrected: number of corrected bits + * @failed: number of uncorrectable errors + * @badblocks: number of bad blocks in this partition + * @bbtblocks: number of blocks reserved for bad block tables + */ +struct mtd_ecc_stats { + __u32 corrected; + __u32 failed; + __u32 badblocks; + __u32 bbtblocks; +}; + +/* + * MTD file modes - for read/write access to MTD + * + * @MTD_FILE_MODE_NORMAL: OTP disabled, ECC enabled + * @MTD_FILE_MODE_OTP_FACTORY: OTP enabled in factory mode + * @MTD_FILE_MODE_OTP_USER: OTP enabled in user mode + * @MTD_FILE_MODE_RAW: OTP disabled, ECC disabled + * + * These modes can be set via ioctl(MTDFILEMODE). The mode mode will be retained + * separately for each open file descriptor. + * + * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW - + * raw access to the flash, without error correction or autoplacement schemes. + * Wherever possible, the MTD_OPS_* mode will override the MTD_FILE_MODE_* mode + * (e.g., when using ioctl(MEMWRITE)), but in some cases, the MTD_FILE_MODE is + * used out of necessity (e.g., `write()', ioctl(MEMWRITEOOB64)). + */ +enum mtd_file_modes { + MTD_FILE_MODE_NORMAL = MTD_OTP_OFF, + MTD_FILE_MODE_OTP_FACTORY = MTD_OTP_FACTORY, + MTD_FILE_MODE_OTP_USER = MTD_OTP_USER, + MTD_FILE_MODE_RAW, +}; + +#endif /* __MTD_ABI_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.c new file mode 100644 index 000000000000..10a429d93bde --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.c @@ -0,0 +1,285 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "firmware_upgrade_sysfs.h" + +static int firmware_sysfs_get_dev_info(int fd, firmware_dev_file_info_t *dev_info) +{ + int ret; + + ret = ioctl(fd, FIRMWARE_SYSFS_DEV_FILE_INFO, dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to get upg flash dev info.\n"); + return ret; + } + + dbg_print(is_debug_on, "sysfs_name=%s per_len=%u.\n", dev_info->sysfs_name, dev_info->per_len); + return 0; +} + +/* sysfs upgrade program function */ +int firmware_upgrade_sysfs_program(firmware_dev_file_info_t *dev_info, uint32_t dev_base, + uint8_t *buf, uint32_t size) +{ + int ret = 0; + uint32_t offset_addr, buf_offset, len; + uint32_t write_len, cmp_retry, reread_len; + int sysfs_fd; + uint8_t *reread_buf; + int i; + + if (dev_info->per_len > 0) { + if (size % dev_info->per_len) { + dbg_print(is_debug_on, "firmware sysfs upgrade size[%u] is width[%u] mismatch, ret %d.\n", + size, dev_info->per_len, ret); + return FIRMWARE_FAILED; + } + len = dev_info->per_len; + } else { + /* Write to the maximum buffer if the length of each write is not configured */ + len = size; + } + + /* Read back data */ + reread_buf = (uint8_t *) malloc(len); + if (reread_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for read back data buf, len=%u.\n", len); + return FIRMWARE_FAILED; + } + + sysfs_fd = open(dev_info->sysfs_name, O_RDWR | O_SYNC); + if (sysfs_fd < 0) { + dbg_print(is_debug_on, "open file[%s] fail.\n", dev_info->sysfs_name); + free(reread_buf); + return FIRMWARE_FAILED; + } + + offset_addr = dev_base; + buf_offset = 0; + cmp_retry = 0; + while (buf_offset < size) { + /* Calibrate upgrade data length */ + if (buf_offset + len > size) { + len = size - buf_offset; + } + + for (i = 0; i < FW_SYSFS_RETRY_TIME; i++) { + ret = lseek(sysfs_fd, offset_addr, SEEK_SET); + if (ret < 0) { + dbg_print(is_debug_on, "lseek file[%s offset=%u] fail.\n", dev_info->sysfs_name, offset_addr); + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + write_len = write(sysfs_fd, buf + buf_offset, len); + if (write_len != len) { + dbg_print(is_debug_on, "write file[%s] fail,offset = 0x%x retrytimes = %u len = %u, write_len =%u\n", + dev_info->sysfs_name, offset_addr, i ,len, write_len); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + break; + } + + if (i == FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "write file[%s] fail, offset = 0x%x, len = %u, write_len =%u\n", + dev_info->sysfs_name, offset_addr, len, write_len); + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + + mem_clear(reread_buf, len); + ret = lseek(sysfs_fd, offset_addr, SEEK_SET); + if (ret < 0) { + dbg_print(is_debug_on, "reread lseek file[%s offset=%u] fail.\n", dev_info->sysfs_name, offset_addr); + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + + for (i = 0; i < FW_SYSFS_RETRY_TIME; i++) { + reread_len = read(sysfs_fd, reread_buf, len); + if (reread_len != len) { + dbg_print(is_debug_on, "reread file[%s] fail,offset = 0x%x retrytimes = %u reread_len = %u, len =%u\n", + dev_info->sysfs_name, offset_addr, i ,reread_len, len); + usleep(FW_SYSFS_RETRY_SLEEP_TIME); + continue; + } + break; + } + if (i == FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "reread file[%s] fail, offset = 0x%x, reread_len = %u, len = %u\n", + dev_info->sysfs_name, offset_addr, reread_len, len); + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + + /* Check data */ + if (memcmp(reread_buf, buf + buf_offset, len) != 0) { + if (cmp_retry < FW_SYSFS_RETRY_TIME) { + dbg_print(is_debug_on, "memcmp file[%s] fail,offset = 0x%x retrytimes = %u\n", + dev_info->sysfs_name, offset_addr, cmp_retry); + cmp_retry++; + continue; + } + + dbg_print(is_debug_on, "upgrade file[%s] fail, offset = 0x%x.\n", dev_info->sysfs_name, offset_addr); + dbg_print(is_debug_on, "want to write buf :\n"); + for (i = 0; i < len; i++) { + dbg_print(is_debug_on, "0x%x ", buf[buf_offset + i]); + if (((i + 1) % 16) == 0) { + dbg_print(is_debug_on, "\n"); + } + } + dbg_print(is_debug_on, "\n"); + + dbg_print(is_debug_on, "actually reread buf :\n"); + for (i = 0; i < len; i++) { + dbg_print(is_debug_on, "0x%x ", reread_buf[i]); + if (((i + 1) % 16) == 0) { + dbg_print(is_debug_on, "\n"); + } + } + dbg_print(is_debug_on, "\n"); + + close(sysfs_fd); + free(reread_buf); + return FIRMWARE_FAILED; + } + offset_addr += len; + buf_offset += len; + usleep(5000); + } + free(reread_buf); + + dbg_print(is_debug_on, "firmware upgrade sysfs success.\n"); + close(sysfs_fd); + return FIRMWARE_SUCCESS; +} + +/* sysfs upgrade function */ +int firmware_upgrade_sysfs(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + int ret = 0; + firmware_dev_file_info_t dev_info; + + if ((buf == NULL) || (info == NULL)) { + dbg_print(is_debug_on, "Input invalid error.\n"); + goto exit; + } + + /* get sysfs information*/ + ret = firmware_sysfs_get_dev_info(fd, &dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_sysfs_get_dev_info failed, ret %d.\n", ret); + goto exit; + } + + /* enable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + goto exit; + } + + ret = firmware_upgrade_sysfs_program(&dev_info, dev_info.dev_base, buf, size); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + goto fail; + } + + dbg_print(is_debug_on, "firmware upgrade sysfs success.\n"); + /* disable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH,NULL); + if (ret < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + return FIRMWARE_SUCCESS; + +fail: + /* disable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } +exit: + dbg_print(is_debug_on, "firmware upgrade sysfs fail.\n"); + return FIRMWARE_FAILED; +} + +/* sysfs upgrade test function */ +int firmware_upgrade_sysfs_test(int fd, name_info_t *info) +{ + int ret, rv; + firmware_dev_file_info_t dev_info; + uint8_t *data_buf; + uint8_t num; + int j; + + if (info == NULL) { + dbg_print(is_debug_on, "Input invalid error.\n"); + return FIRMWARE_FAILED; + } + + /* get sysfs information*/ + ret = firmware_sysfs_get_dev_info(fd, &dev_info); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_sysfs_get_dev_info failed, ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + if (dev_info.test_size == 0) { + dbg_print(is_debug_on, "Error: get sysfs test size:%d, not support.\n", dev_info.test_size); + return FIRMWARE_NOT_SUPPORT; + } + + data_buf = (uint8_t *) malloc(dev_info.test_size); + if (data_buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for test data buf, size=%d.\n", dev_info.test_size); + return FIRMWARE_FAILED; + } + + /* Get random data */ + for (j = 0; j < dev_info.test_size; j++) { + num = (uint8_t) rand() % 256; + data_buf[j] = num & 0xff; + } + + /* enable upgrade access */ + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + free(data_buf); + return FIRMWARE_FAILED; + } + + ret = firmware_upgrade_sysfs_program(&dev_info, dev_info.test_base, data_buf, dev_info.test_size); + /* disable upgrade access */ + rv = ioctl(fd, FIRMWARE_SYSFS_FINISH,NULL); + if (rv < 0) { + dbg_print(is_debug_on, "close dev logic en failed.\n"); + } + free(data_buf); + + if (ret < 0) { + dbg_print(is_debug_on, "init dev logic faile\n"); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "firmware upgrade sysfs success.\n"); + return FIRMWARE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.h new file mode 100644 index 000000000000..b69080ea642e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/firmware_upgrade_sysfs.h @@ -0,0 +1,16 @@ +#ifndef __FIRMWARE_UPGRADE_SYSFS_H__ +#define __FIRMWARE_UPGRADE_SYSFS_H__ + +#define FIRMWARE_DEV_NAME_LEN (64) /* the macro definition needs to same as FIRMWARE_DEV_NAME_LEN in firmware_sysfs_upgrade.h */ +#define FW_SYSFS_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define FW_SYSFS_RETRY_TIME (5) /* retry 5 times, 50ms = FW_SYSFS_RETRY_TIME *FW_SYSFS_RETRY_SLEEP_TIME; */ + +typedef struct firmware_dev_file_info_s { + char sysfs_name[FIRMWARE_DEV_NAME_LEN]; /* sysfs name */ + uint32_t dev_base; /* device upgrade base address */ + uint32_t per_len; /* The length of bytes per operation */ + uint32_t test_base; /* Test device address */ + uint32_t test_size; /* Test flash size */ +} firmware_dev_file_info_t; + +#endif /* End of __FIRMWARE_UPGRADE_SYSFS_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.c new file mode 100644 index 000000000000..7db3c1b7b6ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.c @@ -0,0 +1,1181 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fw_upg_spi_logic_dev.h" + +#define be32_to_cpus(p) __be32_to_cpus(p) +#define le32_to_cpus(p) __le32_to_cpus(p) +#define cpu_to_be32s(p) __cpu_to_be32s(p) +#define cpu_to_le32s(p) __cpu_to_le32s(p) + +static void firmware_upgrade_printf_reg(uint8_t *buf, int buf_len, uint32_t offset_addr) +{ + int i, j, tmp; + + j = offset_addr % 16; + tmp = j; + offset_addr -= j; + printf("\n "); + + for (i = 0; i < 16; i++) { + printf("%2x ", i); + } + + for (i = 0; i < buf_len + j; i++) { + if ((i % 16) == 0) { + printf("\n0x%08x ", offset_addr); + offset_addr = offset_addr + 16; + } + if (tmp) { + printf(" "); + tmp--; + } else { + printf("%02x ", buf[i-j]); + } + } + + printf("\n"); + return; +} + +static int firmware_upgrade_get_spi_logic_info(int fd, firmware_spi_logic_upg_t *current_upg_priv) +{ + int ret; + firmware_spi_logic_info_t syfs_info; + + if (fd < 0) { + dbg_print(is_debug_on, "Error: get spi logic info fd %d.\n", fd); + return fd; + } + + ret = 0; + ret = ioctl(fd, FIRMWARE_SYSFS_SPI_INFO, &syfs_info); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to get upg flash dev info, ret=%d\n", ret); + return -FW_SPI_FLASH_GET_INFO_ERR; + } + + current_upg_priv->flash_base = syfs_info.flash_base; + current_upg_priv->ctrl_base = syfs_info.ctrl_base; + memcpy(current_upg_priv->dev_path, syfs_info.logic_dev_name, FIRMWARE_LOGIC_DEV_NAME_LEN - 1); + current_upg_priv->status_reg = syfs_info.ctrl_base + FPGA_UPG_STATUS_REG; + current_upg_priv->spi_ctrl_reg = syfs_info.ctrl_base + FPGA_UPG_SPI_CTRL_REG; + current_upg_priv->wr_flash_status_reg = syfs_info.ctrl_base + FPGA_UPG_WR_FLASH_STATUS_REG; + current_upg_priv->rd_flash_status_reg = syfs_info.ctrl_base + FPGA_UPG_RD_FLASH_STATUS_REG; + current_upg_priv->instruction_reg = syfs_info.ctrl_base + FPGA_UPG_INSTRUCTION_REG; + current_upg_priv->addr_reg = syfs_info.ctrl_base + FPGA_UPG_ADDR_REG; + current_upg_priv->length_reg = syfs_info.ctrl_base + FPGA_UPG_LENGTH_REG; + current_upg_priv->device_id_reg = syfs_info.ctrl_base + FPGA_UPG_DEVICE_ID_REG; + current_upg_priv->drop_reg_num_reg = syfs_info.ctrl_base + FPGA_UPG_DROP_REQ_NUM_REG; + current_upg_priv->test_base = syfs_info.test_base; + current_upg_priv->test_size = syfs_info.test_size; + + return 0; +} + +static int firmware_upgrade_spi_logic_init(int fd) +{ + int ret; + + ret = 0; + ret = ioctl(fd, FIRMWARE_SYSFS_INIT, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to init spi logic, ret=%d\n", ret); + return -1; + } + + return 0; +} + +static int firmware_upgrade_spi_logic_finish(int fd) +{ + int ret; + + if (fd < 0) { + dbg_print(is_debug_on, "Error: get spi logic info fd %d.\n", fd); + return -1; + } + + ret = 0; + ret = ioctl(fd, FIRMWARE_SYSFS_FINISH, NULL); + if (ret < 0) { + dbg_print(is_debug_on, "Failed to release spi logic, ret=%d\n", ret); + return -1; + } + + return 0; +} + +/** + * firmware_fpga_file_read - + * function:Provide FPGA read-register interface (address must be 4-byte aligned) + * @dev_name: Device file descriptor + * @offset: device offset + * @buf: Read Data Buffer + * @rd_len: Read Data Length + * return: 0--success; other--fail + */ +int firmware_fpga_file_read(char *dev_name, uint32_t offset, uint8_t *buf, uint32_t rd_len) +{ + int ret, fd; + + if ((dev_name == NULL) || (buf == NULL)) { + dbg_print(is_debug_on, "upg_priv or read buf is null.\n"); + return -1; + } + + if ((fd = open(dev_name, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + dbg_print(is_debug_on, "Error: Could not open file %s. Errno=%d\n", dev_name, errno); + return -1; + } + + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) { + dbg_print(is_debug_on, "read llseek failed, errno: %s\n", strerror(errno)); + close(fd); + return -1; + } + + ret = read(fd, buf, rd_len); + if (ret < 0) { + dbg_print(is_debug_on, "read failed, err: %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static int firmware_fpga_read_word(char *dev_name, uint32_t addr, uint32_t *val) +{ + int ret; + uint32_t retry; + + if (sizeof(int) < FIRMWARE_FPGA_WORD_LEN) { + dbg_print(is_debug_on, "Error:dfd_fpga_read_word buf len %ld support len %d.\n", + sizeof(int), FIRMWARE_FPGA_WORD_LEN); + return -1; + } + + retry = 0; + *val = 0; + while(retry < FIRMWARE_FPGA_UPG_RETRY_CNT) { + ret = firmware_fpga_file_read(dev_name, addr, (uint8_t *)val, FIRMWARE_FPGA_WORD_LEN); + if (ret) { + retry++; + dbg_print(is_debug_on, "firmware_fpga_file_read addr 0x%x retry %u failed ret %d.\n", + addr, retry, ret); + continue; + } else { + le32_to_cpus(val); + return 0; + } + } + + dbg_print(is_debug_on, "dfd_fpga_read_word addr 0x%x retry %u failed ret %d.\n", addr, retry, ret); + return -1; +} + +static int firmware_fpga_read_buf(char *dev_name, uint32_t addr, uint8_t *buf, uint32_t rd_len) +{ + int ret; + uint32_t retry; + + retry = 0; + while(retry < FIRMWARE_FPGA_UPG_RETRY_CNT) { + ret = firmware_fpga_file_read(dev_name, addr, buf, rd_len); + if (ret) { + retry++; + dbg_print(is_debug_on, "firmware_fpga_file_read addr 0x%x rd_len %u i %d failed ret %d.\n", + addr, rd_len, retry, ret); + continue; + } else { + return 0; + } + } + + dbg_print(is_debug_on, "firmware_fpga_file_read addr 0x%x rd_len %u retry %u failed ret %d.\n", + addr, rd_len, retry, ret); + return -1; +} + +/** + * firmware_fpga_file_write - + * function:Provide FPGA write-register interface (address must be 4-byte aligned) + * @dev_name: Device file descriptor + * @offset: device offset + * @buf: Write Data Buffer + * @wr_len: Write Data Length + * return: 0--success; other--fail + */ +int firmware_fpga_file_write(char *dev_name, uint32_t offset, uint8_t *buf, uint32_t wr_len) +{ + int ret, fd; + + if ((dev_name == NULL) || (buf == NULL)) { + dbg_print(is_debug_on, "dev_name or write buf is null.\n"); + return -1; + } + + if ((fd = open(dev_name, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + dbg_print(is_debug_on, "Error: Could not open file %s. Errno=%d\n", dev_name, errno); + return -1; + } + + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) { + dbg_print(is_debug_on, "write llseek failed, err: %s\n", strerror(errno)); + close(fd); + return -1; + } + + ret = write(fd, buf, wr_len); + if (ret < 0 ) { + dbg_print(is_debug_on, "write failed, err: %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static int firmware_fpga_write_word(char *dev_name, uint32_t addr, uint32_t val) +{ + int ret; + uint32_t retry, tmp; + + retry = 0; + tmp = val; + cpu_to_le32s(&tmp); + while(retry < FIRMWARE_FPGA_UPG_RETRY_CNT) { + ret = firmware_fpga_file_write(dev_name, addr, (uint8_t *)&tmp, FIRMWARE_FPGA_WORD_LEN); + if (ret) { + retry++; + dbg_print(is_debug_on, "firmware_fpga_file_write addr 0x%x val 0x%x retry %u failed ret %d.\n", + addr, val, retry, ret); + continue; + } else { + return 0; + } + } + + dbg_print(is_debug_on, "firmware_fpga_file_write addr 0x%x val 0x%x retry %u failed ret %d.\n", + addr, val, retry, ret); + return -1; +} + +static int firmware_fpga_write_buf(char *dev_name, uint32_t addr, uint8_t *buf, uint32_t wr_len) +{ + int ret; + uint32_t retry; + + retry = 0; + while(retry < FIRMWARE_FPGA_UPG_RETRY_CNT) { + ret = firmware_fpga_file_write(dev_name, addr, buf, wr_len); + if (ret) { + retry++; + dbg_print(is_debug_on, "firmware_fpga_file_write addr 0x%x wr_len 0x%x retry %u failed ret %d.\n", + addr, wr_len, retry, ret); + continue; + } else { + return 0; + } + } + + dbg_print(is_debug_on, "dfd_fpga_buf_write addr 0x%x wr_len 0x%x retry %u failed ret %d.\n", + addr, wr_len, retry, ret); + + return -1; +} + +/* Whether the SPI port is idle, 0--idle, 1--busy */ +static int firmware_fpga_get_status(firmware_spi_logic_upg_t *upg_priv, char *status) +{ + int ret; + uint32_t addr, val; + + addr = upg_priv->status_reg; + ret = firmware_fpga_read_word(upg_priv->dev_path, addr, &val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_get_status addr 0x%x failed ret %d.\n", addr, ret); + return -1; + } + + *status = val & FPGA_UPG_STATUS_MASK; + + return 0; +} + +/* Wait for the SPI port to become free again */ +static int firmware_fpga_wait_ready(firmware_spi_logic_upg_t *upg_priv) +{ + int timeout; + char status; + int ret; + + timeout = FIRMWARE_UPG_RETRY_TIME_CNT; + while (timeout--) { + usleep(FIRMWARE_UPG_RETRY_SLEEP_TIME); + ret = firmware_fpga_get_status(upg_priv, &status); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_get_status failed ret %d.\n", ret); + continue; + } + + /* Determine if it's idle */ + if (!status) { + return 0; + } + } + + return -1; +} + +/* Configure access */ +static int firmware_fpga_set_access(firmware_spi_logic_upg_t *upg_priv, uint32_t cmd) +{ + int ret; + uint32_t addr, val; + + addr = upg_priv->instruction_reg; + val = cmd; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", addr, val, ret); + return -1; + } + + addr = upg_priv->spi_ctrl_reg; + val = FPGA_UPG_ACCESS_ENABLE; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", addr, val, ret); + return -1; + } + + /* Wait for the SPI port on the FPGA to become free again*/ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_wait_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + return 0; +} + +/* Get SPI STATUS register */ +static int firmware_fpga_get_spi_status(firmware_spi_logic_upg_t *upg_priv, char *status) +{ + int ret; + uint32_t val, addr, cmd; + + cmd = FPGA_UPG_INSTRUTION_RDSR; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd 0x%x failed ret %d.\n", cmd, ret); + return -1; + } + + addr = upg_priv->rd_flash_status_reg; + ret = firmware_fpga_read_word(upg_priv->dev_path, addr, &val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_read_word addr 0x%x failed ret %d.\n", addr, ret); + return -1; + } + + *status = val & FPGA_UPG_SPI_STATUS_MASK; + + return 0; +} + +/* Wait for the SPI chip operation to complete */ +static int firmware_fpga_wait_spi_ready(firmware_spi_logic_upg_t *upg_priv, + uint32_t timeout, uint32_t usleep_time) +{ + char status; + int ret; + + while (timeout--) { + usleep(usleep_time); + ret = firmware_fpga_get_spi_status(upg_priv, &status); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_get_spi_status failed ret %d.\n", ret); + continue; + } + /* Determine if it's idle */ + if (!status) { + return 0; + } + } + + return -FW_SPI_FLASH_SPI_BUSY; +} + +/* Configure FPGA upgrade write enable */ +static int firmware_fpga_set_wr_enable(firmware_spi_logic_upg_t *upg_priv) +{ + int ret; + uint32_t cmd; + + cmd = FPGA_UPG_INSTRUTION_WREN; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -1; + } + + return 0; +} + +#if 0 +/* erase all flash */ +static int firmware_fpga_upg_set_erase_all(firmware_spi_logic_upg_t *upg_priv) +{ + int ret; + int cmd; + + /* Wait for the SPI port on the FPGA to become free */ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_wait_ready failed ret %d.\n", ret); + return -1; + } + + /* Configure FPGA upgrade write enable */ + ret = firmware_fpga_set_wr_enable(upg_priv); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_wr_enable failed ret %d.\n", ret); + return -1; + } + + cmd = FPGA_UPG_INSTRUTION_BE; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -1; + } + + /* Hardware requirements, delay of 1s */ + sleep(1); + + /* Wait for the SPI chip operation to complete, 1s check status once, max delay 300s */ + ret = firmware_fpga_wait_spi_ready(upg_priv, 300, (1 * 1000 * 1000)); + if (ret) { + dbg_print(is_debug_on, "dfd_fpga_wait_spi_ready failed ret %d.\n", ret); + return -1; + } + + dbg_print(is_debug_on, "Success.\n"); + return 0; +} +#endif + +/* Erase sectors (256 pages, 64K total) */ +static int firmware_fpga_erase_sector(firmware_spi_logic_upg_t *upg_priv, uint32_t spi_addr) +{ + int ret; + uint32_t val, addr, cmd; + + /* Wait for the SPI port on the FPGA to become free again */ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_fpga_wait_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + /* Enable write */ + ret = firmware_fpga_set_wr_enable(upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_fpga_set_wr_enable failed ret %d.\n", ret); + return -FW_SPI_FLASH_WR_ENABLE_ERR; + } + + /* Write erase address */ + val = spi_addr; + addr = upg_priv->addr_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", addr, val, ret); + return -FW_SPI_FLASH_ERASE_ADDR_ERR; + } + + /* Enable sector erasure */ + cmd = FPGA_UPG_INSTRUTION_SE; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -FW_SPI_FLASH_ERASE_SECTOR_ERR; + } + + /* Hardware requirements, delay of 0.25s */ + usleep(250 * 1000); + + /* Wait for the SPI chip operation to complete, 1s check status once, max delay 10s */ + ret = firmware_fpga_wait_spi_ready(upg_priv, FPGA_UPG_WAIT_SPI_RETRY_CNT, (100 * 1000)); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_wait_spi_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_SPI_BUSY; + } + + return 0; +} + +#if 0 +int firmware_fpga_erase64_sector(firmware_spi_logic_upg_t *upg_priv, int offset) +{ + int ret; + ret = -1; + + if ((offset % FIRMWARE_SPI_LOGIC_SECTOR_SIZE) == 0) { + dbg_print(is_debug_on, "erase 64k area, offset 0x%x.\n", offset); + ret = firmware_fpga_erase_sector(upg_priv, offset); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_erase_sector offset 0x%x failed ret %d.\n", offset, ret); + return ret; + } + } else { + dbg_print(is_debug_on, "Input para invalid, offset 0x%x.\n", offset); + } + + return ret; +} +#endif + +static int firmware_fpga_upg_program(firmware_spi_logic_upg_t *upg_priv, + uint32_t spi_addr, uint8_t *buf, uint32_t len) +{ + int ret; + uint32_t addr, val, cmd, wr_len; + + /* Write data to the Upgrade Content Register */ + addr = upg_priv->ctrl_base; + wr_len = len; + ret = firmware_fpga_write_buf(upg_priv->dev_path, addr, (uint8_t*)buf, wr_len); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_write_buf addr 0x%x wr_len %d failed ret %d.\n", + addr, len, ret); + return -FW_SPI_FLASH_WR_ERR; + } + + /* Write length register, FPGA is fixed 256 lengths */ + val = FFPGA_UPG_DATA_SIZE; + addr = upg_priv->length_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", + addr, val, ret); + return -FW_SPI_FLASH_WR_LENGTH_ERR; + } + + /* Write address register */ + val = spi_addr; + addr = upg_priv->addr_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", + addr, val, ret); + return -FW_SPI_FLASH_WR_ADDR_ERR; + } + + /* Start writing upgrade data to SPI */ + cmd = FPGA_UPG_INSTRUTION_PP; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -FW_SPI_FLASH_SET_ACCESS_ERR; + } + + /* min write wait 0.33ms */ + usleep(330); + + /* Wait for the SPI chip operation to complete, 100us check status once, max delay 10ms */ + ret = firmware_fpga_wait_spi_ready(upg_priv, FPGA_UPG_WAIT_SPI_RETRY_CNT, (100)); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_wait_spi_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + return 0; +} + +/** + * firmware_fpga_upg_write + * function: write interface provided to the upgrade module + * @upg_priv: Device information + * @addr: upgrade addr + * @buf: Write Data Buffer + * @len: Write Data Length + * return: 0--success; other--fail + */ +static int firmware_fpga_upg_write(firmware_spi_logic_upg_t *upg_priv, + uint32_t addr, uint8_t *buf, uint32_t len) +{ + int ret; + + /* address must be 256 bytes aligned */ + if ((upg_priv == NULL) || (buf == NULL) || (addr & 0xff) || (len > 256)) { + dbg_print(is_debug_on,"Input para invalid upg_priv %p buf %p addr 0x%x len %u.\n", + upg_priv, buf, addr, len); + return -FW_SPI_FLASH_PARAM_ERR; + } + + /* Wait for the SPI port on the FPGA to become free again*/ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_wait_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + /* Configure write enable */ + ret = firmware_fpga_set_wr_enable(upg_priv); + if (ret) { + dbg_print(is_debug_on,"firmware_fpga_set_wr_enable failed ret %d.\n", ret); + return -FW_SPI_FLASH_WR_ENABLE_ERR; + } + + /* Write upgrade data */ + ret = firmware_fpga_upg_program(upg_priv, addr, buf, len); + if (ret) { + dbg_print(is_debug_on,"dfd_fpga_upg_program addr 0x%x len %u failed ret %d.\n", addr, len, ret); + return -FW_SPI_FLASH_UPG_ERR; + } + + return 0; +} + +static int firmware_fpga_fast_read(firmware_spi_logic_upg_t *upg_priv, + uint32_t spi_addr, uint8_t *buf, uint32_t len) +{ + int ret; + uint32_t val, addr, cmd; + + /* Clear register value */ + addr = upg_priv->ctrl_base; + ret = firmware_fpga_write_buf(upg_priv->dev_path, addr, buf, len); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_buf addr 0x%x len %d failed ret %d.\n", addr, len, ret); + return -FW_SPI_FLASH_WR_ERR; + } + /* Write length register */ + val = FFPGA_UPG_DATA_SIZE; + addr = upg_priv->length_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", + addr, val, ret); + return -FW_SPI_FLASH_WR_LENGTH_ERR; + } + + /* Write address register */ + val = spi_addr; + addr = upg_priv->addr_reg; + ret = firmware_fpga_write_word(upg_priv->dev_path, addr, val); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_write_word addr 0x%x val 0x%x failed ret %d.\n", + addr, val, ret); + return -FW_SPI_FLASH_WR_ADDR_ERR; + } + + /* Start reading SPI data */ + cmd = FPGA_UPG_INSTRUTION_FR; + ret = firmware_fpga_set_access(upg_priv, cmd); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_access cmd %d failed ret %d.\n", cmd, ret); + return -FW_SPI_FLASH_SET_ACCESS_ERR; + } + + /* Read the upgraded content register to the buffer, + * FPGA only supports 4 bytes of read and write */ + addr = upg_priv->ctrl_base; + ret = firmware_fpga_read_buf(upg_priv->dev_path, addr, (uint8_t*)buf, len); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_read_buf addr 0x%x len %d failed ret %d.\n", addr, len, ret); + return -FW_SPI_FLASH_RD_ERR; + } + + return 0; +} + +/** + * firmware_fpga_upg_read + * function: read interface provided to the upgrade module + * @upg_priv: Device information + * @addr: upgrade addr + * @buf: Read Data Buffer + * @len: Read Data Length + * return: 0--success; other--fail + */ +static int firmware_fpga_upg_read(firmware_spi_logic_upg_t *upg_priv, + uint32_t addr, uint8_t *buf, uint32_t len) +{ + int ret; + + /* address must be 256 bytes aligned */ + if ((upg_priv == NULL) || (buf == NULL) || (addr & 0xff) || (len > 256)) { + dbg_print(is_debug_on, "Input para invalid upg_priv %p buf %p addr 0x%x len %u.\n", + upg_priv, buf, addr, len); + return -FW_SPI_FLASH_PARAM_ERR; + } + + /* Wait for the SPI port on the FPGA to become free again */ + ret = firmware_fpga_wait_ready(upg_priv); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_wait_ready failed ret %d.\n", ret); + return -FW_SPI_FLASH_BUSY; + } + + /* Configure write enable */ + ret = firmware_fpga_set_wr_enable(upg_priv); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_set_wr_enable failed ret %d.\n", ret); + return -FW_SPI_FLASH_WR_ENABLE_ERR; + } + + /* Read upgrade data */ + ret = firmware_fpga_fast_read(upg_priv, addr, buf, len); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_fast_read addr 0x%x len %u failed ret %d.\n", addr, len, ret); + return -FW_SPI_FLASH_RD_ERR; + } + + return 0; + +} + +static int firmware_upgreade_fpga_onetime(firmware_spi_logic_upg_t *upg_priv, + uint32_t flash_base, uint8_t *buf, uint32_t size) +{ + uint32_t offset, len, flash_addr, retry; + int ret, res; + uint8_t rbuf[FFPGA_UPG_DATA_SIZE]; + + offset = 0; + while(offset < size) { + flash_addr = flash_base + offset; + /* Erases a sector */ + if ((flash_addr % FIRMWARE_SPI_LOGIC_SECTOR_SIZE) == 0) { + ret = firmware_fpga_erase_sector(upg_priv, flash_addr); + if (ret < 0) { + dbg_print(is_debug_on, "firmware_fpga_erase_sector flash_addr 0x%x failed ret %d.\n", + flash_addr, ret); + goto exit; + } + } + + if (size > FFPGA_UPG_DATA_SIZE) { + len = FFPGA_UPG_DATA_SIZE; + } else { + len = size; + } + + /* first, Write data */ + ret = firmware_fpga_upg_write(upg_priv, flash_addr, buf + offset, len); + if (ret) { + dbg_print(is_debug_on, "firmware_fpga_upg_write addr 0x%x len 0x%x failed ret %d.\n", + flash_addr, len, ret); + ret = -FW_SPI_FLASH_UPG_ERR; + goto exit; + } + + /* Read back the data and compare the correctness of the data */ + for (retry = 0; retry < FPGA_UPG_RETRY_TIMES; retry++) { /*retry 3 times*/ + mem_clear(rbuf, len); + ret = firmware_fpga_upg_read(upg_priv, flash_addr, rbuf, len); + res = memcmp(rbuf, buf + offset, len); + if (ret || res) { + usleep(1000); + continue; + } + break; + } + + if (ret) { + dbg_print(is_debug_on, "firmware fpga read offset 0x%x len 0x%x failed ret %d.\n", flash_addr, len, ret); + ret = -FW_SPI_FLASH_RD_ERR; + goto exit; + } + + if (res) { + dbg_print(is_debug_on, "firmware fpga rbuf wbuf not equal, len 0x%x, check failed.\n", len); + ret = -FW_SPI_FLASH_DATA_CMP_ERR; + goto exit; + } + offset += len; + } + + dbg_print(is_debug_on, "Update success.\n"); + return FIRMWARE_SUCCESS; +exit: + dbg_print(is_debug_on, "Update failed.\n"); + return FIRMWARE_FAILED; +} + +static int firmware_upgrade_do_spi_logic(firmware_spi_logic_upg_t *current_upg_priv, + unsigned char *buf, uint32_t size) +{ + int i, ret; + uint32_t retry; + + i = 0; + retry = FIRMWARE_SPI_LOGIC_UPG_RETRY_CNT; + + ret = 0; + while(i < retry) { + ret = firmware_upgreade_fpga_onetime(current_upg_priv, current_upg_priv->flash_base, buf, size); + if (ret) { + i++; + dbg_print(is_debug_on, "firmware_upgreade_fpga_onetime size 0x%x failed ret %d.\n", size, ret); + continue; + } else { + dbg_print(is_debug_on, "firmware_upgreade_fpga_onetime success.\n"); + return 0; + } + } + + return ret; +} + +/* + * firmware_upgrade_spi_logic_dev + * function: FPGA SPI FLASH Firmware upgrade handler function + * @fd: param[in] sysfs device descriptor + * @buf: param[in] Update data + * @size: param[in] Update data size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_spi_logic_dev(int fd, uint8_t *buf, uint32_t size, name_info_t *info) +{ + int ret; + firmware_spi_logic_upg_t current_upg_priv; + + if ((fd < 0) || (buf == NULL) || (info == NULL)) { + dbg_print(is_debug_on, "Error:firmware upgrade spi logic dev parameters failed.\n"); + return FIRMWARE_FAILED; + } + + /* Gets the current logical device information */ + mem_clear(¤t_upg_priv, sizeof(firmware_spi_logic_upg_t)); + ret = firmware_upgrade_get_spi_logic_info(fd, ¤t_upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_get_spi_logic_info failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "current_upg_priv dev_path[%s] flash_base[0x%0x] ctrl_base[0x%0x]\n", + current_upg_priv.dev_path, current_upg_priv.flash_base, + current_upg_priv.ctrl_base); + + /* Enable upgrade access */ + ret = firmware_upgrade_spi_logic_init(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_init failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + /* Upgrade logic device */ + ret = firmware_upgrade_do_spi_logic(¤t_upg_priv, buf, size); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_do_spi_logic failed ret %d.\n", ret); + goto fail; + } + + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_SUCCESS; +fail: + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_FAILED; +} + +int firmware_fpga_upgrade_test(firmware_spi_logic_upg_t *current_upg_priv) +{ + int ret, i, j, num; + uint8_t *wbuf; + uint32_t retry; + + ret = FW_SPI_FLASH_RV_OK; + wbuf = (uint8_t *) malloc(current_upg_priv->test_size); + if (wbuf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory for test data buf, size=0x%x.\n", current_upg_priv->test_size); + ret = -FW_SPI_FLASH_NOT_SUPPORT_TEST; + goto exit; + } + mem_clear(wbuf, current_upg_priv->test_size); + /* Get random data */ + for (j = 0; j < current_upg_priv->test_size; j++) { + num = rand() % 256; + wbuf[j] = num & 0xff; + } + + i = 0; + retry = FIRMWARE_SPI_LOGIC_UPG_RETRY_CNT; + + ret = 0; + while(i < retry) { + ret = firmware_upgreade_fpga_onetime(current_upg_priv, current_upg_priv->test_base, wbuf, current_upg_priv->test_size); + if (ret) { + i++; + dbg_print(is_debug_on, "firmware_upgreade_fpga_onetime test size 0x%x failed ret %d.\n", + current_upg_priv->test_size, ret); + continue; + } else { + dbg_print(is_debug_on, "firmware_upgreade_fpga_onetime test success.\n"); + break; + } + } + free(wbuf); +exit: + return ret; +} + +/* + * firmware_upgrade_spi_logic_dev_test + * function: FPGA SPI FLASH Firmware upgrade test handler function + * @fd: param[in] sysfs device descriptor + * @buf: param[in] Update data + * @size: param[in] Update data size + * @info: param[in] Upgrade file information + * return value : success--FIRMWARE_SUCCESS; fail--FIRMWARE_FAILED + */ +int firmware_upgrade_spi_logic_dev_test(int fd, name_info_t *info) +{ + int ret; + firmware_spi_logic_upg_t current_upg_priv; + + if ((fd < 0) || (info == NULL)) { + dbg_print(is_debug_on, "Error:firmware upgrade spi logic dev parameters failed.\n"); + return FIRMWARE_FAILED; + } + + /* Gets the current logical device information */ + mem_clear(¤t_upg_priv, sizeof(firmware_spi_logic_upg_t)); + ret = firmware_upgrade_get_spi_logic_info(fd, ¤t_upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_get_spi_logic_info failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "current_upg_priv dev_path[%s] test_base[0x%0x] test_size[0x%x]\n", + current_upg_priv.dev_path, current_upg_priv.test_base, current_upg_priv.test_size); + if (current_upg_priv.test_size <= 0) { + dbg_print(is_debug_on, "Error: don't support flast test.\n"); + return FIRMWARE_NOT_SUPPORT; + } + + /* Enable upgrade access */ + ret = firmware_upgrade_spi_logic_init(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_init failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + /* Upgrade logic device */ + ret = firmware_fpga_upgrade_test(¤t_upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_do_spi_logic failed ret %d.\n", ret); + goto fail; + } + + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_SUCCESS; +fail: + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_FAILED; +} + +static int firmware_upgreade_spi_logic_dump(firmware_spi_logic_upg_t *upg_priv, + uint32_t offset, uint8_t *buf, uint32_t size) +{ + int ret, i; + uint32_t addr, buf_page, retry, cnt, rd_len; + + buf_page = FFPGA_UPG_DATA_SIZE; /* read data by BUF SIZE each time */ + + cnt = size / FFPGA_UPG_DATA_SIZE; + if (size % FFPGA_UPG_DATA_SIZE) { + cnt++; + } + dbg_print(is_debug_on, "need read number of times:%d.\n", cnt); + + for (i = 0; i < cnt; i++) { + addr = offset + i * FFPGA_UPG_DATA_SIZE; + if (i == (cnt - 1)) { + /* last time read remain size */ + rd_len = size - buf_page * i; + } else { + /* each time read buf page size */ + rd_len = buf_page; + } + + for (retry = 0; retry < FPGA_UPG_RETRY_TIMES; retry++) { + ret = firmware_fpga_upg_read(upg_priv, addr, buf, rd_len); + if (ret < 0) { + dbg_print(is_debug_on, "addr:0x%x read %d time failed. ret %d\n", addr, retry, ret); + continue; + } + break; + } + + if (ret < 0) { + dbg_print(is_debug_on, "finally addr:0x%x read failed ret %d\n", addr, ret); + return FIRMWARE_FAILED; + } + + buf += rd_len; /* buf pointer offset rd_len */ + } + + return FIRMWARE_SUCCESS; +} + +static int firmware_fpga_dump_read(int fd, uint32_t offset, uint8_t *buf, uint32_t len) +{ + int ret; + firmware_spi_logic_upg_t current_upg_priv; + + if ((fd < 0) || (buf == NULL)) { + dbg_print(is_debug_on, "Error:firmware upgrade spi logic dev parameters failed.\n"); + return FIRMWARE_FAILED; + } + + /* Gets the current logical device information */ + mem_clear(¤t_upg_priv, sizeof(firmware_spi_logic_upg_t)); + ret = firmware_upgrade_get_spi_logic_info(fd, ¤t_upg_priv); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_get_spi_logic_info failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "current_upg_priv dev_path[%s] flash_base[0x%0x] ctrl_base[0x%0x]\n", + current_upg_priv.dev_path, current_upg_priv.flash_base, + current_upg_priv.ctrl_base); + + /* Enable upgrade access */ + ret = firmware_upgrade_spi_logic_init(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_init failed ret %d.\n", ret); + return FIRMWARE_FAILED; + } + + /* read logic device */ + ret = firmware_upgreade_spi_logic_dump(¤t_upg_priv, offset, buf, len); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_do_spi_logic failed ret %d.\n", ret); + goto fail; + } + + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_SUCCESS; + +fail: + /* disable upgrade access */ + ret = firmware_upgrade_spi_logic_finish(fd); + if (ret < 0) { + dbg_print(is_debug_on, "Error:firmware_upgrade_spi_logic_finish failed ret %d.\n", ret); + } + + return FIRMWARE_FAILED; +} + +int firmware_upgrade_spi_logic_dev_dump(char *dev_name, uint32_t offset, + uint32_t len, char *record_file) +{ + int ret, dev_fd, file_fd; + char save_file[FIRMWARE_LOGIC_DEV_NAME_LEN]; + uint8_t *buf; + + dev_fd = open(dev_name, O_RDWR); + if (dev_fd < 0) { + dbg_print(is_debug_on, "Error: Failed to open %s, errno:%d.\n", dev_name, errno); + return FIRMWARE_FAILED; + } + + dbg_print(is_debug_on, "open dev file %s succeeded.\n", dev_name); + + buf = (uint8_t *) malloc(len); + if (buf == NULL) { + dbg_print(is_debug_on, "Error: Failed to malloc memory read %s data.\n", dev_name); + ret = FIRMWARE_FAILED; + goto free_dev_fd; + } + + mem_clear(buf, len); + ret = firmware_fpga_dump_read(dev_fd, offset, buf, len); + if (ret < 0) { + dbg_print(is_debug_on, "addr 0x%x read 0x%x failed ret:%d\n", offset, len, ret); + goto free_data; + } + + dbg_print(is_debug_on, "dump data succeeded. offset:0x%x, len:0x%x\n", offset, len); + + if (strcmp(record_file, "print") != 0) { /* record dump data on 'record_file' */ + mem_clear(save_file, FIRMWARE_LOGIC_DEV_NAME_LEN); + strncpy(save_file, record_file, FIRMWARE_LOGIC_DEV_NAME_LEN - 1); + file_fd = open(save_file, O_RDWR|O_CREAT|O_TRUNC, S_IRWXG|S_IRWXU|S_IRWXO); + if (file_fd < 0) { + dbg_print(is_debug_on, "open file %s fail, errno:%d.\n", save_file, errno); + ret = -ENOENT; + goto free_data; + } + + dbg_print(is_debug_on, "open save file %s succeeded.\n", save_file); + + ret = write(file_fd, buf, len); + if (ret < 0) { + dbg_print(is_debug_on, "write failed (errno: %d).\n", errno); + goto free_file_fd; + } + dbg_print(is_debug_on, "write save file %s succeeded.\n", save_file); + ret = FIRMWARE_SUCCESS; + } else { /* print reg on terminal by format */ + firmware_upgrade_printf_reg((uint8_t*)buf, len, offset); + ret = FIRMWARE_SUCCESS; + goto free_data; + } + +free_file_fd: + close(file_fd); +free_data: + free(buf); +free_dev_fd: + close(dev_fd); + + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.h new file mode 100644 index 000000000000..32f820161e86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/fw_upg_sysfs/fw_upg_spi_logic_dev.h @@ -0,0 +1,90 @@ +#ifndef __FW_UPG_SPI_LOGIC_DEV_H__ +#define __FW_UPG_SPI_LOGIC_DEV_H__ + +#define FIRMWARE_FPGA_WORD_LEN (4) + +#define FIRMWARE_LOGIC_DEV_NAME_LEN (64) /* the macro definition needs to same as FIRMWARE_DEV_NAME_LEN in firmware_sysfs_upgrade.h */ +#define FIRMWARE_SPI_LOGIC_UPG_RETRY_CNT (10) +#define FIRMWARE_SPI_LOGIC_UPG_BUFF_SIZE (256) +#define FIRMWARE_SPI_LOGIC_SECTOR_SIZE (0x10000) /* One sector is 64Kk */ + +#define FIRMWARE_UPG_RETRY_SLEEP_TIME (10) /* 10us */ +#define FIRMWARE_UPG_RETRY_TIME_CNT (1000) +#define FPGA_UPG_WAIT_SPI_RETRY_CNT (100) +#define FPGA_UPG_WAIT_SPI_RETRY_SLEEP_TIME (1000 * 10) /* 10ms */ + +#define FIRMWARE_FPGA_UPG_RETRY_CNT (100) + +/* FPGA upgrades related instruction definitions */ +#define FPGA_UPG_INSTRUTION_SE (0xD8) +#define FPGA_UPG_INSTRUTION_RDSR (0x05) +#define FPGA_UPG_INSTRUTION_WREN (0x06) +#define FPGA_UPG_INSTRUTION_PP (0x02) +#define FPGA_UPG_INSTRUTION_FR (0x0B) +#define FPGA_UPG_INSTRUTION_BE (0xC7) +#define FPGA_UPG_STATUS_MASK (0x1) +#define FPGA_UPG_ACCESS_ENABLE (0x3) +#define FPGA_UPG_SPI_STATUS_MASK (0x1) +#define FFPGA_UPG_DATA_SIZE (256) + +#define FPGA_UPG_RETRY_TIMES (3) + +/* FPGA upgrades the offset of the associated register */ +#define FPGA_UPG_STATUS_REG (0x180) +#define FPGA_UPG_SPI_CTRL_REG (0x184) +#define FPGA_UPG_WR_FLASH_STATUS_REG (0x188) +#define FPGA_UPG_RD_FLASH_STATUS_REG (0x18C) +#define FPGA_UPG_INSTRUCTION_REG (0x190) +#define FPGA_UPG_ADDR_REG (0x194) +#define FPGA_UPG_LENGTH_REG (0x198) +#define FPGA_UPG_DEVICE_ID_REG (0x19C) +#define FPGA_UPG_DROP_REQ_NUM_REG (0x1A8) + +typedef struct firmware_spi_logic_info_s { + char logic_dev_name[FIRMWARE_LOGIC_DEV_NAME_LEN]; /* Logical device name */ + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t ctrl_base; /* SPI upgrade control register base address */ + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +} firmware_spi_logic_info_t; + +typedef struct firmware_spi_logic_upg_s { + char dev_path[FIRMWARE_LOGIC_DEV_NAME_LEN]; + uint32_t flash_base; /* Flash Upgrade Address */ + uint32_t ctrl_base; /* SPI upgrade control register base address */ + uint32_t status_reg; + uint32_t spi_ctrl_reg; + uint32_t wr_flash_status_reg; + uint32_t rd_flash_status_reg; + uint32_t instruction_reg; + uint32_t addr_reg; + uint32_t length_reg; + uint32_t device_id_reg; + uint32_t drop_reg_num_reg; + uint32_t test_base; /* Test flash address */ + uint32_t test_size; /* Test flash size */ +}firmware_spi_logic_upg_t; + +typedef enum firmware_spi_flash_rv_s { + FW_SPI_FLASH_RV_OK = 0, + FW_SPI_FLASH_STATUS_ERR, + FW_SPI_FLASH_BUSY, + FW_SPI_FLASH_SPI_BUSY, + FW_SPI_FLASH_WR_ENABLE_ERR, + FW_SPI_FLASH_ERASE_ADDR_ERR, + FW_SPI_FLASH_ERASE_SECTOR_ERR, + FW_SPI_FLASH_WR_ERR, + FW_SPI_FLASH_RD_ERR, + FW_SPI_FLASH_PARAM_ERR, + FW_SPI_FLASH_UPG_ERR, + FW_SPI_FLASH_WR_LENGTH_ERR, + FW_SPI_FLASH_WR_ADDR_ERR, + FW_SPI_FLASH_SET_ACCESS_ERR, + FW_SPI_FLASH_DATA_CMP_ERR, + FW_SPI_FLASH_GET_INFO_ERR, + FW_SPI_FLASH_NOT_SUPPORT_TEST, +} firmware_spi_flash_rv_t; + +int fpga_test_spi_logic_flash(int argc, char *argv[]); + +#endif /* End of __FW_UPG_SPI_LOGIC_DEV_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/debug.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/debug.h new file mode 100644 index 000000000000..17dd42c3ef77 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/debug.h @@ -0,0 +1,34 @@ +/* + * + * debug.h + * firmware upgrade debug switch control + */ + +#ifndef __FIRMWARE_UPGRADE_DEBUG_H__ +#define __FIRMWARE_UPGRADE_DEBUG_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define DEBUG_INFO_LEN 20 +#define DEBUG_FILE "/tmp/.firmware_upgrade_debug" +#define DEBUG_ON_ALL "3" +#define DEBUG_ON_INFO "1" +#define DEBUG_OFF_INFO "0" + +enum debug_s { + DEBUG_OFF = 0, /* off debug */ + DEBUG_APP_ON, /* open app debug */ + DEBUG_ALL_ON, /* open all debug */ + DEBUG_IGNORE, /* ignore debug */ +}; + +#define dbg_print(debug, fmt, arg...) \ + if (debug == DEBUG_APP_ON || debug == DEBUG_ALL_ON) \ + { do{printf(fmt,##arg);} while(0); } + +/* firmware upgrade debug switch */ +extern int firmware_upgrade_debug(void); +extern int is_debug_on; + +#endif /* End of __FIRMWARE_UPGRADE_DEBUG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/firmware_app.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/firmware_app.h new file mode 100644 index 000000000000..581b2e969ec9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/firmware_app.h @@ -0,0 +1,172 @@ +#ifndef __FIRMWARE_APP_H__ +#define __FIRMWARE_APP_H__ + +#include +#include +#include +#include +#include +#include + +#define ERR_FW_CHECK_CPLD_UPGRADE (-601) /* File validation error */ +#define ERR_FW_CHECK_FPGA_UPGRADE (-602) +#define ERR_FW_MATCH_CPLD_UPGRADE (-603) /* No matching upgrade file found */ +#define ERR_FW_MATCH_FPGA_UPGRADE (-604) +#define ERR_FW_SAMEVER_CPLD_UPGRADE (-605) /* the same version */ +#define ERR_FW_SAMEVER_FPGA_UPGRADE (-606) +#define ERR_FW_DO_CPLD_UPGRADE (-607) /* upgrade fail */ +#define ERR_FW_DO_FPGA_UPGRADE (-608) +#define ERR_FW_UPGRADE (-609) /* other fail */ +#define ERR_FW_CHECK_UPGRADE (-610) /* File validation error */ +#define ERR_FW_MATCH_UPGRADE (-611) /* No matching upgrade file found */ +#define ERR_FW_SAMEVER_UPGRADE (-612) /* the same version */ +#define ERR_FW_DO_UPGRADE (-613) /* upgrade fail */ +#define ERR_FW_DO_UPGRADE_NOT_SUPPORT (-614) /* upgrade fail */ + +#define FIRMWARE_NOT_SUPPORT (-2) +#define FIRMWARE_FAILED (-1) +#define FIRMWARE_SUCCESS (0) + +#define FIRMWARE_ACTION_CHECK 0 +#define FIRMWARE_ACTION_MATCH 1 +#define FIRMWARE_ACTION_VERCHECK 2 +#define FIRMWARE_ACTION_UPGRADE 3 +#define FIRMWARE_ACTION_SUPPORT 4 + +#define FIRMWARE_UPGRADE_RETRY_CNT (10) +#define FIRMWARE_NAME_LEN (48) +#define FIRMWARE_SLOT_MAX_NUM (16) /* Maximum number of links supported by board cards */ + +/* Upgrade file headers */ +#define MAX_DEV_NUM 10 /* Maximum number of devices to which the upgrade file is applicable */ +#define INSMOD_DRIVER 1 /* insmod driver */ +#define RMMOD_DRIVER 0 /* rmmod driver */ +#define MAX_HEADER_SIZE 1000 /* Upgrade the maximum length of file header information */ +#define MAX_HEADER_KV_SIZE 64 /* Upgrade the maximum length of the file header key value */ + +/* Upgrade file header key values */ +#define FILEHEADER_DEVTYPE "DEVTYPE" +#define FILEHEADER_SUBTYPE "SUBTYPE" +#define FILEHEADER_TYPE "TYPE" +#define FILEHEADER_CHAIN "CHAIN" +#define FILEHEADER_CHIPNAME "CHIPNAME" +#define FILEHEADER_VERSION "VERSION" +#define FILEHEADER_FILETYPE "FILETYPE" +#define FILEHEADER_CRC "CRC" + +#define FIRMWARE_CPLD_NAME "cpld" +#define FIRMWARE_FPGA_NAME "fpga" + +/* ioctl publi command, the same as driver */ +#define FIRMWARE_COMMON_TYPE 'C' +#define FIRMWARE_GET_CHIPNAME _IOR(FIRMWARE_COMMON_TYPE, 0, char) /* get the chip name */ +#define FIRMWARE_GET_VERSION _IOR(FIRMWARE_COMMON_TYPE, 2, int) /* get version */ +#define FIRMWARE_SET_DEBUG_ON _IOW(FIRMWARE_COMMON_TYPE, 3, int) /* debug on */ +#define FIRMWARE_SET_DEBUG_OFF _IOW(FIRMWARE_COMMON_TYPE, 4, int) /* debug off */ + +/* firmware cpld driver ioctl command, the same as "firmware_driver\firmware_driver\include\firmware.h" */ +#define FIRMWARE_TYPE 'J' +#define FIRMWARE_PROGRAM _IOW(FIRMWARE_TYPE, 1, char) /* firmware upgrade ISC */ +#define FIRMWARE_READ_CHIP _IOR(FIRMWARE_TYPE, 5, int) /* read the contents of the chip */ +#define FIRMWARE_PROGRAM_JBI _IOW(FIRMWARE_TYPE, 6, char) /* firmware upgrade JBI */ + +/* firmware cpld ispvme driver ioctl command, the same as "firmware_driver\firmware_driver_ispvme\include\firmware_ispvme.h" */ +#define FIRMWARE_VME_TYPE 'V' +#define FIRMWARE_JTAG_TDI _IOR(FIRMWARE_VME_TYPE, 0, char) +#define FIRMWARE_JTAG_TDO _IOR(FIRMWARE_VME_TYPE, 1, char) +#define FIRMWARE_JTAG_TCK _IOR(FIRMWARE_VME_TYPE, 2, char) +#define FIRMWARE_JTAG_TMS _IOR(FIRMWARE_VME_TYPE, 3, char) +#define FIRMWARE_JTAG_EN _IOR(FIRMWARE_VME_TYPE, 4, char) +#define FIRMWARE_JTAG_INIT _IOR(FIRMWARE_VME_TYPE, 7, char) /* enable upgrade access */ +#define FIRMWARE_JTAG_FINISH _IOR(FIRMWARE_VME_TYPE, 8, char) /* disable upgrade access */ + +/* firmware sysfs driver ioctl command, the same as "firmware_driver\firmware_driver_sysfs\include\firmware_sysfs.h" */ +#define FIRMWARE_SYSFS_TYPE 'S' +#define FIRMWARE_SYSFS_INIT _IOR(FIRMWARE_SYSFS_TYPE, 0, char) /* enable upgrade access */ +#define FIRMWARE_SYSFS_FINISH _IOR(FIRMWARE_SYSFS_TYPE, 1, char) /* disable upgrade access */ +#define FIRMWARE_SYSFS_SPI_INFO _IOR(FIRMWARE_SYSFS_TYPE, 2, char) /* spi flash upgrade */ +#define FIRMWARE_SYSFS_DEV_FILE_INFO _IOR(FIRMWARE_SYSFS_TYPE, 3, char) /* sysfs upgrade */ +#define FIRMWARE_SYSFS_MTD_INFO _IOR(FIRMWARE_SYSFS_TYPE, 4, char) /* sysfs mtd upgrade */ + +/* VME file, used to distinguish the JTAG signal that needs to operate */ +#define JTAG_TDO 1 +#define JTAG_TCK 2 +#define JTAG_TDI 3 +#define JTAG_TMS 4 +#define JTAG_ENABLE 5 +#define JTAG_TRST 6 + +typedef struct name_info_s { + int card_type[MAX_DEV_NUM]; /* main board type */ + int sub_type[MAX_DEV_NUM]; /* sub board type */ + int type; /* device type */ + int chain; /* chain num */ + char chip_name[FIRMWARE_NAME_LEN]; /* chip name */ + char version[FIRMWARE_NAME_LEN]; /* version */ + int file_type; /* file type */ + unsigned int crc32; /* 4 byte CRC values */ +} name_info_t; + +typedef struct cmd_info_s { + uint32_t size; + void *data; +} cmd_info_t; + +enum firmware_type_s { + FIRMWARE_UNDEF_TYPE = 0, + FIRMWARE_CPLD, + FIRMWARE_FPGA, + FIRMWARE_SYSFS, + FIRMWARE_OTHER, +}; + +typedef enum firmware_file_type_s { + FIRMWARE_UNDEF_FILE_TYPE = 0, + FIRMWARE_VME, /* ispvme cpld, GPIO simulates JTAG */ + FIRMWARE_ISC, /* cpld, GPIO simulates JTAG */ + FIRMWARE_JBI, + FIRMWARE_SPI_LOGIC_DEV, /* FPGA SPI upgrde register upgrade flash */ + FIRMWARE_SYSFS_DEV, /* write file upgrade eeprom */ + FIRMWARE_MTD, /* upgrade mtd device */ + FIRMWARE_NONE, +} firmware_file_type_t; + +typedef struct firmware_file_name_s { + char firmware_file_name_str[MAX_HEADER_KV_SIZE]; + int firmware_file_type; +} firmware_file_name_t; + +extern int header_offset; + +/* CRC32 calculation */ +extern unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len); +/* VME file upgrade */ +extern int firmware_upgrade_ispvme(int file_fd, char *upgrade_file_name, name_info_t *info); +extern void writePort(unsigned char a_ucPins, unsigned char a_ucValue); +extern unsigned char readPort(); +extern void sclock(); +extern void ispVMStateMachine(signed char NextState); + +/* spi flash upgrade */ +extern int firmware_upgrade_spi_logic_dev(int fd, uint8_t *buf, uint32_t size, name_info_t *info); +/* spi flash upgrade test*/ +extern int firmware_upgrade_spi_logic_dev_test(int fd, name_info_t *info); +/* spi flash data print*/ +extern int firmware_upgrade_spi_logic_dev_dump(char *dev_name, uint32_t offset, uint32_t size, char *record_file); + +/* sysfs upgrade */ +extern int firmware_upgrade_sysfs(int fd, uint8_t *buf, uint32_t size, name_info_t *info); +/* sysfs upgrade test*/ +extern int firmware_upgrade_sysfs_test(int fd, name_info_t *info); + +/* isc upgrade */ +extern int firmware_upgrade_jtag(int fd, uint8_t *buf, uint32_t size, name_info_t *info); +/* isc upgrade test */ +extern int firmware_upgrade_jtag_test(int fd, uint8_t *buf, uint32_t size, name_info_t *info); + +/* mtd upgrade */ +extern int firmware_upgrade_mtd(int fd, uint8_t *buf, uint32_t size, name_info_t *info); +/* mtd upgrade test */ +extern int firmware_upgrade_mtd_test(int fd, name_info_t *info); + +#endif /* End of __FIRMWARE_APP_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/vmopcode.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/vmopcode.h new file mode 100644 index 000000000000..ae9d713ff86c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/firmware_upgrade/firmware_upgrade/include/vmopcode.h @@ -0,0 +1,192 @@ +/*************************************************************** +* +* This is the include file for Lattice Semiconductor's ispVM +* Embedded software application. +* +***************************************************************/ + +/*************************************************************** +* +* VME version. +* +* History: +* +***************************************************************/ + +#define VME_VERSION_NUMBER "12.2" + +/*************************************************************** +* +* Maximum declarations. +* +***************************************************************/ + +#define VMEHEXMAX 60000L /* The hex file is split 60K per file. */ +#define SCANMAX 64000L /* The maximum SDR/SIR burst. */ + +/*************************************************************** +* +* Supported JTAG state transitions. +* +***************************************************************/ + +#define RESET 0x00 +#define IDLE 0x01 +#define IRPAUSE 0x02 +#define DRPAUSE 0x03 +#define SHIFTIR 0x04 +#define SHIFTDR 0x05 +#define DRCAPTURE 0x06 + +/*************************************************************** +* +* Flow control register bit definitions. A set bit indicates +* that the register currently exhibits the corresponding mode. +* +***************************************************************/ + +#define INTEL_PRGM 0x0001 /* Intelligent programming is in effect. */ +#define CASCADE 0x0002 /* Currently splitting large SDR. */ +#define REPEATLOOP 0x0008 /* Currently executing a repeat loop. */ +#define SHIFTRIGHT 0x0080 /* The next data stream needs a right shift. */ +#define SHIFTLEFT 0x0100 /* The next data stream needs a left shift. */ +#define VERIFYUES 0x0200 /* Continue if fail is in effect. */ + +/*************************************************************** +* +* DataType register bit definitions. A set bit indicates +* that the register currently holds the corresponding type of data. +* +***************************************************************/ + +#define EXPRESS 0x0001 /* Simultaneous program and verify. */ +#define SIR_DATA 0x0002 /* SIR is the active SVF command. */ +#define SDR_DATA 0x0004 /* SDR is the active SVF command. */ +#define COMPRESS 0x0008 /* Data is compressed. */ +#define TDI_DATA 0x0010 /* TDI data is present. */ +#define TDO_DATA 0x0020 /* TDO data is present. */ +#define MASK_DATA 0x0040 /* MASK data is present. */ +#define HEAP_IN 0x0080 /* Data is from the heap. */ +#define LHEAP_IN 0x0200 /* Data is from intel data buffer. */ +#define VARIABLE 0x0400 /* Data is from a declared variable. */ +#define CRC_DATA 0x0800 /* CRC data is pressent. */ +#define CMASK_DATA 0x1000 /* CMASK data is pressent. */ +#define RMASK_DATA 0x2000 /* RMASK data is pressent. */ +#define READ_DATA 0x4000 /* READ data is pressent. */ +#define DMASK_DATA 0x8000 /* DMASK data is pressent. */ + +/*************************************************************** +* +* Pin opcodes. +* +***************************************************************/ + +#define signalENABLE 0x1C /* ispENABLE pin. */ +#define signalTMS 0x1D /* TMS pin. */ +#define signalTCK 0x1E /* TCK pin. */ +#define signalTDI 0x1F /* TDI pin. */ +#define signalTRST 0x20 /* TRST pin. */ + +/*************************************************************** +* +* Supported vendors. +* +***************************************************************/ + +#define VENDOR 0x56 +#define LATTICE 0x01 +#define ALTERA 0x02 +#define XILINX 0x03 + +/*************************************************************** +* +* Opcode definitions. +* +* Note: opcodes must be unique. +* +***************************************************************/ + +#define ENDDATA 0x00 /* The end of the current SDR data stream. */ +#define RUNTEST 0x01 /* The duration to stay at the stable state. */ +#define ENDDR 0x02 /* The stable state after SDR. */ +#define ENDIR 0x03 /* The stable state after SIR. */ +#define ENDSTATE 0x04 /* The stable state after RUNTEST. */ +#define TRST 0x05 /* Assert the TRST pin. */ +#define HIR 0x06 /* The sum of the IR bits of the leading devices. */ +#define TIR 0x07 /* The sum of the IR bits of the trailing devices. */ +#define HDR 0x08 /* The number of leading devices. */ +#define TDR 0x09 /* The number of trailing devices. */ +#define ispEN 0x0A /* Assert the ispEN pin. */ +#define FREQUENCY 0x0B /* The maximum clock rate to run the JTAG state machine. */ +#define STATE 0x10 /* Move to the next stable state. */ +#define SIR 0x11 /* The instruction stream follows. */ +#define SDR 0x12 /* The data stream follows. */ +#define TDI 0x13 /* The following data stream feeds into the device. */ +#define TDO 0x14 /* The following data stream is compared against the device. */ +#define MASK 0x15 /* The following data stream is used as mask. */ +#define XSDR 0x16 /* The following data stream is for simultaneous program and verify. */ +#define XTDI 0x17 /* The following data stream is for shift in only. It must be stored for the next XSDR. */ +#define XTDO 0x18 /* There is not data stream. The data stream was stored from the previous XTDI. */ +#define MEM 0x19 /* The maximum memory needed to allocate in order hold one row of data. */ +#define WAIT 0x1A /* The duration of delay to observe. */ +#define TCK 0x1B /* The number of TCK pulses. */ +#define SHR 0x23 /* Set the flow control register for right shift. */ +#define SHL 0x24 /* Set the flow control register for left shift. */ +#define HEAP 0x32 /* The memory size needed to hold one loop. */ +#define REPEAT 0x33 /* The beginning of the loop. */ +#define LEFTPAREN 0x35 /* The beginning of data following the loop. */ +#define VAR 0x55 /* Plac holder for loop data. */ +#define SEC 0x1C /* The delay time in seconds that must be observed. */ +#define SMASK 0x1D /* The mask for TDI data. */ +#define MAX 0x1E /* The absolute maximum wait time. */ +#define ON 0x1F /* Assert the targeted pin. */ +#define OFF 0x20 /* Dis-assert the targeted pin. */ +#define SETFLOW 0x30 /* Change the flow control register. */ +#define RESETFLOW 0x31 /* Clear the flow control register. */ +#define CRC 0x47 /* The following data stream is used for CRC calculation. */ +#define CMASK 0x48 /* The following data stream is used as mask for CRC calculation. */ +#define RMASK 0x49 /* The following data stream is used as mask for read and save. */ +#define READ 0x50 /* The following data stream is used for read and save. */ +#define ENDLOOP 0x59 /* The end of the repeat loop. */ +#define SECUREHEAP 0x60 /* Used to secure the HEAP opcode. */ +#define VUES 0x61 /* Support continue if fail. */ +#define DMASK 0x62 /* The following data stream is used for dynamic I/O. */ +#define COMMENT 0x63 /* Support SVF comments in the VME file. */ +#define HEADER 0x64 /* Support header in VME file. */ +#define FILE_CRC 0x65 /* Support crc-protected VME file. */ +#define LCOUNT 0x66 /* Support intelligent programming. */ +#define LDELAY 0x67 /* Support intelligent programming. */ +#define LSDR 0x68 /* Support intelligent programming. */ +#define LHEAP 0x69 /* Memory needed to hold intelligent data buffer */ +#define CONTINUE 0x70 /* Allow continuation. */ +#define LVDS 0x71 /* Support LVDS. */ +#define ENDVME 0x7F /* End of the VME file. */ +#define HIGH 0x80 /* Assert the targeted pin. */ +#define LOW 0x81 /* Dis-assert the targeted pin. */ +#define ENDFILE 0xFF /* End of file. */ + +/*************************************************************** +* +* ispVM Embedded Return Codes. +* +***************************************************************/ + +#define VME_VERIFICATION_FAILURE -1 +#define VME_FILE_READ_FAILURE -2 +#define VME_VERSION_FAILURE -3 +#define VME_INVALID_FILE -4 +#define VME_ARGUMENT_FAILURE -5 +#define VME_CRC_FAILURE -6 + +/*************************************************************** +* +* Type definitions. +* +***************************************************************/ + +/* Support LVDS */ +typedef struct { + unsigned short usPositiveIndex; + unsigned short usNegativeIndex; + unsigned char ucUpdate; +} LVDSPair; diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Makefile new file mode 100644 index 000000000000..1701b5f62114 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Makefile @@ -0,0 +1,18 @@ +top_srcdir:=$(shell pwd) +include $(top_srcdir)/Rules.mk + +firmware-y:= +firmware-y += fw_upgrade + +.PHONY: all +all: build + +.PHONY: build +build: $(firmware-y) +$(foreach dir,$(firmware-y),$(eval $(call compile_dirs,$(dir)))) + +.PHONY: rpmpkg +rpmpkg: +ifeq ("$(CONFIG_CPLD_UPGRADE_ISPVME)", "y") + #$(RPMPKG) $(install_cpld_dir) firmware-cpld-ispvme.spec git +endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Rules.mk b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Rules.mk new file mode 100644 index 000000000000..5fb5a09d34fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/Rules.mk @@ -0,0 +1,42 @@ +CC ?= $(CROSS)gcc +AR ?= $(CROSS)ar +AS ?= $(CROSS)as +LD ?= $(CROSS)ld +STRIP ?= $(CROSS)strip + +install_root:=${top_srcdir}/images + +install_header_dir:=${install_root}/header +install_adir:=$(install_root)/lib +install_symbol_dir:=$(install_root)/symbol +symbol_files:=$(shell find $(EXPORT_SYMBOL) -name 'Module.symvers') +# +# symbol_files += $(shell find $(install_symbol_dir) -name 'Module.symvers') +# KBUILD_EXTRA_SYMBOLS += $(symbol_files) +# export KBUILD_EXTRA_SYMBOLS + +# top root: install_rootfs_dir +install_rootfs_dir:=$(install_root)/rootfs + +install_sodir:=$(install_rootfs_dir)/$(INSTALL_SODIR) + +install_usr_bin_dir:=$(install_rootfs_dir)/usr/bin +install_sbin_dir:=$(install_rootfs_dir)/sbin +install_etc_dir:=$(install_rootfs_dir)/etc + +export INSTALL_MOD_PATH:=$(ROOT) + +BUILD_CFLAGS:=$(CFLAGS) -I$(install_header_dir) +BUILD_LDFLAGS:=$(LDFLAGS) -L/$(install_sodir) -L/$(install_adir) + +define compile_dirs +.PHONY: $(1) +$(1): + @echo;echo "building $(1)..." + @$(MAKE) -C ${1} +endef + +compile.c = $(CC) $(BUILD_CFLAGS) -d -c -o $@ $< +%.o: %.c + $(compile.c) + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/Makefile new file mode 100644 index 000000000000..8b4bca739087 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/Makefile @@ -0,0 +1,39 @@ +include ../Rules.mk + +OBJ = fw_upgrade.o fw_upgrade_debug.o + +LIB += $(BUILD_CFALGS) $(BUILD_LDFLAGS) -lpthread +ifdef ENABLE_GCOV +ifeq ($(ENABLE_GCOV), y) +LIB += -fprofile-arcs +endif +endif # ENABLE_GCOV + +APP = fw_upgrade +BUILD_DIR = tmp +ELF_FILE = $(BUILD_DIR)/$(APP) +MAP_FILE = $(BUILD_DIR)/$(APP).map.sym +INCLUDE = -Iinclude +CFLAGS+=-Wall -W -g + +.PHONY: build +build:make-dir $(addprefix $(BUILD_DIR)/,$(OBJ)) + $(CC) -o $(ELF_FILE) $(addprefix $(BUILD_DIR)/,$(OBJ)) $(LINKFLAGS) $(LIB) + + cp -p $(ELF_FILE) $(common_out_put_dir) + +.PHONY: make-dir +make-dir: + @mkdir -p $(BUILD_DIR) + +$(BUILD_DIR)/%.o:%.c + $(CC) -c $(CFLAGS) $(INCLUDE) $< -o $@ + +.PHONY: install +install: + echo "fw_upgrade install success." + cp -p $(ELF_FILE) $(common_out_put_dir) + +.PHONY: clean +clean: + rm -rf $(BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c new file mode 100644 index 000000000000..2045608d5c3b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c @@ -0,0 +1,1632 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fw_upgrade.h" + +static flash_info_t flash_info[] = { + { + .flash_name = "M25L6433F", + .flash_size = M32, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX25L6433F, + .block_size = STEP_64, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "S25FL512S", + .flash_size = M64, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = S25FL512S, + .block_size = STEP_256, + .full_erase = 0, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "MX25l512", + .flash_size = M64, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX25l512, + .block_size = STEP_64, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "STM25P64", + .flash_size = M12, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = STM25P64, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "STM25P128", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = STM25P128, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "N25Q256", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = N25Q256, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "N25Q512", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = N25Q512, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25X16", + .flash_size = M3, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25X16, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25X64", + .flash_size = M12, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25X64, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25Q64BV", + .flash_size = M12, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25Q64BV, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25Q128BV", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25Q128BV, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "W25Q256FV", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = W25Q256FV, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "MX25L1605D", + .flash_size = M32, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX25L1605D, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "MX25L12805D", + .flash_size = M32, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX25L12805D, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "MX66L1G45G", + .flash_size = M128, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = MX66L1G45G, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, + { + .flash_name = "GD25Q256", + .flash_size = M16, + .flash_type = SPI, + .page_size = BYTE_256, + .flash_id = GD25Q256, + .block_size = STEP_256, + .full_erase = 1, + .erase_block_command = BLOCK_ERASE_64, + .page_program = COMMON_PAGE_PROGRAM, + }, +}; + +static int debug_on; + +static void help(void) +{ + printf("------------------------------BMC Upgrade Tool--------------------------------\n"); + printf("Program Flash:\n"); + printf("\tfw_upgrade upgrade [file name] [chip select: 0 | 1 | 2] "); + printf("[erase type: full | block]\n"); + printf("\t[file name] if file is not located at /home/admin, path should be added\n"); + printf("\t[chip select] 0:master, 1:slave, 2:both\n"); + printf("\t[erase type] choose a way to erase chip, full erase would be faster\n"); + printf("Read BMC Reg:\n"); + printf("\tfw_upgrade rd [address] [length]\n"); + printf("\t[address(Hexadecimal)] register address of BMC\n"); + printf("\t[length(decimal)] length of read data, should be times of 4\n"); + + return; +} + +static int set_ioport_rw_access(void) +{ + + if ( iopl(3) < 0) { + printf("Can't get access to /dev/port \n"); + return -1; + } + + return 0; +} + +static int get_file_size(char *file_name) +{ + FILE * pFile; + int size; + + pFile = fopen(file_name,"rb"); + if (pFile == NULL) { + printf("Error opening file\n"); + return -1; + } + fseek (pFile, 0, SEEK_END); + size = ftell(pFile); + fclose (pFile); + return size; +} + +static uint8_t _read(uint16_t addr) +{ + return inb(addr); +} + +static void _write(uint16_t addr, uint8_t val) +{ + outb(val, addr); + + return; +} + +static void write_addr_port(uint8_t addr_val, uint16_t addr_port) +{ + _write(addr_port, addr_val); + + return; +} + +static void write_data_port(uint8_t val, uint16_t data_port) +{ + _write(data_port, val); + + return; +} + +static uint8_t read_data_port(uint16_t data_port) +{ + return _read(data_port); +} + +static void write_ilpc2ahb_addr(uint32_t addr) +{ + int i; + + for (i = 0; i < 4; i++) { + write_addr_port(SUPERIO_REG0 + i, LPC_ADDR_PORT); + write_data_port((addr >> (8 * (3 - i))) & MASK, LPC_DATA_PORT); + } + + return; +} + +static void write_ilpc2ahb_data(uint32_t data) +{ + int i; + + for (i = 0; i < 4; i++) { + write_addr_port(SUPERIO_REG4 + i, LPC_ADDR_PORT); + write_data_port((data >> (8 * (3 - i))) & MASK, LPC_DATA_PORT); + } + + return; +} + +static uint32_t read_ilpc2ahb_data(void) +{ + int i, tmp; + uint32_t res; + + res = 0; + for (i = 0; i < 4; i++) { + write_addr_port(SUPERIO_REG4 + i, LPC_ADDR_PORT); + tmp = read_data_port(LPC_DATA_PORT); + res |= (tmp << (8 * (3 - i))); + } + + return res; +} + +static void trigger_ilpc2ahb_read(void) +{ + write_addr_port(SUPERIO_FE, LPC_ADDR_PORT); + read_data_port(LPC_DATA_PORT); + + return; +} + +static void trigger_ilpc2ahb_write(void) +{ + write_addr_port(SUPERIO_FE, LPC_ADDR_PORT); + write_data_port(TOGGLE_WRITE, LPC_DATA_PORT); + + return; +} + +static uint32_t read_bmc_reg(uint32_t addr) +{ + uint32_t res; + + write_ilpc2ahb_addr(addr); + trigger_ilpc2ahb_read(); + res = read_ilpc2ahb_data(); + + return res; +} + +static void write_bmc_reg(uint32_t addr, uint32_t val) +{ + write_ilpc2ahb_addr(addr); + write_ilpc2ahb_data(val); + trigger_ilpc2ahb_write(); + + return; +} + +static uint32_t read_bmc_flash_data(void) +{ + uint32_t res; + + trigger_ilpc2ahb_read(); + res = read_ilpc2ahb_data(); + + return res; +} + +static void write_bmc_flash_data(uint32_t data) +{ + write_ilpc2ahb_data(data); + trigger_ilpc2ahb_write(); + + return; +} + +static void write_bmc_flash_addr(uint32_t addr) +{ + int i; + + for (i = 0; i < 4; i++) { + write_addr_port(SUPERIO_REG4 + i, LPC_ADDR_PORT); + write_data_port((addr >> (8 * i)) & MASK, LPC_DATA_PORT); + } + + trigger_ilpc2ahb_write(); + + return; +} + +static void enable_bytes(int byte) +{ + write_addr_port(SUPERIO_REG8, LPC_ADDR_PORT); + switch (byte) { + case BYTE1: + write_data_port(SUPERIO_A0 + BYTE1_VAL, LPC_DATA_PORT); + break; + case BYTE2: + write_data_port(SUPERIO_A0 + BYTE2_VAL, LPC_DATA_PORT); + break; + case BYTE4: + write_data_port(SUPERIO_A0 + BYTE4_VAL, LPC_DATA_PORT); + break; + default: + write_data_port(SUPERIO_A0 + BYTE_RESERVED, LPC_DATA_PORT); + break; + } + + return; +} + +static void pull_ce_down(flash_info_t* info) +{ + write_bmc_reg(info->ce_control_reg, USER_MODE_PULL_CE_DOWN); + + return; +} + +static void pull_ce_up(flash_info_t* info) +{ + write_bmc_reg(info->ce_control_reg, USER_MODE_PULL_CE_UP); + + return; +} + +static void send_cmd(uint32_t flash_base_addr, int cmd) +{ + write_ilpc2ahb_addr(flash_base_addr); + enable_bytes(1); + write_addr_port(SUPERIO_REG7, LPC_ADDR_PORT); + write_data_port(cmd & MASK, LPC_DATA_PORT); + trigger_ilpc2ahb_write(); + enable_bytes(4); + + return; +} + +static void send_cmd_to_flash(flash_info_t* info, int cmd) +{ + pull_ce_down(info); + send_cmd(info->flash_base_addr, cmd); + pull_ce_up(info); + + return; +} + +static void check_data_length(void) +{ + uint8_t tmp; + /* Data length check, 4 bytes */ + write_addr_port(SUPERIO_REG8, LPC_ADDR_PORT); + tmp = read_data_port(LPC_DATA_PORT); + if (tmp != SUPERIO_A2) { + write_data_port(SUPERIO_A2, LPC_DATA_PORT); + } + + return; +} + +static void enable_ilpc2ahb(void) +{ + /* Write 0xAA then write 0xA5 twice to enable super IO*/ + write_addr_port(DISABLE_LPC, LPC_ADDR_PORT); + write_addr_port(ENABLE_LPC, LPC_ADDR_PORT); + write_addr_port(ENABLE_LPC, LPC_ADDR_PORT); + + /* Enable iLPC2AHB */ + write_addr_port(SUPERIO_07, LPC_ADDR_PORT); + write_data_port(LPC_TO_AHB, LPC_DATA_PORT); + write_addr_port(SUPERIO_30, LPC_ADDR_PORT); + write_data_port(ENABLE_LPC_TO_AHB, LPC_DATA_PORT); + + /* Data length */ + check_data_length(); + + return; +} + +static void disable_ilpc2ahb(void) +{ + /* disable ilpc2ahb */ + write_addr_port(SUPERIO_30, LPC_ADDR_PORT); + write_data_port(DISABLE_LPC_TO_AHB, LPC_DATA_PORT); + /* disable super IO */ + write_addr_port(DISABLE_LPC, LPC_ADDR_PORT); + + return; +} + +/* Enable CPU */ +static void enable_cpu(void) +{ + /* unlock SCU register */ + write_bmc_reg(SCU_ADDR, UNLOCK_SCU_KEY); + /* enable ARM */ + write_bmc_reg(REBOOT_CPU_REGISTER, SET_BMC_CPU_BOOT); + /* lock SCU register */ + write_bmc_reg(SCU_ADDR, LOCK_SCU_KEY); + + return; +} + +/* diasble CPU */ +static void disable_cpu(void) +{ + uint32_t scu_hw_strap_val; + + /* unlock SCU register */ + write_bmc_reg(SCU_ADDR, UNLOCK_SCU_KEY); + /* disable ARM */ + scu_hw_strap_val = read_bmc_reg(HARDWARE_STRAP_REGISTER); + write_bmc_reg(HARDWARE_STRAP_REGISTER, scu_hw_strap_val |0x01); + /* lock SCU register */ + write_bmc_reg(SCU_ADDR, LOCK_SCU_KEY); + + return; +} + +static void enable_upgrade(void) +{ + + enable_ilpc2ahb(); + /* diasble CPU */ + disable_cpu(); + /* init CE control register */ + write_bmc_reg(CE0_CONTROL_REGISTER, 0); + write_bmc_reg(CE1_CONTROL_REGISTER, 0); + /* disable WDT2 */ + write_bmc_reg(WATCHDOG2_CONTROL, DISABLE_WATCHDOG); + + return; +} + +static void disable_upgrade(void) +{ + enable_cpu(); + dbg_print(debug_on, "DEBUG 0x%x\n", read_bmc_reg(HARDWARE_STRAP_REGISTER)); + disable_ilpc2ahb(); + + return; +} + +static void watchdog_status_debug(void) +{ + uint32_t watchdog_reg; + + /* Watchdog Control Register */ + watchdog_reg = read_bmc_reg(WATCHDOG2_CONTROL); + dbg_print(debug_on,"Watchdog Control Register: 0x%x\n", watchdog_reg); + dbg_print(debug_on,"Watchdog Enable Signal: 0x%x\n", watchdog_reg & BIT1); + dbg_print(debug_on,"Watchdog Reset SyS En: 0x%x\n", (watchdog_reg & BIT2) >> 1); + dbg_print(debug_on,"Watchdog Reset Mode: 0x%x\n", (watchdog_reg & (BIT6 | BIT7)) >> 5); + switch (watchdog_reg & (BIT6 | BIT7)) { + case SOC_SYS: + dbg_print(debug_on,"\tReset Mode En: SoC System\n"); + break; + case FULL_CHIP: + dbg_print(debug_on,"\tReset Mode En: Full Chip\n"); + break; + case ARM_CPU: + dbg_print(debug_on,"\tReset Mode En: ARM Cpu\n"); + break; + default: + break; + } + + /* Watchdog Timeout Status Register */ + watchdog_reg = read_bmc_reg(WATCHDOG2_TSR); + dbg_print(debug_on,"Watchdog Timeout Occur: 0x%x\n", watchdog_reg & BIT1); + dbg_print(debug_on,"Watchdog Boot from: CD%d\n", watchdog_reg & BIT2); + dbg_print(debug_on,"Watchdog Interrupt Occur: 0x%x\n", watchdog_reg & BIT3); + + return; +} + +/* CE Type Setting Register */ +static void ce_type_setting_debug(void) +{ + uint32_t fmc_reg; + + fmc_reg = read_bmc_reg(FMC_CE_TYPE_SETTING_REG); + if ((fmc_reg & CE0_SPI_TYPE) == SPI) { + dbg_print(debug_on,"CE0 Type Seeting: 0x%x, Type: SPI\n", fmc_reg & CE0_SPI_TYPE); + } else { + dbg_print(debug_on,"CE0 Type Seeting: 0x%x, Type: Unknown\n", fmc_reg & CE0_SPI_TYPE); + } + if (((fmc_reg & CE1_SPI_TYPE) >> BIT2) == SPI) { + dbg_print(debug_on,"CE1 Type Seeting: 0x%x, Type: SPI\n", (fmc_reg & CE1_SPI_TYPE) >> BIT2); + } else { + dbg_print(debug_on,"CE1 Type Seeting: 0x%x, Type: Unknown\n", (fmc_reg & CE1_SPI_TYPE) >> BIT2); + } + + return; +} +/* CE Control Register */ +static void ce_control_debug(void) +{ + uint32_t fmc_reg; + + fmc_reg = read_bmc_reg(CE_CONTROL_REGISTER); + dbg_print(debug_on,"CE0 Address Mode: 0x%x, Mode: %d Bytes\n", + fmc_reg & BIT1, (fmc_reg & BIT1) + 3); + dbg_print(debug_on,"CE1 Address Mode: 0x%x, Mode: %d Bytes\n", + (fmc_reg & BIT2) >> 1, ((fmc_reg & BIT2) >> 1) + 3); + + return; +} + +/* Interrupt Control & Status Register */ +static void irq_control_status_debug(void) +{ + uint32_t fmc_reg; + + fmc_reg = read_bmc_reg(INR_STATUS_CONTROL_REGISTER); + dbg_print(debug_on,"SPI Write Address Protected Interrupt EN: 0x%x\n", fmc_reg & BIT2); + dbg_print(debug_on,"SPI Command Abort Interrupt EN: 0x%x\n", fmc_reg & BIT3); + dbg_print(debug_on,"SPI Write Address Protected Status: 0x%x, Status: %s\n", + RIGHT_SHIFT_8(fmc_reg) & BIT2, (RIGHT_SHIFT_8(fmc_reg) & BIT2) == BIT2 ? "Occur" : "Normal"); + dbg_print(debug_on,"SPI Command Abort Status: 0x%x, Status: %s\n", + RIGHT_SHIFT_8(fmc_reg) & BIT3, (RIGHT_SHIFT_8(fmc_reg) & BIT3) == BIT3 ? "Occur" : "Normal"); + /*Clear Abnormal Status*/ + if ((RIGHT_SHIFT_8(fmc_reg) & BIT3) || (RIGHT_SHIFT_8(fmc_reg) & BIT2)) { + write_bmc_reg(INR_STATUS_CONTROL_REGISTER, CLEAR_INR_STATUS_CONTROL); + } + + return; +} + +/* Command Control Register */ +static void command_control_debug(void) +{ + uint32_t fmc_reg; + + fmc_reg = read_bmc_reg(COMMAND_CONTROL_REGISTER); + dbg_print(debug_on,"Data Byte Line 0: %s\n", ((fmc_reg & BIT4) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Data Byte Line 1: %s\n", ((fmc_reg & BIT3) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Data Byte Line 2: %s\n", ((fmc_reg & BIT2) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Data Byte Line 3: %s\n", ((fmc_reg & BIT1) != 0) ? "Disable" : "Enable"); + + dbg_print(debug_on,"Address Byte Line 0: %s\n", ((fmc_reg & BIT8) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Address Byte Line 1: %s\n", ((fmc_reg & BIT7) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Address Byte Line 2: %s\n", ((fmc_reg & BIT6) != 0) ? "Disable" : "Enable"); + dbg_print(debug_on,"Address Byte Line 3: %s\n", ((fmc_reg & BIT5) != 0) ? "Disable" : "Enable"); + + return; +} + +static void ce_control_reg_debug(void) +{ + uint32_t fmc_reg; + + /* CE0 Control Register */ + fmc_reg = read_bmc_reg(CE0_CONTROL_REGISTER); + switch (fmc_reg & (BIT1 | BIT2)){ + case NORMAL_READ: + dbg_print(debug_on,"CE0 Command Mode: Normal Read\n"); + break; + case READ_MODE: + dbg_print(debug_on,"CE0 Command Mode: Read Command\n"); + break; + case WRITE_MODE: + dbg_print(debug_on,"CE0 Command Mode: Write Command\n"); + break; + case USER_MODE: + dbg_print(debug_on,"CE0 Command Mode: User Mode\n"); + break; + default: + break; + } + switch((RIGHT_SHIFT_24(fmc_reg) & (BIT5 | BIT6 | BIT7))){ + case 0: + dbg_print(debug_on,"CE0 IO Mode: Single Mode\n"); + break; + case 2: + case 3: + dbg_print(debug_on,"CE0 IO Mode: Dual Mode\n"); + break; + default: + break; + } + + dbg_print(debug_on,"CE0 Inactive Pulse Width: %d HCLK\n", + DEFAULT_WIDTH - (RIGHT_SHIFT_24(fmc_reg) & (BIT1 | BIT2 | BIT3 | BIT4))); + dbg_print(debug_on,"CE0 Data Input Mode: %s Mode\n", (fmc_reg & BIT4) == 0 ? "Single" : "Dual"); + dbg_print(debug_on,"CE0 MSB | LSB: %s First\n", (fmc_reg & BIT6) == 0 ? "MSB" : "LSB"); + + /* CE1 Control Register */ + fmc_reg = read_bmc_reg(CE1_CONTROL_REGISTER); + switch (fmc_reg & (BIT1 | BIT2)){ + case NORMAL_READ: + dbg_print(debug_on,"CE1 Command Mode: Normal Read\n"); + break; + case READ_MODE: + dbg_print(debug_on,"CE1 Command Mode: Read Command\n"); + break; + case WRITE_MODE: + dbg_print(debug_on,"CE1 Command Mode: Write Command\n"); + break; + case USER_MODE: + dbg_print(debug_on,"CE1 Command Mode: User Mode\n"); + break; + default: + break; + } + switch((RIGHT_SHIFT_24(fmc_reg) & (BIT5 | BIT6 | BIT7))){ + case 0: + dbg_print(debug_on,"CE1 IO Mode: Single Mode\n"); + break; + case 2: + case 3: + dbg_print(debug_on,"CE1 IO Mode: Dual Mode\n"); + break; + default: + break; + } + + dbg_print(debug_on,"CE1 Inactive Pulse Width: %d HCLK\n", + DEFAULT_WIDTH - (RIGHT_SHIFT_24(fmc_reg) & (BIT1 | BIT2 | BIT3 | BIT4))); + dbg_print(debug_on,"CE1 Data Input Mode: %s Mode\n", (fmc_reg & BIT4) == 0 ? "Single" : "Dual"); + dbg_print(debug_on,"CE1 MSB | LSB: %s First\n", (fmc_reg & BIT6) == 0 ? "MSB" : "LSB"); + + return; +} + +static void fmc_debug(void) +{ + ce_type_setting_debug(); + ce_control_debug(); + irq_control_status_debug(); + command_control_debug(); + ce_control_reg_debug(); + + return; +} + +/* Enable WatchDog to reset BMC*/ +static void enable_watchdog(int cs) +{ + uint32_t enable_watch_cmd; + + enable_watch_cmd = (cs == CE0) ? ENABLE_WATCHDOG : ENABLE_WATCHDOG | BOOT_DEFAULT_MASK; + write_bmc_reg(WATCHDOG2_CLEAR_STATUS, CLEAR_WATCHDOG_STATUS); + write_bmc_reg(WATCHDOG2_RESET_FUN_MASK, WATCHDOG_GATEMASK); + write_bmc_reg(WATCHDOG2_RELOAD_VALUE, WATCHDOG_NEW_COUNT); + write_bmc_reg(WATCHDOG2_COUNTER_RST, WATCHDOG_RELOAD_COUNTER); + write_bmc_reg(WATCHDOG2_CONTROL, enable_watch_cmd); + + return; +} + +static void bmc_reboot(int cs) +{ + enable_watchdog(cs); + watchdog_status_debug(); + disable_upgrade(); + printf("Upgrade-Complete, BMC rebooting...\n"); + + return; +} + +static int get_current_bmc(void) +{ + return (read_bmc_reg(WATCHDOG2_TSR) & 0x02) >> 1; +} + +static void get_flash_base_and_ce_ctrl(int current_bmc, int cs, uint32_t *flash_base_addr, uint32_t *ce_ctrl_addr) +{ + uint32_t ce0_addr_range_reg_val, ce0_decode_addr; + uint32_t ce1_addr_range_reg_val, ce1_decode_addr; + + ce0_addr_range_reg_val = read_bmc_reg(CE0_ADDRESS_RANGE_REGISTER); + ce0_decode_addr = SEGMENT_ADDR_START(ce0_addr_range_reg_val); + ce1_addr_range_reg_val = read_bmc_reg(CE1_ADDRESS_RANGE_REGISTER); + ce1_decode_addr = SEGMENT_ADDR_START(ce1_addr_range_reg_val); + dbg_print(debug_on,"CE0 addr decode range reg value:0x%08x, decode addr:0x%08x.\n", + ce0_addr_range_reg_val, ce0_decode_addr); + dbg_print(debug_on,"CE1 addr decode range reg value:0x%08x, decode addr:0x%08x.\n", + ce1_addr_range_reg_val, ce1_decode_addr); + + if (((current_bmc == CURRENT_MASTER) && (cs ==CE0)) || ((current_bmc == CURRENT_SLAVE) && (cs ==CE1))) { + *ce_ctrl_addr = CE0_CONTROL_REGISTER; + *flash_base_addr = ce0_decode_addr; + } else { + *ce_ctrl_addr = CE1_CONTROL_REGISTER; + *flash_base_addr = ce1_decode_addr; + } + + return; +} + +static int get_flash_id(uint32_t flash_base_addr, uint32_t ce_ctrl_addr) +{ + uint32_t origin_flash_id, flash_id; + + write_bmc_reg(ce_ctrl_addr, USER_MODE_PULL_CE_DOWN); + send_cmd(flash_base_addr, READID); + origin_flash_id = read_bmc_flash_data(); + write_bmc_reg(ce_ctrl_addr, USER_MODE_PULL_CE_UP); + flash_id = origin_flash_id & 0xFFFFFF; + dbg_print(debug_on,"origin flash id:0x%x, flash id:0x%x\n", origin_flash_id, flash_id); + + return flash_id; +} + +static uint8_t get_flash_status(flash_info_t* info) +{ + uint8_t flash_status; + + pull_ce_down(info); + + send_cmd(info->flash_base_addr, READ_FLASH_STATUS); + + flash_status = read_bmc_flash_data() & MASK; + pull_ce_up(info); + + dbg_print(debug_on,"get_flash_status:0x%x\n", flash_status); + return flash_status; +} + +static int check_flash_write_enable(flash_info_t* info) +{ + uint8_t flash_status; + int i, count; + + count = FLASH_WEL_TIMEOUT / FLASH_WEL_SLEEP_TIME; + for (i = 0; i <= count; i++) { + flash_status = get_flash_status(info); + if ((flash_status & FLASH_WRITE_ENABLE_MASK) != FLASH_WRITE_ENABLE_MASK) { + usleep(FLASH_WEL_SLEEP_TIME); + } else { + dbg_print(debug_on,"Check flash WEL success, RDSR:0x%x\n", flash_status); + return 0; + } + } + printf("Check flash WEL timeout, RDSR:0x%x\n", flash_status); + return -1; +} + +static int check_flash_write_process(flash_info_t* info, int timeout, int sleep_time) +{ + int i, count; + uint8_t flash_status; + + count = timeout / sleep_time; + for (i = 0; i <= count; i++) { + flash_status = get_flash_status(info); + if ((flash_status & FLASH_WIP_MASK) != 0) { + usleep(sleep_time); + } else { + dbg_print(debug_on,"Check flash WIP success, RDSR:0x%x\n", flash_status); + return 0; + } + } + printf("Check flash WIP timeout, RDSR:0x%x.\n", flash_status); + return -1; +} + +static int flash_write_enable(flash_info_t* info) +{ + int ret; + + send_cmd_to_flash(info, WRITE_ENABLE_FLASH); + ret = check_flash_write_enable(info); + if (ret < 0) { + return -1; + } + return 0; +} + +static void send_block_erase_cmd(flash_info_t* info, uint32_t block_addr) +{ + pull_ce_down(info); + send_cmd(info->flash_base_addr, info->erase_block_command); + write_bmc_flash_addr(block_addr); /* Erase Block addr */ + pull_ce_up(info); + + return; +} + +static void send_chip_erase_cmd(flash_info_t* info) +{ + send_cmd_to_flash(info, CHIP_ERASE_FLASH); + + return; +} + +static int write_bmc_flash_page(flash_info_t* info, uint32_t page_addr, uint8_t *p, int len) +{ + int pos; + + if (len % 4) { + printf("Page size %d invalid.\n", len); + return -1; + } + + pos = 0; + pull_ce_down(info); + send_cmd(info->flash_base_addr, info->page_program); + write_bmc_flash_addr(page_addr); /* page address */ + while (len) { + write_bmc_flash_data((*(uint32_t *)(p + pos))); + pos += 4; + len -= 4; + } + pull_ce_up(info); + + return 0; +} + +static int erase_chip_full(flash_info_t* info) +{ + time_t timep; + int ret; + + if (info->full_erase == 0) { + printf("Flash not support full erase function.\n"); + return -1; + } + + ret = flash_write_enable(info); + if(ret < 0) { + printf("Chip erase, enable flash write error.\n"); + return -1; + } + + time(&timep); + printf("Full chip erasing, please wait...\n"); + dbg_print(debug_on,"Erase Start-%s\n",asctime(gmtime(&timep))); + send_chip_erase_cmd(info); + ret = check_flash_write_process(info, CHIP_ERASE_TIMEOUT, CHIP_ERASE_SLEEP_TIME); + if (ret < 0) { + printf("Chip erase timeout.\n"); + return -1; + } + time(&timep); + dbg_print(debug_on,"Erase Finish-%s\n",asctime(gmtime(&timep))); + printf("Erase Finish\n"); + printf("=========================================\n"); + return 0; +} + +static int erase_chip_block(flash_info_t* info) +{ + uint32_t block_addr, end_addr; + time_t timep; + int ret; + + printf("Block erasing...\n"); + time (&timep); + dbg_print(debug_on,"Erase-Start-%s\n", asctime(gmtime(&timep))); + end_addr = info->flash_base_addr + info->flash_size; + block_addr = info->flash_base_addr; + while (1) { + /* Enable write */ + ret = flash_write_enable(info); + if(ret < 0) { + printf("Block erase, enable flash write error, block addr:0x%x\n", block_addr); + return -1; + } + + send_block_erase_cmd(info, block_addr); + /* Erase Block(64KB) MAX time 650ms*/ + ret = check_flash_write_process(info, BLOCK_ERASE_TIMEOUT, BLOCK_ERASE_SLEEP_TIME); + if (ret < 0) { + printf("Block erase, check write status error, block addr:0x%x\n", block_addr); + return -1; + } + printf("\r0x%x", block_addr); + fflush(stdout); + if (block_addr >= end_addr) { + time(&timep); + printf("\r\nErase Finish\n"); + printf("=========================================\n"); + dbg_print(debug_on,"\nEnd-Earse-%s\n",asctime(gmtime(&timep))); + break; + } + block_addr += info->block_size; + } + return 0; +} + +static int program_chip(uint32_t file_size, uint8_t *p, flash_info_t* info) +{ + time_t timep; + uint32_t page_addr, end_addr; + int ret, page_size; + + page_addr = info->flash_base_addr; + page_size = info->page_size; + end_addr = file_size + info->flash_base_addr; + time (&timep); + printf("Programming...\n"); + dbg_print(debug_on,"Program Start-%s\n",asctime(gmtime(&timep))); + /* Debug info */ + fmc_debug(); + while (1) { + /* Write enable */ + ret = flash_write_enable(info); + if(ret < 0) { + printf("Page program, enable flash write error, page addr:0x%x\n", page_addr); + return -1; + } + ret = write_bmc_flash_page(info, page_addr, p, page_size); + if (ret < 0) { + printf("Page program, write bmc flash page error, page addr:0x%x\n", page_addr); + return -1; + } + /* page program MAX time 1.5ms */ + ret = check_flash_write_process(info, PAGE_PROGRAM_TIMEOUT, PAGE_PROGRAM_SLEEP_TIME); + if (ret < 0) { + printf("Page program, check write status error, page addr:0x%x\n", page_addr); + return -1; + } + page_addr += page_size; + p += page_size; + if ((page_addr % 0x10000) == 0) { + printf("\r0x%x", page_addr); + fflush(stdout); + } + + if (page_addr >= end_addr) { + printf("\nProgram Finish\n"); + printf("=========================================\n"); + time(&timep); + dbg_print(debug_on,"\nProgram-End-%s\n",asctime(gmtime(&timep))); + break; + } + } /* End of while (1) */ + return 0; +} + +static int check_chip(uint32_t file_size, uint8_t *p, flash_info_t* info) +{ + time_t timep; + uint32_t offset_addr, rd_val, end_addr; + int pos; + + offset_addr = info->flash_base_addr; + end_addr = file_size + info->flash_base_addr; + pos=0; + /* Checking */ + time(&timep); + printf("Checking...\n"); + dbg_print(debug_on,"Checking-Start-%s\n",asctime(gmtime(&timep))); + + pull_ce_down(info); + send_cmd(info->flash_base_addr, COMMON_FLASH_READ); + write_bmc_flash_addr(info->flash_base_addr); + while (1) { + if (offset_addr >= end_addr) { + break; + } + rd_val = read_bmc_flash_data(); + if (rd_val != (*(uint32_t *)(p + pos))) { + printf("Check Error at 0x%08x\n", offset_addr); + printf("READ:0x%08x VALUE:0x%08x\n", rd_val, (*(uint32_t *)(p + pos))); + pull_ce_up(info); + return -1; + } + if ((offset_addr % 0x10000) == 0) { + printf("\r0x%x ", offset_addr); + fflush(stdout); + } + offset_addr += 4; + pos += 4; + } + pull_ce_up(info); + printf("\r\nFlash Checked\n"); + printf("=========================================\n"); + time(&timep); + dbg_print(debug_on,"Checking-End-%s\n",asctime(gmtime(&timep))); + return 0; +} + +flash_info_t* get_flash_info(int current_bmc, int cs) +{ + int i, size; + uint32_t flash_base_addr, ce_ctrl_addr, flash_id; + + get_flash_base_and_ce_ctrl(current_bmc, cs, &flash_base_addr, &ce_ctrl_addr); + + size = (sizeof(flash_info) / sizeof((flash_info)[0])); + + flash_id = get_flash_id(flash_base_addr, ce_ctrl_addr); + for (i = 0; i < size; i++) { + if (flash_info[i].flash_id == flash_id) { + flash_info[i].flash_base_addr = flash_base_addr; + flash_info[i].ce_control_reg = ce_ctrl_addr; + flash_info[i].cs = cs; + return &flash_info[i]; + } + } + printf("Cannot get flash info, cs:%d, flash base addr:0x%x, ce control addr:0x%x, flash_id:0x%x.\n", + cs, flash_base_addr, ce_ctrl_addr, flash_id); + return NULL; +} + +static void init_flash(flash_info_t* info) +{ + send_cmd_to_flash(info, RSTEN); + send_cmd_to_flash(info, RST); + send_cmd_to_flash(info, EXIT_OTP); + send_cmd_to_flash(info, ENABLE_BYTE4); + + return; +} + +static int upgrade_bmc_core(char *file_name, int erase_type, flash_info_t* info) +{ + int file_size, fp, ret; + uint8_t *p; + + file_size = get_file_size(file_name); + if (file_size < 0) { + printf("file size %d Error\n", file_size); + return -1; + } + + fp = open(file_name, O_RDWR); + if (fp < 0) { + printf("Cannot open %s.\n", file_name); + return -1; + } + + p = mmap(NULL, file_size, PROT_READ, MAP_SHARED, fp, 0); + if (p == MAP_FAILED) { + printf("Could not mmap %s, error(%s).\n", file_name, strerror(errno)); + close(fp); + return -1; + } + + printf("* CE%d FLASH TYPE: SPI FLASH\n", info->cs); + printf("* FLASH NAME: %s\n", info->flash_name); + printf("* File Size:%d, 0x%x\n", file_size, file_size); + printf("=========================================\n"); + + /* Select erase type */ + switch (erase_type) { + case FULL_ERASE: + ret = erase_chip_full(info); + break; + case BLOCK_ERASE: + ret = erase_chip_block(info); + break; + default: + printf("Unsupport earse type:%d\n", erase_type); + goto exit; + break; + } + + if (ret < 0) { + printf("Erase Chip Error\n"); + goto exit; + } + + /* Program the flash */ + ret = program_chip(file_size, p, info); + if(ret < 0) { + printf("Program Chip Error\n"); + goto exit; + } + /* Check */ + ret = check_chip(file_size, p, info); + if(ret < 0) { + printf("Check Chip Error\n"); + goto exit; + } + + munmap(p, file_size); + close(fp); + return 0; +exit: + munmap(p, file_size); + close(fp); + return -1; +} + +static int upgrade_bmc_flash(char *filename, int current_bmc, int cs, int erase_type) +{ + int ret; + flash_info_t* info; + + info = get_flash_info(current_bmc, cs); + if(info == NULL) { + return -1; + } + + init_flash(info); + + ret = upgrade_bmc_core(filename, erase_type, info); + + return ret; +} + +static int upgrade_both_flash(char *filename, int erase_type) +{ + int ret, current_bmc; + + enable_upgrade(); + + current_bmc = get_current_bmc(); + if (current_bmc == CURRENT_MASTER) { + printf("* Current Bmc Default Boot: CE0\n"); + } else { + printf("* Current Bmc Default Boot: CE1\n"); + } + + ret = upgrade_bmc_flash(filename, current_bmc, CE0, erase_type); + if (ret < 0) { + printf("Upgrade master bmc flash failed, stop upgrade.\n"); + goto err; + } + printf("Upgrade master bmc flash success.\n"); + + ret = upgrade_bmc_flash(filename, current_bmc, CE1, erase_type); + if (ret < 0) { + printf("Upgrade slave bmc flash failed.\n"); + goto err; + } + printf("Upgrade slave bmc flash success.\n"); + + bmc_reboot(CE0); + return 0; +err: + disable_upgrade(); + return -1; +} + +static int upgrade_single_flash(char *filename, int cs, int erase_type) +{ + int ret, current_bmc; + + enable_upgrade(); + + current_bmc = get_current_bmc(); + if (current_bmc == CURRENT_MASTER) { + printf("* Current Bmc Default Boot: CE0\n"); + } else { + printf("* Current Bmc Default Boot: CE1\n"); + } + + ret = upgrade_bmc_flash(filename, current_bmc, cs, erase_type); + if (ret < 0) { + printf("Upgrade %s bmc flash failed.\n", cs == 0 ? "master":"slave"); + goto err; + } + printf("Upgrade %s bmc flash success.\n", cs == 0 ? "master":"slave"); + + bmc_reboot(cs); + return 0; +err: + disable_upgrade(); + return -1; +} + +static int upgrade_bmc(char *filename, int cs, int erase_type) +{ + int ret; + + if (access(filename, F_OK) < 0) { + printf("Can't find file\n"); + help(); + return -1; + } + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + switch(cs) { + /* Single */ + case CE0: + case CE1: + ret = upgrade_single_flash(filename, cs, erase_type); + break; + /* Both */ + case BOTHFLASH: + ret = upgrade_both_flash(filename, erase_type); + break; + default: + ret = -1; + printf("Unsupport cs:%d\n", cs); + break; + } + + return ret; +} + +static int read_single_bmc_flash(flash_info_t* info, uint32_t start_addr, int read_size, int is_print) +{ + uint32_t res, flash_start_addr, flash_end_addr; + char filename[MAX_FILENAME_LENGTH]; + int fd, ret; + + flash_start_addr = info->flash_base_addr + start_addr; + flash_end_addr = flash_start_addr + read_size; + ret = 0; + fd = 0; + if (!is_print) { + mem_clear(filename, MAX_FILENAME_LENGTH); + snprintf(filename, MAX_FILENAME_LENGTH, "/tmp/image-bmc%d", info->cs); + fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRWXG|S_IRWXU|S_IRWXO); + if (fd < 0) { + printf("open file %s fail(err:%d)!\r\n", filename, errno); + return -1; + } + } + + printf("* CE%d FLASH TYPE: SPI FLASH\n", info->cs); + printf("* FLASH NAME: %s\n", info->flash_name); + printf("* Read flash addr:0x%x, size:0x%x\n", flash_start_addr, read_size); + printf("=========================================\n"); + printf("Reading...\n"); + + pull_ce_down(info); + send_cmd(info->flash_base_addr, COMMON_FLASH_READ); + write_bmc_flash_addr(flash_start_addr); + while (1) { + if (flash_start_addr >= flash_end_addr) { + break; + } + res = read_bmc_flash_data(); + if (is_print) { + printf("addr:0x%08x, val:0x%08x\n", flash_start_addr, res); + } else { + ret = write(fd, &res, sizeof(res)); + if (ret < 0) { + printf("write failed (errno: %d).\n", errno); + ret = -1; + goto exit; + } + } + if (((flash_start_addr % 0x10000) == 0) && (!is_print)) { + printf("\r0x%x ", flash_start_addr); + fflush(stdout); + } + flash_start_addr += 4; + } + printf("\r\nRead Finish\n"); + printf("=========================================\n"); +exit: + pull_ce_up(info); + if (fd > 0) { + close(fd); + } + return ret; +} + +static int read_bmc_flash(int cs, uint32_t start_addr, int read_size, int is_print) +{ + int ret, current_bmc; + flash_info_t* info; + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + enable_upgrade(); + + current_bmc = get_current_bmc(); + if (current_bmc == CURRENT_MASTER) { + printf("* Current Bmc Default Boot: CE0\n"); + } else { + printf("* Current Bmc Default Boot: CE1\n"); + } + + info = get_flash_info(current_bmc, cs); + if(info == NULL) { + goto err; + } + + if (start_addr >= info->flash_size) { + printf("start_addr 0x%x out of range.\n", start_addr); + goto err; + } + + if ((start_addr + read_size) > info->flash_size) { + printf("read size %d exceed flash size.\n", read_size); + read_size = info->flash_size - start_addr; + } + + init_flash(info); + + ret = read_single_bmc_flash(info, start_addr, read_size, is_print); + if (ret < 0) { + printf("Read %s bmc flash failed.\n", cs == 0 ? "master" : "slave"); + goto err; + } + disable_upgrade(); + return 0; +err: + disable_upgrade(); + return -1; +} + +static int read_bmc_reg_main(int argc, char* argv[]) +{ + uint32_t start_addr, read_val; + int read_size, ret; + char *stopstring; + + if (argc != 4) { + printf("Input invalid.\n"); + help(); + return -1; + } + + start_addr = strtoul(argv[2], &stopstring, 16); + read_size = strtol(argv[3], &stopstring, 10); + + if (read_size <= 0) { + printf("read length %d invalid\n", read_size); + return -1; + } + + if (((start_addr % 4) != 0) || ((read_size % 4) != 0)) { + printf("Params invalid, start_addr:0x%08x, read_size:%d\n", start_addr, read_size); + printf("Please input address/length times of 4\n"); + return -1; + } + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + enable_ilpc2ahb(); + + printf("read bcm reg, start_addr:0x%08x, read length:%d\n", start_addr, read_size); + printf("===Addr=== | ===Cont===\n"); + while (read_size) { + read_val = read_bmc_reg(start_addr); + printf("0x%08x | 0x%08x\n", start_addr, read_val); + start_addr += 4; + read_size -= 4; + } + + disable_ilpc2ahb(); + return 0; +} + +static int write_bmc_reg_main(int argc, char* argv[]) +{ + uint32_t addr, wr_val; + int ret; + char *stopstring; + + if (argc != 4) { + printf("Input invalid.\n"); + help(); + return -1; + } + + addr = strtoul(argv[2], &stopstring, 16); + wr_val = strtoul(argv[3], &stopstring, 16); + + if (((addr & MASK_BYTE) != REGISTER_HEAD) || ((addr % 4) != 0)) { + printf("Address[0x%08x] invalid, address should be register address and times of 4.\n", addr); + return -1; + } + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + printf("write bcm reg, addr:0x%08x, val:0x%08x\n", addr, wr_val); + + enable_ilpc2ahb(); + write_bmc_reg(addr, wr_val); + disable_ilpc2ahb(); + + return 0; +} + +static int get_fmc_info_main(void) +{ + int ret; + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + enable_ilpc2ahb(); + + debug_on = 3; + fmc_debug(); + debug_on = 0; + + disable_ilpc2ahb(); + return 0; +} + +static int program_flash_main(int argc, char* argv[]) +{ + int cs, erase_way, ret; + char *stopstring; + char tmp[128]; + + if (argc != 5) { + printf("Input invalid.\n"); + help(); + return -1; + } + + cs = strtol(argv[3], &stopstring, 10); + if ((strlen(stopstring) != 0) || cs < 0 || cs > 2) { + snprintf(tmp, sizeof(tmp), "%s", argv[3]); + printf("Incorrect chip select %s\n", tmp); + help(); + return -1; + } + + if (strcmp(argv[4], "full") == 0) { + erase_way = FULL_ERASE; + } else if (strcmp(argv[4], "block") == 0) { + erase_way = BLOCK_ERASE; + } else { + snprintf(tmp, sizeof(tmp), "%s", argv[4]); + printf("Incorrect erase type %s\n", tmp); + help(); + return -1; + } + + printf("============BMC Upgrade Tool=============\n"); + ret = upgrade_bmc(argv[2], cs, erase_way); + return ret; +} + +static int read_bmc_flash_main(int argc, char* argv[]) +{ + int cs, ret, read_size, is_print; + uint32_t start_addr; + char *stopstring; + char tmp[128]; + + if (argc != 6) { + printf("Input invalid.\n"); + help(); + return -1; + } + + cs = strtol(argv[2], &stopstring, 10); + if ((strlen(stopstring) != 0) || cs < 0 || cs > 1) { + snprintf(tmp, sizeof(tmp), "%s", argv[2]); + printf("Incorrect chip select %s\n", tmp); + help(); + return -1; + } + + start_addr = strtoul(argv[3], &stopstring, 16); + read_size = strtol(argv[4], &stopstring, 10); + + if (read_size <= 0) { + printf("read length %d invalid\n", read_size); + return -1; + } + + if (((start_addr % 4) != 0) || ((read_size % 4) != 0)) { + printf("Params invalid, start_addr:0x%08x, read_size:%d\n", start_addr, read_size); + printf("Please input address/length times of 4\n"); + return -1; + } + + if (strcmp(argv[5], "print") == 0) { + is_print = 1; + } else { + is_print = 0; + } + + printf("============READ BMC FLASH=============\n"); + ret = read_bmc_flash(cs, start_addr, read_size, is_print); + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret; + + debug_on = fw_upgrade_debug(); + + if (argc < 2) { + help(); + return -1; + } + + if (argc == 2) { + if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { + help(); + return 0; + } + } + + if (strcmp(argv[1], "rd") == 0) { + ret = read_bmc_reg_main(argc, argv); + if (ret < 0) { + printf("Read Failed\n"); + } + return ret; + } + + if (strcmp(argv[1], "wr") == 0 && debug_on == 3) { + ret = write_bmc_reg_main(argc, argv); + if (ret < 0) { + printf("Write Failed\n"); + } + return ret; + } + + if (strcmp(argv[1], "info") == 0) { + ret = get_fmc_info_main(); + if (ret < 0) { + printf("Get fmc info Failed\n"); + } + return ret; + } + + if (strcmp(argv[1], "upgrade") == 0) { + ret = program_flash_main(argc, argv); + if (ret < 0) { + printf("Upgrade BMC failed.\n"); + } + return ret; + } + + if (strcmp(argv[1], "read_bmc_flash") == 0) { + ret = read_bmc_flash_main(argc, argv); + if (ret < 0) { + printf("Read BMC flash failed.\n"); + } + return ret; + } + + printf("Input invalid.\n"); + help(); + + return -1; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c new file mode 100644 index 000000000000..a7a78d011011 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "fw_upgrade_debug.h" + +int fw_upgrade_debug(void) +{ + int size; + FILE *fp; + char debug_info[DEBUG_INFO_LEN]; + + fp = fopen(DEBUG_FILE, "r"); + if (fp == NULL) { + return DEBUG_IGNORE; + } + + mem_clear(debug_info, DEBUG_INFO_LEN); + size = fread(debug_info, DEBUG_INFO_LEN - 1, 1, fp); + if (size < 0) { + fclose(fp); + return DEBUG_IGNORE; + } + + if (strncmp(debug_info, DEBUG_ON_INFO, 1) == 0) { + fclose(fp); + return DEBUG_APP_ON; + } + + if (strncmp(debug_info, DEBUG_ON_KERN, 1) == 0) { + fclose(fp); + return DEBUG_KERN_ON; + } + + if (strncmp(debug_info, DEBUG_ON_ALL, 1) == 0) { + fclose(fp); + return DEBUG_ALL_ON; + } + + if (strncmp(debug_info, DEBUG_OFF_INFO, 1) == 0) { + fclose(fp); + return DEBUG_OFF; + } + + fclose(fp); + return DEBUG_IGNORE; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h new file mode 100644 index 000000000000..bd806a94b154 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h @@ -0,0 +1,230 @@ +#ifndef _FW_UPGRADE_H_ +#define _FW_UPGRADE_H_ + +#include "fw_upgrade_debug.h" + +#define dbg_print(debug, fmt, arg...) \ + if (debug == DEBUG_APP_ON || debug == DEBUG_ALL_ON) \ + { do{printf(fmt,##arg);} while(0); } + +/* LPC Interface */ +#define LPC_ADDR_PORT (0x4E) +#define LPC_DATA_PORT (0x4F) + +/* FMC REGISTER ADDR */ +#define FMC_BASE_ADDR (0x1E620000) +#define FMC_CE_TYPE_SETTING_REG (FMC_BASE_ADDR + 0x00) +#define CE_CONTROL_REGISTER (FMC_BASE_ADDR + 0x04) +#define INR_STATUS_CONTROL_REGISTER (FMC_BASE_ADDR + 0x08) +#define COMMAND_CONTROL_REGISTER (FMC_BASE_ADDR + 0x0C) +#define CE0_CONTROL_REGISTER (FMC_BASE_ADDR + 0x10) +#define CE1_CONTROL_REGISTER (FMC_BASE_ADDR + 0x14) +#define CE0_ADDRESS_RANGE_REGISTER (FMC_BASE_ADDR + 0x30) +#define CE1_ADDRESS_RANGE_REGISTER (FMC_BASE_ADDR + 0x34) + +/* SCU REGISTER ADDR */ +#define SCU_ADDR (0x1E6E2000) +#define HARDWARE_STRAP_REGISTER (SCU_ADDR + 0x70) +#define REBOOT_CPU_REGISTER (SCU_ADDR + 0x7C) + +/* SCU KEY */ +#define UNLOCK_SCU_KEY (0x1688A8A8) +#define LOCK_SCU_KEY (0x11111111) + +/* WATCHDOG REGISTER ADDR */ +#define WATCHDOG_ADDR (0x1E785000) +#define WATCHDOG1_RELOAD_VALUE (WATCHDOG_ADDR + 0x04) +#define WATCHDOG1_COUNTER_RST (WATCHDOG_ADDR + 0x08) +#define WATCHDOG1_CONTROL (WATCHDOG_ADDR + 0x0C) +#define WATCHDOG1_TSR (WATCHDOG_ADDR + 0x10) +#define WATCHDOG1_CLEAR_STATUS (WATCHDOG_ADDR + 0x14) +#define WATCHDOG1_RESET_FUN_MASK (WATCHDOG_ADDR + 0x1C) + +#define WATCHDOG2_RELOAD_VALUE (WATCHDOG_ADDR + 0x24) +#define WATCHDOG2_COUNTER_RST (WATCHDOG_ADDR + 0x28) +#define WATCHDOG2_CONTROL (WATCHDOG_ADDR + 0x2C) +#define WATCHDOG2_TSR (WATCHDOG_ADDR + 0x30) +#define WATCHDOG2_CLEAR_STATUS (WATCHDOG_ADDR + 0x34) +#define WATCHDOG2_RESET_FUN_MASK (WATCHDOG_ADDR + 0x3C) + +/* User Mode Command */ +#define WRITE_STATUS (0x01) +#define COMMON_PAGE_PROGRAM (0x02) +#define COMMON_FLASH_READ (0x03) +#define WRITE_DISABLE_FLASH (0x04) +#define READ_FLASH_STATUS (0x05) +#define WRITE_ENABLE_FLASH (0x06) +#define PAGE_PROGRAM_FLASH (0x12) +#define SECTOR_ERASE (0x20) +#define CLEAR_FLAG (0x50) +#define SUBBLOCK_ERASE (0x52) +#define CHIP_ERASE_FLASH (0x60) +#define BLOCK_ERASE_64 (0xD8) +#define READID (0x9F) +#define ENABLE_BYTE4 (0xB7) +#define EXIT_OTP (0xC1) +#define RSTEN (0x66) +#define RST (0x99) + +#define BIT1 (0x01) +#define BIT2 (0x02) +#define BIT3 (0x04) +#define BIT4 (0x08) +#define BIT5 (0x10) +#define BIT6 (0x20) +#define BIT7 (0x40) +#define BIT8 (0x80) +#define RIGHT_SHIFT_8(reg) (reg >> 8) +#define RIGHT_SHIFT_16(reg) (reg >> 16) +#define RIGHT_SHIFT_24(reg) (reg >> 24) +#define MASK (0xFF) +#define FLASH_TYPE_MASK (BIT1 | BIT2) +#define BOOT_DEFAULT_MASK (BIT8) +#define HEAD_MASK (0x00FFFF00) +#define MASK_BYTE (0xFF000000) +#define BYTE1 (1) +#define BYTE2 (2) +#define BYTE4 (4) +#define BYTE1_VAL (0) +#define BYTE2_VAL (1) +#define BYTE4_VAL (2) +#define BYTE_RESERVED (3) + +/* SuperIO */ +#define SUPERIO_07 (0x07) +#define SUPERIO_30 (0x30) +#define SUPERIO_A0 (0xA0) +#define SUPERIO_A2 (0xA2) +#define SUPERIO_REG0 (0xF0) +#define SUPERIO_REG1 (0xF1) +#define SUPERIO_REG2 (0xF2) +#define SUPERIO_REG3 (0xF3) +#define SUPERIO_REG4 (0xF4) +#define SUPERIO_REG5 (0xF5) +#define SUPERIO_REG6 (0xF6) +#define SUPERIO_REG7 (0xF7) +#define SUPERIO_REG8 (0xF8) +#define SUPERIO_FE (0xFE) + +/* SPI Command */ +#define HIGH_CLOCK (0x00000000) +#define NORMAL_READ (0x00000000) +#define READ_MODE (0x00000001) +#define WRITE_MODE (0x00000002) +#define USER_MODE (0x00000003) +#define PULL_DOWN (0x00000000) +#define PULL_UP (0x00000004) + +#define CHIP_ERASE_TIME (60) +#define CHIP_ERASE_TIMEOUT (300 * 1000 * 1000) +#define CHIP_ERASE_SLEEP_TIME (5 * 1000 * 1000) +#define BLOCK_ERASE_TIMEOUT (10 * 1000 * 1000) +#define BLOCK_ERASE_SLEEP_TIME (100 * 1000) +#define PAGE_PROGRAM_TIMEOUT (100 * 1000) +#define PAGE_PROGRAM_SLEEP_TIME (1000) +#define FLASH_WEL_TIMEOUT (100 * 1000) +#define FLASH_WEL_SLEEP_TIME (1000) +#define FLASH_WIP_MASK (0x00000001) +#define FLASH_WRITE_ENABLE_MASK (0x00000002) + +#define DATA_LENGTH_MASK (0xA2) +#define TOGGLE_WRITE (0xCF) +#define DISABLE_LPC (0xAA) +#define ENABLE_LPC (0xA5) +#define LPC_TO_AHB (0x0D) +#define ENABLE_LPC_TO_AHB (0x01) +#define DISABLE_LPC_TO_AHB (0x00) +#define ENABLE_BMC_CPU_BOOT (0xF10BD286) +#define DISABLE_BMC_CPU_BOOT (0xF10BD287) +#define SET_BMC_CPU_BOOT (0x01) +#define CLEAR_WATCHDOG_STATUS (0x01) +#define DISABLE_WATCHDOG (0x00000030) +#define ENABLE_WATCHDOG (0x00000033) +#define WATCHDOG_GATEMASK (0x033FFFF3) +#define WATCHDOG_NEW_COUNT (0x00050000) +#define WATCHDOG_RELOAD_COUNTER (0x4755) + +#define CE0_SPI_TYPE (0x00000002) +#define CE1_SPI_TYPE (0x00000008) +#define ERROR_COMMAND (0x00000400) +#define ADDRESS_PROTECT (0x00000200) +#define CLEAR_INR_STATUS_CONTROL (ERROR_COMMAND | ADDRESS_PROTECT) +#define USER_MODE_PULL_CE_DOWN (HIGH_CLOCK | USER_MODE | PULL_DOWN) +#define USER_MODE_PULL_CE_UP (HIGH_CLOCK | USER_MODE | PULL_UP) + +#define STEP_64 (64 * 1024) +#define STEP_256 (256 * 1024) +#define BYTE_256 (256) + +#define CE0 (0) +#define CE1 (1) +#define BOTHFLASH (2) +#define SOC_SYS (0) +#define FULL_CHIP (1) +#define ARM_CPU (2) +#define FULL_ERASE (0) +#define BLOCK_ERASE (1) +#define READ_ALL (2) +#define CURRENT_SLAVE (1) +#define CURRENT_MASTER (0) +#define REGISTER_HEAD (0x1e000000) +#define DEFAULT_WIDTH (16) +#define MAX_FILENAME_LENGTH (64) +#define SEGMENT_ADDR_START(_r) ((((_r) >> 16) & 0xFF) << 23) + +typedef struct flash_info { + uint32_t flash_size; + int cs; + int flash_type; + uint32_t flash_id; + int page_size; + char flash_name[64]; + int erase_block_command; + int page_program; + int block_size; + int full_erase; + uint32_t ce_control_reg; + uint32_t flash_base_addr; +} flash_info_t; + +typedef enum flash_id { + MX25L6433F = 0x1920c2, + S25FL512S = 0x200201, + MX25l512 = 0x1a20c2, + STM25P64 = 0x172020, + STM25P128 = 0x182020, + N25Q256 = 0x19ba20, + N25Q512 = 0x20ba20, + W25X16 = 0x1530ef, + W25X64 = 0x1730ef, + W25Q64BV = 0x1740ef, + W25Q128BV = 0x1840ef, + W25Q256FV = 0x1940ef, + MX25L1605D = 0x1520C2, + MX25L12805D = 0x1820C2, + MX66L1G45G = 0x1B20C2, + SST25VF016B = 0x4125bf, + SST25VF064C = 0x4b25bf, + SST25VF040B = 0x8d25bf, + AT25DF161 = 0x02461F, + AT25DF321 = 0x01471F, + GD25Q256 = 0X1940c8, +} flash_id_t; + +typedef enum flash_type { + NOR = 0, + SPI = 2, +} flash_type_t; + +typedef enum flash_size { + M1 = 0x00080000, + M3 = 0x00200000, /* 3M */ + M6 = 0x00400000, /* 6M */ + M12 = 0x00800000, /* 12M */ + M16 = 0x01000000, /* 16M */ + M32 = 0x02000000, /* 32M */ + M64 = 0x04000000, /* 64M */ + M128 = 0x08000000, /* 128M */ +} flash_size_t; + +#endif /*_FW_UPGRADE_H_*/ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h new file mode 100644 index 000000000000..05911da62a7e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h @@ -0,0 +1,25 @@ +#ifndef __FW_UPGRADE_DEBUG_H__ +#define __FW_UPGRADE_DEBUG_H__ + +#include + +#define DEBUG_INFO_LEN 20 +#define DEBUG_FILE "/tmp/.fw_upgrade_debug" +#define DEBUG_ON_ALL "3" +#define DEBUG_ON_KERN "2" +#define DEBUG_ON_INFO "1" +#define DEBUG_OFF_INFO "0" + +#define mem_clear(data, size) memset((data), 0, (size)) + +enum debug_s { + DEBUG_OFF = 0, + DEBUG_APP_ON, + DEBUG_KERN_ON, + DEBUG_ALL_ON, + DEBUG_IGNORE, +}; + +extern int fw_upgrade_debug(void); + +#endif /* End of __FW_UPGRADE_DEBUG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/depmod_conf/distsearch.conf b/platform/broadcom/sonic-platform-modules-ragile/common/depmod_conf/distsearch.conf deleted file mode 100644 index ad60b2eb6f95..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/depmod_conf/distsearch.conf +++ /dev/null @@ -1,4 +0,0 @@ -# depmod.conf -# -# override default search ordering for kmod packaging -search updates extra external built-in weak-updates diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/__init__.py rename to platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/__init__.py diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/hysteresis.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/hysteresis.py new file mode 100644 index 000000000000..81fd596e7fee --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/hysteresis.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +import os +import syslog +import copy + +from plat_hal.baseutil import baseutil + +HYST_DEBUG_FILE = "/etc/.hysteresis_debug_flag" + +HYSTERROR = 1 +HYSTDEBUG = 2 + +debuglevel = 0 + + +def hyst_debug(s): + if HYSTDEBUG & debuglevel: + syslog.openlog("FANCONTROL-HYST", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def hyst_error(s): + if HYSTERROR & debuglevel: + syslog.openlog("FANCONTROL-HYST", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +class hysteresis(object): + __config = None + __hyst_config = None + + def __init__(self): + self.__config = baseutil.get_monitor_config() + self.__hyst_config = copy.deepcopy(self.__config.get("hyst", {})) + # init check + errcnt = 0 + errmsg = "" + self.debug_init() + for temp_hyst_conf in self.__hyst_config.values(): + if temp_hyst_conf["flag"] == 0: + continue + for i in range(temp_hyst_conf["temp_min"], temp_hyst_conf["temp_max"] + 1): + if i not in temp_hyst_conf["rising"]: + errcnt -= 1 + msg = "%s hyst config error, temp value %d not in rising curve;" % (temp_hyst_conf["name"], i) + hyst_error(msg) + errmsg += msg + if i not in temp_hyst_conf["descending"]: + errcnt -= 1 + msg = "%s hyst config error, temp value %d not in descending curve;" % (temp_hyst_conf["name"], i) + hyst_error(msg) + errmsg += msg + if errcnt < 0: + raise KeyError(errmsg) + + def debug_init(self): + global debuglevel + if os.path.exists(HYST_DEBUG_FILE): + debuglevel = debuglevel | HYSTDEBUG | HYSTERROR + else: + debuglevel = debuglevel & ~(HYSTDEBUG | HYSTERROR) + + def get_temp_hyst_conf(self, temp_name): + temp_hyst_conf = self.__hyst_config.get(temp_name) + return temp_hyst_conf + + def get_temp_update(self, hyst_para, current_temp): + temp = hyst_para["value"] + if temp is None: + return None + temp.append(current_temp) + del temp[0] + return temp + + def duty_to_pwm(self, duty): + pwm = int(round(float(duty) * 255 / 100)) + return pwm + + def pwm_to_duty(self, pwm): + duty = int(round(float(pwm) * 100 / 255)) + return duty + + def calc_hyst_val(self, temp_name, temp_list): + + temp_hyst_conf = self.get_temp_hyst_conf(temp_name) + hyst_min = temp_hyst_conf["hyst_min"] + hyst_max = temp_hyst_conf["hyst_max"] + temp_min = temp_hyst_conf["temp_min"] + temp_max = temp_hyst_conf["temp_max"] + rising = temp_hyst_conf["rising"] + descending = temp_hyst_conf["descending"] + last_hyst_value = temp_hyst_conf["last_hyst_value"] + current_temp = temp_list[1] + last_temp = temp_list[0] + + hyst_debug("calc_hyst_val, temp_name: %s, current_temp: %s, last_temp: %s, last_hyst_value: %s" % + (temp_name, current_temp, last_temp, last_hyst_value)) + + if current_temp < temp_min: + hyst_debug("%s current_temp %s less than temp_min %s, set min hyst value: %s" % + (temp_name, current_temp, temp_min, hyst_min)) + return hyst_min + + if current_temp > temp_max: + hyst_debug("%s current_temp %s more than temp_max %s, set max hyst value: %s" % + (temp_name, current_temp, temp_max, hyst_max)) + return hyst_max + + if last_temp is None: # first time + hyst_value = rising[current_temp] + hyst_debug("last_temp is None, it's first hysteresis, using rising hyst value: %s" % hyst_value) + return hyst_value + + if current_temp == last_temp: # temp unchanging + hyst_debug("current_temp equal last_temp, keep last hyst value: %s" % last_hyst_value) + return last_hyst_value + + if current_temp > last_temp: + calc_hyst_value = rising[current_temp] + if calc_hyst_value < last_hyst_value: + hyst_value = last_hyst_value + else: + hyst_value = calc_hyst_value + hyst_debug("temp rising, last_hyst_value: %s, calc_hyst_value: %s, set hyst value: %s" % + (last_hyst_value, calc_hyst_value, hyst_value)) + return hyst_value + + calc_hyst_value = descending[current_temp] + if calc_hyst_value > last_hyst_value: + hyst_value = last_hyst_value + else: + hyst_value = calc_hyst_value + hyst_debug("temp descending, last_hyst_value: %s, calc_hyst_value: %s, set hyst value: %s" % + (last_hyst_value, calc_hyst_value, hyst_value)) + return hyst_value + + def cacl(self, temp_name, current_temp): + self.debug_init() + try: + temp_hyst_conf = self.get_temp_hyst_conf(temp_name) + if temp_hyst_conf is None: + hyst_debug("get %s hysteresis config failed" % temp_name) + return None + + flag = temp_hyst_conf["flag"] + if flag != 1: + hyst_debug("%s hysteresis flag == 0, skip" % temp_name) + return None + + temp = self.get_temp_update(temp_hyst_conf, current_temp) + if temp is None: + hyst_debug("get %s update failed" % temp_name) + return None + + value = self.calc_hyst_val(temp_name, temp) + + temp_hyst_conf["last_hyst_value"] = value + + speed_type = temp_hyst_conf["type"] + if speed_type == "duty": + pwm = self.duty_to_pwm(value) + else: + pwm = value + + hyst_debug("temp_name: %s, current_temp: %s, set pwm 0x%x" % (temp_name, current_temp, pwm)) + return pwm + except Exception as e: + hyst_error("temp_name: %s calc hysteresis pwm error, msg: %s" % (temp_name, str(e))) + return None diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/openloop.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/openloop.py new file mode 100644 index 000000000000..6ff731fa7eb2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/openloop.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +import os +import syslog + +from plat_hal.baseutil import baseutil + +OPENLOOP_DEBUG_FILE = "/etc/.openloop_debug_flag" + +OPENLOOPERROR = 1 +OPENLOOPDEBUG = 2 + +debuglevel = 0 + + +def openloop_debug(s): + if OPENLOOPDEBUG & debuglevel: + syslog.openlog("FANCONTROL-OPENLOOP", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def openloop_error(s): + if OPENLOOPERROR & debuglevel: + syslog.openlog("FANCONTROL-OPENLOOP", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +class openloop(object): + __config = None + __openloop_config = None + + def __init__(self): + self.__config = baseutil.get_monitor_config() + self.__openloop_config = self.__config["openloop"] + + def debug_init(self): + global debuglevel + if os.path.exists(OPENLOOP_DEBUG_FILE): + debuglevel = debuglevel | OPENLOOPDEBUG | OPENLOOPERROR + else: + debuglevel = debuglevel & ~(OPENLOOPDEBUG | OPENLOOPERROR) + + def get_para(self, t): + para = self.__openloop_config.get(t) + return para + + def linear_cacl(self, temp): + self.debug_init() + openloop_para = self.get_para("linear") + if openloop_para is None: + openloop_debug("linear openloop: get para failed") + return None + + K = openloop_para["K"] + tin_min = openloop_para["tin_min"] + pwm_min = openloop_para["pwm_min"] + pwm_max = openloop_para["pwm_max"] + flag = openloop_para["flag"] + + if flag != 1: + openloop_debug("linear openloop: flag == 0") + return None + + if temp <= tin_min: + openloop_debug("linear openloop: temp = %d less than tin_min[%d]" % (temp, tin_min)) + return pwm_min + + pwm = int(pwm_min + (temp - tin_min) * K) + openloop_debug("linear openloop: cacl_pwm = 0x%x" % pwm) + + pwm = min(pwm, pwm_max) + pwm = max(pwm, pwm_min) + openloop_debug("linear openloop: temp = %d, pwm = 0x%x" % (temp, pwm)) + return pwm + + def curve_cacl(self, temp): + self.debug_init() + openloop_para = self.get_para("curve") + if openloop_para is None: + openloop_debug("curve openloop: get para failed") + return None + + a = openloop_para["a"] + b = openloop_para["b"] + c = openloop_para["c"] + tin_min = openloop_para["tin_min"] + pwm_min = openloop_para["pwm_min"] + pwm_max = openloop_para["pwm_max"] + flag = openloop_para["flag"] + + if flag != 1: + openloop_debug("curve openloop: flag == 0") + return None + + if temp <= tin_min: + openloop_debug("curve openloop: temp = %d less than tin_min[%d]" % (temp, tin_min)) + return pwm_min + + pwm = int(a * temp * temp + b * temp + c) + openloop_debug("curve openloop: cacl_pwm = 0x%x" % pwm) + + pwm = min(pwm, pwm_max) + pwm = max(pwm, pwm_min) + openloop_debug("curve openloop: temp = %d, pwm = 0x%x" % (temp, pwm)) + return pwm diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/pid.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/pid.py new file mode 100644 index 000000000000..c33c1df33b4e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/algorithm/pid.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +import os +import syslog +import copy + +from plat_hal.baseutil import baseutil + +PID_DEBUG_FILE = "/etc/.pid_debug_flag" + +PIDERROR = 1 +PIDDEBUG = 2 + +debuglevel = 0 + + +def pid_debug(s): + if PIDDEBUG & debuglevel: + syslog.openlog("FANCONTROL-PID", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def pid_error(s): + if PIDERROR & debuglevel: + syslog.openlog("FANCONTROL-PID", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +class pid(object): + __config = None + __pid_config = None + + def __init__(self): + self.__config = baseutil.get_monitor_config() + self.__pid_config = copy.deepcopy(self.__config["pid"]) + + def debug_init(self): + global debuglevel + if os.path.exists(PID_DEBUG_FILE): + debuglevel = debuglevel | PIDDEBUG | PIDERROR + else: + debuglevel = debuglevel & ~(PIDDEBUG | PIDERROR) + + def get_para(self, name): + para = self.__pid_config.get(name) + return para + + def get_temp_update(self, pid_para, current_temp): + temp = pid_para["value"] + if temp is None: + return None + temp.append(current_temp) + del temp[0] + return temp + + def cacl(self, last_pwm, name, current_temp): + delta_pwm = 0 + self.debug_init() + pid_debug("last_pwm = %d" % last_pwm) + + pid_para = self.get_para(name) + if pid_para is None: + pid_debug("get %s pid para failed" % name) + return None + + temp = self.get_temp_update(pid_para, current_temp) + if temp is None: + pid_debug("get %s update failed" % name) + return None + + speed_type = pid_para["type"] + Kp = pid_para["Kp"] + Ki = pid_para["Ki"] + Kd = pid_para["Kd"] + target = pid_para["target"] + pwm_min = pid_para["pwm_min"] + pwm_max = pid_para["pwm_max"] + flag = pid_para["flag"] + + if flag != 1: + pid_debug("%s pid flag == 0" % name) + return None + + if speed_type == "duty": + current_pwm = round(last_pwm * 100 / 255) + else: + current_pwm = last_pwm + + if temp[2] is None: + tmp_pwm = current_pwm + elif ((temp[0] is None) or (temp[1] is None)): + delta_pwm = Ki * (temp[2] - target) + tmp_pwm = current_pwm + delta_pwm + else: + delta_pwm = Kp * (temp[2] - temp[1]) + Ki * (temp[2] - target) + Kd * (temp[2] - 2 * temp[1] + temp[0]) + tmp_pwm = current_pwm + delta_pwm + + pid_debug("delta_pwm = %d" % delta_pwm) + if speed_type == "duty": + pwm = round(tmp_pwm * 255 / 100) + else: + pwm = int(tmp_pwm) + + pwm = min(pwm, pwm_max) + pwm = max(pwm, pwm_min) + pid_debug("last_pwm = 0x%x, pwm = 0x%x" % (last_pwm, pwm)) + return pwm diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fantlv.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fantlv.py index 38beb068f44c..4be78e7fdc03 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fantlv.py +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fantlv.py @@ -1,19 +1,21 @@ #!/usr/bin/python3 # -*- coding: utf-8 -*- + class FantlvException(Exception): - def __init__(self, message='fantlverror', code=-100): + def __init__(self, message='fantlverror', code=-100): err = 'errcode: {0} message:{1}'.format(code, message) Exception.__init__(self, err) self.code = code self.message = message -class fan_tlv(object): + +class fan_tlv(): HEAD_INFO = "\x01\x7e\x01\xf1" - VERSION = 0x01 # E2PROM file init version is 0x01 - FLAG = 0x7E #new version E2PROM mark as 0x7E - HW_VER = 0X01 # consists of master version and revised version - TYPE = 0xf1 # hardware type define - TLV_LEN = 00 # vaild data length(16bit) + VERSION = 0x01 + FLAG = 0x7E + HW_VER = 0X01 + TYPE = 0xf1 + TLV_LEN = 00 _FAN_TLV_HDR_LEN = 6 _FAN_TLV_CRC_LEN = 2 @@ -22,8 +24,6 @@ class fan_tlv(object): _FAN_TLV_TYPE_HW_INFO = 0x05 _FAN_TLV_TYPE_DEV_TYPE = 0x06 - _fandecodetime = 0 - @property def dstatus(self): return self._dstatus @@ -44,18 +44,6 @@ def typehwinfo(self): def typedevtype(self): return self._typedevtype - @property - def fanbus(self): - return self._fanbus - - @property - def fanloc(self): - return self._fanloc - - @property - def fandecodetime(self): - return self._fandecodetime - def __init__(self): self._typename = "" self._typesn = "" @@ -63,25 +51,20 @@ def __init__(self): self._typedevtype = "" self._dstatus = 0 - def strtoarr(self, str): + def strtoarr(self, val): s = [] - if str is not None: - for index in range(len(str)): - s.append(str[index]) + if not isinstance(val, str): + return s + for index in val: + s.append(index) return s - def str_to_hex(self,rest_v): - value = 0 - for index in range(len(rest_v)): - value |= ord(rest_v[index]) << ((len(rest_v) - index - 1) * 8) - return value - - def hex_to_str(self,s): + def hex_to_str(self, s): len_t = len(s) if len_t % 2 != 0: return 0 ret = "" - for t in range(0, int(len_t / 2)): + for t in range(0, len_t / 2): ret += chr(int(s[2 * t:2 * t + 2], 16)) return ret @@ -92,7 +75,7 @@ def generate_fan_value(self): bin_buffer[2] = chr(self.HW_VER) bin_buffer[3] = chr(self.TYPE) - temp_t = "%08x" % self.typedevtype # handle devtype first + temp_t = "%08x" % self.typedevtype typedevtype_t = self.hex_to_str(temp_t) total_len = len(self.typename) + len(self.typesn) + \ len(self.typehwinfo) + len(typedevtype_t) + 8 @@ -125,10 +108,9 @@ def generate_fan_value(self): len(typedevtype_t)] = self.strtoarr(typedevtype_t) index_start = index_start + 2 + len(typedevtype_t) - crcs = fan_tlv.fancrc(''.join(bin_buffer[0:index_start])) # 2bytes checking + crcs = fan_tlv.fancrc(''.join(bin_buffer[0:index_start])) bin_buffer[index_start] = chr(crcs >> 8) bin_buffer[index_start + 1] = chr(crcs & 0x00ff) - # printvalue(bin_buffer) return bin_buffer def decode(self, e2): @@ -144,7 +126,6 @@ def decode(self, e2): tlv_index = self._FAN_TLV_HDR_LEN tlv_end = self._FAN_TLV_HDR_LEN + self.TLV_LEN - # check sum if len(e2) < self._FAN_TLV_HDR_LEN + self.TLV_LEN + 2: raise FantlvException("Fan tlv eeprom len error!", -2) sumcrc = fan_tlv.fancrc(e2[0:self._FAN_TLV_HDR_LEN + self.TLV_LEN]) @@ -152,8 +133,7 @@ def decode(self, e2): ) << 8 | ord(e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN + 1]) if sumcrc != readcrc: raise FantlvException("Fan tlv eeprom checksum error!", -1) - else: - self._dstatus = 0 + self._dstatus = 0 while (tlv_index + 2) < len(e2) and tlv_index < tlv_end: s = self.decoder( e2[tlv_index:tlv_index + 2 + ord(e2[tlv_index + 1])]) @@ -164,15 +144,16 @@ def decode(self, e2): @staticmethod def fancrc(t): - sum = 0 - for index in range(len(t)): - sum += ord(t[index]) - return sum + crc = 0 + for item in t: + crc += ord(item) + return crc def decoder(self, t): try: name = "" value = "" + _len = 0 if ord(t[0]) == self._FAN_TLV_TYPE_NAME: name = "Product Name" _len = ord(t[1]) @@ -194,10 +175,10 @@ def decoder(self, t): value = "0x" for c in t[2:2 + ord(t[1])]: value += "%02X" % (ord(c),) - self._typedevtype = int(value,16) + self._typedevtype = int(value, 16) except Exception as e: print(e) - return {"name": name, "code": ord(t[0]), "value": value,"lens": _len} + return {"name": name, "code": ord(t[0]), "value": value, "lens": _len} def __str__(self): formatstr = "VERSION : 0x%02x \n" \ @@ -207,6 +188,5 @@ def __str__(self): "typename : %s \n" \ "typesn : %s \n" \ "typehwinfo : %s \n" - return formatstr % (self.VERSION, self.FLAG, self.HW_VER, self.TYPE, self.typename, self.typesn, self.typehwinfo) - - + return formatstr % (self.VERSION, self.FLAG, self.HW_VER, self.TYPE, + self.typename, self.typesn, self.typehwinfo) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fru.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fru.py index 90a690a19edd..f95164e03601 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fru.py +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/fru.py @@ -1,18 +1,14 @@ #!/usr/bin/python3 -# -*- coding: utf-8 -*- import collections -from bitarray import bitarray from datetime import datetime, timedelta -import sys +from bitarray import bitarray -__all__ = ["FruException", "FruUtil", "BaseArea", "BoardInfoArea", "ProductInfoArea", - "MultiRecordArea", "Field", "ipmifru"] __DEBUG__ = "N" class FruException(Exception): - def __init__(self, message='fruerror', code=-100): + def __init__(self, message='fruerror', code=-100): err = 'errcode: {0} message:{1}'.format(code, message) Exception.__init__(self, err) self.code = code @@ -24,7 +20,7 @@ def e_print(err): def d_print(debug_info): - if(__DEBUG__ == "Y"): + if __DEBUG__ == "Y": print(debug_info) @@ -43,7 +39,7 @@ def minToData(): starttime = datetime(1996, 1, 1, 0, 0, 0) endtime = datetime.now() seconds = (endtime - starttime).total_seconds() - mins = seconds / 60 + mins = seconds // 60 m = int(round(mins)) return m @@ -53,7 +49,7 @@ def getTimeFormat(): @staticmethod def getTypeLength(value): - if value is None: + if value is None or len(value) == 0: return 0 a = bitarray(8) a.setall(False) @@ -65,8 +61,8 @@ def getTypeLength(value): @staticmethod def checksum(b): result = 0 - for i in range(len(b)): - result += ord(b[i]) + for item in b: + result += ord(item) return (0x100 - (result & 0xff)) & 0xff @@ -89,7 +85,6 @@ def __init__(self, name="", size=0, offset=0): self._size = size self._isPresent = False self._data = b'\x00' * size - self.__dataoffset = 0 @property def childList(self): @@ -144,6 +139,9 @@ class BoardInfoArea(BaseArea): _boardTime = None _fields = None _mfg_date = None + areaversion = None + _boardversion = None + _language = None def __str__(self): formatstr = "version : %x\n" \ @@ -229,8 +227,7 @@ def decodedata(self): self.fruFileId = self.data[index + 1: index + templen + 1] index += templen + 1 d_print("decode fruFileId:%s" % self.fruFileId) - - + for i in range(1, 11): valtmp = "boardextra%d" % i if self.data[index] != chr(0xc1): @@ -242,6 +239,11 @@ def decodedata(self): else: break + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + def recalcute(self): d_print("boardInfoArea version:%x" % ord(self.boardversion)) d_print("boardInfoArea length:%d" % self.size) @@ -250,7 +252,7 @@ def recalcute(self): d_print("boardInfoArea mfg_date:%x" % self.mfg_date) self.data = chr(ord(self.boardversion)) + \ - chr(self.size / 8) + chr(self.language) + chr(self.size // 8) + chr(self.language) self.data += chr(self.mfg_date & 0xFF) self.data += chr((self.mfg_date >> 8) & 0xFF) @@ -283,9 +285,7 @@ def recalcute(self): valtmpval = getattr(self, valtmp) d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) self.data += chr(FruUtil.getTypeLength(valtmpval)) - if valtmpval is None: - pass - else: + if valtmpval is not None: self.data += valtmpval else: break @@ -293,14 +293,14 @@ def recalcute(self): self.data += chr(0xc1) if len(self.data) > (self.size - 1): - incr = (len(self.data) - self.size) / 8 + 1 + incr = (len(self.data) - self.size) // 8 + 1 self.size += incr * 8 - self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:] + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] d_print("self data:%d" % len(self.data)) d_print("self size:%d" % self.size) d_print("adjust size:%d" % (self.size - len(self.data) - 1)) - self.data = self.data.ljust((self.size - 1), self.INITVALUE) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) # checksum checksum = FruUtil.checksum(self.data) @@ -391,6 +391,7 @@ class ProductInfoArea(BaseArea): _productManufacturer = None _productAssetTag = None _FRUFileID = None + _language = None def __str__(self): formatstr = "version : %x\n" \ @@ -483,7 +484,7 @@ def decodedata(self): self.fruFileId = self.data[index + 1: index + templen + 1] index += templen + 1 d_print("decode fruFileId:%s" % self.fruFileId) - + for i in range(1, 11): valtmp = "productextra%d" % i if self.data[index] != chr(0xc1) and index < self.size - 1: @@ -567,12 +568,17 @@ def fruFileId(self): def fruFileId(self, name): self._FRUFileID = name + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + def recalcute(self): d_print("product version:%x" % ord(self.areaversion)) d_print("product length:%d" % self.size) d_print("product language:%x" % self.language) self.data = chr(ord(self.areaversion)) + \ - chr(self.size / 8) + chr(self.language) + chr(self.size // 8) + chr(self.language) typelength = FruUtil.getTypeLength(self.productManufacturer) self.data += chr(typelength) @@ -597,29 +603,26 @@ def recalcute(self): self.data += chr(FruUtil.getTypeLength(self.fruFileId)) self.data += self.fruFileId - # whether the extended field exists or not for i in range(1, 11): valtmp = "productextra%d" % i if hasattr(self, valtmp): valtmpval = getattr(self, valtmp) d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) self.data += chr(FruUtil.getTypeLength(valtmpval)) - if valtmpval is None: - pass - else: + if valtmpval is not None: self.data += valtmpval else: break self.data += chr(0xc1) if len(self.data) > (self.size - 1): - incr = (len(self.data) - self.size) / 8 + 1 + incr = (len(self.data) - self.size) // 8 + 1 self.size += incr * 8 d_print("self.data:%d" % len(self.data)) d_print("self.size:%d" % self.size) - self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:] - self.data = self.data.ljust((self.size - 1), self.INITVALUE) + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) checksum = FruUtil.checksum(self.data) d_print("board info checksum:%x" % checksum) self.data += chr(checksum) @@ -635,17 +638,13 @@ def __init__(self, fieldType="ASCII", fieldData=""): self.fieldData = fieldData self.fieldType = fieldType - @property - def data(self): - return self._data - @property def fieldType(self): - return self._fieldType + return self.fieldType @property def fieldData(self): - return self._fieldData + return self.fieldData class ipmifru(BaseArea): @@ -663,6 +662,7 @@ class ipmifru(BaseArea): _bodybin = None _version = BaseArea.COMMON_HEAD_VERSION _zeroCheckSum = None + _frusize = 256 def __str__(self): tmpstr = "" @@ -677,13 +677,13 @@ def __str__(self): def decodeBin(self, eeprom): commonHead = eeprom[0:8] d_print("decode version %x" % ord(commonHead[0])) - if self.COMMON_HEAD_VERSION != commonHead[0]: + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): raise FruException("HEAD VERSION error,not Fru format!", -10) if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): strtemp = "check header checksum error [cal:%02x data:%02x]" % ( FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) raise FruException(strtemp, -3) - if commonHead[1] != self.INITVALUE: + if ord(commonHead[1]) != ord(self.INITVALUE): d_print("Internal Use Area is present") self.internalUseArea = InternalUseArea( name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) @@ -691,7 +691,7 @@ def decodeBin(self, eeprom): self.internalUserAreaOffset = ord(commonHead[1]) self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( self.internalUserAreaOffset * 8 + self.internalUseArea.size)] - if commonHead[2] != self.INITVALUE: + if ord(commonHead[2]) != ord(self.INITVALUE): d_print("Chassis Info Area is present") self.chassisInfoArea = ChassisInfoArea( name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) @@ -699,7 +699,7 @@ def decodeBin(self, eeprom): self.chassicInfoAreaOffset = ord(commonHead[2]) self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] - if commonHead[3] != self.INITVALUE: + if ord(commonHead[3]) != ord(self.INITVALUE): self.boardInfoArea = BoardInfoArea( name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) self.boardInfoArea.isPresent = True @@ -711,12 +711,12 @@ def decodeBin(self, eeprom): self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): - print("check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ (FruUtil.checksum( - self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:]))) - sys.exit(-1) + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) self.boardInfoArea.decodedata() - if commonHead[4] != self.INITVALUE: + if ord(commonHead[4]) != ord(self.INITVALUE): d_print("Product Info Area is present") self.productInfoArea = ProductInfoArea( name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) @@ -736,7 +736,7 @@ def decodeBin(self, eeprom): FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) raise FruException(strtmp, -3) self.productInfoArea.decodedata() - if commonHead[5] != self.INITVALUE: + if ord(commonHead[5]) != ord(self.INITVALUE): self.multiRecordArea = MultiRecordArea( name="MultiRecord record Area ") d_print("MultiRecord record present") @@ -752,7 +752,6 @@ def initDefault(self): self.boardInfoAreaOffset = self.INITVALUE self.productinfoAreaOffset = self.INITVALUE self.multiRecordAreaOffset = self.INITVALUE - self.PAD = self.INITVALUE self.zeroCheckSum = self.INITVALUE self.offset = self.SUGGESTED_SIZE_COMMON_HEADER self.productInfoArea = None @@ -878,30 +877,31 @@ def recalcuteCommonHead(self): self.bindata = "" self.offset = self.SUGGESTED_SIZE_COMMON_HEADER d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) if self.internalUseArea is not None and self.internalUseArea.isPresent: - self.internalUserAreaOffset = self.offset / 8 + self.internalUserAreaOffset = self.offset // 8 self.offset += self.internalUseArea.size d_print("internalUseArea is present offset:%d" % self.offset) if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: - self.chassicInfoAreaOffset = self.offset / 8 + self.chassicInfoAreaOffset = self.offset // 8 self.offset += self.chassisInfoArea.size d_print("chassisInfoArea is present offset:%d" % self.offset) if self.boardInfoArea is not None and self.boardInfoArea.isPresent: - self.boardInfoAreaOffset = self.offset / 8 + self.boardInfoAreaOffset = self.offset // 8 self.offset += self.boardInfoArea.size d_print("boardInfoArea is present offset:%d" % self.offset) d_print("boardInfoArea is present size:%d" % self.boardInfoArea.size) if self.productInfoArea is not None and self.productInfoArea.isPresent: - self.productinfoAreaOffset = self.offset / 8 + self.productinfoAreaOffset = self.offset // 8 self.offset += self.productInfoArea.size d_print("productInfoArea is present offset:%d" % self.offset) if self.multiRecordArea is not None and self.multiRecordArea.isPresent: - self.multiRecordAreaOffset = self.offset / 8 + self.multiRecordAreaOffset = self.offset // 8 d_print("multiRecordArea is present offset:%d" % self.offset) if self.internalUserAreaOffset == self.INITVALUE: @@ -918,16 +918,17 @@ def recalcuteCommonHead(self): self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff d_print("zerochecksum:%x" % self.zeroCheckSum) - self.data = self.version + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( - self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + self.INITVALUE + chr(self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) self.bindata = self.data + self.bodybin totallen = len(self.bindata) d_print("totallen %d" % totallen) - if (totallen < 256): - self.bindata = self.bindata.ljust(256, self.INITVALUE) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) else: - raise FruException('bin data more than 256', -2) + raise FruException('bin data more than %d' % self._frusize, -2) def recalcutebin(self): self.bodybin = "" @@ -949,6 +950,12 @@ def recalcutebin(self): d_print("multiRecordArea present") self.bodybin += self.productInfoArea.data - def recalcute(self): + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size self.recalcutebin() self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/onietlv.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/onietlv.py new file mode 100644 index 000000000000..a90f8f8453c8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/eepromutil/onietlv.py @@ -0,0 +1,441 @@ +#!/usr/bin/python3 +import binascii + + +class OnietlvException(Exception): + def __init__(self, message='onietlverror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +class onie_tlv(object): + TLV_INFO_ID_STRING = "TlvInfo\x00" + TLV_INFO_INIA_ID = "\x00\x00\x13\x11" + TLV_INFO_VERSION = 0x01 + TLV_INFO_LENGTH = 0x00 + TLV_INFO_LENGTH_VALUE = 0xba + + TLV_CODE_PRODUCT_NAME = 0x21 + TLV_CODE_PART_NUMBER = 0x22 + TLV_CODE_SERIAL_NUMBER = 0x23 + TLV_CODE_MAC_BASE = 0x24 + TLV_CODE_MANUF_DATE = 0x25 + TLV_CODE_DEVICE_VERSION = 0x26 + TLV_CODE_LABEL_REVISION = 0x27 + TLV_CODE_PLATFORM_NAME = 0x28 + TLV_CODE_ONIE_VERSION = 0x29 + TLV_CODE_MAC_SIZE = 0x2A + TLV_CODE_MANUF_NAME = 0x2B + TLV_CODE_MANUF_COUNTRY = 0x2C + TLV_CODE_VENDOR_NAME = 0x2D + TLV_CODE_DIAG_VERSION = 0x2E + TLV_CODE_SERVICE_TAG = 0x2F + TLV_CODE_VENDOR_EXT = 0xFD + TLV_CODE_CRC_32 = 0xFE + _TLV_DISPLAY_VENDOR_EXT = 1 + TLV_CODE_WB_CARID = 0x01 + _TLV_INFO_HDR_LEN = 11 + TLV_CODE_PRODUCT_ID = 0x40 + TLV_CODE_HW_VERSION = 0x41 + TLV_CODE_MAIN_FILENAME = 0x42 + TLV_CODE_DTS_FINENAME = 0x43 + TLV_CODE_SY_SERIAL0 = 0x44 + TLV_CODE_SY_SERIAL1 = 0x45 + TLV_CODE_SY_SERIAL2 = 0x46 + TLV_CODE_SY_SERIAL3 = 0x47 + TLV_CODE_PROJECT_ID = 0x48 + TLV_CODE_SETMAC_VERSION = 0x49 + TLV_CODE_EEPROM_TYPE = 0x4A + + @property + def dstatus(self): + return self._dstatus + + @property + def cardid(self): + return self._cardid + + @property + def productname(self): + return self._productname + + @property + def partnum(self): + return self._partnum + + @property + def serialnum(self): + return self._serialnum + + @property + def macbase(self): + return self._macbase + + @property + def manufdate(self): + return self._manufdate + + @property + def deviceversion(self): + return self._deviceversion + + @property + def labelrevision(self): + return self._labelrevision + + @property + def platformname(self): + return self._platformname + + @property + def onieversion(self): + return self._onieversion + + @property + def macsize(self): + return self._macsize + + @property + def manufname(self): + return self._manufname + + @property + def manufcountry(self): + return self._manufcountry + + @property + def vendorname(self): + return self._vendorname + + @property + def diagname(self): + return self._diagname + + @property + def servicetag(self): + return self._servicetag + + @property + def vendorext(self): + return self._vendorext + + def __init__(self): + self._cardid = "" + self._productname = "" + self._partnum = "" + self._serialnum = "" + self._macbase = "" + self._manufdate = "" + self._deviceversion = "" + self._labelrevision = "" + self._platformname = "" + self._onieversion = "" + self._macsize = "" + self._manufname = "" + self._manufcountry = "" + self._vendorname = "" + self._diagname = "" + self._servicetag = "" + self._vendorext = "" + self._productid = "" + self._hwversion = "" + self._mainfilename = "" + self._dtsfilename = "" + self._syserial0 = "" + self._syserial1 = "" + self._syserial2 = "" + self._syserial3 = "" + self._projectid = "" + self._setmacversion = "" + self._eepromtype = "" + self._crc32 = "" + self._dstatus = 0 + + def oniecrc32(self, v): + data_array = bytearray() + for x in v: + data_array.append(ord(x)) + return '0x%08x' % (binascii.crc32(bytes(data_array)) & 0xffffffff) + + def getTLV_BODY(self, tlv_type, value): + x = [] + temp_t = "" + if tlv_type == self.TLV_CODE_MAC_BASE: + arr = value.split(':') + for tt in arr: + temp_t += chr(int(tt, 16)) + elif tlv_type == self.TLV_CODE_DEVICE_VERSION: + temp_t = chr(value) + elif tlv_type == self.TLV_CODE_MAC_SIZE: + temp_t = chr(value >> 8) + chr(value & 0x00ff) + else: + temp_t = value + x.append(chr(tlv_type)) + x.append(chr(len(temp_t))) + for i in temp_t: + x.append(i) + return x + + def generate_ext(self, cardid): + s = "%08x" % cardid + ret = "" + for t in range(0, 4): + ret += chr(int(s[2 * t:2 * t + 2], 16)) + ret = chr(0x01) + chr(len(ret)) + ret + return ret + + def generate_value(self, _t): + ret = [] + for i in self.TLV_INFO_ID_STRING: + ret.append(i) + ret.append(chr(self.TLV_INFO_VERSION)) + ret.append(chr(self.TLV_INFO_LENGTH)) + ret.append(chr(self.TLV_INFO_LENGTH_VALUE)) + + total_len = 0 + for key in _t: + x = self.getTLV_BODY(key, _t[key]) + ret += x + total_len += len(x) + ret[10] = chr(total_len + 6) + + ret.append(chr(0xFE)) + ret.append(chr(0x04)) + s = self.oniecrc32(''.join(ret)) + for t in range(0, 4): + ret.append(chr(int(s[2 * t + 2:2 * t + 4], 16))) + totallen = len(ret) + if totallen < 256: + for left_t in range(0, 256 - totallen): + ret.append(chr(0x00)) + return (ret, True) + + def decode_tlv(self, e): + tlv_index = 0 + tlv_end = len(e) + ret = [] + while tlv_index < tlv_end and (tlv_index + 2 + ord(e[tlv_index + 1])) <= len(e): + rt = self.decoder(e[tlv_index:tlv_index + 2 + ord(e[tlv_index + 1])]) + ret.append(rt) + if ord(e[tlv_index]) == self.TLV_CODE_CRC_32: + break + tlv_index += ord(e[tlv_index + 1]) + 2 + return ret + + def decode(self, e): + if e[0:8] != self.TLV_INFO_ID_STRING: + raise OnietlvException("ONIE tlv head info error,not onie tlv type", -1) + total_len = (ord(e[9]) << 8) | ord(e[10]) + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_len + if tlv_end > len(e): + raise OnietlvException("ONIE tlv length error", -2) + ret = [] + ret = self.decode_tlv(e[tlv_index:tlv_end]) + for item in ret: + if item['code'] == self.TLV_CODE_VENDOR_EXT: + if item["value"][0:4] == self.TLV_INFO_INIA_ID: + rt = self.decode_tlv(item["value"][4:]) + else: + rt = self.decode_tlv(item["value"][0:]) + ret.extend(rt) + return ret + + def decoder(self, t): + if ord(t[0]) == self.TLV_CODE_PRODUCT_NAME: + name = "Product Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._productname = value + elif ord(t[0]) == self.TLV_CODE_PART_NUMBER: + name = "Part Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._partnum = value + elif ord(t[0]) == self.TLV_CODE_SERIAL_NUMBER: + name = "Serial Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._serialnum = value + elif ord(t[0]) == self.TLV_CODE_MAC_BASE: + name = "Base MAC Address" + _len = ord(t[1]) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._macbase = value + elif ord(t[0]) == self.TLV_CODE_MANUF_DATE: + name = "Manufacture Date" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._manufdate = value + elif ord(t[0]) == self.TLV_CODE_DEVICE_VERSION: + name = "Device Version" + _len = ord(t[1]) + value = ord(t[2]) + self._deviceversion = value + elif ord(t[0]) == self.TLV_CODE_LABEL_REVISION: + name = "Label Revision" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._labelrevision = value + elif ord(t[0]) == self.TLV_CODE_PLATFORM_NAME: + name = "Platform Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._platformname = value + elif ord(t[0]) == self.TLV_CODE_ONIE_VERSION: + name = "ONIE Version" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._onieversion = value + elif ord(t[0]) == self.TLV_CODE_MAC_SIZE: + name = "MAC Addresses" + _len = ord(t[1]) + value = str((ord(t[2]) << 8) | ord(t[3])) + self._macsize = value + elif ord(t[0]) == self.TLV_CODE_MANUF_NAME: + name = "Manufacturer" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._manufname = value + elif ord(t[0]) == self.TLV_CODE_MANUF_COUNTRY: + name = "Manufacture Country" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._manufcountry = value + elif ord(t[0]) == self.TLV_CODE_VENDOR_NAME: + name = "Vendor Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._vendorname = value + elif ord(t[0]) == self.TLV_CODE_DIAG_VERSION: + name = "Diag Version" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._diagname = value + elif ord(t[0]) == self.TLV_CODE_SERVICE_TAG: + name = "Service Tag" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._servicetag = value + elif ord(t[0]) == self.TLV_CODE_VENDOR_EXT: + name = "Vendor Extension" + _len = ord(t[1]) + value = "" + if self._TLV_DISPLAY_VENDOR_EXT: + value = t[2:2 + ord(t[1])] + self._vendorext = value + elif ord(t[0]) == self.TLV_CODE_CRC_32 and len(t) == 6: + name = "CRC-32" + _len = ord(t[1]) + value = "0x%08X" % (((ord(t[2]) << 24) | ( + ord(t[3]) << 16) | (ord(t[4]) << 8) | ord(t[5])),) + self._crc32 = value + elif ord(t[0]) == self.TLV_CODE_WB_CARID: + name = "Card id" + _len = ord(t[1]) + value = "" + for c in t[2:2 + ord(t[1])]: + value += "%02X" % (ord(c),) + self._cardid = value + elif ord(t[0]) == self.TLV_CODE_PRODUCT_ID: + name = "Product id" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._productid = value + elif ord(t[0]) == self.TLV_CODE_HW_VERSION: + name = "Hardware Version" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._hwversion = value + elif ord(t[0]) == self.TLV_CODE_MAIN_FILENAME: + name = "Main File Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._mainfilename = value + elif ord(t[0]) == self.TLV_CODE_DTS_FINENAME: + name = "DTS File Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._dtsfilename = value + elif ord(t[0]) == self.TLV_CODE_SY_SERIAL0: + name = "SY Serial 0" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._syserial0 = value + elif ord(t[0]) == self.TLV_CODE_SY_SERIAL1: + name = "SY Serial 1" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._syserial1 = value + elif ord(t[0]) == self.TLV_CODE_SY_SERIAL2: + name = "SY Serial 2" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._syserial2 = value + elif ord(t[0]) == self.TLV_CODE_SY_SERIAL3: + name = "SY Serial 3" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._syserial3 = value + elif ord(t[0]) == self.TLV_CODE_PROJECT_ID: + name = "Project id" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._projectid = value + elif ord(t[0]) == self.TLV_CODE_SETMAC_VERSION: + name = "Setmac Version" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._setmacversion = value + elif ord(t[0]) == self.TLV_CODE_EEPROM_TYPE: + name = "EEPROM Type" + _len = ord(t[1]) + value = "" + for c in t[2:2 + ord(t[1])]: + value += "%02X" % (ord(c),) + self._eepromtype = value + else: + name = "Unknown" + _len = ord(t[1]) + value = "" + for c in t[2:2 + ord(t[1])]: + value += "0x%02X " % (ord(c),) + return {"name": name, "code": ord(t[0]), "value": value, "lens": _len} + + def __str__(self): + formatstr = "Card id : %s \n" \ + "Product Name : %s \n" \ + "Part Number : %s \n" \ + "Serial Number : %s \n" \ + "Base MAC Address : %s \n" \ + "Manufacture Date : %s \n" \ + "Device Version : %s \n" \ + "Label Revision : %s \n" \ + "Platform Name : %s \n" \ + "ONIE Version : %s \n" \ + "MAC Addresses : %s \n" \ + "Manufacturer : %s \n" \ + "Manufacture Country : %s \n" \ + "Vendor Name : %s \n" \ + "Diag Version : %s \n" \ + "Service Tag : %s \n" \ + "CRC-32 : %s \n" + return formatstr % (self._cardid, + self._productname, + self._partnum, + self._serialnum, + self._macbase, + self._manufdate, + self._deviceversion, + self._labelrevision, + self._platformname, + self._onieversion, + self._macsize, + self._manufname, + self._manufcountry, + self._vendorname, + self._diagname, + self._servicetag, + self._crc32) diff --git a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/pddf_support b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/__init__.py similarity index 100% rename from device/ragile/x86_64-ragile_ra-b6910-64c-r0/pddf_support rename to platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/__init__.py diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/baseutil.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/baseutil.py new file mode 100644 index 000000000000..ffe271a424c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/baseutil.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python3 +####################################################### +# +# baseutil.py +# Python implementation of the Class baseutil +# +####################################################### +import importlib.machinery +import os +import syslog +import json +from plat_hal.osutil import osutil + +SYSLOG_IDENTIFIER = "HAL" + +CONFIG_DB_PATH = "/etc/sonic/config_db.json" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + +def getonieplatform(path): + if not os.path.isfile(path): + return "" + machine_vars = {} + with open(path) as machine_file: + for line in machine_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + machine_vars[tokens[0]] = tokens[1].strip() + return machine_vars.get("onie_platform") + + +def getboardid(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +def getplatform_config_db(): + if not os.path.isfile(CONFIG_DB_PATH): + return "" + val = os.popen("sonic-cfggen -j %s -v DEVICE_METADATA.localhost.platform" % CONFIG_DB_PATH).read().strip() + if len(val) <= 0: + return "" + return val + + +def getplatform_name(): + if os.path.isfile('/host/machine.conf'): + return getonieplatform('/host/machine.conf') + if os.path.isfile('/usr/share/sonic/hwsku/machine.conf'): + return getonieplatform('/usr/share/sonic/hwsku/machine.conf') + return getplatform_config_db() + + +platform = (getplatform_name()).replace("-", "_") +boardid = getboardid() +boardairflow = getboardairflow() + + +CONFIG_FILE_PATH_LIST = [ + "/usr/local/bin/", + "/usr/lib/python3/dist-packages/", + "/usr/local/lib/python3.7/dist-packages/hal-config/", + "/usr/local/lib/python3.9/dist-packages/hal-config/" +] + + +DEVICE_CONFIG_FILE_LIST = [ + platform + "_" + boardid + "_" + boardairflow + "_device.py", + platform + "_" + boardid + "_device.py", + platform + "_" + boardairflow + "_device.py", + platform + "_device.py" +] + + +MONITOR_CONFIG_FILE_LIST = [ + platform + "_" + boardid + "_" + boardairflow + "_monitor.py", + platform + "_" + boardid + "_monitor.py", + platform + "_" + boardairflow + "_monitor.py", + platform + "_monitor.py" +] + + +class baseutil: + + CONFIG_NAME = 'devices' + MONITOR_CONFIG_NAME = 'monitor' + UBOOT_ENV_URL = '/etc/device/uboot_env' + + @staticmethod + def get_config(): + real_path = None + for configfile_path in CONFIG_FILE_PATH_LIST: + for config_file in DEVICE_CONFIG_FILE_LIST: + file = configfile_path + config_file + if os.path.exists(file): + real_path = file + break + if real_path is not None: + break + + if real_path is None: + raise Exception("get hal device config error") + devices = importlib.machinery.SourceFileLoader(baseutil.CONFIG_NAME, real_path).load_module() + return devices.devices + + @staticmethod + def get_monitor_config(): + real_path = None + for configfile_path in CONFIG_FILE_PATH_LIST: + for config_file in MONITOR_CONFIG_FILE_LIST: + file = configfile_path + config_file + if os.path.exists(file): + real_path = file + break + if real_path is not None: + break + + if real_path is None: + raise Exception("get hal monitor config error") + monitor = importlib.machinery.SourceFileLoader(baseutil.MONITOR_CONFIG_NAME, real_path).load_module() + return monitor.monitor + + @staticmethod + def get_productname(): + ret, val = osutil.command("cat %s |grep productname | awk -F\"=\" '{print $2;}'" % baseutil.UBOOT_ENV_URL) + tmp = val.lower().replace('-', '_') + if ret != 0 or len(val) <= 0: + raise Exception("get productname error") + return tmp + + @staticmethod + def get_platform(): + ret, val = osutil.command("cat %s |grep conffitname | awk -F\"=\" '{print $2;}'" % baseutil.UBOOT_ENV_URL) + if ret != 0 or len(val) <= 0: + raise Exception("get platform error") + return val + + @staticmethod + def get_product_fullname(): + ret, val = osutil.command("cat %s |grep productname | awk -F\"=\" '{print $2;}'" % baseutil.UBOOT_ENV_URL) + if ret != 0 or len(val) <= 0: + raise Exception("get productname error") + return val + + @staticmethod + def logger_debug(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_DEBUG, msg) + syslog.closelog() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/chassisbase.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/chassisbase.py new file mode 100644 index 000000000000..767d6da34ba9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/chassisbase.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python3 +####################################################### +# +# chassisbase.py +# Python implementation of the Class chassisbase +# +####################################################### +from plat_hal.dcdc import dcdc +from plat_hal.onie_e2 import onie_e2 +from plat_hal.psu import psu +from plat_hal.led import led +from plat_hal.temp import temp +from plat_hal.fan import fan +from plat_hal.cpld import cpld +from plat_hal.component import component +from plat_hal.cpu import cpu +from plat_hal.baseutil import baseutil + + +class chassisbase(object): + __onie_e2_list = [] + __psu_list = [] + __led_list = [] + __temp_list = [] + __fan_list = [] + __card_list = [] + __sensor_list = [] + __dcdc_list = [] + __cpld_list = [] + __comp_list = [] + __bios_list = [] + __bmc_list = [] + __cpu = None + + def __init__(self, conftype=0, conf=None): + # type: (object, object, object) -> object + """ + init chassisbase as order + + type = 0 use default conf, maybe auto find by platform + type = 1 use given conf, conf is not None + + BITMAP + bit 16 + bit 0 PSU + bit 1 LED + bit 2 TEMP + bit 3 fan + bit 4 card + bit 5 sensor + """ + __confTemp = None + + if conftype == 0: + # user + __confTemp = baseutil.get_config() + elif conftype == 1: + __confTemp = conf + + # onie_e2 + onie_e2temp = [] + onie_e2config = __confTemp.get('onie_e2', []) + for item in onie_e2config: + onie_e2_1 = onie_e2(item) + onie_e2temp.append(onie_e2_1) + self.onie_e2_list = onie_e2temp + + # psu + psutemp = [] + psuconfig = __confTemp.get('psus', []) + for item in psuconfig: + psu1 = psu(item) + psutemp.append(psu1) + self.psu_list = psutemp + + # led + ledtemp = [] + ledconfig = __confTemp.get('leds', []) + for item in ledconfig: + led1 = led(item) + ledtemp.append(led1) + self.led_list = ledtemp + + # temp + temptemp = [] + tempconfig = __confTemp.get('temps', []) + for item in tempconfig: + temp1 = temp(item) + temptemp.append(temp1) + self.temp_list = temptemp + + # fan + fantemp = [] + fanconfig = __confTemp.get('fans', []) + for item in fanconfig: + fan1 = fan(item) + fantemp.append(fan1) + self.fan_list = fantemp + + # dcdc + dcdctemp = [] + dcdcconfig = __confTemp.get('dcdc', []) + for item in dcdcconfig: + dcdc1 = dcdc(item) + dcdctemp.append(dcdc1) + self.dcdc_list = dcdctemp + + # cpld + cpldtemp = [] + cpldconfig = __confTemp.get('cplds', []) + for item in cpldconfig: + cpld1 = cpld(item) + cpldtemp.append(cpld1) + self.cpld_list = cpldtemp + + # compoment: cpld/fpga/bios + comptemp = [] + compconfig = __confTemp.get('comp_cpld', []) + for item in compconfig: + comp1 = component(item) + comptemp.append(comp1) + self.comp_list = comptemp + + compconfig = __confTemp.get('comp_fpga', []) + for item in compconfig: + comp1 = component(item) + self.comp_list.append(comp1) + + compconfig = __confTemp.get('comp_bios', []) + for item in compconfig: + comp1 = component(item) + self.comp_list.append(comp1) + + # cpu + cpuconfig = __confTemp.get('cpu', []) + if len(cpuconfig): + self.cpu = cpu(cpuconfig[0]) + + # dcdc + @property + def dcdc_list(self): + return self.__dcdc_list + + @dcdc_list.setter + def dcdc_list(self, val): + self.__dcdc_list = val + + # sensor + @property + def sensor_list(self): + return self.__sensor_list + + @sensor_list.setter + def sensor_list(self, val): + self.__sensor_list = val + + def get_sensor_byname(self, name): + tmp = self.sensor_list + for item in tmp: + if name == item.name: + return item + return None + + # onie_e2 + @property + def onie_e2_list(self): + return self.__onie_e2_list + + @onie_e2_list.setter + def onie_e2_list(self, val): + self.__onie_e2_list = val + + def get_onie_e2_byname(self, name): + tmp = self.onie_e2_list + for item in tmp: + if name == item.name: + return item + return None + + # psu + @property + def psu_list(self): + return self.__psu_list + + @psu_list.setter + def psu_list(self, val): + self.__psu_list = val + + def get_psu_byname(self, name): + tmp = self.psu_list + for item in tmp: + if name == item.name: + return item + return None + + # fan + @property + def fan_list(self): + return self.__fan_list + + @fan_list.setter + def fan_list(self, val): + self.__fan_list = val + + def get_fan_byname(self, name): + tmp = self.fan_list + for item in tmp: + if name == item.name: + return item + return None + + # led + + @property + def led_list(self): + return self.__led_list + + @led_list.setter + def led_list(self, val): + self.__led_list = val + + def get_led_byname(self, name): + tmp = self.led_list + for item in tmp: + if name == item.name: + return item + return None + + # temp + @property + def temp_list(self): + return self.__temp_list + + @temp_list.setter + def temp_list(self, val): + self.__temp_list = val + + def get_temp_byname(self, name): + tmp = self.temp_list + for item in tmp: + if name == item.name: + return item + return None + + # cpld + @property + def cpld_list(self): + return self.__cpld_list + + @cpld_list.setter + def cpld_list(self, val): + self.__cpld_list = val + + def get_cpld_byname(self, name): + tmp = self.cpld_list + for item in tmp: + if name == item.name: + return item + return None + + @property + def comp_list(self): + return self.__comp_list + + @comp_list.setter + def comp_list(self, val): + self.__comp_list = val + + def get_comp_byname(self, name): + tmp = self.comp_list + for item in tmp: + if name == item.name: + return item + return None + + # bios + @property + def bios_list(self): + return self.__bios_list + + @bios_list.setter + def bios_list(self, val): + self.__bios_list = val + + def get_bios_byname(self, name): + tmp = self.bios_list + for item in tmp: + if name == item.name: + return item + return None + + # bmc + @property + def bmc_list(self): + return self.__bmc_list + + @bmc_list.setter + def bmc_list(self, val): + self.__bmc_list = val + + def get_bmc_byname(self, name): + tmp = self.bmc_list + for item in tmp: + if name == item.name: + return item + return None + + # cpu + @property + def cpu(self): + return self.__cpu + + @cpu.setter + def cpu(self, val): + self.__cpu = val + + def get_cpu_byname(self, name): + return self.cpu diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/component.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/component.py new file mode 100644 index 000000000000..0f2ad2167485 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/component.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +####################################################### +# +# component.py +# Python implementation of the Class fan +# +####################################################### +from plat_hal.devicebase import devicebase +from plat_hal.osutil import osutil + + +class component(devicebase): + __user_reg = None + + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.version_file = conf.get('VersionFile', None) + self.comp_id = conf.get("comp_id", None) + self.desc = conf.get("desc", None) + self.slot = conf.get("slot", None) + + def get_version(self): + version = "NA" + try: + ret, version = self.get_value(self.version_file) + if ret is False: + return version + pattern = self.version_file.get('pattern', None) + version = osutil.std_match(version, pattern) + except Exception: + return version + return version diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpld.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpld.py new file mode 100644 index 000000000000..ceb44cb4ca31 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpld.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +####################################################### +# +# fan.py +# Python implementation of the Class fan +# +####################################################### +from plat_hal.devicebase import devicebase + + +class cpld(devicebase): + __user_reg = None + + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.user_reg = conf.get('UserReg', None) + self.console_reg = conf.get('ConsoleReg', None) + self.console_reg_attrs = conf.get('ConsoleRegAttrs', None) + self.version_file = conf.get('VersionFile', None) + self.cpld_id = conf.get("cpld_id", None) + self.desc = conf.get("desc", None) + self.slot = conf.get("slot", None) + self.format = conf.get("format", "big_endian") + self.warm = conf.get("warm", None) + self.type = conf.get("type", None) + + def get_user_reg(self): + if self.user_reg is None: + return False + ret, val = self.get_value(self.user_reg) + return val + + def set_user_reg(self, value): + if self.user_reg is None: + return False + byte = value & 0xFF + ret, val = self.set_value(self.user_reg, byte) + return ret + + def set_console_owner(self, owner): + ret = False + + if self.console_reg is None: + return False + tmpattr = self.console_reg_attrs.get(owner, None) + if tmpattr is not None: + ret, val = self.set_value(self.console_reg, tmpattr) + return ret + + def get_version(self): + ret, val = self.get_value(self.version_file) + if ret is False: + val = "N/A" + return val + if self.type == "str": + return self.byteTostr(val).strip('\n') + val = val.strip('\n').split(" ") + if len(val) < 4: + val = "N/A" + return val + if self.format == "little_endian": + cpld_version = "%s%s%s%s" % (val[3], val[2], val[1], val[0]) + else: + cpld_version = "%s%s%s%s" % (val[0], val[1], val[2], val[3]) + return cpld_version diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpu.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpu.py new file mode 100644 index 000000000000..98aecdab4129 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/cpu.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +############################################################################### +# +# Hardware Abstraction Layer APIs -- CPU APIs. +# +############################################################################### +from plat_hal.devicebase import devicebase + + +class cpu(devicebase): + + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.cpu_reset_cnt_reg = conf.get('CpuResetCntReg', None) + + def get_cpu_reset_num(self): + """ + get cpu reset num. + @return cpu reset number, -1 for failure + """ + ret = -1 + if self.cpu_reset_cnt_reg is None: + self.logger_debug("ERR: no support get cpu reset num") + return ret + ret, reset_num = self.get_value(self.cpu_reset_cnt_reg) + if ret is False or reset_num is None: + self.logger_debug("ERR: i2c read cpu_reset_cnt_reg,result:%s" % reset_num) + else: + if isinstance(reset_num, str): + ret = int(reset_num, 16) + else: + ret = reset_num + return ret diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/dcdc.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/dcdc.py new file mode 100644 index 000000000000..ba604995043d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/dcdc.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +from plat_hal.devicebase import devicebase +from plat_hal.sensor import sensor + + +class dcdc(devicebase): + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.dcdc_id = conf.get("dcdc_id", None) + self.sensor = sensor(conf) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/devicebase.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/devicebase.py new file mode 100644 index 000000000000..e66ae0143f02 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/devicebase.py @@ -0,0 +1,355 @@ +#!/usr/bin/env python3 +####################################################### +# +# devicebase.py +# Python implementation of the Class devicebase +# +####################################################### +import subprocess +import shlex +import ast +from plat_hal.osutil import osutil +from plat_hal.baseutil import baseutil + +class CodeVisitor(ast.NodeVisitor): + + def __init__(self): + self.value = None + + def get_value(self): + return self.value + + def get_op_value(self, node): + if isinstance(node, ast.Call): # node is func call + value = self.visit_Call(node) + elif isinstance(node, ast.BinOp): # node is BinOp + value = self.visit_BinOp(node) + elif isinstance(node, ast.UnaryOp): # node is UnaryOp + value = self.visit_UnaryOp(node) + elif isinstance(node, ast.Num): # node is Num Constant + value = node.n + elif isinstance(node, ast.Str): # node is Str Constant + value = node.s + else: + raise NotImplementedError("Unsupport operand type: %s" % type(node)) + return value + + def visit_UnaryOp(self, node): + ''' + node.op: operand type, only support ast.UAdd/ast.USub + node.operand: only support ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp/ast.UnaryOp + ''' + + operand_value = self.get_op_value(node.operand) + if isinstance(node.op, ast.UAdd): + self.value = operand_value + elif isinstance(node.op, ast.USub): + self.value = 0 - operand_value + else: + raise NotImplementedError("Unsupport arithmetic methods %s" % type(node.op)) + return self.value + + def visit_BinOp(self, node): + ''' + node.left: left operand, only support ast.Call/ast.Constant(ast.Num)/ast.BinOp + node.op: operand type, only support ast.Add/ast.Sub/ast.Mult/ast.Div + node.right: right operan, only support ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp + ''' + left_value = self.get_op_value(node.left) + right_value = self.get_op_value(node.right) + + if isinstance(node.op, ast.Add): + self.value = left_value + right_value + elif isinstance(node.op, ast.Sub): + self.value = left_value - right_value + elif isinstance(node.op, ast.Mult): + self.value = left_value * right_value + elif isinstance(node.op, ast.Div): + self.value = left_value / right_value + else: + raise NotImplementedError("Unsupport arithmetic methods %s" % type(node.op)) + return self.value + + def visit_Call(self, node): + ''' + node.func.id: func name, only support 'float', 'int', 'str' + node.args: func args list,only support ast.Constant(ast.Num/ast.Str)/ast.BinOp/ast.Call + str/float only support one parameter, eg: float(XXX), str(xxx) + int support one or two parameters, eg: int(xxx) or int(xxx, 16) + xxx can be ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp + ''' + calc_tuple = ("float", "int", "str") + + if node.func.id not in calc_tuple: + raise NotImplementedError("Unsupport function call type: %s" % node.func.id) + + args_val_list = [] + for item in node.args: + ret = self.get_op_value(item) + args_val_list.append(ret) + + if node.func.id == "str": + if len(args_val_list) != 1: + raise TypeError("str() takes 1 positional argument but %s were given" % len(args_val_list)) + value = str(args_val_list[0]) + self.value = value + return value + + if node.func.id == "float": + if len(args_val_list) != 1: + raise TypeError("float() takes 1 positional argument but %s were given" % len(args_val_list)) + value = float(args_val_list[0]) + self.value = value + return value + # int + if len(args_val_list) == 1: + value = int(args_val_list[0]) + self.value = value + return value + if len(args_val_list) == 2: + value = int(args_val_list[0], args_val_list[1]) + self.value = value + return value + raise TypeError("int() takes 1 or 2 arguments (%s given)" % len(args_val_list)) + + +class devicebase(object): + _name = None + __error_ret = -99999 + + @property + def name(self): + return self._name + + @name.setter + def name(self, val): + self._name = val + + def dumpValueByI2c(self, bus, loc): + value = "" + for i in range(256): + ret, val = self.get_i2c(bus, loc, i) + value += chr(val) + return value + + def byteTostr(self, val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + def get_eeprom_info(self, conf): + eeprom = "" + if conf.get('way') == 'sysfs': + ret, eeprom = self.get_value(conf) + if ret is False: + return None + elif conf.get('way') == 'devfile': + ret, eeprom_list = self.get_value(conf) + if ret is False: + return None + for item in eeprom_list: + eeprom += chr(item) + else: + eeprom = self.dumpValueByI2c(conf.get('bus'), conf.get('addr')) + return eeprom + + def exec_os_cmd(self, cmd): + cmds = cmd.split('|') + procs = [] + for i, c in enumerate(cmds): + stdin = None if i == 0 else procs[i-1].stdout + p = subprocess.Popen(shlex.split(c), stdin=stdin, stdout=subprocess.PIPE, shell=False, stderr=subprocess.STDOUT) + procs.append(p) + for proc in procs: + proc.wait() + return procs[-1].returncode, self.byteTostr(procs[-1].communicate()[0]) + + def get_value(self, config): + ''' + get value by config way + way i2c/sysfs/lpc + ''' + way = config.get("way") + if way == 'sysfs': + return self.get_sysfs(config.get("loc"), config.get("flock_path")) + if way == "i2c": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.get_i2c(bus, addr, offset) + if way == "io": + io_addr = config.get('io_addr') + read_len = config.get('read_len', 1) + return self.get_io(io_addr, read_len) + if way == "i2cword": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.get_i2cword(bus, addr, offset) + if way == "devmem": + addr = config.get("addr") + digit = config.get("digit") + mask = config.get("mask", None) + return self.get_devmem(addr, digit, mask) + if way == "sdk": + get_type = config.get("type") + if get_type == "bcm_temp": + return self.getbcmtemp() + if get_type == "bcm_reg": + reg = config.get("reg") + return self.getbcmreg(reg) + raise Exception("cannot found sdk type deal") + if way == "devfile": + loc = config.get("loc") + offset = config.get("offset") + length = config.get("len") + ret, val_list = self.devfile_read(loc, offset, length) + if ret is True: + if length == 1: + val = val_list[0] + return True, val + return True, val_list + return False, ("devfile read failed. path:%s, offset:0x%x, read_len:%d" % (loc, offset, length)) + if way == "devfile_ascii": + loc = config.get("loc") + offset = config.get("offset") + length = config.get("len") + return self.devfile_read_ascii(loc, offset, length) + if way == 'cmd': + cmd = config.get("cmd") + ret, log = self.exec_os_cmd(cmd) + if ret: + return False, ("cmd write exec %s failed, log: %s" % (cmd, log)) + return True, log + raise Exception("cannot found way deal") + + def devfile_read(self, loc, offset, length): + return osutil.readdevfile(loc, offset, length) + + def devfile_read_ascii(self, loc, offset, length): + return osutil.readdevfile_ascii(loc, offset, length) + + def get_sysfs(self, loc, flock_path=None): + return self.getsysfs(loc, flock_path) + + def getsysfs(self, loc, flock_path=None): + ret, val = osutil.readsysfs(loc, flock_path) + return ret, val + + def get_devmem(self, addr, digit, mask): + return osutil.getdevmem(addr, digit, mask) + + def get_i2cword(self, bus, addr, offset): + return self.geti2cword(bus, addr, offset) + + def geti2cword(self, bus, addr, offset): + ret, val = osutil.geti2cword(bus, addr, offset) + return ret, val + + def get_io(self, reg_addr, read_len): + return self.getio(reg_addr, read_len) + + def getio(self, reg_addr, read_len): + ret, val = osutil.io_rd(reg_addr, read_len) + return ret, val + + def get_i2c(self, bus, addr, offset): + return self.geti2c(bus, addr, offset) + + def geti2c(self, bus, addr, offset): + ret, val = osutil.wbi2cget(bus, addr, offset) + return ret, val + + def set_value(self, config, val): + ''' + get value by config way + way i2c/sysfs/lpc + ''' + way = config.get("way") + if way == 'sysfs': + return self.set_sysfs(config.get("loc"), "0x%02x" % val) + if way == "i2c": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.set_i2c(bus, addr, offset, val) + if way == "i2cpec": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.seti2c_byte_pec(bus, addr, offset, val) + if way == 'i2cword': + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.set_i2cword(bus, addr, offset, val) + if way == "i2cwordpec": + bus = config.get("bus") + addr = config.get("addr") + offset = config.get("offset") + return self.set_i2cwordpec(bus, addr, offset, val) + if way == "devfile": + loc = config.get("loc") + offset = config.get("offset") + return self.devfile_write(loc, offset, val) + return False, "unsupport way: %s" % way + + def set_sysfs(self, loc, value): + return self.setsysfs(loc, value) + + def setsysfs(self, loc, value): + return osutil.writesysfs(loc, value) + + def set_i2cword(self, bus, addr, offset, byte): + return self.seti2cword(bus, addr, offset, byte) + + def seti2cword(self, bus, addr, offset, byte): + return osutil.seti2cword(bus, addr, offset, byte) + + def set_i2cwordpec(self, bus, addr, offset, val): + return osutil.seti2cwordpec(bus, addr, offset, val) + + def seti2c_byte_pec(self, bus, addr, offset, val): + return osutil.seti2c_byte_pec(bus, addr, offset, val) + + def set_i2c(self, bus, addr, offset, byte): + return self.seti2c(bus, addr, offset, byte) + + def seti2c(self, bus, addr, offset, byte): + ret, val = osutil.wbi2cset(bus, addr, offset, byte) + return ret, val + + def devfile_write(self, loc, offset, val): + ret, val = osutil.writedevfile(loc, offset, val) + return ret, val + + def getbcmtemp(self): + try: + sta, ret = osutil.getmactemp() + if sta is True: + mac_aver = float(ret.get("average", self.__error_ret)) + mac_aver = mac_aver * 1000 + else: + return False, ret + except AttributeError as e: + return False, str(e) + return True, mac_aver + + def getbcmreg(self, reg): + ret, val = osutil.getsdkreg(reg) + return ret, val + + def logger_debug(self, msg): + baseutil.logger_debug(msg) + + def command(self, cmd): + ret, output = osutil.command(cmd) + return ret, output + + def get_format_value(self, format_str): + ast_obj = ast.parse(format_str, mode='eval') + visitor = CodeVisitor() + visitor.visit(ast_obj) + ret = visitor.get_value() + return ret diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/fan.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/fan.py new file mode 100644 index 000000000000..8b503bf6418f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/fan.py @@ -0,0 +1,413 @@ +#!/usr/bin/env python3 +####################################################### +# +# fan.py +# Python implementation of the Class fan +# +####################################################### +from eepromutil.fru import ipmifru +from eepromutil.fantlv import fan_tlv +from plat_hal.devicebase import devicebase +from plat_hal.rotor import rotor + + +class fan(devicebase): + __rotor_list = [] + __pn = None + __raweeprom = None + __sn = None + __hw_version = None + __e2loc = None + __rotors = None + __AirFlow = None + __SpeedMin = None + __SpeedMax = None + __PowerMax = None + __productName = None + __productSerialNumber = None + __WatchdogStatus = None + __led_attrs_config = None + __led_config = None + __WatchdogStatus_config = None + __AirFlowconifg = None + __EnableWatchdogConf = None + __Rotor_config = None + __fan_display_name = None # 'N/A' + __fan_display_name_conifg = None + + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.sn = conf.get('sn', None) + self.present = conf.get('present', None) + self.e2loc = conf.get('e2loc', None) + self.SpeedMin = conf.get('SpeedMin', None) + self.SpeedMax = conf.get('SpeedMax', None) + self.PowerMax = conf.get('PowerMax', None) + self.AirFlowconifg = conf.get("airflow", None) + self.WatchdogStatus_config = conf.get('WatchdogStatus', None) + self.EnableWatchdogConf = conf.get('EnableWatchdogConf', None) + self.led_attrs_config = conf.get('led_attrs', None) + self.led_config = conf.get('led', None) + self.Rotor_config = conf.get('Rotor', None) + self.fan_display_name_conifg = conf.get("fan_display_name", None) + rotor_tmp = [] + for value in self.Rotor_config.values(): + rotor_tmp.append(rotor(value)) + rotor_tmp.sort(key=lambda x: x.name, reverse=False) + self.rotor_list = rotor_tmp + self.rotors = len(self.rotor_list) + + @property + def EnableWatchdogConf(self): + return self.__EnableWatchdogConf + + @EnableWatchdogConf.setter + def EnableWatchdogConf(self, val): + self.__EnableWatchdogConf = val + + @property + def rotor_list(self): + return self.__rotor_list + + @rotor_list.setter + def rotor_list(self, val): + self.__rotor_list = val + + @property + def Rotor_config(self): + return self.__Rotor_config + + @Rotor_config.setter + def Rotor_config(self, val): + self.__Rotor_config = val + + @property + def productName(self): + return self.__productName + + @productName.setter + def productName(self, val): + self.__productName = val + + @property + def productSerialNumber(self): + return self.__productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, val): + self.__productSerialNumber = val + + @property + def hw_version(self): + return self.__hw_version + + @hw_version.setter + def hw_version(self, val): + self.__hw_version = val + + @property + def sn(self): + return self.__sn + + @sn.setter + def sn(self, val): + self.__sn = val + + @property + def pn(self): + return self.__pn + + @pn.setter + def pn(self, val): + self.__pn = val + + @property + def raweeprom(self): + return self.__raweeprom + + @raweeprom.setter + def raweeprom(self, val): + self.__raweeprom = val + + @property + def SpeedMax(self): + return self.__SpeedMax + + @SpeedMax.setter + def SpeedMax(self, val): + self.__SpeedMax = val + + @property + def SpeedMin(self): + return self.__SpeedMin + + @SpeedMin.setter + def SpeedMin(self, val): + self.__SpeedMin = val + + @property + def PowerMax(self): + return self.__PowerMax + + @PowerMax.setter + def PowerMax(self, val): + self.__PowerMax = val + + @property + def rotors(self): + return self.__rotors + + @property + def AirFlow(self): + return self.__AirFlow + + @AirFlow.setter + def AirFlow(self, val): + self.__AirFlow = val + + @rotors.setter + def rotors(self, val): + self.__rotors = val + + @property + def fan_display_name_conifg(self): + return self.__fan_display_name_conifg + + @fan_display_name_conifg.setter + def fan_display_name_conifg(self, val): + self.__fan_display_name_conifg = val + + @property + def fan_display_name(self): + return self.__fan_display_name + + @fan_display_name.setter + def fan_display_name(self, val): + self.__fan_display_name = val + + def getspeed(self, conf): + tmp = None + if conf is None: + return -1 + ret, val = self.get_value(conf) + if ret is True: + tmp = int(str(val), 10) + else: + val = None + if val is not None: + return int(15000000 / tmp) + return -1 + + def get_speed(self, rotor_index): + rotor_item = self.get_rotor_index(rotor_index) + if rotor_item is None: + return None + speed = rotor_item.rotor_Speed.Value + if speed is None: + return None + return int(speed) + + def set_led(self, color): + status = self.led_attrs_config.get(color, None) + if status is None: + return False + + mask = self.led_attrs_config.get('mask', 0xff) + ret, value = self.get_value(self.led_config) + if ret is False or value is None: + return False + setval = (int(value) & ~mask) | (status) + ret, val = self.set_value(self.led_config, setval) + return ret + + def get_led(self): + mask = self.led_attrs_config.get('mask', 0xff) + ret, value = self.get_value(self.led_config) + if ret is False or value is None: + return False, 'N/A' + ledval = int(value) & mask + for key, val in self.led_attrs_config.items(): + if (ledval == val) and (key != "mask"): + return True, key + return False, 'N/A' + + def set_speed(self, rotor_index, level): + if level > 255 or level < 0: + return False + rotor_item = self.get_rotor_index(rotor_index) + if rotor_item is None: + return False + ret, val = self.set_value(rotor_item.Speedconfig, int(level)) + return ret + + def get_rotor_index(self, rotor_index): + if rotor_index > len(self.rotor_list): + return None + rotor_item = self.rotor_list[rotor_index - 1] + return rotor_item + + def get_rotor_byname(self, rotor_index): + for rotor_item in self.rotor_list: + if rotor_item.name == rotor_index: + return rotor_item + return None + + def get_presence(self): + ret, val = self.get_value(self.present) + if ret is False or val is None: + return -1 + if isinstance(val, str): + value = int(val, 16) + else: + value = val + mask = self.present.get("mask") + flag = value & mask + okval = self.present.get("okval", 0) + if flag == okval: + return True + return False + + def get_speed_pwm(self, rotor_index): + rotor_item = self.get_rotor_index(rotor_index) + if rotor_item is None: + return False + if rotor_item.i2c_speed is None: + return False + val = round(rotor_item.i2c_speed * 100 / 255) + return val + + def feed_watchdog(self): + ret = False + for rotor_item in self.rotor_list: + ret, val = rotor_item.feed_watchdog() + if ret is False: + return ret + return ret + + def get_fru_info(self): + try: + if self.get_presence() is False: + raise Exception("%s: not present" % self.name) + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s: value is none" % self.name) + fru = ipmifru() + if isinstance(eeprom, bytes): + eeprom = self.byteTostr(eeprom) + fru.decodeBin(eeprom) + self.productName = fru.productInfoArea.productName.strip() # PN + self.productSerialNumber = fru.productInfoArea.productSerialNumber.strip() # SN + self.hw_version = fru.productInfoArea.productVersion.strip() # HW + except Exception: + self.productName = None + self.productSerialNumber = None + self.hw_version = None + return False + return True + + def get_tlv_info(self): + try: + if self.get_presence() is False: + raise Exception("%s: not present" % self.name) + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s: value is none" % self.name) + tlv = fan_tlv() + rets = tlv.decode(eeprom) + for item in rets: + if item["name"] == "Product Name": + self.productName = item["value"].replace("\x00", "").strip() + elif item["name"] == "serial Number": + self.productSerialNumber = item["value"].replace("\x00", "").strip() + elif item["name"] == "hardware info": + self.hw_version = item["value"].replace("\x00", "").strip() + except Exception: + self.productName = None + self.productSerialNumber = None + self.hw_version = None + return False + return True + + def decode_eeprom_info(self): + '''get fan name, hw version, sn''' + ret = self.get_tlv_info() + if ret is True: + return ret + return self.get_fru_info() + + def get_AirFlow(self): + if self.productName is None: + ret = self.decode_eeprom_info() + if ret is False: + self.AirFlow = None + return False + if self.AirFlowconifg is None: + self.AirFlow = None + return False + for i in self.AirFlowconifg: + if self.productName in self.AirFlowconifg[i]: + self.AirFlow = i + return True + self.AirFlow = None + return False + + def enable_watchdog(self, enable): + ret = False + if enable is True: + byte = self.EnableWatchdogConf.get("enable_byte", None) + ret, val = self.set_value(self.EnableWatchdogConf, byte) + elif enable is False: + byte = self.EnableWatchdogConf.get("disable_byte", None) + ret, val = self.set_value(self.EnableWatchdogConf, byte) + return ret + + def get_watchdog_status(self): + dic = {"support": None, "open": None, "work_full": None, "work_allow_set": None} + if self.WatchdogStatus_config is None: + return None + ret, val = self.get_value(self.WatchdogStatus_config) + if ret is False or val is None: + return None + support_watchdog_off = self.WatchdogStatus_config.get("support_watchdog_off", None) + is_open_off = self.WatchdogStatus_config.get("is_open_off", None) + full_running_off = self.WatchdogStatus_config.get("full_running_off", None) + running_setting_off = self.WatchdogStatus_config.get("running_setting_off", None) + if support_watchdog_off is not None: + if support_watchdog_off & val == self.WatchdogStatus_config.get("support_watchdog_mask", None): + dic["support"] = True + else: + dic["support"] = False + return dic + if is_open_off is not None: + if is_open_off & val == self.WatchdogStatus_config.get("is_open_mask", None): + dic["open"] = True + else: + dic["open"] = False + if full_running_off is not None: + if full_running_off & val == self.WatchdogStatus_config.get("full_running_mask", None): + dic["work_full"] = True + else: + dic["work_full"] = False + if running_setting_off is not None: + if running_setting_off & val == self.WatchdogStatus_config.get("running_setting_mask", None): + dic["work_allow_set"] = True + else: + dic["work_allow_set"] = False + return dic + + def get_fan_display_name(self): + if self.productName is None: + ret = self.get_fru_info() + if ret is False: + self.fan_display_name = None + return False + if self.fan_display_name_conifg is None: + self.fan_display_name = self.productName + return False + for i in self.fan_display_name_conifg: + if self.productName in self.fan_display_name_conifg[i]: + self.fan_display_name = i + return True + self.fan_display_name = self.productName + return False diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/interface.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/interface.py new file mode 100644 index 000000000000..161149eed33d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/interface.py @@ -0,0 +1,1311 @@ +#!/usr/bin/env python3 +####################################################### +# +# interface.py +# Python implementation of the Class interface +# +####################################################### +import collections +from plat_hal.chassisbase import chassisbase +from plat_hal.baseutil import baseutil +from plat_hal.osutil import osutil + + +def Singleton(cls): + _instance = {} + + def _singleton(*args, **kargs): + if cls not in _instance: + _instance[cls] = cls(*args, **kargs) + return _instance[cls] + + return _singleton + + +@Singleton +class interface(object): + __chas = None + __error_ret = None + + def __init__(self): + self.chas = chassisbase() + self.__error_ret = -99999 + self.__na_ret = 'N/A' + + @property + def na_ret(self): + return self.__na_ret + + @na_ret.setter + def na_ret(self, val): + self.__na_ret = val + + @property + def error_ret(self): + return self.__error_ret + + @error_ret.setter + def error_ret(self, val): + self.__error_ret = val + + @property + def chas(self): + return self.__chas + + @chas.setter + def chas(self, val): + self.__chas = val + + # onie_e2 + def get_onie_e2(self): + onie_e2_list = self.chas.onie_e2_list + return onie_e2_list + + def get_onie_e2_path(self, name): + onie_e2 = self.chas.get_onie_e2_byname(name) + if onie_e2 is None: + return None + return onie_e2.e2_path + + def get_device_airflow(self, name): + onie_e2 = self.chas.get_onie_e2_byname(name) + if onie_e2 is None: + return None + return onie_e2.airflow + + def get_onie_e2_obj(self, name): + onie_e2 = self.chas.get_onie_e2_byname(name) + if onie_e2 is None: + return None + onie_e2.get_onie_e2_info() + return onie_e2 + + # temp + def get_temps(self): + templist = self.chas.temp_list + return templist + + def get_temp_total_number(self): + templist = self.chas.temp_list + return len(templist) + + def check_temp_id_exist(self, temp_id): + templist = self.chas.temp_list + for temp in templist: + if temp.temp_id == temp_id: + return True + return False + + def get_temp_id_number(self): + templist = self.chas.temp_list + temp_num = 0 + for i in range(len(templist)): + temp_id = "TEMP" + str(i + 1) + ret = self.check_temp_id_exist(temp_id) + if ret is True: + temp_num = temp_num + 1 + else: + return temp_num + return temp_num + + def get_temp_location(self, temp_name): + temp = self.chas.get_temp_byname(temp_name) + return temp.get_location() + + def set_temp_location(self, temp_name, location): + temp = self.chas.get_temp_byname(temp_name) + return temp.set_location(location) + + def set_temp_name(self, temp_name, name): + temp = self.chas.get_temp_byname(temp_name) + return temp.set_name(name) + + def get_appoint_temp(self, temp_name): + temp = self.chas.get_led_byname(temp_name) + return temp.get_temp() + + def set_appoint_temp(self, temp_name, val): + temp = self.chas.get_temp_byname(temp_name) + return temp.set_temp(val) + + def get_temp_mintemp(self, temp_name): + temp = self.chas.get_temp_byname(temp_name) + return temp.get_mintemp() + + def set_temp_mintemp(self, temp_name, val): + temp = self.chas.get_temp_byname(temp_name) + return temp.set_mintemp(val) + + # led + def get_leds(self): + ledlist = self.chas.led_list + return ledlist + + def get_led_total_number(self): + ledlist = self.chas.led_list + return len(ledlist) + + def get_led_color(self, led_name): + led = self.chas.get_led_byname(led_name) + if led is None: + return -1 + return led.get_color() + + def get_led_color_by_type(self, led_type): + ledlist = self.chas.led_list + ledtmp = None + for temp in ledlist: + if temp.led_type == led_type: + ledtmp = temp + break + if ledtmp is None: + return -1 + return ledtmp.get_color() + + def set_led_color(self, led_name, color): + led = self.chas.get_led_byname(led_name) + if led is None: + return -1 + return led.set_color(color) + + # psu + def get_psu_total_number(self): + psulist = self.chas.psu_list + if psulist is None: + return -1 + return len(psulist) + + def get_psus(self): + psulist = self.chas.psu_list + return psulist + + def get_psu_presence(self, psu_name): + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + return psu.present + + def get_psu_fru_info(self, psu_name): + ''' + { + "Name": "PSU1", + "SN": "serial_number_example", # 'N/A' + "PN": "part_number_example", # 'N/A' + "AirFlow": "B2F" # 'N/A' + } + ''' + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + psu.get_fru_info() + psu.get_AirFlow() + psu.get_psu_display_name() + + dic = collections.OrderedDict() + dic["Name"] = psu.name + dic["SN"] = psu.productSerialNumber if (psu.productSerialNumber is not None) else self.na_ret + dic["PN"] = psu.productPartModelName if (psu.productPartModelName is not None) else self.na_ret + dic["DisplayName"] = psu.psu_display_name if (psu.psu_display_name is not None) else self.na_ret + dic["VENDOR"] = psu.productManufacturer if (psu.productManufacturer is not None) else self.na_ret + dic["HW"] = psu.productVersion if (psu.productVersion is not None) else self.na_ret + dic["AirFlow"] = psu.AirFlow if (psu.AirFlow is not None) else self.na_ret + return dic + + def get_psu_input_output_status(self, psu_name): + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + psu.InputsCurrent.Value # just for clear faults + if (psu.InputStatus is True) and (psu.OutputStatus is True): + return True + return False + + def get_psu_status(self, psu_name): + """ + Get status of a specific PSU + @return dict of the specific PSU's status, None for failure + Example return value(all keys are mandatory) + { + "Name": "PSU1", + "InputType": "DC", # "AC" or 'N/A' + "InputStatus": True, # H/W status bit + "OutputStatus": True # H/W status bit + "FanSpeed": { + "Value": 4000, # -99999 + "Min": 2000, # -99999 + "Max": 10000 # -99999 + }, + "Temperature": { + "Value": 40.0, # -99999.0 + "Min": -30.0, # -99999.0 + "Max": 50.0 # -99999.0 + } + } + """ + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + + dic = collections.OrderedDict() + # psu.get_Temperature() + temp_dict = collections.OrderedDict() + temp_dict['Min'] = psu.Temperature.Min + temp_dict['Max'] = psu.Temperature.Max + temp_dict['Value'] = psu.Temperature.Value + temp_dict['Unit'] = psu.Temperature.Unit + dic["Temperature"] = temp_dict + + # psu.get_FanSpeed() + fan_speed_dict = collections.OrderedDict() + fan_speed_dict['Min'] = psu.FanSpeed.Min + fan_speed_dict['Max'] = psu.FanSpeed.Max + fan_speed_dict['Tolerance'] = psu.FanSpeedTolerance + fan_speed_dict['Value'] = psu.FanSpeed.Value + fan_speed_dict['Unit'] = psu.FanSpeed.Unit + dic["FanSpeed"] = fan_speed_dict + + dic["Name"] = psu.name + dic["InputType"] = psu.InputsType + dic["InputStatus"] = psu.InputStatus + dic["OutputStatus"] = psu.OutputStatus + dic["TempStatus"] = psu.TempStatus + dic["FanStatus"] = psu.FanStatus + return dic + + def get_psu_power_status(self, psu_name): + """ + Get power status of a specific PSU + @return dict of the specific PSU's power status, None for failure + Example return value + { + "Name": "PSU1", + "Inputs": { + "Status": True, # H/W status bit + "Type": "DC", # or "AC" or "N/A" + "Voltage": { + "Value": 220, # -1 + "LowAlarm": 200, # -1 + "HighAlarm": 240, # -1 + "Unit": "V" + }, + "Current": { + "Value": 6.0, # -99999.0 + "LowAlarm": 0.2, # -99999.0 + "HighAlarm": 7.0, # -99999.0 + "Unit": "A" + }, + "Power": { + "Value": 1000, # -99999 + "LowAlarm": -1, # -99999 + "HighAlarm": 1400, # -99999 + "Unit": "W" + } + }, + "Outputs": { + "Status": True, + "Voltage": { + "Value": 220, + "LowAlarm": 200, + "HighAlarm": 240, + "Unit": "V" + }, + "Current": { + "Value": 6.0, + "LowAlarm": 0.2, + "HighAlarm": 7.0, + "Unit": "A" + }, + "Power": { + "Value": 1000, + "LowAlarm": -1, # Don't care + "HighAlarm": 1400, + "Unit": "W" + } + } + } + """ + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + + dic = collections.OrderedDict() + inputdic = collections.OrderedDict() + Outputsdic = collections.OrderedDict() + dic["Name"] = psu.name + inputdic["Status"] = psu.InputStatus + inputdic["Type"] = psu.InputsType + + # psu.get_InputsVoltage() + inputdic_voltage = collections.OrderedDict() + + inputdic_voltage["Value"] = psu.InputsVoltage.Value + inputdic_voltage["LowAlarm"] = psu.InputsVoltage.Min + inputdic_voltage["HighAlarm"] = psu.InputsVoltage.Max + inputdic_voltage["Unit"] = psu.InputsVoltage.Unit + + inputdic["Voltage"] = inputdic_voltage + inputdic_current = collections.OrderedDict() + inputdic_current["Value"] = psu.InputsCurrent.Value + inputdic_current["LowAlarm"] = psu.InputsCurrent.Min + inputdic_current["HighAlarm"] = psu.InputsCurrent.Max + inputdic_current["Unit"] = psu.InputsCurrent.Unit + inputdic["Current"] = inputdic_current + + inputdic_power = collections.OrderedDict() + inputdic_power["Value"] = psu.InputsPower.Value + inputdic_power["LowAlarm"] = psu.InputsPower.Min + inputdic_power["HighAlarm"] = psu.InputsPower.Max + inputdic_power["Unit"] = psu.InputsPower.Unit + inputdic["Power"] = inputdic_power + Outputsdic["Status"] = psu.InputStatus + + outputdic_voltage = collections.OrderedDict() + outputdic_current = collections.OrderedDict() + outputdic_power = collections.OrderedDict() + + outputdic_voltage["Value"] = psu.OutputsVoltage.Value + outputdic_voltage["LowAlarm"] = psu.OutputsVoltage.Min + outputdic_voltage["HighAlarm"] = psu.OutputsVoltage.Max + outputdic_voltage["Unit"] = psu.OutputsVoltage.Unit + + outputdic_current["Value"] = psu.OutputsCurrent.Value + outputdic_current["LowAlarm"] = psu.OutputsCurrent.Min + outputdic_current["HighAlarm"] = psu.OutputsCurrent.Max + outputdic_current["Unit"] = psu.OutputsCurrent.Unit + + outputdic_power["Value"] = psu.OutputsPower.Value + outputdic_power["LowAlarm"] = psu.OutputsPower.Min + outputdic_power["HighAlarm"] = psu.OutputsPower.Max + outputdic_power["Unit"] = psu.OutputsPower.Unit + + Outputsdic["Voltage"] = outputdic_voltage + Outputsdic["Current"] = outputdic_current + Outputsdic["Power"] = outputdic_power + + dic["Inputs"] = inputdic + dic["Outputs"] = Outputsdic + + return dic + + def set_psu_fan_speed_pwm(self, psu_name, pwm): + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + return psu.set_fan_speed_pwm(pwm) + + def get_psu_fan_speed_pwm(self, psu_name): + psu = self.chas.get_psu_byname(psu_name) + if psu is None: + return -1 + return psu.get_fan_speed_pwm() + + def get_psu_info_all(self): + """ + { + "Number": 2, + "PSU1": { + "SN": "serial_number_example", # 'N/A' + "PN": "part_number_example", # 'N/A' + "AirFlow": "intake", # 'N/A' + + "FanSpeed": { + "Value": 4000, + "Min": 2000, + "Max": 30000 + }, + "Temperature": { + "Value": 35.0, + "Min": -20.0, + "Max": 45.0 + }, + "Inputs": { + "Status": True, # H/W status bit + "Type": "DC", # or "AC" + "Voltage": { + "Value": 220, + "LowAlarm": 200, + "HighAlarm": 240, + "Unit": "V" + }, + "Current": { + "Value": 6.0, + "LowAlarm": 0.2, + "HighAlarm": 7.0, + "Unit": "A" + }, + "Power": { + "Value": 1000, + "LowAlarm": -1, + "HighAlarm": 1400, + "Unit": "W" + } + }, + "Outputs": { + "Status": True, + "Voltage": { + "Value": 220, + "LowAlarm": 200, + "HighAlarm": 240, + "Unit": "V" + }, + "Current": { + "Value": 6.0, + "LowAlarm": 0.2, + "HighAlarm": 7.0, + "Unit": "A" + }, + "Power": { + "Value": 1000, + "LowAlarm": -1, # Don't care + "HighAlarm": 1400, + "Unit": "W" + } + } + } + } + """ + + psus = self.get_psus() + psu_dict = collections.OrderedDict() + psu_dict['Number'] = len(psus) + for psu in psus: + dicttmp = self.get_psu_fru_info(psu.name) + dicttmp.update(self.get_psu_status(psu.name)) + dicttmp.update(self.get_psu_power_status(psu.name)) + if self.get_psu_presence(psu.name) is True: + dicttmp['Present'] = 'yes' + else: + dicttmp['Present'] = 'no' + psu_dict[psu.name] = dicttmp + return psu_dict + + def get_fans(self): + fanlist = self.chas.fan_list + return fanlist + + # fan + def get_fan_total_number(self): + fanlist = self.chas.fan_list + if fanlist is None: + return -1 + return len(fanlist) + + def get_fan_rotor_number(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + ret = fan.rotors + if ret is None: + return -1 + return ret + + def get_fan_speed(self, fan_name, rotor_index): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + ret = fan.get_speed(rotor_index) + if ret is None: + return -1 + return ret + + def fan_speed_set_level(self, fan_name, rotor_index, level): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + ret = fan.set_speed(rotor_index, level) + if ret is True: + return 0 + return -1 + + def get_fan_speed_pwm(self, fan_name, rotor_index): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + val = fan.get_speed_pwm(rotor_index) + if val is False: + return -1 + return val + + def set_fan_speed_pwm(self, fan_name, rotor_index, pwm): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + if isinstance(pwm, str): + rate = float(pwm.strip('%s')) + speed = round(rate * 255 / 100) + elif isinstance(pwm, int): + speed = round(pwm * 255 / 100) + elif isinstance(pwm, float): + speed = round(pwm * 255 / 100) + else: + return -1 + ret = self.fan_speed_set_level(fan.name, rotor_index, speed) + if ret == 0: + return 0 + return -1 + + def get_fan_watchdog_status(self): + fan = self.chas.fan_list[0] + dic = fan.get_watchdog_status() + if dic is None or dic["support"] is False: + return self.na_ret + if dic["open"] is False or dic["work_allow_set"] is True: + return "Normal" + if dic["work_full"] is True: + return "Abnormal" + return "Abnormal" + + def enable_fan_watchdog(self, enable=True): + fan = self.chas.fan_list[0] + ret = fan.enable_watchdog(enable) + if ret is True: + return 0 + return -1 + + def feed_fan_watchdog(self): + fan_list = self.chas.fan_list + if fan_list is None: + return -1 + for fan in fan_list: + ret = fan.feed_watchdog() + if ret is False: + return -1 + return 0 + + def set_fan_led(self, fan_name, color): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + ret = fan.set_led(color) + if ret is True: + return 0 + return -1 + + def get_fan_led(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return False, 'N/A' + return fan.get_led() + + def get_fan_presence(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + return fan.get_presence() + + def get_fan_fru_info(self, fan_name): + """ + Get specific fan's information + # Properties + "Name": "FAN1", + "SN": "serial_number_example", # 'N/A' + "PN": "part_number_exampple", # 'N/A' + "Rotors": 2, # -1 + "AirFlow": "intake", # 'N/A' + "SpeedMin": 2000, # -1 + "SpeedMax": 30000 # -1 + """ + fan = self.chas.get_fan_byname(fan_name) + fan.get_fru_info() + fan.get_AirFlow() + fan.get_fan_display_name() + + dic = collections.OrderedDict() + dic["Name"] = fan.name + dic["SN"] = fan.productSerialNumber + if dic["SN"] is None: + dic["SN"] = self.na_ret + dic["PN"] = fan.productName + if dic["PN"] is None: + dic["PN"] = self.na_ret + dic["DisplayName"] = fan.fan_display_name + if dic["DisplayName"] is None: + dic["DisplayName"] = self.na_ret + + dic["Rotors"] = fan.rotors + dic["AirFlow"] = fan.AirFlow + if dic["AirFlow"] is None: + dic["AirFlow"] = self.na_ret + dic["SpeedMin"] = fan.SpeedMin + dic["SpeedMax"] = fan.SpeedMax + return dic + + def get_fan_eeprom_info(self, fan_name): + """ + Get specific fan's information + # Properties + "Name": "M6510-FAN-F", # 'N/A' + "SN": "serial_number_example", # 'N/A' + "HW": "hw_version_exampple", # 'N/A' + """ + fan = self.chas.get_fan_byname(fan_name) + fan.decode_eeprom_info() + dic = collections.OrderedDict() + dic["NAME"] = fan.productName + if dic["NAME"] is None: + dic["NAME"] = self.na_ret + dic["SN"] = fan.productSerialNumber + if dic["SN"] is None: + dic["SN"] = self.na_ret + dic["HW"] = fan.hw_version + if dic["HW"] is None: + dic["HW"] = self.na_ret + + return dic + + def get_product_fullname(self): + return baseutil.get_product_fullname() + + def get_fan_status(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + rotorlist = fan.rotor_list + dic = collections.OrderedDict() + for rotor in rotorlist: + dic_val = collections.OrderedDict() + if rotor.rotor_Running is True: + dic_val['Running'] = 'yes' + else: + dic_val['Running'] = 'no' + if rotor.rotor_HwAlarm is True: + dic_val['HwAlarm'] = 'yes' + else: + dic_val['HwAlarm'] = 'no' + dic_val['Speed'] = int(rotor.rotor_Speed.Value) + dic[rotor.name] = dic_val + return dic + + def get_fan_rotor_status(self, fan_name, rotor_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + rotorlist = fan.rotor_list + for rotor in rotorlist: + if rotor_name == rotor.name: + if rotor.rotor_Running is True: + return True + return False + return -1 + + def get_fan_roll_status(self, fan_name, rotor_index): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + rotor = fan.get_rotor_index(rotor_index) + if rotor is None: + return -1 + if rotor.rotor_Running is True: + return True + return False + + def get_fan_info_fru(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + fan.get_fru_info() + fan.get_AirFlow() + dic = collections.OrderedDict() + dic["Name"] = fan.name + dic["SN"] = fan.productSerialNumber + if dic["SN"] is None: + dic["SN"] = self.na_ret + dic["PN"] = fan.productPartModelName + if dic["PN"] is None: + dic["PN"] = self.na_ret + flag = self.get_fan_presence(fan_name) + if flag is True: + dic["Present"] = "yes" + elif flag is False: + dic["Present"] = "no" + else: + dic["Present"] = self.na_ret + dic["Rotors"] = fan.rotors + dic["AirFlow"] = fan.AirFlow + if dic["AirFlow"] is None: + dic["AirFlow"] = self.na_ret + return dic + + # support TLV and FRU FAN E2 + def get_fan_info(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return None + fan.get_AirFlow() + dic = self.get_fan_eeprom_info(fan_name) + flag = self.get_fan_presence(fan_name) + if flag is True: + dic["Present"] = "yes" + elif flag is False: + dic["Present"] = "no" + else: + dic["Present"] = self.na_ret + dic["Rotors"] = fan.rotors + dic["AirFlow"] = fan.AirFlow + if dic["AirFlow"] is None: + dic["AirFlow"] = self.na_ret + dic["PowerMax"] = fan.PowerMax + if dic["PowerMax"] is None: + dic["PowerMax"] = self.na_ret + return dic + + def get_fan_info_rotor(self, fan_name): + fan = self.chas.get_fan_byname(fan_name) + if fan is None: + return -1 + rotorlist = fan.rotor_list + dic = collections.OrderedDict() + for rotor in rotorlist: + dic_val = collections.OrderedDict() + if rotor.rotor_Running is True: + dic_val['Running'] = 'yes' + else: + dic_val['Running'] = 'no' + if rotor.rotor_HwAlarm is True: + dic_val['HwAlarm'] = 'yes' + else: + dic_val['HwAlarm'] = 'no' + speed_value = rotor.rotor_Speed.Value + if speed_value is None: + dic_val['Speed'] = self.error_ret + else: + dic_val['Speed'] = int(speed_value) + if rotor.SpeedMin is None: + dic_val['SpeedMin'] = self.error_ret + else: + dic_val['SpeedMin'] = rotor.SpeedMin + if rotor.SpeedMax is None: + dic_val['SpeedMax'] = self.error_ret + else: + dic_val['SpeedMax'] = rotor.SpeedMax + if rotor.Tolerance is None: + dic_val['Tolerance'] = self.error_ret + else: + dic_val['Tolerance'] = rotor.Tolerance + + dic[rotor.name] = dic_val + return dic + + def get_fan_info_all(self): + fanlist = self.chas.fan_list + dic = collections.OrderedDict() + dic['Number'] = len(fanlist) + dic['WatchdogStatus'] = self.get_fan_watchdog_status() + for fan in fanlist: + dic[fan.name] = self.get_fan_info(fan.name) + dic[fan.name].update(self.get_fan_info_rotor(fan.name)) + return dic + + def temp_test(self): + templist = self.chas.temp_list + dicret = collections.OrderedDict() + + for temp in templist: + dic = collections.OrderedDict() + temp_value = temp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["LowAlarm"] = temp.Min + dic["HighAlarm"] = temp.Max + dicret[temp.name] = dic + return dicret + + # dcdc + def get_dcdc_total_number(self): + dcdclist = self.chas.dcdc_list + if dcdclist is None: + return -1 + return len(dcdclist) + + def get_dcdc_by_id(self, dcdc_id): + dcdclist = self.chas.dcdc_list + dcdctmp = None + for dcdc in dcdclist: + if dcdc.dcdc_id == dcdc_id: + dcdctmp = dcdc + dic = collections.OrderedDict() + if dcdctmp is None: + dic["Name"] = self.error_ret + dic["Min"] = self.error_ret + dic["Max"] = self.error_ret + dic["Low"] = self.error_ret + dic["High"] = self.error_ret + dic["Value"] = self.error_ret + dic["Unit"] = self.error_ret + else: + dic["Name"] = dcdctmp.name + dic["Min"] = dcdctmp.sensor.Min + dic["Max"] = dcdctmp.sensor.Max + dic["Low"] = dcdctmp.sensor.Low + dic["High"] = dcdctmp.sensor.High + tmp = dcdctmp.sensor.Value + if tmp is not None: + dic['Value'] = tmp + else: + dic['Value'] = self.error_ret + dic["Unit"] = dcdctmp.sensor.Unit + return dic + + def get_dcdc_all_info(self): + val_list = collections.OrderedDict() + dcdclist = self.chas.dcdc_list + for dcdc in dcdclist: + dicttmp = {} + sensorname = "%s" % (dcdc.name) + dicttmp['Min'] = dcdc.sensor.Min + dicttmp['Max'] = dcdc.sensor.Max + tmp = dcdc.sensor.Value + if tmp is not None: + dicttmp['Value'] = tmp + else: + dicttmp['Value'] = self.error_ret + dicttmp['Unit'] = dcdc.sensor.Unit + val_list[sensorname] = dicttmp + return val_list + + # sensors + def get_monitor_temp(self, name): + templist = self.chas.temp_list + temptmp = None + for temp in templist: + if temp.name == name: + temptmp = temp + + dic = collections.OrderedDict() + if temptmp is None: + dic["Min"] = self.error_ret + dic["Max"] = self.error_ret + dic["Value"] = self.error_ret + dic["Unit"] = self.error_ret + else: + dic["Min"] = temptmp.Min + dic["Max"] = temptmp.Max + temp_value = temptmp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temptmp.Unit + return dic + + def get_monitor_temp_by_id(self, temp_id): + templist = self.chas.temp_list + temptmp = None + for temp in templist: + if temp.temp_id == temp_id: + temptmp = temp + + dic = collections.OrderedDict() + if temptmp is None: + dic["Name"] = self.error_ret + dic["Api_name"] = self.error_ret + dic["Min"] = self.error_ret + dic["Max"] = self.error_ret + dic["Low"] = self.error_ret + dic["High"] = self.error_ret + dic["Value"] = self.error_ret + dic["Unit"] = self.error_ret + else: + dic["Name"] = temptmp.name + dic["Api_name"] = temptmp.api_name + dic["Min"] = temptmp.Min + dic["Max"] = temptmp.Max + dic["Low"] = temptmp.Low + dic["High"] = temptmp.High + temp_value = temptmp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temptmp.Unit + return dic + + def get_temp_info(self): + val_list = collections.OrderedDict() + # temp + templist = self.chas.temp_list + for temp in templist: + dic = collections.OrderedDict() + dic["Min"] = temp.Min + dic["Max"] = temp.Max + dic["Low"] = temp.Low + dic["High"] = temp.High + temp_value = temp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temp.Unit + val_list[temp.name] = dic + return val_list + + def get_sensor_info(self): + val_list = collections.OrderedDict() + # temp + templist = self.chas.temp_list + for temp in templist: + dic = collections.OrderedDict() + dic["Min"] = temp.Min + dic["Max"] = temp.Max + dic["Low"] = temp.Low + dic["High"] = temp.High + temp_value = temp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temp.Unit + val_list[temp.name] = dic + # fan + fanlist = self.chas.fan_list + for fan in fanlist: + for rotor in fan.rotor_list: + sensorname = "%s%s" % (fan.name, rotor.name) + speed = collections.OrderedDict() + speed['Min'] = rotor.rotor_Speed.Min + speed['Max'] = rotor.rotor_Speed.Max + rotor_speed_Value = rotor.rotor_Speed.Value + speed['Value'] = rotor_speed_Value if (rotor_speed_Value is not None) else self.error_ret + speed['Unit'] = rotor.rotor_Speed.Unit + val_list[sensorname] = speed + + val_list.update(self.get_dcdc_all_info()) + + # psu + psulist = self.chas.psu_list + for psu in psulist: + inputdic_voltage = collections.OrderedDict() + inputdic_current = collections.OrderedDict() + inputdic_power = collections.OrderedDict() + outputdic_voltage = collections.OrderedDict() + outputdic_current = collections.OrderedDict() + outputdic_power = collections.OrderedDict() + temperature = collections.OrderedDict() + fanspeed = collections.OrderedDict() + + psu_temp_value = psu.Temperature.Value + temperature["Value"] = psu_temp_value if (psu_temp_value is not None) else self.error_ret + temperature["Min"] = psu.Temperature.Min + temperature["Max"] = psu.Temperature.Max + temperature["Unit"] = psu.Temperature.Unit + + fanspeed["Value"] = psu.FanSpeed.Value + fanspeed["Min"] = psu.FanSpeed.Min + fanspeed["Max"] = psu.FanSpeed.Max + fanspeed["Unit"] = psu.FanSpeed.Unit + + psu_inputvoltage_value = psu.InputsVoltage.Value + inputdic_voltage["Value"] = psu_inputvoltage_value if ( + psu_inputvoltage_value is not None) else self.error_ret + inputdic_voltage["Min"] = psu.InputsVoltage.Min + inputdic_voltage["Max"] = psu.InputsVoltage.Max + inputdic_voltage["Unit"] = psu.InputsVoltage.Unit + + psu_inputcurrent_value = psu.InputsCurrent.Value + inputdic_current["Value"] = psu_inputcurrent_value if ( + psu_inputcurrent_value is not None) else self.error_ret + inputdic_current["Min"] = psu.InputsCurrent.Min + inputdic_current["Max"] = psu.InputsCurrent.Max + inputdic_current["Unit"] = psu.InputsCurrent.Unit + + psu_inputpower_value = psu.InputsPower.Value + inputdic_power["Value"] = psu_inputpower_value if (psu_inputpower_value is not None) else self.error_ret + inputdic_power["Min"] = psu.InputsPower.Min + inputdic_power["Max"] = psu.InputsPower.Max + inputdic_power["Unit"] = psu.InputsPower.Unit + + psu_outputvoltage_value = psu.OutputsVoltage.Value + outputdic_voltage["Value"] = psu_outputvoltage_value if ( + psu_outputvoltage_value is not None) else self.error_ret + outputdic_voltage["Min"] = psu.OutputsVoltage.Min + outputdic_voltage["Max"] = psu.OutputsVoltage.Max + outputdic_voltage["Unit"] = psu.OutputsVoltage.Unit + + psu_outputcurrent_value = psu.OutputsCurrent.Value + outputdic_current["Value"] = psu_outputcurrent_value if ( + psu_outputcurrent_value is not None) else self.error_ret + outputdic_current["Min"] = psu.OutputsCurrent.Min + outputdic_current["Max"] = psu.OutputsCurrent.Max + outputdic_current["Unit"] = psu.OutputsCurrent.Unit + + psu_outputpower_value = psu.OutputsPower.Value + outputdic_power["Value"] = psu_outputpower_value if ( + psu_outputpower_value is not None) else self.error_ret + outputdic_power["Min"] = psu.OutputsPower.Min + outputdic_power["Max"] = psu.OutputsPower.Max + outputdic_power["Unit"] = psu.OutputsPower.Unit + + val_list["%s%s" % (psu.name, "Vol_I")] = inputdic_voltage + val_list["%s%s" % (psu.name, "Curr_I")] = inputdic_current + val_list["%s%s" % (psu.name, "Power_I")] = inputdic_power + val_list["%s%s" % (psu.name, "Vol_O")] = outputdic_voltage + val_list["%s%s" % (psu.name, "Curr_O")] = outputdic_current + val_list["%s%s" % (psu.name, "Power_O")] = outputdic_power + val_list["%s%s" % (psu.name, "Fan")] = fanspeed + val_list["%s%s" % (psu.name, "Temp")] = temperature + + return val_list + + # cpld + def get_cpld_total_number(self): + cpldlist = self.chas.cpld_list + return len(cpldlist) + + def get_cpld_user_reg(self): + cpld = self.chas.get_cpld_byname("BASE_CPLD") + if cpld is None: + return None + return cpld.get_user_reg() + + def set_cpld_user_reg(self, value): + if isinstance(value, int) is False: + baseutil.logger_debug("value must int %s" % type(value)) + return -1 + if (int(value) < 0 or int(value) > 255): + baseutil.logger_debug("value must [0 - 255]") + return -1 + cpld = self.chas.get_cpld_byname("BASE_CPLD") + if cpld is None: + baseutil.logger_debug("name BASE_CPLD not find") + return -1 + if cpld.set_user_reg(value) is True: + return 0 + return -1 + + def set_cpld_console_owner(self, owner): + """ + Set console I/O owner + + @param owner I/O owner of the console, either "cpu" or "bmc" + + @return 0 for success, -1 for failure + """ + if owner is None: + baseutil.logger_debug("owner is None") + return -1 + owner_tuple = ("cpu", "bmc") + if owner not in owner_tuple: + baseutil.logger_debug("owner is %s, must cpu or bmc" % owner) + return -1 + cpld = self.chas.get_cpld_byname("BASE_CPLD") + if cpld is None: + baseutil.logger_debug("name BASE_CPLD not find") + return -1 + if cpld.set_console_owner(owner) is True: + return 0 + return -1 + + def get_cpld_version_by_id(self, cpld_id): + cpldlist = self.chas.cpld_list + cpldtmp = None + for cpld in cpldlist: + if cpld.cpld_id == cpld_id: + cpldtmp = cpld + + dic = collections.OrderedDict() + if cpldtmp is None: + dic["Name"] = self.na_ret + dic["Version"] = self.na_ret + dic["Desc"] = self.na_ret + dic["Slot"] = None + dic["Warm"] = None + else: + dic["Name"] = cpldtmp.name + dic["Version"] = cpldtmp.get_version() + dic["Desc"] = cpldtmp.desc + dic["Slot"] = cpldtmp.slot + dic["Warm"] = cpldtmp.warm + return dic + + def get_cpld_all_version(self): + """ + Get version of all CPLDs' that can be read from BMC + + @return dict of CPLDs' version or None for failure. + example outputs: + { + "BASE_CPLD": "0.1", # or "N/A" for read failure + "FAN_CPLD": "0.2" + } + """ + cpld_version = { + "BASE_CPLD": "N/A", + "FAN_CPLD": "N/A" + } + for cpld_name in cpld_version: + cpld = self.chas.get_cpld_byname(cpld_name) + if cpld is None: + baseutil.logger_debug("name %s not find" % cpld_name) + continue + cpld_version[cpld_name] = cpld.get_version() + return cpld_version + + # comp + def get_comp_total_number(self): + complist = self.chas.comp_list + return len(complist) + + def get_comp_list(self): + return self.chas.comp_list + + def get_comp_id(self, comp): + return comp.comp_id + + def get_comp_version_by_id(self, comp_id): + comp_list = self.chas.comp_list + comptmp = None + for comp in comp_list: + if comp.comp_id == comp_id: + comptmp = comp + break + + dic = collections.OrderedDict() + if comptmp is None: + dic["Name"] = self.na_ret + dic["Version"] = self.na_ret + dic["Desc"] = self.na_ret + dic["Slot"] = None + else: + dic["Name"] = comptmp.name + dic["Version"] = comptmp.get_version() + dic["Desc"] = comptmp.desc + dic["Slot"] = comptmp.slot + return dic + + def get_bmc_productname(self): + """ + Get product name + + @return product name string, e.g. $(device name)-F-$(VENDOR_NAME), if error return "N/A" + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name bmc(master) not find") + return self.na_ret + return bmc.get_productname() + + def call_bmc_diagcmd(self, cmdstr): + """ + Call BMC diag comman func + + @return ret: 0 sucess , -1 fail + outmsg: if success is out msg, or fail is err msg + """ + if (cmdstr is None or cmdstr == ""): + outmsg = "cmdstr is empty" + baseutil.logger_debug(outmsg) + return -1, outmsg + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + outmsg = "name bmc(master) not find" + baseutil.logger_debug(outmsg) + return -1, outmsg + baseutil.logger_debug("call cmdstr %s" % cmdstr) + return bmc.call_diagcmd(cmdstr) + + def write_bios_version(self, flash, version): + bios = self.chas.get_bios_byname("master") + if bios is None: + baseutil.logger_debug("name bios(master) not find") + return -1 + return bios.set_bios_version(flash, version) + + def get_bios_version(self): + bios = self.chas.get_bios_byname("master") + if bios is None: + baseutil.logger_debug("name bios(master) not find") + return -1 + return bios.get_bios_version() + + def get_bios_status(self): + bios = self.chas.get_bios_byname("master") + if bios is None: + baseutil.logger_debug("name bios(master) not find") + return -1 + return bios.get_bios_boot_status() + + def get_bmc_mac_rov(self): + """ + Get BMC mac rov + + @return ret: 0 sucess , -1 fail + outmsg: if success is out msg, or fail is err msg + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + msg = "name master not find" + baseutil.logger_debug(msg) + return -1, msg + return bmc.get_mac_rov() + + def get_bmc_next_boot(self): + """ + Get next booting flash of BMC + + @return 'master'/'slave' on success, "N/A" for failure + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return self.na_ret + return bmc.get_next_boot() + + def set_bmc_next_boot(self, flash): + """ + Set flash from which next BMC boot + + @param flash Booting flash of BMC, "master" or "slave" + + @return 0 on success, -1 for failure + """ + flash_status = ("master", "slave") + if flash is None or flash not in flash_status: + baseutil.logger_debug("parameter flash illegal, should be [master|slave]") + return -1 + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return -1 + return bmc.set_next_boot(flash) + + def reboot_bmc(self): + """ + Reboot running BMC + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return -1 + return bmc.reboot() + + def get_bmc_info(self): + """ + Get BMC info + + @return dict of BMC info or None for failure + "Version": "1.1.1", # "N/A" + "Flash": "master", # "N/A" + "Next": "master" # "N/A" + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return self.na_ret + return bmc.get_info() + + def get_bmc_version_all(self): + """ + @return dict of BMCs + { + "MasterVersion": "1.1.1", # "N/A" + "SlaveVersion": "1.1.1" # "N/A" + } + """ + bmc = self.chas.get_bmc_byname("master") + if bmc is None: + baseutil.logger_debug("name master not find") + return self.na_ret + return bmc.get_version_all() + + def bmc_execute_command(self, cmd_str): + ret, output = osutil.command(cmd_str) + if ret: + baseutil.logger_debug("execute %s command failed" % (cmd_str)) + return ret, output + + def get_cpu_reset_num(self): + """ + Get CPU reset num + @return CPU reset num on success, -1 for failure + """ + cpu = self.chas.get_cpu_byname("cpu") + if cpu is None: + msg = "name cpu not find" + baseutil.logger_debug(msg) + return -1 + return cpu.get_cpu_reset_num() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/led.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/led.py new file mode 100644 index 000000000000..7fb869c74d7f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/led.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +####################################################### +# +# led.py +# Python implementation of the Class led +# +####################################################### +from plat_hal.devicebase import devicebase + + +class led(devicebase): + def __init__(self, conf=None): + if conf is not None: + self.name = conf.get('name', None) + self.led_type = conf.get('led_type', None) + self.led_attrs_config = conf.get('led_attrs', None) + self.led_config = conf.get('led', None) + + def set_color(self, color): + status = self.led_attrs_config.get(color, None) + if status is None: + return False + + mask = self.led_attrs_config.get('mask', 0xff) + + if isinstance(self.led_config, list): + for led_config_index in self.led_config: + ret, value = self.get_value(led_config_index) + if (ret is False) or (value is None): + return False + setval = (int(value) & ~mask) | (status) + ret, val = self.set_value(led_config_index, setval) + if ret is False: + return ret + else: + ret, value = self.get_value(self.led_config) + if (ret is False) or (value is None): + return False + setval = (int(value) & ~mask) | (status) + ret, val = self.set_value(self.led_config, setval) + return ret + + def get_color(self): + mask = self.led_attrs_config.get('mask', 0xff) + ret, value = self.get_value(self.led_config) + if ret is False or value is None: + return False, 'N/A' + ledval = int(value) & mask + for key, val in self.led_attrs_config.items(): + if (ledval == val) and (key != "mask"): + return True, key + return False, 'N/A' diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/onie_e2.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/onie_e2.py new file mode 100644 index 000000000000..9ac32cace263 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/onie_e2.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +####################################################### +# +# onie_e2.py +# Python implementation of the Class onie_e2 +# +####################################################### +from plat_hal.devicebase import devicebase +from eepromutil.onietlv import onie_tlv + + +class onie_e2(devicebase): + + def __init__(self, conf=None): + self._cardid = "" + self._productname = "" + self._partnum = "" + self._serialnum = "" + self._macbase = "" + self._manufdate = "" + self._deviceversion = "" + self._labelrevision = "" + self._platformname = "" + self._onieversion = "" + self._macsize = "" + self._manufname = "" + self._manufcountry = "" + self._vendorname = "" + self._diagname = "" + self._servicetag = "" + + if conf is not None: + self.name = conf.get('name', None) + self.e2loc = conf.get('e2loc', None) + self.e2_path = self.e2loc.get('loc', None) + self.airflow = conf.get('airflow', "intake") + + @property + def cardid(self): + return self._cardid + + @property + def productname(self): + return self._productname + + @property + def partnum(self): + return self._partnum + + @property + def serialnum(self): + return self._serialnum + + @property + def macbase(self): + return self._macbase + + @property + def manufdate(self): + return self._manufdate + + @property + def deviceversion(self): + return self._deviceversion + + @property + def labelrevision(self): + return self._labelrevision + + @property + def platformname(self): + return self._platformname + + @property + def onieversion(self): + return self._onieversion + + @property + def macsize(self): + return self._macsize + + @property + def manufname(self): + return self._manufname + + @property + def manufcountry(self): + return self._manufcountry + + @property + def vendorname(self): + return self._vendorname + + @property + def diagname(self): + return self._diagname + + @property + def servicetag(self): + return self._servicetag + + def get_onie_e2_info(self): + try: + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s: value is none" % self.name) + onietlv = onie_tlv() + onietlv.decode(eeprom) + self._cardid = onietlv.cardid + self._productname = onietlv.productname + self._partnum = onietlv.partnum + self._serialnum = onietlv.serialnum + self._macbase = onietlv.macbase + self._manufdate = onietlv.manufdate + self._deviceversion = onietlv.deviceversion + self._labelrevision = onietlv.labelrevision + self._platformname = onietlv.platformname + self._onieversion = onietlv.onieversion + self._macsize = onietlv.macsize + self._manufname = onietlv.manufname + self._manufcountry = onietlv.manufcountry + self._vendorname = onietlv.vendorname + self._diagname = onietlv.diagname + self._servicetag = onietlv.servicetag + except Exception: + return False + return True diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/osutil.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/osutil.py new file mode 100644 index 000000000000..684e26bb9ecd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/osutil.py @@ -0,0 +1,440 @@ +#!/usr/bin/env python3 +####################################################### +# +# osutil.py +# Python implementation of the Class osutil +# +####################################################### + +import os +import glob +import re +import time +import subprocess +import fcntl +import syslog +from functools import wraps +from wbutil.smbus import SMBus + + +PLATFORM_HAL_DEBUG_FILE = "/etc/.platform_hal_debug_flag" + + +def platform_hal_debug(s): + if os.path.exists(PLATFORM_HAL_DEBUG_FILE): + syslog.openlog("PLATFORM_HAL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def retry(maxretry=6, delay=0.01): + ''' + maxretry: max retry times + delay : interval after last retry + ''' + def decorator(f): + @wraps(f) + def wrapper(*args, **kwargs): + time_retry = maxretry + time_delay = delay + result_msg = "" + while time_retry: + try: + val, result_msg = f(*args, **kwargs) + if val is True: + return val, result_msg + time_retry -= 1 + time.sleep(time_delay) + except Exception as e: + time_retry -= 1 + result_msg = str(e) + time.sleep(time_delay) + return False, "max time retry last errmsg is {}".format(result_msg) + return wrapper + return decorator + + +pidfile = None + + +def file_rw_lock(file_path): + global pidfile + pidfile = open(file_path, "r") + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + platform_hal_debug("file_rw_lock success") + return True + except Exception: + if pidfile is not None: + pidfile.close() + pidfile = None + return False + + +def file_rw_unlock(): + try: + global pidfile + + if pidfile is not None: + fcntl.flock(pidfile, fcntl.LOCK_UN) + pidfile.close() + pidfile = None + platform_hal_debug("file_rw_unlock success") + else: + platform_hal_debug("pidfile is invalid, do nothing") + return True + except Exception as e: + platform_hal_debug("file_rw_unlock err, msg: %s" % (str(e))) + return False + + +def take_file_rw_lock(file_path): + loop = 1000 + ret = False + for i in range(0, loop): + ret = file_rw_lock(file_path) + if ret is True: + break + time.sleep(0.001) + return ret + + +class osutil(object): + """ + osutil + """ + + @staticmethod + @retry(maxretry=6) + def wbi2cget_python(bus, addr, reg): + with SMBus(bus) as y: + val, ind = y.read_byte_data(addr, reg, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2cset_python(bus, addr, reg, value): + with SMBus(bus) as y: + val, ind = y.write_byte_data(addr, reg, value, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2cgetword_python(bus, addr, reg): + with SMBus(bus) as y: + val, ind = y.read_word_data(addr, reg, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2csetword_python(bus, addr, reg, value): + with SMBus(bus) as y: + val, ind = y.write_word_data(addr, reg, value, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2csetwordpec_python(bus, addr, reg, value): + with SMBus(bus) as y: + val, ind = y.write_word_data_pec(addr, reg, value, True) + return val, ind + + @staticmethod + @retry(maxretry=6) + def wbi2cset_byte_pec_python(bus, addr, reg, value): + with SMBus(bus) as y: + val, ind = y.write_byte_data_pec(addr, reg, value, True) + return val, ind + + @staticmethod + def command(cmdstr): + retcode, output = subprocess.getstatusoutput(cmdstr) + return retcode, output + + @staticmethod + def geti2cword_i2ctool(bus, addr, offset): + command_line = "i2cget -f -y %d 0x%02x 0x%02x wp" % (bus, addr, offset) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + return True, int(ret_t, 16) + time.sleep(0.1) + return False, ret_t + + @staticmethod + def seti2cword_i2ctool(bus, addr, offset, val): + command_line = "i2cset -f -y %d 0x%02x 0x%0x 0x%04x wp" % (bus, addr, offset, val) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + return True, ret_t + time.sleep(0.1) + return False, ret_t + + @staticmethod + def wbi2cget_i2ctool(bus, devno, address): + command_line = "i2cget -f -y %d 0x%02x 0x%02x " % (bus, devno, address) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + return True, int(ret_t, 16) + time.sleep(0.1) + return False, ret_t + + @staticmethod + def wbi2cset_i2ctool(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + @staticmethod + def geti2cword(bus, addr, offset): + return osutil.wbi2cgetword_python(bus, addr, offset) + + @staticmethod + def seti2cword(bus, addr, offset, val): + return osutil.wbi2csetword_python(bus, addr, offset, val) + + @staticmethod + def seti2cwordpec(bus, addr, offset, val): + return osutil.wbi2csetwordpec_python(bus, addr, offset, val) + + @staticmethod + def seti2c_byte_pec(bus, addr, offset, val): + return osutil.wbi2cset_byte_pec_python(bus, addr, offset, val) + + @staticmethod + def wbi2cget(bus, devno, address): + return osutil.wbi2cget_python(bus, devno, address) + + @staticmethod + def wbi2cset(bus, devno, address, byte): + return osutil.wbi2cset_python(bus, devno, address, byte) + + @staticmethod + def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + @staticmethod + def io_rd(reg_addr, read_len=1): + try: + regaddr = 0 + if isinstance(reg_addr, int): + regaddr = reg_addr + else: + regaddr = int(reg_addr, 16) + devfile = "/dev/port" + fd = os.open(devfile, os.O_RDWR | os.O_CREAT) + os.lseek(fd, regaddr, os.SEEK_SET) + val = os.read(fd, read_len) + return True, "".join(["%02x" % item for item in val]) + except ValueError as e: + return False, str(e) + except Exception as e: + return False, str(e) + finally: + os.close(fd) + + @staticmethod + def readsysfs(location, flock_path=None): + flock_path_tmp = None + platform_hal_debug("readsysfs, location:%s, flock_path:%s" % (location, flock_path)) + try: + if flock_path is not None: + flock_paths = glob.glob(flock_path) + if len(flock_paths) != 0: + flock_path_tmp = flock_paths[0] + platform_hal_debug("try to get file lock, path:%s" % flock_path_tmp) + ret = take_file_rw_lock(flock_path_tmp) + if ret is False: + platform_hal_debug("take file lock timeout, path:%s" % flock_path_tmp) + return False, ("take file rw lock timeout, path:%s" % flock_path_tmp) + else: + platform_hal_debug("config error, can't find flock_path:%s" % flock_path) + + locations = glob.glob(location) + with open(locations[0], 'rb') as fd1: + retval = fd1.read() + retval = osutil.byteTostr(retval) + if flock_path_tmp is not None: + file_rw_unlock() + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + except Exception as e: + if flock_path_tmp is not None: + file_rw_unlock() + platform_hal_debug("readsysfs error, msg:%s" % str(e)) + return False, (str(e) + " location[%s]" % location) + return True, retval + + @staticmethod + def writesysfs(location, value): + try: + if not os.path.isfile(location): + print(location, 'not found !') + return False, ("location[%s] not found !" % location) + with open(location, 'w') as fd1: + fd1.write(value) + except Exception as e: + return False, (str(e) + " location[%s]" % location) + return True, ("set location[%s] %s success !" % (location, value)) + + @staticmethod + def getdevmem(addr, digit, mask): + command_line = "devmem 0x%02x %d" % (addr, digit) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = osutil.command(command_line) + if ret == 0: + if mask is not None: + ret_t = str(int(ret_t, 16) & mask) + return True, ret_t + return False, ret_t + + @staticmethod + def readdevfile_ascii(path, offset, length): + msg = "" + ret = "" + joinstr = '' + fd = -1 + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, length) + for item in ret: + joinstr += '%02x ' % item # like sysfs, display in hex + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + return True, joinstr + + @staticmethod + def readdevfile(path, offset, length): + msg = "" + ret = "" + fd = -1 + val_list = [] + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, length) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + return True, val_list + + @staticmethod + def writedevfile(path, offset, buf): + msg = "" + fd = -1 + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + if isinstance(buf, list): + if len(buf) == 0: + msg = "buf:%s is NONE !" % buf + return False, msg + elif isinstance(buf, int): + buf = [buf] + else: + msg = "buf:%s is not list type or not int type !" % buf + return False, msg + + try: + fd = os.open(path, os.O_WRONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.write(fd, bytes(buf)) + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + + return True, ret + + @staticmethod + def wb_os_system(cmd): + status, output = subprocess.getstatusoutput(cmd) + return status, output + + @staticmethod + def getsdkreg(reg): + try: + cmd = "bcmcmd -t 1 'getr %s ' < /dev/null" % reg + ret, result = osutil.wb_os_system(cmd) + result_t = result.strip().replace("\r", "").replace("\n", "") + if ret != 0 or "Error:" in result_t: + return False, result + patt = r"%s.(.*):(.*)>drivshell" % reg + rt = re.findall(patt, result_t, re.S) + test = re.findall("=(.*)", rt[0][0])[0] + except Exception as e: + return False, 'get sdk register error, msg: %s' % str(e) + return True, test + + @staticmethod + def getmactemp(): + try: + result = {} + # need to exec twice + osutil.wb_os_system("bcmcmd -t 1 \"show temp\" < /dev/null") + ret, log = osutil.wb_os_system("bcmcmd -t 1 \"show temp\" < /dev/null") + if ret: + return False, result + logs = log.splitlines() + for line in logs: + if "average" in line: + b = re.findall(r'\d+.\d+', line) + result["average"] = b[0] + elif "maximum" in line: + b = re.findall(r'\d+.\d+', line) + result["maximum"] = b[0] + except Exception as e: + return False, str(e) + return True, result + + @staticmethod + def std_match(stdout, pattern): + if pattern is None: + return stdout.strip() + for line in stdout.splitlines(): + if re.match(pattern, line): + return line.strip() + return None diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/psu.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/psu.py new file mode 100644 index 000000000000..e7db0cdcca8b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/psu.py @@ -0,0 +1,607 @@ +#!/usr/bin/env python3 +####################################################### +# +# psu.py +# Python implementation of the Class psu +# +####################################################### +from eepromutil.fru import ipmifru +from plat_hal.devicebase import devicebase +from plat_hal.sensor import sensor + + +class psu(devicebase): + __pmbus = None + __e2loc = None + __productManufacturer = None # : ARTESYN + __productName = None # : CRPS550W + __productPartModelName = None # : CSU550AP-3-300 + __productVersion = None # : AB + __productSerialNumber = None # : M623UZ00JYABL + __AirFlow = None # 'N/A' + __AirFlowconifg = None + __psu_display_name = None # 'N/A' + __psu_display_name_conifg = None + __psu_not_present_pwm = None + __InputStatus_config = None + __OutputStatus_config = None + __FanSpeed_config = None + __Temperature_config = None + __InputStatus = None + __OutputStatus = None + __FanSpeed = None + __Temperature = None + __FanSpeedMin = None + __FanSpeedMax = None + __FanSpeedTolerance = None + __InputsVoltage_config = None + __InputsCurrent_config = None + __InputsPower_config = None + __OutputsVoltage_config = None + __OutputsCurrent_config = None + __OutputsPower_config = None + __InputsVoltage = {} + __InputsCurrent = None + __InputsPower = None + __OutputsVoltage = None + __OutputsCurrent = None + __OutputsPower = None + __InputsType_config = None + __InputsType = None + __psu_sn_config = None + __psu_hw_config = None + __psu_pn_config = None + __psu_vendor_config = None + __TempStatus_config = None + __FanStatus_config = None + __TempStatus = None + __FanStatus = None + + def __init__(self, conf=None): + self.pmbus = conf.get("pmbusloc", None) + self.e2loc = conf.get("e2loc", None) + self.__presentconfig = conf.get("present", None) + self.name = conf.get("name", None) + self.AirFlowconifg = conf.get("airflow", None) + self.psu_display_name_conifg = conf.get("psu_display_name", None) + self.psu_not_present_pwm = conf.get("psu_not_present_pwm", 100) + self.Temperature_config = conf.get("Temperature", None) + self.Temperature = sensor(self.Temperature_config) + + self.FanSpeedTolerance = conf.get('psu_fan_tolerance', 30) + self.FanSpeed_config = conf.get("FanSpeed", None) + self.FanSpeed = sensor(self.FanSpeed_config) + + self.__InputsVoltage_config = conf.get("InputsVoltage", None) + self.generate_psu_input_vol(self.__InputsVoltage_config) + self.__InputsCurrent_config = conf.get("InputsCurrent", None) + self.InputsCurrent = sensor(self.__InputsCurrent_config) + self.__InputsPower_config = conf.get("InputsPower", None) + self.InputsPower = sensor(self.__InputsPower_config) + self.__OutputsVoltage_config = conf.get("OutputsVoltage", None) + self.OutputsVoltage = sensor(self.__OutputsVoltage_config) + self.__OutputsCurrent_config = conf.get("OutputsCurrent", None) + self.OutputsCurrent = sensor(self.__OutputsCurrent_config) + self.__OutputsPower_config = conf.get("OutputsPower", None) + self.OutputsPower = sensor(self.__OutputsPower_config) + + self.__InputStatus_config = conf.get("InputsStatus", None) + self.__OutputStatus_config = conf.get("OutputsStatus", None) + self.__InputsType_config = conf.get('InputsType', None) + self.__psu_sn_config = conf.get('psu_sn', None) + self.__psu_hw_config = conf.get('psu_hw', None) + self.__psu_pn_config = conf.get('psu_pn', None) + self.__psu_vendor_config = conf.get('psu_vendor', None) + self.__TempStatus_config = conf.get("TempStatus", None) + self.__FanStatus_config = conf.get("FanStatus", None) + + def generate_psu_input_vol(self, config): + tmp = {} + for (key, item) in config.items(): + tmp.setdefault(key, sensor(item)) + self.__InputsVoltage = tmp + + def get_psu_sensor_by_name(self, psutype): + return self.__InputsVoltage.get(psutype) or self.__InputsVoltage.get('other') + + @property + def InputsVoltage(self): + psutype = self.InputsType + input_sensor = self.get_psu_sensor_by_name(psutype) + if input_sensor is None: + return None + return input_sensor + + @InputsVoltage.setter + def InputsVoltage(self, val): + self.__InputsVoltage = val + + @property + def InputsCurrent(self): + return self.__InputsCurrent + + @InputsCurrent.setter + def InputsCurrent(self, val): + self.__InputsCurrent = val + + @property + def InputsPower(self): + return self.__InputsPower + + @InputsPower.setter + def InputsPower(self, val): + self.__InputsPower = val + + @property + def OutputsVoltage(self): + return self.__OutputsVoltage + + @OutputsVoltage.setter + def OutputsVoltage(self, val): + self.__OutputsVoltage = val + + @property + def OutputsCurrent(self): + return self.__OutputsCurrent + + @OutputsCurrent.setter + def OutputsCurrent(self, val): + self.__OutputsCurrent = val + + @property + def OutputsPower(self): + return self.__OutputsPower + + @OutputsPower.setter + def OutputsPower(self, val): + self.__OutputsPower = val + + @property + def InputStatus(self): + if self.present is False: + self.__InputStatus = False + else: + ret, val = self.get_value(self.__InputStatus_config) + mask = self.__InputStatus_config.get("mask") + if ret is True: + ttt = val & mask + if ttt == 0: + self.__InputStatus = True + else: + self.__InputStatus = False + else: + self.__InputStatus = False + return self.__InputStatus + + @InputStatus.setter + def InputStatus(self, val): + self.__InputStatus = val + + @property + def TempStatus(self): + if self.__TempStatus_config is None: + return None + if self.present is False: + self.__TempStatus = False + else: + ret, val = self.get_value(self.__TempStatus_config) + mask = self.__TempStatus_config.get("mask") + if ret is True: + ttt = val & mask + if ttt == 0: + self.__TempStatus = True + else: + self.__TempStatus = False + else: + self.__TempStatus = False + return self.__TempStatus + + @TempStatus.setter + def TempStatus(self, val): + self.__TempStatus = val + + @property + def FanStatus(self): + if self.__FanStatus_config is None: + return None + if self.present is False: + self.__FanStatus = False + else: + ret, val = self.get_value(self.__FanStatus_config) + mask = self.__FanStatus_config.get("mask") + if ret is True: + ttt = val & mask + if ttt == 0: + self.__FanStatus = True + else: + self.__FanStatus = False + else: + self.__FanStatus = False + return self.__FanStatus + + @FanStatus.setter + def FanStatus(self, val): + self.__FanStatus = val + + @property + def InputsType(self): + psutypedecode = self.__InputsType_config.get('psutypedecode', None) + if self.present is False: + self.__InputsType = psutypedecode.get(0x00) + else: + ret, val = self.get_value(self.__InputsType_config) + self.__InputsType = self.__InputsType_config.get(val, None) + if self.__InputsType is not None: + return self.__InputsType + if ret is True and val in psutypedecode: + self.__InputsType = psutypedecode.get(val) + else: + self.__InputsType = psutypedecode.get(0x00) + return self.__InputsType + + @InputsType.setter + def InputsType(self, val): + self.__InputsType = val + + @property + def FanSpeedMin(self): + return self.__FanSpeedMin + + @FanSpeedMin.setter + def FanSpeedMin(self, val): + self.__FanSpeedMin = val + + @property + def FanSpeedMax(self): + return self.__FanSpeedMax + + @FanSpeedMax.setter + def FanSpeedMax(self, val): + self.__FanSpeedMax = val + + @property + def FanSpeedTolerance(self): + return self.__FanSpeedTolerance + + @FanSpeedTolerance.setter + def FanSpeedTolerance(self, val): + self.__FanSpeedTolerance = val + + @property + def OutputStatus(self): + if self.present is False: + self.__OutputStatus = False + else: + ret, val = self.get_value(self.__OutputStatus_config) + mask = self.__OutputStatus_config.get("mask") + if ret is True: + ttt = val & mask + if ttt == 0: + self.__OutputStatus = True + else: + self.__OutputStatus = False + else: + self.__OutputStatus = False + return self.__OutputStatus + + @OutputStatus.setter + def OutputStatus(self, val): + self.__OutputStatus = val + + @property + def FanSpeed(self): + return self.__FanSpeed + + @FanSpeed.setter + def FanSpeed(self, val): + self.__FanSpeed = val + + @property + def Temperature(self): + return self.__Temperature + + @Temperature.setter + def Temperature(self, val): + self.__Temperature = val + + @property + def Temperature_config(self): + return self.__Temperature_config + + @Temperature_config.setter + def Temperature_config(self, val): + self.__Temperature_config = val + + @property + def AirFlowconifg(self): + return self.__AirFlowconifg + + @AirFlowconifg.setter + def AirFlowconifg(self, val): + self.__AirFlowconifg = val + + @property + def psu_display_name_conifg(self): + return self.__psu_display_name_conifg + + @psu_display_name_conifg.setter + def psu_display_name_conifg(self, val): + self.__psu_display_name_conifg = val + + @property + def pmbus(self): + return self.__pmbus + + @pmbus.setter + def pmbus(self, val): + self.__pmbus = val + + @property + def e2loc(self): + return self.__e2loc + + @e2loc.setter + def e2loc(self, val): + self.__e2loc = val + + @property + def AirFlow(self): + return self.__AirFlow + + @AirFlow.setter + def AirFlow(self, val): + self.__AirFlow = val + + @property + def psu_display_name(self): + return self.__psu_display_name + + @psu_display_name.setter + def psu_display_name(self, val): + self.__psu_display_name = val + + @property + def psu_not_present_pwm(self): + return self.__psu_not_present_pwm + + @psu_not_present_pwm.setter + def psu_not_present_pwm(self, val): + self.__psu_not_present_pwm = val + + @property + def present(self): + ret, val = self.get_value(self.__presentconfig) + if ret is False or val is None: + return False + mask = self.__presentconfig.get("mask") + if isinstance(val, str): + value = int(val, 16) + else: + value = val + ttt = value & mask + okval = self.__presentconfig.get("okval", 0) + if ttt == okval: + return True + return False + + @property + def productManufacturer(self): + return self.__productManufacturer + + @productManufacturer.setter + def productManufacturer(self, val): + self.__productManufacturer = val + + @property + def productName(self): + return self.__productName + + @productName.setter + def productName(self, val): + self.__productName = val + + @property + def productPartModelName(self): + return self.__productPartModelName + + @productPartModelName.setter + def productPartModelName(self, val): + self.__productPartModelName = val + + @property + def productVersion(self): + return self.__productVersion + + @productVersion.setter + def productVersion(self, val): + self.__productVersion = val + + @property + def productSerialNumber(self): + return self.__productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, val): + self.__productSerialNumber = val + + @property + def psu_sn_sysfs(self): + if self.__psu_sn_config is None: + return None + ret, val = self.get_value(self.__psu_sn_config) + if ret is False or val is None: + return None + return val + + @property + def psu_hw_sysfs(self): + if self.__psu_hw_config is None: + return None + ret, val = self.get_value(self.__psu_hw_config) + if ret is False or val is None: + return None + return val + + @property + def psu_pn_sysfs(self): + if self.__psu_pn_config is None: + return None + ret, val = self.get_value(self.__psu_pn_config) + if ret is False or val is None: + return None + return val + + @property + def psu_vendor_sysfs(self): + if self.__psu_vendor_config is None: + return None + ret, val = self.get_value(self.__psu_vendor_config) + if ret is False or val is None: + return None + return val + + def __str__(self): + formatstr = \ + "name : %s \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "AirFlow : %s \n" \ + + tmpstr = formatstr % (self.name, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, self.AirFlow) + return tmpstr + + def get_fan_speed_pwm(self): + if self.present is False: + return self.psu_not_present_pwm + selfconfig = {} + selfconfig['bus'] = self.pmbus['bus'] + selfconfig['addr'] = self.pmbus['addr'] + selfconfig['way'] = 'i2cword' + selfconfig['offset'] = 0x3b + ret, val = self.get_value(selfconfig) + if ret is True: + return val + return None + + def set_fan_speed_pwm(self, pwm): + ''' + pmbus + if duty: + i2cset -f -y 0x3b 0x0064 wp + ''' + if self.present is False: + return None + if 0 <= pwm <= 100: + # enable duty first + selfconfig = {} + + selfconfig['bus'] = self.pmbus['bus'] + selfconfig['addr'] = self.pmbus['addr'] + selfconfig['way'] = 'i2cpec' + selfconfig['offset'] = 0x3a + self.set_value(selfconfig, 0x80) + + selfconfig['way'] = 'i2cwordpec' + selfconfig['offset'] = 0x3b + bytetmp = pwm + ret, val = self.set_value(selfconfig, int(bytetmp)) + if ret is True: + return True + return None + raise Exception("pwm not in range [0,100]") + + def get_fru_info_by_sysfs(self): + try: + psu_sn = self.psu_sn_sysfs + psu_hw = self.psu_hw_sysfs + psu_pn = self.psu_pn_sysfs + psu_vendor = self.psu_vendor_sysfs + if psu_sn is None or psu_hw is None or psu_pn is None or psu_vendor is None: + return False + self.productSerialNumber = psu_sn.strip().replace(chr(0), "") + self.productVersion = psu_hw.strip() + self.productPartModelName = psu_pn.strip() + self.productManufacturer = psu_vendor.strip().replace(chr(0), "") + except Exception: + self.productSerialNumber = None + self.productVersion = None + self.productPartModelName = None + self.productManufacturer = None + return False + return True + + def get_fru_info_by_decode(self): + try: + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s:value is none" % self.name) + fru = ipmifru() + if isinstance(eeprom, bytes): + eeprom = self.byteTostr(eeprom) + fru.decodeBin(eeprom) + if fru.productInfoArea is not None: + self.productManufacturer = fru.productInfoArea.productManufacturer.strip() + self.productName = fru.productInfoArea.productName.strip() + self.productPartModelName = fru.productInfoArea.productPartModelName.strip() + self.productVersion = fru.productInfoArea.productVersion.strip() + self.productSerialNumber = fru.productInfoArea.productSerialNumber.strip().replace(chr(0), "") + except Exception: + self.productManufacturer = None + self.productName = None + self.productPartModelName = None + self.productVersion = None + self.productSerialNumber = None + return False + return True + + def get_fru_info(self): + try: + if self.present is not True: + raise Exception("%s: not present" % self.name) + if self.get_fru_info_by_sysfs() is True: + return True + return self.get_fru_info_by_decode() + except Exception: + self.productManufacturer = None + self.productName = None + self.productPartModelName = None + self.productVersion = None + self.productSerialNumber = None + return False + + def get_AirFlow(self): + if self.productPartModelName is None: + ret = self.get_fru_info() + if ret is False: + self.AirFlow = None + return False + if self.AirFlowconifg is None: + self.AirFlow = None + return False + for i in self.AirFlowconifg: + if self.productPartModelName in self.AirFlowconifg[i]: + self.AirFlow = i + return True + self.AirFlow = None + return False + + def get_psu_display_name(self): + if self.productPartModelName is None: + ret = self.get_fru_info() + if ret is False: + self.psu_display_name = None + return False + if self.psu_display_name_conifg is None: + self.psu_display_name = self.productPartModelName + return False + for i in self.psu_display_name_conifg: + if self.productPartModelName in self.psu_display_name_conifg[i]: + self.psu_display_name = i + return True + self.psu_display_name = self.productPartModelName + return False diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/rotor.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/rotor.py new file mode 100644 index 000000000000..2b4e4ffd5f0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/rotor.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 +####################################################### +# +# rotor.py +# Python implementation of the Class rotor +# +####################################################### +from plat_hal.devicebase import devicebase +from plat_hal.sensor import sensor + + +class rotor(devicebase): + __rotor_Running = None + __rotor_HwAlarm_conf = None + __rotor_Speed = None + __rotor_run_conf = None + __Speedconfig = None + __i2c_speed = None + __SpeedMin = None + __SpeedMax = None + __SpeedTolerance = None + + def __init__(self, conf=None): + self.name = conf.get('name', None) + self.rotor_HwAlarm_conf = conf.get('HwAlarm', None) + self.rotor_run_conf = conf.get('Running', None) + self.SpeedMin = conf.get('SpeedMin', None) + self.SpeedMax = conf.get('SpeedMax', None) + self.Tolerance = conf.get('tolerance', 30) + self.rotor_Speed = sensor(conf.get('Speed', None)) + self.Speedconfig = conf.get('Set_speed', None) + + def getRunning(self): + ret, val = self.get_value(self.rotor_run_conf) + if ret is False or val is None: + return False + if isinstance(val, str): + value = int(val, 16) + else: + value = val + mask = self.rotor_run_conf.get("mask") + is_runing_value = self.rotor_run_conf.get("is_runing") + flag = value & mask + if flag == is_runing_value: + return True + return False + + @property + def SpeedMin(self): + return self.__SpeedMin + + @SpeedMin.setter + def SpeedMin(self, val): + self.__SpeedMin = val + + @property + def SpeedMax(self): + return self.__SpeedMax + + @SpeedMax.setter + def SpeedMax(self, val): + self.__SpeedMax = val + + @property + def Tolerance(self): + return self.__SpeedTolerance + + @Tolerance.setter + def Tolerance(self, val): + self.__SpeedTolerance = val + + @property + def i2c_speed(self): + ret, val = self.get_value(self.Speedconfig) + if ret is False: + return None + if val is not None: + self.__i2c_speed = val + return self.__i2c_speed + + def feed_watchdog(self): + ret, val = self.get_value(self.Speedconfig) + if ret is False: + return False, None + if val is not None: + ret, val = self.set_value(self.Speedconfig, val) + return ret, val + return False, None + + @i2c_speed.setter + def i2c_speed(self, val): + self.__i2c_speed = val + + @property + def Speedconfig(self): + return self.__Speedconfig + + @Speedconfig.setter + def Speedconfig(self, val): + self.__Speedconfig = val + + @property + def rotor_run_conf(self): + return self.__rotor_run_conf + + @rotor_run_conf.setter + def rotor_run_conf(self, val): + self.__rotor_run_conf = val + + @property + def rotor_Speed(self): + return self.__rotor_Speed + + @rotor_Speed.setter + def rotor_Speed(self, val): + self.__rotor_Speed = val + + @property + def rotor_HwAlarm(self): + ret, val = self.get_value(self.rotor_HwAlarm_conf) + mask = self.rotor_HwAlarm_conf.get("mask") + no_alarm_value = self.rotor_HwAlarm_conf.get("no_alarm") + if ret is False or val is None: + return False + if isinstance(val, str): + value = int(val, 16) + else: + value = val + flag = value & mask + if flag == no_alarm_value: + return False + return True + + @property + def rotor_HwAlarm_conf(self): + return self.__rotor_HwAlarm_conf + + @rotor_HwAlarm_conf.setter + def rotor_HwAlarm_conf(self, val): + self.__rotor_HwAlarm_conf = val + + @property + def rotor_Running(self): + self.__rotor_Running = self.getRunning() + return self.__rotor_Running + + @rotor_Running.setter + def rotor_Running(self, val): + self.__rotor_Running = val diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/sensor.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/sensor.py new file mode 100644 index 000000000000..2b4e05e00e43 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/sensor.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 +####################################################### +# +# sensor.py +# Python implementation of the Class sensor +# +####################################################### +import time +from plat_hal.devicebase import devicebase + + +class sensor(devicebase): + + __Value = None + __Min = None + __Max = None + __Low = None + __High = None + __ValueConfig = None + __Flag = None + __Unit = None + __format = None + __read_times = None + + __Min_config = None + __Max_config = None + __Low_config = None + __High_config = None + + @property + def Min_config(self): + return self.__Min_config + + @Min_config.setter + def Min_config(self, val): + self.__Min_config = val + + @property + def Max_config(self): + return self.__Max_config + + @Max_config.setter + def Max_config(self, val): + self.__Max_config = val + + @property + def Low_config(self): + return self.__Low_config + + @Low_config.setter + def Low_config(self, val): + self.__Low_config = val + + @property + def High_config(self): + return self.__High_config + + @High_config.setter + def High_config(self, val): + self.__High_config = val + + @property + def Unit(self): + return self.__Unit + + @Unit.setter + def Unit(self, val): + self.__Unit = val + + @property + def format(self): + return self.__format + + @format.setter + def format(self, val): + self.__format = val + + @property + def read_times(self): + return self.__read_times + + @read_times.setter + def read_times(self, val): + self.__read_times = val + + @property + def ValueConfig(self): + return self.__ValueConfig + + @ValueConfig.setter + def ValueConfig(self, val): + self.__ValueConfig = val + + @property + def Flag(self): + return self.__Flag + + @Flag.setter + def Flag(self, val): + self.__Flag = val + + def get_median(self, value_config, read_times): + val_list = [] + for i in range(0, read_times): + ret, real_value = self.get_value(value_config) + if i != (read_times - 1): + time.sleep(0.01) + if ret is False or real_value is None: + continue + val_list.append(real_value) + val_list.sort() + if val_list: + return True, val_list[int((len(val_list) - 1) / 2)] + return False, None + + @property + def Value(self): + try: + ret, val = self.get_median(self.ValueConfig, self.read_times) + if ret is False or val is None: + return None + if self.format is None: + self.__Value = int(val) + else: + self.__Value = self.get_format_value(self.format % val) + self.__Value = round(float(self.__Value), 3) + except Exception: + return None + return self.__Value + + @Value.setter + def Value(self, val): + self.__Value = val + + @property + def Min(self): + try: + if self.format is None: + self.__Min = self.Min_config + else: + self.__Min = self.get_format_value(self.format % self.Min_config) + self.__Min = round(float(self.__Min), 3) + except Exception: + return None + return self.__Min + + @Min.setter + def Min(self, val): + self.__Min = val + + @property + def Max(self): + try: + if self.format is None: + self.__Max = self.Max_config + else: + self.__Max = self.get_format_value(self.format % self.Max_config) + self.__Max = round(float(self.__Max), 3) + except Exception: + return None + return self.__Max + + @Max.setter + def Max(self, val): + self.__Max = val + + @property + def Low(self): + try: + if self.format is None: + self.__Low = self.Low_config + else: + self.__Low = self.get_format_value(self.format % self.Low_config) + except Exception: + return None + return self.__Low + + @Low.setter + def Low(self, val): + self.__Low = val + + @property + def High(self): + try: + if self.format is None: + self.__High = self.High_config + else: + self.__High = self.get_format_value(self.format % self.High_config) + except Exception: + return None + return self.__High + + @High.setter + def High(self, val): + self.__High = val + + def __init__(self, conf=None): + self.ValueConfig = conf.get("value", None) + self.Flag = conf.get("flag", None) + self.Min_config = conf.get("Min", None) + self.Max_config = conf.get("Max", None) + self.Low_config = conf.get("Low", None) + self.High_config = conf.get("High", None) + self.Unit = conf.get('Unit', None) + self.format = conf.get('format', None) + self.read_times = conf.get('read_times', 1) + + def __str__(self): + formatstr = \ + "ValueConfig: : %s \n" \ + "Min : %s \n" \ + "Max : %s \n" \ + "Unit : %s \n" \ + "format: : %s \n" + + tmpstr = formatstr % (self.ValueConfig, self.Min, + self.Max, self.Unit, + self.format) + return tmpstr diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/temp.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/temp.py new file mode 100644 index 000000000000..a202c20339c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/plat_hal/temp.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +####################################################### +# +# temp.py +# Python implementation of the Class temp +# +####################################################### +import os +import syslog +from plat_hal.sensor import sensor + + +PLATFORM_HAL_TEMP_DEBUG_FILE = "/etc/.platform_hal_temp_debug_flag" + + +def platform_hal_temp_debug(s): + if os.path.exists(PLATFORM_HAL_TEMP_DEBUG_FILE): + syslog.openlog("PLATFORM_HAL_TEPM", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +class temp(sensor): + def __init__(self, conf=None): + super(temp, self).__init__(conf.get('Temperature', None)) + self.name = conf.get("name", None) + self.temp_id = conf.get("temp_id", None) + self.api_name = conf.get("api_name", self.name) + self.fix_value = conf.get("fix_value", None) + self.temp_invalid = conf.get("invalid", None) + self.temp_error = conf.get("error", None) + + def temp_cali_by_fan_pwm(self, param, origin_value): + fan_pwm_conf = param.get("fan_pwm") + temp_fix_list = param.get("temp_fix_list") + + ret, val = self.get_value(fan_pwm_conf) + if ret is False or val is None: + platform_hal_temp_debug("temp calibration get fan pwm failed, msg: %s, return None" % (val)) + return None + + fan_pwm = int(val) + for item in temp_fix_list: + if item["min"] <= fan_pwm <= item["max"]: + fix_value = origin_value + item["fix"] + platform_hal_temp_debug("temp calibration by fan pwm, origin_value: %s, pwm: %s, fix_value: %s" % + (origin_value, fan_pwm, fix_value)) + return fix_value + platform_hal_temp_debug("temp calibration by fan pwm, origin_value: %s, pwm: %s, not match return None" % + (origin_value, fan_pwm)) + return None + + def fix_temp_value(self, origin_value): + try: + fix_type = self.fix_value.get("fix_type") + + if fix_type == "func": + func_name = self.fix_value.get("func_name") + func_param = self.fix_value.get("func_param") + func = getattr(self, func_name) + if func is None: + platform_hal_temp_debug("function %s, not defined" % func_name) + return None + value = func(func_param, origin_value) + return value + + if fix_type == "config": + coefficient = self.fix_value.get("coefficient", 1) + addend = self.fix_value.get("addend", 0) + value = (origin_value + addend) * coefficient + platform_hal_temp_debug("temp calibration by config, coefficient: %s, addend: %s, origin_value: %s, fix_value: %s" % + (coefficient, addend, origin_value, value)) + return value + + platform_hal_temp_debug("unsupport fix type: %s, return origin value: %s" % (fix_type, origin_value)) + return origin_value + except Exception as e: + platform_hal_temp_debug("fix_temp_value raise exception, msg: %s" % (str(e))) + return None + + def get_max_value(self, conf): + try: + ret, val = self.get_value(conf) + if ret is False or val is None: + return None + return val + except Exception: + return None + + def check_flag(self): + try: + okbit = self.Flag.get('okbit') + okval = self.Flag.get('okval') + ret, val = self.get_value(self.Flag) + if (ret is False) or (val is None): + return False + val_t = (int(val) & (1 << okbit)) >> okbit + if val_t != okval: + return False + except Exception: + return False + return True + + @property + def Value(self): + try: + if self.Flag is not None: + if self.check_flag() is False: + return None + if isinstance(self.ValueConfig, list): + max_val = None + for i in self.ValueConfig: + tmp = self.get_max_value(i) + if tmp is None: + continue + if max_val is None or max_val < tmp: + max_val = tmp + if max_val is None: + return None + if self.format is None: + self.__Value = int(max_val) + else: + self.__Value = self.get_format_value(self.format % max_val) + else: + ret, val = self.get_value(self.ValueConfig) + if ret is False or val is None: + return None + if self.format is None: + self.__Value = int(val) + else: + self.__Value = self.get_format_value(self.format % val) + except Exception: + return None + if self.fix_value is not None and self.__Value != self.temp_invalid and self.__Value != self.temp_error: + self.__Value = self.fix_temp_value(self.__Value) + return self.__Value + + @Value.setter + def Value(self, val): + self.__Value = val diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/logutil.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/logutil.py deleted file mode 100644 index 2b001f21d72c..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/logutil.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: UTF-8 -*- - -import logging -from syslog import ( - syslog, - openlog, - LOG_WARNING, - LOG_CRIT, - LOG_DEBUG, - LOG_ERR, - LOG_PID, - LOG_INFO, -) - -class Logger(): - def __init__(self, prefix, filepath=None, syslog=False, dbg_mask=0x0): - self.logger = None - if syslog is False: - if filepath is None: - raise AttributeError("filepath needed") - - # init logging - formatter = logging.Formatter( "%(asctime)s %(levelname)s %(filename)s[%(funcName)s][%(lineno)s]: %(message)s") - handler = logging.FileHandler(self.filepath) - handler.setFormatter(formatter) - self.logger = logging.getLogger(__name__) - self.logger.setLevel(logging.DEBUG) - self.logger.addHandler(handler) - - self.prefix = prefix - self.use_syslog = syslog - self.dbg_mask = dbg_mask - - def info(self, s): - if self.use_syslog: - self._syslog(s, LOG_INFO) - else: - self.logger.info(s) - - def debug(self, dbg_lvl, s): - if dbg_lvl & self.dbg_mask: - if self.use_syslog: - self._syslog(s, LOG_DEBUG) - else: - self.logger.debug(s) - - def warn(self, s): - if self.use_syslog: - self._syslog(s, LOG_WARNING) - else: - self.logger.warning(s) - - def error(self, s): - if self.use_syslog: - self._syslog(s, LOG_ERR) - else: - self.logger.error(s) - - def crit(self, s): - if self.use_syslog: - self._syslog(s, LOG_CRIT) - else: - self.logger.critical(s) - - def _syslog(self, s, t): - openlog(self.prefix, LOG_PID) - syslog(t, s) diff --git a/device/ragile/x86_64-ragile_ra-b6910-64c-r0/platform_env.conf b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/__init__.py similarity index 100% rename from device/ragile/x86_64-ragile_ra-b6910-64c-r0/platform_env.conf rename to platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/__init__.py diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/baseutil.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/baseutil.py similarity index 51% rename from platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/baseutil.py rename to platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/baseutil.py index 1cf74d32d22f..340a1f7a733f 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/baseutil.py +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/baseutil.py @@ -1,6 +1,7 @@ -# -*- coding: UTF-8 -*- +#!/usr/bin/env python3 import os + def get_machine_info(): if not os.path.isfile('/host/machine.conf'): return None @@ -13,11 +14,25 @@ def get_machine_info(): machine_vars[tokens[0]] = tokens[1].strip() return machine_vars + def get_platform_info(machine_info): - if machine_info != None: + if machine_info is not None: if 'onie_platform' in machine_info: - return machine_info['onie_platform'] - elif 'aboot_platform' in machine_info: + return machine_info['onie_platform'] + if 'aboot_platform' in machine_info: return machine_info['aboot_platform'] return None + +def get_board_id(machine_info): + if machine_info is not None: + if 'onie_board_id' in machine_info: + return machine_info['onie_board_id'].lower() + return "NA" + + +def get_onie_machine(machine_info): + if machine_info is not None: + if 'onie_machine' in machine_info: + return machine_info['onie_machine'] + return None diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/smbus.py b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/smbus.py similarity index 89% rename from platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/smbus.py rename to platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/smbus.py index f3651fe59a4a..5f1659b3bbf0 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/common/lib/rgutil/smbus.py +++ b/platform/broadcom/sonic-platform-modules-ragile/common/lib/wbutil/smbus.py @@ -1,4 +1,5 @@ -"""smbus2 - A drop-in replacement for smbus-cffi/smbus-python""" +#!/usr/bin/env python3 +# smbus2 - A drop-in replacement for smbus-cffi/smbus-python # The MIT License (MIT) # Copyright (c) 2017 Karl-Petter Lindegaard # @@ -32,6 +33,7 @@ I2C_FUNCS = 0x0705 # Get the adapter functionality mask I2C_RDWR = 0x0707 # Combined R/W transfer (one STOP only) I2C_SMBUS = 0x0720 # SMBus transfer. Takes pointer to i2c_smbus_ioctl_data +I2C_PEC = 0x0708 # SMBus transfer read or write markers from uapi/linux/i2c.h I2C_SMBUS_WRITE = 0 @@ -43,7 +45,8 @@ I2C_SMBUS_BYTE_DATA = 2 I2C_SMBUS_WORD_DATA = 3 I2C_SMBUS_PROC_CALL = 4 -I2C_SMBUS_BLOCK_DATA = 5 # This isn't supported by Pure-I2C drivers with SMBUS emulation, like those in RaspberryPi, OrangePi, etc :( +# This isn't supported by Pure-I2C drivers with SMBUS emulation, like those in RaspberryPi, OrangePi, etc :( +I2C_SMBUS_BLOCK_DATA = 5 I2C_SMBUS_BLOCK_PROC_CALL = 7 # Like I2C_SMBUS_BLOCK_DATA, it isn't supported by Pure-I2C drivers either. I2C_SMBUS_I2C_BLOCK_DATA = 8 I2C_SMBUS_BLOCK_MAX = 32 @@ -216,12 +219,12 @@ def write(address, buf): :rtype: :py:class:`i2c_msg` """ if sys.version_info.major >= 3: - if type(buf) is str: + if isinstance(buf, str): buf = bytes(map(ord, buf)) else: buf = bytes(buf) else: - if type(buf) is not str: + if not isinstance(buf, str): buf = ''.join([chr(x) for x in buf]) arr = create_string_buffer(buf, len(buf)) return i2c_msg( @@ -406,7 +409,7 @@ def read_byte_data(self, i2c_addr, register, force=None): :rtype: int """ val_t = -1 - returnmsg="" + returnmsg = "" try: self._set_address(i2c_addr, force=force) msg = i2c_smbus_ioctl_data.create( @@ -418,8 +421,7 @@ def read_byte_data(self, i2c_addr, register, force=None): returnmsg = str(e) if val_t < 0: return False, returnmsg - else: - return True, msg.data.contents.byte + return True, msg.data.contents.byte def write_byte_data(self, i2c_addr, register, value, force=None): """ @@ -449,8 +451,40 @@ def write_byte_data(self, i2c_addr, register, value, force=None): self.close() if val_t < 0: return False, returnmsg or "" - else: - return True, "" + return True, "" + + def write_byte_data_pec(self, i2c_addr, register, value, force=None): + """ + Write a byte to a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to write to + :type register: int + :param value: Byte value to transmit + :type value: int + :param force: + :type force: Boolean + :rtype: None + """ + val_t = -1 + returnmsg = "" + try: + val_t = ioctl(self.fd, I2C_PEC, 1) + if val_t < 0: + raise Exception("set pec mod error") + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BYTE_DATA + ) + msg.data.contents.byte = value + val_t = ioctl(self.fd, I2C_SMBUS, msg) + except Exception as e: + returnmsg = str(e) + self.close() + if val_t < 0: + return False, returnmsg or "" + return True, "" def read_word_data(self, i2c_addr, register, force=None): """ @@ -478,8 +512,40 @@ def read_word_data(self, i2c_addr, register, force=None): self.close() if val_t < 0: return False, returnmsg or "" - else: - return True, msg.data.contents.word + return True, msg.data.contents.word + + def write_word_data_pec(self, i2c_addr, register, value, force=None): + """ + Write a byte to a given register. + + :param i2c_addr: i2c address + :type i2c_addr: int + :param register: Register to write to + :type register: int + :param value: Word value to transmit + :type value: int + :param force: + :type force: Boolean + :rtype: None + """ + val_t = -1 + returnmsg = "" + try: + val_t = ioctl(self.fd, I2C_PEC, 1) + if val_t < 0: + raise Exception("set pec mod error") + self._set_address(i2c_addr, force=force) + msg = i2c_smbus_ioctl_data.create( + read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_WORD_DATA + ) + msg.data.contents.word = value + val_t = ioctl(self.fd, I2C_SMBUS, msg) + except Exception as e: + returnmsg = str(e) + self.close() + if val_t < 0: + return False, returnmsg or "" + return True, "" def write_word_data(self, i2c_addr, register, value, force=None): """ @@ -509,8 +575,7 @@ def write_word_data(self, i2c_addr, register, value, force=None): self.close() if val_t < 0: return False, returnmsg or "" - else: - return True, "" + return True, "" def process_call(self, i2c_addr, register, value, force=None): """ @@ -685,6 +750,7 @@ class SMBusWrapper: :py:class:`SMBus` handle will be automatically closed upon exit of the ``with`` block. """ + def __init__(self, bus_number=0, auto_cleanup=True, force=False): """ :param auto_cleanup: Close bus when leaving scope. @@ -695,6 +761,7 @@ def __init__(self, bus_number=0, auto_cleanup=True, force=False): self.bus_number = bus_number self.auto_cleanup = auto_cleanup self.force = force + self.bus = None def __enter__(self): self.bus = SMBus(bus=self.bus_number, force=self.force) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modprobe_conf/kernel_drivers_blacklist.conf b/platform/broadcom/sonic-platform-modules-ragile/common/modprobe_conf/kernel_drivers_blacklist.conf new file mode 100644 index 000000000000..5e861802d915 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modprobe_conf/kernel_drivers_blacklist.conf @@ -0,0 +1,5 @@ +blacklist wb_fpga_pcie +blacklist wb_i2c_i801 +blacklist wb_spi_gpio +blacklist intel_spi +blacklist intel_spi_platform diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile old mode 100755 new mode 100644 index f7204c8684d9..8727f1f508f1 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/Makefile @@ -1,15 +1,55 @@ -obj-m := rg-gpio-xeon.o -obj-m += rg_fan.o -obj-m += rg_psu.o -obj-m += ragile_platform.o -obj-m += i2c-mux-pca9641.o -obj-m += i2c-mux-pca954x.o -obj-m += csu550.o -ragile_common-objs := ragile_common_module.o -obj-m += ragile_common.o -obj-m += fpga_pcie_i2c.o -obj-m += fpga_i2c_ocores.o -obj-m += lpc_dbg.o -obj-m += lpc_cpld_i2c_ocores.o -obj-m += rg-i2c-algo-bit.o -obj-m += rg-i2c-gpio.o +PWD = $(shell pwd) +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +KVERSION ?= $(shell uname -r) +KERNEL_SRC ?= /lib/modules/$(KVERSION) + +module_out_put_dir := $(PWD)/build +export module_out_put_dir + +KERNEL_MODULES_SRC = $(PWD)/linux-5.10 + +PLAT_SYSFS_DIR = $(PWD)/plat_sysfs +INTEL_SPI = $(PWD)/intel_spi + +export PLAT_SYSFS_DIR + +platform_common-objs := platform_common_module.o dfd_tlveeprom.o +obj-m += platform_common.o +obj-m += wb_mac_bsc.o +obj-m += wb_fpga_pcie.o +obj-m += wb_pcie_dev.o +obj-m += wb_fpga_i2c_bus_drv.o +obj-m += wb_fpga_pca954x_drv.o +obj-m += wb_lpc_drv.o +obj-m += wb_i2c_dev.o +obj-m += wb_platform_i2c_dev.o +obj-m += wb_io_dev.o +obj-m += wb_eeprom_93xx46.o +obj-m += wb_spi_93xx46.o +obj-m += wb_gpio_d1500.o +obj-m += wb_gpio_device.o +obj-m += wb_i2c_ocores.o +obj-m += wb_spi_ocores.o +obj-m += wb_spi_dev.o +obj-m += wb_wdt.o +obj-m += wb_optoe.o +obj-m += wb_spi_gpio.o +obj-m += wb_spi_gpio_device.o +obj-m += wb_spi_nor_device.o +obj-m += wb_xdpe132g5c.o +obj-m += wb_uio_irq.o + +all : + $(MAKE) -C $(KERNEL_MODULES_SRC) + $(MAKE) -C $(PLAT_SYSFS_DIR) + $(MAKE) -C $(INTEL_SPI) + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) + +clean : + rm -rf $(module_out_put_dir) + rm -f ${PWD}/*.o ${PWD}/*.ko ${PWD}/*.mod.c ${PWD}/.*.cmd ${PWD}/.*.o.d ${PWD}/*.mod + rm -f ${PWD}/Module.markers ${PWD}/Module.symvers ${PWD}/modules.order + rm -rf ${PWD}/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/csu550.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/csu550.c deleted file mode 100755 index 3df7c73ecad0..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/csu550.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * csu550.c - A driver for pmbus - * - * Copyright (c) 2010, 2011 Ericsson AB. - * Copyright (c) 2019 - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pmbus.h" - - -/* - * Find sensor groups and status registers on each page. - */ -static void pmbus_find_sensor_groups(struct i2c_client *client, - struct pmbus_driver_info *info) -{ - int page; - - /* Sensors detected on page 0 only */ - if (pmbus_check_word_register(client, 0, PMBUS_READ_VIN)) - info->func[0] |= PMBUS_HAVE_VIN; - if (pmbus_check_word_register(client, 0, PMBUS_READ_IIN)) - info->func[0] |= PMBUS_HAVE_IIN; - if (pmbus_check_word_register(client, 0, PMBUS_READ_PIN)) - info->func[0] |= PMBUS_HAVE_PIN; - if (info->func[0] && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT)) - info->func[0] |= PMBUS_HAVE_STATUS_INPUT; - if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) && - pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) { - info->func[0] |= PMBUS_HAVE_FAN12; - if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12)) - info->func[0] |= PMBUS_HAVE_STATUS_FAN12; - } - if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) - info->func[0] |= PMBUS_HAVE_TEMP; - if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2)) - info->func[0] |= PMBUS_HAVE_TEMP2; - if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3)) - info->func[0] |= PMBUS_HAVE_TEMP3; - if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3) - && pmbus_check_byte_register(client, 0, PMBUS_STATUS_TEMPERATURE)) - info->func[0] |= PMBUS_HAVE_STATUS_TEMP; - - /* Sensors detected on all pages */ - for (page = 0; page < info->pages; page++) { - if (pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) { - info->func[page] |= PMBUS_HAVE_VOUT; - if (pmbus_check_byte_register(client, page, - PMBUS_STATUS_VOUT)) - info->func[page] |= PMBUS_HAVE_STATUS_VOUT; - } - if (pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) { - info->func[page] |= PMBUS_HAVE_IOUT; - if (pmbus_check_byte_register(client, 0, - PMBUS_STATUS_IOUT)) - info->func[page] |= PMBUS_HAVE_STATUS_IOUT; - } - if (pmbus_check_word_register(client, page, PMBUS_READ_POUT)) - info->func[page] |= PMBUS_HAVE_POUT; - } -} - -/* - * Identify chip parameters. - */ -static int pmbus_identify(struct i2c_client *client, - struct pmbus_driver_info *info) -{ - int ret = 0; - - if (!info->pages) { - /* - * Check if the PAGE command is supported. If it is, - * keep setting the page number until it fails or until the - * maximum number of pages has been reached. Assume that - * this is the number of pages supported by the chip. - */ - if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) { - int page; - - for (page = 1; page < PMBUS_PAGES; page++) { - if (pmbus_set_page(client, page) < 0) - break; - } - pmbus_set_page(client, 0); - info->pages = page; - } else { - info->pages = 1; - } - } - - if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) { - int vout_mode; - - vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); - if (vout_mode >= 0 && vout_mode != 0xff) { - switch (vout_mode >> 5) { - case 0: - break; - case 1: - info->format[PSC_VOLTAGE_OUT] = vid; - break; - case 2: - info->format[PSC_VOLTAGE_OUT] = direct; - break; - default: - ret = -ENODEV; - goto abort; - } - } - } - - /* - * We should check if the COEFFICIENTS register is supported. - * If it is, and the chip is configured for direct mode, we can read - * the coefficients from the chip, one set per group of sensor - * registers. - * - * To do this, we will need access to a chip which actually supports the - * COEFFICIENTS command, since the command is too complex to implement - * without testing it. Until then, abort if a chip configured for direct - * mode was detected. - */ - if (info->format[PSC_VOLTAGE_OUT] == direct) { - ret = -ENODEV; - goto abort; - } - - /* Try to find sensor groups */ - pmbus_find_sensor_groups(client, info); -abort: - return ret; -} - -static int pmbus_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct pmbus_driver_info *info; - struct pmbus_platform_data *pdata = NULL; - struct device *dev = &client->dev; - - info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - if (!strncmp(id->name, "dps460", sizeof("dps460")) || - !strncmp(id->name, "fsp1200", sizeof("fsp1200")) || !strncmp(id->name, "dps550", sizeof("dps550"))) { - pdata = kzalloc(sizeof(struct pmbus_platform_data), GFP_KERNEL); - if (!pdata) { - kfree(info); - return -ENOMEM; - } - pdata->flags = PMBUS_SKIP_STATUS_CHECK; - } - - info->pages = id->driver_data; - info->identify = pmbus_identify; - dev->platform_data = pdata; - - return pmbus_do_probe(client, id, info); -} - -static const struct i2c_device_id pmbus_id[] = { - {"csu550", 0}, - {"csu800", 1}, - {"fsp1200", 1}, - {"dps550", 1}, - {} -}; -MODULE_DEVICE_TABLE(i2c, pmbus_id); - -/* This is the driver that will be inserted */ -static struct i2c_driver pmbus_driver = { - .probe = pmbus_probe, - .remove = pmbus_do_remove, - .id_table = pmbus_id, - .driver = { - .name = "pmbus", - }, -}; - -module_i2c_driver(pmbus_driver); - -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("ragile psupmbus driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.c new file mode 100644 index 000000000000..0d6f38ecc551 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.c @@ -0,0 +1,516 @@ +/* + * Copyright (C) 2003-2014 FreeIPMI Core Team + * + * 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 . + * + */ +/*****************************************************************************\ + * Copyright (C) 2007-2014 Lawrence Livermore National Security, LLC. + * Copyright (C) 2007 The Regents of the University of California. + * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). + * Written by Albert Chu + * UCRL-CODE-232183 + * + * This file is part of Ipmi-fru, a tool used for retrieving + * motherboard field replaceable unit (FRU) information. For details, + * see http://www.llnl.gov/linux/. + * + * Ipmi-fru 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. + * + * Ipmi-fru 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 Ipmi-fru. If not, see . +\*****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "platform_common.h" +#include "dfd_tlveeprom.h" + +/* using in is_valid_tlvinfo_header */ +static u_int32_t eeprom_size; + +/* + * List of TLV codes and names. + */ +static const struct tlv_code_desc tlv_code_list[] = { + { TLV_CODE_PRODUCT_NAME , "Product Name"}, + { TLV_CODE_PART_NUMBER , "Part Number"}, + { TLV_CODE_SERIAL_NUMBER , "Serial Number"}, + { TLV_CODE_MAC_BASE , "Base MAC Address"}, + { TLV_CODE_MANUF_DATE , "Manufacture Date"}, + { TLV_CODE_DEVICE_VERSION , "Device Version"}, + { TLV_CODE_LABEL_REVISION , "Label Revision"}, + { TLV_CODE_PLATFORM_NAME , "Platform Name"}, + { TLV_CODE_ONIE_VERSION , "ONIE Version"}, + { TLV_CODE_MAC_SIZE , "MAC Addresses"}, + { TLV_CODE_MANUF_NAME , "Manufacturer"}, + { TLV_CODE_MANUF_COUNTRY , "Country Code"}, + { TLV_CODE_VENDOR_NAME , "Vendor Name"}, + { TLV_CODE_DIAG_VERSION , "Diag Version"}, + { TLV_CODE_SERVICE_TAG , "Service Tag"}, + { TLV_CODE_VENDOR_EXT , "Vendor Extension"}, + { TLV_CODE_CRC_32 , "CRC-32"}, +}; + +#if 0 +#define OPENBMC_VPD_KEY_INVAIL_VAL 0 + +static const tlv_code_map_t tlv_code_map[] = { + { TLV_CODE_PRODUCT_NAME , OPENBMC_VPD_KEY_PRODUCT_NAME}, + { TLV_CODE_PART_NUMBER , OPENBMC_VPD_KEY_PRODUCT_PART_MODEL_NUM}, + { TLV_CODE_SERIAL_NUMBER , OPENBMC_VPD_KEY_PRODUCT_SERIAL_NUM}, + { TLV_CODE_MAC_BASE , OPENBMC_VPD_KEY_INVAIL_VAL}, + { TLV_CODE_MANUF_DATE , OPENBMC_VPD_KEY_BOARD_MFG_DATE}, + { TLV_CODE_DEVICE_VERSION , OPENBMC_VPD_KEY_PRODUCT_VER}, + { TLV_CODE_LABEL_REVISION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM7}, + { TLV_CODE_PLATFORM_NAME , OPENBMC_VPD_KEY_PRODUCT_CUSTOM1}, + { TLV_CODE_ONIE_VERSION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM2}, + { TLV_CODE_MAC_SIZE , OPENBMC_VPD_KEY_INVAIL_VAL}, + { TLV_CODE_MANUF_NAME , OPENBMC_VPD_KEY_PRODUCT_MFR}, + { TLV_CODE_MANUF_COUNTRY , OPENBMC_VPD_KEY_PRODUCT_CUSTOM3}, + { TLV_CODE_VENDOR_NAME , OPENBMC_VPD_KEY_PRODUCT_CUSTOM4}, + { TLV_CODE_DIAG_VERSION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM8}, + { TLV_CODE_SERVICE_TAG , OPENBMC_VPD_KEY_PRODUCT_CUSTOM5}, + { TLV_CODE_VENDOR_EXT , OPENBMC_VPD_KEY_PRODUCT_CUSTOM6}, + { TLV_CODE_CRC_32 , OPENBMC_VPD_KEY_INVAIL_VAL}, +}; +#endif + +#define TLV_CODE_NUM (sizeof(tlv_code_list) / sizeof(tlv_code_list[0])) + +#if 0 +#define TLV_CODE_MAP_NUM (sizeof(tlv_code_map) / sizeof(tlv_code_map[0])) +#endif + +const unsigned long crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +static unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len) +{ + unsigned i; + if (len < 1) + return 0xffffffff; + + for (i = 0; i != len; ++i) + { + crc = crc_table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8); + } + + crc = crc ^ 0xffffffff; + + return crc; +} + +/* + * is_valid_tlv + * + * Perform basic sanity checks on a TLV field. The TLV is pointed to + * by the parameter provided. + * 1. The type code is not reserved (0x00 or 0xFF) + */ +static inline bool is_valid_tlv(tlvinfo_tlv_t *tlv) +{ + return ((tlv->type != 0x00) && (tlv->type != 0xFF)); +} + +/* + * is_valid_tlvinfo_header + * + * Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM + * data pointed to by the parameter: + * 1. First 8 bytes contain null-terminated ASCII string "TlvInfo" + * 2. Version byte is 1 + * 3. Total length bytes contain value which is less than or equal + * to the allowed maximum (2048-11) + * + */ +static inline bool is_valid_tlvinfo_header(tlvinfo_header_t *hdr) +{ + int max_size = eeprom_size; + return((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) && + (hdr->version == TLV_INFO_VERSION) && + (be16_to_cpu(hdr->totallen) <= max_size) ); +} + +/* + * decode_tlv_value + * + * Decode a single TLV value into a string. + + * The validity of EEPROM contents and the TLV field have been verified + * prior to calling this function. + */ +static void decode_tlv_value(tlvinfo_tlv_t *tlv, tlv_decode_value_t *decode_value) +{ + int i; + char *value; + u_int32_t length; + + value = (char *)decode_value->value; + + switch (tlv->type) { + case TLV_CODE_PRODUCT_NAME: + case TLV_CODE_PART_NUMBER: + case TLV_CODE_SERIAL_NUMBER: + case TLV_CODE_MANUF_DATE: + case TLV_CODE_LABEL_REVISION: + case TLV_CODE_PLATFORM_NAME: + case TLV_CODE_ONIE_VERSION: + case TLV_CODE_MANUF_NAME: + case TLV_CODE_MANUF_COUNTRY: + case TLV_CODE_VENDOR_NAME: + case TLV_CODE_DIAG_VERSION: + case TLV_CODE_SERVICE_TAG: + case TLV_CODE_VENDOR_EXT: + memcpy(value, tlv->value, tlv->length); + value[tlv->length] = 0; + length = tlv->length; + break; + case TLV_CODE_MAC_BASE: + length = sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X", + tlv->value[0], tlv->value[1], tlv->value[2], + tlv->value[3], tlv->value[4], tlv->value[5]); + break; + case TLV_CODE_DEVICE_VERSION: + length = sprintf(value, "%u", tlv->value[0]); + break; + case TLV_CODE_MAC_SIZE: + length = sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]); + break; + #if 0 + case TLV_CODE_VENDOR_EXT: + value[0] = 0; + length = 0; + for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) { + length += sprintf(value, "%s 0x%02X", value, tlv->value[i]); + } + break; + #endif + case TLV_CODE_CRC_32: + length = sprintf(value, "0x%02X%02X%02X%02X", tlv->value[0], + tlv->value[1], tlv->value[2], tlv->value[3]); + break; + default: + value[0] = 0; + length = 0; + for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) { + length += sprintf(value, "%s 0x%02X", value, tlv->value[i]); + } + break; + } + + decode_value->length = length; +} + +/* + * is_checksum_valid + * + * Validate the checksum in the provided TlvInfo EEPROM data. First, + * verify that the TlvInfo header is valid, then make sure the last + * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data + * and compare it to the value stored in the EEPROM CRC-32 TLV. + */ +static bool is_checksum_valid(u_int8_t *eeprom) +{ + tlvinfo_header_t *eeprom_hdr; + tlvinfo_tlv_t *eeprom_crc; + unsigned int calc_crc; + unsigned int stored_crc; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + + // Is the eeprom header valid? + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + return false; + } + + // Is the last TLV a CRC? + eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) + + be16_to_cpu(eeprom_hdr->totallen) - (sizeof(tlvinfo_tlv_t) + 4)]; + if ((eeprom_crc->type != TLV_CODE_CRC_32) || (eeprom_crc->length != 4)) { + return false; + } + + // Calculate the checksum + calc_crc = crc32(0xffffffffL, (const unsigned char *)eeprom, sizeof(tlvinfo_header_t) + + be16_to_cpu(eeprom_hdr->totallen) - 4); + stored_crc = ((eeprom_crc->value[0] << 24) | (eeprom_crc->value[1] << 16) | + (eeprom_crc->value[2] << 8) | eeprom_crc->value[3]); + + return (calc_crc == stored_crc); +} + +/* + * tlvinfo_find_tlv + * + * This function finds the TLV with the supplied code in the EERPOM. + * An offset from the beginning of the EEPROM is returned in the + * eeprom_index parameter if the TLV is found. + */ +static bool tlvinfo_find_tlv(u_int8_t *eeprom, u_int8_t tcode, int *eeprom_index) +{ + tlvinfo_header_t *eeprom_hdr; + tlvinfo_tlv_t *eeprom_tlv; + int eeprom_end; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + + // Search through the TLVs, looking for the first one which matches the + // supplied type code. + *eeprom_index = sizeof(tlvinfo_header_t); + eeprom_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen); + while (*eeprom_index < eeprom_end) { + eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[*eeprom_index]; + if (!is_valid_tlv(eeprom_tlv)) { + return false; + } + + if (eeprom_tlv->type == tcode) { + return true; + } + + *eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length; + } + + return false; +} + +/* + * tlvinfo_decode_tlv + * + * This function finds the TLV with the supplied code in the EERPOM + * and decodes the value into the buffer provided. + */ +static bool tlvinfo_decode_tlv(u_int8_t *eeprom, u_int8_t tcode, tlv_decode_value_t *decode_value) +{ + int eeprom_index; + tlvinfo_tlv_t *eeprom_tlv; + + // Find the TLV and then decode it + if (tlvinfo_find_tlv(eeprom, tcode, &eeprom_index)) { + eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index]; + decode_tlv_value(eeprom_tlv, decode_value); + return true; + } + + return false; +} + +/* + * parse_tlv_eeprom + * + * parse the EEPROM into memory, if it hasn't already been read. + */ +int parse_tlv_eeprom(u_int8_t *eeprom, u_int32_t size) +{ + unsigned int i; + bool ret; + tlvinfo_header_t *eeprom_hdr; + //tlv_info_vec_t tlv_info; + tlv_decode_value_t decode_value; + int j; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + eeprom_size = size; /* eeprom real size */ + + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + DBG_ERROR("Failed to check tlv header.\n"); + return -1; + } + + if (!is_checksum_valid(eeprom)) { + DBG_ERROR("Failed to check tlv crc.\n"); + return -1; + } + + for (i = 0; i < TLV_CODE_NUM; i++) { + mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t)); + ret = tlvinfo_decode_tlv(eeprom, tlv_code_list[i].m_code, &decode_value); + if (!ret) { + DBG_ERROR("No found type: %s\n", tlv_code_list[i].m_name); + continue; + } + + DBG_DEBUG("i: %d,Found type: %s tlv[%d]:%s\n", i, tlv_code_list[i].m_name, tlv_code_list[i].m_code, + decode_value.value); + for (j = 0; j < decode_value.length; j++) { + if ((j % 16) == 0) { + DBG_DEBUG("\n"); + } + DBG_DEBUG("%02x ", decode_value.value[j]); + } + DBG_DEBUG("\n\n"); + } + return 0; +} +static int dfd_parse_tlv_eeprom(u_int8_t *eeprom, u_int32_t size, u_int8_t main_type, tlv_decode_value_t *decode_value) +{ + bool ret; + tlvinfo_header_t *eeprom_hdr; + //tlv_info_vec_t tlv_info; + int j; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + eeprom_size = size; /* eeprom real size */ + + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + DBG_ERROR("Failed to check tlv header.\n"); + return -1; + } + + if (!is_checksum_valid(eeprom)) { + DBG_ERROR("Failed to check tlv crc.\n"); + return -1; + } + + ret = tlvinfo_decode_tlv(eeprom, main_type, decode_value); + if (!ret) { + DBG_ERROR("No found type: %d\n", main_type); + return -1; + } + + DBG_DEBUG("Found type: %d, value: %s\n", main_type,decode_value->value); + for (j = 0; j < decode_value->length; j++) { + if ((j % 16) == 0) { + DBG_DEBUG("\n"); + } + DBG_DEBUG("%02x ", decode_value->value[j]); + } + DBG_DEBUG("\n\n"); + + return 0; +} + +static int tlvinfo_find_wb_ext_tlv(tlv_decode_value_t *ext_tlv_value, u_int8_t ext_type, + u_int8_t *buf, u_int8_t *buf_len) +{ + tlvinfo_tlv_t *eeprom_tlv; + int eeprom_end, eeprom_index; + + // Search through the TLVs, looking for the first one which matches the + // supplied type code. + DBG_DEBUG("ext_tlv_value->length: %d.\n", ext_tlv_value->length); + for (eeprom_index = 0; eeprom_index < ext_tlv_value->length; eeprom_index++) { + if ((eeprom_index % 16) == 0) { + DBG_DEBUG("\n"); + } + DBG_DEBUG("%02x ", ext_tlv_value->value[eeprom_index]); + } + + DBG_DEBUG("\n"); + + eeprom_index = 0; + eeprom_end = ext_tlv_value->length; + while (eeprom_index < eeprom_end) { + eeprom_tlv = (tlvinfo_tlv_t *) &(ext_tlv_value->value[eeprom_index]); + if (!is_valid_tlv(eeprom_tlv)) { + DBG_ERROR("tlv is not valid, eeprom_tlv->type 0x%x.\n", eeprom_tlv->type); + return -1; + } + + DBG_DEBUG("eeprom_tlv->length %d.\n", eeprom_tlv->length); + if (eeprom_tlv->type == ext_type) { + if (*buf_len >= eeprom_tlv->length) { + memcpy(buf, eeprom_tlv->value, eeprom_tlv->length); + DBG_DEBUG("eeprom_tlv->length %d.\n", eeprom_tlv->length); + *buf_len = eeprom_tlv->length; + return 0; + } + DBG_ERROR("buf_len %d small than info_len %d.\n", *buf_len, eeprom_tlv->length); + return -1; + } + + eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length; + } + + DBG_ERROR("ext_type %d: tlv is not found.\n", ext_type); + return -1; +} + +int dfd_tlvinfo_get_e2prom_info(u_int8_t *eeprom, u_int32_t size, dfd_tlv_type_t *tlv_type, u_int8_t* buf, u_int8_t *buf_len) +{ + tlv_decode_value_t decode_value; + int ret; + + if (eeprom == NULL || tlv_type == NULL || buf == NULL) { + DBG_ERROR("Input para invalid.\n"); + return -1; + } + + mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t)); + ret = dfd_parse_tlv_eeprom(eeprom, size, tlv_type->main_type, &decode_value); + if (ret) { + DBG_ERROR("dfd_parse_tlv_eeprom failed ret %d.\n", ret); + return ret; + } + + if (tlv_type->main_type != TLV_CODE_VENDOR_EXT) { + if (*buf_len >= decode_value.length) { + memcpy(buf, decode_value.value, decode_value.length); + *buf_len = decode_value.length; + return 0; + } + DBG_ERROR("buf_len %d small than info_len %d.\n", *buf_len, decode_value.length); + return -1; + } + DBG_DEBUG("info_len %d.\n", decode_value.length); + + return tlvinfo_find_wb_ext_tlv(&decode_value, tlv_type->ext_type, buf, buf_len); +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.h new file mode 100644 index 000000000000..6eaac5848223 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/dfd_tlveeprom.h @@ -0,0 +1,121 @@ +#ifndef DFD_OPENBMC_TLVEEPROM_H +#define DFD_OPENBMC_TLVEEPROM_H + +#ifndef u_int8_t +#define u_int8_t unsigned char +#endif + +#ifndef u_int16_t +#define u_int16_t unsigned short +#endif + +#ifndef u_int32_t +#define u_int32_t unsigned int +#endif + +#ifndef be16_to_cpu +#define be16_to_cpu(x) ntohs(x) +#endif + +#ifndef cpu_to_be16 +#define cpu_to_be16(x) htons(x) +#endif + +/** + * The TLV Types. + * + * Keep these in sync with tlv_code_list in cmd_sys_eeprom.c + */ +#define TLV_CODE_PRODUCT_NAME 0x21 +#define TLV_CODE_PART_NUMBER 0x22 +#define TLV_CODE_SERIAL_NUMBER 0x23 +#define TLV_CODE_MAC_BASE 0x24 +#define TLV_CODE_MANUF_DATE 0x25 +#define TLV_CODE_DEVICE_VERSION 0x26 +#define TLV_CODE_LABEL_REVISION 0x27 +#define TLV_CODE_PLATFORM_NAME 0x28 +#define TLV_CODE_ONIE_VERSION 0x29 +#define TLV_CODE_MAC_SIZE 0x2A +#define TLV_CODE_MANUF_NAME 0x2B +#define TLV_CODE_MANUF_COUNTRY 0x2C +#define TLV_CODE_VENDOR_NAME 0x2D +#define TLV_CODE_DIAG_VERSION 0x2E +#define TLV_CODE_SERVICE_TAG 0x2F +#define TLV_CODE_VENDOR_EXT 0xFD +#define TLV_CODE_CRC_32 0xFE + +#define TLV_CODE_NAME_LEN 64 +/* + * Struct for displaying the TLV codes and names. + */ +struct tlv_code_desc { + u_int8_t m_code; + char m_name[TLV_CODE_NAME_LEN]; +}; + +typedef struct dfd_tlv_type_s { + u_int8_t main_type; + u_int8_t ext_type; +} dfd_tlv_type_t; + +// Header Field Constants +#define TLV_INFO_ID_STRING "TlvInfo" +#define TLV_INFO_VERSION 0x01 +/*#define TLV_TOTAL_LEN_MAX (XXXXXXXX - sizeof(tlvinfo_header_t))*/ + +struct __attribute__ ((__packed__)) tlvinfo_header_s { + char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */ + u_int8_t version; /* 0x08 Structure version */ + u_int16_t totallen; /* 0x09 - 0x0A Length of all data which follows */ +}; +typedef struct tlvinfo_header_s tlvinfo_header_t; + +/* + * TlvInfo TLV: Layout of a TLV field + */ +struct __attribute__ ((__packed__)) tlvinfo_tlv_s { + u_int8_t type; + u_int8_t length; + u_int8_t value[0]; +}; +typedef struct tlvinfo_tlv_s tlvinfo_tlv_t; + +#define TLV_VALUE_MAX_LEN 255 +/* + * The max decode value is currently for the 'raw' type or the 'vendor + * extension' type, both of which have the same decode format. The + * max decode string size is computed as follows: + * + * strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1 + * + */ +#define TLV_DECODE_VALUE_MAX_LEN ((5 * TLV_VALUE_MAX_LEN) + 1) + +typedef struct tlv_decode_value_s { + u_int8_t value[TLV_DECODE_VALUE_MAX_LEN]; + u_int32_t length; +} tlv_decode_value_t; + +typedef enum dfd_tlvinfo_ext_tlv_type_e { + DFD_TLVINFO_EXT_TLV_TYPE_DEV_TYPE = 1, +} dfd_tlvinfo_ext_tlv_type_t; + +#if 0 +#define TLV_TIME_LEN 64 + +int ipmi_tlv_validate_fru_area(const uint8_t fruid, const char *fru_file_name, + sd_bus *bus_type, const bool bmc_fru); + +extern const char *get_vpd_key_names(int key_id); +extern std::string getService(sdbusplus::bus::bus& bus, + const std::string& intf, + const std::string& path); +extern std::string getFRUValue(const std::string& section, + const std::string& key, + const std::string& delimiter, + IPMIFruInfo& fruData); +#endif + +int dfd_tlvinfo_get_e2prom_info(u_int8_t *eeprom, u_int32_t size, dfd_tlv_type_t *tlv_type, u_int8_t* buf, u_int8_t *buf_len); + +#endif /* endif DFD_OPENBMC_TLVEEPROM_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c.h new file mode 100644 index 000000000000..649a8452debe --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c.h @@ -0,0 +1,133 @@ +#ifndef _FPGA_I2C_H +#define _FPGA_I2C_H + +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#if 0 + +#define FPGA_I2C_EXT_9548_ADDR (0x00) +#define FPGA_I2C_EXT_9548_CHAN (0x04) +#define FPGA_I2C_DEV_SLAVE_ADDR (0x08) +#define FPGA_I2C_DEV_REG_ADDR (0x0C) +#define FPGA_I2C_DEV_RDWR_LEN (0x10) +#define FPGA_I2C_CTRL_REG (0x14) +#define FPGA_I2C_STATUS_REG (0x18) +#define FPGA_I2C_SCALE_REG (0x1C) +#define FPGA_I2C_FILTER_REG (0x20) +#define FPGA_I2C_STRETCH_REG (0x24) +#define FPGA_I2C_EXT_9548_EXITS_FLAG (0x28) +#define FPGA_I2C_INTERNAL_9548_CHAN (0x2C) +#define FPGA_I2C_RDWR_DATA_BUF (0x80) +#endif +#define FPGA_I2C_RDWR_MAX_LEN_DEFAULT (128) +#define I2C_REG_MAX_WIDTH (16) + +#define DEV_NAME_MAX_LEN (64) + +#define FPGA_I2C_MAX_TIMES (10) +#define FPGA_I2C_XFER_TIME_OUT (100000) +#define FPGA_I2C_SLEEP_TIME (40) + +typedef struct fpga_i2c_reg_s { + uint32_t i2c_scale; + uint32_t i2c_filter; + uint32_t i2c_stretch; + uint32_t i2c_ext_9548_exits_flag; + uint32_t i2c_ext_9548_addr; + uint32_t i2c_ext_9548_chan; + uint32_t i2c_in_9548_chan; + uint32_t i2c_slave; + uint32_t i2c_reg; + uint32_t i2c_reg_len; + uint32_t i2c_data_len; + uint32_t i2c_ctrl; + uint32_t i2c_status; + uint32_t i2c_err_vec; + uint32_t i2c_data_buf; + uint32_t i2c_data_buf_len; +} fpga_i2c_reg_t; + +typedef struct fpga_i2c_reset_cfg_s { + uint32_t i2c_adap_reset_flag; + uint32_t reset_addr; + uint32_t reset_on; + uint32_t reset_off; + uint32_t reset_delay_b; + uint32_t reset_delay; + uint32_t reset_delay_a; +} fpga_i2c_reset_cfg_t; + +typedef struct fpga_i2c_reg_addr_s { + uint8_t reg_addr_len; + uint8_t read_reg_addr[I2C_REG_MAX_WIDTH]; +} fpga_i2c_reg_addr_t; + +typedef struct fpga_i2c_dev_s { + fpga_i2c_reg_t reg; + fpga_i2c_reset_cfg_t reset_cfg; + fpga_i2c_reg_addr_t i2c_addr_desc; + const char *dev_name; + uint32_t i2c_scale_value; + uint32_t i2c_filter_value; + uint32_t i2c_stretch_value; + uint32_t i2c_timeout; + uint32_t i2c_func_mode; + wait_queue_head_t queue; + struct i2c_adapter adap; + int adap_nr; + struct device *dev; + bool i2c_params_check; +} fpga_i2c_dev_t; + +typedef struct fpga_i2c_bus_device_s { + int i2c_timeout; + int i2c_scale; + int i2c_filter; + int i2c_stretch; + int i2c_ext_9548_exits_flag; + int i2c_ext_9548_addr; + int i2c_ext_9548_chan; + int i2c_in_9548_chan; + int i2c_slave; + int i2c_reg; + int i2c_reg_len; + int i2c_data_len; + int i2c_ctrl; + int i2c_status; + int i2c_err_vec; + int i2c_data_buf; + int i2c_data_buf_len; + char dev_name[DEV_NAME_MAX_LEN]; + int adap_nr; + int i2c_scale_value; + int i2c_filter_value; + int i2c_stretch_value; + int i2c_func_mode; + int i2c_adap_reset_flag; + int i2c_reset_addr; + int i2c_reset_on; + int i2c_reset_off; + int i2c_rst_delay_b; /* delay time before reset(us) */ + int i2c_rst_delay; /* reset time(us) */ + int i2c_rst_delay_a; /* delay time after reset(us) */ + int device_flag; + bool i2c_params_check; + int i2c_data_buf_len_reg; + int i2c_offset_reg; +} fpga_i2c_bus_device_t; + +typedef struct fpga_pca954x_device_s { + struct i2c_client *client; + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t fpga_9548_flag; + uint32_t fpga_9548_reset_flag; + uint32_t pca9548_base_nr; +} fpga_pca954x_device_t; + +#endif /* _FPGA_I2C_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c_ocores.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c_ocores.c deleted file mode 100755 index 81068a14029e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c_ocores.c +++ /dev/null @@ -1,906 +0,0 @@ -/* - * i2c-ocores.c: I2C bus driver for OpenCores I2C controller - * (http://www.opencores.org/projects.cgi/web/i2c/overview). - * - * Peter Korsgaard - * - * Support for the GRLIB port of the controller by - * Andreas Larsson - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -struct ocores_i2c { - void __iomem *base; - u32 reg_shift; - u32 reg_io_width; - wait_queue_head_t wait; - struct i2c_adapter adap; - struct i2c_msg *msg; - int pos; - int nmsgs; - int state; /* see STATE_ */ - spinlock_t process_lock; - struct mutex xfer_lock; - int clock_khz; - void (*setreg)(struct ocores_i2c *i2c, int reg, u8 value); - u8 (*getreg)(struct ocores_i2c *i2c, int reg); -}; - -/* registers */ -#define OCI2C_PRELOW 0x0 -#define OCI2C_PREHIGH 0x4 -#define OCI2C_CONTROL 0x8 -#define OCI2C_DATA 0xc -#define OCI2C_CMD 0x10 /* write only */ -#define OCI2C_STATUS 0x10 /* read only, same address as OCI2C_CMD */ - -#define OCI2C_TRAN_REV 0x14 -#define OCI2C_CMD_REV 0x18 - - -#define OCI2C_CTRL_IEN 0x40 -#define OCI2C_CTRL_EN 0x80 - -#define OCI2C_CMD_START 0x91 -#define OCI2C_CMD_STOP 0x41 -#define OCI2C_CMD_READ 0x21 -#define OCI2C_CMD_WRITE 0x11 -#define OCI2C_CMD_READ_ACK 0x21 -#define OCI2C_CMD_READ_NACK 0x29 -#define OCI2C_CMD_IACK 0x01 - -#define OCI2C_STAT_IF 0x01 -#define OCI2C_STAT_TIP 0x02 -#define OCI2C_STAT_ARBLOST 0x20 -#define OCI2C_STAT_BUSY 0x40 -#define OCI2C_STAT_NACK 0x80 - -#define STATE_DONE 0 -#define STATE_START 1 -#define STATE_WRITE 2 -#define STATE_READ 3 -#define STATE_ERROR 4 - -#define TYPE_OCORES 0 -#define TYPE_GRLIB 1 - -#define BUF_SIZE 256 -#define DEFAULT_I2C_SCL 100 -#define DEFAULT_I2C_PRE 0xF9 - -int g_fpga_i2c_debug = 0; -int g_fpga_i2c_irq = 0; -int g_fpga_i2c_error = 0; -int g_irq_dump_debug = 0; -int g_irq_invalid_cnt = 0; -int g_fpga_debug = 0; - -module_param(g_fpga_i2c_debug, int, S_IRUGO | S_IWUSR); -module_param(g_fpga_i2c_error, int, S_IRUGO | S_IWUSR); -module_param(g_fpga_i2c_irq, int, S_IRUGO | S_IWUSR); -module_param(g_irq_dump_debug, int, S_IRUGO | S_IWUSR); -module_param(g_irq_invalid_cnt, int, S_IRUGO | S_IWUSR); -module_param(g_fpga_debug, int, S_IRUGO | S_IWUSR); - -#define FPGA_I2C_DEBUG(fmt, args...) do { \ - if (g_fpga_debug) { \ - printk(KERN_DEBUG ""fmt, ## args); \ - } \ -} while (0) - -#define FPGA_I2C_DEBUG_DUMP(fmt, args...) do { \ - if (g_irq_dump_debug) { \ - printk(KERN_ERR ""fmt, ## args); \ - } \ -} while (0) - -#define FPGA_I2C_DEBUG_XFER(fmt, args...) do { \ - if (g_fpga_i2c_irq) { \ - printk(KERN_ERR "[FPGA_I2C][XFER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define FPGA_I2C_DEBUG_VERBOSE(fmt, args...) do { \ - if (g_fpga_i2c_debug) { \ - printk(KERN_ERR "[FPGA_I2C][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define FPGA_I2C_DEBUG_ERROR(fmt, args...) do { \ - if (g_fpga_i2c_error) { \ - printk(KERN_ERR "[FPGA_I2C][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -static int check_ocores_i2c(struct i2c_msg *msgs, int num); -static void oc_debug_dump_reg(struct ocores_i2c *i2c); -static void oc_debug_dump_reg_dump(struct ocores_i2c *i2c); -static int oc_set_scl_clk(struct ocores_i2c *i2c, int val); - -static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u8 value) -{ - iowrite8(value, i2c->base + (reg << i2c->reg_shift)); -} - -static void oc_setreg_16(struct ocores_i2c *i2c, int reg, u8 value) -{ - iowrite16(value, i2c->base + (reg << i2c->reg_shift)); -} - -static void oc_setreg_32(struct ocores_i2c *i2c, int reg, u8 value) -{ - iowrite32(value, i2c->base + (reg << i2c->reg_shift)); -} - -static inline u8 oc_getreg_8(struct ocores_i2c *i2c, int reg) -{ - return ioread8(i2c->base + (reg << i2c->reg_shift)); -} - -static inline u8 oc_getreg_16(struct ocores_i2c *i2c, int reg) -{ - return ioread16(i2c->base + (reg << i2c->reg_shift)); -} - -static inline u8 oc_getreg_32(struct ocores_i2c *i2c, int reg) -{ - return ioread32(i2c->base + (reg << i2c->reg_shift)); -} - -static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) -{ - i2c->setreg(i2c, reg, value); -} - -static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) -{ - return i2c->getreg(i2c, reg); -} - -#define FPGA_I2C_SPIN_LOCK(lock, flags) spin_lock_irqsave(&(lock), (flags)) -#define FPGA_I2C_SPIN_UNLOCK(lock, flags) spin_unlock_irqrestore(&(lock), (flags)) -#define FPGA_I2C_MUTEX_LOCK(lock) mutex_lock(&(lock)) -#define FPGA_I2C_MUTEX_UNLOCK(lock) mutex_unlock(&(lock)) - -static void ocores_process(struct ocores_i2c *i2c, u8 stat) -{ - struct i2c_msg *msg = i2c->msg; - - FPGA_I2C_DEBUG_XFER("Enter nr %d.\n", i2c->adap.nr); - if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { - /* stop has been sent */ - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); - wake_up(&i2c->wait); - FPGA_I2C_DEBUG_XFER("stop has been sent, exit.\n"); - goto out; - } - - FPGA_I2C_DEBUG_XFER("Enter 111.\n"); - - /* error */ - if (stat & OCI2C_STAT_ARBLOST) { - i2c->state = STATE_ERROR; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - FPGA_I2C_DEBUG_XFER("error, exit.\n"); - goto out; - } - - FPGA_I2C_DEBUG_XFER("Enter 222.\n"); - - if (check_ocores_i2c(i2c->msg, i2c->nmsgs) != 0) { - FPGA_I2C_DEBUG("i2c->msg->buf is null, i2c->state:%d exit.\n", i2c->state); - oc_debug_dump_reg_dump(i2c); - i2c->state = STATE_ERROR; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - goto out; - } - - if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { - i2c->state = - (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; - - if (stat & OCI2C_STAT_NACK) { - i2c->state = STATE_ERROR; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - FPGA_I2C_DEBUG_XFER("OCI2C_STAT_NACK, exit.\n"); - goto out; - } - } else { - msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); - } - FPGA_I2C_DEBUG_XFER("Enter 333.\n"); - - /* end of msg? */ - if (i2c->pos == msg->len) { - FPGA_I2C_DEBUG_XFER("Enter end of msg.\n"); - i2c->nmsgs--; - i2c->msg++; - i2c->pos = 0; - msg = i2c->msg; - - if (i2c->nmsgs) { /* end? */ - /* send start? */ - if (!(msg->flags & I2C_M_NOSTART)) { - u8 addr = (msg->addr << 1); - - if (msg->flags & I2C_M_RD) - addr |= 1; - - i2c->state = STATE_START; - - oc_setreg(i2c, OCI2C_DATA, addr); - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); - FPGA_I2C_DEBUG_XFER("send start, exit.\n"); - goto out; - } - - i2c->state = (msg->flags & I2C_M_RD) - ? STATE_READ : STATE_WRITE; - } else { - i2c->state = STATE_DONE; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - FPGA_I2C_DEBUG_XFER("send OCI2C_CMD_STOP, exit.\n"); - goto out; - } - } - - if (i2c->state == STATE_READ) { - oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? - OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); - } else { - oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); - } - -out: - FPGA_I2C_DEBUG_XFER("normal, exit nr %d.\n", i2c->adap.nr); -} - -static irqreturn_t ocores_isr(int irq, void *dev_id) -{ - struct ocores_i2c *i2c = dev_id; - unsigned long flags; - u8 stat; - - if (!i2c) { - return IRQ_NONE; - } - /* - * If we spin here is because we are in timeout, so we are going - * to be in STATE_ERROR. See ocores_process_timeout() - */ - FPGA_I2C_SPIN_LOCK(i2c->process_lock, flags); - stat = oc_getreg(i2c, OCI2C_STATUS); - if (!(stat & OCI2C_STAT_IF)) { - g_irq_invalid_cnt++; - FPGA_I2C_SPIN_UNLOCK(i2c->process_lock, flags); - return IRQ_NONE; - } - - FPGA_I2C_DEBUG_XFER("Enter, irq %d nr %d addr 0x%x.\n", irq, i2c->adap.nr, (!i2c->msg)?0:i2c->msg->addr); - ocores_process(i2c, stat); - FPGA_I2C_DEBUG_XFER("Leave, irq %d nr %d addr 0x%x.\n", irq, i2c->adap.nr, (!i2c->msg)?0:i2c->msg->addr); - - FPGA_I2C_SPIN_UNLOCK(i2c->process_lock, flags); - return IRQ_HANDLED; -} - -/** - * Process timeout event - * @i2c: ocores I2C device instance - */ -static void ocores_process_timeout(struct ocores_i2c *i2c) -{ - unsigned long flags; - - FPGA_I2C_SPIN_LOCK(i2c->process_lock, flags); - FPGA_I2C_DEBUG_ERROR("wait_event_timeout i2c->state %d.\n", i2c->state); - oc_debug_dump_reg(i2c); - i2c->state = STATE_ERROR; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - mdelay(1); - FPGA_I2C_SPIN_UNLOCK(i2c->process_lock, flags); -} - -static int check_ocores_i2c(struct i2c_msg *msgs, int num) -{ - int i; - if (!msgs) { - return -1; - } - for (i = 0; i < num; ++i) { - if (!msgs[i].buf) { - return -1; - } - } - return 0; -} - -static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) -{ - struct ocores_i2c *i2c; - int ret; - unsigned long flags; - int xfer_ret; - - if (!adap || check_ocores_i2c(msgs, num) != 0) { - FPGA_I2C_DEBUG("msgs: %p , num:%d exit.\n", msgs, num); - return -EINVAL; - } - i2c = i2c_get_adapdata(adap); - - FPGA_I2C_MUTEX_LOCK(i2c->xfer_lock); - FPGA_I2C_SPIN_LOCK(i2c->process_lock, flags); - i2c->msg = msgs; - i2c->pos = 0; - i2c->nmsgs = num; - i2c->state = STATE_START; - FPGA_I2C_DEBUG_XFER("Enter, nr %d addr 0x%x num %d.\n", adap->nr, i2c->msg->addr, num); - - oc_setreg(i2c, OCI2C_DATA, - (i2c->msg->addr << 1) | - ((i2c->msg->flags & I2C_M_RD) ? 1:0)); - - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); - FPGA_I2C_DEBUG_XFER("After, oc_setreg OCI2C_CMD.\n"); - FPGA_I2C_SPIN_UNLOCK(i2c->process_lock, flags); - - ret = wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || - (i2c->state == STATE_DONE), HZ); - - if (ret == 0) { - ocores_process_timeout(i2c); - FPGA_I2C_MUTEX_UNLOCK(i2c->xfer_lock); - return -ETIMEDOUT; - } - xfer_ret = i2c->state; - FPGA_I2C_MUTEX_UNLOCK(i2c->xfer_lock); - return (xfer_ret == STATE_DONE) ? num : -EIO; -} - -static void ocores_init(struct ocores_i2c *i2c) -{ - int prescale; - u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); - - mutex_init(&i2c->xfer_lock); - spin_lock_init(&i2c->process_lock); - - /* make sure the device is disabled */ - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); - - prescale = oc_set_scl_clk(i2c, DEFAULT_I2C_SCL); - FPGA_I2C_DEBUG_VERBOSE("i2c->base 0x%p, i2c->clock_khz %d, prescale 0x%x.\n", i2c->base, i2c->clock_khz, prescale); - - /* Init the device */ - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); - oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN); -} - - -static u32 ocores_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static const struct i2c_algorithm ocores_algorithm = { - .master_xfer = ocores_xfer, - .functionality = ocores_func, -}; - -static struct i2c_adapter ocores_adapter = { - .owner = THIS_MODULE, - .name = "rg-i2c-ocores", - .class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED, - .algo = &ocores_algorithm, -}; - -static const struct of_device_id ocores_i2c_match[] = { - { - .compatible = "opencores,rg-i2c-ocores", - .data = (void *)TYPE_OCORES, - }, - { - .compatible = "aeroflexgaisler,i2cmst", - .data = (void *)TYPE_GRLIB, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, ocores_i2c_match); - -#ifdef CONFIG_OF -/* Read and write functions for the GRLIB port of the controller. Registers are - * 32-bit big endian and the PRELOW and PREHIGH registers are merged into one - * register. The subsequent registers has their offset decreased accordingly. */ -static u8 oc_getreg_grlib(struct ocores_i2c *i2c, int reg) -{ - u32 rd; - int rreg = reg; - if (reg != OCI2C_PRELOW) - rreg--; - rd = ioread32be(i2c->base + (rreg << i2c->reg_shift)); - if (reg == OCI2C_PREHIGH) - return (u8)(rd >> 8); - else - return (u8)rd; -} - -static void oc_setreg_grlib(struct ocores_i2c *i2c, int reg, u8 value) -{ - u32 curr, wr; - int rreg = reg; - if (reg != OCI2C_PRELOW) - rreg--; - if (reg == OCI2C_PRELOW || reg == OCI2C_PREHIGH) { - curr = ioread32be(i2c->base + (rreg << i2c->reg_shift)); - if (reg == OCI2C_PRELOW) - wr = (curr & 0xff00) | value; - else - wr = (((u32)value) << 8) | (curr & 0xff); - } else { - wr = value; - } - iowrite32be(wr, i2c->base + (rreg << i2c->reg_shift)); -} - -static int ocores_i2c_of_probe(struct platform_device *pdev, - struct ocores_i2c *i2c) -{ - struct device_node *np = pdev->dev.of_node; - const struct of_device_id *match; - u32 val; - - if (of_property_read_u32(np, "reg-shift", &i2c->reg_shift)) { - /* no 'reg-shift', check for deprecated 'regstep' */ - if (!of_property_read_u32(np, "regstep", &val)) { - if (!is_power_of_2(val)) { - dev_err(&pdev->dev, "invalid regstep %d\n", - val); - return -EINVAL; - } - i2c->reg_shift = ilog2(val); - dev_warn(&pdev->dev, - "regstep property deprecated, use reg-shift\n"); - } - } - - if (of_property_read_u32(np, "clock-frequency", &val)) { - dev_err(&pdev->dev, - "Missing required parameter 'clock-frequency'\n"); - return -ENODEV; - } - i2c->clock_khz = val / 1000; - - of_property_read_u32(pdev->dev.of_node, "reg-io-width", - &i2c->reg_io_width); - - match = of_match_node(ocores_i2c_match, pdev->dev.of_node); - if (match && (long)match->data == TYPE_GRLIB) { - dev_dbg(&pdev->dev, "GRLIB variant of i2c-ocores\n"); - i2c->setreg = oc_setreg_grlib; - i2c->getreg = oc_getreg_grlib; - } - - return 0; -} -#else -#define ocores_i2c_of_probe(pdev,i2c) -ENODEV -#endif - - -static void oc_debug_dump_reg_dump(struct ocores_i2c *i2c) -{ - if (i2c) { - FPGA_I2C_DEBUG("base: %p.\n", i2c->base); - FPGA_I2C_DEBUG("reg_shift: %d.\n", i2c->reg_shift); - FPGA_I2C_DEBUG("reg_io_width: %d.\n", i2c->reg_io_width); - FPGA_I2C_DEBUG("adap.nr: %d.\n", i2c->adap.nr); - FPGA_I2C_DEBUG("msg: %p.\n", i2c->msg); - if (i2c->msg) { - FPGA_I2C_DEBUG("msg->buf: %p.\n", i2c->msg->buf); - FPGA_I2C_DEBUG("msg->addr: 0x%x.\n", i2c->msg->addr); - FPGA_I2C_DEBUG("msg->flags: 0x%x.\n", i2c->msg->flags); - FPGA_I2C_DEBUG("msg->len: %d.\n", i2c->msg->len); - } else { - FPGA_I2C_DEBUG("msg: %p is null.\n", i2c->msg); - } - - FPGA_I2C_DEBUG("pos: %d.\n", i2c->pos); - FPGA_I2C_DEBUG("nmsgs: %d.\n", i2c->nmsgs); - FPGA_I2C_DEBUG("state: %d.\n", i2c->state); - FPGA_I2C_DEBUG("clock_khz: %d.\n", i2c->clock_khz); - FPGA_I2C_DEBUG("setreg: %p.\n", i2c->setreg); - FPGA_I2C_DEBUG("getreg: %p.\n", i2c->getreg); - if (i2c->getreg) { - FPGA_I2C_DEBUG("OCI2C_PRELOW: 0x%02x.\n", oc_getreg(i2c, OCI2C_PRELOW)); - FPGA_I2C_DEBUG("OCI2C_PREHIGH: 0x%02x.\n", oc_getreg(i2c, OCI2C_PREHIGH)); - FPGA_I2C_DEBUG("OCI2C_CONTROL: 0x%02x.\n", oc_getreg(i2c, OCI2C_CONTROL)); - FPGA_I2C_DEBUG("OCI2C_DATA: 0x%02x.\n", oc_getreg(i2c, OCI2C_DATA)); - FPGA_I2C_DEBUG("OCI2C_CMD: 0x%02x.\n", oc_getreg(i2c, OCI2C_CMD)); - FPGA_I2C_DEBUG("OCI2C_STATUS: 0x%02x.\n", oc_getreg(i2c, OCI2C_STATUS)); - } else { - FPGA_I2C_DEBUG("getreg: %p is null.\n", i2c->getreg); - } - } else { - FPGA_I2C_DEBUG("i2c %p is null.\n", i2c); - } -} - - -static void oc_debug_dump_reg(struct ocores_i2c *i2c) -{ - if (i2c) { - FPGA_I2C_DEBUG_DUMP("base: %p.\n", i2c->base); - FPGA_I2C_DEBUG_DUMP("reg_shift: %d.\n", i2c->reg_shift); - FPGA_I2C_DEBUG_DUMP("reg_io_width: %d.\n", i2c->reg_io_width); - FPGA_I2C_DEBUG_DUMP("adap.nr: %d.\n", i2c->adap.nr); - FPGA_I2C_DEBUG_DUMP("msg: %p.\n", i2c->msg); - if (i2c->msg) { - FPGA_I2C_DEBUG_DUMP("msg->buf: %p.\n", i2c->msg->buf); - FPGA_I2C_DEBUG_DUMP("msg->addr: 0x%x.\n", i2c->msg->addr); - FPGA_I2C_DEBUG_DUMP("msg->flags: 0x%x.\n", i2c->msg->flags); - FPGA_I2C_DEBUG_DUMP("msg->len: %d.\n", i2c->msg->len); - } else { - FPGA_I2C_DEBUG_DUMP("msg: %p is null.\n", i2c->msg); - } - - FPGA_I2C_DEBUG_DUMP("pos: %d.\n", i2c->pos); - FPGA_I2C_DEBUG_DUMP("nmsgs: %d.\n", i2c->nmsgs); - FPGA_I2C_DEBUG_DUMP("state: %d.\n", i2c->state); - FPGA_I2C_DEBUG_DUMP("clock_khz: %d.\n", i2c->clock_khz); - FPGA_I2C_DEBUG_DUMP("setreg: %p.\n", i2c->setreg); - FPGA_I2C_DEBUG_DUMP("getreg: %p.\n", i2c->getreg); - if (i2c->getreg) { - FPGA_I2C_DEBUG_DUMP("OCI2C_PRELOW: 0x%02x.\n", oc_getreg(i2c, OCI2C_PRELOW)); - FPGA_I2C_DEBUG_DUMP("OCI2C_PREHIGH: 0x%02x.\n", oc_getreg(i2c, OCI2C_PREHIGH)); - FPGA_I2C_DEBUG_DUMP("OCI2C_CONTROL: 0x%02x.\n", oc_getreg(i2c, OCI2C_CONTROL)); - FPGA_I2C_DEBUG_DUMP("OCI2C_DATA: 0x%02x.\n", oc_getreg(i2c, OCI2C_DATA)); - FPGA_I2C_DEBUG_DUMP("OCI2C_CMD: 0x%02x.\n", oc_getreg(i2c, OCI2C_CMD)); - FPGA_I2C_DEBUG_DUMP("OCI2C_STATUS: 0x%02x.\n", oc_getreg(i2c, OCI2C_STATUS)); - } else { - FPGA_I2C_DEBUG_DUMP("getreg: %p is null.\n", i2c->getreg); - } - } else { - FPGA_I2C_DEBUG_DUMP("i2c %p is null.\n", i2c); - } -} - -void oc_debug_dump_reg_exception(void) -{ - int bus_beg, bus_end, bus; - struct i2c_adapter *adap; - struct ocores_i2c *adap_data; - - bus_beg = 1; - bus_end = 14; - for (bus = bus_beg; bus <= bus_end; bus++) { - adap = i2c_get_adapter(bus); - if (adap) { - adap_data = (struct ocores_i2c *)i2c_get_adapdata(adap); - if (adap_data) { - FPGA_I2C_DEBUG_DUMP("bus %d call oc_debug_dump_reg begin.\n", bus); - oc_debug_dump_reg(adap_data); - FPGA_I2C_DEBUG_DUMP("bus %d call oc_debug_dump_reg end.\n", bus); - } else { - FPGA_I2C_DEBUG_DUMP("bus %d i2c_get_adapdata null.\n", bus); - } - i2c_put_adapter(adap); - } else { - FPGA_I2C_DEBUG_DUMP("bus %d i2c_get_adapter null.\n", bus); - } - } -} - -static int oc_calculate_prescale(struct ocores_i2c *i2c, int val) { - if (val <= 0) { - FPGA_I2C_DEBUG_ERROR("input scl clock error, set to default clock: %d.\n", val); - val = DEFAULT_I2C_SCL; - } - return (i2c->clock_khz / (5 * val)) - 1; -} - -static int oc_calculate_scl_clk(struct ocores_i2c *i2c, int prescale) { - if (prescale <= -1) { - FPGA_I2C_DEBUG_ERROR("input prescale error, set to default prescale: %d.\n", prescale); - prescale = DEFAULT_I2C_PRE; - } - return (i2c->clock_khz / (prescale + 1)) / 5; -} - -static int oc_set_scl_clk(struct ocores_i2c *i2c, int val) { - int prescale; - - prescale = oc_calculate_prescale(i2c, val); - oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); - oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); - return prescale; -} - -static int oc_get_scl_clk(struct ocores_i2c *i2c) { - int prescale, prescale_high, prescale_low; - - prescale_low = oc_getreg(i2c, OCI2C_PRELOW); - prescale_high = oc_getreg(i2c, OCI2C_PREHIGH); - prescale = (prescale_high << 8) + (prescale_low & 0xff); - - return oc_calculate_scl_clk(i2c, prescale); -} - -static ssize_t oc_sysfs_show_scl_clk(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct i2c_adapter *adapter; - struct ocores_i2c *i2c; - int scl_clk; - - adapter = to_i2c_adapter(dev); - i2c = (struct ocores_i2c *)i2c_get_adapdata(adapter); - scl_clk = oc_get_scl_clk(i2c); - return snprintf(buf, BUF_SIZE, "%d\n", scl_clk); -} - -static ssize_t oc_sysfs_set_scl_clk(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct i2c_adapter *adapter; - struct ocores_i2c *i2c; - int val; - int ret; - int prescale; - - adapter = to_i2c_adapter(dev); - i2c = (struct ocores_i2c *)i2c_get_adapdata(adapter); - ret = kstrtoint(buf, 0, &val); - if (ret) { - return ret; - } - FPGA_I2C_MUTEX_LOCK(i2c->xfer_lock); - prescale = oc_set_scl_clk(i2c, val); - FPGA_I2C_DEBUG_VERBOSE("i2c->base 0x%p, i2c->clock_khz %d, scl clk 0x%x.\n", i2c->base, i2c->clock_khz, prescale); - FPGA_I2C_MUTEX_UNLOCK(i2c->xfer_lock); - return count; -} -static ssize_t show_oc_debug_value(struct device *dev, struct device_attribute *da, char *buf) -{ - oc_debug_dump_reg_exception(); - return 0; -} - -static SENSOR_DEVICE_ATTR(oc_debug, S_IRUGO | S_IWUSR, show_oc_debug_value, NULL, 0x15); -static SENSOR_DEVICE_ATTR(oc_scl_clk, S_IRUGO | S_IWUSR, oc_sysfs_show_scl_clk, oc_sysfs_set_scl_clk, 0); - -static struct attribute *oc_debug_sysfs_attrs[] = { - &sensor_dev_attr_oc_debug.dev_attr.attr, - NULL -}; - -static struct attribute *oc_scl_clk_sysfs_attrs[] = { - &sensor_dev_attr_oc_scl_clk.dev_attr.attr, - NULL -}; - -static const struct attribute_group oc_debug_sysfs_group = { - .attrs = oc_debug_sysfs_attrs, -}; - -static const struct attribute_group oc_scl_clk_sysfs_group = { - .attrs = oc_scl_clk_sysfs_attrs, -}; - -static void oc_scl_clk_sysfs_init(struct i2c_adapter *adap) -{ - int ret; - - ret = sysfs_create_group(&adap->dev.kobj, &oc_scl_clk_sysfs_group); - FPGA_I2C_DEBUG_VERBOSE("sysfs_create_group ret %d.\n", ret); - return; -} - -static void oc_scl_clk_sysfs_exit(struct i2c_adapter *adap) -{ - sysfs_remove_group(&adap->dev.kobj, (const struct attribute_group *)&oc_scl_clk_sysfs_group); - FPGA_I2C_DEBUG_VERBOSE("sysfs_remove_group.\n"); - return; -} - -static void oc_debug_sysfs_init(struct platform_device *pdev) -{ - int ret; - - ret = sysfs_create_group(&pdev->dev.kobj, &oc_debug_sysfs_group); - FPGA_I2C_DEBUG_VERBOSE("sysfs_create_group ret %d.\n", ret); - return; -} - -static void oc_debug_sysfs_exit(struct platform_device *pdev) -{ - sysfs_remove_group(&pdev->dev.kobj, (const struct attribute_group *)&oc_debug_sysfs_group); - FPGA_I2C_DEBUG_VERBOSE("sysfs_remove_group.\n"); - return; -} - -static int rg_ocores_i2c_probe(struct platform_device *pdev) -{ - struct ocores_i2c *i2c; - struct rg_ocores_i2c_platform_data *pdata; - struct resource *res; - int irq; - int ret; - int i; - - FPGA_I2C_DEBUG_VERBOSE("Enter.\n"); - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - FPGA_I2C_DEBUG_ERROR("platform_get_irq failed irq %d.\n", irq); - return irq; - } - - i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); - if (!i2c) { - FPGA_I2C_DEBUG_ERROR("devm_kzalloc failed.\n"); - return -ENOMEM; - } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - i2c->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(i2c->base)) { - FPGA_I2C_DEBUG_ERROR("devm_ioremap_resource failed.\n"); - return PTR_ERR(i2c->base); - } - - pdata = dev_get_platdata(&pdev->dev); - if (pdata) { - i2c->reg_shift = pdata->reg_shift; - i2c->reg_io_width = pdata->reg_io_width; - i2c->clock_khz = pdata->clock_khz; - } else { - ret = ocores_i2c_of_probe(pdev, i2c); - if (ret) - return ret; - } - - if (i2c->reg_io_width == 0) - i2c->reg_io_width = 1; /* Set to default value */ - - - if (!i2c->setreg || !i2c->getreg) { - switch (i2c->reg_io_width) { - case 1: - i2c->setreg = oc_setreg_8; - i2c->getreg = oc_getreg_8; - break; - - case 2: - i2c->setreg = oc_setreg_16; - i2c->getreg = oc_getreg_16; - break; - - case 4: - i2c->setreg = oc_setreg_32; - i2c->getreg = oc_getreg_32; - break; - - default: - dev_err(&pdev->dev, "Unsupported I/O width (%d)\n", - i2c->reg_io_width); - return -EINVAL; - } - } - - ocores_init(i2c); - - init_waitqueue_head(&i2c->wait); - ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, - pdev->name, i2c); - if (ret) { - dev_err(&pdev->dev, "Cannot claim IRQ\n"); - return ret; - } - - /* hook up driver to tree */ - platform_set_drvdata(pdev, i2c); - i2c->adap = ocores_adapter; - if (pdata->nr) { - i2c->adap.nr = pdata->nr; - dev_info(&pdev->dev, "fpga ocores nr is (%d), irq %d \n", i2c->adap.nr, irq); - } - i2c_set_adapdata(&i2c->adap, i2c); - i2c->adap.dev.parent = &pdev->dev; - i2c->adap.dev.of_node = pdev->dev.of_node; - - /* add i2c adapter to i2c tree */ - ret = i2c_add_numbered_adapter(&i2c->adap); - if (ret) { - dev_err(&pdev->dev, "Failed to add adapter\n"); - return ret; - } - - /* add in known devices to the bus */ - if (pdata) { - for (i = 0; i < pdata->num_devices; i++) - i2c_new_device(&i2c->adap, pdata->devices + i); - } - - oc_debug_sysfs_init(pdev); - oc_scl_clk_sysfs_init(&i2c->adap); - return 0; -} - -static int rg_ocores_i2c_remove(struct platform_device *pdev) -{ - struct ocores_i2c *i2c = platform_get_drvdata(pdev); - - /* disable i2c logic */ - oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL) - & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); - - /* remove adapter & data */ - oc_scl_clk_sysfs_exit(&i2c->adap); - i2c_del_adapter(&i2c->adap); - oc_debug_sysfs_exit(pdev); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int ocores_i2c_suspend(struct device *dev) -{ - struct ocores_i2c *i2c = dev_get_drvdata(dev); - u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); - - /* make sure the device is disabled */ - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); - - return 0; -} - -static int ocores_i2c_resume(struct device *dev) -{ - struct ocores_i2c *i2c = dev_get_drvdata(dev); - - ocores_init(i2c); - - return 0; -} - -static SIMPLE_DEV_PM_OPS(ocores_i2c_pm, ocores_i2c_suspend, ocores_i2c_resume); -#define OCORES_I2C_PM (&ocores_i2c_pm) -#else -#define OCORES_I2C_PM NULL -#endif - -static struct platform_driver ocores_i2c_driver = { - .probe = rg_ocores_i2c_probe, - .remove = rg_ocores_i2c_remove, - .driver = { - .owner = THIS_MODULE, - .name = "rg-i2c-ocores", - .of_match_table = ocores_i2c_match, - .pm = OCORES_I2C_PM, - }, -}; - -module_platform_driver(ocores_i2c_driver); - -MODULE_AUTHOR("Peter Korsgaard "); -MODULE_DESCRIPTION("OpenCores I2C bus driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ocores-i2c"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c_ocores.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c_ocores.h deleted file mode 100755 index 1aedd7793c77..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_i2c_ocores.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _FPGA_I2C_OCORES_H -#define _FPGA_I2C_OCORES_H - -struct rg_ocores_i2c_platform_data { - u32 reg_shift; /* register offset shift value */ - u32 reg_io_width; /* register io read/write width */ - u32 clock_khz; /* input clock in kHz */ - u8 num_devices; /* number of devices in the devices list */ - struct i2c_board_info const *devices; /* devices connected to the bus */ - int nr; /* i2c bus num */ -}; - -#endif /* _FPGA_I2C_OCORES_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_pcie_i2c.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_pcie_i2c.c deleted file mode 100755 index 82ae9f558f50..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_pcie_i2c.c +++ /dev/null @@ -1,1144 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 15, 0) -#include -#else -#include -#endif -#include -#include -#include - - -#ifdef FPGA_PCIE_I2C_DEBUG -#include -#include -#include -#include -#include - -char *enum_log="/home/pciuio-log"; - -void filewrite(char* filename, char* data) -{ - struct file *filp; - mm_segment_t fs; - filp = filp_open(filename, O_RDWR|O_APPEND|O_CREAT, 0644); - if(IS_ERR(filp)) - { - printk("<0>""open file error...\n"); - return; - } - - fs=get_fs(); - set_fs(KERNEL_DS); - filp->f_op->write(filp, data, strlen(data),&filp->f_pos); - set_fs(fs); - filp_close(filp,NULL); -} - -void enum_time_log(char *log) -{ - struct timex txc; - struct rtc_time tm; - char time_str[64]; - int ret = 0; - - do_gettimeofday(&(txc.time)); - rtc_time_to_tm(txc.time.tv_sec,&tm); - memset(time_str, 0x0, 64); - ret = sprintf(time_str, "UTC time:%d-%d-%d %d:%d:%d ", - tm.tm_year+1900, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - - filewrite(enum_log, time_str); - filewrite(enum_log, log); -} - -void enum_notime_log(char *log) -{ - filewrite(enum_log, log); -} -#else -void enum_time_log(char *log) -{ - return; -} -void enum_notime_log(char *log) -{ - return; -} -#endif - - -static void __iomem *g_fpga_pcie_mem_base = NULL; - -int g_fpga_pcie_debug = 0; -int g_fpga_pcie_error = 0; -int g_fpga_pcie_reset_en = 0; -int ocore_ctl_startbus = 1; -int ocore_ctl_numbers = 14; -module_param(g_fpga_pcie_reset_en, int, S_IRUGO | S_IWUSR); -module_param(g_fpga_pcie_debug, int, S_IRUGO | S_IWUSR); -module_param(g_fpga_pcie_error, int, S_IRUGO | S_IWUSR); -module_param(ocore_ctl_startbus, int, S_IRUGO | S_IWUSR); -module_param(ocore_ctl_numbers, int, S_IRUGO | S_IWUSR); - - -#define FPGA_PCIE_DEBUG_VERBOSE(fmt, args...) do { \ - if (g_fpga_pcie_debug) { \ - printk(KERN_ERR "[FPGA_PCIE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define FPGA_PCIE_DEBUG_ERROR(fmt, args...) do { \ - if (g_fpga_pcie_error) { \ - printk(KERN_ERR "[FPGA_PCIE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define FPGA_MSI_IRQ_NUM (ocore_ctl_numbers) -#define FPGA_MSI_IRQ_BEGIN (0) -#define FPGA_MSI_IRQ_END ((FPGA_MSI_IRQ_BEGIN) + (FPGA_MSI_IRQ_NUM)) -#define FPGA_I2C_OCORE_START_BASE (0x800) -#define FPGA_I2C_OCORE_END_BASE (0x81f) -#define FPGA_I2C_OCORE_CTRL_SIZE (0x20) -#define FPGA_I2C_OCORE_CTRL_START(id) ((FPGA_I2C_OCORE_START_BASE) + (id) * (FPGA_I2C_OCORE_CTRL_SIZE)) -#define FPGA_I2C_OCORE_CTRL_END(id) ((FPGA_I2C_OCORE_END_BASE) + (id) * (FPGA_I2C_OCORE_CTRL_SIZE)) -#define FPGA_I2C_OCORE_CTRL_IRQ(id) (id) - - -#define DEFINE_FPGA_PCIE_OCORE_DATA(_id) \ - static struct rg_ocores_i2c_platform_data rg_i2c_ocore_pdata_##_id = { \ - .reg_shift = 0, \ - .reg_io_width = 4, \ - .clock_khz = 125000, \ - .num_devices = 0, \ - }; - -DEFINE_FPGA_PCIE_OCORE_DATA(0); -DEFINE_FPGA_PCIE_OCORE_DATA(1); -DEFINE_FPGA_PCIE_OCORE_DATA(2); -DEFINE_FPGA_PCIE_OCORE_DATA(3); -DEFINE_FPGA_PCIE_OCORE_DATA(4); -DEFINE_FPGA_PCIE_OCORE_DATA(5); -DEFINE_FPGA_PCIE_OCORE_DATA(6); -DEFINE_FPGA_PCIE_OCORE_DATA(7); -DEFINE_FPGA_PCIE_OCORE_DATA(8); -DEFINE_FPGA_PCIE_OCORE_DATA(9); -DEFINE_FPGA_PCIE_OCORE_DATA(10); -DEFINE_FPGA_PCIE_OCORE_DATA(11); -DEFINE_FPGA_PCIE_OCORE_DATA(12); -DEFINE_FPGA_PCIE_OCORE_DATA(13); -DEFINE_FPGA_PCIE_OCORE_DATA(14); -DEFINE_FPGA_PCIE_OCORE_DATA(15); -DEFINE_FPGA_PCIE_OCORE_DATA(16); -DEFINE_FPGA_PCIE_OCORE_DATA(17); -DEFINE_FPGA_PCIE_OCORE_DATA(18); -DEFINE_FPGA_PCIE_OCORE_DATA(19); -DEFINE_FPGA_PCIE_OCORE_DATA(20); -DEFINE_FPGA_PCIE_OCORE_DATA(21); -DEFINE_FPGA_PCIE_OCORE_DATA(22); -DEFINE_FPGA_PCIE_OCORE_DATA(23); -DEFINE_FPGA_PCIE_OCORE_DATA(24); -DEFINE_FPGA_PCIE_OCORE_DATA(25); -DEFINE_FPGA_PCIE_OCORE_DATA(26); -DEFINE_FPGA_PCIE_OCORE_DATA(27); - -#define DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(_id) \ - static const struct resource fpga_pcie_i2c_ocores_resources_##_id[] = { \ - { \ - .start = FPGA_I2C_OCORE_CTRL_START(_id), \ - .end = FPGA_I2C_OCORE_CTRL_END(_id), \ - .flags = IORESOURCE_MEM, \ - }, \ - { \ - .start = FPGA_I2C_OCORE_CTRL_IRQ(_id), \ - .end = FPGA_I2C_OCORE_CTRL_IRQ(_id), \ - .flags = IORESOURCE_IRQ, \ - }, \ - } - -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(0); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(1); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(2); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(3); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(4); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(5); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(6); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(7); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(8); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(9); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(10); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(11); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(12); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(13); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(14); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(15); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(16); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(17); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(18); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(19); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(20); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(21); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(22); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(23); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(24); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(25); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(26); -DEFINE_FPGA_PCIE_I2C_OCORE_RESOURCES(27); - -#define DEFINE_FPGA_PCIE_MFD_CELL_CFG(_id) \ -{ \ - .name = "rg-i2c-ocores", \ - .id = (_id), \ - .num_resources = ARRAY_SIZE(fpga_pcie_i2c_ocores_resources_##_id), \ - .resources = fpga_pcie_i2c_ocores_resources_##_id, \ - .platform_data = &rg_i2c_ocore_pdata_##_id, \ - .pdata_size = sizeof(rg_i2c_ocore_pdata_##_id), \ -} - - -static const struct mfd_cell fpga_pcie_cells_bar0_cfg0[] = { - DEFINE_FPGA_PCIE_MFD_CELL_CFG(0), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(1), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(2), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(3), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(4), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(5), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(6), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(7), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(8), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(9), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(10), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(11), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(12), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(13), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(14), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(15), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(16), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(17), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(18), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(19), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(20), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(21), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(22), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(23), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(24), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(25), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(26), - DEFINE_FPGA_PCIE_MFD_CELL_CFG(27), -}; - -struct rgde_dev { - struct uio_info info; - struct pci_dev *pdev; - struct list_head list; - enum xdk_intr_mode mode; -}; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,36) -/* XXX taken from uio.c, just for dumping */ -struct uio_device { - struct module *owner; - struct device *dev; - int minor; - atomic_t event; - struct fasync_struct *async_queue; - wait_queue_head_t wait; - struct uio_info *info; - struct kobject *map_dir; - struct kobject *portio_dir; -}; -#else -/* do noting add tjm */ -#endif - - -static char *intr_mode; -static enum xdk_intr_mode intr_mode_preferred = XDK_INTR_MODE_MSIX; - - -static struct list_head rgde_dev_que; - -static int rgde_dev_list_dump(void) -{ - char str[256]; - struct rgde_dev *node, *tmp; - struct uio_device *udev; - - list_for_each_entry_safe(node, tmp, &rgde_dev_que, list) { - udev = node->info.uio_dev; - memset(str, 0x0, 256); - sprintf(str, "pciuio device minor:%d\n", udev->minor); - enum_notime_log(str); - } - return 0; -} - -void rgde_dev_que_add(struct rgde_dev *uiodev) -{ - struct rgde_dev *node, *tmp; - - if (uiodev == NULL) { - return; - } - - if (list_empty(&rgde_dev_que)) { - list_add(&uiodev->list, &rgde_dev_que); - return; - } - - list_for_each_entry_safe(node, tmp, &rgde_dev_que, list) { - if (((node->info).uio_dev)->minor > ((uiodev->info).uio_dev)->minor) { - break; - } - } - list_add_tail(&uiodev->list, &node->list); - - return; -} - - -void rgde_dev_que_del(struct rgde_dev *uiodev) -{ - struct rgde_dev *node, *tmp; - - if (uiodev == NULL) { - return; - } - - list_for_each_entry_safe(node, tmp, &rgde_dev_que, list) { - if (((node->info).uio_dev)->minor == ((uiodev->info).uio_dev)->minor) { - list_del(&node->list); - break; - } - } - - return; -} - - -struct pci_dev *rgde_to_pci_device(int minor) -{ - - struct rgde_dev *node, *tmp; - - list_for_each_entry_safe(node, tmp, &rgde_dev_que, list) { - if (node->info.uio_dev->minor == minor) { - return node->pdev; - } - - if (node->info.uio_dev->minor < minor) { - return NULL; - } - } - - return NULL; -} -EXPORT_SYMBOL(rgde_to_pci_device); - -int pkt_get_mod(int logic_dev, int *mod) -{ - *mod = 0; - return 0; -} -EXPORT_SYMBOL(pkt_get_mod); - -int pkt_get_port(int logic_dev, int *port) -{ - *port = 1; - return 0; -} -EXPORT_SYMBOL(pkt_get_port); - -static int rgde_intr_mode_config(char *intr_str) -{ -#if 0 - /* default intr mode : msix */ - if (!intr_str) { - return 0; - } - - if (!strcmp(intr_str, INTR_MODE_MSIX_NAME)) { - intr_mode_preferred = XDK_INTR_MODE_MSIX; - return 0; - } - - if (!strcmp(intr_str, INTR_MODE_LEGACY_NAME)) { - intr_mode_preferred = XDK_INTR_MODE_LEGACY; - return 0; - } - - /* For now, msix & legacy mode supported only. */ - printk("<0>""Error: bad parameter - %s\n", intr_str); - return -EINVAL; -#else - intr_mode_preferred = XDK_INTR_MODE_LEGACY; - return 0; -#endif -} - -/* Remap pci resources described by bar #pci_bar in uio resource n. */ -static int rgde_setup_iomem(struct pci_dev *dev, struct uio_info *info, - int n, int pci_bar, const char *name) -{ - unsigned long addr, len; - void *internal_addr; - - if (n >= ARRAY_SIZE(info->mem)) { - return -EINVAL; - } - - addr = pci_resource_start(dev, pci_bar); - FPGA_PCIE_DEBUG_VERBOSE("iomem phys addr:%lx\n", addr); - len = pci_resource_len(dev, pci_bar); - if (addr == 0 || len == 0) { - return -1; - } - - - internal_addr = ioremap(addr, len); - FPGA_PCIE_DEBUG_VERBOSE("iomem phys addr:0x%lx, len 0x%lx, internal_addr %p.\n", addr, len, internal_addr); - - if (internal_addr == NULL) { - return -1; - } - - FPGA_PCIE_DEBUG_VERBOSE("iomem internal_addr:%p\n", internal_addr); - if (pci_bar == 0) { - - g_fpga_pcie_mem_base = internal_addr; - FPGA_PCIE_DEBUG_VERBOSE("pci_bar %d, set g_fpga_pcie_mem_base %p\n", pci_bar, g_fpga_pcie_mem_base); - } - info->mem[n].name = name; - info->mem[n].addr = addr; - info->mem[n].internal_addr = internal_addr; - info->mem[n].size = len; - info->mem[n].memtype = UIO_MEM_PHYS; - - return 0; -} - -/* Unmap previously ioremap'd resources */ -static void rgde_release_iomem(struct uio_info *info) -{ - int i; - - for (i = 0; i < MAX_UIO_MAPS; i++) { - if (info->mem[i].internal_addr) { - iounmap(info->mem[i].internal_addr); - } - } -} - -/* Get pci port io resources described by bar #pci_bar in uio resource n. */ -static int rgde_setup_ioport(struct pci_dev *dev, struct uio_info *info, - int n, int pci_bar, const char *name) -{ - unsigned long addr, len; - - if (n >= ARRAY_SIZE(info->port)) { - return -EINVAL; - } - - addr = pci_resource_start(dev, pci_bar); - len = pci_resource_len(dev, pci_bar); - if (addr == 0 || len == 0) { - return -EINVAL; - } - - info->port[n].name = name; - info->port[n].start = addr; - info->port[n].size = len; - /* skl : FIX me */ - info->port[n].porttype = UIO_PORT_X86; - - return 0; -} - -static int rgde_setup_bars(struct pci_dev *dev, struct uio_info *info) -{ - int i, iom, iop, ret; - unsigned long flags; - static const char *bar_names[PCI_STD_RESOURCE_END + 1] = { - "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", - }; - iom = 0; - iop = 0; - - for (i = 0; i < ARRAY_SIZE(bar_names); i++) { - if (pci_resource_len(dev, i) != 0 && pci_resource_start(dev, i) != 0) { - - flags = pci_resource_flags(dev, i); - FPGA_PCIE_DEBUG_VERBOSE("flags:%lx\n", flags); - if (flags & IORESOURCE_MEM) { - ret = rgde_setup_iomem(dev, info, iom, i, bar_names[i]); - if (ret != 0) { - return ret; - } - iom++; - } else if (flags & IORESOURCE_IO) { - ret = rgde_setup_ioport(dev, info, iop, i, bar_names[i]); - if (ret != 0) { - return ret; - } - iop++; - } - } - } - - return (iom != 0 || iop != 0) ? ret : -ENOENT; -} - -/** - * This is interrupt handler which will check if the interrupt is for the right device. - * If yes, disable it here and will be enable later. - */ -static irqreturn_t rgde_irqhandler(int irq, struct uio_info *info) -{ - struct rgde_dev *udev = info->priv; - - if (udev->mode == XDK_INTR_MODE_LEGACY /*&& !pci_check_and_mask_intx(udev->pdev)*/) { - return IRQ_NONE; - } - - return IRQ_HANDLED; -} - -/* - * It masks the msix on/off of generating MSI-X messages. - */ -static void rgde_msix_mask_irq(struct msi_desc *desc, int32_t state) -{ - u32 mask_bits = desc->masked; - unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL; - - if (state != 0) { - mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; - } else { - mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; - } - - if (mask_bits != desc->masked) { - writel(mask_bits, desc->mask_base + offset); - readl(desc->mask_base); - desc->masked = mask_bits; - } -} - -/** - * This is the irqcontrol callback to be registered to uio_info. - * It can be used to disable/enable interrupt from user space processes. - * - * @param info - * pointer to uio_info. - * @param irq_state - * state value. 1 to enable interrupt, 0 to disable interrupt. - * - * @return - * - On success, 0. - * - On failure, a negative value. - */ -static int rgde_irqcontrol(struct uio_info *info, s32 irq_state) -{ - struct rgde_dev *udev = info->priv; - struct pci_dev *pdev = udev->pdev; - - /* pci_cfg_access_lock(pdev); */ - - if (udev->mode == XDK_INTR_MODE_LEGACY) { - pci_intx(pdev, !!irq_state); - } else if (udev->mode == XDK_INTR_MODE_MSIX) { - struct msi_desc *desc; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)) - list_for_each_entry(desc, &pdev->msi_list, list) { - rgde_msix_mask_irq(desc, irq_state); - } -#else - list_for_each_entry(desc, &pdev->dev.msi_list, list) { - rgde_msix_mask_irq(desc, irq_state); - } -#endif - } - - //pci_cfg_access_unlock(pdev); - - return 0; -} - -int rgde_reg32_read(int minor, uint64_t offset, uint32_t *data) -{ - struct rgde_dev *node, *tmp; - struct rgde_dev *uiodev; - - FPGA_PCIE_DEBUG_VERBOSE("enter rgde_reg32_read\n"); - uiodev = NULL; - list_for_each_entry_safe(node, tmp, &rgde_dev_que, list) { - if (((node->info).uio_dev)->minor == minor) { - uiodev = node; - break; - } - } - - if (uiodev == NULL) { - return -1; - } - - if (uiodev->info.mem[0].internal_addr == NULL) { - return -1; - } - -#if 0 - FPGA_PCIE_DEBUG_VERBOSE("internal_addr:%x\n", uiodev->info.mem[0].internal_addr); - - memcpy(ioval, (uint8_t *)uiodev->info.mem[0].internal_addr + offset, sizeof(ioval)); - for (i = 0; i < sizeof(ioval); i++) { - FPGA_PCIE_DEBUG_VERBOSE("mem[%x]:%02x\n", (uint32_t)(offset + i), ioval[i]); - } -#endif - - *data = (*((uint32_t *)((uint8_t *)(uiodev->info.mem[0].internal_addr) + offset))); - return 0; -} -EXPORT_SYMBOL(rgde_reg32_read); - -int rgde_reg32_write(int minor, uint64_t offset, uint32_t data) -{ - struct rgde_dev *node, *tmp; - struct rgde_dev *uiodev; - - uiodev = NULL; - list_for_each_entry_safe(node, tmp, &rgde_dev_que, list) { - if (((node->info).uio_dev)->minor == minor) { - uiodev = node; - break; - } - } - - if (uiodev == NULL) { - return -1; - } - - if (uiodev->info.mem[0].internal_addr == NULL) { - return -1; - } - - FPGA_PCIE_DEBUG_VERBOSE("enter rgde_reg32_write\n"); - FPGA_PCIE_DEBUG_VERBOSE("internal_addr:%p,offset:%llx,data:%x\n", uiodev->info.mem[0].internal_addr, offset, data); - - *((uint32_t *)((uint8_t *)(uiodev->info.mem[0].internal_addr) + offset)) = (data); - FPGA_PCIE_DEBUG_VERBOSE("rgde_reg32_write ok!\n"); - return 0; -} -EXPORT_SYMBOL(rgde_reg32_write); - -#if 0 -static void rgde_dump_global_regs(int minor) -{ - struct rgde_dev *node, *tmp; - struct rgde_dev *uiodev; - uint8_t ioval[4]; - int i, j; - - - uiodev = NULL; - list_for_each_entry_safe(node, tmp, &rgde_dev_que, list) { - if (((node->info).uio_dev)->minor == minor) { - uiodev = node; - break; - } - } - - if (uiodev == NULL) { - return ; - } - - if (uiodev->info.mem[0].internal_addr == NULL) { - return ; - } - - FPGA_PCIE_DEBUG_VERBOSE("internal_addr:%p\n", uiodev->info.mem[0].internal_addr); - for (j = 0; j < sizeof(uint32_t) * 6; j += sizeof(uint32_t)) { - memcpy(ioval, (uint8_t *)uiodev->info.mem[0].internal_addr + j, sizeof(ioval)); - for (i = 0; i < sizeof(ioval); i++) { - FPGA_PCIE_DEBUG_VERBOSE("mem[%d]:%02x\n", (uint32_t)(j + i), ioval[i]); - } - } - - return; -} -#endif - -#if 1 - -#define FPGA_PCIE_TEST_REG (0x08) -#define FPGA_PCIE_TEST_VAL (0x5A) - -#define FPGA_PCIE_RESET_PCA9548_BASE (0x20) -#define FPGA_PCIE_RESET_PCA9548_NUM (0x4) -#define FPGA_PCIE_RESET_OCORE_BASE (0x100) -#define FPGA_PCIE_RESET_OCORE_NUM (ocore_ctl_numbers) - -#define FPGA_PCIE_RESET_CPLD_I2C_BASE (0x40) -#define FPGA_PCIE_RESET_CPLD_I2C_NUM (0x4) - - -#define FPGA_PCIE_REG_STEP (0x4) - -#define DFD_CPLD_I2C_RETRY_TIMES 3 -#define DFD_CPLD_I2C_RETRY_DELAY 100 /* ms */ - -#define PCA9548_MAX_CPLD_NUM (32) - -typedef struct fpga_pcie_pca9548_cfg_info_s { - int pca9548_bus; - int pca9548_addr; - int cfg_offset; -} fpga_pcie_pca9548_cfg_info_t; - -typedef struct fpga_pcie_card_info_s { - int dev_type; - fpga_pcie_pca9548_cfg_info_t pca9548_cfg_info[PCA9548_MAX_CPLD_NUM]; -} fpga_pcie_card_info_t; - -static fpga_pcie_card_info_t g_fpga_pcie_card_info[] = { - { - /* RA-B6510-32C */ - .dev_type = 0x404b, - .pca9548_cfg_info = { - { - .pca9548_bus = 12, - .pca9548_addr = 0x70, - .cfg_offset = 0x20, - }, - { - .pca9548_bus = 12, - .pca9548_addr = 0x71, - .cfg_offset = 0x20, - }, - { - .pca9548_bus = 12, - .pca9548_addr = 0x72, - .cfg_offset = 0x20, - }, - { - .pca9548_bus = 12, - .pca9548_addr = 0x73, - .cfg_offset = 0x20, - }, - }, - }, -}; - -extern void pca954x_hw_do_reset_func_register(void* func); -extern int dfd_get_my_card_type(void); - -static void fpga_pcie_setreg_32(int offset, u32 data) -{ - if (g_fpga_pcie_mem_base) { - *((uint32_t *)((uint8_t *)(g_fpga_pcie_mem_base) + offset)) = (data); - } else { - FPGA_PCIE_DEBUG_ERROR("g_fpga_pcie_mem_base is null.\n"); - } - return; -} - - -static inline u32 fpga_pcie_getreg_32(int offset) -{ - u32 data = 0; - - if (g_fpga_pcie_mem_base) { - data = (*((uint32_t *)((uint8_t *)(g_fpga_pcie_mem_base) + offset))); - } else { - FPGA_PCIE_DEBUG_ERROR("g_fpga_pcie_mem_base is null.\n"); - } - return data; -} - -static void fpga_do_cpld_i2c_ctrl(int en) -{ -#if 0 - int i; - int offset; - - for (i = 0; i < FPGA_PCIE_RESET_CPLD_I2C_NUM; i++) { - offset = FPGA_PCIE_RESET_CPLD_I2C_BASE + i * FPGA_PCIE_REG_STEP; - FPGA_PCIE_DEBUG_VERBOSE("offset 0x%x, write en 0x%x.\n", offset, en); - fpga_pcie_setreg_32(offset, en); - } -#endif - return; -} - - -static void fpga_do_ocore_ctrl(int en) -{ - int i; - int offset; - - for (i = 0; i < FPGA_PCIE_RESET_OCORE_NUM; i++) { - offset = FPGA_PCIE_RESET_OCORE_BASE + i * FPGA_PCIE_REG_STEP; - FPGA_PCIE_DEBUG_VERBOSE("offset 0x%x, write en 0x%x.\n", offset, en); - fpga_pcie_setreg_32(offset, en); - } -} - -static void fpga_do_9548_ctrl(int en) -{ - int i; - int offset; - - for (i = 0; i < FPGA_PCIE_RESET_PCA9548_NUM; i++) { - offset = FPGA_PCIE_RESET_PCA9548_BASE + i * FPGA_PCIE_REG_STEP; - FPGA_PCIE_DEBUG_VERBOSE("offset 0x%x, write en 0x%x.\n", offset, en); - fpga_pcie_setreg_32(offset, en); - } - -} - -static void fpga_reset_ocore_i2c(void) -{ - u32 data; - - - if (g_fpga_pcie_reset_en == 0) { - FPGA_PCIE_DEBUG_VERBOSE("g_fpga_pcie_reset_en is 0, do nothing.\n"); - return; - } - - data = fpga_pcie_getreg_32(FPGA_PCIE_TEST_REG); - FPGA_PCIE_DEBUG_VERBOSE("BEGIN FPGA_PCIE_TEST_REG=[0x%x], write 0x%x.\n", data, FPGA_PCIE_TEST_VAL); - fpga_pcie_setreg_32(FPGA_PCIE_TEST_REG, FPGA_PCIE_TEST_VAL); - data = fpga_pcie_getreg_32(FPGA_PCIE_TEST_REG); - FPGA_PCIE_DEBUG_VERBOSE("END FPGA_PCIE_TEST_REG=[0x%x].\n", data); - - - - fpga_do_9548_ctrl(0); - fpga_do_ocore_ctrl(0); - fpga_do_cpld_i2c_ctrl(0); - - mdelay(500); - - - fpga_do_9548_ctrl(1); - fpga_do_ocore_ctrl(1); - fpga_do_cpld_i2c_ctrl(1); - - return; -} - -static void fpga_do_pca9548_reset_ctrl(int offset, int en) -{ - FPGA_PCIE_DEBUG_VERBOSE("offset 0x%x, write en 0x%x.\n", offset, en); - fpga_pcie_setreg_32(offset, en); -} - -fpga_pcie_card_info_t* fpga_pcie_get_card_info(int dev_type) -{ - int i; - int size; - - size = ARRAY_SIZE(g_fpga_pcie_card_info); - - FPGA_PCIE_DEBUG_VERBOSE("Enter dev_type 0x%x size %d.\n", dev_type, size); - for (i = 0; i < size; i++) { - if (g_fpga_pcie_card_info[i].dev_type == dev_type) { - FPGA_PCIE_DEBUG_VERBOSE("match dev_type 0x%x.\n", dev_type); - return &g_fpga_pcie_card_info[i]; - } - } - - FPGA_PCIE_DEBUG_VERBOSE("dismatch dev_type 0x%x.\n", dev_type); - return NULL; -} - -fpga_pcie_pca9548_cfg_info_t* fpga_pcie_get_pca9548_cfg_info(int bus, int addr) -{ - int dev_type; - fpga_pcie_card_info_t *info; - fpga_pcie_pca9548_cfg_info_t *pca9548_cfg_info; - int i; - int size; - - dev_type = dfd_get_my_card_type(); - if (dev_type < 0) { - FPGA_PCIE_DEBUG_ERROR("drv_get_my_dev_type failed ret %d.\n", dev_type); - return NULL; - } - - info = fpga_pcie_get_card_info(dev_type); - if (info == NULL) { - FPGA_PCIE_DEBUG_ERROR("fpga_pcie_get_card_info dev_type %d failed.\n", dev_type); - return NULL; - } - - size = PCA9548_MAX_CPLD_NUM; - for (i = 0; i < size; i++) { - pca9548_cfg_info = &(info->pca9548_cfg_info[i]); - if ((pca9548_cfg_info->pca9548_bus == bus) && (pca9548_cfg_info->pca9548_addr == addr)) { - FPGA_PCIE_DEBUG_VERBOSE("match dev_type 0x%x bus %d addr 0x%x.\n", dev_type, bus, addr); - return pca9548_cfg_info; - } - } - - FPGA_PCIE_DEBUG_VERBOSE("dismatch dev_type 0x%x bus %d addr 0x%x.\n", dev_type, bus, addr); - return NULL; -} - - -void fpga_do_pca954x_reset_func(int bus, int addr) -{ - fpga_pcie_pca9548_cfg_info_t *cfg_info; - - cfg_info = fpga_pcie_get_pca9548_cfg_info(bus, addr); - if (cfg_info == NULL) { - FPGA_PCIE_DEBUG_VERBOSE("fpga_do_pca954x_reset_func do nothing.\n"); - return; - } - - FPGA_PCIE_DEBUG_VERBOSE("bus %d addr 0x%x, cfg_info.offset:0x%x.\n", bus, addr, cfg_info->cfg_offset); - - fpga_do_pca9548_reset_ctrl(cfg_info->cfg_offset, 0); - mdelay(250); - fpga_do_pca9548_reset_ctrl(cfg_info->cfg_offset, 1); -} - -static void fpga_do_pca954x_reset_func_reg(void) -{ - pca954x_hw_do_reset_func_register(fpga_do_pca954x_reset_func); -} - -#endif - - -static int fpga_i2c_ocore_device_init(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int ret, index; - struct rg_ocores_i2c_platform_data *init_nr_ocores; - - for (index = 0 ; index < ARRAY_SIZE(fpga_pcie_cells_bar0_cfg0); index++) { - init_nr_ocores = fpga_pcie_cells_bar0_cfg0[index].platform_data; - init_nr_ocores->nr = ocore_ctl_startbus + index; - } - FPGA_PCIE_DEBUG_VERBOSE("Enter.\n"); - FPGA_PCIE_DEBUG_VERBOSE("Begin mfd_add_devices.\n"); - ret = mfd_add_devices(&pdev->dev, 0, - fpga_pcie_cells_bar0_cfg0, - ocore_ctl_numbers > ARRAY_SIZE(fpga_pcie_cells_bar0_cfg0) ? ARRAY_SIZE(fpga_pcie_cells_bar0_cfg0) : ocore_ctl_numbers , - &pdev->resource[0], pdev->irq, NULL); - FPGA_PCIE_DEBUG_VERBOSE("End mfd_add_devices ret %d.\n", ret); - if (ret) { - dev_err(&pdev->dev, "mfd_add_devices failed: %d\n", ret); - return -1; - } - - fpga_do_pca954x_reset_func_reg(); - FPGA_PCIE_DEBUG_VERBOSE("Call fpga_do_pca954x_reset_func_reg.\n"); - return 0; -} - -static void fpga_pcie_recover(struct pci_dev *pdev, const struct pci_device_id *id) -{ - struct resource *mem_base; - u32 bar0_val; - int ret; - - mem_base = &pdev->resource[0]; - ret = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &bar0_val); - if (ret) { - FPGA_PCIE_DEBUG_ERROR("pci_read_config_dword failed ret %d.\n", ret); - return; - } - FPGA_PCIE_DEBUG_VERBOSE("mem_base->start[0x%llx], bar0_val[0x%x], ret %d.\n", - mem_base->start, bar0_val, ret); - - if (bar0_val != mem_base->start) { - ret = pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, mem_base->start); - if (ret) { - FPGA_PCIE_DEBUG_ERROR("pci_write_config_dword mem_base->start[0x%llx], failed ret %d.\n", mem_base->start, ret); - return; - } - FPGA_PCIE_DEBUG_VERBOSE("pci_write_config_dword mem_base->start[0x%llx] success.\n", mem_base->start); - } else { - FPGA_PCIE_DEBUG_VERBOSE("mem_base->start[0x%llx], bar0_val[0x%x], do nothing.\n", - mem_base->start, bar0_val); - } -} - -static int fpga_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int err; - struct rgde_dev *rdev = NULL; - - FPGA_PCIE_DEBUG_VERBOSE("Enter vendor 0x%x, subsystem_vendor 0x%x.\n", pdev->vendor, pdev->subsystem_vendor); - - /* skl : FIX me */ - /* - if ((pdev->vendor != ) || (pdev->subsystem_vendor != )) { - err = -ENODEV; - goto dev_suppport_err:; - }*/ - - - fpga_pcie_recover(pdev, id); - - /* enable device: ask low-level code to enable I/O and memory */ - FPGA_PCIE_DEBUG_VERBOSE("start pci_enable_device!\n"); - err = pci_enable_device(pdev); - if (err) { - FPGA_PCIE_DEBUG_ERROR("pci_enable_device failed: %d\n", err); - goto dev_ebable_err; - } - - FPGA_PCIE_DEBUG_VERBOSE("start pci_set_master!\n"); - pci_set_master(pdev); - - rdev = kzalloc(sizeof(struct rgde_dev), GFP_KERNEL); - if (!rdev) { - err = -ENOMEM; - goto kzalloc_err; - } - - - FPGA_PCIE_DEBUG_VERBOSE("start rgde_setup_bars!\n"); - err = rgde_setup_bars(pdev, &rdev->info); - if (err != 0) { - goto setup_bars_err; - } - - rdev->info.name = "fpga_pcie"; - rdev->info.version = "0.1"; - rdev->info.handler = rgde_irqhandler; - rdev->info.irqcontrol = rgde_irqcontrol; - rdev->info.priv = rdev; - rdev->pdev = pdev; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) - err = pci_alloc_irq_vectors(pdev,FPGA_MSI_IRQ_BEGIN + 1, ocore_ctl_numbers, PCI_IRQ_MSI); -#else - err = pci_enable_msi_range(pdev, FPGA_MSI_IRQ_BEGIN + 1, ocore_ctl_numbers); -#endif - if (err != ocore_ctl_numbers) { - FPGA_PCIE_DEBUG_ERROR("pci_enable_msi_block err %d FPGA_MSI_IRQ_NUM %d.\n", err, - ocore_ctl_numbers); - goto uio_register_err; - } - - FPGA_PCIE_DEBUG_VERBOSE("before pci_set_drvdata.\n"); - - pci_set_drvdata(pdev, rdev); - FPGA_PCIE_DEBUG_VERBOSE("after pci_set_drvdata.\n"); - enum_time_log("rgde_dev_que_add\n"); - - mdelay(100); - - fpga_reset_ocore_i2c(); - - fpga_i2c_ocore_device_init(pdev, id); - return 0; - -uio_register_err: - /* udev_irq_err: */ -setup_bars_err: - rgde_release_iomem(&rdev->info); - pci_disable_msi(rdev->pdev); - pci_release_regions(pdev); - kfree(rdev); -kzalloc_err: - /* request_region_err: */ - pci_disable_device(pdev); -dev_ebable_err: - /* dev_suppport_err: */ - return err; -} - -static void fpga_pcie_remove(struct pci_dev *pdev) -{ - struct rgde_dev *rdev = pci_get_drvdata(pdev); - - FPGA_PCIE_DEBUG_VERBOSE("fpga_pcie_remove.\n"); -#if 0 - enum_time_log("rgde_dev_que_del\n"); - printk("<0>""uio device %d del.\n", rdev->info.uio_dev->minor); -#endif - rgde_dev_que_del(rdev); - rgde_dev_list_dump(); -#if 0 - uio_unregister_device(&rdev->info); -#endif - mfd_remove_devices(&pdev->dev); - rgde_release_iomem(&rdev->info); - pci_disable_msi(rdev->pdev); - //pci_release_regions(pdev); - pci_disable_device(pdev); - kfree(rdev); -} - -/* static DEFINE_PCI_DEVICE_TABLE(fpga_pci_ids) = { */ - -static const struct pci_device_id fpga_pci_ids[] = { - { PCI_DEVICE(0x10ee, 0x7022)}, - {0} -}; -MODULE_DEVICE_TABLE(pci, fpga_pci_ids); - - -static struct pci_driver fpga_pcie_driver = { - .name = "fpga_pcie", - .id_table = fpga_pci_ids,/* only dynamic id's */ - .probe = fpga_pcie_probe, - .remove = fpga_pcie_remove, -}; - -static int __init fpga_pcie_init(void) -{ - int ret; - - FPGA_PCIE_DEBUG_VERBOSE("fpga_pcie_init enter!\n"); - ret = rgde_intr_mode_config(intr_mode); - if (ret < 0) { - return ret; - } - - INIT_LIST_HEAD(&rgde_dev_que); - - return pci_register_driver(&fpga_pcie_driver); -} - -static void __exit fpga_pcie_exit(void) -{ - FPGA_PCIE_DEBUG_VERBOSE("fpga_pcie_exit enter!\n"); - pci_unregister_driver(&fpga_pcie_driver); -} - -module_init(fpga_pcie_init); -module_exit(fpga_pcie_exit); -module_param(intr_mode, charp, S_IRUGO); -MODULE_PARM_DESC(intr_mode, - "pci_uio interrupt mode (default=msix):\n" - " " INTR_MODE_MSIX_NAME " Use MSIX interrupt\n" - " " INTR_MODE_LEGACY_NAME " Use Legacy interrupt\n" - "\n"); -MODULE_DESCRIPTION("UIO Driver for PCI Devices"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("support "); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_pcie_i2c.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_pcie_i2c.h deleted file mode 100755 index 1ea970cc2206..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_pcie_i2c.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef _FPGA_PCIE_I2C_H_ -#define _FPGA_PCIE_I2C_H_ - -#ifdef __KERNEL__ -#include -#else -#include -#endif - -#define ENUM_MAX_DEVS (255) - -typedef enum { - CHIP_NONE, - CHIP_PC, -} chiptype_t; - -/* bitmap for ports, 256 ports for now. */ -typedef struct portbitmap_s { - uint8_t bit[32]; -} portbitmap_t; - -typedef struct pc_info_s { - uint8_t ntables; /* number of flow tables */ - uint8_t ncores; /* number of cores */ - uint8_t npipelines; /* number of pipelines */ - uint8_t nports; /* number of ports */ - portbitmap_t pbm_caui; /* bitmap for CAUI ports */ - portbitmap_t pbm_ge; /* bitmap for GE ports */ -} pc_info_t; - -/** - * A structure describing a PCI resource. - */ -struct pci_resource { - uint64_t phys_addr; /**< Physical address, 0 if no resource. */ - uint64_t len; /**< Length of the resource. */ - void *addr; /**< Virtual address, NULL when not mapped. */ -}; - -/** Maximum number of PCI resources. */ -#define PCI_MAX_RESOURCE 6 - -/** Nb. of values in PCI resource format. */ -#define PCI_RESOURCE_FMT_NVAL 3 - -#if 0 -/** IO resource type: memory address space */ -#define IORESOURCE_MEM 0x00000200 -#endif - -typedef struct chipinfo_s { - /* PCI ID */ - uint16_t vendor; - uint16_t dev; - uint8_t rev; - - /* chip properties */ - chiptype_t type; - pc_info_t pc_info; /* if type == CHIP_PC */ -} chipinfo_t; - -typedef struct devinfo_s { - /* static info */ - chipinfo_t chipinfo; - - /* running states */ - uint32_t uiono; /* the "X" in /dev/uioX */ - char *pci_conf_file; /* /sys/devices/ */ - char *dev_file; /* /dev/uioX */ - - struct pci_resource mem_resource[PCI_MAX_RESOURCE]; /**< PCI Memory Resource */ - - uint32_t n_mems; /* no of mem-mapped regions, MUST BE 1 for now */ - uint32_t n_ports;/* no of port-maped regions, MUST BE 0 for now */ -} devinfo_t; - - -#ifdef __KERNEL__ -#include - -struct pci_dev *rgde_to_pci_device(int index); - -int rgde_reg32_read(int minor, uint64_t offset, uint32_t *data); - -int rgde_reg32_write(int minor, uint64_t offset, uint32_t data); - -int pkt_get_mod(int logic_dev, int *mod); - -int pkt_get_port(int logic_dev, int *port); - -/* interrupt mode */ -enum xdk_intr_mode { - XDK_INTR_MODE_NONE = 0, - XDK_INTR_MODE_LEGACY, - XDK_INTR_MODE_MSI, - XDK_INTR_MODE_MSIX -}; - -#define INTR_MODE_NONE_NAME "none" -#define INTR_MODE_LEGACY_NAME "legacy" -#define INTR_MODE_MSI_NAME "msi" -#define INTR_MODE_MSIX_NAME "msix" - -#endif /*__KERNEL__ */ - - -#endif /* _FPGA_PCIE_I2C_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_reg_defs.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_reg_defs.h deleted file mode 100755 index f80c6318564c..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/fpga_reg_defs.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef _FPGA_REG_DEFS_H_ -#define _FPGA_REG_DEFS_H_ - -/** Define Registers */ -/* Global Registers */ -#define RGDE_REG_GLOBAL_BASE 0x00000000 -#define RGDE_REG_VERSION (RGDE_REG_GLOBAL_BASE + 0x00) -#define RGDE_REG_DATE (RGDE_REG_GLOBAL_BASE + 0x04) -#define RGDE_REG_TEST (RGDE_REG_GLOBAL_BASE + 0x08) -#define RGDE_REG_INT_ENABLE (RGDE_REG_GLOBAL_BASE + 0x10) -#define RGDE_REG_INT_STATUS (RGDE_REG_GLOBAL_BASE + 0x14) - -/* MDIO Registers */ -#define RGDE_REG_MDIO_BASE 0x00000100 -#define RGDE_REG_MDIO_CFG_DT (RGDE_REG_MDIO_BASE + 0x00) -#define RGDE_REG_MDIO_CFG_SPEED (RGDE_REG_MDIO_BASE + 0x04) -#define RGDE_REG_MDIO_CFG_START (RGDE_REG_MDIO_BASE + 0x08) -#define RGDE_REG_MDIO_RDAT (RGDE_REG_MDIO_BASE + 0x10) -#define RGDE_REG_MDIO_STATUS (RGDE_REG_MDIO_BASE + 0x14) - -/* GE0 PORT Registers */ -#define RGDE_REG_GE0_PORT_BASE 0x00001000 -#define RGDE_REG_GE0_PORT_CTL (RGDE_REG_GE0_PORT_BASE + 0x00) -#define RGDE_REG_GE0_PORT_STA (RGDE_REG_GE0_PORT_BASE + 0x04) -#define RGDE_REG_GE0_PORT_MTU (RGDE_REG_GE0_PORT_BASE + 0x08) -#define RGDE_REG_GE0_PORT_RXPKTS (RGDE_REG_GE0_PORT_BASE + 0x10) -#define RGDE_REG_GE0_PORT_RXBYTE (RGDE_REG_GE0_PORT_BASE + 0x18) -#define RGDE_REG_GE0_PORT_RXERR (RGDE_REG_GE0_PORT_BASE + 0x20) -#define RGDE_REG_GE0_PORT_RXDROP (RGDE_REG_GE0_PORT_BASE + 0x28) -#define RGDE_REG_GE0_PORT_RXMULTI (RGDE_REG_GE0_PORT_BASE + 0x30) -#define RGDE_REG_GE0_PORT_RXBRO (RGDE_REG_GE0_PORT_BASE + 0x38) -#define RGDE_REG_GE0_PORT_TXPKTS (RGDE_REG_GE0_PORT_BASE + 0x40) -#define RGDE_REG_GE0_PORT_TXBYTE (RGDE_REG_GE0_PORT_BASE + 0x48) -#define RGDE_REG_GE0_PORT_TXERR (RGDE_REG_GE0_PORT_BASE + 0x50) -#define RGDE_REG_GE0_PORT_TXDROP (RGDE_REG_GE0_PORT_BASE + 0x58) -#define RGDE_REG_GE0_PORT_TXMULT (RGDE_REG_GE0_PORT_BASE + 0x60) -#define RGDE_REG_GE0_PORT_TXBRO (RGDE_REG_GE0_PORT_BASE + 0x68) - -/* GE1 PORT Registers */ -#define RGDE_REG_GE1_PORT_BASE 0x00001100 -#define RGDE_REG_GE1_PORT_CTL (RGDE_REG_GE1_PORT_BASE + 0x00) -#define RGDE_REG_GE1_PORT_STA (RGDE_REG_GE1_PORT_BASE + 0x04) -#define RGDE_REG_GE1_PORT_MTU (RGDE_REG_GE1_PORT_BASE + 0x08) -#define RGDE_REG_GE1_PORT_RXPKTS (RGDE_REG_GE1_PORT_BASE + 0x10) -#define RGDE_REG_GE1_PORT_RXBYTE (RGDE_REG_GE1_PORT_BASE + 0x18) -#define RGDE_REG_GE1_PORT_RXERR (RGDE_REG_GE1_PORT_BASE + 0x20) -#define RGDE_REG_GE1_PORT_RXDROP (RGDE_REG_GE1_PORT_BASE + 0x28) -#define RGDE_REG_GE1_PORT_RXMULTI (RGDE_REG_GE1_PORT_BASE + 0x30) -#define RGDE_REG_GE1_PORT_RXBRO (RGDE_REG_GE1_PORT_BASE + 0x38) -#define RGDE_REG_GE1_PORT_TXPKTS (RGDE_REG_GE1_PORT_BASE + 0x40) -#define RGDE_REG_GE1_PORT_TXBYTE (RGDE_REG_GE1_PORT_BASE + 0x48) -#define RGDE_REG_GE1_PORT_TXERR (RGDE_REG_GE1_PORT_BASE + 0x50) -#define RGDE_REG_GE1_PORT_TXDROP (RGDE_REG_GE1_PORT_BASE + 0x58) -#define RGDE_REG_GE1_PORT_TXMULT (RGDE_REG_GE1_PORT_BASE + 0x60) -#define RGDE_REG_GE1_PORT_TXBRO (RGDE_REG_GE1_PORT_BASE + 0x68) - -/* GE2 PORT Registers */ -#define RGDE_REG_GE2_PORT_BASE 0x00001200 -#define RGDE_REG_GE2_PORT_CTL (RGDE_REG_GE2_PORT_BASE + 0x00) -#define RGDE_REG_GE2_PORT_STA (RGDE_REG_GE2_PORT_BASE + 0x04) -#define RGDE_REG_GE2_PORT_MTU (RGDE_REG_GE2_PORT_BASE + 0x08) -#define RGDE_REG_GE2_PORT_RXPKTS (RGDE_REG_GE2_PORT_BASE + 0x10) -#define RGDE_REG_GE2_PORT_RXBYTE (RGDE_REG_GE2_PORT_BASE + 0x18) -#define RGDE_REG_GE2_PORT_RXERR (RGDE_REG_GE2_PORT_BASE + 0x20) -#define RGDE_REG_GE2_PORT_RXDROP (RGDE_REG_GE2_PORT_BASE + 0x28) -#define RGDE_REG_GE2_PORT_RXMULTI (RGDE_REG_GE2_PORT_BASE + 0x30) -#define RGDE_REG_GE2_PORT_RXBRO (RGDE_REG_GE2_PORT_BASE + 0x38) -#define RGDE_REG_GE2_PORT_TXPKTS (RGDE_REG_GE2_PORT_BASE + 0x40) -#define RGDE_REG_GE2_PORT_TXBYTE (RGDE_REG_GE2_PORT_BASE + 0x48) -#define RGDE_REG_GE2_PORT_TXERR (RGDE_REG_GE2_PORT_BASE + 0x50) -#define RGDE_REG_GE2_PORT_TXDROP (RGDE_REG_GE2_PORT_BASE + 0x58) -#define RGDE_REG_GE2_PORT_TXMULT (RGDE_REG_GE2_PORT_BASE + 0x60) -#define RGDE_REG_GE2_PORT_TXBRO (RGDE_REG_GE2_PORT_BASE + 0x68) - -/* GE3 PORT Registers */ -#define RGDE_REG_GE3_PORT_BASE 0x00001300 -#define RGDE_REG_GE3_PORT_CTL (RGDE_REG_GE3_PORT_BASE + 0x00) -#define RGDE_REG_GE3_PORT_STA (RGDE_REG_GE3_PORT_BASE + 0x04) -#define RGDE_REG_GE3_PORT_MTU (RGDE_REG_GE3_PORT_BASE + 0x08) -#define RGDE_REG_GE3_PORT_RXPKTS (RGDE_REG_GE3_PORT_BASE + 0x10) -#define RGDE_REG_GE3_PORT_RXBYTE (RGDE_REG_GE3_PORT_BASE + 0x18) -#define RGDE_REG_GE3_PORT_RXERR (RGDE_REG_GE3_PORT_BASE + 0x20) -#define RGDE_REG_GE3_PORT_RXDROP (RGDE_REG_GE3_PORT_BASE + 0x28) -#define RGDE_REG_GE3_PORT_RXMULTI (RGDE_REG_GE3_PORT_BASE + 0x30) -#define RGDE_REG_GE3_PORT_RXBRO (RGDE_REG_GE3_PORT_BASE + 0x38) -#define RGDE_REG_GE3_PORT_TXPKTS (RGDE_REG_GE3_PORT_BASE + 0x40) -#define RGDE_REG_GE3_PORT_TXBYTE (RGDE_REG_GE3_PORT_BASE + 0x48) -#define RGDE_REG_GE3_PORT_TXERR (RGDE_REG_GE3_PORT_BASE + 0x50) -#define RGDE_REG_GE3_PORT_TXDROP (RGDE_REG_GE3_PORT_BASE + 0x58) -#define RGDE_REG_GE3_PORT_TXMULT (RGDE_REG_GE3_PORT_BASE + 0x60) -#define RGDE_REG_GE3_PORT_TXBRO (RGDE_REG_GE3_PORT_BASE + 0x68) - -/* GE4 PORT Registers */ -#define RGDE_REG_XGE0_PORT_BASE 0x00001400 -#define RGDE_REG_XGE0_PORT_CTL (RGDE_REG_XGE0_PORT_BASE + 0x00) -#define RGDE_REG_XGE0_PORT_STA (RGDE_REG_XGE0_PORT_BASE + 0x04) -#define RGDE_REG_XGE0_PORT_MTU (RGDE_REG_XGE0_PORT_BASE + 0x08) -#define RGDE_REG_XGE0_PORT_RXPKTS (RGDE_REG_XGE0_PORT_BASE + 0x10) -#define RGDE_REG_XGE0_PORT_RXBYTE (RGDE_REG_XGE0_PORT_BASE + 0x18) -#define RGDE_REG_XGE0_PORT_RXERR (RGDE_REG_XGE0_PORT_BASE + 0x20) -#define RGDE_REG_XGE0_PORT_RXDROP (RGDE_REG_XGE0_PORT_BASE + 0x28) -#define RGDE_REG_XGE0_PORT_RXMULTI (RGDE_REG_XGE0_PORT_BASE + 0x30) -#define RGDE_REG_XGE0_PORT_RXBRO (RGDE_REG_XGE0_PORT_BASE + 0x38) -#define RGDE_REG_XGE0_PORT_TXPKTS (RGDE_REG_XGE0_PORT_BASE + 0x40) -#define RGDE_REG_XGE0_PORT_TXBYTE (RGDE_REG_XGE0_PORT_BASE + 0x48) -#define RGDE_REG_XGE0_PORT_TXERR (RGDE_REG_XGE0_PORT_BASE + 0x50) -#define RGDE_REG_XGE0_PORT_TXDROP (RGDE_REG_XGE0_PORT_BASE + 0x58) -#define RGDE_REG_XGE0_PORT_TXMULT (RGDE_REG_XGE0_PORT_BASE + 0x60) -#define RGDE_REG_XGE0_PORT_TXBRO (RGDE_REG_XGE0_PORT_BASE + 0x68) - -/* GE5 PORT Registers */ -#define RGDE_REG_XGE1_PORT_BASE 0x00001500 -#define RGDE_REG_XGE1_PORT_CTL (RGDE_REG_XGE1_PORT_BASE + 0x00) -#define RGDE_REG_XGE1_PORT_STA (RGDE_REG_XGE1_PORT_BASE + 0x04) -#define RGDE_REG_XGE1_PORT_MTU (RGDE_REG_XGE1_PORT_BASE + 0x08) -#define RGDE_REG_XGE1_PORT_RXPKTS (RGDE_REG_XGE1_PORT_BASE + 0x10) -#define RGDE_REG_XGE1_PORT_RXBYTE (RGDE_REG_XGE1_PORT_BASE + 0x18) -#define RGDE_REG_XGE1_PORT_RXERR (RGDE_REG_XGE1_PORT_BASE + 0x20) -#define RGDE_REG_XGE1_PORT_RXDROP (RGDE_REG_XGE1_PORT_BASE + 0x28) -#define RGDE_REG_XGE1_PORT_RXMULTI (RGDE_REG_XGE1_PORT_BASE + 0x30) -#define RGDE_REG_XGE1_PORT_RXBRO (RGDE_REG_XGE1_PORT_BASE + 0x38) -#define RGDE_REG_XGE1_PORT_TXPKTS (RGDE_REG_XGE1_PORT_BASE + 0x40) -#define RGDE_REG_XGE1_PORT_TXBYTE (RGDE_REG_XGE1_PORT_BASE + 0x48) -#define RGDE_REG_XGE1_PORT_TXERR (RGDE_REG_XGE1_PORT_BASE + 0x50) -#define RGDE_REG_XGE1_PORT_TXDROP (RGDE_REG_XGE1_PORT_BASE + 0x58) -#define RGDE_REG_XGE1_PORT_TXMULT (RGDE_REG_XGE1_PORT_BASE + 0x60) -#define RGDE_REG_XGE1_PORT_TXBRO (RGDE_REG_XGE1_PORT_BASE + 0x68) - -#define RGDE_REG_CPU_BASE 0x00002100 -#define RGDE_REG_PCIE_ENDIAN_CNTR (RGDE_REG_CPU_BASE + 0x08) - -/* DMA Registers */ -#define RGDE_REG_DMA_BASE 0x00004000 -#define RGDE_REG_BD_WR_OVERTIME (RGDE_REG_DMA_BASE + 0x00) -#define RGDE_REG_BD_DEEP (RGDE_REG_DMA_BASE + 0x04) - -/* TX0 Registers */ -#define RGDE_REG_TX0_BASE 0x00005000 -#define RGDE_REG_TX0_CHN_EN (RGDE_REG_TX0_BASE + 0x00) -#define RGDE_REG_TX0_BD_BASE (RGDE_REG_TX0_BASE + 0x04) -#define RGDE_REG_TX0_BD_TAIL (RGDE_REG_TX0_BASE + 0x08) -#define RGDE_REG_TX0_BD_READY_NUM (RGDE_REG_TX0_BASE + 0x0c) -#define RGDE_REG_TX0_CPU2FPGA_BD_NUM (RGDE_REG_TX0_BASE + 0x30) -#define RGDE_REG_TX0_FPGA2CPU_BD_NUM (RGDE_REG_TX0_BASE + 0x34) - -/* TX1 Registers */ -#define RGDE_REG_TX1_BASE 0x00005100 -#define RGDE_REG_TX1_CHN_EN (RGDE_REG_TX1_BASE + 0x00) -#define RGDE_REG_TX1_BD_BASE (RGDE_REG_TX1_BASE + 0x04) -#define RGDE_REG_TX1_BD_TAIL (RGDE_REG_TX1_BASE + 0x08) -#define RGDE_REG_TX1_BD_READY_NUM (RGDE_REG_TX1_BASE + 0x0c) -#define RGDE_REG_TX1_CPU2FPGA_BD_NUM (RGDE_REG_TX1_BASE + 0x30) -#define RGDE_REG_TX1_FPGA2CPU_BD_NUM (RGDE_REG_TX1_BASE + 0x34) - -/* RX0 Registers */ -#define RGDE_REG_RX0_BASE 0x00006400 -#define RGDE_REG_RX0_CHN_EN (RGDE_REG_RX0_BASE + 0x00) -#define RGDE_REG_RX0_BD_BASE (RGDE_REG_RX0_BASE + 0x04) -#define RGDE_REG_RX0_BD_TAIL (RGDE_REG_RX0_BASE + 0x08) -#define RGDE_REG_RX0_BD_READY_NUM (RGDE_REG_RX0_BASE + 0x0c) -#define RGDE_REG_RX0_CPU2FPGA_BD_NUM (RGDE_REG_RX0_BASE + 0x30) -#define RGDE_REG_RX0_FPGA2CPU_BD_NUM (RGDE_REG_RX0_BASE + 0x34) - -/* RX1 Registers */ -#define RGDE_REG_RX1_BASE 0x00006500 -#define RGDE_REG_RX1_CHN_EN (RGDE_REG_RX1_BASE + 0x00) -#define RGDE_REG_RX1_BD_BASE (RGDE_REG_RX1_BASE + 0x04) -#define RGDE_REG_RX1_BD_TAIL (RGDE_REG_RX1_BASE + 0x08) -#define RGDE_REG_RX1_BD_READY_NUM (RGDE_REG_RX1_BASE + 0x0c) -#define RGDE_REG_RX1_CPU2FPGA_BD_NUM (RGDE_REG_RX1_BASE + 0x30) -#define RGDE_REG_RX1_FPGA2CPU_BD_NUM (RGDE_REG_RX1_BASE + 0x34) - - -#endif /* _FPGA_REG_DEFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/i2c-mux-pca954x.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/i2c-mux-pca954x.c deleted file mode 100755 index f7b6bb952bf9..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/i2c-mux-pca954x.c +++ /dev/null @@ -1,1413 +0,0 @@ -/* - * Copyright (c) 2008-2009 Rodolfo Giometti - * Copyright (c) 2008-2009 Eurotech S.p.A. - * Copyright (c) 2019 - * - * I2C multiplexer - * - * This module supports the PCA954x series of I2C multiplexer/switch chips - * made by Philips Semiconductors. - * This includes the: - * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547 - * and PCA9548. - * - * 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 . - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define PCA954X_MAX_NCHANS 8 - -#define PCA954X_IRQ_OFFSET 4 - -extern int pca9641_setmuxflag(int nr, int flag); - -int force_create_bus = 0; -module_param(force_create_bus, int, S_IRUGO | S_IWUSR); - -enum pca_type { - pca_9540, - pca_9542, - pca_9543, - pca_9544, - pca_9545, - pca_9546, - pca_9547, - pca_9548, -}; - -struct chip_desc { - u8 nchans; - u8 enable; /* used for muxes only */ - u8 has_irq; - enum muxtype { - pca954x_ismux = 0, - pca954x_isswi - } muxtype; -}; - - - - -struct pca954x { - const struct chip_desc *chip; - - u8 last_chan; /* last register value */ - u8 deselect; - 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, - }, - [pca_9542] = { - .nchans = 2, - .enable = 0x4, - .has_irq = 1, - .muxtype = pca954x_ismux, - }, - [pca_9543] = { - .nchans = 2, - .has_irq = 1, - .muxtype = pca954x_isswi, - }, - [pca_9544] = { - .nchans = 4, - .enable = 0x4, - .has_irq = 1, - .muxtype = pca954x_ismux, - }, - [pca_9545] = { - .nchans = 4, - .has_irq = 1, - .muxtype = pca954x_isswi, - }, - [pca_9546] = { - .nchans = 4, - .muxtype = pca954x_isswi, - }, - [pca_9547] = { - .nchans = 8, - .enable = 0x8, - .muxtype = pca954x_ismux, - }, - [pca_9548] = { - .nchans = 8, - .muxtype = pca954x_isswi, - }, -}; - -static const struct i2c_device_id pca954x_id[] = { - { "pca9540", pca_9540 }, - { "pca9542", pca_9542 }, - { "pca9543", pca_9543 }, - { "pca9544", pca_9544 }, - { "pca9545", pca_9545 }, - { "pca9546", pca_9546 }, - { "pca9547", pca_9547 }, - { "pca9548", pca_9548 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, pca954x_id); - -#ifdef CONFIG_OF -static const struct of_device_id pca954x_of_match[] = { - { .compatible = "nxp,pca9540", .data = &chips[pca_9540] }, - { .compatible = "nxp,pca9542", .data = &chips[pca_9542] }, - { .compatible = "nxp,pca9543", .data = &chips[pca_9543] }, - { .compatible = "nxp,pca9544", .data = &chips[pca_9544] }, - { .compatible = "nxp,pca9545", .data = &chips[pca_9545] }, - { .compatible = "nxp,pca9546", .data = &chips[pca_9546] }, - { .compatible = "nxp,pca9547", .data = &chips[pca_9547] }, - { .compatible = "nxp,pca9548", .data = &chips[pca_9548] }, - {} -}; -MODULE_DEVICE_TABLE(of, pca954x_of_match); -#endif - -/* 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) -{ - int ret = -ENODEV; - - if (adap->algo->master_xfer) { - struct i2c_msg msg; - char buf[1]; - - msg.addr = client->addr; - msg.flags = 0; - msg.len = 1; - buf[0] = val; - msg.buf = buf; - ret = __i2c_transfer(adap, &msg, 1); - - if (ret >= 0 && ret != 1) - ret = -EREMOTEIO; - } else { - union i2c_smbus_data data; - ret = adap->algo->smbus_xfer(adap, client->addr, - client->flags, - I2C_SMBUS_WRITE, - val, I2C_SMBUS_BYTE, &data); - } - - return ret; -} - -static int pca954x_setmuxflag(struct i2c_client *client, int flag) -{ - struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); - pca9641_setmuxflag(adap->nr, flag); - return 0; -} - -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; - const struct chip_desc *chip = data->chip; - u8 regval; - int ret = 0; - - /* we make switches look like muxes, not sure how to be smarter */ - if (chip->muxtype == pca954x_ismux) - regval = chan | chip->enable; - else - regval = 1 << chan; - - /* Only select the channel if its different from the last channel */ - if (data->last_chan != regval) { - pca954x_setmuxflag(client, 0); - ret = pca954x_reg_write(muxc->parent, client, regval); - data->last_chan = ret < 0 ? 0 : regval; - } - - return ret; -} - - -typedef void (*pca954x_hw_do_reset_func_t)(int busid, int addr); -pca954x_hw_do_reset_func_t g_notify_to_do_reset = NULL; - -void pca954x_hw_do_reset_func_register(void* func) -{ - if (func == NULL) { - return ; - } - g_notify_to_do_reset = func; - return; -} -EXPORT_SYMBOL(pca954x_hw_do_reset_func_register); - -static int pca954x_hw_do_reset(int busid, int addr) -{ - if (g_notify_to_do_reset != NULL) { - (*g_notify_to_do_reset)(busid, addr); - return 0; - } - - return 0; -} -/***************************************9548 reset*****************************************/ -#define DEV_TYPE 0x404a -#define PCA9548_MAX_CPLD_NUM (32) /* PCA9548 max number */ -#define PCA9548_MAX_CPLD_LAYER (8) /* PCA9548 max layer */ -#define DFD_PID_BUF_LEN (32) -#define DFD_PRODUCT_ID_LENGTH (8) -#define CPLD_PCA9548_RESET 0x023500b0 /* bus:2, addr:0x35, offset:0xb0 */ -#define B6510_32CQ_CPLD_PCA9548_RESET 0x060d0060 /* bus:6, addr:0x0d, offset:0x60 */ - -#define DFD_PUB_CARDTYPE_FILE "/sys/module/ragile_common/parameters/dfd_my_type" -#define DFD_MAX_PRODUCT_NUM (32) - - -#define I2C_RETRY_TIMES 5 -#define I2C_RETRY_WAIT_TIMES 10 /*delay 10ms*/ - -#define PCA9548_I2C_GET_BUS(addr) (((addr) >> 24) & 0x00ff) -#define PCA9548_I2C_GET_CLIENT(addr) (((addr) >> 16) & 0x00ff) -#define PCA9548_I2C_GET_OFFSET(addr) (addr & 0xffff) - -typedef enum pca9548_reset_type { - PCA9548_RESET_FUNC = 0, - PCA9548_RESET_GPIO = 1, -} pca9548_reset_type_t; - -typedef void (*pca954x_hw_do_reset_func_t_new)(int io_port, u8 value); -typedef u8 (*pca954x_get_umask_func_t)(int io_port); - -void pca954x_hw_do_reset_by_i2c(int addr, u8 value); -u8 pca954x_get_umask_by_i2c(int addr); -void pca954x_hw_do_reset_by_lpc(int io_port, u8 value); -u8 pca954x_get_umask_by_lpc(int io_port); - - -typedef struct func_attr_s { - int cfg_offset[PCA9548_MAX_CPLD_LAYER]; - int umask[PCA9548_MAX_CPLD_LAYER]; - pca954x_hw_do_reset_func_t_new reset_func; /* 9548 reset function */ - pca954x_get_umask_func_t get_umask_func; /* get reset mask */ -} func_attr_t; - -typedef struct gpio_attr_s { - int gpio; - int gpio_init; - u8 reset_on; - u8 reset_off; -} gpio_attr_t; - -typedef struct pca9548_cfg_info_s { - int pca9548_reset_type; - int pca9548_bus; - int pca9548_addr; - int rst_delay_b; /* delay time before reset(us) */ - int rst_delay; /* reset time(us) */ - int rst_delay_a; /* delay time after reset(us) */ - union { - func_attr_t func_attr; - gpio_attr_t gpio_attr; - } attr; -} pca9548_cfg_info_t; - -typedef struct fpga_pcie_card_info_s { - int dev_type[DFD_MAX_PRODUCT_NUM]; /* dev type */ - pca9548_cfg_info_t pca9548_cfg_info[PCA9548_MAX_CPLD_NUM]; -} pca9548_card_info_t; - -static pca9548_card_info_t g_pca9548_card_info[] = { - { - .dev_type = {0x404a}, /* RA-B6510-48V8C */ - .pca9548_cfg_info = { - /* psu fan */ - { - .pca9548_reset_type = PCA9548_RESET_GPIO, - .pca9548_bus = 2, - .pca9548_addr = 0x70, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .gpio_attr.gpio = 7, - .gpio_attr.gpio_init = 0, - .gpio_attr.reset_on = 1, - .gpio_attr.reset_off = 0, - }, - }, - /* sff1 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x70, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(0), -1}, - }, - }, - /* sff2 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x71, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(1), -1}, - }, - }, - /* sff3 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x72, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(2), -1}, - }, - }, - /* sff4 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x73, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(3), -1}, - }, - }, - /* sff5 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x74, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(4), -1}, - }, - }, - /* sff6 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x75, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(5), -1}, - }, - }, - /* sff7 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x76, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(6), -1}, - }, - }, - }, - }, - { - /*RA-B6910-64C*/ - .dev_type = {0x404c}, - .pca9548_cfg_info = { - /* psu fan */ - { - .pca9548_reset_type = PCA9548_RESET_GPIO, - .pca9548_bus = 2, - .pca9548_addr = 0x70, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .gpio_attr.gpio = 7, - .gpio_attr.gpio_init = 0, - .gpio_attr.reset_on = 1, - .gpio_attr.reset_off = 0, - }, - }, - /* sff1 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x70, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(0), -1}, - }, - }, - /* sff2 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x71, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(1), -1}, - }, - }, - /* sff3 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x72, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(2), -1}, - }, - }, - /* sff4 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x73, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(3), -1}, - }, - }, - /* sff5 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x74, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(4), -1}, - }, - }, - /* sff6 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x75, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(5), -1}, - }, - }, - /* sff7 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x76, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(6), -1}, - }, - }, - /* sff8 */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 1, - .pca9548_addr = 0x77, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_i2c, - .func_attr.get_umask_func = pca954x_get_umask_by_i2c, - .func_attr.cfg_offset = {CPLD_PCA9548_RESET, -1}, - .func_attr.umask = {BIT(7), -1}, - }, - }, - }, - }, - { - /* RA-B6510-32C */ - .dev_type = {0x404b}, - .pca9548_cfg_info = { - /* psu */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 4, - .pca9548_addr = 0x77, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_lpc, - .func_attr.get_umask_func = pca954x_get_umask_by_lpc, - .func_attr.cfg_offset = {0x960, -1}, - .func_attr.umask = {BIT(0), -1}, - }, - }, - /* fan */ - { - .pca9548_reset_type = PCA9548_RESET_FUNC, - .pca9548_bus = 2, - .pca9548_addr = 0x77, - .rst_delay_b = 0, - .rst_delay = 1000, - .rst_delay_a = 1000, - .attr = { - .func_attr.reset_func = pca954x_hw_do_reset_by_lpc, - .func_attr.get_umask_func = pca954x_get_umask_by_lpc, - .func_attr.cfg_offset = {0x960, -1}, - .func_attr.umask = {BIT(1), -1}, - }, - }, - }, - }, -}; -int g_pca954x_debug = 0; -module_param(g_pca954x_debug, int, S_IRUGO | S_IWUSR); - -#define PCA954X_DEBUG(fmt, args...) do { \ - if (g_pca954x_debug) { \ - printk(KERN_ERR "[PCA95x][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - - -static int dfd_get_my_dev_type_by_file(void) -{ - struct file *fp; - /* mm_segment_t fs;*/ - loff_t pos; - static int card_type; - char buf[DFD_PID_BUF_LEN]; - - if (card_type != 0) { - return card_type; - } - - fp= filp_open(DFD_PUB_CARDTYPE_FILE, O_RDONLY, 0); - if (IS_ERR(fp)) { - PCA954X_DEBUG("open file fail!\r\n"); - return -1; - } - /* fs = get_fs(); */ - /* set_fs(KERNEL_DS); */ - memset(buf, 0, DFD_PID_BUF_LEN); - pos = 0; - kernel_read(fp, buf, DFD_PRODUCT_ID_LENGTH + 1, &pos); - // kernel_read(fp, pos, buf, DFD_PRODUCT_ID_LENGTH + 1 ); - if (pos < 0) { - PCA954X_DEBUG("read file fail!\r\n"); - goto exit; - } - - card_type = simple_strtoul(buf, NULL, 10); - PCA954X_DEBUG("card_type 0x%x.\n", card_type); - -exit: - /* set_fs(fs); */ - filp_close(fp, NULL); - return card_type; -} - -static int drv_get_my_dev_type(void) -{ - static int type = -1; - - if (type > 0) { - return type; - } - type = dfd_get_my_dev_type_by_file(); - PCA954X_DEBUG("ko board type %d\r\n", type); - - return type; -} - -pca9548_card_info_t* pca9548_get_card_info(int dev_type) -{ - int i, j; - int size; - - size = ARRAY_SIZE(g_pca9548_card_info); - - PCA954X_DEBUG("Enter dev_type 0x%x size %d.\n", dev_type, size); - for (i = 0; i < size; i++) { - for(j = 0; j < DFD_MAX_PRODUCT_NUM; j++) { - if (g_pca9548_card_info[i].dev_type[j] == dev_type) { - PCA954X_DEBUG("match dev_type 0x%x.\n", dev_type); - return &g_pca9548_card_info[i]; - } - } - } - - PCA954X_DEBUG("dismatch dev_type 0x%x.\n", dev_type); - return NULL; -} - -pca9548_cfg_info_t* get_pca9548_cfg_info(int bus, int addr) -{ - int dev_type; - pca9548_card_info_t *info; - pca9548_cfg_info_t *pca9548_cfg_info; - int i; - int size; - - dev_type = drv_get_my_dev_type(); - if (dev_type < 0) { - PCA954X_DEBUG("drv_get_my_dev_type failed ret %d.\n", dev_type); - return NULL; - } - - info = pca9548_get_card_info(dev_type); - if (info == NULL) { - PCA954X_DEBUG("fpga_pcie_get_card_info dev_type %d failed.\n", dev_type); - return NULL; - } - - size = PCA9548_MAX_CPLD_NUM; - for (i = 0; i < size; i++) { - pca9548_cfg_info = &(info->pca9548_cfg_info[i]); - if ((pca9548_cfg_info->pca9548_bus == bus) && (pca9548_cfg_info->pca9548_addr == addr)) { - PCA954X_DEBUG("match dev_type 0x%x bus %d addr 0x%x.\n", dev_type, bus, addr); - return pca9548_cfg_info; - } - } - - PCA954X_DEBUG("dismatch dev_type 0x%x bus %d addr 0x%x.\n", dev_type, bus, addr); - return NULL; -} - -static void pca9548_gpio_init(gpio_attr_t *gpio_attr) -{ - if (gpio_attr->gpio_init == 0) { - PCA954X_DEBUG("gpio%d init.\n", gpio_attr->gpio); - gpio_request(gpio_attr->gpio, "pca9548_reset"); - gpio_direction_output(gpio_attr->gpio, gpio_attr->reset_off); - gpio_attr->gpio_init = 1; - } -} - -static void pca9548_gpio_free(gpio_attr_t *gpio_attr) -{ - if (gpio_attr == NULL) { - PCA954X_DEBUG("pca9548_gpio_free,params error\n"); - return ; - } - if (gpio_attr->gpio_init == 1) { - PCA954X_DEBUG("gpio%d release.\n", gpio_attr->gpio); - gpio_free(gpio_attr->gpio); - gpio_attr->gpio_init = 0; - } -} - -static int pca954x_do_gpio_reset(pca9548_cfg_info_t *cfg_info, struct i2c_adapter *adap, - struct i2c_client *client, u32 chan) -{ - struct i2c_mux_core *muxc = i2c_get_clientdata(client); - struct pca954x *data = i2c_mux_priv(muxc); - int ret = -1; - gpio_attr_t *tmp_gpio_attr; - int timeout; - int val; - struct i2c_adapter *adapter; - int adapter_timeout; - - if (cfg_info == NULL) { - PCA954X_DEBUG("pca9548 cfg info is null.\n"); - return ret; - } - - if (cfg_info->pca9548_reset_type == PCA9548_RESET_GPIO) { - tmp_gpio_attr = &(cfg_info->attr.gpio_attr); - timeout = cfg_info->rst_delay_a; - - pca9548_gpio_init(tmp_gpio_attr); - udelay(cfg_info->rst_delay_b); - /* reset on */ - PCA954X_DEBUG("set gpio%d %d.\n", tmp_gpio_attr->gpio, tmp_gpio_attr->reset_on); - __gpio_set_value(tmp_gpio_attr->gpio, tmp_gpio_attr->reset_on); - udelay(cfg_info->rst_delay); - /* reset off */ - PCA954X_DEBUG("set gpio%d %d.\n", tmp_gpio_attr->gpio, tmp_gpio_attr->reset_off); - __gpio_set_value(tmp_gpio_attr->gpio, tmp_gpio_attr->reset_off); - - while (timeout > 0) { - udelay(1); - val = __gpio_get_value(tmp_gpio_attr->gpio); - if (val == tmp_gpio_attr->reset_off) { - adapter = adap; - /* get bus info */ - while(i2c_parent_is_i2c_adapter(adapter)){ - adapter = to_i2c_adapter(adapter->dev.parent); - } - - adapter_timeout = adapter->timeout; - adapter->timeout = msecs_to_jiffies(50); - pca954x_reg_write(adap, client, data->last_chan); - adapter->timeout = adapter_timeout; - ret = 0; - PCA954X_DEBUG("pca954x_do_gpio_reset success.\n"); - break; - } - - if (timeout >= 1000 && (timeout % 1000 == 0)) { - /* 1MS schedule*/ - schedule(); - } - timeout--; - } - - if (ret) { - PCA954X_DEBUG("pca954x_do_gpio_reset failed.\n"); - } - pca9548_gpio_free(&(cfg_info->attr.gpio_attr)); - } else { - PCA954X_DEBUG("pca9548_reset_type invalid, pca954x_do_gpio_reset failed.\n"); - } - - return ret; -} - -static int pca954x_do_func_reset(pca9548_cfg_info_t *cfg_info, struct i2c_adapter *adap, - struct i2c_client *client, u32 chan) -{ - struct i2c_mux_core *muxc = i2c_get_clientdata(client); - struct pca954x *data = i2c_mux_priv(muxc); - int ret = -1; - func_attr_t *tmp_func_attr; - int timeout; - int val; - struct i2c_adapter *adapter; - int adapter_timeout; - int i; - u8 old_value; - - if (cfg_info == NULL) { - PCA954X_DEBUG("pca9548 cfg info is null.\n"); - return ret; - } - - if (cfg_info->pca9548_reset_type == PCA9548_RESET_FUNC) { - tmp_func_attr = &(cfg_info->attr.func_attr); - timeout = cfg_info->rst_delay_a; - - if ((tmp_func_attr->reset_func == NULL) || (tmp_func_attr->get_umask_func == NULL)) { - PCA954X_DEBUG("pca954x hw do reset func or get umask func is null.\n"); - return ret; - } - - for(i = 0; (i < PCA9548_MAX_CPLD_LAYER) && (tmp_func_attr->cfg_offset[i] != -1) - && (tmp_func_attr->umask[i] != -1); i++) { - old_value = (*tmp_func_attr->get_umask_func)(tmp_func_attr->cfg_offset[i]); - PCA954X_DEBUG("cfg info: offset:0x%x umask:0x%x, old_value:0x%x\n", - tmp_func_attr->cfg_offset[i], tmp_func_attr->umask[i],old_value); - (*tmp_func_attr->reset_func)(tmp_func_attr->cfg_offset[i], old_value & ~tmp_func_attr->umask[i]); - udelay(cfg_info->rst_delay); - (*tmp_func_attr->reset_func)(tmp_func_attr->cfg_offset[i], old_value | tmp_func_attr->umask[i]); - } - - while (timeout > 0) { - udelay(1); - val = (*tmp_func_attr->get_umask_func)(tmp_func_attr->cfg_offset[i - 1]); - val &= (tmp_func_attr->umask[i - 1]); - if (val == tmp_func_attr->umask[i - 1]) { - adapter = adap; - /* get bus info */ - while(i2c_parent_is_i2c_adapter(adapter)){ - adapter = to_i2c_adapter(adapter->dev.parent); - } - - adapter_timeout = adapter->timeout; - adapter->timeout = msecs_to_jiffies(50); - pca954x_reg_write(adap, client, data->last_chan); - adapter->timeout = adapter_timeout; - ret = 0; - PCA954X_DEBUG("pca954x_do_func_reset success.\n"); - break; - } - - if (timeout >= 1000 && (timeout % 1000 == 0)) { - /* 1MS schedule*/ - schedule(); - } - timeout--; - } - - if (ret) { - PCA954X_DEBUG("pca954x_do_func_reset failed.\n"); - } - } else { - PCA954X_DEBUG("pca9548_reset_type invalid, pca954x_do_func_reset failed.\n"); - } - - return ret; -} - -static int pca9548_reset_ctrl(pca9548_cfg_info_t *cfg_info, struct i2c_adapter *adap, - struct i2c_client *client, u32 chan) -{ - int ret = -1; - - if (cfg_info == NULL) { - PCA954X_DEBUG("pca9548 cfg info is null.\n"); - return ret; - } - - if (cfg_info->pca9548_reset_type == PCA9548_RESET_FUNC) { - ret = pca954x_do_func_reset(cfg_info, adap, client, chan); - } else if (cfg_info->pca9548_reset_type == PCA9548_RESET_GPIO) { - ret = pca954x_do_gpio_reset(cfg_info, adap, client, chan); - } - - if (ret < 0) { - PCA954X_DEBUG("pca9548_reset_ctrl failed.\n"); - } - return ret; -} - -static int pca954x_reset_i2c_read(uint32_t bus, uint32_t addr, uint32_t offset_addr, - unsigned char *buf, uint32_t size) -{ - struct file *fp; - /* mm_segment_t fs; */ - struct i2c_client client; - char i2c_path[32]; - int i ,j ; - int rv; - - rv = 0; - memset(i2c_path, 0, 32); - snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); - fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); - if (IS_ERR(fp)) { - PCA954X_DEBUG("i2c open fail.\n"); - return -1; - } - memcpy(&client, fp->private_data, sizeof(struct i2c_client)); - client.addr = addr; - /* fs = get_fs(); */ - /* set_fs(KERNEL_DS); */ - for (j = 0 ;j < size ;j++){ - for (i = 0; i < I2C_RETRY_TIMES; i++) { - rv = i2c_smbus_read_byte_data(&client, (offset_addr + j)); - if (rv < 0) { - PCA954X_DEBUG("i2c read failed, try again.\n"); - msleep(I2C_RETRY_WAIT_TIMES); - if (i >= (I2C_RETRY_TIMES - 1)) { - goto out; - } - continue; - } - *(buf + j) = (unsigned char)rv; - break; - } - } -out: - filp_close(fp, NULL); - /* set_fs(fs); */ - return rv; -} - -static int pca954x_reset_i2c_write(uint32_t bus, uint32_t dev_addr, uint32_t offset_addr, - uint8_t write_buf) -{ - struct file *fp; - /* mm_segment_t fs; */ - struct i2c_client client; - char i2c_path[32]; - int i; - int rv; - - rv = 0; - memset(i2c_path, 0, 32); - snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); - fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); - if (IS_ERR(fp)) { - PCA954X_DEBUG("i2c open fail.\n"); - return -1; - } - memcpy(&client, fp->private_data, sizeof(struct i2c_client)); - client.addr = dev_addr; - /* fs = get_fs(); */ - /* set_fs(KERNEL_DS); */ - for (i = 0; i < I2C_RETRY_TIMES; i++) { - rv = i2c_smbus_write_byte_data(&client, offset_addr, write_buf); - if (rv < 0) { - PCA954X_DEBUG("i2c write failed, try again.\n"); - msleep(I2C_RETRY_WAIT_TIMES); - if (i >= (I2C_RETRY_TIMES - 1)) { - goto out; - } - continue; - } - break; - } -out: - filp_close(fp, NULL); - /* set_fs(fs); */ - return rv; -} - -int pca954x_reset_reg_i2c_read_byte(int addr, u8 *value) -{ - int bus; - int client_addr; - int offset; - int ret; - - bus = PCA9548_I2C_GET_BUS(addr); - client_addr = PCA9548_I2C_GET_CLIENT(addr); - offset = PCA9548_I2C_GET_OFFSET(addr); - - ret = pca954x_reset_i2c_read(bus, client_addr, offset, value, 1); - if (ret < 0) { - PCA954X_DEBUG(" 0x%x read fail\r\n", addr); - goto end; - } -end: - return ret; -} - -int pca954x_reset_reg_i2c_write_byte(int addr, u8 value) -{ - int bus; - int client_addr; - int offset; - int ret; - - bus = PCA9548_I2C_GET_BUS(addr); - client_addr = PCA9548_I2C_GET_CLIENT(addr); - offset = PCA9548_I2C_GET_OFFSET(addr); - - ret = pca954x_reset_i2c_write(bus, client_addr, offset, value); - if (ret < 0) { - PCA954X_DEBUG(" 0x%x write fail\r\n", addr); - goto end; - } -end: - return ret; -} - -void pca954x_hw_do_reset_by_i2c(int addr, u8 value) -{ - int ret; - - PCA954X_DEBUG("write i2c cpld[0x%x], value[%d]\n", addr, value); - ret = pca954x_reset_reg_i2c_write_byte(addr, value); - if (ret < 0) { - PCA954X_DEBUG("write cpld pca9548 reset reg failed, ret = %d \n", ret); - } -} - -u8 pca954x_get_umask_by_i2c(int addr) -{ - u8 value = 0xFF; - int ret; - - ret = pca954x_reset_reg_i2c_read_byte(addr, &value); - PCA954X_DEBUG("read i2c cpld[0x%x], value[%d], ret = %d\n", addr, value, ret); - - return value; -} - -void pca954x_hw_do_reset_by_lpc(int io_port, u8 value) -{ - PCA954X_DEBUG("write lpc offset[0x%x], value[%d]\n", (u16)io_port, value); - outb(value, (u16)io_port); -} - -u8 pca954x_get_umask_by_lpc(int io_port) -{ - u8 value; - - value = inb(io_port); - PCA954X_DEBUG("read lpc offset[0x%x], value[%d]\n", (u16)io_port, value); - - return value; -} - -int pca954x_hw_do_reset_new(struct i2c_adapter *adap, - struct i2c_client *client, u32 chan) -{ - pca9548_cfg_info_t *cfg_info; - int ret = -1; - - cfg_info = get_pca9548_cfg_info(adap->nr, client->addr); - if (cfg_info == NULL && g_notify_to_do_reset == NULL) { - PCA954X_DEBUG("fpga_do_pca954x_reset_func do nothing.\n"); - return ret; - } - if(cfg_info != NULL) { - ret = pca9548_reset_ctrl(cfg_info, adap, client, chan); - } else { - ret = pca954x_hw_do_reset(adap->nr, client->addr); - } - if (ret < 0) { - PCA954X_DEBUG("pca954x_hw_do_reset failed.\n"); - } - return ret; -} -/******************************end 9548 reset***********************************/ - -static int pca954x_do_reset(struct i2c_adapter *adap, - void *client, u32 chan) -{ - struct i2c_client *new_client; - int ret = -1; - - PCA954X_DEBUG("do pca954x reset x86\n"); - new_client =(struct i2c_client *) client; - ret = pca954x_hw_do_reset_new(adap, new_client, chan); - if (ret < 0) { - PCA954X_DEBUG("pca954x_do_reset failed.\n"); - return ret; - } - - PCA954X_DEBUG("pca954x_do_reset success.\n"); - ret = 0; - 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; - int ret, rv; - struct i2c_client * new_client; - - /* Deselect active channel */ - data->last_chan = 0; - - ret = pca954x_reg_write(muxc->parent, client, data->last_chan); - if (ret < 0) { - new_client =(struct i2c_client *) client; - dev_warn(&new_client->dev, "pca954x close chn failed, do reset.\n"); - rv = pca954x_do_reset(client->adapter, client, chan); - if (rv == 0) { - ret = 0; - } - - } - pca954x_setmuxflag(client, 1); - (void)pca954x_reg_write(muxc->parent, client, data->last_chan); - - return ret; - -} - -static irqreturn_t pca954x_irq_handler(int irq, void *dev_id) -{ - struct pca954x *data = dev_id; - unsigned int child_irq; - int ret, i, handled = 0; - - ret = i2c_smbus_read_byte(data->client); - if (ret < 0) - return IRQ_NONE; - - for (i = 0; i < data->chip->nchans; i++) { - if (ret & BIT(PCA954X_IRQ_OFFSET + i)) { - child_irq = irq_linear_revmap(data->irq, i); - handle_nested_irq(child_irq); - handled++; - } - } - return handled ? IRQ_HANDLED : IRQ_NONE; -} - -static void pca954x_irq_mask(struct irq_data *idata) -{ - struct pca954x *data = irq_data_get_irq_chip_data(idata); - unsigned int pos = idata->hwirq; - unsigned long flags; - - raw_spin_lock_irqsave(&data->lock, flags); - - data->irq_mask &= ~BIT(pos); - if (!data->irq_mask) - disable_irq(data->client->irq); - - raw_spin_unlock_irqrestore(&data->lock, flags); -} - -static void pca954x_irq_unmask(struct irq_data *idata) -{ - struct pca954x *data = irq_data_get_irq_chip_data(idata); - unsigned int pos = idata->hwirq; - unsigned long flags; - - raw_spin_lock_irqsave(&data->lock, flags); - - if (!data->irq_mask) - enable_irq(data->client->irq); - data->irq_mask |= BIT(pos); - - raw_spin_unlock_irqrestore(&data->lock, flags); -} - -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_mask = pca954x_irq_mask, - .irq_unmask = pca954x_irq_unmask, - .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, err, 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); - irq_set_chip_data(irq, data); - irq_set_chip_and_handler(irq, &pca954x_irq_chip, - handle_simple_irq); - } - - err = devm_request_threaded_irq(&client->dev, data->client->irq, NULL, - pca954x_irq_handler, - IRQF_ONESHOT | IRQF_SHARED, - "pca954x", data); - if (err) - goto err_req_irq; - - disable_irq(data->client->irq); - - return 0; -err_req_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); - - return err; -} - -/* - * I2C init/probing/exit functions - */ -static int pca954x_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); - struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); - struct device_node *of_node = client->dev.of_node; - bool idle_disconnect_dt; - struct gpio_desc *gpio; - int num, force, class; - struct i2c_mux_core *muxc; - struct pca954x *data; - const struct of_device_id *match; - int ret; - - - if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) - return -ENODEV; - - muxc = i2c_mux_alloc(adap, &client->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; - - /* Get the mux out of reset if a reset GPIO is specified. */ - gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(gpio)) - return PTR_ERR(gpio); - - /* Write the mux register at addr to verify - * that the mux is in fact present. This also - * initializes the mux to disconnected state. - */ - if ((i2c_smbus_write_byte(client, 0) < 0) && (force_create_bus == 0)) { - dev_warn(&client->dev, "probe failed\n"); - return -ENODEV; - } - - match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev); - if (match) - data->chip = of_device_get_match_data(&client->dev); - else - data->chip = &chips[id->driver_data]; - - data->last_chan = 0; /* force the first selection */ - - idle_disconnect_dt = of_node && - of_property_read_bool(of_node, "i2c-mux-idle-disconnect"); - - ret = pca954x_irq_setup(muxc); - if (ret) - goto fail_del_adapters; - - /* Now create an adapter for each channel */ - for (num = 0; num < data->chip->nchans; num++) { - bool idle_disconnect_pd = false; - - force = 0; /* dynamic adap number */ - class = 0; /* no class by default */ - if (pdata) { - if (num < pdata->num_modes) { - /* force static number */ - force = pdata->modes[num].adap_id; - class = pdata->modes[num].class; - } else - /* discard unconfigured channels */ - break; - idle_disconnect_pd = pdata->modes[num].deselect_on_exit; - } - data->deselect |= (idle_disconnect_pd || - idle_disconnect_dt) << num; - - ret = i2c_mux_add_adapter(muxc, force, num, class); - if (ret) - goto fail_del_adapters; - } - - dev_info(&client->dev, - "registered %d multiplexed busses for I2C %s %s\n", - num, data->chip->muxtype == pca954x_ismux - ? "mux" : "switch", client->name); - - return 0; - -fail_del_adapters: - i2c_mux_del_adapters(muxc); - return ret; -} - -static int pca954x_remove(struct i2c_client *client) -{ - struct i2c_mux_core *muxc = i2c_get_clientdata(client); - 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); - 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); - - data->last_chan = 0; - return i2c_smbus_write_byte(client, 0); -} -#endif - -static SIMPLE_DEV_PM_OPS(pca954x_pm, NULL, pca954x_resume); - -static struct i2c_driver pca954x_driver = { - .driver = { - .name = "pca954x", - .pm = &pca954x_pm, - .of_match_table = of_match_ptr(pca954x_of_match), - }, - .probe = pca954x_probe, - .remove = pca954x_remove, - .id_table = pca954x_id, -}; - -module_i2c_driver(pca954x_driver); - -MODULE_AUTHOR("support support@ragile.com"); -MODULE_DESCRIPTION("PCA954x I2C mux/switch driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/i2c-mux-pca9641.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/i2c-mux-pca9641.c deleted file mode 100755 index 501cfef8a91b..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/i2c-mux-pca9641.c +++ /dev/null @@ -1,643 +0,0 @@ -/* - * I2C multiplexer driver for PCA9541 bus master selector - * - * Copyright (c) 2010 Ericsson AB. - * Copyright (c) 2019 - * Author: Guenter Roeck - * - * Derived from: - * pca954x.c - * - * Copyright (c) 2008-2009 Rodolfo Giometti - * Copyright (c) 2008-2009 Eurotech S.p.A. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * The PCA9541 is a bus master selector. It supports two I2C masters connected - * to a single slave bus. - * - * Before each bus transaction, a master has to acquire bus ownership. After the - * transaction is complete, bus ownership has to be released. This fits well - * into the I2C multiplexer framework, which provides select and release - * functions for this purpose. For this reason, this driver is modeled as - * single-channel I2C bus multiplexer. - * - * This driver assumes that the two bus masters are controlled by two different - * hosts. If a single host controls both masters, platform code has to ensure - * that only one of the masters is instantiated at any given time. - */ - -#define PCA9541_CONTROL 0x01 -#define PCA9541_ISTAT 0x02 - -#define PCA9541_CTL_MYBUS (1 << 0) -#define PCA9541_CTL_NMYBUS (1 << 1) -#define PCA9541_CTL_BUSON (1 << 2) -#define PCA9541_CTL_NBUSON (1 << 3) -#define PCA9541_CTL_BUSINIT (1 << 4) -#define PCA9541_CTL_TESTON (1 << 6) -#define PCA9541_CTL_NTESTON (1 << 7) -#define PCA9541_ISTAT_INTIN (1 << 0) -#define PCA9541_ISTAT_BUSINIT (1 << 1) -#define PCA9541_ISTAT_BUSOK (1 << 2) -#define PCA9541_ISTAT_BUSLOST (1 << 3) -#define PCA9541_ISTAT_MYTEST (1 << 6) -#define PCA9541_ISTAT_NMYTEST (1 << 7) -#define PCA9641_ID 0x00 -#define PCA9641_ID_MAGIC 0x38 -#define PCA9641_CONTROL 0x01 -#define PCA9641_STATUS 0x02 -#define PCA9641_TIME 0x03 -#define PCA9641_CTL_LOCK_REQ BIT(0) -#define PCA9641_CTL_LOCK_GRANT BIT(1) -#define PCA9641_CTL_BUS_CONNECT BIT(2) -#define PCA9641_CTL_BUS_INIT BIT(3) -#define PCA9641_CTL_SMBUS_SWRST BIT(4) -#define PCA9641_CTL_IDLE_TIMER_DIS BIT(5) -#define PCA9641_CTL_SMBUS_DIS BIT(6) -#define PCA9641_CTL_PRIORITY BIT(7) -#define PCA9641_STS_OTHER_LOCK BIT(0) -#define PCA9641_STS_BUS_INIT_FAIL BIT(1) -#define PCA9641_STS_BUS_HUNG BIT(2) -#define PCA9641_STS_MBOX_EMPTY BIT(3) -#define PCA9641_STS_MBOX_FULL BIT(4) -#define PCA9641_STS_TEST_INT BIT(5) -#define PCA9641_STS_SCL_IO BIT(6) -#define PCA9641_STS_SDA_IO BIT(7) -#define PCA9641_RES_TIME 0x03 -#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) -#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) -#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) -#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) -#define BUSOFF(x, y) (!((x) & PCA9641_CTL_LOCK_GRANT) && \ - !((y) & PCA9641_STS_OTHER_LOCK)) -#define other_lock(x) ((x) & PCA9641_STS_OTHER_LOCK) -#define lock_grant(x) ((x) & PCA9641_CTL_LOCK_GRANT) - -#define PCA9641_RETRY_TIME 8 - -typedef struct i2c_muxs_struct_flag -{ - int nr; - char name[48]; - struct mutex update_lock; - int flag; -}i2c_mux_flag; - -i2c_mux_flag pca_flag = { - .flag = -1, -}; - -int pca9641_setmuxflag(int nr, int flag) -{ - if (pca_flag.nr == nr) { - pca_flag.flag = flag; - } - return 0; -} -EXPORT_SYMBOL(pca9641_setmuxflag); - -int g_debug = 0; -module_param(g_debug, int, S_IRUGO | S_IWUSR); - -#define PCA_DEBUG(fmt, args...) do { \ - if (g_debug) { \ - printk(KERN_ERR "[pca9641][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - - -/* arbitration timeouts, in jiffies */ -#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */ -#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */ - -/* arbitration retry delays, in us */ -#define SELECT_DELAY_SHORT 50 -#define SELECT_DELAY_LONG 1000 - -struct pca9541 { - struct i2c_client *client; - unsigned long select_timeout; - unsigned long arb_timeout; -}; - -static const struct i2c_device_id pca9541_id[] = { - {"pca9541", 0}, - {"pca9641", 1}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, pca9541_id); - -#ifdef CONFIG_OF -static const struct of_device_id pca9541_of_match[] = { - { .compatible = "nxp,pca9541" }, - { .compatible = "nxp,pca9641" }, - {} -}; -MODULE_DEVICE_TABLE(of, pca9541_of_match); -#endif - - -/* - * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() - * as they will try to lock the adapter a second time. - */ -static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val) -{ - struct i2c_adapter *adap = client->adapter; - int ret; - - if (adap->algo->master_xfer) { - struct i2c_msg msg; - char buf[2]; - - msg.addr = client->addr; - msg.flags = 0; - msg.len = 2; - buf[0] = command; - buf[1] = val; - msg.buf = buf; - ret = __i2c_transfer(adap, &msg, 1); - } else { - union i2c_smbus_data data; - - data.byte = val; - ret = adap->algo->smbus_xfer(adap, client->addr, - client->flags, - I2C_SMBUS_WRITE, - command, - I2C_SMBUS_BYTE_DATA, &data); - } - - return ret; -} - -/* - * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer() - * as they will try to lock adapter a second time. - */ -static int pca9541_reg_read(struct i2c_client *client, u8 command) -{ - struct i2c_adapter *adap = client->adapter; - int ret; - u8 val; - - if (adap->algo->master_xfer) { - struct i2c_msg msg[2] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = &command - }, - { - .addr = client->addr, - .flags = I2C_M_RD, - .len = 1, - .buf = &val - } - }; - ret = __i2c_transfer(adap, msg, 2); - if (ret == 2) - ret = val; - else if (ret >= 0) - ret = -EIO; - } else { - union i2c_smbus_data data; - - ret = adap->algo->smbus_xfer(adap, client->addr, - client->flags, - I2C_SMBUS_READ, - command, - I2C_SMBUS_BYTE_DATA, &data); - if (!ret) - ret = data.byte; - } - return ret; -} - -/* - * Arbitration management functions - */ - -/* Release bus. Also reset NTESTON and BUSINIT if it was set. */ -static void pca9541_release_bus(struct i2c_client *client) -{ - int reg; - - reg = pca9541_reg_read(client, PCA9541_CONTROL); - if (reg >= 0 && !busoff(reg) && mybus(reg)) - pca9541_reg_write(client, PCA9541_CONTROL, - (reg & PCA9541_CTL_NBUSON) >> 1); -} - -/* - * Arbitration is defined as a two-step process. A bus master can only activate - * the slave bus if it owns it; otherwise it has to request ownership first. - * This multi-step process ensures that access contention is resolved - * gracefully. - * - * Bus Ownership Other master Action - * state requested access - * ---------------------------------------------------- - * off - yes wait for arbitration timeout or - * for other master to drop request - * off no no take ownership - * off yes no turn on bus - * on yes - done - * on no - wait for arbitration timeout or - * for other master to release bus - * - * The main contention point occurs if the slave bus is off and both masters - * request ownership at the same time. In this case, one master will turn on - * the slave bus, believing that it owns it. The other master will request - * bus ownership. Result is that the bus is turned on, and master which did - * _not_ own the slave bus before ends up owning it. - */ - -/* Control commands per PCA9541 datasheet */ -static const u8 pca9541_control[16] = { - 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1 -}; - -/* - * Channel arbitration - * - * Return values: - * <0: error - * 0 : bus not acquired - * 1 : bus acquired - */ -static int pca9541_arbitrate(struct i2c_client *client) -{ - struct i2c_mux_core *muxc = i2c_get_clientdata(client); - struct pca9541 *data = i2c_mux_priv(muxc); - int reg; - - reg = pca9541_reg_read(client, PCA9541_CONTROL); - if (reg < 0) - return reg; - - if (busoff(reg)) { - int istat; - /* - * Bus is off. Request ownership or turn it on unless - * other master requested ownership. - */ - istat = pca9541_reg_read(client, PCA9541_ISTAT); - if (!(istat & PCA9541_ISTAT_NMYTEST) - || time_is_before_eq_jiffies(data->arb_timeout)) { - /* - * Other master did not request ownership, - * or arbitration timeout expired. Take the bus. - */ - pca9541_reg_write(client, - PCA9541_CONTROL, - pca9541_control[reg & 0x0f] - | PCA9541_CTL_NTESTON); - data->select_timeout = SELECT_DELAY_SHORT; - } else { - /* - * Other master requested ownership. - * Set extra long timeout to give it time to acquire it. - */ - data->select_timeout = SELECT_DELAY_LONG * 2; - } - } else if (mybus(reg)) { - /* - * Bus is on, and we own it. We are done with acquisition. - * Reset NTESTON and BUSINIT, then return success. - */ - if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT)) - pca9541_reg_write(client, - PCA9541_CONTROL, - reg & ~(PCA9541_CTL_NTESTON - | PCA9541_CTL_BUSINIT)); - return 1; - } else { - /* - * Other master owns the bus. - * If arbitration timeout has expired, force ownership. - * Otherwise request it. - */ - data->select_timeout = SELECT_DELAY_LONG; - if (time_is_before_eq_jiffies(data->arb_timeout)) { - /* Time is up, take the bus and reset it. */ - pca9541_reg_write(client, - PCA9541_CONTROL, - pca9541_control[reg & 0x0f] - | PCA9541_CTL_BUSINIT - | PCA9541_CTL_NTESTON); - } else { - /* Request bus ownership if needed */ - if (!(reg & PCA9541_CTL_NTESTON)) - pca9541_reg_write(client, - PCA9541_CONTROL, - reg | PCA9541_CTL_NTESTON); - } - } - return 0; -} - -static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan) -{ - struct pca9541 *data = i2c_mux_priv(muxc); - struct i2c_client *client = data->client; - int ret; - unsigned long timeout = jiffies + ARB2_TIMEOUT; - /* give up after this time */ - - data->arb_timeout = jiffies + ARB_TIMEOUT; - /* force bus ownership after this time */ - - do { - ret = pca9541_arbitrate(client); - if (ret) - return ret < 0 ? ret : 0; - - if (data->select_timeout == SELECT_DELAY_SHORT) - udelay(data->select_timeout); - else - msleep(data->select_timeout / 1000); - } while (time_is_after_eq_jiffies(timeout)); - - return -ETIMEDOUT; -} - -static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) -{ - struct pca9541 *data = i2c_mux_priv(muxc); - struct i2c_client *client = data->client; - pca9541_release_bus(client); - return 0; -} - -/* - * Arbitration management functions - */ -static void pca9641_release_bus(struct i2c_client *client) -{ - pca9541_reg_write(client, PCA9641_CONTROL, 0x80); //master 0x80 -} - -/* - * Channel arbitration - * - * Return values: - * <0: error - * 0 : bus not acquired - * 1 : bus acquired - */ -static int pca9641_arbitrate(struct i2c_client *client) -{ - struct i2c_mux_core *muxc = i2c_get_clientdata(client); - struct pca9541 *data = i2c_mux_priv(muxc); - int reg_ctl, reg_sts; - - reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); - if (reg_ctl < 0) - return reg_ctl; - reg_sts = pca9541_reg_read(client, PCA9641_STATUS); - - if (BUSOFF(reg_ctl, reg_sts)) { - /* - * Bus is off. Request ownership or turn it on unless - * other master requested ownership. - */ - reg_ctl |= PCA9641_CTL_LOCK_REQ; - pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); - reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); - - if (lock_grant(reg_ctl)) { - /* - * Other master did not request ownership, - * or arbitration timeout expired. Take the bus. - */ - reg_ctl |= PCA9641_CTL_BUS_CONNECT - | PCA9641_CTL_LOCK_REQ; - pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); - data->select_timeout = SELECT_DELAY_SHORT; - - return 1; - } else { - /* - * Other master requested ownership. - * Set extra long timeout to give it time to acquire it. - */ - data->select_timeout = SELECT_DELAY_LONG * 2; - } - } else if (lock_grant(reg_ctl)) { - /* - * Bus is on, and we own it. We are done with acquisition. - */ - reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ; - pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); - - return 1; - } else if (other_lock(reg_sts)) { - /* - * Other master owns the bus. - * If arbitration timeout has expired, force ownership. - * Otherwise request it. - */ - data->select_timeout = SELECT_DELAY_LONG; - reg_ctl |= PCA9641_CTL_LOCK_REQ; - pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); - } - return 0; -} - - -int pca9641_select_chan(struct i2c_mux_core *muxc, u32 chan) -{ - struct pca9541 *data = i2c_mux_priv(muxc); - struct i2c_client *client = data->client; - int ret; - int result; - unsigned long timeout = jiffies + ARB2_TIMEOUT; - /* give up after this time */ - data->arb_timeout = jiffies + ARB_TIMEOUT; - /* force bus ownership after this time */ - for (result = 0 ; result < PCA9641_RETRY_TIME ; result ++) { - do { - ret = pca9641_arbitrate(client); - if (ret == 1) { - return 0; - } - if (data->select_timeout == SELECT_DELAY_SHORT) - udelay(data->select_timeout); - else - msleep(data->select_timeout / 1000); - } while (time_is_after_eq_jiffies(timeout)); - timeout = jiffies + ARB2_TIMEOUT; - } - return -ETIMEDOUT; -} -EXPORT_SYMBOL(pca9641_select_chan); - -static int pca9641_release_chan(struct i2c_mux_core *muxc, u32 chan) -{ - struct pca9541 *data = i2c_mux_priv(muxc); - struct i2c_client *client = data->client; - if (pca_flag.flag) { - pca9641_release_bus(client); - } - return 0; -} - -static int pca9641_detect_id(struct i2c_client *client) -{ - int reg; - - reg = pca9541_reg_read(client, PCA9641_ID); - if (reg == PCA9641_ID_MAGIC) - return 1; - else - return 0; -} - - -static int pca9641_recordflag(struct i2c_adapter *adap) { - if (pca_flag.flag != -1) { - pr_err(" %s %d has init already!!!", __func__, __LINE__); - return -1 ; - } - pca_flag.nr = adap->nr; - PCA_DEBUG(" adap->nr:%d\n", adap->nr); - snprintf(pca_flag.name, sizeof(pca_flag.name),adap->name); - return 0; -} - -static void i2c_lock_adapter(struct i2c_adapter *adapter){ - struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); - if (parent) - i2c_lock_adapter(parent); - else - rt_mutex_lock(&adapter->bus_lock); -} - -void i2c_unlock_adapter(struct i2c_adapter *adapter) -{ - struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); - - if (parent) - i2c_unlock_adapter(parent); - else - rt_mutex_unlock(&adapter->bus_lock); -} -/* - * I2C init/probing/exit functions - */ -static int pca9541_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 i2c_mux_core *muxc; - struct pca9541 *data; - int force; - int ret = -ENODEV; - int detect_id; - - if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - - detect_id = pca9641_detect_id(client); - - /* - * I2C accesses are unprotected here. - * We have to lock the adapter before releasing the bus. - */ - if (detect_id == 0) { - i2c_lock_adapter(adap); - pca9541_release_bus(client); - i2c_unlock_adapter(adap); - } else { - i2c_lock_adapter(adap); - pca9641_release_bus(client); - i2c_unlock_adapter(adap); - } - - /* Create mux adapter */ - - force = 0; - if (pdata) - force = pdata->modes[0].adap_id; - - if (detect_id == 0) { - muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), - I2C_MUX_ARBITRATOR, - pca9541_select_chan, pca9541_release_chan); - if (!muxc) - return -ENOMEM; - - data = i2c_mux_priv(muxc); - data->client = client; - - i2c_set_clientdata(client, muxc); - - ret = i2c_mux_add_adapter(muxc, force, 0, 0); - if (ret) - return ret; - } else { - muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), - I2C_MUX_ARBITRATOR, - pca9641_select_chan, pca9641_release_chan); - if (!muxc) - return -ENOMEM; - - data = i2c_mux_priv(muxc); - data->client = client; - - i2c_set_clientdata(client, muxc); - - ret = i2c_mux_add_adapter(muxc, force, 0, 0); - if (ret) - return ret; - } - pca9641_recordflag(muxc->adapter[0]); - - dev_info(&client->dev, "registered master selector for I2C %s\n", - client->name); - - return 0; - -} - -static int pca9541_remove(struct i2c_client *client) -{ - struct i2c_mux_core *muxc = i2c_get_clientdata(client); - - i2c_mux_del_adapters(muxc); - return 0; -} - -static struct i2c_driver pca9641_driver = { - .driver = { - .name = "pca9641", - .of_match_table = of_match_ptr(pca9541_of_match), - }, - .probe = pca9541_probe, - .remove = pca9541_remove, - .id_table = pca9541_id, -}; - -module_i2c_driver(pca9641_driver); - -MODULE_AUTHOR("support support@ragile.com"); -MODULE_DESCRIPTION("PCA9541 I2C master selector driver"); -MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/Makefile new file mode 100644 index 000000000000..269e95019cba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/Makefile @@ -0,0 +1,21 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +#ifdef ENABLE_GCOV +#ifeq ($(ENABLE_GCOV), y) +#EXTRA_CFLAGS+= -fprofile-arcs -ftest-coverage -lgcov +#endif +#endif # ENABLE_GCOV + +obj-m := intel_spi.o +obj-m += intel_spi_platform.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/include/intel_spi.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/include/intel_spi.h new file mode 100644 index 000000000000..d0a570b1f3b0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/include/intel_spi.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Intel PCH/PCU SPI flash driver. + * + * Copyright (C) 2016, Intel Corporation + * Author: Mika Westerberg + */ + +#ifndef INTEL_SPI_H +#define INTEL_SPI_H + +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +struct intel_spi; +struct resource; + +struct intel_spi *intel_spi_probe(struct device *dev, + struct resource *mem, const struct intel_spi_boardinfo *info); +int intel_spi_remove(struct intel_spi *ispi); + +#endif /* INTEL_SPI_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi.c new file mode 100644 index 000000000000..98de90f0c0b2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi.c @@ -0,0 +1,969 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Intel PCH/PCU SPI flash driver. + * + * Copyright (C) 2016, Intel Corporation + * Author: Mika Westerberg + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "intel_spi.h" + +/* Offsets are from @ispi->base */ +#define BFPREG 0x00 + +#define HSFSTS_CTL 0x04 +#define HSFSTS_CTL_FSMIE BIT(31) +#define HSFSTS_CTL_FDBC_SHIFT 24 +#define HSFSTS_CTL_FDBC_MASK (0x3f << HSFSTS_CTL_FDBC_SHIFT) + +#define HSFSTS_CTL_FCYCLE_SHIFT 17 +#define HSFSTS_CTL_FCYCLE_MASK (0x0f << HSFSTS_CTL_FCYCLE_SHIFT) +/* HW sequencer opcodes */ +#define HSFSTS_CTL_FCYCLE_READ (0x00 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_WRITE (0x02 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_ERASE (0x03 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_ERASE_64K (0x04 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_RDID (0x06 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_WRSR (0x07 << HSFSTS_CTL_FCYCLE_SHIFT) +#define HSFSTS_CTL_FCYCLE_RDSR (0x08 << HSFSTS_CTL_FCYCLE_SHIFT) + +#define HSFSTS_CTL_FGO BIT(16) +#define HSFSTS_CTL_FLOCKDN BIT(15) +#define HSFSTS_CTL_FDV BIT(14) +#define HSFSTS_CTL_SCIP BIT(5) +#define HSFSTS_CTL_AEL BIT(2) +#define HSFSTS_CTL_FCERR BIT(1) +#define HSFSTS_CTL_FDONE BIT(0) + +#define FADDR 0x08 +#define DLOCK 0x0c +#define FDATA(n) (0x10 + ((n) * 4)) + +#define FRACC 0x50 + +#define FREG(n) (0x54 + ((n) * 4)) +#define FREG_BASE_MASK 0x3fff +#define FREG_LIMIT_SHIFT 16 +#define FREG_LIMIT_MASK (0x03fff << FREG_LIMIT_SHIFT) + +/* Offset is from @ispi->pregs */ +#define PR(n) ((n) * 4) +#define PR_WPE BIT(31) +#define PR_LIMIT_SHIFT 16 +#define PR_LIMIT_MASK (0x3fff << PR_LIMIT_SHIFT) +#define PR_RPE BIT(15) +#define PR_BASE_MASK 0x3fff + +/* Offsets are from @ispi->sregs */ +#define SSFSTS_CTL 0x00 +#define SSFSTS_CTL_FSMIE BIT(23) +#define SSFSTS_CTL_DS BIT(22) +#define SSFSTS_CTL_DBC_SHIFT 16 +#define SSFSTS_CTL_SPOP BIT(11) +#define SSFSTS_CTL_ACS BIT(10) +#define SSFSTS_CTL_SCGO BIT(9) +#define SSFSTS_CTL_COP_SHIFT 12 +#define SSFSTS_CTL_FRS BIT(7) +#define SSFSTS_CTL_DOFRS BIT(6) +#define SSFSTS_CTL_AEL BIT(4) +#define SSFSTS_CTL_FCERR BIT(3) +#define SSFSTS_CTL_FDONE BIT(2) +#define SSFSTS_CTL_SCIP BIT(0) + +#define PREOP_OPTYPE 0x04 +#define OPMENU0 0x08 +#define OPMENU1 0x0c + +#define OPTYPE_READ_NO_ADDR 0 +#define OPTYPE_WRITE_NO_ADDR 1 +#define OPTYPE_READ_WITH_ADDR 2 +#define OPTYPE_WRITE_WITH_ADDR 3 + +/* CPU specifics */ +#define BYT_PR 0x74 +#define BYT_SSFSTS_CTL 0x90 +#define BYT_BCR 0xfc +#define BYT_BCR_WPD BIT(0) +#define BYT_FREG_NUM 5 +#define BYT_PR_NUM 5 + +#define LPT_PR 0x74 +#define LPT_SSFSTS_CTL 0x90 +#define LPT_FREG_NUM 5 +#define LPT_PR_NUM 5 + +#define BXT_PR 0x84 +#define BXT_SSFSTS_CTL 0xa0 +#define BXT_FREG_NUM 12 +#define BXT_PR_NUM 6 + +#define CNL_PR 0x84 +#define CNL_FREG_NUM 6 +#define CNL_PR_NUM 5 + +#define LVSCC 0xc4 +#define UVSCC 0xc8 +#define ERASE_OPCODE_SHIFT 8 +#define ERASE_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) +#define ERASE_64K_OPCODE_SHIFT 16 +#define ERASE_64K_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) + +#define INTEL_SPI_TIMEOUT 5000 /* ms */ +#define INTEL_SPI_FIFO_SZ 64 + +/** + * struct intel_spi - Driver private data + * @dev: Device pointer + * @info: Pointer to board specific info + * @nor: SPI NOR layer structure + * @base: Beginning of MMIO space + * @pregs: Start of protection registers + * @sregs: Start of software sequencer registers + * @nregions: Maximum number of regions + * @pr_num: Maximum number of protected range registers + * @writeable: Is the chip writeable + * @locked: Is SPI setting locked + * @swseq_reg: Use SW sequencer in register reads/writes + * @swseq_erase: Use SW sequencer in erase operation + * @erase_64k: 64k erase supported + * @atomic_preopcode: Holds preopcode when atomic sequence is requested + * @opcodes: Opcodes which are supported. This are programmed by BIOS + * before it locks down the controller. + */ +struct intel_spi { + struct device *dev; + const struct intel_spi_boardinfo *info; + struct spi_nor nor; + void __iomem *base; + void __iomem *pregs; + void __iomem *sregs; + size_t nregions; + size_t pr_num; + bool writeable; + bool locked; + bool swseq_reg; + bool swseq_erase; + bool erase_64k; + u8 atomic_preopcode; + u8 opcodes[8]; +}; + +static bool writeable; +module_param(writeable, bool, 0); +MODULE_PARM_DESC(writeable, "Enable write access to SPI flash chip (default=0)"); + +static void intel_spi_dump_regs(struct intel_spi *ispi) +{ + u32 value; + int i; + + dev_dbg(ispi->dev, "BFPREG=0x%08x\n", readl(ispi->base + BFPREG)); + + value = readl(ispi->base + HSFSTS_CTL); + dev_dbg(ispi->dev, "HSFSTS_CTL=0x%08x\n", value); + if (value & HSFSTS_CTL_FLOCKDN) + dev_dbg(ispi->dev, "-> Locked\n"); + + dev_dbg(ispi->dev, "FADDR=0x%08x\n", readl(ispi->base + FADDR)); + dev_dbg(ispi->dev, "DLOCK=0x%08x\n", readl(ispi->base + DLOCK)); + + for (i = 0; i < 16; i++) + dev_dbg(ispi->dev, "FDATA(%d)=0x%08x\n", + i, readl(ispi->base + FDATA(i))); + + dev_dbg(ispi->dev, "FRACC=0x%08x\n", readl(ispi->base + FRACC)); + + for (i = 0; i < ispi->nregions; i++) + dev_dbg(ispi->dev, "FREG(%d)=0x%08x\n", i, + readl(ispi->base + FREG(i))); + for (i = 0; i < ispi->pr_num; i++) + dev_dbg(ispi->dev, "PR(%d)=0x%08x\n", i, + readl(ispi->pregs + PR(i))); + + if (ispi->sregs) { + value = readl(ispi->sregs + SSFSTS_CTL); + dev_dbg(ispi->dev, "SSFSTS_CTL=0x%08x\n", value); + dev_dbg(ispi->dev, "PREOP_OPTYPE=0x%08x\n", + readl(ispi->sregs + PREOP_OPTYPE)); + dev_dbg(ispi->dev, "OPMENU0=0x%08x\n", + readl(ispi->sregs + OPMENU0)); + dev_dbg(ispi->dev, "OPMENU1=0x%08x\n", + readl(ispi->sregs + OPMENU1)); + } + + if (ispi->info->type == INTEL_SPI_BYT) + dev_dbg(ispi->dev, "BCR=0x%08x\n", readl(ispi->base + BYT_BCR)); + + dev_dbg(ispi->dev, "LVSCC=0x%08x\n", readl(ispi->base + LVSCC)); + dev_dbg(ispi->dev, "UVSCC=0x%08x\n", readl(ispi->base + UVSCC)); + + dev_dbg(ispi->dev, "Protected regions:\n"); + for (i = 0; i < ispi->pr_num; i++) { + u32 base, limit; + + value = readl(ispi->pregs + PR(i)); + if (!(value & (PR_WPE | PR_RPE))) + continue; + + limit = (value & PR_LIMIT_MASK) >> PR_LIMIT_SHIFT; + base = value & PR_BASE_MASK; + + dev_dbg(ispi->dev, " %02d base: 0x%08x limit: 0x%08x [%c%c]\n", + i, base << 12, (limit << 12) | 0xfff, + value & PR_WPE ? 'W' : '.', + value & PR_RPE ? 'R' : '.'); + } + + dev_dbg(ispi->dev, "Flash regions:\n"); + for (i = 0; i < ispi->nregions; i++) { + u32 region, base, limit; + + region = readl(ispi->base + FREG(i)); + base = region & FREG_BASE_MASK; + limit = (region & FREG_LIMIT_MASK) >> FREG_LIMIT_SHIFT; + + if (base >= limit || (i > 0 && limit == 0)) + dev_dbg(ispi->dev, " %02d disabled\n", i); + else + dev_dbg(ispi->dev, " %02d base: 0x%08x limit: 0x%08x\n", + i, base << 12, (limit << 12) | 0xfff); + } + + dev_dbg(ispi->dev, "Using %cW sequencer for register access\n", + ispi->swseq_reg ? 'S' : 'H'); + dev_dbg(ispi->dev, "Using %cW sequencer for erase operation\n", + ispi->swseq_erase ? 'S' : 'H'); +} + +/* Reads max INTEL_SPI_FIFO_SZ bytes from the device fifo */ +static int intel_spi_read_block(struct intel_spi *ispi, void *buf, size_t size) +{ + size_t bytes; + int i = 0; + + if (size > INTEL_SPI_FIFO_SZ) + return -EINVAL; + + while (size > 0) { + bytes = min_t(size_t, size, 4); + memcpy_fromio(buf, ispi->base + FDATA(i), bytes); + size -= bytes; + buf += bytes; + i++; + } + + return 0; +} + +/* Writes max INTEL_SPI_FIFO_SZ bytes to the device fifo */ +static int intel_spi_write_block(struct intel_spi *ispi, const void *buf, + size_t size) +{ + size_t bytes; + int i = 0; + + if (size > INTEL_SPI_FIFO_SZ) + return -EINVAL; + + while (size > 0) { + bytes = min_t(size_t, size, 4); + memcpy_toio(ispi->base + FDATA(i), buf, bytes); + size -= bytes; + buf += bytes; + i++; + } + + return 0; +} + +static int intel_spi_wait_hw_busy(struct intel_spi *ispi) +{ + u32 val; + + return readl_poll_timeout(ispi->base + HSFSTS_CTL, val, + !(val & HSFSTS_CTL_SCIP), 0, + INTEL_SPI_TIMEOUT * 1000); +} + +static int intel_spi_wait_sw_busy(struct intel_spi *ispi) +{ + u32 val; + + return readl_poll_timeout(ispi->sregs + SSFSTS_CTL, val, + !(val & SSFSTS_CTL_SCIP), 0, + INTEL_SPI_TIMEOUT * 1000); +} + +static int intel_spi_init(struct intel_spi *ispi) +{ + u32 opmenu0, opmenu1, lvscc, uvscc, val; + int i; + + switch (ispi->info->type) { + case INTEL_SPI_BYT: + ispi->sregs = ispi->base + BYT_SSFSTS_CTL; + ispi->pregs = ispi->base + BYT_PR; + ispi->nregions = BYT_FREG_NUM; + ispi->pr_num = BYT_PR_NUM; + ispi->swseq_reg = true; + + if (writeable) { + /* Disable write protection */ + val = readl(ispi->base + BYT_BCR); + if (!(val & BYT_BCR_WPD)) { + val |= BYT_BCR_WPD; + writel(val, ispi->base + BYT_BCR); + val = readl(ispi->base + BYT_BCR); + } + + ispi->writeable = !!(val & BYT_BCR_WPD); + } + + break; + + case INTEL_SPI_LPT: + ispi->sregs = ispi->base + LPT_SSFSTS_CTL; + ispi->pregs = ispi->base + LPT_PR; + ispi->nregions = LPT_FREG_NUM; + ispi->pr_num = LPT_PR_NUM; + ispi->swseq_reg = true; + break; + + case INTEL_SPI_BXT: + ispi->sregs = ispi->base + BXT_SSFSTS_CTL; + ispi->pregs = ispi->base + BXT_PR; + ispi->nregions = BXT_FREG_NUM; + ispi->pr_num = BXT_PR_NUM; + ispi->erase_64k = true; + break; + + case INTEL_SPI_CNL: + ispi->sregs = NULL; + ispi->pregs = ispi->base + CNL_PR; + ispi->nregions = CNL_FREG_NUM; + ispi->pr_num = CNL_PR_NUM; + break; + + default: + return -EINVAL; + } + + /* Disable #SMI generation from HW sequencer */ + val = readl(ispi->base + HSFSTS_CTL); + val &= ~HSFSTS_CTL_FSMIE; + writel(val, ispi->base + HSFSTS_CTL); + + /* + * Determine whether erase operation should use HW or SW sequencer. + * + * The HW sequencer has a predefined list of opcodes, with only the + * erase opcode being programmable in LVSCC and UVSCC registers. + * If these registers don't contain a valid erase opcode, erase + * cannot be done using HW sequencer. + */ + lvscc = readl(ispi->base + LVSCC); + uvscc = readl(ispi->base + UVSCC); + if (!(lvscc & ERASE_OPCODE_MASK) || !(uvscc & ERASE_OPCODE_MASK)) + ispi->swseq_erase = true; + /* SPI controller on Intel BXT supports 64K erase opcode */ + if (ispi->info->type == INTEL_SPI_BXT && !ispi->swseq_erase) + if (!(lvscc & ERASE_64K_OPCODE_MASK) || + !(uvscc & ERASE_64K_OPCODE_MASK)) + ispi->erase_64k = false; + + if (ispi->sregs == NULL && (ispi->swseq_reg || ispi->swseq_erase)) { + dev_err(ispi->dev, "software sequencer not supported, but required\n"); + return -EINVAL; + } + + /* + * Some controllers can only do basic operations using hardware + * sequencer. All other operations are supposed to be carried out + * using software sequencer. + */ + if (ispi->swseq_reg) { + /* Disable #SMI generation from SW sequencer */ + val = readl(ispi->sregs + SSFSTS_CTL); + val &= ~SSFSTS_CTL_FSMIE; + writel(val, ispi->sregs + SSFSTS_CTL); + } + + /* Check controller's lock status */ + val = readl(ispi->base + HSFSTS_CTL); + ispi->locked = !!(val & HSFSTS_CTL_FLOCKDN); + + if (ispi->locked && ispi->sregs) { + /* + * BIOS programs allowed opcodes and then locks down the + * register. So read back what opcodes it decided to support. + * That's the set we are going to support as well. + */ + opmenu0 = readl(ispi->sregs + OPMENU0); + opmenu1 = readl(ispi->sregs + OPMENU1); + + if (opmenu0 && opmenu1) { + for (i = 0; i < ARRAY_SIZE(ispi->opcodes) / 2; i++) { + ispi->opcodes[i] = opmenu0 >> i * 8; + ispi->opcodes[i + 4] = opmenu1 >> i * 8; + } + } + } + + intel_spi_dump_regs(ispi); + + return 0; +} + +static int intel_spi_opcode_index(struct intel_spi *ispi, u8 opcode, int optype) +{ + int i; + int preop; + + if (ispi->locked) { + for (i = 0; i < ARRAY_SIZE(ispi->opcodes); i++) + if (ispi->opcodes[i] == opcode) + return i; + + return -EINVAL; + } + + /* The lock is off, so just use index 0 */ + writel(opcode, ispi->sregs + OPMENU0); + preop = readw(ispi->sregs + PREOP_OPTYPE); + writel(optype << 16 | preop, ispi->sregs + PREOP_OPTYPE); + + return 0; +} + +static int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len) +{ + u32 val, status; + int ret; + + val = readl(ispi->base + HSFSTS_CTL); + val &= ~(HSFSTS_CTL_FCYCLE_MASK | HSFSTS_CTL_FDBC_MASK); + + switch (opcode) { + case SPINOR_OP_RDID: + val |= HSFSTS_CTL_FCYCLE_RDID; + break; + case SPINOR_OP_WRSR: + val |= HSFSTS_CTL_FCYCLE_WRSR; + break; + case SPINOR_OP_RDSR: + val |= HSFSTS_CTL_FCYCLE_RDSR; + break; + default: + return -EINVAL; + } + + if (len > INTEL_SPI_FIFO_SZ) + return -EINVAL; + + val |= (len - 1) << HSFSTS_CTL_FDBC_SHIFT; + val |= HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; + val |= HSFSTS_CTL_FGO; + writel(val, ispi->base + HSFSTS_CTL); + + ret = intel_spi_wait_hw_busy(ispi); + if (ret) + return ret; + + status = readl(ispi->base + HSFSTS_CTL); + if (status & HSFSTS_CTL_FCERR) + return -EIO; + else if (status & HSFSTS_CTL_AEL) + return -EACCES; + + return 0; +} + +static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len, + int optype) +{ + u32 val = 0, status; + u8 atomic_preopcode; + int ret; + + ret = intel_spi_opcode_index(ispi, opcode, optype); + if (ret < 0) + return ret; + + if (len > INTEL_SPI_FIFO_SZ) + return -EINVAL; + + /* + * Always clear it after each SW sequencer operation regardless + * of whether it is successful or not. + */ + atomic_preopcode = ispi->atomic_preopcode; + ispi->atomic_preopcode = 0; + + /* Only mark 'Data Cycle' bit when there is data to be transferred */ + if (len > 0) + val = ((len - 1) << SSFSTS_CTL_DBC_SHIFT) | SSFSTS_CTL_DS; + val |= ret << SSFSTS_CTL_COP_SHIFT; + val |= SSFSTS_CTL_FCERR | SSFSTS_CTL_FDONE; + val |= SSFSTS_CTL_SCGO; + if (atomic_preopcode) { + u16 preop; + + switch (optype) { + case OPTYPE_WRITE_NO_ADDR: + case OPTYPE_WRITE_WITH_ADDR: + /* Pick matching preopcode for the atomic sequence */ + preop = readw(ispi->sregs + PREOP_OPTYPE); + if ((preop & 0xff) == atomic_preopcode) + ; /* Do nothing */ + else if ((preop >> 8) == atomic_preopcode) + val |= SSFSTS_CTL_SPOP; + else + return -EINVAL; + + /* Enable atomic sequence */ + val |= SSFSTS_CTL_ACS; + break; + + default: + return -EINVAL; + } + + } + writel(val, ispi->sregs + SSFSTS_CTL); + + ret = intel_spi_wait_sw_busy(ispi); + if (ret) + return ret; + + status = readl(ispi->sregs + SSFSTS_CTL); + if (status & SSFSTS_CTL_FCERR) + return -EIO; + else if (status & SSFSTS_CTL_AEL) + return -EACCES; + + return 0; +} + +static int intel_spi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, + size_t len) +{ + struct intel_spi *ispi = nor->priv; + int ret; + + /* Address of the first chip */ + writel(0, ispi->base + FADDR); + + if (ispi->swseq_reg) + ret = intel_spi_sw_cycle(ispi, opcode, len, + OPTYPE_READ_NO_ADDR); + else + ret = intel_spi_hw_cycle(ispi, opcode, len); + + if (ret) + return ret; + + return intel_spi_read_block(ispi, buf, len); +} + +static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, + size_t len) +{ + struct intel_spi *ispi = nor->priv; + int ret; + + /* + * This is handled with atomic operation and preop code in Intel + * controller so we only verify that it is available. If the + * controller is not locked, program the opcode to the PREOP + * register for later use. + * + * When hardware sequencer is used there is no need to program + * any opcodes (it handles them automatically as part of a command). + */ + if (opcode == SPINOR_OP_WREN) { + u16 preop; + + if (!ispi->swseq_reg) + return 0; + + preop = readw(ispi->sregs + PREOP_OPTYPE); + if ((preop & 0xff) != opcode && (preop >> 8) != opcode) { + if (ispi->locked) + return -EINVAL; + writel(opcode, ispi->sregs + PREOP_OPTYPE); + } + + /* + * This enables atomic sequence on next SW sycle. Will + * be cleared after next operation. + */ + ispi->atomic_preopcode = opcode; + return 0; + } + + /* + * We hope that HW sequencer will do the right thing automatically and + * with the SW sequencer we cannot use preopcode anyway, so just ignore + * the Write Disable operation and pretend it was completed + * successfully. + */ + if (opcode == SPINOR_OP_WRDI) + return 0; + + writel(0, ispi->base + FADDR); + + /* Write the value beforehand */ + ret = intel_spi_write_block(ispi, buf, len); + if (ret) + return ret; + + if (ispi->swseq_reg) + return intel_spi_sw_cycle(ispi, opcode, len, + OPTYPE_WRITE_NO_ADDR); + return intel_spi_hw_cycle(ispi, opcode, len); +} + +static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len, + u_char *read_buf) +{ + struct intel_spi *ispi = nor->priv; + size_t block_size, retlen = 0; + u32 val, status; + ssize_t ret; + + /* + * Atomic sequence is not expected with HW sequencer reads. Make + * sure it is cleared regardless. + */ + if (WARN_ON_ONCE(ispi->atomic_preopcode)) + ispi->atomic_preopcode = 0; + + switch (nor->read_opcode) { + case SPINOR_OP_READ: + case SPINOR_OP_READ_FAST: + case SPINOR_OP_READ_4B: + case SPINOR_OP_READ_FAST_4B: + break; + default: + return -EINVAL; + } + + while (len > 0) { + block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); + + /* Read cannot cross 4K boundary */ + block_size = min_t(loff_t, from + block_size, + round_up(from + 1, SZ_4K)) - from; + + writel(from, ispi->base + FADDR); + + val = readl(ispi->base + HSFSTS_CTL); + val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK); + val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; + val |= (block_size - 1) << HSFSTS_CTL_FDBC_SHIFT; + val |= HSFSTS_CTL_FCYCLE_READ; + val |= HSFSTS_CTL_FGO; + writel(val, ispi->base + HSFSTS_CTL); + + ret = intel_spi_wait_hw_busy(ispi); + if (ret) + return ret; + + status = readl(ispi->base + HSFSTS_CTL); + if (status & HSFSTS_CTL_FCERR) + ret = -EIO; + else if (status & HSFSTS_CTL_AEL) + ret = -EACCES; + + if (ret < 0) { + dev_err(ispi->dev, "read error: %llx: %#x\n", from, + status); + return ret; + } + + ret = intel_spi_read_block(ispi, read_buf, block_size); + if (ret) + return ret; + + len -= block_size; + from += block_size; + retlen += block_size; + read_buf += block_size; + } + + return retlen; +} + +static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len, + const u_char *write_buf) +{ + struct intel_spi *ispi = nor->priv; + size_t block_size, retlen = 0; + u32 val, status; + ssize_t ret; + + /* Not needed with HW sequencer write, make sure it is cleared */ + ispi->atomic_preopcode = 0; + + while (len > 0) { + block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); + + /* Write cannot cross 4K boundary */ + block_size = min_t(loff_t, to + block_size, + round_up(to + 1, SZ_4K)) - to; + + writel(to, ispi->base + FADDR); + + val = readl(ispi->base + HSFSTS_CTL); + val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK); + val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; + val |= (block_size - 1) << HSFSTS_CTL_FDBC_SHIFT; + val |= HSFSTS_CTL_FCYCLE_WRITE; + + ret = intel_spi_write_block(ispi, write_buf, block_size); + if (ret) { + dev_err(ispi->dev, "failed to write block\n"); + return ret; + } + + /* Start the write now */ + val |= HSFSTS_CTL_FGO; + writel(val, ispi->base + HSFSTS_CTL); + + ret = intel_spi_wait_hw_busy(ispi); + if (ret) { + dev_err(ispi->dev, "timeout\n"); + return ret; + } + + status = readl(ispi->base + HSFSTS_CTL); + if (status & HSFSTS_CTL_FCERR) + ret = -EIO; + else if (status & HSFSTS_CTL_AEL) + ret = -EACCES; + + if (ret < 0) { + dev_err(ispi->dev, "write error: %llx: %#x\n", to, + status); + return ret; + } + + len -= block_size; + to += block_size; + retlen += block_size; + write_buf += block_size; + } + + return retlen; +} + +static int intel_spi_erase(struct spi_nor *nor, loff_t offs) +{ + size_t erase_size, len = nor->mtd.erasesize; + struct intel_spi *ispi = nor->priv; + u32 val, status, cmd; + int ret; + + /* If the hardware can do 64k erase use that when possible */ + if (len >= SZ_64K && ispi->erase_64k) { + cmd = HSFSTS_CTL_FCYCLE_ERASE_64K; + erase_size = SZ_64K; + } else { + cmd = HSFSTS_CTL_FCYCLE_ERASE; + erase_size = SZ_4K; + } + + if (ispi->swseq_erase) { + while (len > 0) { + writel(offs, ispi->base + FADDR); + + ret = intel_spi_sw_cycle(ispi, nor->erase_opcode, + 0, OPTYPE_WRITE_WITH_ADDR); + if (ret) + return ret; + + offs += erase_size; + len -= erase_size; + } + + return 0; + } + + /* Not needed with HW sequencer erase, make sure it is cleared */ + ispi->atomic_preopcode = 0; + + while (len > 0) { + writel(offs, ispi->base + FADDR); + + val = readl(ispi->base + HSFSTS_CTL); + val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK); + val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; + val |= cmd; + val |= HSFSTS_CTL_FGO; + writel(val, ispi->base + HSFSTS_CTL); + + ret = intel_spi_wait_hw_busy(ispi); + if (ret) + return ret; + + status = readl(ispi->base + HSFSTS_CTL); + if (status & HSFSTS_CTL_FCERR) + return -EIO; + else if (status & HSFSTS_CTL_AEL) + return -EACCES; + + offs += erase_size; + len -= erase_size; + } + + return 0; +} + +static bool intel_spi_is_protected(const struct intel_spi *ispi, + unsigned int base, unsigned int limit) +{ + int i; + + for (i = 0; i < ispi->pr_num; i++) { + u32 pr_base, pr_limit, pr_value; + + pr_value = readl(ispi->pregs + PR(i)); + if (!(pr_value & (PR_WPE | PR_RPE))) + continue; + + pr_limit = (pr_value & PR_LIMIT_MASK) >> PR_LIMIT_SHIFT; + pr_base = pr_value & PR_BASE_MASK; + + if (pr_base >= base && pr_limit <= limit) + return true; + } + + return false; +} + +/* + * There will be a single partition holding all enabled flash regions. We + * call this "BIOS". + */ +static void intel_spi_fill_partition(struct intel_spi *ispi, + struct mtd_partition *part) +{ + u64 end; + int i; + + mem_clear(part, sizeof(*part)); + + /* Start from the mandatory descriptor region */ + part->size = 4096; + part->name = "BIOS"; + + /* + * Now try to find where this partition ends based on the flash + * region registers. + */ + for (i = 1; i < ispi->nregions; i++) { + u32 region, base, limit; + + region = readl(ispi->base + FREG(i)); + base = region & FREG_BASE_MASK; + limit = (region & FREG_LIMIT_MASK) >> FREG_LIMIT_SHIFT; + + if (base >= limit || limit == 0) + continue; + + /* + * If any of the regions have protection bits set, make the + * whole partition read-only to be on the safe side. + */ + if (intel_spi_is_protected(ispi, base, limit)) + ispi->writeable = false; + + end = (limit << 12) + 4096; + if (end > part->size) + part->size = end; + } +} + +static const struct spi_nor_controller_ops intel_spi_controller_ops = { + .read_reg = intel_spi_read_reg, + .write_reg = intel_spi_write_reg, + .read = intel_spi_read, + .write = intel_spi_write, + .erase = intel_spi_erase, +}; + +struct intel_spi *intel_spi_probe(struct device *dev, + struct resource *mem, const struct intel_spi_boardinfo *info) +{ + const struct spi_nor_hwcaps hwcaps = { + .mask = SNOR_HWCAPS_READ | + SNOR_HWCAPS_READ_FAST | + SNOR_HWCAPS_PP, + }; + struct mtd_partition part; + struct intel_spi *ispi; + int ret; + + if (!info || !mem) + return ERR_PTR(-EINVAL); + + ispi = devm_kzalloc(dev, sizeof(*ispi), GFP_KERNEL); + if (!ispi) + return ERR_PTR(-ENOMEM); + + ispi->base = devm_ioremap_resource(dev, mem); + if (IS_ERR(ispi->base)) + return ERR_CAST(ispi->base); + + ispi->dev = dev; + ispi->info = info; + ispi->writeable = info->writeable; + + ret = intel_spi_init(ispi); + if (ret) + return ERR_PTR(ret); + + ispi->nor.dev = ispi->dev; + ispi->nor.priv = ispi; + ispi->nor.controller_ops = &intel_spi_controller_ops; + + ret = spi_nor_scan(&ispi->nor, NULL, &hwcaps); + if (ret) { + dev_info(dev, "failed to locate the chip\n"); + return ERR_PTR(ret); + } + + intel_spi_fill_partition(ispi, &part); + + /* Prevent writes if not explicitly enabled */ + if (!ispi->writeable || !writeable) + ispi->nor.mtd.flags &= ~MTD_WRITEABLE; + + ret = mtd_device_register(&ispi->nor.mtd, &part, 1); + if (ret) + return ERR_PTR(ret); + + return ispi; +} +EXPORT_SYMBOL_GPL(intel_spi_probe); + +int intel_spi_remove(struct intel_spi *ispi) +{ + return mtd_device_unregister(&ispi->nor.mtd); +} +EXPORT_SYMBOL_GPL(intel_spi_remove); + +MODULE_DESCRIPTION("Intel PCH/PCU SPI flash core driver"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi_platform.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi_platform.c new file mode 100644 index 000000000000..b9f294860ce4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/intel_spi/intel_spi_platform.c @@ -0,0 +1,167 @@ +/* + * Intel PCH/PCU SPI flash platform driver. + * + * Copyright (C) 2016, Intel Corporation + * Author: Mika Westerberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include "intel_spi.h" + +#define PCI_VENDOR_ID_D1527_LPC (0x8c54) + +#define BIOS_CNTL (0xdc) +#define BIOS_CNTL_SRC_SHIFT 2 +#define BIOS_CNTL_WN BIT(0) +#define BIOS_CNTL_BLE BIT(1) +#define BIOS_CNTL_SMM_BMP BIT(5) + +#define RCBABASE 0xf0 + +int intel_spi_platform_debug = 0; +module_param(intel_spi_platform_debug, int, S_IRUGO | S_IWUSR); +int intel_spi_platform_error = 0; +module_param(intel_spi_platform_error, int, S_IRUGO | S_IWUSR); + +static bool writeable; +module_param(writeable, bool, 0); +MODULE_PARM_DESC(writeable, "Enable write access to BIOS (default=0)"); + +#define INTEL_SPI_PLATFORM_VERBOSE(fmt, args...) do { \ + if (intel_spi_platform_debug) { \ + printk(KERN_INFO "[INTEL_SPI_PLATFORM][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ + } while (0) + +#define INTEL_SPI_PLATFORM_ERROR(fmt, args...) do { \ + if (intel_spi_platform_error) { \ + printk(KERN_ERR "[INTEL_SPI_PLATFORM][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ + } while (0) + +static void intel_spi_enable_bios_write(struct pci_dev *pci_dev, struct intel_spi_boardinfo *info) +{ + u8 bios_cntl, value, want, new; + + if (writeable) { + pci_read_config_byte(pci_dev, BIOS_CNTL, &bios_cntl); + want = bios_cntl; + value = (bios_cntl >> BIOS_CNTL_SRC_SHIFT) & 0x3 ; + if (value == 0x3) { + INTEL_SPI_PLATFORM_VERBOSE("invalid prefetching/caching settings, "); + } else { + INTEL_SPI_PLATFORM_VERBOSE("prefetching %sabled, caching %sabled, ", + (value & 0x2) ? "en" : "dis", + (value & 0x1) ? "dis" : "en"); + } + + /* writeable regardless */ + want &= ~BIOS_CNTL_SMM_BMP; + /* write enable */ + want |= BIOS_CNTL_WN; + /* BIOS lock disabled */ + want &= ~BIOS_CNTL_BLE; + INTEL_SPI_PLATFORM_VERBOSE("bios cntl is:0x%x, want is:0x%x\n", bios_cntl, want); + pci_write_config_byte(pci_dev, BIOS_CNTL, want); + pci_read_config_byte(pci_dev, BIOS_CNTL, &new); + INTEL_SPI_PLATFORM_VERBOSE("\nBIOS_CNTL = 0x%02x: ", new); + INTEL_SPI_PLATFORM_VERBOSE("BIOS Lock Enable: %sabled, ", (new & BIOS_CNTL_BLE) ? "en" : "dis"); + INTEL_SPI_PLATFORM_VERBOSE("BIOS Write Enable: %sabled\n", (new & BIOS_CNTL_WN) ? "en" : "dis"); + + if (new & BIOS_CNTL_SMM_BMP) { + INTEL_SPI_PLATFORM_VERBOSE("BIOS region SMM protection is enabled!\n"); + } + + if (new != want) { + INTEL_SPI_PLATFORM_VERBOSE("Warning: Setting Bios Control at 0x%x from 0x%02x to 0x%02x failed.\n" + "New value is 0x%02x.\n", BIOS_CNTL, value, want, new); + } else { + info->writeable = !!(new & BIOS_CNTL_WN); + } + INTEL_SPI_PLATFORM_VERBOSE("Bios Control is 0x%x\n", new); + } else { + INTEL_SPI_PLATFORM_VERBOSE("Bios don't write\n"); + } + + return ; +} + +static int intel_spi_platform_probe(struct platform_device *pdev) +{ + struct intel_spi_boardinfo *info; + struct intel_spi *ispi; + struct resource *mem; + struct pci_dev *pci_dev = NULL; + u32 rcba; + + info = dev_get_platdata(&pdev->dev); + if (!info) + return -EINVAL; + + pci_dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC, pci_dev); + if (!pci_dev) { + INTEL_SPI_PLATFORM_ERROR("pci_get_device(0x8086, 0x8c54) failed!\n"); + return -1; + } + + switch (info->type) { + case INTEL_SPI_LPT: + pci_read_config_dword(pci_dev, RCBABASE, &rcba); + if (rcba & 1) { + intel_spi_enable_bios_write(pci_dev, info); + } + break; + default: + INTEL_SPI_PLATFORM_ERROR("info type[%d] not need set writeable.\n",info->type); + break; + } + INTEL_SPI_PLATFORM_VERBOSE("intel spi boardinfo writeable is %sabled\n", + info->writeable ? "en" : "dis"); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ispi = intel_spi_probe(&pdev->dev, mem, info); + if (IS_ERR(ispi)) + return PTR_ERR(ispi); + + platform_set_drvdata(pdev, ispi); + return 0; +} + +static int intel_spi_platform_remove(struct platform_device *pdev) +{ + struct intel_spi *ispi = platform_get_drvdata(pdev); + + return intel_spi_remove(ispi); +} + +static struct of_device_id intel_spi_match[] = { + { + .compatible = "spi-c224", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, intel_spi_match); + +static struct platform_driver intel_spi_platform_driver = { + .probe = intel_spi_platform_probe, + .remove = intel_spi_platform_remove, + .driver = { + .name = "intel-spi", + .of_match_table = intel_spi_match, + }, +}; + +module_platform_driver(intel_spi_platform_driver); + +MODULE_DESCRIPTION("Intel PCH/PCU SPI flash platform driver"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:intel-spi"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/Makefile new file mode 100644 index 000000000000..4226f2734275 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/Makefile @@ -0,0 +1,34 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +#ifdef ENABLE_GCOV +#ifeq ($(ENABLE_GCOV), y) +#EXTRA_CFLAGS+= -fprofile-arcs -ftest-coverage -lgcov +#endif +#endif # ENABLE_GCOV + +obj-m := wb_lm75.o +obj-m += wb_tmp401.o +obj-m += wb_i2c_mux_pca9641.o +obj-m += wb_i2c_mux_pca954x.o +obj-m += wb_i2c_i801.o +obj-m += wb_i2c_algo_bit.o +obj-m += wb_i2c_gpio.o +obj-m += wb_i2c_gpio_device.o +obj-m += wb_at24.o +obj-m += wb_pmbus_core.o +obj-m += wb_csu550.o +obj-m += wb_ina3221.o +obj-m += wb_isl68137.o +obj-m += wb_tps53622.o +obj-m += wb_ucd9000.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/*.mod + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_at24.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_at24.c new file mode 100644 index 000000000000..1075e6ef18de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_at24.c @@ -0,0 +1,861 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Address pointer is 16 bit. */ +#define AT24_FLAG_ADDR16 BIT(7) +/* sysfs-entry will be read-only. */ +#define AT24_FLAG_READONLY BIT(6) +/* sysfs-entry will be world-readable. */ +#define AT24_FLAG_IRUGO BIT(5) +/* Take always 8 addresses (24c00). */ +#define AT24_FLAG_TAKE8ADDR BIT(4) +/* Factory-programmed serial number. */ +#define AT24_FLAG_SERIAL BIT(3) +/* Factory-programmed mac address. */ +#define AT24_FLAG_MAC BIT(2) +/* Does not auto-rollover reads to the next slave address. */ +#define AT24_FLAG_NO_RDROL BIT(1) + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_client { + struct i2c_client *client; + struct regmap *regmap; +}; + +struct at24_data { + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + + unsigned int write_max; + unsigned int num_addresses; + unsigned int offset_adj; + + u32 byte_len; + u16 page_size; + u8 flags; + + struct nvmem_device *nvmem; + struct regulator *vcc_reg; + void (*read_post)(unsigned int off, char *buf, size_t count); + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct at24_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 at24_io_limit = 128; +module_param_named(io_limit, at24_io_limit, uint, 0); +MODULE_PARM_DESC(at24_io_limit, "Maximum bytes per I/O (default 128)"); + +/* + * Specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned int at24_write_timeout = 25; +module_param_named(write_timeout, at24_write_timeout, uint, 0); +MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)"); + +struct at24_chip_data { + u32 byte_len; + u8 flags; + void (*read_post)(unsigned int off, char *buf, size_t count); +}; + +#define AT24_CHIP_DATA(_name, _len, _flags) \ + static const struct at24_chip_data _name = { \ + .byte_len = _len, .flags = _flags, \ + } + +#define AT24_CHIP_DATA_CB(_name, _len, _flags, _read_post) \ + static const struct at24_chip_data _name = { \ + .byte_len = _len, .flags = _flags, \ + .read_post = _read_post, \ + } + +static void at24_read_post_vaio(unsigned int off, char *buf, size_t count) +{ + int i; + + if (capable(CAP_SYS_ADMIN)) + return; + + /* + * Hide VAIO private settings to regular users: + * - BIOS passwords: bytes 0x00 to 0x0f + * - UUID: bytes 0x10 to 0x1f + * - Serial number: 0xc0 to 0xdf + */ + for (i = 0; i < count; i++) { + if ((off + i <= 0x1f) || + (off + i >= 0xc0 && off + i <= 0xdf)) + buf[i] = 0; + } +} + +/* needs 8 addresses as A0-A2 are ignored */ +AT24_CHIP_DATA(at24_data_24c00, 128 / 8, AT24_FLAG_TAKE8ADDR); +/* old variants can't be handled with this generic entry! */ +AT24_CHIP_DATA(at24_data_24c01, 1024 / 8, 0); +AT24_CHIP_DATA(at24_data_24cs01, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c02, 2048 / 8, AT24_FLAG_IRUGO); +AT24_CHIP_DATA(at24_data_24cs02, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24mac402, 48 / 8, + AT24_FLAG_MAC | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24mac602, 64 / 8, + AT24_FLAG_MAC | AT24_FLAG_READONLY); +/* spd is a 24c02 in memory DIMMs */ +AT24_CHIP_DATA(at24_data_spd, 2048 / 8, + AT24_FLAG_READONLY | AT24_FLAG_IRUGO); +/* 24c02_vaio is a 24c02 on some Sony laptops */ +AT24_CHIP_DATA_CB(at24_data_24c02_vaio, 2048 / 8, + AT24_FLAG_READONLY | AT24_FLAG_IRUGO, + at24_read_post_vaio); +AT24_CHIP_DATA(at24_data_24c04, 4096 / 8, 0); +AT24_CHIP_DATA(at24_data_24cs04, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +/* 24rf08 quirk is handled at i2c-core */ +AT24_CHIP_DATA(at24_data_24c08, 8192 / 8, 0); +AT24_CHIP_DATA(at24_data_24cs08, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c16, 16384 / 8, 0); +AT24_CHIP_DATA(at24_data_24cs16, 16, + AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c32, 32768 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24cs32, 16, + AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c64, 65536 / 8, AT24_FLAG_ADDR16 | AT24_FLAG_IRUGO); +AT24_CHIP_DATA(at24_data_24cs64, 16, + AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY); +AT24_CHIP_DATA(at24_data_24c128, 131072 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24c256, 262144 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24c512, 524288 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24c1024, 1048576 / 8, AT24_FLAG_ADDR16); +AT24_CHIP_DATA(at24_data_24c2048, 2097152 / 8, AT24_FLAG_ADDR16); +/* identical to 24c08 ? */ +AT24_CHIP_DATA(at24_data_INT3499, 8192 / 8, 0); + +static const struct i2c_device_id at24_ids[] = { + { "wb_24c00", (kernel_ulong_t)&at24_data_24c00 }, + { "wb_24c01", (kernel_ulong_t)&at24_data_24c01 }, + { "wb_24cs01", (kernel_ulong_t)&at24_data_24cs01 }, + { "wb_24c02", (kernel_ulong_t)&at24_data_24c02 }, + { "wb_24cs02", (kernel_ulong_t)&at24_data_24cs02 }, + { "wb_24mac402", (kernel_ulong_t)&at24_data_24mac402 }, + { "wb_24mac602", (kernel_ulong_t)&at24_data_24mac602 }, + { "wb_spd", (kernel_ulong_t)&at24_data_spd }, + { "wb_24c02-vaio", (kernel_ulong_t)&at24_data_24c02_vaio }, + { "wb_24c04", (kernel_ulong_t)&at24_data_24c04 }, + { "wb_24cs04", (kernel_ulong_t)&at24_data_24cs04 }, + { "wb_24c08", (kernel_ulong_t)&at24_data_24c08 }, + { "wb_24cs08", (kernel_ulong_t)&at24_data_24cs08 }, + { "wb_24c16", (kernel_ulong_t)&at24_data_24c16 }, + { "wb_24cs16", (kernel_ulong_t)&at24_data_24cs16 }, + { "wb_24c32", (kernel_ulong_t)&at24_data_24c32 }, + { "wb_24cs32", (kernel_ulong_t)&at24_data_24cs32 }, + { "wb_24c64", (kernel_ulong_t)&at24_data_24c64 }, + { "wb_24cs64", (kernel_ulong_t)&at24_data_24cs64 }, + { "wb_24c128", (kernel_ulong_t)&at24_data_24c128 }, + { "wb_24c256", (kernel_ulong_t)&at24_data_24c256 }, + { "wb_24c512", (kernel_ulong_t)&at24_data_24c512 }, + { "wb_24c1024", (kernel_ulong_t)&at24_data_24c1024 }, + { "wb_24c2048", (kernel_ulong_t)&at24_data_24c2048 }, + { "wb_at24", 0 }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ids); + +static const struct of_device_id at24_of_match[] = { + { .compatible = "atmel,24c00", .data = &at24_data_24c00 }, + { .compatible = "atmel,24c01", .data = &at24_data_24c01 }, + { .compatible = "atmel,24cs01", .data = &at24_data_24cs01 }, + { .compatible = "atmel,24c02", .data = &at24_data_24c02 }, + { .compatible = "atmel,24cs02", .data = &at24_data_24cs02 }, + { .compatible = "atmel,24mac402", .data = &at24_data_24mac402 }, + { .compatible = "atmel,24mac602", .data = &at24_data_24mac602 }, + { .compatible = "atmel,spd", .data = &at24_data_spd }, + { .compatible = "atmel,24c04", .data = &at24_data_24c04 }, + { .compatible = "atmel,24cs04", .data = &at24_data_24cs04 }, + { .compatible = "atmel,24c08", .data = &at24_data_24c08 }, + { .compatible = "atmel,24cs08", .data = &at24_data_24cs08 }, + { .compatible = "atmel,24c16", .data = &at24_data_24c16 }, + { .compatible = "atmel,24cs16", .data = &at24_data_24cs16 }, + { .compatible = "atmel,24c32", .data = &at24_data_24c32 }, + { .compatible = "atmel,24cs32", .data = &at24_data_24cs32 }, + { .compatible = "atmel,24c64", .data = &at24_data_24c64 }, + { .compatible = "atmel,24cs64", .data = &at24_data_24cs64 }, + { .compatible = "atmel,24c128", .data = &at24_data_24c128 }, + { .compatible = "atmel,24c256", .data = &at24_data_24c256 }, + { .compatible = "atmel,24c512", .data = &at24_data_24c512 }, + { .compatible = "atmel,24c1024", .data = &at24_data_24c1024 }, + { .compatible = "atmel,24c2048", .data = &at24_data_24c2048 }, + { /* END OF LIST */ }, +}; +MODULE_DEVICE_TABLE(of, at24_of_match); + +static const struct acpi_device_id __maybe_unused at24_acpi_ids[] = { + { "INT3499", (kernel_ulong_t)&at24_data_INT3499 }, + { "TPF0001", (kernel_ulong_t)&at24_data_24c1024 }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(acpi, at24_acpi_ids); + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + * + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + */ +static struct at24_client *at24_translate_offset(struct at24_data *at24, + unsigned int *offset) +{ + unsigned int i; + + if (at24->flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return &at24->client[i]; +} + +static struct device *at24_base_client_dev(struct at24_data *at24) +{ + return &at24->client[0].client->dev; +} + +static size_t at24_adjust_read_count(struct at24_data *at24, + unsigned int offset, size_t count) +{ + unsigned int bits; + size_t remainder; + + /* + * In case of multi-address chips that don't rollover reads to + * the next slave address: truncate the count to the slave boundary, + * so that the read never straddles slaves. + */ + if (at24->flags & AT24_FLAG_NO_RDROL) { + bits = (at24->flags & AT24_FLAG_ADDR16) ? 16 : 8; + remainder = BIT(bits) - offset; + if (count > remainder) + count = remainder; + } + + if (count > at24_io_limit) + count = at24_io_limit; + + return count; +} + +static ssize_t at24_regmap_read(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct at24_client *at24_client; + struct i2c_client *client; + struct regmap *regmap; + int ret; + + at24_client = at24_translate_offset(at24, &offset); + regmap = at24_client->regmap; + client = at24_client->client; + count = at24_adjust_read_count(at24, offset, count); + + /* adjust offset for mac and serial read ops */ + offset += at24->offset_adj; + + timeout = jiffies + msecs_to_jiffies(at24_write_timeout); + do { + /* + * The timestamp shall be taken before the actual operation + * to avoid a premature timeout in case of high CPU load. + */ + read_time = jiffies; + + ret = regmap_bulk_read(regmap, offset, buf, count); + dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", + count, offset, ret, jiffies); + if (!ret) + return count; + + usleep_range(1000, 1500); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. These routines + * write at most one page. + */ + +static size_t at24_adjust_write_count(struct at24_data *at24, + unsigned int offset, size_t count) +{ + unsigned int next_page; + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->page_size); + if (offset + count > next_page) + count = next_page - offset; + + return count; +} + +static ssize_t at24_regmap_write(struct at24_data *at24, const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct at24_client *at24_client; + struct i2c_client *client; + struct regmap *regmap; + int ret; + + at24_client = at24_translate_offset(at24, &offset); + regmap = at24_client->regmap; + client = at24_client->client; + count = at24_adjust_write_count(at24, offset, count); + timeout = jiffies + msecs_to_jiffies(at24_write_timeout); + + do { + /* + * The timestamp shall be taken before the actual operation + * to avoid a premature timeout in case of high CPU load. + */ + write_time = jiffies; + + ret = regmap_bulk_write(regmap, offset, buf, count); + dev_dbg(&client->dev, "write %zu@%d --> %d (%ld)\n", + count, offset, ret, jiffies); + if (!ret) + return count; + + usleep_range(1000, 1500); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + +static int at24_read(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24; + struct device *dev; + char *buf = val; + int i, ret; + + at24 = priv; + dev = at24_base_client_dev(at24); + + if (unlikely(!count)) + return count; + + if (off + count > at24->byte_len) + return -EINVAL; + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + return ret; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + for (i = 0; count; i += ret, count -= ret) { + ret = at24_regmap_read(at24, buf + i, off + i, count); + if (ret < 0) { + mutex_unlock(&at24->lock); + pm_runtime_put(dev); + return ret; + } + } + + mutex_unlock(&at24->lock); + + pm_runtime_put(dev); + + if (unlikely(at24->read_post)) + at24->read_post(off, buf, i); + + return 0; +} + +static int at24_write(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24; + struct device *dev; + char *buf = val; + int ret; + + at24 = priv; + dev = at24_base_client_dev(at24); + + if (unlikely(!count)) + return -EINVAL; + + if (off + count > at24->byte_len) + return -EINVAL; + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + return ret; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + ret = at24_regmap_write(at24, buf, off, count); + if (ret < 0) { + mutex_unlock(&at24->lock); + pm_runtime_put(dev); + return ret; + } + buf += ret; + off += ret; + count -= ret; + } + + mutex_unlock(&at24->lock); + + pm_runtime_put(dev); + + return 0; +} + +static const struct at24_chip_data *at24_get_chip_data(struct device *dev) +{ + struct device_node *of_node = dev->of_node; + const struct at24_chip_data *cdata; + const struct i2c_device_id *id; + + id = i2c_match_id(at24_ids, to_i2c_client(dev)); + + /* + * The I2C core allows OF nodes compatibles to match against the + * I2C device ID table as a fallback, so check not only if an OF + * node is present but also if it matches an OF device ID entry. + */ + if (of_node && of_match_device(at24_of_match, dev)) + cdata = of_device_get_match_data(dev); + else if (id) + cdata = (void *)id->driver_data; + else + cdata = acpi_device_get_match_data(dev); + + if (!cdata) + return ERR_PTR(-ENODEV); + + return cdata; +} + +static int at24_make_dummy_client(struct at24_data *at24, unsigned int index, + struct regmap_config *regmap_config) +{ + struct i2c_client *base_client, *dummy_client; + struct regmap *regmap; + struct device *dev; + + base_client = at24->client[0].client; + dev = &base_client->dev; + + dummy_client = devm_i2c_new_dummy_device(dev, base_client->adapter, + base_client->addr + index); + if (IS_ERR(dummy_client)) + return PTR_ERR(dummy_client); + + regmap = devm_regmap_init_i2c(dummy_client, regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + at24->client[index].client = dummy_client; + at24->client[index].regmap = regmap; + + return 0; +} + +static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len) +{ + if (flags & AT24_FLAG_MAC) { + /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */ + return 0xa0 - byte_len; + } else if (flags & AT24_FLAG_SERIAL && flags & AT24_FLAG_ADDR16) { + /* + * For 16 bit address pointers, the word address must contain + * a '10' sequence in bits 11 and 10 regardless of the + * intended position of the address pointer. + */ + return 0x0800; + } else if (flags & AT24_FLAG_SERIAL) { + /* + * Otherwise the word address must begin with a '10' sequence, + * regardless of the intended address. + */ + return 0x0080; + } else { + return 0; + } +} + +static int at24_probe(struct i2c_client *client) +{ + struct regmap_config regmap_config = { }; + struct nvmem_config nvmem_config = { }; + u32 byte_len, page_size, flags, addrw; + const struct at24_chip_data *cdata; + struct device *dev = &client->dev; + bool i2c_fn_i2c, i2c_fn_block; + unsigned int i, num_addresses; + struct at24_data *at24; + struct regmap *regmap; + bool writable; + u8 test_byte; + int err; + + i2c_fn_i2c = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); + i2c_fn_block = i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK); + + cdata = at24_get_chip_data(dev); + if (IS_ERR(cdata)) + return PTR_ERR(cdata); + + err = device_property_read_u32(dev, "pagesize", &page_size); + if (err) + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via device tree + * or properties is recommended anyhow. + */ + page_size = 1; + + flags = cdata->flags; + if (device_property_present(dev, "read-only")) + flags |= AT24_FLAG_READONLY; + if (device_property_present(dev, "no-read-rollover")) + flags |= AT24_FLAG_NO_RDROL; + + err = device_property_read_u32(dev, "address-width", &addrw); + if (!err) { + switch (addrw) { + case 8: + if (flags & AT24_FLAG_ADDR16) + dev_warn(dev, + "Override address width to be 8, while default is 16\n"); + flags &= ~AT24_FLAG_ADDR16; + break; + case 16: + flags |= AT24_FLAG_ADDR16; + break; + default: + dev_warn(dev, "Bad \"address-width\" property: %u\n", + addrw); + } + } + + err = device_property_read_u32(dev, "size", &byte_len); + if (err) + byte_len = cdata->byte_len; + + if (!i2c_fn_i2c && !i2c_fn_block) + page_size = 1; + + if (!page_size) { + dev_err(dev, "page_size must not be 0!\n"); + return -EINVAL; + } + + if (!is_power_of_2(page_size)) + dev_warn(dev, "page_size looks suspicious (no power of 2)!\n"); + + err = device_property_read_u32(dev, "num-addresses", &num_addresses); + if (err) { + if (flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(byte_len, + (flags & AT24_FLAG_ADDR16) ? 65536 : 256); + } + + if ((flags & AT24_FLAG_SERIAL) && (flags & AT24_FLAG_MAC)) { + dev_err(dev, + "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC."); + return -EINVAL; + } + + regmap_config.val_bits = 8; + regmap_config.reg_bits = (flags & AT24_FLAG_ADDR16) ? 16 : 8; + regmap_config.disable_locking = true; + + regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + at24 = devm_kzalloc(dev, struct_size(at24, client, num_addresses), + GFP_KERNEL); + if (!at24) + return -ENOMEM; + + mutex_init(&at24->lock); + at24->byte_len = byte_len; + at24->page_size = page_size; + at24->flags = flags; + at24->read_post = cdata->read_post; + at24->num_addresses = num_addresses; + at24->offset_adj = at24_get_offset_adj(flags, byte_len); + at24->client[0].client = client; + at24->client[0].regmap = regmap; + + at24->vcc_reg = devm_regulator_get(dev, "vcc"); + if (IS_ERR(at24->vcc_reg)) + return PTR_ERR(at24->vcc_reg); + + writable = !(flags & AT24_FLAG_READONLY); + if (writable) { + at24->write_max = min_t(unsigned int, + page_size, at24_io_limit); + if (!i2c_fn_i2c && at24->write_max > I2C_SMBUS_BLOCK_MAX) + at24->write_max = I2C_SMBUS_BLOCK_MAX; + } + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + err = at24_make_dummy_client(at24, i, ®map_config); + if (err) + return err; + } + + /* + * If the 'label' property is not present for the AT24 EEPROM, + * then nvmem_config.id is initialised to NVMEM_DEVID_AUTO, + * and this will append the 'devid' to the name of the NVMEM + * device. This is purely legacy and the AT24 driver has always + * defaulted to this. However, if the 'label' property is + * present then this means that the name is specified by the + * firmware and this name should be used verbatim and so it is + * not necessary to append the 'devid'. + */ + if (device_property_present(dev, "label")) { + nvmem_config.id = NVMEM_DEVID_NONE; + err = device_property_read_string(dev, "label", + &nvmem_config.name); + if (err) + return err; + } else { + nvmem_config.id = NVMEM_DEVID_AUTO; + nvmem_config.name = dev_name(dev); + } + + nvmem_config.type = NVMEM_TYPE_EEPROM; + nvmem_config.dev = dev; + nvmem_config.read_only = !writable; + nvmem_config.root_only = !(flags & AT24_FLAG_IRUGO); + nvmem_config.owner = THIS_MODULE; + nvmem_config.compat = true; + nvmem_config.base_dev = dev; + nvmem_config.reg_read = at24_read; + nvmem_config.reg_write = at24_write; + nvmem_config.priv = at24; + nvmem_config.stride = 1; + nvmem_config.word_size = 1; + nvmem_config.size = byte_len; + + i2c_set_clientdata(client, at24); + + err = regulator_enable(at24->vcc_reg); + if (err) { + dev_err(dev, "Failed to enable vcc regulator\n"); + return err; + } + + /* enable runtime pm */ + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + at24->nvmem = devm_nvmem_register(dev, &nvmem_config); + if (IS_ERR(at24->nvmem)) { + pm_runtime_disable(dev); + if (!pm_runtime_status_suspended(dev)) + regulator_disable(at24->vcc_reg); + return PTR_ERR(at24->nvmem); + } + + /* + * Perform a one-byte test read to verify that the + * chip is functional. + */ + err = at24_read(at24, 0, &test_byte, 1); + if (err) { + pm_runtime_disable(dev); + if (!pm_runtime_status_suspended(dev)) + regulator_disable(at24->vcc_reg); + return -ENODEV; + } + + pm_runtime_idle(dev); + + if (writable) + dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n", + byte_len, client->name, at24->write_max); + else + dev_info(dev, "%u byte %s EEPROM, read-only\n", + byte_len, client->name); + + return 0; +} + +static int at24_remove(struct i2c_client *client) +{ + struct at24_data *at24 = i2c_get_clientdata(client); + + pm_runtime_disable(&client->dev); + if (!pm_runtime_status_suspended(&client->dev)) + regulator_disable(at24->vcc_reg); + pm_runtime_set_suspended(&client->dev); + + return 0; +} + +static int __maybe_unused at24_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct at24_data *at24 = i2c_get_clientdata(client); + + return regulator_disable(at24->vcc_reg); +} + +static int __maybe_unused at24_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct at24_data *at24 = i2c_get_clientdata(client); + + return regulator_enable(at24->vcc_reg); +} + +static const struct dev_pm_ops at24_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(at24_suspend, at24_resume, NULL) +}; + +static struct i2c_driver at24_driver = { + .driver = { + .name = "wb_at24", + .pm = &at24_pm_ops, + .of_match_table = at24_of_match, + .acpi_match_table = ACPI_PTR(at24_acpi_ids), + }, + .probe_new = at24_probe, + .remove = at24_remove, + .id_table = at24_ids, +}; + +static int __init at24_init(void) +{ + if (!at24_io_limit) { + pr_err("at24: at24_io_limit must not be 0!\n"); + return -EINVAL; + } + + at24_io_limit = rounddown_pow_of_two(at24_io_limit); + return i2c_add_driver(&at24_driver); +} +module_init(at24_init); + +static void __exit at24_exit(void) +{ + i2c_del_driver(&at24_driver); +} +module_exit(at24_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_csu550.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_csu550.c new file mode 100644 index 000000000000..574d344c7966 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_csu550.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Hardware monitoring driver for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_pmbus.h" + +struct pmbus_device_info { + int pages; + u32 flags; +}; + +static const struct i2c_device_id pmbus_id[]; + +/* + * Find sensor groups and status registers on each page. + */ +static void pmbus_find_sensor_groups(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int page; + + /* Sensors detected on page 0 only */ + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_VIN)) + info->func[0] |= PMBUS_HAVE_VIN; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_VCAP)) + info->func[0] |= PMBUS_HAVE_VCAP; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_IIN)) + info->func[0] |= PMBUS_HAVE_IIN; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_PIN)) + info->func[0] |= PMBUS_HAVE_PIN; + if (info->func[0] + && wb_pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT)) + info->func[0] |= PMBUS_HAVE_STATUS_INPUT; + if (wb_pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) && + wb_pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) { + info->func[0] |= PMBUS_HAVE_FAN12; + if (wb_pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN12; + } + if (wb_pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) && + wb_pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) { + info->func[0] |= PMBUS_HAVE_FAN34; + if (wb_pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN34; + } + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) + info->func[0] |= PMBUS_HAVE_TEMP; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2)) + info->func[0] |= PMBUS_HAVE_TEMP2; + if (wb_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3)) + info->func[0] |= PMBUS_HAVE_TEMP3; + if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_TEMP3) + && wb_pmbus_check_byte_register(client, 0, + PMBUS_STATUS_TEMPERATURE)) + info->func[0] |= PMBUS_HAVE_STATUS_TEMP; + + /* Sensors detected on all pages */ + for (page = 0; page < info->pages; page++) { + if (wb_pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) { + info->func[page] |= PMBUS_HAVE_VOUT; + if (wb_pmbus_check_byte_register(client, page, + PMBUS_STATUS_VOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_VOUT; + } + if (wb_pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) { + info->func[page] |= PMBUS_HAVE_IOUT; + if (wb_pmbus_check_byte_register(client, 0, + PMBUS_STATUS_IOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_IOUT; + } + if (wb_pmbus_check_word_register(client, page, PMBUS_READ_POUT)) + info->func[page] |= PMBUS_HAVE_POUT; + } +} + +/* + * Identify chip parameters. + */ +static int pmbus_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int ret = 0; + + if (!info->pages) { + /* + * Check if the PAGE command is supported. If it is, + * keep setting the page number until it fails or until the + * maximum number of pages has been reached. Assume that + * this is the number of pages supported by the chip. + */ + if (wb_pmbus_check_byte_register(client, 0, PMBUS_PAGE)) { + int page; + + for (page = 1; page < PMBUS_PAGES; page++) { + if (wb_pmbus_set_page(client, page, 0xff) < 0) + break; + } + wb_pmbus_set_page(client, 0, 0xff); + info->pages = page; + } else { + info->pages = 1; + } + + wb_pmbus_clear_faults(client); + } + + if (wb_pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) { + int vout_mode, i; + + vout_mode = wb_pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); + if (vout_mode >= 0 && vout_mode != 0xff) { + switch (vout_mode >> 5) { + case 0: + break; + case 1: + info->format[PSC_VOLTAGE_OUT] = vid; + for (i = 0; i < info->pages; i++) + info->vrm_version[i] = vr11; + break; + case 2: + info->format[PSC_VOLTAGE_OUT] = direct; + break; + default: + ret = -ENODEV; + goto abort; + } + } + } + + /* + * We should check if the COEFFICIENTS register is supported. + * If it is, and the chip is configured for direct mode, we can read + * the coefficients from the chip, one set per group of sensor + * registers. + * + * To do this, we will need access to a chip which actually supports the + * COEFFICIENTS command, since the command is too complex to implement + * without testing it. Until then, abort if a chip configured for direct + * mode was detected. + */ + if (info->format[PSC_VOLTAGE_OUT] == direct) { + ret = -ENODEV; + goto abort; + } + + /* Try to find sensor groups */ + pmbus_find_sensor_groups(client, info); +abort: + return ret; +} + +static int pmbus_probe(struct i2c_client *client) +{ + struct pmbus_driver_info *info; + struct pmbus_platform_data *pdata = NULL; + struct device *dev = &client->dev; + struct pmbus_device_info *device_info; + + info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + device_info = (struct pmbus_device_info *)i2c_match_id(pmbus_id, client)->driver_data; + if (device_info->flags & PMBUS_SKIP_STATUS_CHECK) { + pdata = devm_kzalloc(dev, sizeof(struct pmbus_platform_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdata->flags = PMBUS_SKIP_STATUS_CHECK; + } + + info->pages = device_info->pages; + info->identify = pmbus_identify; + dev->platform_data = pdata; + + return wb_pmbus_do_probe(client, info); +} + +static const struct pmbus_device_info pmbus_info_one = { + .pages = 1, + .flags = 0 +}; + +static const struct pmbus_device_info pmbus_info_zero = { + .pages = 0, + .flags = 0 +}; + +static const struct pmbus_device_info pmbus_info_one_skip = { + .pages = 1, + .flags = PMBUS_SKIP_STATUS_CHECK +}; + +static const struct pmbus_device_info pmbus_info_zero_skip = { + .pages = 0, + .flags = PMBUS_SKIP_STATUS_CHECK +}; +/* + * Use driver_data to set the number of pages supported by the chip. + */ +static const struct i2c_device_id pmbus_id[] = { + {"wb_csu550", (kernel_ulong_t)&pmbus_info_zero_skip}, + {"wb_csu800", (kernel_ulong_t)&pmbus_info_one_skip}, + {"wb_fsp1200", (kernel_ulong_t)&pmbus_info_one_skip}, + {"wb_dps550", (kernel_ulong_t)&pmbus_info_one_skip}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pmbus_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver pmbus_driver = { + .driver = { + .name = "wb_pmbus", + }, + .probe_new = pmbus_probe, + .remove = wb_pmbus_do_remove, + .id_table = pmbus_id, +}; + +module_i2c_driver(pmbus_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Generic PMBus driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_algo_bit.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_algo_bit.c new file mode 100644 index 000000000000..c98ac7a1c5b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_algo_bit.c @@ -0,0 +1,725 @@ +/* ------------------------------------------------------------------------- + * i2c-algo-bit.c i2c driver algorithms for bit-shift adapters + * ------------------------------------------------------------------------- + * Copyright (C) 1995-2000 Simon G. Vogl + + 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. + * ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include + +static int g_i2c_algo_bit_debug = 0; +static int g_i2c_algo_bit_error = 0; + +module_param(g_i2c_algo_bit_debug, int, S_IRUGO | S_IWUSR); +module_param(g_i2c_algo_bit_error, int, S_IRUGO | S_IWUSR); + +#define I2C_ALGO_BIT_DEBUG(fmt, args...) do { \ + if (g_i2c_algo_bit_debug) { \ + printk(KERN_INFO "[I2C_ALGO_BIT][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define I2C_ALGO_BIT_ERROR(fmt, args...) do { \ + if (g_i2c_algo_bit_error) { \ + printk(KERN_ERR "[I2C_ALGO_BIT][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* ----- global defines ----------------------------------------------- */ + +#ifdef DEBUG +#define bit_dbg(level, dev, format, args...) \ + do { \ + if (i2c_debug >= level) \ + dev_dbg(dev, format, ##args); \ + } while (0) +#else +#define bit_dbg(level, dev, format, args...) \ + do {} while (0) +#endif /* DEBUG */ + +/* ----- global variables --------------------------------------------- */ + +static int bit_test; /* see if the line-setting functions work */ +module_param(bit_test, int, S_IRUGO); +MODULE_PARM_DESC(bit_test, "lines testing - 0 off; 1 report; 2 fail if stuck"); + +#ifdef DEBUG +static int i2c_debug = 1; +module_param(i2c_debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(i2c_debug, + "debug level - 0 off; 1 normal; 2 verbose; 3 very verbose"); +#endif + +/* --- setting states on the bus with the right timing: --------------- */ + +#define setsda(adap, val) adap->setsda(adap->data, val) +#define setscl(adap, val) adap->setscl(adap->data, val) +#define getsda(adap) adap->getsda(adap->data) +#define getscl(adap) adap->getscl(adap->data) + +static inline void sdalo(struct i2c_algo_bit_data *adap) +{ + setsda(adap, 0); + udelay((adap->udelay + 1) / 2); +} + +static inline void sdahi(struct i2c_algo_bit_data *adap) +{ + setsda(adap, 1); + udelay((adap->udelay + 1) / 2); +} + +static inline void scllo(struct i2c_algo_bit_data *adap) +{ + setscl(adap, 0); + udelay(adap->udelay / 2); +} + +/* + * Raise scl line, and do checking for delays. This is necessary for slower + * devices. + */ +static int sclhi(struct i2c_algo_bit_data *adap) +{ + unsigned long start; + + setscl(adap, 1); + + /* Not all adapters have scl sense line... */ + if (!adap->getscl) + goto done; + + start = jiffies; + while (!getscl(adap)) { + /* This hw knows how to read the clock line, so we wait + * until it actually gets high. This is safer as some + * chips may hold it low ("clock stretching") while they + * are processing data internally. + */ + if (time_after(jiffies, start + adap->timeout)) { + /* Test one last time, as we may have been preempted + * between last check and timeout test. + */ + if (getscl(adap)) + break; + return -ETIMEDOUT; + } + cpu_relax(); + } +#ifdef DEBUG + if (jiffies != start && i2c_debug >= 3) + pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go " + "high\n", jiffies - start); +#endif + +done: + udelay(adap->udelay); + return 0; +} + +/* --- other auxiliary functions -------------------------------------- */ +static void i2c_start(struct i2c_algo_bit_data *adap) +{ + /* assert: scl, sda are high */ + setsda(adap, 0); + udelay(adap->udelay); + scllo(adap); +} + +static void i2c_repstart(struct i2c_algo_bit_data *adap) +{ + /* assert: scl is low */ + sdahi(adap); + sclhi(adap); + setsda(adap, 0); + udelay(adap->udelay); + scllo(adap); +} + +static void i2c_stop(struct i2c_algo_bit_data *adap) +{ + /* assert: scl is low */ + sdalo(adap); + sclhi(adap); + setsda(adap, 1); + udelay(adap->udelay); +} + +/* send a byte without start cond., look for arbitration, + check ackn. from slave */ +/* returns: + * 1 if the device acknowledged + * 0 if the device did not ack + * -ETIMEDOUT if an error occurred (while raising the scl line) + */ +static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) +{ + int i; + int sb; + int ack; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: scl is low */ + for (i = 7; i >= 0; i--) { + sb = (c >> i) & 1; + setsda(adap, sb); + udelay((adap->udelay + 1) / 2); + if (sclhi(adap) < 0) { /* timed out */ + bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " + "timeout at bit #%d\n", (int)c, i); + return -ETIMEDOUT; + } + /* FIXME do arbitration here: + * if (sb && !getsda(adap)) -> ouch! Get out of here. + * + * Report a unique code, so higher level code can retry + * the whole (combined) message and *NOT* issue STOP. + */ + scllo(adap); + } + sdahi(adap); + if (sclhi(adap) < 0) { /* timeout */ + bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " + "timeout at ack\n", (int)c); + return -ETIMEDOUT; + } + + /* read ack: SDA should be pulled down by slave, or it may + * NAK (usually to report problems with the data we wrote). + */ + ack = !getsda(adap); /* ack: sda is pulled low -> success */ + bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, + ack ? "A" : "NA"); + + scllo(adap); + return ack; + /* assert: scl is low (sda undef) */ +} + +static int i2c_inb(struct i2c_adapter *i2c_adap) +{ + /* read byte via i2c port, without start/stop sequence */ + /* acknowledge is sent in i2c_read. */ + int i; + unsigned char indata = 0; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: scl is low */ + sdahi(adap); + for (i = 0; i < 8; i++) { + if (sclhi(adap) < 0) { /* timeout */ + bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit " + "#%d\n", 7 - i); + return -ETIMEDOUT; + } + indata *= 2; + if (getsda(adap)) + indata |= 0x01; + setscl(adap, 0); + udelay(i == 7 ? adap->udelay / 2 : adap->udelay); + } + /* assert: scl is low */ + return indata; +} + +/* + * Sanity check for the adapter hardware - check the reaction of + * the bus lines only if it seems to be idle. + */ +static int test_bus(struct i2c_adapter *i2c_adap) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + const char *name = i2c_adap->name; + int scl, sda, ret; + + if (adap->pre_xfer) { + ret = adap->pre_xfer(i2c_adap); + if (ret < 0) + return -ENODEV; + } + + if (adap->getscl == NULL) + pr_info("%s: Testing SDA only, SCL is not readable\n", name); + + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (!scl || !sda) { + printk(KERN_WARNING + "%s: bus seems to be busy (scl=%d, sda=%d)\n", + name, scl, sda); + goto bailout; + } + + sdalo(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (sda) { + printk(KERN_WARNING "%s: SDA stuck high!\n", name); + goto bailout; + } + if (!scl) { + printk(KERN_WARNING "%s: SCL unexpected low " + "while pulling SDA low!\n", name); + goto bailout; + } + + sdahi(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (!sda) { + printk(KERN_WARNING "%s: SDA stuck low!\n", name); + goto bailout; + } + if (!scl) { + printk(KERN_WARNING "%s: SCL unexpected low " + "while pulling SDA high!\n", name); + goto bailout; + } + + scllo(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 0 : getscl(adap); + if (scl) { + printk(KERN_WARNING "%s: SCL stuck high!\n", name); + goto bailout; + } + if (!sda) { + printk(KERN_WARNING "%s: SDA unexpected low " + "while pulling SCL low!\n", name); + goto bailout; + } + + sclhi(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (!scl) { + printk(KERN_WARNING "%s: SCL stuck low!\n", name); + goto bailout; + } + if (!sda) { + printk(KERN_WARNING "%s: SDA unexpected low " + "while pulling SCL high!\n", name); + goto bailout; + } + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); + + pr_info("%s: Test OK\n", name); + return 0; +bailout: + sdahi(adap); + sclhi(adap); + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); + + return -ENODEV; +} + +/* ----- Utility functions + */ + +/* try_address tries to contact a chip for a number of + * times before it gives up. + * return values: + * 1 chip answered + * 0 chip did not answer + * -x transmission error + */ +static int try_address(struct i2c_adapter *i2c_adap, + unsigned char addr, int retries) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int i, ret = 0; + + for (i = 0; i <= retries; i++) { + ret = i2c_outb(i2c_adap, addr); + if (ret == 1 || i == retries) + break; + bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); + i2c_stop(adap); + udelay(adap->udelay); + yield(); + bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); + i2c_start(adap); + } + if (i && ret) + bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at " + "0x%02x: %s\n", i + 1, + addr & 1 ? "read from" : "write to", addr >> 1, + ret == 1 ? "success" : "failed, timeout?"); + return ret; +} + +static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + const unsigned char *temp = msg->buf; + int count = msg->len; + unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + int retval; + int wrcount = 0; + + while (count > 0) { + retval = i2c_outb(i2c_adap, *temp); + + /* OK/ACK; or ignored NAK */ + if ((retval > 0) || (nak_ok && (retval == 0))) { + count--; + temp++; + wrcount++; + + /* A slave NAKing the master means the slave didn't like + * something about the data it saw. For example, maybe + * the SMBus PEC was wrong. + */ + } else if (retval == 0) { + dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n"); + return -EIO; + + /* Timeout; or (someday) lost arbitration + * + * FIXME Lost ARB implies retrying the transaction from + * the first message, after the "winning" master issues + * its STOP. As a rule, upper layer code has no reason + * to know or care about this ... it is *NOT* an error. + */ + } else { + dev_err(&i2c_adap->dev, "sendbytes: error %d\n", + retval); + return retval; + } + } + return wrcount; +} + +static int acknak(struct i2c_adapter *i2c_adap, int is_ack) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: sda is high */ + if (is_ack) /* send ack */ + setsda(adap, 0); + udelay((adap->udelay + 1) / 2); + if (sclhi(adap) < 0) { /* timeout */ + dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n"); + return -ETIMEDOUT; + } + scllo(adap); + return 0; +} + +static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int inval; + int rdcount = 0; /* counts bytes read */ + unsigned char *temp = msg->buf; + int count = msg->len; + const unsigned flags = msg->flags; + + while (count > 0) { + inval = i2c_inb(i2c_adap); + if (inval >= 0) { + *temp = inval; + rdcount++; + } else { /* read timed out */ + break; + } + + temp++; + count--; + + /* Some SMBus transactions require that we receive the + transaction length as the first read byte. */ + if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) { + if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { + if (!(flags & I2C_M_NO_RD_ACK)) + acknak(i2c_adap, 0); + dev_err(&i2c_adap->dev, "readbytes: invalid " + "block length (%d)\n", inval); + return -EPROTO; + } + /* The original count value accounts for the extra + bytes, that is, either 1 for a regular transaction, + or 2 for a PEC transaction. */ + count += inval; + msg->len += inval; + } + + bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n", + inval, + (flags & I2C_M_NO_RD_ACK) + ? "(no ack/nak)" + : (count ? "A" : "NA")); + + if (!(flags & I2C_M_NO_RD_ACK)) { + inval = acknak(i2c_adap, count); + if (inval < 0) + return inval; + } + } + return rdcount; +} + +/* doAddress initiates the transfer by generating the start condition (in + * try_address) and transmits the address in the necessary format to handle + * reads, writes as well as 10bit-addresses. + * returns: + * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set + * -x an error occurred (like: -ENXIO if the device did not answer, or + * -ETIMEDOUT, for example if the lines are stuck...) + */ +static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + unsigned char addr; + int ret, retries; + + retries = nak_ok ? 0 : i2c_adap->retries; + + if (flags & I2C_M_TEN) { + /* a ten bit address */ + addr = 0xf0 | ((msg->addr >> 7) & 0x06); + bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); + /* try extended address code...*/ + ret = try_address(i2c_adap, addr, retries); + if ((ret != 1) && !nak_ok) { + dev_err(&i2c_adap->dev, + "died at extended address code\n"); + return -ENXIO; + } + /* the remaining 8 bit address */ + ret = i2c_outb(i2c_adap, msg->addr & 0xff); + if ((ret != 1) && !nak_ok) { + /* the chip did not ack / xmission error occurred */ + dev_err(&i2c_adap->dev, "died at 2nd address code\n"); + return -ENXIO; + } + if (flags & I2C_M_RD) { + bit_dbg(3, &i2c_adap->dev, "emitting repeated " + "start condition\n"); + i2c_repstart(adap); + /* okay, now switch into reading mode */ + addr |= 0x01; + ret = try_address(i2c_adap, addr, retries); + if ((ret != 1) && !nak_ok) { + dev_err(&i2c_adap->dev, + "died at repeated address code\n"); + return -EIO; + } + } + } else { /* normal 7bit address */ + addr = msg->addr << 1; + if (flags & I2C_M_RD) + addr |= 1; + if (flags & I2C_M_REV_DIR_ADDR) + addr ^= 1; + ret = try_address(i2c_adap, addr, retries); + if ((ret != 1) && !nak_ok) + return -ENXIO; + } + + return 0; +} + +static void bit_i2c_unblock(struct i2c_adapter *i2c_adap) +{ + int i; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + for (i = 0; i < 9; i++) { + setscl(adap, 0); + udelay(5); + setscl(adap, 1); + udelay(5); + } + setscl(adap, 0); + setsda(adap, 0); + udelay(5); + setscl(adap, 1); + udelay(5); + setsda(adap, 1); +} + +static int check_bit_i2c_unblock(struct i2c_adapter *i2c_adap) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int sda, scl; + + sda = getsda(adap); + scl = getscl(adap); + if ((sda == 0) && scl) { + I2C_ALGO_BIT_ERROR("SCL is high and SDA is low, send 9 clock to device.\n"); + bit_i2c_unblock(i2c_adap); + } + + sda = getsda(adap); + scl = getscl(adap); + if (sda && scl) { + I2C_ALGO_BIT_DEBUG("SCL and SDA are both high, i2c level check ok.\n"); + return 0; + } + dev_warn(&i2c_adap->dev, "Check i2c level failed, SCL %s, SDA %s.\n", scl ? "high" : "low", sda ? "high" : "low"); + return -EIO; +} + +static int bit_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], int num) +{ + struct i2c_msg *pmsg; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int i, ret; + unsigned short nak_ok; + + if (adap->pre_xfer) { + ret = adap->pre_xfer(i2c_adap); + if (ret < 0) + return ret; + } + + if (check_bit_i2c_unblock(i2c_adap) < 0) { + I2C_ALGO_BIT_ERROR("check i2c is block.\n"); + return -EIO; + } + + bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); + i2c_start(adap); + for (i = 0; i < num; i++) { + pmsg = &msgs[i]; + nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; + if (!(pmsg->flags & I2C_M_NOSTART)) { + if (i) { + bit_dbg(3, &i2c_adap->dev, "emitting " + "repeated start condition\n"); + i2c_repstart(adap); + } + ret = bit_doAddress(i2c_adap, pmsg); + if ((ret != 0) && !nak_ok) { + bit_dbg(1, &i2c_adap->dev, "NAK from " + "device addr 0x%02x msg #%d\n", + msgs[i].addr, i); + goto bailout; + } + } + if (pmsg->flags & I2C_M_RD) { + /* read bytes into buffer*/ + ret = readbytes(i2c_adap, pmsg); + if (ret >= 1) + bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n", + ret, ret == 1 ? "" : "s"); + if (ret < pmsg->len) { + if (ret >= 0) + ret = -EIO; + goto bailout; + } + } else { + /* write bytes from buffer */ + ret = sendbytes(i2c_adap, pmsg); + if (ret >= 1) + bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n", + ret, ret == 1 ? "" : "s"); + if (ret < pmsg->len) { + if (ret >= 0) + ret = -EIO; + goto bailout; + } + } + } + ret = i; + +bailout: + bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); + i2c_stop(adap); + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); + return ret; +} + +static u32 bit_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_SMBUS_READ_BLOCK_DATA | + I2C_FUNC_SMBUS_BLOCK_PROC_CALL | + I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; +} + +/* -----exported algorithm data: ------------------------------------- */ + +const struct i2c_algorithm wb_i2c_bit_algo = { + .master_xfer = bit_xfer, + .functionality = bit_func, +}; +EXPORT_SYMBOL(wb_i2c_bit_algo); + +static const struct i2c_adapter_quirks i2c_bit_quirk_no_clk_stretch = { + .flags = I2C_AQ_NO_CLK_STRETCH, +}; + +/* + * registering functions to load algorithms at runtime + */ +static int __i2c_bit_add_bus(struct i2c_adapter *adap, + int (*add_adapter)(struct i2c_adapter *)) +{ + struct i2c_algo_bit_data *bit_adap = adap->algo_data; + int ret; + + if (bit_test) { + ret = test_bus(adap); + if (bit_test >= 2 && ret < 0) + return -ENODEV; + } + + /* register new adapter to i2c module... */ + adap->algo = &wb_i2c_bit_algo; + adap->retries = 3; + if (bit_adap->getscl == NULL) + adap->quirks = &i2c_bit_quirk_no_clk_stretch; + + ret = add_adapter(adap); + if (ret < 0) + return ret; + + /* Complain if SCL can't be read */ + if (bit_adap->getscl == NULL) { + dev_warn(&adap->dev, "Not I2C compliant: can't read SCL\n"); + dev_warn(&adap->dev, "Bus may be unreliable\n"); + } + return 0; +} + +int wb_i2c_bit_add_bus(struct i2c_adapter *adap) +{ + return __i2c_bit_add_bus(adap, i2c_add_adapter); +} +EXPORT_SYMBOL(wb_i2c_bit_add_bus); + +int wb_i2c_bit_add_numbered_bus(struct i2c_adapter *adap) +{ + return __i2c_bit_add_bus(adap, i2c_add_numbered_adapter); +} +EXPORT_SYMBOL(wb_i2c_bit_add_numbered_bus); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio.c new file mode 100644 index 000000000000..0362e905fddb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio.c @@ -0,0 +1,431 @@ +/* + * Bitbanging I2C bus driver using the GPIO API + * + * Copyright (C) 2007 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int wb_i2c_bit_add_numbered_bus(struct i2c_adapter *adap); + +struct i2c_gpio_private_data { + struct gpio_desc *sda; + struct gpio_desc *scl; + struct i2c_adapter adap; + struct i2c_algo_bit_data bit_data; + struct i2c_gpio_platform_data pdata; +#ifdef CONFIG_I2C_GPIO_FAULT_INJECTOR + struct dentry *debug_dir; +#endif +}; + +/* + * Toggle SDA by changing the output value of the pin. This is only + * valid for pins configured as open drain (i.e. setting the value + * high effectively turns off the output driver.) + */ +static void i2c_gpio_setsda_val(void *data, int state) +{ + struct i2c_gpio_private_data *priv = data; + + gpiod_set_value_cansleep(priv->sda, state); +} + +/* + * Toggle SCL by changing the output value of the pin. This is used + * for pins that are configured as open drain and for output-only + * pins. The latter case will break the i2c protocol, but it will + * often work in practice. + */ +static void i2c_gpio_setscl_val(void *data, int state) +{ + struct i2c_gpio_private_data *priv = data; + + gpiod_set_value_cansleep(priv->scl, state); +} + +static int i2c_gpio_getsda(void *data) +{ + struct i2c_gpio_private_data *priv = data; + + return gpiod_get_value_cansleep(priv->sda); +} + +static int i2c_gpio_getscl(void *data) +{ + struct i2c_gpio_private_data *priv = data; + + return gpiod_get_value_cansleep(priv->scl); +} + +#ifdef CONFIG_I2C_GPIO_FAULT_INJECTOR +static struct dentry *i2c_gpio_debug_dir; + +#define setsda(bd, val) ((bd)->setsda((bd)->data, val)) +#define setscl(bd, val) ((bd)->setscl((bd)->data, val)) +#define getsda(bd) ((bd)->getsda((bd)->data)) +#define getscl(bd) ((bd)->getscl((bd)->data)) + +#define WIRE_ATTRIBUTE(wire) \ +static int fops_##wire##_get(void *data, u64 *val) \ +{ \ + struct i2c_gpio_private_data *priv = data; \ + \ + i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ + *val = get##wire(&priv->bit_data); \ + i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ + return 0; \ +} \ +static int fops_##wire##_set(void *data, u64 val) \ +{ \ + struct i2c_gpio_private_data *priv = data; \ + \ + i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ + set##wire(&priv->bit_data, val); \ + i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ + return 0; \ +} \ +DEFINE_DEBUGFS_ATTRIBUTE(fops_##wire, fops_##wire##_get, fops_##wire##_set, "%llu\n") + +WIRE_ATTRIBUTE(scl); +WIRE_ATTRIBUTE(sda); + +static void i2c_gpio_incomplete_transfer(struct i2c_gpio_private_data *priv, + u32 pattern, u8 pattern_size) +{ + struct i2c_algo_bit_data *bit_data = &priv->bit_data; + int i; + + i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); + + /* START condition */ + setsda(bit_data, 0); + udelay(bit_data->udelay); + + /* Send pattern, request ACK, don't send STOP */ + for (i = pattern_size - 1; i >= 0; i--) { + setscl(bit_data, 0); + udelay(bit_data->udelay / 2); + setsda(bit_data, (pattern >> i) & 1); + udelay((bit_data->udelay + 1) / 2); + setscl(bit_data, 1); + udelay(bit_data->udelay); + } + + i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); +} + +static int fops_incomplete_addr_phase_set(void *data, u64 addr) +{ + struct i2c_gpio_private_data *priv = data; + u32 pattern; + + if (addr > 0x7f) + return -EINVAL; + + /* ADDR (7 bit) + RD (1 bit) + Client ACK, keep SDA hi (1 bit) */ + pattern = (addr << 2) | 3; + + i2c_gpio_incomplete_transfer(priv, pattern, 9); + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(fops_incomplete_addr_phase, NULL, fops_incomplete_addr_phase_set, "%llu\n"); + +static int fops_incomplete_write_byte_set(void *data, u64 addr) +{ + struct i2c_gpio_private_data *priv = data; + u32 pattern; + + if (addr > 0x7f) + return -EINVAL; + + /* ADDR (7 bit) + WR (1 bit) + Client ACK (1 bit) */ + pattern = (addr << 2) | 1; + /* 0x00 (8 bit) + Client ACK, keep SDA hi (1 bit) */ + pattern = (pattern << 9) | 1; + + i2c_gpio_incomplete_transfer(priv, pattern, 18); + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(fops_incomplete_write_byte, NULL, fops_incomplete_write_byte_set, "%llu\n"); + +static void i2c_gpio_fault_injector_init(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv = platform_get_drvdata(pdev); + + /* + * If there will be a debugfs-dir per i2c adapter somewhen, put the + * 'fault-injector' dir there. Until then, we have a global dir with + * all adapters as subdirs. + */ + if (!i2c_gpio_debug_dir) { + i2c_gpio_debug_dir = debugfs_create_dir("i2c-fault-injector", NULL); + if (!i2c_gpio_debug_dir) + return; + } + + priv->debug_dir = debugfs_create_dir(pdev->name, i2c_gpio_debug_dir); + if (!priv->debug_dir) + return; + + debugfs_create_file_unsafe("scl", 0600, priv->debug_dir, priv, &fops_scl); + debugfs_create_file_unsafe("sda", 0600, priv->debug_dir, priv, &fops_sda); + debugfs_create_file_unsafe("incomplete_address_phase", 0200, priv->debug_dir, + priv, &fops_incomplete_addr_phase); + debugfs_create_file_unsafe("incomplete_write_byte", 0200, priv->debug_dir, + priv, &fops_incomplete_write_byte); +} + +static void i2c_gpio_fault_injector_exit(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv = platform_get_drvdata(pdev); + + debugfs_remove_recursive(priv->debug_dir); +} +#else +static inline void i2c_gpio_fault_injector_init(struct platform_device *pdev) {} +static inline void i2c_gpio_fault_injector_exit(struct platform_device *pdev) {} +#endif /* CONFIG_I2C_GPIO_FAULT_INJECTOR*/ + +static void of_i2c_gpio_get_props(struct device_node *np, + struct i2c_gpio_platform_data *pdata) +{ + u32 reg; + + of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay); + + if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", ®)) + pdata->timeout = msecs_to_jiffies(reg); + + pdata->sda_is_open_drain = + of_property_read_bool(np, "i2c-gpio,sda-open-drain"); + pdata->scl_is_open_drain = + of_property_read_bool(np, "i2c-gpio,scl-open-drain"); + pdata->scl_is_output_only = + of_property_read_bool(np, "i2c-gpio,scl-output-only"); +} + +static struct gpio_desc *i2c_gpio_get_desc(struct device *dev, + const char *con_id, + unsigned int index, + enum gpiod_flags gflags) +{ + struct gpio_desc *retdesc; + int ret; + + retdesc = devm_gpiod_get(dev, con_id, gflags); + if (!IS_ERR(retdesc)) { + dev_dbg(dev, "got GPIO from name %s\n", con_id); + return retdesc; + } + + retdesc = devm_gpiod_get_index(dev, NULL, index, gflags); + if (!IS_ERR(retdesc)) { + dev_dbg(dev, "got GPIO from index %u\n", index); + return retdesc; + } + + ret = PTR_ERR(retdesc); + + /* FIXME: hack in the old code, is this really necessary? */ + if (ret == -EINVAL) + retdesc = ERR_PTR(-EPROBE_DEFER); + + /* This happens if the GPIO driver is not yet probed, let's defer */ + if (ret == -ENOENT) + retdesc = ERR_PTR(-EPROBE_DEFER); + + if (PTR_ERR(retdesc) != -EPROBE_DEFER) + dev_err(dev, "error trying to get descriptor: %d\n", ret); + + return retdesc; +} + +static int i2c_gpio_probe(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv; + struct i2c_gpio_platform_data *pdata; + struct i2c_algo_bit_data *bit_data; + struct i2c_adapter *adap; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + enum gpiod_flags gflags; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + adap = &priv->adap; + bit_data = &priv->bit_data; + pdata = &priv->pdata; + + if (np) { + of_i2c_gpio_get_props(np, pdata); + } else { + /* + * If all platform data settings are zero it is OK + * to not provide any platform data from the board. + */ + if (dev_get_platdata(dev)) + memcpy(pdata, dev_get_platdata(dev), sizeof(*pdata)); + } + + /* + * First get the GPIO pins; if it fails, we'll defer the probe. + * If the SDA line is marked from platform data or device tree as + * "open drain" it means something outside of our control is making + * this line being handled as open drain, and we should just handle + * it as any other output. Else we enforce open drain as this is + * required for an I2C bus. + */ + if (pdata->sda_is_open_drain) + gflags = GPIOD_OUT_HIGH; + else + gflags = GPIOD_OUT_HIGH_OPEN_DRAIN; + priv->sda = i2c_gpio_get_desc(dev, "sda", 0, gflags); + if (IS_ERR(priv->sda)) + return PTR_ERR(priv->sda); + + /* + * If the SCL line is marked from platform data or device tree as + * "open drain" it means something outside of our control is making + * this line being handled as open drain, and we should just handle + * it as any other output. Else we enforce open drain as this is + * required for an I2C bus. + */ + if (pdata->scl_is_open_drain) + gflags = GPIOD_OUT_HIGH; + else + gflags = GPIOD_OUT_HIGH_OPEN_DRAIN; + priv->scl = i2c_gpio_get_desc(dev, "scl", 1, gflags); + if (IS_ERR(priv->scl)) + return PTR_ERR(priv->scl); + + if (gpiod_cansleep(priv->sda) || gpiod_cansleep(priv->scl)) + dev_warn(dev, "Slow GPIO pins might wreak havoc into I2C/SMBus bus timing"); + + bit_data->setsda = i2c_gpio_setsda_val; + bit_data->setscl = i2c_gpio_setscl_val; + + if (!pdata->scl_is_output_only) + bit_data->getscl = i2c_gpio_getscl; + bit_data->getsda = i2c_gpio_getsda; + + if (pdata->udelay) + bit_data->udelay = pdata->udelay; + else if (pdata->scl_is_output_only) + bit_data->udelay = 50; /* 10 kHz */ + else + bit_data->udelay = 5; /* 100 kHz */ + + if (pdata->timeout) + bit_data->timeout = pdata->timeout; + else + bit_data->timeout = HZ / 10; /* 100 ms */ + + bit_data->data = priv; + + adap->owner = THIS_MODULE; + if (np) + strlcpy(adap->name, dev_name(dev), sizeof(adap->name)); + else + snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id); + + adap->algo_data = bit_data; + adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + adap->dev.parent = dev; + adap->dev.of_node = np; + + adap->nr = pdev->id; + ret = wb_i2c_bit_add_numbered_bus(adap); + if (ret) + return ret; + + platform_set_drvdata(pdev, priv); + + /* + * FIXME: using global GPIO numbers is not helpful. If/when we + * get accessors to get the actual name of the GPIO line, + * from the descriptor, then provide that instead. + */ + dev_info(dev, "using lines %u (SDA) and %u (SCL%s)\n", + desc_to_gpio(priv->sda), desc_to_gpio(priv->scl), + pdata->scl_is_output_only + ? ", no clock stretching" : ""); + + i2c_gpio_fault_injector_init(pdev); + + return 0; +} + +static int i2c_gpio_remove(struct platform_device *pdev) +{ + struct i2c_gpio_private_data *priv; + struct i2c_adapter *adap; + + i2c_gpio_fault_injector_exit(pdev); + + priv = platform_get_drvdata(pdev); + adap = &priv->adap; + + i2c_del_adapter(adap); + + return 0; +} + +#if defined(CONFIG_OF) +static const struct of_device_id i2c_gpio_dt_ids[] = { + { .compatible = "wb-i2c-gpio", }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids); +#endif + +static struct platform_driver i2c_gpio_driver = { + .driver = { + .name = "wb-i2c-gpio", + .of_match_table = of_match_ptr(i2c_gpio_dt_ids), + }, + .probe = i2c_gpio_probe, + .remove = i2c_gpio_remove, +}; + +static int __init i2c_gpio_init(void) +{ + int ret; + + ret = platform_driver_register(&i2c_gpio_driver); + if (ret) + printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); + + return ret; +} +subsys_initcall(i2c_gpio_init); + +static void __exit i2c_gpio_exit(void) +{ + platform_driver_unregister(&i2c_gpio_driver); +} +module_exit(i2c_gpio_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:i2c-gpio"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio_device.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio_device.c new file mode 100644 index 000000000000..5cf949d70ef8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_gpio_device.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int gpio_sda = 17; +module_param(gpio_sda, int, S_IRUGO | S_IWUSR); + +static int gpio_scl = 1; +module_param(gpio_scl, int, S_IRUGO | S_IWUSR); + +static int gpio_udelay = 2; +module_param(gpio_udelay, int, S_IRUGO | S_IWUSR); + +static int g_wb_i2c_gpio_device_debug = 0; +static int g_wb_i2c_gpio_device_error = 0; + +module_param(g_wb_i2c_gpio_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_gpio_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_GPIO_DEVICE_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_gpio_device_debug) { \ + printk(KERN_INFO "[WB_I2C_GPIO_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_GPIO_DEVICE_ERROR(fmt, args...) do { \ + if (g_wb_i2c_gpio_device_error) { \ + printk(KERN_ERR "[WB_I2C_GPIO_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/****************** i2c adapter with gpio ***********************/ +static struct i2c_gpio_platform_data i2c_pdata = { + .udelay = 2, + .scl_is_output_only = 0, + .sda_is_open_drain = 0, + .scl_is_open_drain = 0, +}; + +static void i2c_gpio_release(struct device *dev) +{ + return; +} + +static struct platform_device wb_i2c_gpio_device = { + .name = "wb-i2c-gpio", + .id = -1, + .num_resources = 0, + .resource = NULL, + .dev = { + .platform_data = &i2c_pdata, + .release = i2c_gpio_release, + }, +}; + +/* + * i2c + */ +static struct gpiod_lookup_table wb_i2c_gpio_table = { + .dev_id = "wb-i2c-gpio", + .table = { + GPIO_LOOKUP_IDX("wb_gpio_d1500", 17, NULL, 0, + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), + GPIO_LOOKUP_IDX("wb_gpio_d1500", 1, NULL, 1, + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), + }, +}; + +static int __init wb_i2c_gpio_device_init(void) +{ + int err; + + WB_I2C_GPIO_DEVICE_VERBOSE("wb_i2c_gpio_device_init enter!\n"); + wb_i2c_gpio_table.table[0].chip_hwnum = gpio_sda; + wb_i2c_gpio_table.table[1].chip_hwnum = gpio_scl; + i2c_pdata.udelay = gpio_udelay; + gpiod_add_lookup_table(&wb_i2c_gpio_table); + + err = platform_device_register(&wb_i2c_gpio_device); + if (err < 0) { + printk(KERN_ERR "register i2c gpio device fail(%d). \n", err); + gpiod_remove_lookup_table(&wb_i2c_gpio_table); + return -1; + } + return 0; +} + +static void __exit wb_i2c_gpio_device_exit(void) +{ + WB_I2C_GPIO_DEVICE_VERBOSE("wb_i2c_gpio_device_exit enter!\n"); + platform_device_unregister(&wb_i2c_gpio_device); + gpiod_remove_lookup_table(&wb_i2c_gpio_table); +} + +module_init(wb_i2c_gpio_device_init); +module_exit(wb_i2c_gpio_device_exit); +MODULE_DESCRIPTION("I2C GPIO Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_i801.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_i801.c new file mode 100644 index 000000000000..a733c115487e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_i801.c @@ -0,0 +1,2114 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + Copyright (c) 1998 - 2002 Frodo Looijaard , + Philip Edelbrock , and Mark D. Studebaker + + Copyright (C) 2007 - 2014 Jean Delvare + Copyright (C) 2010 Intel Corporation, + David Woodhouse + +*/ + +/* + * Supports the following Intel I/O Controller Hubs (ICH): + * + * I/O Block I2C + * region SMBus Block proc. block + * Chip name PCI ID size PEC buffer call read + * --------------------------------------------------------------------------- + * 82801AA (ICH) 0x2413 16 no no no no + * 82801AB (ICH0) 0x2423 16 no no no no + * 82801BA (ICH2) 0x2443 16 no no no no + * 82801CA (ICH3) 0x2483 32 soft no no no + * 82801DB (ICH4) 0x24c3 32 hard yes no no + * 82801E (ICH5) 0x24d3 32 hard yes yes yes + * 6300ESB 0x25a4 32 hard yes yes yes + * 82801F (ICH6) 0x266a 32 hard yes yes yes + * 6310ESB/6320ESB 0x269b 32 hard yes yes yes + * 82801G (ICH7) 0x27da 32 hard yes yes yes + * 82801H (ICH8) 0x283e 32 hard yes yes yes + * 82801I (ICH9) 0x2930 32 hard yes yes yes + * EP80579 (Tolapai) 0x5032 32 hard yes yes yes + * ICH10 0x3a30 32 hard yes yes yes + * ICH10 0x3a60 32 hard yes yes yes + * 5/3400 Series (PCH) 0x3b30 32 hard yes yes yes + * 6 Series (PCH) 0x1c22 32 hard yes yes yes + * Patsburg (PCH) 0x1d22 32 hard yes yes yes + * Patsburg (PCH) IDF 0x1d70 32 hard yes yes yes + * Patsburg (PCH) IDF 0x1d71 32 hard yes yes yes + * Patsburg (PCH) IDF 0x1d72 32 hard yes yes yes + * DH89xxCC (PCH) 0x2330 32 hard yes yes yes + * Panther Point (PCH) 0x1e22 32 hard yes yes yes + * Lynx Point (PCH) 0x8c22 32 hard yes yes yes + * Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes + * Avoton (SOC) 0x1f3c 32 hard yes yes yes + * Wellsburg (PCH) 0x8d22 32 hard yes yes yes + * Wellsburg (PCH) MS 0x8d7d 32 hard yes yes yes + * Wellsburg (PCH) MS 0x8d7e 32 hard yes yes yes + * Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes + * Coleto Creek (PCH) 0x23b0 32 hard yes yes yes + * Wildcat Point (PCH) 0x8ca2 32 hard yes yes yes + * Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes + * BayTrail (SOC) 0x0f12 32 hard yes yes yes + * Braswell (SOC) 0x2292 32 hard yes yes yes + * Sunrise Point-H (PCH) 0xa123 32 hard yes yes yes + * Sunrise Point-LP (PCH) 0x9d23 32 hard yes yes yes + * DNV (SOC) 0x19df 32 hard yes yes yes + * Emmitsburg (PCH) 0x1bc9 32 hard yes yes yes + * Broxton (SOC) 0x5ad4 32 hard yes yes yes + * Lewisburg (PCH) 0xa1a3 32 hard yes yes yes + * Lewisburg Supersku (PCH) 0xa223 32 hard yes yes yes + * Kaby Lake PCH-H (PCH) 0xa2a3 32 hard yes yes yes + * Gemini Lake (SOC) 0x31d4 32 hard yes yes yes + * Cannon Lake-H (PCH) 0xa323 32 hard yes yes yes + * Cannon Lake-LP (PCH) 0x9da3 32 hard yes yes yes + * Cedar Fork (PCH) 0x18df 32 hard yes yes yes + * Ice Lake-LP (PCH) 0x34a3 32 hard yes yes yes + * Comet Lake (PCH) 0x02a3 32 hard yes yes yes + * Comet Lake-H (PCH) 0x06a3 32 hard yes yes yes + * Elkhart Lake (PCH) 0x4b23 32 hard yes yes yes + * Tiger Lake-LP (PCH) 0xa0a3 32 hard yes yes yes + * Tiger Lake-H (PCH) 0x43a3 32 hard yes yes yes + * Jasper Lake (SOC) 0x4da3 32 hard yes yes yes + * Comet Lake-V (PCH) 0xa3a3 32 hard yes yes yes + * Alder Lake-S (PCH) 0x7aa3 32 hard yes yes yes + * + * Features supported by this driver: + * Software PEC no + * Hardware PEC yes + * Block buffer yes + * Block process call transaction yes + * I2C block read transaction yes (doesn't use the block buffer) + * Slave mode no + * SMBus Host Notify yes + * Interrupt processing yes + * + * See the file Documentation/i2c/busses/i2c-i801.rst for details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI +#include +#include +#endif + +#define mem_clear(data, size) memset((data), 0, (size)) + +/* I801 SMBus address offsets */ +#define SMBHSTSTS(p) (0 + (p)->smba) +#define SMBHSTCNT(p) (2 + (p)->smba) +#define SMBHSTCMD(p) (3 + (p)->smba) +#define SMBHSTADD(p) (4 + (p)->smba) +#define SMBHSTDAT0(p) (5 + (p)->smba) +#define SMBHSTDAT1(p) (6 + (p)->smba) +#define SMBBLKDAT(p) (7 + (p)->smba) +#define SMBPEC(p) (8 + (p)->smba) /* ICH3 and later */ +#define SMBAUXSTS(p) (12 + (p)->smba) /* ICH4 and later */ +#define SMBAUXCTL(p) (13 + (p)->smba) /* ICH4 and later */ +#define SMBSLVSTS(p) (16 + (p)->smba) /* ICH3 and later */ +#define SMBSLVCMD(p) (17 + (p)->smba) /* ICH3 and later */ +#define SMBNTFDADD(p) (20 + (p)->smba) /* ICH3 and later */ +#define SMBPINCTL(p) (15 + (p)->smba) /* SMBus Pin Control Register */ + +/* PCI Address Constants */ +#define SMBBAR 4 +#define SMBPCICTL 0x004 +#define SMBPCISTS 0x006 +#define SMBHSTCFG 0x040 +#define TCOBASE 0x050 +#define TCOCTL 0x054 + +#define SBREG_BAR 0x10 +#define SBREG_SMBCTRL 0xc6000c +#define SBREG_SMBCTRL_DNV 0xcf000c + +/* Host status bits for SMBPCISTS */ +#define SMBPCISTS_INTS BIT(3) + +/* Control bits for SMBPCICTL */ +#define SMBPCICTL_INTDIS BIT(10) + +/* Host configuration bits for SMBHSTCFG */ +#define SMBHSTCFG_HST_EN BIT(0) +#define SMBHSTCFG_SMB_SMI_EN BIT(1) +#define SMBHSTCFG_I2C_EN BIT(2) +#define SMBHSTCFG_SSRESET BIT(3) +#define SSRESET_SLEEP_TIME 1 /* 1us */ +#define SSRESET_RETRY_TIME (1000 / SSRESET_SLEEP_TIME) + +/* Pin status for SMBPINCTL */ +#define SMBPINCTL_CLK_STS 1 /* bit0 SMBCLK_CUR_STS*/ +#define SMBPINCTL_SDA_STS 2 /* bit1 SMBDATA_CUR_STS*/ +#define SMBPINCTL_CLK_CTL 4 /* bit2 SMBCLK_CTL */ + +#define SMBHSTCFG_SPD_WD BIT(4) + +/* TCO configuration bits for TCOCTL */ +#define TCOCTL_EN BIT(8) + +/* Auxiliary status register bits, ICH4+ only */ +#define SMBAUXSTS_CRCE BIT(0) +#define SMBAUXSTS_STCO BIT(1) + +/* Auxiliary control register bits, ICH4+ only */ +#define SMBAUXCTL_CRC BIT(0) +#define SMBAUXCTL_E32B BIT(1) + +/* Other settings */ +#define MAX_RETRIES 400 + +/* I801 command constants */ +#define I801_QUICK 0x00 +#define I801_BYTE 0x04 +#define I801_BYTE_DATA 0x08 +#define I801_WORD_DATA 0x0C +#define I801_PROC_CALL 0x10 /* unimplemented */ +#define I801_BLOCK_DATA 0x14 +#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */ +#define I801_BLOCK_PROC_CALL 0x1C + +/* I801 Host Control register bits */ +#define SMBHSTCNT_INTREN BIT(0) +#define SMBHSTCNT_KILL BIT(1) +#define SMBHSTCNT_LAST_BYTE BIT(5) +#define SMBHSTCNT_START BIT(6) +#define SMBHSTCNT_PEC_EN BIT(7) /* ICH3 and later */ + +/* I801 Hosts Status register bits */ +#define SMBHSTSTS_BYTE_DONE BIT(7) +#define SMBHSTSTS_INUSE_STS BIT(6) +#define SMBHSTSTS_SMBALERT_STS BIT(5) +#define SMBHSTSTS_FAILED BIT(4) +#define SMBHSTSTS_BUS_ERR BIT(3) +#define SMBHSTSTS_DEV_ERR BIT(2) +#define SMBHSTSTS_INTR BIT(1) +#define SMBHSTSTS_HOST_BUSY BIT(0) + +/* Host Notify Status register bits */ +#define SMBSLVSTS_HST_NTFY_STS BIT(0) + +/* Host Notify Command register bits */ +#define SMBSLVCMD_HST_NTFY_INTREN BIT(0) + +#define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \ + SMBHSTSTS_DEV_ERR) + +#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \ + STATUS_ERROR_FLAGS) + +/* Older devices have their ID defined in */ +#define PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS 0x02a3 +#define PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS 0x06a3 +#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 +#define PCI_DEVICE_ID_INTEL_CDF_SMBUS 0x18df +#define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df +#define PCI_DEVICE_ID_INTEL_EBG_SMBUS 0x1bc9 +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 +/* Patsburg also has three 'Integrated Device Function' SMBus controllers */ +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70 +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22 +#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c +#define PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS 0x2292 +#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 +#define PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS 0x23b0 +#define PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS 0x31d4 +#define PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS 0x34a3 +#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 +#define PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS 0x43a3 +#define PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS 0x4b23 +#define PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS 0x4da3 +#define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4 +#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 +#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS 0x8d22 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0 0x8d7d +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1 0x8d7e +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 +#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS 0x9ca2 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS 0x9d23 +#define PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS 0x9da3 +#define PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS 0xa0a3 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS 0xa123 +#define PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS 0xa1a3 +#define PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS 0xa223 +#define PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS 0xa2a3 +#define PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS 0xa323 +#define PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS 0xa3a3 + +struct i801_mux_config { + char *gpio_chip; + unsigned values[3]; + int n_values; + unsigned classes[3]; + unsigned gpios[2]; /* Relative to gpio_chip->base */ + int n_gpios; +}; + +struct i801_priv { + struct i2c_adapter adapter; + unsigned long smba; + unsigned char original_hstcfg; + unsigned char original_slvcmd; + struct pci_dev *pci_dev; + unsigned int features; + + /* isr processing */ + wait_queue_head_t waitq; + u8 status; + + /* Command state used by isr for byte-by-byte block transactions */ + u8 cmd; + bool is_read; + int count; + int len; + u8 *data; + +#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI + const struct i801_mux_config *mux_drvdata; + struct platform_device *mux_pdev; + struct gpiod_lookup_table *lookup; +#endif + struct platform_device *tco_pdev; + + /* + * If set to true the host controller registers are reserved for + * ACPI AML use. Protected by acpi_lock. + */ + bool acpi_reserved; + struct mutex acpi_lock; +}; + +#define FEATURE_SMBUS_PEC BIT(0) +#define FEATURE_BLOCK_BUFFER BIT(1) +#define FEATURE_BLOCK_PROC BIT(2) +#define FEATURE_I2C_BLOCK_READ BIT(3) +#define FEATURE_IRQ BIT(4) +#define FEATURE_HOST_NOTIFY BIT(5) +/* Not really a feature, but it's convenient to handle it as such */ +#define FEATURE_IDF BIT(15) +#define FEATURE_TCO_SPT BIT(16) +#define FEATURE_TCO_CNL BIT(17) + +static const char *i801_feature_names[] = { + "SMBus PEC", + "Block buffer", + "Block process call", + "I2C block read", + "Interrupt", + "SMBus Host Notify", +}; + +static unsigned int disable_features; +module_param(disable_features, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n" + "\t\t 0x01 disable SMBus PEC\n" + "\t\t 0x02 disable the block buffer\n" + "\t\t 0x08 disable the I2C block read functionality\n" + "\t\t 0x10 don't use interrupts\n" + "\t\t 0x20 disable SMBus Host Notify "); + +static void i801_setscl(struct i801_priv *priv, unsigned int level) +{ + int pin_status; + pin_status = inb_p(SMBPINCTL(priv)); + if (level == 0) { + pin_status &= (~SMBPINCTL_CLK_CTL); + } + else { + pin_status |= SMBPINCTL_CLK_CTL; + } + outb_p(pin_status, SMBPINCTL(priv)); + return; +} + +static void i801_i2c_unblock(struct i801_priv *priv) +{ + int i; + for (i = 0; i < 10; i++) { + i801_setscl(priv, 0); + udelay(5); + i801_setscl(priv, 1); + udelay(5); + } + return; +} + +static int i801_check_i2c_unblock(struct i801_priv *priv) +{ + int pin_status; + + pin_status = inb_p(SMBPINCTL(priv)); + if ( (!(pin_status & SMBPINCTL_SDA_STS) ) && (pin_status & SMBPINCTL_CLK_STS) ) { + dev_dbg(&priv->pci_dev->dev, "SDA is low, send 9 clock to device!\n"); + i801_i2c_unblock(priv); + } + return 0; +} + +static void i801_do_reset(struct i801_priv *priv) +{ + unsigned char tmp; + unsigned int retry_count = 0; + + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &tmp); + tmp |= SMBHSTCFG_SSRESET; + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, tmp); + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &tmp); + + while( ((tmp & SMBHSTCFG_SSRESET) != 0) && (retry_count < SSRESET_RETRY_TIME)) { + usleep_range(SSRESET_SLEEP_TIME, SSRESET_SLEEP_TIME + 1); + retry_count++; + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &tmp); + } + + return ; +} + +static int i801_check_i2c_scl(struct i801_priv *priv) +{ + int pin_status; + + pin_status = inb_p(SMBPINCTL(priv)); + if ( (pin_status & SMBPINCTL_SDA_STS) && (pin_status & SMBPINCTL_CLK_STS) ) { + return 0; + } + + dev_dbg(&priv->pci_dev->dev, "SDA or SCL is low, begin to reset SMBus adapter, pin_status: 0x%x\n",pin_status); + i801_do_reset(priv); + pin_status = inb_p(SMBPINCTL(priv)); + if ( (pin_status & SMBPINCTL_SDA_STS) && (pin_status & SMBPINCTL_CLK_STS) ) { + return 0; + } + dev_warn(&priv->pci_dev->dev, "SDA or SCL is low.pin_status:0x%x\n",pin_status); + return -1; +} + +/* Make sure the SMBus host is ready to start transmitting. + Return 0 if it is, -EBUSY if it is not. */ +static int i801_check_pre(struct i801_priv *priv) +{ + int status; + + i801_check_i2c_unblock(priv); + + if (i801_check_i2c_scl(priv)) { + return -EIO; + } + + status = inb_p(SMBHSTSTS(priv)); + if (status & SMBHSTSTS_HOST_BUSY) { + dev_dbg(&priv->pci_dev->dev, "SMBus is busy, begin to reset SMBus adapter!\n"); + + i801_do_reset(priv); + + status = inb_p(SMBHSTSTS(priv)); + if (status & SMBHSTSTS_HOST_BUSY) { + dev_err(&priv->pci_dev->dev, "SMBus is busy, can't use it!\n"); + return -EBUSY; + } + } + + status &= STATUS_FLAGS; + if (status) { + dev_dbg(&priv->pci_dev->dev, "Clearing status flags (%02x)\n", + status); + outb_p(status, SMBHSTSTS(priv)); + status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS; + if (status) { + dev_err(&priv->pci_dev->dev, + "Failed clearing status flags (%02x)\n", + status); + return -EBUSY; + } + } + + /* + * Clear CRC status if needed. + * During normal operation, i801_check_post() takes care + * of it after every operation. We do it here only in case + * the hardware was already in this state when the driver + * started. + */ + if (priv->features & FEATURE_SMBUS_PEC) { + status = inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE; + if (status) { + dev_dbg(&priv->pci_dev->dev, + "Clearing aux status flags (%02x)\n", status); + outb_p(status, SMBAUXSTS(priv)); + status = inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE; + if (status) { + dev_err(&priv->pci_dev->dev, + "Failed clearing aux status flags (%02x)\n", + status); + return -EBUSY; + } + } + } + + return 0; +} + +/* + * Convert the status register to an error code, and clear it. + * Note that status only contains the bits we want to clear, not the + * actual register value. + */ +static int i801_check_post(struct i801_priv *priv, int status) +{ + int result = 0; + + /* + * If the SMBus is still busy, we give up + * Note: This timeout condition only happens when using polling + * transactions. For interrupt operation, NAK/timeout is indicated by + * DEV_ERR. + */ + if (unlikely(status < 0)) { + dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); + /* try to stop the current command */ + dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n"); + outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv)); + usleep_range(1000, 2000); + outb_p(0, SMBHSTCNT(priv)); + + /* Check if it worked */ + status = inb_p(SMBHSTSTS(priv)); + if ((status & SMBHSTSTS_HOST_BUSY) || + !(status & SMBHSTSTS_FAILED)) + dev_err(&priv->pci_dev->dev, + "Failed terminating the transaction\n"); + outb_p(STATUS_FLAGS, SMBHSTSTS(priv)); + return -ETIMEDOUT; + } + + if (status & SMBHSTSTS_FAILED) { + result = -EIO; + dev_err(&priv->pci_dev->dev, "Transaction failed\n"); + } + if (status & SMBHSTSTS_DEV_ERR) { + /* + * This may be a PEC error, check and clear it. + * + * AUXSTS is handled differently from HSTSTS. + * For HSTSTS, i801_isr() or i801_wait_intr() + * has already cleared the error bits in hardware, + * and we are passed a copy of the original value + * in "status". + * For AUXSTS, the hardware register is left + * for us to handle here. + * This is asymmetric, slightly iffy, but safe, + * since all this code is serialized and the CRCE + * bit is harmless as long as it's cleared before + * the next operation. + */ + if ((priv->features & FEATURE_SMBUS_PEC) && + (inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE)) { + outb_p(SMBAUXSTS_CRCE, SMBAUXSTS(priv)); + result = -EBADMSG; + dev_dbg(&priv->pci_dev->dev, "PEC error\n"); + } else { + result = -ENXIO; + dev_dbg(&priv->pci_dev->dev, "No response\n"); + } + } + if (status & SMBHSTSTS_BUS_ERR) { + result = -EAGAIN; + dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n"); + } + + /* Clear status flags except BYTE_DONE, to be cleared by caller */ + outb_p(status, SMBHSTSTS(priv)); + + return result; +} + +/* Wait for BUSY being cleared and either INTR or an error flag being set */ +static int i801_wait_intr(struct i801_priv *priv) +{ + int timeout = 0; + int status; + + /* We will always wait for a fraction of a second! */ + do { + usleep_range(250, 500); + status = inb_p(SMBHSTSTS(priv)); + } while (((status & SMBHSTSTS_HOST_BUSY) || + !(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) && + (timeout++ < MAX_RETRIES)); + + if (timeout > MAX_RETRIES) { + dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n"); + return -ETIMEDOUT; + } + return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR); +} + +/* Wait for either BYTE_DONE or an error flag being set */ +static int i801_wait_byte_done(struct i801_priv *priv) +{ + int timeout = 0; + int status; + + /* We will always wait for a fraction of a second! */ + do { + usleep_range(250, 500); + status = inb_p(SMBHSTSTS(priv)); + } while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) && + (timeout++ < MAX_RETRIES)); + + if (timeout > MAX_RETRIES) { + dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n"); + return -ETIMEDOUT; + } + return status & STATUS_ERROR_FLAGS; +} + +static int i801_transaction(struct i801_priv *priv, int xact) +{ + int status; + int result; + const struct i2c_adapter *adap = &priv->adapter; + + result = i801_check_pre(priv); + if (result < 0) + return result; + + if (priv->features & FEATURE_IRQ) { + outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START, + SMBHSTCNT(priv)); + result = wait_event_timeout(priv->waitq, + (status = priv->status), + adap->timeout); + if (!result) { + status = -ETIMEDOUT; + dev_warn(&priv->pci_dev->dev, + "Timeout waiting for interrupt!\n"); + } + priv->status = 0; + return i801_check_post(priv, status); + } + + /* the current contents of SMBHSTCNT can be overwritten, since PEC, + * SMBSCMD are passed in xact */ + outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv)); + + status = i801_wait_intr(priv); + return i801_check_post(priv, status); +} + +static int i801_block_transaction_by_block(struct i801_priv *priv, + union i2c_smbus_data *data, + char read_write, int command, + int hwpec) +{ + int i, len; + int status; + int xact = hwpec ? SMBHSTCNT_PEC_EN : 0; + + switch (command) { + case I2C_SMBUS_BLOCK_PROC_CALL: + xact |= I801_BLOCK_PROC_CALL; + break; + case I2C_SMBUS_BLOCK_DATA: + xact |= I801_BLOCK_DATA; + break; + default: + return -EOPNOTSUPP; + } + + inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */ + + /* Use 32-byte buffer to process this transaction */ + if (read_write == I2C_SMBUS_WRITE) { + len = data->block[0]; + outb_p(len, SMBHSTDAT0(priv)); + for (i = 0; i < len; i++) + outb_p(data->block[i+1], SMBBLKDAT(priv)); + } + + status = i801_transaction(priv, xact); + if (status) + return status; + + if (read_write == I2C_SMBUS_READ || + command == I2C_SMBUS_BLOCK_PROC_CALL) { + len = inb_p(SMBHSTDAT0(priv)); + if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) + return -EPROTO; + + data->block[0] = len; + for (i = 0; i < len; i++) + data->block[i + 1] = inb_p(SMBBLKDAT(priv)); + } + return 0; +} + +static void i801_isr_byte_done(struct i801_priv *priv) +{ + if (priv->is_read) { + /* For SMBus block reads, length is received with first byte */ + if (((priv->cmd & 0x1c) == I801_BLOCK_DATA) && + (priv->count == 0)) { + priv->len = inb_p(SMBHSTDAT0(priv)); + if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX) { + dev_err(&priv->pci_dev->dev, + "Illegal SMBus block read size %d\n", + priv->len); + /* FIXME: Recover */ + priv->len = I2C_SMBUS_BLOCK_MAX; + } else { + dev_dbg(&priv->pci_dev->dev, + "SMBus block read size is %d\n", + priv->len); + } + priv->data[-1] = priv->len; + } + + /* Read next byte */ + if (priv->count < priv->len) + priv->data[priv->count++] = inb(SMBBLKDAT(priv)); + else + dev_dbg(&priv->pci_dev->dev, + "Discarding extra byte on block read\n"); + + /* Set LAST_BYTE for last byte of read transaction */ + if (priv->count == priv->len - 1) + outb_p(priv->cmd | SMBHSTCNT_LAST_BYTE, + SMBHSTCNT(priv)); + } else if (priv->count < priv->len - 1) { + /* Write next byte, except for IRQ after last byte */ + outb_p(priv->data[++priv->count], SMBBLKDAT(priv)); + } + + /* Clear BYTE_DONE to continue with next byte */ + outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv)); +} + +static irqreturn_t i801_host_notify_isr(struct i801_priv *priv) +{ + unsigned short addr; + + addr = inb_p(SMBNTFDADD(priv)) >> 1; + + /* + * With the tested platforms, reading SMBNTFDDAT (22 + (p)->smba) + * always returns 0. Our current implementation doesn't provide + * data, so we just ignore it. + */ + i2c_handle_smbus_host_notify(&priv->adapter, addr); + + /* clear Host Notify bit and return */ + outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv)); + return IRQ_HANDLED; +} + +/* + * There are three kinds of interrupts: + * + * 1) i801 signals transaction completion with one of these interrupts: + * INTR - Success + * DEV_ERR - Invalid command, NAK or communication timeout + * BUS_ERR - SMI# transaction collision + * FAILED - transaction was canceled due to a KILL request + * When any of these occur, update ->status and wake up the waitq. + * ->status must be cleared before kicking off the next transaction. + * + * 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt + * occurs for each byte of a byte-by-byte to prepare the next byte. + * + * 3) Host Notify interrupts + */ +static irqreturn_t i801_isr(int irq, void *dev_id) +{ + struct i801_priv *priv = dev_id; + u16 pcists; + u8 status; + + /* Confirm this is our interrupt */ + pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); + if (!(pcists & SMBPCISTS_INTS)) + return IRQ_NONE; + + if (priv->features & FEATURE_HOST_NOTIFY) { + status = inb_p(SMBSLVSTS(priv)); + if (status & SMBSLVSTS_HST_NTFY_STS) + return i801_host_notify_isr(priv); + } + + status = inb_p(SMBHSTSTS(priv)); + if (status & SMBHSTSTS_BYTE_DONE) + i801_isr_byte_done(priv); + + /* + * Clear irq sources and report transaction result. + * ->status must be cleared before the next transaction is started. + */ + status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; + if (status) { + outb_p(status, SMBHSTSTS(priv)); + priv->status = status; + wake_up(&priv->waitq); + } + + return IRQ_HANDLED; +} + +/* + * For "byte-by-byte" block transactions: + * I2C write uses cmd=I801_BLOCK_DATA, I2C_EN=1 + * I2C read uses cmd=I801_I2C_BLOCK_DATA + */ +static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, + union i2c_smbus_data *data, + char read_write, int command, + int hwpec) +{ + int i, len; + int smbcmd; + int status; + int result; + const struct i2c_adapter *adap = &priv->adapter; + + if (command == I2C_SMBUS_BLOCK_PROC_CALL) + return -EOPNOTSUPP; + + result = i801_check_pre(priv); + if (result < 0) + return result; + + len = data->block[0]; + + if (read_write == I2C_SMBUS_WRITE) { + outb_p(len, SMBHSTDAT0(priv)); + outb_p(data->block[1], SMBBLKDAT(priv)); + } + + if (command == I2C_SMBUS_I2C_BLOCK_DATA && + read_write == I2C_SMBUS_READ) + smbcmd = I801_I2C_BLOCK_DATA; + else + smbcmd = I801_BLOCK_DATA; + + if (priv->features & FEATURE_IRQ) { + priv->is_read = (read_write == I2C_SMBUS_READ); + if (len == 1 && priv->is_read) + smbcmd |= SMBHSTCNT_LAST_BYTE; + priv->cmd = smbcmd | SMBHSTCNT_INTREN; + priv->len = len; + priv->count = 0; + priv->data = &data->block[1]; + + outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv)); + result = wait_event_timeout(priv->waitq, + (status = priv->status), + adap->timeout); + if (!result) { + status = -ETIMEDOUT; + dev_warn(&priv->pci_dev->dev, + "Timeout waiting for interrupt!\n"); + } + priv->status = 0; + return i801_check_post(priv, status); + } + + for (i = 1; i <= len; i++) { + if (i == len && read_write == I2C_SMBUS_READ) + smbcmd |= SMBHSTCNT_LAST_BYTE; + outb_p(smbcmd, SMBHSTCNT(priv)); + + if (i == 1) + outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START, + SMBHSTCNT(priv)); + + status = i801_wait_byte_done(priv); + if (status) + goto exit; + + if (i == 1 && read_write == I2C_SMBUS_READ + && command != I2C_SMBUS_I2C_BLOCK_DATA) { + len = inb_p(SMBHSTDAT0(priv)); + if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) { + dev_err(&priv->pci_dev->dev, + "Illegal SMBus block read size %d\n", + len); + /* Recover */ + while (inb_p(SMBHSTSTS(priv)) & + SMBHSTSTS_HOST_BUSY) + outb_p(SMBHSTSTS_BYTE_DONE, + SMBHSTSTS(priv)); + outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv)); + return -EPROTO; + } + data->block[0] = len; + } + + /* Retrieve/store value in SMBBLKDAT */ + if (read_write == I2C_SMBUS_READ) + data->block[i] = inb_p(SMBBLKDAT(priv)); + if (read_write == I2C_SMBUS_WRITE && i+1 <= len) + outb_p(data->block[i+1], SMBBLKDAT(priv)); + + /* signals SMBBLKDAT ready */ + outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv)); + } + + status = i801_wait_intr(priv); +exit: + return i801_check_post(priv, status); +} + +static int i801_set_block_buffer_mode(struct i801_priv *priv) +{ + outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv)); + if ((inb_p(SMBAUXCTL(priv)) & SMBAUXCTL_E32B) == 0) + return -EIO; + return 0; +} + +/* Block transaction function */ +static int i801_block_transaction(struct i801_priv *priv, + union i2c_smbus_data *data, char read_write, + int command, int hwpec) +{ + int result = 0; + unsigned char hostc; + + if (command == I2C_SMBUS_I2C_BLOCK_DATA) { + if (read_write == I2C_SMBUS_WRITE) { + /* set I2C_EN bit in configuration register */ + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc); + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, + hostc | SMBHSTCFG_I2C_EN); + } else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) { + dev_err(&priv->pci_dev->dev, + "I2C block read is unsupported!\n"); + return -EOPNOTSUPP; + } + } + + if (read_write == I2C_SMBUS_WRITE + || command == I2C_SMBUS_I2C_BLOCK_DATA) { + if (data->block[0] < 1) + data->block[0] = 1; + if (data->block[0] > I2C_SMBUS_BLOCK_MAX) + data->block[0] = I2C_SMBUS_BLOCK_MAX; + } else { + data->block[0] = 32; /* max for SMBus block reads */ + } + + /* Experience has shown that the block buffer can only be used for + SMBus (not I2C) block transactions, even though the datasheet + doesn't mention this limitation. */ + if ((priv->features & FEATURE_BLOCK_BUFFER) + && command != I2C_SMBUS_I2C_BLOCK_DATA + && i801_set_block_buffer_mode(priv) == 0) + result = i801_block_transaction_by_block(priv, data, + read_write, + command, hwpec); + else + result = i801_block_transaction_byte_by_byte(priv, data, + read_write, + command, hwpec); + + if (command == I2C_SMBUS_I2C_BLOCK_DATA + && read_write == I2C_SMBUS_WRITE) { + /* restore saved configuration register value */ + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc); + } + return result; +} + +/* Return negative errno on error. */ +static s32 i801_access(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, u8 command, + int size, union i2c_smbus_data *data) +{ + int hwpec; + int block = 0; + int ret = 0, xact = 0; + struct i801_priv *priv = i2c_get_adapdata(adap); + + mutex_lock(&priv->acpi_lock); + if (priv->acpi_reserved) { + mutex_unlock(&priv->acpi_lock); + return -EBUSY; + } + + pm_runtime_get_sync(&priv->pci_dev->dev); + + hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC) + && size != I2C_SMBUS_QUICK + && size != I2C_SMBUS_I2C_BLOCK_DATA; + + switch (size) { + case I2C_SMBUS_QUICK: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + xact = I801_QUICK; + break; + case I2C_SMBUS_BYTE: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + if (read_write == I2C_SMBUS_WRITE) + outb_p(command, SMBHSTCMD(priv)); + xact = I801_BYTE; + break; + case I2C_SMBUS_BYTE_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + outb_p(command, SMBHSTCMD(priv)); + if (read_write == I2C_SMBUS_WRITE) + outb_p(data->byte, SMBHSTDAT0(priv)); + xact = I801_BYTE_DATA; + break; + case I2C_SMBUS_WORD_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + outb_p(command, SMBHSTCMD(priv)); + if (read_write == I2C_SMBUS_WRITE) { + outb_p(data->word & 0xff, SMBHSTDAT0(priv)); + outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv)); + } + xact = I801_WORD_DATA; + break; + case I2C_SMBUS_BLOCK_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD(priv)); + outb_p(command, SMBHSTCMD(priv)); + block = 1; + break; + case I2C_SMBUS_I2C_BLOCK_DATA: + /* + * NB: page 240 of ICH5 datasheet shows that the R/#W + * bit should be cleared here, even when reading. + * However if SPD Write Disable is set (Lynx Point and later), + * the read will fail if we don't set the R/#W bit. + */ + outb_p(((addr & 0x7f) << 1) | + ((priv->original_hstcfg & SMBHSTCFG_SPD_WD) ? + (read_write & 0x01) : 0), + SMBHSTADD(priv)); + if (read_write == I2C_SMBUS_READ) { + /* NB: page 240 of ICH5 datasheet also shows + * that DATA1 is the cmd field when reading */ + outb_p(command, SMBHSTDAT1(priv)); + } else + outb_p(command, SMBHSTCMD(priv)); + block = 1; + break; + case I2C_SMBUS_BLOCK_PROC_CALL: + /* + * Bit 0 of the slave address register always indicate a write + * command. + */ + outb_p((addr & 0x7f) << 1, SMBHSTADD(priv)); + outb_p(command, SMBHSTCMD(priv)); + block = 1; + break; + default: + dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n", + size); + ret = -EOPNOTSUPP; + goto out; + } + + if (hwpec) /* enable/disable hardware PEC */ + outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv)); + else + outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC), + SMBAUXCTL(priv)); + + if (block) + ret = i801_block_transaction(priv, data, read_write, size, + hwpec); + else + ret = i801_transaction(priv, xact); + + /* Some BIOSes don't like it when PEC is enabled at reboot or resume + time, so we forcibly disable it after every transaction. Turn off + E32B for the same reason. */ + if (hwpec || block) + outb_p(inb_p(SMBAUXCTL(priv)) & + ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); + + if (block) + goto out; + if (ret) + goto out; + if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK)) + goto out; + + switch (xact & 0x7f) { + case I801_BYTE: /* Result put in SMBHSTDAT0 */ + case I801_BYTE_DATA: + data->byte = inb_p(SMBHSTDAT0(priv)); + break; + case I801_WORD_DATA: + data->word = inb_p(SMBHSTDAT0(priv)) + + (inb_p(SMBHSTDAT1(priv)) << 8); + break; + } + +out: + pm_runtime_mark_last_busy(&priv->pci_dev->dev); + pm_runtime_put_autosuspend(&priv->pci_dev->dev); + mutex_unlock(&priv->acpi_lock); + return ret; +} + +static u32 i801_func(struct i2c_adapter *adapter) +{ + struct i801_priv *priv = i2c_get_adapdata(adapter); + + 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_WRITE_I2C_BLOCK | + ((priv->features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) | + ((priv->features & FEATURE_BLOCK_PROC) ? + I2C_FUNC_SMBUS_BLOCK_PROC_CALL : 0) | + ((priv->features & FEATURE_I2C_BLOCK_READ) ? + I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0) | + ((priv->features & FEATURE_HOST_NOTIFY) ? + I2C_FUNC_SMBUS_HOST_NOTIFY : 0); +} + +static void i801_enable_host_notify(struct i2c_adapter *adapter) +{ + struct i801_priv *priv = i2c_get_adapdata(adapter); + + if (!(priv->features & FEATURE_HOST_NOTIFY)) + return; + + if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd)) + outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd, + SMBSLVCMD(priv)); + + /* clear Host Notify bit to allow a new notification */ + outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv)); +} + +static void i801_disable_host_notify(struct i801_priv *priv) +{ + if (!(priv->features & FEATURE_HOST_NOTIFY)) + return; + + outb_p(priv->original_slvcmd, SMBSLVCMD(priv)); +} + +static const struct i2c_algorithm smbus_algorithm = { + .smbus_xfer = i801_access, + .functionality = i801_func, +}; + +static const struct pci_device_id i801_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EP80579_1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CDF_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EBG_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROXTON_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS) }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, i801_ids); + +#if defined CONFIG_X86 && defined CONFIG_DMI +static unsigned char apanel_addr; + +/* Scan the system ROM for the signature "FJKEYINF" */ +static __init const void __iomem *bios_signature(const void __iomem *bios) +{ + ssize_t offset; + const unsigned char signature[] = "FJKEYINF"; + + for (offset = 0; offset < 0x10000; offset += 0x10) { + if (check_signature(bios + offset, signature, + sizeof(signature)-1)) + return bios + offset; + } + return NULL; +} + +static void __init input_apanel_init(void) +{ + void __iomem *bios; + const void __iomem *p; + + bios = ioremap(0xF0000, 0x10000); /* Can't fail */ + p = bios_signature(bios); + if (p) { + /* just use the first address */ + apanel_addr = readb(p + 8 + 3) >> 1; + } + iounmap(bios); +} + +struct dmi_onboard_device_info { + const char *name; + u8 type; + unsigned short i2c_addr; + const char *i2c_type; +}; + +static const struct dmi_onboard_device_info dmi_devices[] = { + { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" }, + { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" }, + { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" }, +}; + +static void dmi_check_onboard_device(u8 type, const char *name, + struct i2c_adapter *adap) +{ + int i; + struct i2c_board_info info; + + for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) { + /* & ~0x80, ignore enabled/disabled bit */ + if ((type & ~0x80) != dmi_devices[i].type) + continue; + if (strcasecmp(name, dmi_devices[i].name)) + continue; + + mem_clear(&info, sizeof(struct i2c_board_info)); + info.addr = dmi_devices[i].i2c_addr; + strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE); + i2c_new_client_device(adap, &info); + break; + } +} + +/* We use our own function to check for onboard devices instead of + dmi_find_device() as some buggy BIOS's have the devices we are interested + in marked as disabled */ +static void dmi_check_onboard_devices(const struct dmi_header *dm, void *adap) +{ + int i, count; + + if (dm->type != 10) + return; + + count = (dm->length - sizeof(struct dmi_header)) / 2; + for (i = 0; i < count; i++) { + const u8 *d = (char *)(dm + 1) + (i * 2); + const char *name = ((char *) dm) + dm->length; + u8 type = d[0]; + u8 s = d[1]; + + if (!s) + continue; + s--; + while (s > 0 && name[0]) { + name += strlen(name) + 1; + s--; + } + if (name[0] == 0) /* Bogus string reference */ + continue; + + dmi_check_onboard_device(type, name, adap); + } +} + +/* NOTE: Keep this list in sync with drivers/platform/x86/dell-smo8800.c */ +static const char *const acpi_smo8800_ids[] = { + "SMO8800", + "SMO8801", + "SMO8810", + "SMO8811", + "SMO8820", + "SMO8821", + "SMO8830", + "SMO8831", +}; + +static acpi_status check_acpi_smo88xx_device(acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + struct acpi_device_info *info; + acpi_status status; + char *hid; + int i; + + status = acpi_get_object_info(obj_handle, &info); + if (ACPI_FAILURE(status)) + return AE_OK; + + if (!(info->valid & ACPI_VALID_HID)) + goto smo88xx_not_found; + + hid = info->hardware_id.string; + if (!hid) + goto smo88xx_not_found; + + i = match_string(acpi_smo8800_ids, ARRAY_SIZE(acpi_smo8800_ids), hid); + if (i < 0) + goto smo88xx_not_found; + + kfree(info); + + *((bool *)return_value) = true; + return AE_CTRL_TERMINATE; + +smo88xx_not_found: + kfree(info); + return AE_OK; +} + +static bool is_dell_system_with_lis3lv02d(void) +{ + bool found; + const char *vendor; + + vendor = dmi_get_system_info(DMI_SYS_VENDOR); + if (!vendor || strcmp(vendor, "Dell Inc.")) + return false; + + /* + * Check that ACPI device SMO88xx is present and is functioning. + * Function acpi_get_devices() already filters all ACPI devices + * which are not present or are not functioning. + * ACPI device SMO88xx represents our ST microelectronics lis3lv02d + * accelerometer but unfortunately ACPI does not provide any other + * information (like I2C address). + */ + found = false; + acpi_get_devices(NULL, check_acpi_smo88xx_device, NULL, + (void **)&found); + + return found; +} + +/* + * Accelerometer's I2C address is not specified in DMI nor ACPI, + * so it is needed to define mapping table based on DMI product names. + */ +static const struct { + const char *dmi_product_name; + unsigned short i2c_addr; +} dell_lis3lv02d_devices[] = { + /* + * Dell platform team told us that these Latitude devices have + * ST microelectronics accelerometer at I2C address 0x29. + */ + { "Latitude E5250", 0x29 }, + { "Latitude E5450", 0x29 }, + { "Latitude E5550", 0x29 }, + { "Latitude E6440", 0x29 }, + { "Latitude E6440 ATG", 0x29 }, + { "Latitude E6540", 0x29 }, + /* + * Additional individual entries were added after verification. + */ + { "Latitude 5480", 0x29 }, + { "Vostro V131", 0x1d }, +}; + +static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv) +{ + struct i2c_board_info info; + const char *dmi_product_name; + int i; + + dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME); + for (i = 0; i < ARRAY_SIZE(dell_lis3lv02d_devices); ++i) { + if (strcmp(dmi_product_name, + dell_lis3lv02d_devices[i].dmi_product_name) == 0) + break; + } + + if (i == ARRAY_SIZE(dell_lis3lv02d_devices)) { + dev_warn(&priv->pci_dev->dev, + "Accelerometer lis3lv02d is present on SMBus but its" + " address is unknown, skipping registration\n"); + return; + } + + mem_clear(&info, sizeof(struct i2c_board_info)); + info.addr = dell_lis3lv02d_devices[i].i2c_addr; + strlcpy(info.type, "lis3lv02d", I2C_NAME_SIZE); + i2c_new_client_device(&priv->adapter, &info); +} + +/* Register optional slaves */ +static void i801_probe_optional_slaves(struct i801_priv *priv) +{ + /* Only register slaves on main SMBus channel */ + if (priv->features & FEATURE_IDF) + return; + + if (apanel_addr) { + struct i2c_board_info info; + + mem_clear(&info, sizeof(struct i2c_board_info)); + info.addr = apanel_addr; + strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE); + i2c_new_client_device(&priv->adapter, &info); + } + + if (dmi_name_in_vendors("FUJITSU")) + dmi_walk(dmi_check_onboard_devices, &priv->adapter); + + if (is_dell_system_with_lis3lv02d()) + register_dell_lis3lv02d_i2c_device(priv); + + /* Instantiate SPD EEPROMs unless the SMBus is multiplexed */ +#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) + if (!priv->mux_drvdata) +#endif + i2c_register_spd(&priv->adapter); +} +#else +static void __init input_apanel_init(void) {} +static void i801_probe_optional_slaves(struct i801_priv *priv) {} +#endif /* CONFIG_X86 && CONFIG_DMI */ + +#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI +static struct i801_mux_config i801_mux_config_asus_z8_d12 = { + .gpio_chip = "gpio_ich", + .values = { 0x02, 0x03 }, + .n_values = 2, + .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD }, + .gpios = { 52, 53 }, + .n_gpios = 2, +}; + +static struct i801_mux_config i801_mux_config_asus_z8_d18 = { + .gpio_chip = "gpio_ich", + .values = { 0x02, 0x03, 0x01 }, + .n_values = 3, + .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD }, + .gpios = { 52, 53 }, + .n_gpios = 2, +}; + +static const struct dmi_system_id mux_dmi_table[] = { + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"), + }, + .driver_data = &i801_mux_config_asus_z8_d18, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"), + }, + .driver_data = &i801_mux_config_asus_z8_d18, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { } +}; + +/* Setup multiplexing if needed */ +static int i801_add_mux(struct i801_priv *priv) +{ + struct device *dev = &priv->adapter.dev; + const struct i801_mux_config *mux_config; + struct i2c_mux_gpio_platform_data gpio_data; + struct gpiod_lookup_table *lookup; + int err, i; + + if (!priv->mux_drvdata) + return 0; + mux_config = priv->mux_drvdata; + + /* Prepare the platform data */ + mem_clear(&gpio_data, sizeof(struct i2c_mux_gpio_platform_data)); + gpio_data.parent = priv->adapter.nr; + gpio_data.values = mux_config->values; + gpio_data.n_values = mux_config->n_values; + gpio_data.classes = mux_config->classes; + gpio_data.idle = I2C_MUX_GPIO_NO_IDLE; + + /* Register GPIO descriptor lookup table */ + lookup = devm_kzalloc(dev, + struct_size(lookup, table, mux_config->n_gpios + 1), + GFP_KERNEL); + if (!lookup) + return -ENOMEM; + lookup->dev_id = "i2c-mux-gpio"; + for (i = 0; i < mux_config->n_gpios; i++) { + lookup->table[i] = (struct gpiod_lookup) + GPIO_LOOKUP(mux_config->gpio_chip, + mux_config->gpios[i], "mux", 0); + } + gpiod_add_lookup_table(lookup); + priv->lookup = lookup; + + /* + * Register the mux device, we use PLATFORM_DEVID_NONE here + * because since we are referring to the GPIO chip by name we are + * anyways in deep trouble if there is more than one of these + * devices, and there should likely only be one platform controller + * hub. + */ + priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio", + PLATFORM_DEVID_NONE, &gpio_data, + sizeof(struct i2c_mux_gpio_platform_data)); + if (IS_ERR(priv->mux_pdev)) { + err = PTR_ERR(priv->mux_pdev); + gpiod_remove_lookup_table(lookup); + priv->mux_pdev = NULL; + dev_err(dev, "Failed to register i2c-mux-gpio device\n"); + return err; + } + + return 0; +} + +static void i801_del_mux(struct i801_priv *priv) +{ + if (priv->mux_pdev) + platform_device_unregister(priv->mux_pdev); + if (priv->lookup) + gpiod_remove_lookup_table(priv->lookup); +} + +static unsigned int i801_get_adapter_class(struct i801_priv *priv) +{ + const struct dmi_system_id *id; + const struct i801_mux_config *mux_config; + unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + int i; + + id = dmi_first_match(mux_dmi_table); + if (id) { + /* Remove branch classes from trunk */ + mux_config = id->driver_data; + for (i = 0; i < mux_config->n_values; i++) + class &= ~mux_config->classes[i]; + + /* Remember for later */ + priv->mux_drvdata = mux_config; + } + + return class; +} +#else +static inline int i801_add_mux(struct i801_priv *priv) { return 0; } +static inline void i801_del_mux(struct i801_priv *priv) { } + +static inline unsigned int i801_get_adapter_class(struct i801_priv *priv) +{ + return I2C_CLASS_HWMON | I2C_CLASS_SPD; +} +#endif + +static const struct itco_wdt_platform_data spt_tco_platform_data = { + .name = "Intel PCH", + .version = 4, +}; + +static DEFINE_SPINLOCK(p2sb_spinlock); + +static struct platform_device * +i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, + struct resource *tco_res) +{ + struct resource *res; + unsigned int devfn; + u64 base64_addr; + u32 base_addr; + u8 hidden; + + /* + * We must access the NO_REBOOT bit over the Primary to Sideband + * bridge (P2SB). The BIOS prevents the P2SB device from being + * enumerated by the PCI subsystem, so we need to unhide/hide it + * to lookup the P2SB BAR. + */ + spin_lock(&p2sb_spinlock); + + devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 1); + + /* Unhide the P2SB device, if it is hidden */ + pci_bus_read_config_byte(pci_dev->bus, devfn, 0xe1, &hidden); + if (hidden) + pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, 0x0); + + pci_bus_read_config_dword(pci_dev->bus, devfn, SBREG_BAR, &base_addr); + base64_addr = base_addr & 0xfffffff0; + + pci_bus_read_config_dword(pci_dev->bus, devfn, SBREG_BAR + 0x4, &base_addr); + base64_addr |= (u64)base_addr << 32; + + /* Hide the P2SB device, if it was hidden before */ + if (hidden) + pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden); + spin_unlock(&p2sb_spinlock); + + res = &tco_res[1]; + if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS) + res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV; + else + res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL; + + res->end = res->start + 3; + res->flags = IORESOURCE_MEM; + + return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, + tco_res, 2, &spt_tco_platform_data, + sizeof(spt_tco_platform_data)); +} + +static const struct itco_wdt_platform_data cnl_tco_platform_data = { + .name = "Intel PCH", + .version = 6, +}; + +static struct platform_device * +i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev, + struct resource *tco_res) +{ + return platform_device_register_resndata(&pci_dev->dev, + "iTCO_wdt", -1, tco_res, 1, &cnl_tco_platform_data, + sizeof(cnl_tco_platform_data)); +} + +static void i801_add_tco(struct i801_priv *priv) +{ + struct pci_dev *pci_dev = priv->pci_dev; + struct resource tco_res[2], *res; + u32 tco_base, tco_ctl; + + /* If we have ACPI based watchdog use that instead */ + if (acpi_has_watchdog()) + return; + + if (!(priv->features & (FEATURE_TCO_SPT | FEATURE_TCO_CNL))) + return; + + pci_read_config_dword(pci_dev, TCOBASE, &tco_base); + pci_read_config_dword(pci_dev, TCOCTL, &tco_ctl); + if (!(tco_ctl & TCOCTL_EN)) + return; + + mem_clear(tco_res, sizeof(tco_res)); + /* + * Always populate the main iTCO IO resource here. The second entry + * for NO_REBOOT MMIO is filled by the SPT specific function. + */ + res = &tco_res[0]; + res->start = tco_base & ~1; + res->end = res->start + 32 - 1; + res->flags = IORESOURCE_IO; + + if (priv->features & FEATURE_TCO_CNL) + priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res); + else + priv->tco_pdev = i801_add_tco_spt(priv, pci_dev, tco_res); + + if (IS_ERR(priv->tco_pdev)) + dev_warn(&pci_dev->dev, "failed to create iTCO device\n"); +} + +#ifdef CONFIG_ACPI +static bool i801_acpi_is_smbus_ioport(const struct i801_priv *priv, + acpi_physical_address address) +{ + return address >= priv->smba && + address <= pci_resource_end(priv->pci_dev, SMBBAR); +} + +static acpi_status +i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits, + u64 *value, void *handler_context, void *region_context) +{ + struct i801_priv *priv = handler_context; + struct pci_dev *pdev = priv->pci_dev; + acpi_status status; + + /* + * Once BIOS AML code touches the OpRegion we warn and inhibit any + * further access from the driver itself. This device is now owned + * by the system firmware. + */ + mutex_lock(&priv->acpi_lock); + + if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) { + priv->acpi_reserved = true; + + dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n"); + dev_warn(&pdev->dev, "Driver SMBus register access inhibited\n"); + + /* + * BIOS is accessing the host controller so prevent it from + * suspending automatically from now on. + */ + pm_runtime_get_sync(&pdev->dev); + } + + if ((function & ACPI_IO_MASK) == ACPI_READ) + status = acpi_os_read_port(address, (u32 *)value, bits); + else + status = acpi_os_write_port(address, (u32)*value, bits); + + mutex_unlock(&priv->acpi_lock); + + return status; +} + +static int i801_acpi_probe(struct i801_priv *priv) +{ + struct acpi_device *adev; + acpi_status status; + + adev = ACPI_COMPANION(&priv->pci_dev->dev); + if (adev) { + status = acpi_install_address_space_handler(adev->handle, + ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler, + NULL, priv); + if (ACPI_SUCCESS(status)) + return 0; + } + + return acpi_check_resource_conflict(&priv->pci_dev->resource[SMBBAR]); +} + +static void i801_acpi_remove(struct i801_priv *priv) +{ + struct acpi_device *adev; + + adev = ACPI_COMPANION(&priv->pci_dev->dev); + if (!adev) + return; + + acpi_remove_address_space_handler(adev->handle, + ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler); + + mutex_lock(&priv->acpi_lock); + if (priv->acpi_reserved) + pm_runtime_put(&priv->pci_dev->dev); + mutex_unlock(&priv->acpi_lock); +} +#else +static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; } +static inline void i801_acpi_remove(struct i801_priv *priv) { } +#endif + +static unsigned char i801_setup_hstcfg(struct i801_priv *priv) +{ + unsigned char hstcfg = priv->original_hstcfg; + + hstcfg &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ + hstcfg |= SMBHSTCFG_HST_EN; + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hstcfg); + return hstcfg; +} + +static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + unsigned char temp; + int err, i; + struct i801_priv *priv; + + priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + i2c_set_adapdata(&priv->adapter, priv); + priv->adapter.owner = THIS_MODULE; + priv->adapter.class = i801_get_adapter_class(priv); + priv->adapter.algo = &smbus_algorithm; + priv->adapter.dev.parent = &dev->dev; + ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&dev->dev)); + priv->adapter.retries = 3; + mutex_init(&priv->acpi_lock); + + priv->pci_dev = dev; + switch (dev->device) { + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS: + case PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS: + case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS: + case PCI_DEVICE_ID_INTEL_DNV_SMBUS: + case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS: + case PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS: + priv->features |= FEATURE_BLOCK_PROC; + priv->features |= FEATURE_I2C_BLOCK_READ; + priv->features |= FEATURE_IRQ; + priv->features |= FEATURE_SMBUS_PEC; + priv->features |= FEATURE_BLOCK_BUFFER; + priv->features |= FEATURE_TCO_SPT; + priv->features |= FEATURE_HOST_NOTIFY; + break; + + case PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS: + case PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS: + case PCI_DEVICE_ID_INTEL_CDF_SMBUS: + case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS: + case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS: + case PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS: + case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS: + case PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS: + case PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS: + case PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS: + case PCI_DEVICE_ID_INTEL_EBG_SMBUS: + case PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS: + priv->features |= FEATURE_BLOCK_PROC; + priv->features |= FEATURE_I2C_BLOCK_READ; + priv->features |= FEATURE_IRQ; + priv->features |= FEATURE_SMBUS_PEC; + priv->features |= FEATURE_BLOCK_BUFFER; + priv->features |= FEATURE_TCO_CNL; + priv->features |= FEATURE_HOST_NOTIFY; + break; + + case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0: + case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1: + case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2: + priv->features |= FEATURE_IDF; + fallthrough; + default: + priv->features |= FEATURE_BLOCK_PROC; + priv->features |= FEATURE_I2C_BLOCK_READ; + priv->features |= FEATURE_IRQ; + fallthrough; + case PCI_DEVICE_ID_INTEL_82801DB_3: + priv->features |= FEATURE_SMBUS_PEC; + priv->features |= FEATURE_BLOCK_BUFFER; + fallthrough; + case PCI_DEVICE_ID_INTEL_82801CA_3: + priv->features |= FEATURE_HOST_NOTIFY; + fallthrough; + case PCI_DEVICE_ID_INTEL_82801BA_2: + case PCI_DEVICE_ID_INTEL_82801AB_3: + case PCI_DEVICE_ID_INTEL_82801AA_3: + break; + } + + /* Disable features on user request */ + for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) { + if (priv->features & disable_features & (1 << i)) + dev_notice(&dev->dev, "%s disabled by user\n", + i801_feature_names[i]); + } + priv->features &= ~disable_features; + + err = pcim_enable_device(dev); + if (err) { + dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", + err); + return err; + } + pcim_pin_device(dev); + + /* Determine the address of the SMBus area */ + priv->smba = pci_resource_start(dev, SMBBAR); + if (!priv->smba) { + dev_err(&dev->dev, + "SMBus base address uninitialized, upgrade BIOS\n"); + return -ENODEV; + } + + if (i801_acpi_probe(priv)) + return -ENODEV; + + err = pcim_iomap_regions(dev, 1 << SMBBAR, + dev_driver_string(&dev->dev)); + if (err) { + dev_err(&dev->dev, + "Failed to request SMBus region 0x%lx-0x%Lx\n", + priv->smba, + (unsigned long long)pci_resource_end(dev, SMBBAR)); + i801_acpi_remove(priv); + return err; + } + + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &priv->original_hstcfg); + temp = i801_setup_hstcfg(priv); + if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN)) + dev_info(&dev->dev, "Enabling SMBus device\n"); + + if (temp & SMBHSTCFG_SMB_SMI_EN) { + dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); + /* Disable SMBus interrupt feature if SMBus using SMI# */ + priv->features &= ~FEATURE_IRQ; + } + if (temp & SMBHSTCFG_SPD_WD) + dev_info(&dev->dev, "SPD Write Disable is set\n"); + + /* Clear special mode bits */ + if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER)) + outb_p(inb_p(SMBAUXCTL(priv)) & + ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); + + /* Remember original Host Notify setting */ + if (priv->features & FEATURE_HOST_NOTIFY) + priv->original_slvcmd = inb_p(SMBSLVCMD(priv)); + + /* Default timeout in interrupt mode: 200 ms */ + priv->adapter.timeout = HZ / 5; + + if (dev->irq == IRQ_NOTCONNECTED) + priv->features &= ~FEATURE_IRQ; + + if (priv->features & FEATURE_IRQ) { + u16 pcictl, pcists; + + /* Complain if an interrupt is already pending */ + pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); + if (pcists & SMBPCISTS_INTS) + dev_warn(&dev->dev, "An interrupt is pending!\n"); + + /* Check if interrupts have been disabled */ + pci_read_config_word(priv->pci_dev, SMBPCICTL, &pcictl); + if (pcictl & SMBPCICTL_INTDIS) { + dev_info(&dev->dev, "Interrupts are disabled\n"); + priv->features &= ~FEATURE_IRQ; + } + } + + if (priv->features & FEATURE_IRQ) { + init_waitqueue_head(&priv->waitq); + + err = devm_request_irq(&dev->dev, dev->irq, i801_isr, + IRQF_SHARED, + dev_driver_string(&dev->dev), priv); + if (err) { + dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", + dev->irq, err); + priv->features &= ~FEATURE_IRQ; + } + } + dev_info(&dev->dev, "SMBus using %s\n", + priv->features & FEATURE_IRQ ? "PCI interrupt" : "polling"); + + i801_add_tco(priv); + + snprintf(priv->adapter.name, sizeof(priv->adapter.name), + "SMBus I801 adapter at %04lx", priv->smba); + err = i2c_add_adapter(&priv->adapter); + if (err) { + i801_acpi_remove(priv); + return err; + } + + i801_enable_host_notify(&priv->adapter); + + i801_probe_optional_slaves(priv); + /* We ignore errors - multiplexing is optional */ + i801_add_mux(priv); + + pci_set_drvdata(dev, priv); + + dev_pm_set_driver_flags(&dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE); + pm_runtime_set_autosuspend_delay(&dev->dev, 1000); + pm_runtime_use_autosuspend(&dev->dev); + pm_runtime_put_autosuspend(&dev->dev); + pm_runtime_allow(&dev->dev); + dev_info(&dev->dev, "wb-i2c-i801 probe ok.\n"); + + return 0; +} + +static void i801_remove(struct pci_dev *dev) +{ + struct i801_priv *priv = pci_get_drvdata(dev); + + pm_runtime_forbid(&dev->dev); + pm_runtime_get_noresume(&dev->dev); + + i801_disable_host_notify(priv); + i801_del_mux(priv); + i2c_del_adapter(&priv->adapter); + i801_acpi_remove(priv); + pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); + + platform_device_unregister(priv->tco_pdev); + + /* + * do not call pci_disable_device(dev) since it can cause hard hangs on + * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) + */ +} + +static void i801_shutdown(struct pci_dev *dev) +{ + struct i801_priv *priv = pci_get_drvdata(dev); + + /* Restore config registers to avoid hard hang on some systems */ + i801_disable_host_notify(priv); + pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); +} + +#ifdef CONFIG_PM_SLEEP +static int i801_suspend(struct device *dev) +{ + struct i801_priv *priv = dev_get_drvdata(dev); + + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, priv->original_hstcfg); + return 0; +} + +static int i801_resume(struct device *dev) +{ + struct i801_priv *priv = dev_get_drvdata(dev); + + i801_setup_hstcfg(priv); + i801_enable_host_notify(&priv->adapter); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(i801_pm_ops, i801_suspend, i801_resume); + +static struct pci_driver i801_driver = { + .name = "wb_i801_smbus", + .id_table = i801_ids, + .probe = i801_probe, + .remove = i801_remove, + .shutdown = i801_shutdown, + .driver = { + .pm = &i801_pm_ops, + }, +}; + +static int __init i2c_i801_init(void) +{ + if (dmi_name_in_vendors("FUJITSU")) + input_apanel_init(); + return pci_register_driver(&i801_driver); +} + +static void __exit i2c_i801_exit(void) +{ + pci_unregister_driver(&i801_driver); +} + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("I801 SMBus driver"); +MODULE_LICENSE("GPL"); + +module_init(i2c_i801_init); +module_exit(i2c_i801_exit); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.c new file mode 100644 index 000000000000..0859cf16539e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.c @@ -0,0 +1,1343 @@ +/* + * I2C multiplexer + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This module supports the PCA954x series of I2C multiplexer/switch chips + * made by Philips Semiconductors. + * This includes the: + * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547 + * and PCA9548. + * + * 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 . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_i2c_mux_pca954x.h" + +#define PCA954X_MAX_NCHANS 8 +#define PCA954X_IRQ_OFFSET 4 + +#define I2C_RETRY_TIMES 5 +#define I2C_RETRY_WAIT_TIMES 10 /*delay 10ms*/ + +typedef struct pca9548_cfg_info_s { + uint32_t pca9548_base_nr; + uint32_t pca9548_reset_type; + uint32_t rst_delay_b; /* delay time before reset(us) */ + uint32_t rst_delay; /* reset time(us) */ + uint32_t rst_delay_a; /* delay time after reset(us) */ + union { + i2c_attr_t i2c_attr; + gpio_attr_t gpio_attr; + io_attr_t io_attr; + file_attr_t file_attr; + } attr; + bool select_chan_check; + bool close_chan_force_reset; +} pca9548_cfg_info_t; + +int g_pca954x_debug = 0; +int g_pca954x_error = 0; + +module_param(g_pca954x_debug, int, S_IRUGO | S_IWUSR); +module_param(g_pca954x_error, int, S_IRUGO | S_IWUSR); + +#define PCA954X_DEBUG(fmt, args...) do { \ + if (g_pca954x_debug) { \ + printk(KERN_INFO "[PCA95x][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PCA954X_ERROR(fmt, args...) do { \ + if (g_pca954x_error) { \ + printk(KERN_ERR "[PCA95x][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +extern int pca9641_setmuxflag(int nr, int flag); +enum pca_type { + pca_9540, + pca_9542, + pca_9543, + pca_9544, + pca_9545, + pca_9546, + pca_9547, + pca_9548, +}; + +struct chip_desc { + u8 nchans; + u8 enable; /* used for muxes only */ + u8 has_irq; + enum muxtype { + pca954x_ismux = 0, + pca954x_isswi + } muxtype; +}; + +struct pca954x { + const struct chip_desc *chip; + u8 last_chan; /* last register value */ + u8 deselect; + struct i2c_client *client; + struct irq_domain *irq; + unsigned int irq_mask; + raw_spinlock_t lock; + pca9548_cfg_info_t pca9548_cfg_info; /* pca9548 reset cfg */ +}; + +/* Provide specs for the PCA954x types we know about */ +static const struct chip_desc chips[] = { + [pca_9540] = { + .nchans = 2, + .enable = 0x4, + .muxtype = pca954x_ismux, + }, + [pca_9542] = { + .nchans = 2, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + }, + [pca_9543] = { + .nchans = 2, + .has_irq = 1, + .muxtype = pca954x_isswi, + }, + [pca_9544] = { + .nchans = 4, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + }, + [pca_9545] = { + .nchans = 4, + .has_irq = 1, + .muxtype = pca954x_isswi, + }, + [pca_9546] = { + .nchans = 4, + .muxtype = pca954x_isswi, + }, + [pca_9547] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + }, + [pca_9548] = { + .nchans = 8, + .muxtype = pca954x_isswi, + }, +}; + +static const struct i2c_device_id pca954x_id[] = { + { "wb_pca9540", pca_9540 }, + { "wb_pca9542", pca_9542 }, + { "wb_pca9543", pca_9543 }, + { "wb_pca9544", pca_9544 }, + { "wb_pca9545", pca_9545 }, + { "wb_pca9546", pca_9546 }, + { "wb_pca9547", pca_9547 }, + { "wb_pca9548", pca_9548 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pca954x_id); + +#ifdef CONFIG_OF +static const struct of_device_id pca954x_of_match[] = { + { .compatible = "nxp,wb_pca9540", .data = &chips[pca_9540] }, + { .compatible = "nxp,wb_pca9542", .data = &chips[pca_9542] }, + { .compatible = "nxp,wb_pca9543", .data = &chips[pca_9543] }, + { .compatible = "nxp,wb_pca9544", .data = &chips[pca_9544] }, + { .compatible = "nxp,wb_pca9545", .data = &chips[pca_9545] }, + { .compatible = "nxp,wb_pca9546", .data = &chips[pca_9546] }, + { .compatible = "nxp,wb_pca9547", .data = &chips[pca_9547] }, + { .compatible = "nxp,wb_pca9548", .data = &chips[pca_9548] }, + {} +}; +MODULE_DEVICE_TABLE(of, pca954x_of_match); +#endif + +/* 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) +{ + int ret = -ENODEV; + + if (adap->algo->master_xfer) { + struct i2c_msg msg; + char buf[1]; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = 1; + buf[0] = val; + msg.buf = buf; + ret = __i2c_transfer(adap, &msg, 1); + + if (ret >= 0 && ret != 1) + ret = -EREMOTEIO; + } else { + union i2c_smbus_data data; + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_WRITE, + val, I2C_SMBUS_BYTE, &data); + } + return ret; +} + + static int pca954x_reg_read(struct i2c_adapter *adap, + struct i2c_client *client, u8 *val) + { + int ret = -ENODEV; + u8 tmp_val; + + if (adap->algo->master_xfer) { + struct i2c_msg msg; + + msg.addr = client->addr; + msg.flags = I2C_M_RD; + msg.len = 1; + msg.buf = &tmp_val; + ret = __i2c_transfer(adap, &msg, 1); + + if (ret >= 0 && ret != 1) + ret = -EREMOTEIO; + } else { + union i2c_smbus_data data; + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_READ, + 0, I2C_SMBUS_BYTE, &data); + + if (!ret) { + tmp_val = data.byte; + } + } + + *val = tmp_val; + return ret; + } + +static int pca954x_setmuxflag(struct i2c_client *client, int flag) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + + pca9641_setmuxflag(adap->nr, flag); + return 0; +} + +static int pca9548_gpio_init(gpio_attr_t *gpio_attr) +{ + int err; + + if (gpio_attr->gpio_init) { + PCA954X_DEBUG("gpio%d already init, do nothing.\n", gpio_attr->gpio); + return 0; + } + + PCA954X_DEBUG("gpio%d init.\n", gpio_attr->gpio); + err = gpio_request(gpio_attr->gpio, "pca9548_reset"); + if (err) { + goto error; + } + err = gpio_direction_output(gpio_attr->gpio, gpio_attr->reset_off); + if (err) { + gpio_free(gpio_attr->gpio); + goto error; + } + gpio_attr->gpio_init = 1; + return 0; +error: + PCA954X_ERROR("pca9548_gpio_init failed, ret:%d.\n", err); + return err; +} + +static void pca9548_gpio_free(gpio_attr_t *gpio_attr) +{ + if (gpio_attr->gpio_init == 1) { + PCA954X_DEBUG("gpio%d release.\n", gpio_attr->gpio); + gpio_free(gpio_attr->gpio); + gpio_attr->gpio_init = 0; + } +} + +static int pca954x_reset_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + PCA954X_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + PCA954X_ERROR("kernel_read failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int pca954x_reset_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + PCA954X_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + PCA954X_ERROR("kernel_write failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int pca954x_reset_i2c_read(uint32_t bus, uint32_t addr, uint32_t offset_addr, + unsigned char *buf, uint32_t size) +{ + struct file *fp; + struct i2c_client client; + char i2c_path[32]; + int i ,j ; + int rv; + + rv = 0; + mem_clear(i2c_path, sizeof(i2c_path)); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + PCA954X_ERROR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = addr; + for (j = 0 ;j < size ;j++) { + for (i = 0; i < I2C_RETRY_TIMES; i++) { + rv = i2c_smbus_read_byte_data(&client, (offset_addr + j)); + if (rv < 0) { + PCA954X_ERROR("i2c read failed, try again.\n"); + msleep(I2C_RETRY_WAIT_TIMES); + if (i >= (I2C_RETRY_TIMES - 1)) { + goto out; + } + continue; + } + *(buf + j) = (unsigned char)rv; + break; + } + } +out: + filp_close(fp, NULL); + return rv; +} + +static int pca954x_reset_i2c_write(uint32_t bus, uint32_t dev_addr, uint32_t offset_addr, + uint8_t write_buf) +{ + struct file *fp; + struct i2c_client client; + char i2c_path[32]; + int i; + int rv; + + rv = 0; + mem_clear(i2c_path, sizeof(i2c_path)); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + PCA954X_ERROR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = dev_addr; + for (i = 0; i < I2C_RETRY_TIMES; i++) { + rv = i2c_smbus_write_byte_data(&client, offset_addr, write_buf); + if (rv < 0) { + PCA954X_ERROR("i2c write failed, try again.\n"); + msleep(I2C_RETRY_WAIT_TIMES); + if (i >= (I2C_RETRY_TIMES - 1)) { + goto out; + } + continue; + } + break; + } +out: + filp_close(fp, NULL); + return rv; +} + +static void pca954x_close_chan_finally(struct i2c_mux_core * muxc) +{ + struct pca954x *data; + struct i2c_adapter *adapter; + struct i2c_client *client; + int adapter_timeout; + + data = i2c_mux_priv(muxc); + client = data->client; + adapter = muxc->parent; + /* get bus info */ + while (i2c_parent_is_i2c_adapter(adapter)) { + adapter = to_i2c_adapter(adapter->dev.parent); + } + adapter_timeout = adapter->timeout; + adapter->timeout = msecs_to_jiffies(50); + pca954x_reg_write(muxc->parent, client, data->last_chan); + adapter->timeout = adapter_timeout; + + return; +} + +static int pca954x_do_file_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout, err; + struct pca954x *data; + struct i2c_client *client; + pca9548_cfg_info_t *reset_cfg; + file_attr_t *file_attr; + u8 val; + + data = i2c_mux_priv(muxc); + client = data->client; + reset_cfg = &data->pca9548_cfg_info; + file_attr = &reset_cfg->attr.file_attr; + ret = -1; + + PCA954X_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA954X_DEBUG("dev_name:%s, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + file_attr->dev_name, file_attr->offset, file_attr->mask, + file_attr->reset_on, file_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + err = pca954x_reset_file_read(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= ~(file_attr->mask); + val |= file_attr->reset_on; + err = pca954x_reset_file_write(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(file_attr->mask); + val |= file_attr->reset_off; + err = pca954x_reset_file_write(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + err = pca954x_reset_file_read(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= (file_attr->mask); + if (val == file_attr->reset_off) { + ret = 0; + pca954x_close_chan_finally(muxc); + PCA954X_DEBUG("pca954x_do_file_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + if (ret < 0) { + PCA954X_ERROR("pca954x_do_file_reset timeout.\n"); + } +out: + if (err < 0) { + PCA954X_ERROR("pca954x_do_file_reset file rd/wr failed, ret:%d.\n", err); + } + + return ret; +} + +static int pca954x_do_io_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout; + struct pca954x *data; + struct i2c_client *client; + pca9548_cfg_info_t *reset_cfg; + io_attr_t *io_attr; + u8 val; + + data = i2c_mux_priv(muxc); + client = data->client; + reset_cfg = &data->pca9548_cfg_info; + io_attr = &reset_cfg->attr.io_attr; + + PCA954X_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA954X_DEBUG("io_addr:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + io_attr->io_addr, io_attr->mask, io_attr->reset_on, io_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + val = inb(io_attr->io_addr); + val &= ~(io_attr->mask); + val |= io_attr->reset_on; + outb(val, io_attr->io_addr); + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(io_attr->mask); + val |= io_attr->reset_off; + outb(val, io_attr->io_addr); + + ret = -1; + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + val = inb(io_attr->io_addr); + val &= (io_attr->mask); + if (val == io_attr->reset_off) { + ret = 0; + pca954x_close_chan_finally(muxc); + PCA954X_DEBUG("pca954x_do_io_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + + if (ret < 0) { + PCA954X_ERROR("pca954x_do_io_reset timeout.\n"); + } + + return ret; +} + +static int pca954x_do_gpio_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout; + struct pca954x *data; + struct i2c_client *client; + pca9548_cfg_info_t *reset_cfg; + gpio_attr_t *gpio_attr; + u8 val; + + data = i2c_mux_priv(muxc); + client = data->client; + reset_cfg = &data->pca9548_cfg_info; + gpio_attr = &reset_cfg->attr.gpio_attr; + + ret = pca9548_gpio_init(gpio_attr); + if (ret) { + return -1; + } + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + /* reset on */ + __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_on); + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + /* reset off */ + __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_off); + ret = -1; + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + val = __gpio_get_value(gpio_attr->gpio); + if (val == gpio_attr->reset_off) { + ret = 0; + pca954x_close_chan_finally(muxc); + PCA954X_DEBUG("pca954x_do_gpio_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + /* 1MS schedule*/ + schedule(); + } + timeout--; + } + + if (ret < 0) { + PCA954X_ERROR("pca954x_do_gpio_reset timeout.\n"); + } + + pca9548_gpio_free(gpio_attr); + return ret; +} + +static int pca954x_do_i2c_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout, err; + struct pca954x *data; + struct i2c_client *client; + pca9548_cfg_info_t *reset_cfg; + i2c_attr_t *i2c_attr; + u8 val; + + data = i2c_mux_priv(muxc); + client = data->client; + reset_cfg = &data->pca9548_cfg_info; + i2c_attr = &reset_cfg->attr.i2c_attr; + ret = -1; + + PCA954X_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA954X_DEBUG("bus:0x%x, addr:0x%x, reg:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + i2c_attr->i2c_bus, i2c_attr->i2c_addr, i2c_attr->reg_offset, + i2c_attr->mask, i2c_attr->reset_on, i2c_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + err = pca954x_reset_i2c_read(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= ~(i2c_attr->mask); + val |= i2c_attr->reset_on; + err = pca954x_reset_i2c_write(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, val); + if (err < 0) { + goto out; + } + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(i2c_attr->mask); + val |= i2c_attr->reset_off; + err = pca954x_reset_i2c_write(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, val); + if (err < 0) { + goto out; + } + + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + err = pca954x_reset_i2c_read(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= (i2c_attr->mask); + if (val == i2c_attr->reset_off) { + ret = 0; + pca954x_close_chan_finally(muxc); + PCA954X_DEBUG("pca954x_do_i2c_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + if (ret < 0) { + PCA954X_ERROR("pca954x_do_i2c_reset timeout.\n"); + } +out: + if (err < 0) { + PCA954X_ERROR("pca954x_do_i2c_reset i2c op failed, ret:%d.\n", err); + } + return ret; +} + +static int pca954x_do_reset(struct i2c_mux_core *muxc) +{ + int ret; + struct pca954x *data; + + data = i2c_mux_priv(muxc); + if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_NONE) { + ret = -1; + PCA954X_DEBUG("Don't need to reset.\n"); + } else if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_I2C) { + ret = pca954x_do_i2c_reset(muxc); + } else if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_GPIO) { + ret = pca954x_do_gpio_reset(muxc); + } else if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_IO) { + ret = pca954x_do_io_reset(muxc); + } else if (data->pca9548_cfg_info.pca9548_reset_type == PCA9548_RESET_FILE) { + ret = pca954x_do_file_reset(muxc); + } else { + ret = -1; + PCA954X_ERROR("Unsupport reset type:0x%x.\n", + data->pca9548_cfg_info.pca9548_reset_type); + } + + if (ret < 0) { + PCA954X_ERROR("pca9548_reset_ctrl failed, reset type:%u, ret:%d.\n", + data->pca9548_cfg_info.pca9548_reset_type, ret); + } + return ret; +} + +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; + const struct chip_desc *chip = data->chip; + u8 regval; + int ret = 0; + u8 read_val = 0; + int rv; + + /* we make switches look like muxes, not sure how to be smarter */ + if (chip->muxtype == pca954x_ismux) + regval = chan | chip->enable; + else + regval = 1 << chan; + + /* Only select the channel if its different from the last channel */ + if (data->last_chan != regval) { + pca954x_setmuxflag(client, 0); + ret = pca954x_reg_write(muxc->parent, client, regval); + data->last_chan = ret < 0 ? 0 : regval; + } + + if (data->pca9548_cfg_info.select_chan_check) { /* check chan */ + ret = pca954x_reg_read(muxc->parent, client, &read_val); + /* read failed or chan not open, reset pca9548 */ + if ((ret < 0) || (read_val != data->last_chan)) { + dev_warn(&client->dev, "pca954x open channle %u failed, do reset.\n", chan); + PCA954X_DEBUG("ret = %d, read_val = %d, last_chan = %d.\n", ret, read_val, data->last_chan); + rv = pca954x_do_reset(muxc); + if (rv >= 0) { + PCA954X_DEBUG("pca954x_do_reset success, rv = %d.\n", rv); + } else { + PCA954X_DEBUG("pca954x_do_reset failed, rv = %d.\n", rv); + } + if (ret >= 0) { + ret = -EIO; /* chan not match, return IO error */ + } + } + } + + 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; + int ret, rv; + + /* Deselect active channel */ + data->last_chan = 0; + if (data->pca9548_cfg_info.close_chan_force_reset) { + ret = pca954x_do_reset(muxc); + } else { + ret = pca954x_reg_write(muxc->parent, client, data->last_chan); + if (ret < 0 ) { + + dev_warn(&client->dev, "pca954x close channel %u failed, do reset.\n", chan); + rv = pca954x_do_reset(muxc); + if (rv == 0) { + ret = 0; + } + } + } + + pca954x_setmuxflag(client, 1); + (void)pca954x_reg_write(muxc->parent, client, data->last_chan); + + return ret; + +} + +static irqreturn_t pca954x_irq_handler(int irq, void *dev_id) +{ + struct pca954x *data = dev_id; + unsigned int child_irq; + int ret, i, handled = 0; + + ret = i2c_smbus_read_byte(data->client); + if (ret < 0) + return IRQ_NONE; + + for (i = 0; i < data->chip->nchans; i++) { + if (ret & BIT(PCA954X_IRQ_OFFSET + i)) { + child_irq = irq_linear_revmap(data->irq, i); + handle_nested_irq(child_irq); + handled++; + } + } + return handled ? IRQ_HANDLED : IRQ_NONE; +} + +static void pca954x_irq_mask(struct irq_data *idata) +{ + struct pca954x *data = irq_data_get_irq_chip_data(idata); + unsigned int pos = idata->hwirq; + unsigned long flags; + + raw_spin_lock_irqsave(&data->lock, flags); + + data->irq_mask &= ~BIT(pos); + if (!data->irq_mask) + disable_irq(data->client->irq); + + raw_spin_unlock_irqrestore(&data->lock, flags); +} + +static void pca954x_irq_unmask(struct irq_data *idata) +{ + struct pca954x *data = irq_data_get_irq_chip_data(idata); + unsigned int pos = idata->hwirq; + unsigned long flags; + + raw_spin_lock_irqsave(&data->lock, flags); + + if (!data->irq_mask) + enable_irq(data->client->irq); + data->irq_mask |= BIT(pos); + + raw_spin_unlock_irqrestore(&data->lock, flags); +} + +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_mask = pca954x_irq_mask, + .irq_unmask = pca954x_irq_unmask, + .irq_set_type = pca954x_irq_set_type, +}; + +static int of_pca954x_irq_setup(struct i2c_mux_core *muxc) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int c, err, 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); + irq_set_chip_data(irq, data); + irq_set_chip_and_handler(irq, &pca954x_irq_chip, + handle_simple_irq); + } + + err = devm_request_threaded_irq(&client->dev, data->client->irq, NULL, + pca954x_irq_handler, + IRQF_ONESHOT | IRQF_SHARED, + "pca954x", data); + if (err) + goto err_req_irq; + + disable_irq(data->client->irq); + + return 0; +err_req_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); + + return err; +} + +static int pca954x_irq_setup(struct i2c_mux_core *muxc) +{ + return 0; +} + +static int of_pca954x_reset_data_init(struct pca954x *data) +{ + int err; + struct device *dev = &data->client->dev; + pca9548_cfg_info_t *reset_cfg; + + reset_cfg = &data->pca9548_cfg_info; + if (dev == NULL || dev->of_node == NULL) { + PCA954X_DEBUG("dev or dev->of_node is NUll, no reset.\n"); + reset_cfg->pca9548_reset_type = PCA9548_RESET_NONE; + return 0; + } + + reset_cfg->select_chan_check = of_property_read_bool(dev->of_node, "select_chan_check"); + reset_cfg->close_chan_force_reset = of_property_read_bool(dev->of_node, "close_chan_force_reset"); + PCA954X_DEBUG("select_chan_check:%d, close_chan_force_reset:%d.\n", reset_cfg->select_chan_check, + reset_cfg->close_chan_force_reset); + + if (of_property_read_u32(dev->of_node, "pca9548_reset_type", &reset_cfg->pca9548_reset_type)) { + + PCA954X_DEBUG("pca9548_reset_type not found, no reset.\n"); + reset_cfg->pca9548_reset_type = PCA9548_RESET_NONE; + return 0; + } + err = of_property_read_u32(dev->of_node, "rst_delay_b", &reset_cfg->rst_delay_b); + err |= of_property_read_u32(dev->of_node, "rst_delay", &reset_cfg->rst_delay); + err |= of_property_read_u32(dev->of_node, "rst_delay_a", &reset_cfg->rst_delay_a); + + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("reset_type:0x%x, rst_delay_b:0x%x, rst_delay:0x%x, rst_delay_a:0x%x.\n", + reset_cfg->pca9548_reset_type, reset_cfg->rst_delay_b, + reset_cfg->rst_delay, reset_cfg->rst_delay_a); + + if (reset_cfg->pca9548_reset_type == PCA9548_RESET_I2C) { + + PCA954X_DEBUG("reset by i2c.\n"); + err = of_property_read_u32(dev->of_node, "i2c_bus", &reset_cfg->attr.i2c_attr.i2c_bus); + err |=of_property_read_u32(dev->of_node, "i2c_addr", &reset_cfg->attr.i2c_attr.i2c_addr); + err |=of_property_read_u32(dev->of_node, "reg_offset", &reset_cfg->attr.i2c_attr.reg_offset); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.i2c_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.i2c_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.i2c_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("bus:%u, addr:0x%x, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + reset_cfg->attr.i2c_attr.i2c_bus, reset_cfg->attr.i2c_attr.i2c_addr, + reset_cfg->attr.i2c_attr.reg_offset, reset_cfg->attr.i2c_attr.mask, + reset_cfg->attr.i2c_attr.reset_on, reset_cfg->attr.i2c_attr.reset_off); + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_GPIO) { + + PCA954X_DEBUG("reset by gpio.\n"); + err = of_property_read_u32(dev->of_node, "gpio", &reset_cfg->attr.gpio_attr.gpio); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.gpio_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.gpio_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("gpio number:%u, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.gpio_attr.gpio, reset_cfg->attr.gpio_attr.reset_on, + reset_cfg->attr.gpio_attr.reset_off); + reset_cfg->attr.gpio_attr.gpio_init = 0; + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_IO) { + + PCA954X_DEBUG("reset by io.\n"); + err = of_property_read_u32(dev->of_node, "io_addr", &reset_cfg->attr.io_attr.io_addr); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.io_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.io_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.io_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("io_addr:0x%x, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.io_attr.io_addr, reset_cfg->attr.io_attr.mask, + reset_cfg->attr.io_attr.reset_on, reset_cfg->attr.io_attr.reset_off); + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_FILE) { + + PCA954X_DEBUG("reset by file.\n"); + err = of_property_read_string(dev->of_node, "dev_name", &reset_cfg->attr.file_attr.dev_name); + err |=of_property_read_u32(dev->of_node, "offset", &reset_cfg->attr.file_attr.offset); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.file_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.file_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.file_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA954X_DEBUG("dev_name:%s, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.file_attr.dev_name, reset_cfg->attr.file_attr.mask, + reset_cfg->attr.file_attr.reset_on, reset_cfg->attr.file_attr.reset_off); + } else { + PCA954X_ERROR("Unsupport reset type:%d.\n", reset_cfg->pca9548_reset_type); + goto dts_config_err; + } + return 0; +dts_config_err: + PCA954X_ERROR("dts config error, ret:%d.\n", err); + return -EINVAL; +} + +static int pca954x_reset_data_init(struct pca954x *data) +{ + pca9548_cfg_info_t *reset_cfg; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device; + + if (data->client->dev.platform_data == NULL) { + PCA954X_DEBUG("pca954x has no reset platform data config.\n"); + return 0; + } + reset_cfg = &data->pca9548_cfg_info; + i2c_mux_pca954x_device = data->client->dev.platform_data; + reset_cfg->select_chan_check = i2c_mux_pca954x_device->select_chan_check; + reset_cfg->close_chan_force_reset = i2c_mux_pca954x_device->close_chan_force_reset; + PCA954X_DEBUG("select_chan_check:%d, close_chan_force_reset:%d.\n", reset_cfg->select_chan_check, + reset_cfg->close_chan_force_reset); + + reset_cfg->pca9548_reset_type = i2c_mux_pca954x_device->pca9548_reset_type; + if (reset_cfg->pca9548_reset_type == PCA9548_RESET_NONE) { + PCA954X_DEBUG("pca9548_reset_type not found, no reset.\n"); + return 0; + } + + reset_cfg->rst_delay_b = i2c_mux_pca954x_device->rst_delay_b; + reset_cfg->rst_delay = i2c_mux_pca954x_device->rst_delay; + reset_cfg->rst_delay_a = i2c_mux_pca954x_device->rst_delay_a; + PCA954X_DEBUG("reset_type:0x%x, rst_delay_b:0x%x, rst_delay:0x%x, rst_delay_a:0x%x.\n", + reset_cfg->pca9548_reset_type, reset_cfg->rst_delay_b, + reset_cfg->rst_delay, reset_cfg->rst_delay_a); + + if (reset_cfg->pca9548_reset_type == PCA9548_RESET_I2C) { + + PCA954X_DEBUG("reset by i2c.\n"); + reset_cfg->attr.i2c_attr.i2c_bus = i2c_mux_pca954x_device->attr.i2c_attr.i2c_bus; + reset_cfg->attr.i2c_attr.i2c_addr = i2c_mux_pca954x_device->attr.i2c_attr.i2c_addr; + reset_cfg->attr.i2c_attr.reg_offset = i2c_mux_pca954x_device->attr.i2c_attr.reg_offset; + reset_cfg->attr.i2c_attr.mask = i2c_mux_pca954x_device->attr.i2c_attr.mask; + reset_cfg->attr.i2c_attr.reset_on = i2c_mux_pca954x_device->attr.i2c_attr.reset_on; + reset_cfg->attr.i2c_attr.reset_off = i2c_mux_pca954x_device->attr.i2c_attr.reset_off; + PCA954X_DEBUG("bus:%u, addr:0x%x, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + reset_cfg->attr.i2c_attr.i2c_bus, reset_cfg->attr.i2c_attr.i2c_addr, + reset_cfg->attr.i2c_attr.reg_offset, reset_cfg->attr.i2c_attr.mask, + reset_cfg->attr.i2c_attr.reset_on, reset_cfg->attr.i2c_attr.reset_off); + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_GPIO) { + + PCA954X_DEBUG("reset by gpio.\n"); + reset_cfg->attr.gpio_attr.gpio = i2c_mux_pca954x_device->attr.gpio_attr.gpio; + reset_cfg->attr.gpio_attr.reset_on = i2c_mux_pca954x_device->attr.gpio_attr.reset_on; + reset_cfg->attr.gpio_attr.reset_off = i2c_mux_pca954x_device->attr.gpio_attr.reset_off; + PCA954X_DEBUG("gpio number:%u, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.gpio_attr.gpio, reset_cfg->attr.gpio_attr.reset_on, + reset_cfg->attr.gpio_attr.reset_off); + reset_cfg->attr.gpio_attr.gpio_init = 0; + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_IO) { + + PCA954X_DEBUG("reset by io.\n"); + reset_cfg->attr.io_attr.io_addr = i2c_mux_pca954x_device->attr.io_attr.io_addr; + reset_cfg->attr.io_attr.mask = i2c_mux_pca954x_device->attr.io_attr.mask; + reset_cfg->attr.io_attr.reset_on = i2c_mux_pca954x_device->attr.io_attr.reset_on; + reset_cfg->attr.io_attr.reset_off = i2c_mux_pca954x_device->attr.io_attr.reset_off; + PCA954X_DEBUG("io_addr:0x%x, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.io_attr.io_addr, reset_cfg->attr.io_attr.mask, + reset_cfg->attr.io_attr.reset_on, reset_cfg->attr.io_attr.reset_off); + } else if (reset_cfg->pca9548_reset_type == PCA9548_RESET_FILE) { + + reset_cfg->attr.file_attr.dev_name = i2c_mux_pca954x_device->attr.file_attr.dev_name; + reset_cfg->attr.file_attr.offset = i2c_mux_pca954x_device->attr.file_attr.offset; + reset_cfg->attr.file_attr.mask = i2c_mux_pca954x_device->attr.file_attr.mask; + reset_cfg->attr.file_attr.reset_on = i2c_mux_pca954x_device->attr.file_attr.reset_on; + reset_cfg->attr.file_attr.reset_off = i2c_mux_pca954x_device->attr.file_attr.reset_off; + PCA954X_DEBUG("dev_name:%s, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.file_attr.dev_name, reset_cfg->attr.file_attr.mask, + reset_cfg->attr.file_attr.reset_on, reset_cfg->attr.file_attr.reset_off); + } else { + PCA954X_ERROR("Unsupport reset type:%d.\n", reset_cfg->pca9548_reset_type); + return -EINVAL; + } + return 0; +} + +/* + * I2C init/probing/exit functions + */ +static int pca954x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + struct device_node *of_node = client->dev.of_node; + bool idle_disconnect_dt; + struct gpio_desc *gpio; + int num, force, class; + struct i2c_mux_core *muxc; + struct pca954x *data; + const struct of_device_id *match; + unsigned int probe_disable; + int ret, dynamic_nr; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device; + + PCA954X_DEBUG("pca954x_probe, parent bus: %d, 9548 addr:0x%x.\n", adap->nr, client->addr); + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + + muxc = i2c_mux_alloc(adap, &client->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; + + /* Get the mux out of reset if a reset GPIO is specified. */ + gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + + /* check device connection status */ + + if (client->dev.of_node == NULL) { + if (client->dev.platform_data == NULL) { + probe_disable = 1; + PCA954X_DEBUG("has no platform data config, set probe_disable = 1.\n"); + } else { + i2c_mux_pca954x_device = client->dev.platform_data; + probe_disable = i2c_mux_pca954x_device->probe_disable; + } + } else { + probe_disable = of_property_read_bool(of_node, "probe_disable"); + } + + /* Write the mux register at addr to verify + * that the mux is in fact present. This also + * initializes the mux to disconnected state. + */ + if (!probe_disable && (i2c_smbus_write_byte(client, 0) < 0)) { + dev_warn(&client->dev, "probe failed\n"); + return -ENODEV; + } + + match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev); + if (match) + data->chip = of_device_get_match_data(&client->dev); + else + data->chip = &chips[id->driver_data]; + + data->last_chan = 0; /* force the first selection */ + + if (client->dev.of_node == NULL) { + idle_disconnect_dt = false; + } else { + idle_disconnect_dt = of_node && + of_property_read_bool(of_node, "i2c-mux-idle-disconnect"); + } + + if (client->dev.of_node) { + ret= of_pca954x_reset_data_init(data); + } else { + ret= pca954x_reset_data_init(data); + } + if (ret < 0) { + dev_err(&client->dev, "pca954x reset config err, ret:%d.\n", ret); + return ret; + } + + if (client->dev.of_node) { + ret = of_pca954x_irq_setup(muxc); + } else { + ret = pca954x_irq_setup(muxc); + } + if (ret) { + goto fail_del_adapters; + } + + if (client->dev.of_node == NULL) { + if (client->dev.platform_data == NULL) { + dynamic_nr = 1; + PCA954X_DEBUG("platform data is NULL, use dynamic adap number.\n"); + } else { + i2c_mux_pca954x_device = client->dev.platform_data; + data->pca9548_cfg_info.pca9548_base_nr = i2c_mux_pca954x_device->pca9548_base_nr; + if (data->pca9548_cfg_info.pca9548_base_nr == 0) { + dynamic_nr = 1; + PCA954X_DEBUG("pca9548_base_nr = 0, use dynamic adap number.\n"); + } else { + dynamic_nr = 0; + PCA954X_DEBUG("pca9548_base_nr:%u.\n", data->pca9548_cfg_info.pca9548_base_nr); + } + } + } else { + if (of_property_read_u32(of_node, "pca9548_base_nr", &data->pca9548_cfg_info.pca9548_base_nr)) { + + dynamic_nr = 1; + PCA954X_DEBUG("pca9548_base_nr not found, use dynamic adap number"); + } else { + dynamic_nr = 0; + PCA954X_DEBUG("pca9548_base_nr:%u.\n", data->pca9548_cfg_info.pca9548_base_nr); + } + } + + /* Now create an adapter for each channel */ + for (num = 0; num < data->chip->nchans; num++) { + bool idle_disconnect_pd = false; + if (dynamic_nr == 1) { + force = 0; /* dynamic adap number */ + } else { + force = data->pca9548_cfg_info.pca9548_base_nr + num; + } + + class = 0; /* no class by default */ + data->deselect |= (idle_disconnect_pd || + idle_disconnect_dt) << num; + + ret = i2c_mux_add_adapter(muxc, force, num, class); + if (ret) + goto fail_del_adapters; + } + + dev_info(&client->dev, + "registered %d multiplexed busses for I2C %s %s\n", + num, data->chip->muxtype == pca954x_ismux + ? "mux" : "switch", client->name); + + return 0; + +fail_del_adapters: + i2c_mux_del_adapters(muxc); + return ret; +} + +static int pca954x_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + 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); + 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); + + data->last_chan = 0; + return i2c_smbus_write_byte(client, 0); +} +#endif + +static SIMPLE_DEV_PM_OPS(pca954x_pm, NULL, pca954x_resume); + +static struct i2c_driver pca954x_driver = { + .driver = { + .name = "wb_pca954x", + .pm = &pca954x_pm, + .of_match_table = of_match_ptr(pca954x_of_match), + }, + .probe = pca954x_probe, + .remove = pca954x_remove, + .id_table = pca954x_id, +}; + +module_i2c_driver(pca954x_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PCA954x I2C mux/switch driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.h new file mode 100644 index 000000000000..9cbe162782c5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca954x.h @@ -0,0 +1,67 @@ +#ifndef __WB_I2C_MUX_PCA954X_H__ +#define __WB_I2C_MUX_PCA954X_H__ + +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef enum pca9548_reset_type_s { + PCA9548_RESET_NONE = 0, + PCA9548_RESET_I2C = 1, + PCA9548_RESET_GPIO = 2, + PCA9548_RESET_IO = 3, + PCA9548_RESET_FILE = 4, +} pca9548_reset_type_t; + +typedef struct i2c_attr_s { + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t reg_offset; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} i2c_attr_t; + +typedef struct io_attr_s { + uint32_t io_addr; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} io_attr_t; + +typedef struct file_attr_s { + const char *dev_name; + uint32_t offset; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} file_attr_t; + +typedef struct gpio_attr_s { + int gpio_init; + uint32_t gpio; + uint32_t reset_on; + uint32_t reset_off; +} gpio_attr_t; + +typedef struct i2c_mux_pca954x_device_s { + struct i2c_client *client; + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t pca9548_base_nr; + uint32_t pca9548_reset_type; + uint32_t rst_delay_b; /* delay time before reset(us) */ + uint32_t rst_delay; /* reset time(us) */ + uint32_t rst_delay_a; /* delay time after reset(us) */ + bool probe_disable; + bool select_chan_check; + bool close_chan_force_reset; + union { + i2c_attr_t i2c_attr; + gpio_attr_t gpio_attr; + io_attr_t io_attr; + file_attr_t file_attr; + } attr; +} i2c_mux_pca954x_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.c new file mode 100644 index 000000000000..9945f6fcad25 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.c @@ -0,0 +1,1375 @@ +/* + * I2C multiplexer driver for PCA9541 bus master selector + * + * Copyright (c) 2010 Ericsson AB. + * + * Author: Guenter Roeck + * + * Derived from: + * pca954x.c + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_i2c_mux_pca9641.h" + +/* + * The PCA9541 is a bus master selector. It supports two I2C masters connected + * to a single slave bus. + * + * Before each bus transaction, a master has to acquire bus ownership. After the + * transaction is complete, bus ownership has to be released. This fits well + * into the I2C multiplexer framework, which provides select and release + * functions for this purpose. For this reason, this driver is modeled as + * single-channel I2C bus multiplexer. + * + * This driver assumes that the two bus masters are controlled by two different + * hosts. If a single host controls both masters, platform code has to ensure + * that only one of the masters is instantiated at any given time. + */ + +#define PCA9541_CONTROL 0x01 +#define PCA9541_ISTAT 0x02 + +#define PCA9541_CTL_MYBUS (1 << 0) +#define PCA9541_CTL_NMYBUS (1 << 1) +#define PCA9541_CTL_BUSON (1 << 2) +#define PCA9541_CTL_NBUSON (1 << 3) +#define PCA9541_CTL_BUSINIT (1 << 4) +#define PCA9541_CTL_TESTON (1 << 6) +#define PCA9541_CTL_NTESTON (1 << 7) +#define PCA9541_ISTAT_INTIN (1 << 0) +#define PCA9541_ISTAT_BUSINIT (1 << 1) +#define PCA9541_ISTAT_BUSOK (1 << 2) +#define PCA9541_ISTAT_BUSLOST (1 << 3) +#define PCA9541_ISTAT_MYTEST (1 << 6) +#define PCA9541_ISTAT_NMYTEST (1 << 7) +#define PCA9641_ID 0x00 +#define PCA9641_ID_MAGIC 0x38 +#define PCA9641_CONTROL 0x01 +#define PCA9641_STATUS 0x02 +#define PCA9641_TIME 0x03 +#define PCA9641_CTL_LOCK_REQ BIT(0) +#define PCA9641_CTL_LOCK_GRANT BIT(1) +#define PCA9641_CTL_BUS_CONNECT BIT(2) +#define PCA9641_CTL_BUS_INIT BIT(3) +#define PCA9641_CTL_SMBUS_SWRST BIT(4) +#define PCA9641_CTL_IDLE_TIMER_DIS BIT(5) +#define PCA9641_CTL_SMBUS_DIS BIT(6) +#define PCA9641_CTL_PRIORITY BIT(7) +#define PCA9641_STS_OTHER_LOCK BIT(0) +#define PCA9641_STS_BUS_INIT_FAIL BIT(1) +#define PCA9641_STS_BUS_HUNG BIT(2) +#define PCA9641_STS_MBOX_EMPTY BIT(3) +#define PCA9641_STS_MBOX_FULL BIT(4) +#define PCA9641_STS_TEST_INT BIT(5) +#define PCA9641_STS_SCL_IO BIT(6) +#define PCA9641_STS_SDA_IO BIT(7) +#define PCA9641_RES_TIME 0x03 +#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) +#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) +#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) +#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) +#define BUSOFF(x, y) (!((x) & PCA9641_CTL_LOCK_GRANT) && \ + !((y) & PCA9641_STS_OTHER_LOCK)) +#define other_lock(x) ((x) & PCA9641_STS_OTHER_LOCK) +#define lock_grant(x) ((x) & PCA9641_CTL_LOCK_GRANT) + +#define PCA9641_RETRY_TIME (8) +#define PCA9641_RESET_DELAY (150) + +typedef struct i2c_muxs_struct_flag +{ + int nr; + char name[48]; + struct mutex update_lock; + int flag; +}i2c_mux_flag; + +i2c_mux_flag pca_flag = { + .flag = -1, +}; + +int pca9641_setmuxflag(int nr, int flag) +{ + if (pca_flag.nr == nr) { + pca_flag.flag = flag; + } + return 0; +} +EXPORT_SYMBOL(pca9641_setmuxflag); + +static int g_debug_info = 0; +static int g_debug_err = 0; + +module_param(g_debug_info, int, S_IRUGO | S_IWUSR); +module_param(g_debug_err, int, S_IRUGO | S_IWUSR); + +#define PCA_DEBUG(fmt, args...) do { \ + if (g_debug_info) { \ + printk(KERN_INFO "[pca9641][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PCA_DEBUG_ERR(fmt, args...) do { \ + if (g_debug_err) { \ + printk(KERN_ERR "[pca9641][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* arbitration timeouts, in jiffies */ +#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */ +#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */ + +/* arbitration retry delays, in us */ +#define SELECT_DELAY_SHORT 50 +#define SELECT_DELAY_LONG 1000 +#define I2C_RETRY_TIMES (5) +#define I2C_RETRY_WAIT_TIMES (10) /*delay 10ms*/ + +typedef struct pca9641_cfg_info_s { + uint32_t pca9641_reset_type; + uint32_t rst_delay_b; /* delay time before reset(us) */ + uint32_t rst_delay; /* reset time(us) */ + uint32_t rst_delay_a; /* delay time after reset(us) */ + union { + i2c_attr_t i2c_attr; + gpio_attr_t gpio_attr; + io_attr_t io_attr; + file_attr_t file_attr; + } attr; +} pca9641_cfg_info_t; + +struct pca9541 { + struct i2c_client *client; + unsigned long select_timeout; + unsigned long arb_timeout; + uint32_t pca9641_nr; + pca9641_cfg_info_t pca9641_cfg_info; /* pca9641 reset cfg */ +}; + +static const struct i2c_device_id pca9541_id[] = { + {"wb_pca9541", 0}, + {"wb_pca9641", 1}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pca9541_id); + +#ifdef CONFIG_OF +static const struct of_device_id pca9541_of_match[] = { + { .compatible = "nxp,wb_pca9541" }, + { .compatible = "nxp,wb_pca9641" }, + {} +}; +MODULE_DEVICE_TABLE(of, pca9541_of_match); +#endif + +static int pca9641_gpio_init(gpio_attr_t *gpio_attr) +{ + int err; + + if (gpio_attr->gpio_init) { + PCA_DEBUG("gpio%d already init, do nothing.\n", gpio_attr->gpio); + return 0; + } + + PCA_DEBUG("gpio%d init.\n", gpio_attr->gpio); + err = gpio_request(gpio_attr->gpio, "pca9641_reset"); + if (err) { + goto error; + } + err = gpio_direction_output(gpio_attr->gpio, gpio_attr->reset_off); + if (err) { + gpio_free(gpio_attr->gpio); + goto error; + } + gpio_attr->gpio_init = 1; + return 0; +error: + PCA_DEBUG_ERR("pca9641_gpio_init failed, ret:%d.\n", err); + return err; +} + +static void pca9641_gpio_free(gpio_attr_t *gpio_attr) +{ + if (gpio_attr->gpio_init == 1) { + PCA_DEBUG("gpio%d release.\n", gpio_attr->gpio); + gpio_free(gpio_attr->gpio); + gpio_attr->gpio_init = 0; + } + return; +} + +static int pca9641_reset_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + PCA_DEBUG_ERR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + PCA_DEBUG_ERR("kernel_read failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int pca9641_reset_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + PCA_DEBUG_ERR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + PCA_DEBUG_ERR("kernel_write failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int pca9641_reset_i2c_read(uint32_t bus, uint32_t addr, uint32_t offset_addr, + unsigned char *buf, uint32_t size) +{ + struct file *fp; + struct i2c_client client; + char i2c_path[32]; + int i, j; + int rv; + + rv = 0; + mem_clear(i2c_path, sizeof(i2c_path)); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + PCA_DEBUG_ERR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = addr; + for (j = 0; j < size; j++) { + for (i = 0; i < I2C_RETRY_TIMES; i++) { + rv = i2c_smbus_read_byte_data(&client, (offset_addr + j)); + if (rv < 0) { + PCA_DEBUG_ERR("i2c read failed, try again.\n"); + msleep(I2C_RETRY_WAIT_TIMES); + if (i >= (I2C_RETRY_TIMES - 1)) { + goto out; + } + continue; + } + *(buf + j) = (unsigned char)rv; + break; + } + } +out: + filp_close(fp, NULL); + return rv; +} + +static int pca9641_reset_i2c_write(uint32_t bus, uint32_t dev_addr, uint32_t offset_addr, + uint8_t write_buf) +{ + struct file *fp; + struct i2c_client client; + char i2c_path[32]; + int i; + int rv; + + rv = 0; + mem_clear(i2c_path, sizeof(i2c_path)); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + PCA_DEBUG_ERR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = dev_addr; + for (i = 0; i < I2C_RETRY_TIMES; i++) { + rv = i2c_smbus_write_byte_data(&client, offset_addr, write_buf); + if (rv < 0) { + PCA_DEBUG_ERR("i2c write failed, try again.\n"); + msleep(I2C_RETRY_WAIT_TIMES); + if (i >= (I2C_RETRY_TIMES - 1)) { + goto out; + } + continue; + } + break; + } +out: + filp_close(fp, NULL); + return rv; +} + +static int pca9641_do_file_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout, err; + struct pca9541 *data; + pca9641_cfg_info_t *reset_cfg; + file_attr_t *file_attr; + u8 val; + + data = i2c_mux_priv(muxc); + reset_cfg = &data->pca9641_cfg_info; + file_attr = &reset_cfg->attr.file_attr; + ret = -1; + + PCA_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA_DEBUG("dev_name:%s, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + file_attr->dev_name, file_attr->offset, file_attr->mask, + file_attr->reset_on, file_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + err = pca9641_reset_file_read(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + val &= ~(file_attr->mask); + val |= file_attr->reset_on; + err = pca9641_reset_file_write(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(file_attr->mask); + val |= file_attr->reset_off; + err = pca9641_reset_file_write(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + err = pca9641_reset_file_read(file_attr->dev_name, file_attr->offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= (file_attr->mask); + if (val == file_attr->reset_off) { + ret = 0; + PCA_DEBUG("pca9641_do_file_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_do_file_reset timeout.\n"); + } +out: + if (err < 0) { + PCA_DEBUG_ERR("pca9641_do_file_reset file rd/wr failed, ret:%d.\n", err); + } + + return ret; +} + +static int pca9641_do_io_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout; + struct pca9541 *data; + pca9641_cfg_info_t *reset_cfg; + io_attr_t *io_attr; + u8 val; + + data = i2c_mux_priv(muxc); + reset_cfg = &data->pca9641_cfg_info; + io_attr = &reset_cfg->attr.io_attr; + + PCA_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA_DEBUG("io_addr:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + io_attr->io_addr, io_attr->mask, io_attr->reset_on, io_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + val = inb(io_attr->io_addr); + val &= ~(io_attr->mask); + val |= io_attr->reset_on; + outb(val, io_attr->io_addr); + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(io_attr->mask); + val |= io_attr->reset_off; + outb(val, io_attr->io_addr); + + ret = -1; + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + val = inb(io_attr->io_addr); + val &= (io_attr->mask); + if (val == io_attr->reset_off) { + ret = 0; + PCA_DEBUG("pca9641_do_io_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_do_io_reset timeout.\n"); + } + + return ret; +} + +static int pca9641_do_gpio_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout; + struct pca9541 *data; + pca9641_cfg_info_t *reset_cfg; + gpio_attr_t *gpio_attr; + u8 val; + + data = i2c_mux_priv(muxc); + reset_cfg = &data->pca9641_cfg_info; + gpio_attr = &reset_cfg->attr.gpio_attr; + + ret = pca9641_gpio_init(gpio_attr); + if (ret) { + return -1; + } + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_on); + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_off); + ret = -1; + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + val = __gpio_get_value(gpio_attr->gpio); + if (val == gpio_attr->reset_off) { + ret = 0; + PCA_DEBUG("pca9641_do_gpio_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + /* 1MS schedule*/ + schedule(); + } + timeout--; + } + + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_do_gpio_reset timeout.\n"); + } + + pca9641_gpio_free(gpio_attr); + return ret; +} + +static int pca9641_do_i2c_reset(struct i2c_mux_core *muxc) +{ + int ret, timeout, err; + struct pca9541 *data; + pca9641_cfg_info_t *reset_cfg; + i2c_attr_t *i2c_attr; + u8 val; + + data = i2c_mux_priv(muxc); + reset_cfg = &data->pca9641_cfg_info; + i2c_attr = &reset_cfg->attr.i2c_attr; + ret = -1; + + PCA_DEBUG("rst_delay_b:%u, rst_delay:%u, rst_delay_a:%u.\n", + reset_cfg->rst_delay_b, reset_cfg->rst_delay, reset_cfg->rst_delay_a); + PCA_DEBUG("bus:0x%x, addr:0x%x, reg:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + i2c_attr->i2c_bus, i2c_attr->i2c_addr, i2c_attr->reg_offset, + i2c_attr->mask, i2c_attr->reset_on, i2c_attr->reset_off); + + if (reset_cfg->rst_delay_b) { + udelay(reset_cfg->rst_delay_b); + } + + err = pca9641_reset_i2c_read(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + + val &= ~(i2c_attr->mask); + val |= i2c_attr->reset_on; + err = pca9641_reset_i2c_write(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, val); + if (err < 0) { + goto out; + } + + if (reset_cfg->rst_delay) { + udelay(reset_cfg->rst_delay); + } + + val &= ~(i2c_attr->mask); + val |= i2c_attr->reset_off; + err = pca9641_reset_i2c_write(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, val); + if (err < 0) { + goto out; + } + + timeout = reset_cfg->rst_delay_a; + while (timeout > 0) { + udelay(1); + err = pca9641_reset_i2c_read(i2c_attr->i2c_bus, i2c_attr->i2c_addr, + i2c_attr->reg_offset, &val, sizeof(val)); + if (err < 0) { + goto out; + } + val &= (i2c_attr->mask); + if (val == i2c_attr->reset_off) { + ret = 0; + PCA_DEBUG("pca9641_do_i2c_reset success.\n"); + break; + } + if (timeout >= 1000 && (timeout % 1000 == 0)) { + schedule(); + } + timeout--; + } + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_do_i2c_reset timeout.\n"); + } +out: + if (err < 0) { + PCA_DEBUG_ERR("pca9641_do_i2c_reset i2c op failed, ret:%d.\n", err); + } + return ret; +} + +static int pca9641_do_reset(struct i2c_mux_core *muxc) +{ + int ret; + struct pca9541 *data; + + data = i2c_mux_priv(muxc); + if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_NONE) { + ret = -1; + PCA_DEBUG("Don't need to reset.\n"); + } else if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_I2C) { + ret = pca9641_do_i2c_reset(muxc); + } else if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_GPIO) { + ret = pca9641_do_gpio_reset(muxc); + } else if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_IO) { + ret = pca9641_do_io_reset(muxc); + } else if (data->pca9641_cfg_info.pca9641_reset_type == PCA9641_RESET_FILE) { + ret = pca9641_do_file_reset(muxc); + } else { + ret = -1; + PCA_DEBUG_ERR("Unsupport reset type:0x%x.\n", + data->pca9641_cfg_info.pca9641_reset_type); + } + + if (ret < 0) { + PCA_DEBUG_ERR("pca9641_reset_ctrl failed, reset type:%u, ret:%d.\n", + data->pca9641_cfg_info.pca9641_reset_type, ret); + } else { + udelay(PCA9641_RESET_DELAY); + } + return ret; +} + +/* + * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock the adapter a second time. + */ +static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val) +{ + struct i2c_adapter *adap = client->adapter; + int ret; + + if (adap->algo->master_xfer) { + struct i2c_msg msg; + char buf[2]; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = 2; + buf[0] = command; + buf[1] = val; + msg.buf = buf; + ret = __i2c_transfer(adap, &msg, 1); + } else { + union i2c_smbus_data data; + + data.byte = val; + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_WRITE, + command, + I2C_SMBUS_BYTE_DATA, &data); + } + + return ret; +} + +/* + * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock adapter a second time. + */ +static int pca9541_reg_read(struct i2c_client *client, u8 command) +{ + struct i2c_adapter *adap = client->adapter; + int ret; + u8 val; + + if (adap->algo->master_xfer) { + struct i2c_msg msg[2] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &command + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = &val + } + }; + ret = __i2c_transfer(adap, msg, 2); + if (ret == 2) + ret = val; + else if (ret >= 0) + ret = -EIO; + } else { + union i2c_smbus_data data; + + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_READ, + command, + I2C_SMBUS_BYTE_DATA, &data); + if (!ret) + ret = data.byte; + } + return ret; +} + +/* + * Arbitration management functions + */ + +/* Release bus. Also reset NTESTON and BUSINIT if it was set. */ +static void pca9541_release_bus(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg >= 0 && !busoff(reg) && mybus(reg)) + pca9541_reg_write(client, PCA9541_CONTROL, + (reg & PCA9541_CTL_NBUSON) >> 1); +} + +/* + * Arbitration is defined as a two-step process. A bus master can only activate + * the slave bus if it owns it; otherwise it has to request ownership first. + * This multi-step process ensures that access contention is resolved + * gracefully. + * + * Bus Ownership Other master Action + * state requested access + * ---------------------------------------------------- + * off - yes wait for arbitration timeout or + * for other master to drop request + * off no no take ownership + * off yes no turn on bus + * on yes - done + * on no - wait for arbitration timeout or + * for other master to release bus + * + * The main contention point occurs if the slave bus is off and both masters + * request ownership at the same time. In this case, one master will turn on + * the slave bus, believing that it owns it. The other master will request + * bus ownership. Result is that the bus is turned on, and master which did + * _not_ own the slave bus before ends up owning it. + */ + +/* Control commands per PCA9541 datasheet */ +static const u8 pca9541_control[16] = { + 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1 +}; + +/* + * Channel arbitration + * + * Return values: + * <0: error + * 0 : bus not acquired + * 1 : bus acquired + */ +static int pca9541_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg < 0) + return reg; + + if (busoff(reg)) { + int istat; + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + istat = pca9541_reg_read(client, PCA9541_ISTAT); + if (!(istat & PCA9541_ISTAT_NMYTEST) + || time_is_before_eq_jiffies(data->arb_timeout)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_NTESTON); + data->select_timeout = SELECT_DELAY_SHORT; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (mybus(reg)) { + /* + * Bus is on, and we own it. We are done with acquisition. + * Reset NTESTON and BUSINIT, then return success. + */ + if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg & ~(PCA9541_CTL_NTESTON + | PCA9541_CTL_BUSINIT)); + return 1; + } else { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + data->select_timeout = SELECT_DELAY_LONG; + if (time_is_before_eq_jiffies(data->arb_timeout)) { + /* Time is up, take the bus and reset it. */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_BUSINIT + | PCA9541_CTL_NTESTON); + } else { + /* Request bus ownership if needed */ + if (!(reg & PCA9541_CTL_NTESTON)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg | PCA9541_CTL_NTESTON); + } + } + return 0; +} + +static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + + do { + ret = pca9541_arbitrate(client); + if (ret) + return ret < 0 ? ret : 0; + + if (data->select_timeout == SELECT_DELAY_SHORT) + udelay(data->select_timeout); + else + msleep(data->select_timeout / 1000); + } while (time_is_after_eq_jiffies(timeout)); + + dev_warn(&client->dev, "pca9541 select channel timeout.\n"); + return -ETIMEDOUT; +} + +static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + pca9541_release_bus(client); + return 0; +} + +/* +* Arbitration management functions +*/ +static void pca9641_release_bus(struct i2c_client *client) +{ + pca9541_reg_write(client, PCA9641_CONTROL, 0x80); //master 0x80 +} + +/* +* Channel arbitration +* +* Return values: +* <0: error +* 0 : bus not acquired +* 1 : bus acquired +*/ +static int pca9641_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg_ctl, reg_sts; + + reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); + if (reg_ctl < 0) { + PCA_DEBUG_ERR("pca9641 read control register failed, ret:%d.\n", reg_ctl); + return reg_ctl; + } + + reg_sts = pca9541_reg_read(client, PCA9641_STATUS); + if (reg_sts < 0) { + PCA_DEBUG_ERR("pca9641 read status register failed, ret:%d.\n", reg_sts); + return reg_sts; + } + + if (BUSOFF(reg_ctl, reg_sts)) { + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + reg_ctl |= PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); + if (reg_ctl < 0) { + PCA_DEBUG_ERR("Bus is off, but read control register failed, ret:%d.\n", reg_ctl); + return reg_ctl; + } + + if (lock_grant(reg_ctl)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + PCA_DEBUG("Bus is off, get pca9641 arbitration success.\n"); + reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + return 1; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + PCA_DEBUG("Bus is off, but get pca9641 arbitration failed.\n"); + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (lock_grant(reg_ctl)) { + /* + * Bus is on, and we own it. We are done with acquisition. + */ + PCA_DEBUG("Bus is on, get pca9641 arbitration success.\n"); + reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + return 1; + } else if (other_lock(reg_sts)) { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + PCA_DEBUG("Other master owns the bus, try to request it.\n"); + data->select_timeout = SELECT_DELAY_LONG; + reg_ctl |= PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + } + return 0; +} + +int pca9641_select_chan_single(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + int result; + unsigned long msleep_time; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + for (result = 0 ; result < PCA9641_RETRY_TIME ; result ++) { + do { + ret = pca9641_arbitrate(client); + if (ret) { + return ret < 0 ? -EIO : 0; + } + msleep_time = data->select_timeout / 1000; + if (msleep_time < 1) { + msleep(1); + } else { + msleep(msleep_time); + } + } while (time_is_after_eq_jiffies(timeout)); + timeout = jiffies + ARB2_TIMEOUT; + } + dev_warn(&client->dev, "pca9641 select channel timeout.\n"); + return -ETIMEDOUT; +} + +static int pca9641_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + int ret, rv; + + ret = pca9641_select_chan_single(muxc, chan); + if (ret < 0) { + PCA_DEBUG_ERR("pca9641 select channel failed, ret:%d, try to reset pca9641.\n", ret); + rv = pca9641_do_reset(muxc); + + if (rv < 0) { + PCA_DEBUG_ERR("pca9641 reset failed, rv:%d.\n", rv); + return ret; + } + + ret = pca9641_select_chan_single(muxc, chan); + if (ret < 0) { + PCA_DEBUG_ERR("after pca9641 reset, select channel still failed, ret:%d.\n", ret); + } + } + return ret; +} + +static int pca9641_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + if (pca_flag.flag) { + pca9641_release_bus(client); + } + return 0; +} + +static int pca9641_detect_id(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9641_ID); + if (reg == PCA9641_ID_MAGIC) + return 1; + else + return 0; +} + +static int pca9641_recordflag(struct i2c_adapter *adap) { + if (pca_flag.flag != -1) { + pr_err(" %s %d has init already!!!", __func__, __LINE__); + return -1 ; + } + pca_flag.nr = adap->nr; + PCA_DEBUG(" adap->nr:%d\n", adap->nr); + snprintf(pca_flag.name, sizeof(pca_flag.name),adap->name); + return 0; +} + +static int of_pca9641_reset_data_init(struct pca9541 *data) +{ + int err; + struct device *dev = &data->client->dev; + pca9641_cfg_info_t *reset_cfg; + + reset_cfg = &data->pca9641_cfg_info; + if (dev == NULL || dev->of_node == NULL) { + PCA_DEBUG("dev or dev->of_node is NUll, no reset.\n"); + reset_cfg->pca9641_reset_type = PCA9641_RESET_NONE; + return 0; + } + + if (of_property_read_u32(dev->of_node, "pca9641_reset_type", &reset_cfg->pca9641_reset_type)) { + + PCA_DEBUG("pca9641_reset_type not found, no reset.\n"); + reset_cfg->pca9641_reset_type = PCA9641_RESET_NONE; + return 0; + } + err = of_property_read_u32(dev->of_node, "rst_delay_b", &reset_cfg->rst_delay_b); + err |= of_property_read_u32(dev->of_node, "rst_delay", &reset_cfg->rst_delay); + err |= of_property_read_u32(dev->of_node, "rst_delay_a", &reset_cfg->rst_delay_a); + + if (err) { + goto dts_config_err; + } + PCA_DEBUG("reset_type:0x%x, rst_delay_b:0x%x, rst_delay:0x%x, rst_delay_a:0x%x.\n", + reset_cfg->pca9641_reset_type, reset_cfg->rst_delay_b, + reset_cfg->rst_delay, reset_cfg->rst_delay_a); + + if (reset_cfg->pca9641_reset_type == PCA9641_RESET_I2C) { + + PCA_DEBUG("reset by i2c.\n"); + err = of_property_read_u32(dev->of_node, "i2c_bus", &reset_cfg->attr.i2c_attr.i2c_bus); + err |=of_property_read_u32(dev->of_node, "i2c_addr", &reset_cfg->attr.i2c_attr.i2c_addr); + err |=of_property_read_u32(dev->of_node, "reg_offset", &reset_cfg->attr.i2c_attr.reg_offset); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.i2c_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.i2c_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.i2c_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA_DEBUG("bus:%u, addr:0x%x, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + reset_cfg->attr.i2c_attr.i2c_bus, reset_cfg->attr.i2c_attr.i2c_addr, + reset_cfg->attr.i2c_attr.reg_offset, reset_cfg->attr.i2c_attr.mask, + reset_cfg->attr.i2c_attr.reset_on, reset_cfg->attr.i2c_attr.reset_off); + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_GPIO) { + + PCA_DEBUG("reset by gpio.\n"); + err = of_property_read_u32(dev->of_node, "gpio", &reset_cfg->attr.gpio_attr.gpio); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.gpio_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.gpio_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA_DEBUG("gpio number:%u, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.gpio_attr.gpio, reset_cfg->attr.gpio_attr.reset_on, + reset_cfg->attr.gpio_attr.reset_off); + reset_cfg->attr.gpio_attr.gpio_init = 0; + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_IO) { + + PCA_DEBUG("reset by io.\n"); + err = of_property_read_u32(dev->of_node, "io_addr", &reset_cfg->attr.io_attr.io_addr); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.io_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.io_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.io_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA_DEBUG("io_addr:0x%x, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.io_attr.io_addr, reset_cfg->attr.io_attr.mask, + reset_cfg->attr.io_attr.reset_on, reset_cfg->attr.io_attr.reset_off); + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_FILE) { + + PCA_DEBUG("reset by file.\n"); + err = of_property_read_string(dev->of_node, "dev_name", &reset_cfg->attr.file_attr.dev_name); + err |=of_property_read_u32(dev->of_node, "offset", &reset_cfg->attr.file_attr.offset); + err |=of_property_read_u32(dev->of_node, "mask", &reset_cfg->attr.file_attr.mask); + err |=of_property_read_u32(dev->of_node, "reset_on", &reset_cfg->attr.file_attr.reset_on); + err |=of_property_read_u32(dev->of_node, "reset_off", &reset_cfg->attr.file_attr.reset_off); + if (err) { + goto dts_config_err; + } + PCA_DEBUG("dev_name:%s, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.file_attr.dev_name, reset_cfg->attr.file_attr.mask, + reset_cfg->attr.file_attr.reset_on, reset_cfg->attr.file_attr.reset_off); + } else { + PCA_DEBUG_ERR("Unsupport reset type:%d.\n", reset_cfg->pca9641_reset_type); + goto dts_config_err; + } + return 0; +dts_config_err: + PCA_DEBUG_ERR("dts config error, ret:%d.\n", err); + return -EINVAL; +} + +static int pca9641_reset_data_init(struct pca9541 *data) +{ + pca9641_cfg_info_t *reset_cfg; + i2c_mux_pca9641_device_t *i2c_mux_pca9641_device; + + if (data->client->dev.platform_data == NULL) { + PCA_DEBUG("pca9641 has no reset platform data config.\n"); + return 0; + } + reset_cfg = &data->pca9641_cfg_info; + i2c_mux_pca9641_device = data->client->dev.platform_data; + reset_cfg->pca9641_reset_type = i2c_mux_pca9641_device->pca9641_reset_type; + if (reset_cfg->pca9641_reset_type == PCA9641_RESET_NONE) { + PCA_DEBUG("pca9641 has no reset function.\n"); + return 0; + } + + reset_cfg->rst_delay_b = i2c_mux_pca9641_device->rst_delay_b; + reset_cfg->rst_delay = i2c_mux_pca9641_device->rst_delay; + reset_cfg->rst_delay_a = i2c_mux_pca9641_device->rst_delay_a; + PCA_DEBUG("reset_type:0x%x, rst_delay_b:0x%x, rst_delay:0x%x, rst_delay_a:0x%x.\n", + reset_cfg->pca9641_reset_type, reset_cfg->rst_delay_b, + reset_cfg->rst_delay, reset_cfg->rst_delay_a); + + if (reset_cfg->pca9641_reset_type == PCA9641_RESET_I2C) { + + PCA_DEBUG("reset by i2c.\n"); + reset_cfg->attr.i2c_attr.i2c_bus = i2c_mux_pca9641_device->attr.i2c_attr.i2c_bus; + reset_cfg->attr.i2c_attr.i2c_addr = i2c_mux_pca9641_device->attr.i2c_attr.i2c_addr; + reset_cfg->attr.i2c_attr.reg_offset = i2c_mux_pca9641_device->attr.i2c_attr.reg_offset; + reset_cfg->attr.i2c_attr.mask = i2c_mux_pca9641_device->attr.i2c_attr.mask; + reset_cfg->attr.i2c_attr.reset_on = i2c_mux_pca9641_device->attr.i2c_attr.reset_on; + reset_cfg->attr.i2c_attr.reset_off = i2c_mux_pca9641_device->attr.i2c_attr.reset_off; + PCA_DEBUG("bus:%u, addr:0x%x, offset:0x%x, mask:0x%x, on:0x%x, off:0x%x.\n", + reset_cfg->attr.i2c_attr.i2c_bus, reset_cfg->attr.i2c_attr.i2c_addr, + reset_cfg->attr.i2c_attr.reg_offset, reset_cfg->attr.i2c_attr.mask, + reset_cfg->attr.i2c_attr.reset_on, reset_cfg->attr.i2c_attr.reset_off); + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_GPIO) { + + PCA_DEBUG("reset by gpio.\n"); + reset_cfg->attr.gpio_attr.gpio = i2c_mux_pca9641_device->attr.gpio_attr.gpio; + reset_cfg->attr.gpio_attr.reset_on = i2c_mux_pca9641_device->attr.gpio_attr.reset_on; + reset_cfg->attr.gpio_attr.reset_off = i2c_mux_pca9641_device->attr.gpio_attr.reset_off; + PCA_DEBUG("gpio number:%u, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.gpio_attr.gpio, reset_cfg->attr.gpio_attr.reset_on, + reset_cfg->attr.gpio_attr.reset_off); + reset_cfg->attr.gpio_attr.gpio_init = 0; + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_IO) { + + PCA_DEBUG("reset by io.\n"); + reset_cfg->attr.io_attr.io_addr = i2c_mux_pca9641_device->attr.io_attr.io_addr; + reset_cfg->attr.io_attr.mask = i2c_mux_pca9641_device->attr.io_attr.mask; + reset_cfg->attr.io_attr.reset_on = i2c_mux_pca9641_device->attr.io_attr.reset_on; + reset_cfg->attr.io_attr.reset_off = i2c_mux_pca9641_device->attr.io_attr.reset_off; + PCA_DEBUG("io_addr:0x%x, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.io_attr.io_addr, reset_cfg->attr.io_attr.mask, + reset_cfg->attr.io_attr.reset_on, reset_cfg->attr.io_attr.reset_off); + } else if (reset_cfg->pca9641_reset_type == PCA9641_RESET_FILE) { + + PCA_DEBUG("reset by file.\n"); + reset_cfg->attr.file_attr.dev_name = i2c_mux_pca9641_device->attr.file_attr.dev_name; + reset_cfg->attr.file_attr.offset = i2c_mux_pca9641_device->attr.file_attr.offset; + reset_cfg->attr.file_attr.mask = i2c_mux_pca9641_device->attr.file_attr.mask; + reset_cfg->attr.file_attr.reset_on = i2c_mux_pca9641_device->attr.file_attr.reset_on; + reset_cfg->attr.file_attr.reset_off = i2c_mux_pca9641_device->attr.file_attr.reset_off; + PCA_DEBUG("dev_name:%s, mask:0x%x, reset_on:0x%x, reset_off:0x%x.\n", + reset_cfg->attr.file_attr.dev_name, reset_cfg->attr.file_attr.mask, + reset_cfg->attr.file_attr.reset_on, reset_cfg->attr.file_attr.reset_off); + } else { + PCA_DEBUG_ERR("Unsupport reset type:%d.\n", reset_cfg->pca9641_reset_type); + return -EINVAL; + } + return 0; +} + +/* + * I2C init/probing/exit functions + */ +static int pca9541_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = client->adapter; + struct i2c_mux_core *muxc; + struct pca9541 *data; + int force; + int ret = -ENODEV; + int detect_id; + i2c_mux_pca9641_device_t *i2c_mux_pca9641_device; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + detect_id = pca9641_detect_id(client); + + /* + * I2C accesses are unprotected here. + * We have to lock the adapter before releasing the bus. + */ + if (detect_id == 0) { + i2c_lock_bus(adap, I2C_LOCK_ROOT_ADAPTER); + pca9541_release_bus(client); + i2c_unlock_bus(adap, I2C_LOCK_ROOT_ADAPTER); + } else { + i2c_lock_bus(adap, I2C_LOCK_ROOT_ADAPTER); + pca9641_release_bus(client); + i2c_unlock_bus(adap, I2C_LOCK_ROOT_ADAPTER); + } + + if (detect_id == 0) { /* pca9541 */ + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), + I2C_MUX_ARBITRATOR, + pca9541_select_chan, pca9541_release_chan); + if (!muxc) + return -ENOMEM; + + data = i2c_mux_priv(muxc); + data->client = client; + + i2c_set_clientdata(client, muxc); + /* Create mux adapter */ + if (of_property_read_u32(client->dev.of_node, "pca9641_nr", &data->pca9641_nr)) { + + force = 0; + PCA_DEBUG("pca9641_nr not found, use dynamic adap number.\n"); + } else { + force = data->pca9641_nr; + PCA_DEBUG("pca9641_nr: %d.\n", force); + } + + ret = i2c_mux_add_adapter(muxc, force, 0, 0); + if (ret) + return ret; + } else { + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), I2C_MUX_ARBITRATOR, + pca9641_select_chan, pca9641_release_chan); + if (!muxc) { + dev_err(&client->dev, "i2c_mux_alloc failed, out of memory.\n"); + return -ENOMEM; + } + + data = i2c_mux_priv(muxc); + data->client = client; + + i2c_set_clientdata(client, muxc); + + if (client->dev.of_node) { + ret= of_pca9641_reset_data_init(data); + } else { + ret= pca9641_reset_data_init(data); + } + if (ret < 0) { + dev_err(&client->dev, "pca9641 reset config err, ret:%d.\n", ret); + return ret; + } + + if (client->dev.of_node == NULL) { + if (client->dev.platform_data == NULL) { + force = 0; + PCA_DEBUG("platform data is NULL, use dynamic adap number.\n"); + } else { + i2c_mux_pca9641_device = client->dev.platform_data; + data->pca9641_nr = i2c_mux_pca9641_device->pca9641_nr; + if (data->pca9641_nr == 0) { + force = 0; + PCA_DEBUG("pca9641_nr = 0, use dynamic adap number.\n"); + } else { + force = data->pca9641_nr; + PCA_DEBUG("pca9641_nr: %d.\n", force); + } + } + } else { + /* Create mux adapter */ + if (of_property_read_u32(client->dev.of_node, "pca9641_nr", &data->pca9641_nr)) { + + force = 0; + PCA_DEBUG("pca9641_nr not found, use dynamic adap number.\n"); + } else { + force = data->pca9641_nr; + PCA_DEBUG("pca9641_nr: %d.\n", force); + } + } + + ret = i2c_mux_add_adapter(muxc, force, 0, 0); + if (ret) { + dev_err(&client->dev, "Failed to register master selector.\n"); + return ret; + } + } + pca9641_recordflag(muxc->adapter[0]); + + dev_info(&client->dev, "registered master selector for I2C %s\n", client->name); + + return 0; +} + +static int pca9541_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + i2c_mux_del_adapters(muxc); + return 0; +} + +static struct i2c_driver pca9641_driver = { + .driver = { + .name = "wb_pca9641", + .of_match_table = of_match_ptr(pca9541_of_match), + }, + .probe = pca9541_probe, + .remove = pca9541_remove, + .id_table = pca9541_id, +}; + +module_i2c_driver(pca9641_driver); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PCA9541 I2C master selector driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.h new file mode 100644 index 000000000000..b87f7585567b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_i2c_mux_pca9641.h @@ -0,0 +1,64 @@ +#ifndef __WB_I2C_MUX_PCA9641_H__ +#define __WB_I2C_MUX_PCA9641_H__ + +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef enum pca9641_reset_type_s { + PCA9641_RESET_NONE = 0, + PCA9641_RESET_I2C = 1, + PCA9641_RESET_GPIO = 2, + PCA9641_RESET_IO = 3, + PCA9641_RESET_FILE = 4, +} pca9641_reset_type_t; + +typedef struct i2c_attr_s { + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t reg_offset; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} i2c_attr_t; + +typedef struct io_attr_s { + uint32_t io_addr; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} io_attr_t; + +typedef struct file_attr_s { + const char *dev_name; + uint32_t offset; + uint32_t mask; + uint32_t reset_on; + uint32_t reset_off; +} file_attr_t; + +typedef struct gpio_attr_s { + int gpio_init; + uint32_t gpio; + uint32_t reset_on; + uint32_t reset_off; +} gpio_attr_t; + +typedef struct i2c_mux_pca9641_device_s { + struct i2c_client *client; + uint32_t i2c_bus; + uint32_t i2c_addr; + uint32_t pca9641_nr; + uint32_t pca9641_reset_type; + uint32_t rst_delay_b; /* delay time before reset(us) */ + uint32_t rst_delay; /* reset time(us) */ + uint32_t rst_delay_a; /* delay time after reset(us) */ + union { + i2c_attr_t i2c_attr; + gpio_attr_t gpio_attr; + io_attr_t io_attr; + file_attr_t file_attr; + } attr; +} i2c_mux_pca9641_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ina3221.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ina3221.c new file mode 100644 index 000000000000..fba2c4e3a68e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ina3221.c @@ -0,0 +1,1031 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * INA3221 Triple Current/Voltage Monitor + * + * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/ + * Andrew F. Davis + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define INA3221_DRIVER_NAME "wb_ina3221" + +#define INA3221_CONFIG 0x00 +#define INA3221_SHUNT1 0x01 +#define INA3221_BUS1 0x02 +#define INA3221_SHUNT2 0x03 +#define INA3221_BUS2 0x04 +#define INA3221_SHUNT3 0x05 +#define INA3221_BUS3 0x06 +#define INA3221_CRIT1 0x07 +#define INA3221_WARN1 0x08 +#define INA3221_CRIT2 0x09 +#define INA3221_WARN2 0x0a +#define INA3221_CRIT3 0x0b +#define INA3221_WARN3 0x0c +#define INA3221_SHUNT_SUM 0x0d +#define INA3221_CRIT_SUM 0x0e +#define INA3221_MASK_ENABLE 0x0f + +#define INA3221_CONFIG_MODE_MASK GENMASK(2, 0) +#define INA3221_CONFIG_MODE_POWERDOWN 0 +#define INA3221_CONFIG_MODE_SHUNT BIT(0) +#define INA3221_CONFIG_MODE_BUS BIT(1) +#define INA3221_CONFIG_MODE_CONTINUOUS BIT(2) +#define INA3221_CONFIG_VSH_CT_SHIFT 3 +#define INA3221_CONFIG_VSH_CT_MASK GENMASK(5, 3) +#define INA3221_CONFIG_VSH_CT(x) (((x) & GENMASK(5, 3)) >> 3) +#define INA3221_CONFIG_VBUS_CT_SHIFT 6 +#define INA3221_CONFIG_VBUS_CT_MASK GENMASK(8, 6) +#define INA3221_CONFIG_VBUS_CT(x) (((x) & GENMASK(8, 6)) >> 6) +#define INA3221_CONFIG_AVG_SHIFT 9 +#define INA3221_CONFIG_AVG_MASK GENMASK(11, 9) +#define INA3221_CONFIG_AVG(x) (((x) & GENMASK(11, 9)) >> 9) +#define INA3221_CONFIG_CHs_EN_MASK GENMASK(14, 12) +#define INA3221_CONFIG_CHx_EN(x) BIT(14 - (x)) + +#define INA3221_MASK_ENABLE_SCC_MASK GENMASK(14, 12) + +#define INA3221_CONFIG_DEFAULT 0x7127 +#define INA3221_RSHUNT_DEFAULT 10000 + +enum ina3221_fields { + /* Configuration */ + F_RST, + + /* Status Flags */ + F_CVRF, + + /* Warning Flags */ + F_WF3, F_WF2, F_WF1, + + /* Alert Flags: SF is the summation-alert flag */ + F_SF, F_CF3, F_CF2, F_CF1, + + /* sentinel */ + F_MAX_FIELDS +}; + +static const struct reg_field ina3221_reg_fields[] = { + [F_RST] = REG_FIELD(INA3221_CONFIG, 15, 15), + + [F_CVRF] = REG_FIELD(INA3221_MASK_ENABLE, 0, 0), + [F_WF3] = REG_FIELD(INA3221_MASK_ENABLE, 3, 3), + [F_WF2] = REG_FIELD(INA3221_MASK_ENABLE, 4, 4), + [F_WF1] = REG_FIELD(INA3221_MASK_ENABLE, 5, 5), + [F_SF] = REG_FIELD(INA3221_MASK_ENABLE, 6, 6), + [F_CF3] = REG_FIELD(INA3221_MASK_ENABLE, 7, 7), + [F_CF2] = REG_FIELD(INA3221_MASK_ENABLE, 8, 8), + [F_CF1] = REG_FIELD(INA3221_MASK_ENABLE, 9, 9), +}; + +enum ina3221_channels { + INA3221_CHANNEL1, + INA3221_CHANNEL2, + INA3221_CHANNEL3, + INA3221_NUM_CHANNELS +}; + +/** + * struct ina3221_input - channel input source specific information + * @label: label of channel input source + * @shunt_resistor: shunt resistor value of channel input source + * @disconnected: connection status of channel input source + */ +struct ina3221_input { + const char *label; + int shunt_resistor; + bool disconnected; +}; + +/** + * struct ina3221_data - device specific information + * @pm_dev: Device pointer for pm runtime + * @regmap: Register map of the device + * @fields: Register fields of the device + * @inputs: Array of channel input source specific structures + * @lock: mutex lock to serialize sysfs attribute accesses + * @reg_config: Register value of INA3221_CONFIG + * @summation_shunt_resistor: equivalent shunt resistor value for summation + * @single_shot: running in single-shot operating mode + */ +struct ina3221_data { + struct device *pm_dev; + struct regmap *regmap; + struct regmap_field *fields[F_MAX_FIELDS]; + struct ina3221_input inputs[INA3221_NUM_CHANNELS]; + struct mutex lock; + u32 reg_config; + int summation_shunt_resistor; + + bool single_shot; +}; + +static inline bool ina3221_is_enabled(struct ina3221_data *ina, int channel) +{ + /* Summation channel checks shunt resistor values */ + if (channel > INA3221_CHANNEL3) + return ina->summation_shunt_resistor != 0; + + return pm_runtime_active(ina->pm_dev) && + (ina->reg_config & INA3221_CONFIG_CHx_EN(channel)); +} + +/** + * Helper function to return the resistor value for current summation. + * + * There is a condition to calculate current summation -- all the shunt + * resistor values should be the same, so as to simply fit the formula: + * current summation = shunt voltage summation / shunt resistor + * + * Returns the equivalent shunt resistor value on success or 0 on failure + */ +static inline int ina3221_summation_shunt_resistor(struct ina3221_data *ina) +{ + struct ina3221_input *input = ina->inputs; + int i, shunt_resistor = 0; + + for (i = 0; i < INA3221_NUM_CHANNELS; i++) { + if (input[i].disconnected || !input[i].shunt_resistor) + continue; + if (!shunt_resistor) { + /* Found the reference shunt resistor value */ + shunt_resistor = input[i].shunt_resistor; + } else { + /* No summation if resistor values are different */ + if (shunt_resistor != input[i].shunt_resistor) + return 0; + } + } + + return shunt_resistor; +} + +/* Lookup table for Bus and Shunt conversion times in usec */ +static const u16 ina3221_conv_time[] = { + 140, 204, 332, 588, 1100, 2116, 4156, 8244, +}; + +/* Lookup table for number of samples using in averaging mode */ +static const int ina3221_avg_samples[] = { + 1, 4, 16, 64, 128, 256, 512, 1024, +}; + +/* Converting update_interval in msec to conversion time in usec */ +static inline u32 ina3221_interval_ms_to_conv_time(u16 config, int interval) +{ + u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK); + u32 samples_idx = INA3221_CONFIG_AVG(config); + u32 samples = ina3221_avg_samples[samples_idx]; + + /* Bisect the result to Bus and Shunt conversion times */ + return DIV_ROUND_CLOSEST(interval * 1000 / 2, channels * samples); +} + +/* Converting CONFIG register value to update_interval in usec */ +static inline u32 ina3221_reg_to_interval_us(u16 config) +{ + u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK); + u32 vbus_ct_idx = INA3221_CONFIG_VBUS_CT(config); + u32 vsh_ct_idx = INA3221_CONFIG_VSH_CT(config); + u32 samples_idx = INA3221_CONFIG_AVG(config); + u32 samples = ina3221_avg_samples[samples_idx]; + u32 vbus_ct = ina3221_conv_time[vbus_ct_idx]; + u32 vsh_ct = ina3221_conv_time[vsh_ct_idx]; + + /* Calculate total conversion time */ + return channels * (vbus_ct + vsh_ct) * samples; +} + +static inline int ina3221_wait_for_data(struct ina3221_data *ina) +{ + u32 wait, cvrf; + + wait = ina3221_reg_to_interval_us(ina->reg_config); + + /* Polling the CVRF bit to make sure read data is ready */ + return regmap_field_read_poll_timeout(ina->fields[F_CVRF], + cvrf, cvrf, wait, wait * 2); +} + +static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg, + int *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(ina->regmap, reg, ®val); + if (ret) + return ret; + + /* + * Shunt Voltage Sum register has 14-bit value with 1-bit shift + * Other Shunt Voltage registers have 12 bits with 3-bit shift + */ + if (reg == INA3221_SHUNT_SUM) + *val = sign_extend32(regval >> 1, 14); + else + *val = sign_extend32(regval >> 3, 12); + + return 0; +} + +static const u8 ina3221_in_reg[] = { + INA3221_BUS1, + INA3221_BUS2, + INA3221_BUS3, + INA3221_SHUNT1, + INA3221_SHUNT2, + INA3221_SHUNT3, + INA3221_SHUNT_SUM, +}; + +static int ina3221_read_chip(struct device *dev, u32 attr, long *val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int regval; + + switch (attr) { + case hwmon_chip_samples: + regval = INA3221_CONFIG_AVG(ina->reg_config); + *val = ina3221_avg_samples[regval]; + return 0; + case hwmon_chip_update_interval: + /* Return in msec */ + *val = ina3221_reg_to_interval_us(ina->reg_config); + *val = DIV_ROUND_CLOSEST(*val, 1000); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int ina3221_read_in(struct device *dev, u32 attr, int channel, long *val) +{ + const bool is_shunt = channel > INA3221_CHANNEL3; + struct ina3221_data *ina = dev_get_drvdata(dev); + u8 reg = ina3221_in_reg[channel]; + int regval, ret; + + /* + * Translate shunt channel index to sensor channel index except + * the 7th channel (6 since being 0-aligned) is for summation. + */ + if (channel != 6) + channel %= INA3221_NUM_CHANNELS; + + switch (attr) { + case hwmon_in_input: + if (!ina3221_is_enabled(ina, channel)) + return -ENODATA; + + /* Write CONFIG register to trigger a single-shot measurement */ + if (ina->single_shot) + regmap_write(ina->regmap, INA3221_CONFIG, + ina->reg_config); + + ret = ina3221_wait_for_data(ina); + if (ret) + return ret; + + ret = ina3221_read_value(ina, reg, ®val); + if (ret) + return ret; + + /* + * Scale of shunt voltage (uV): LSB is 40uV + * Scale of bus voltage (mV): LSB is 8mV + */ + *val = regval * (is_shunt ? 40 : 8); + return 0; + case hwmon_in_enable: + *val = ina3221_is_enabled(ina, channel); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static const u8 ina3221_curr_reg[][INA3221_NUM_CHANNELS + 1] = { + [hwmon_curr_input] = { INA3221_SHUNT1, INA3221_SHUNT2, + INA3221_SHUNT3, INA3221_SHUNT_SUM }, + [hwmon_curr_max] = { INA3221_WARN1, INA3221_WARN2, INA3221_WARN3, 0 }, + [hwmon_curr_crit] = { INA3221_CRIT1, INA3221_CRIT2, + INA3221_CRIT3, INA3221_CRIT_SUM }, + [hwmon_curr_max_alarm] = { F_WF1, F_WF2, F_WF3, 0 }, + [hwmon_curr_crit_alarm] = { F_CF1, F_CF2, F_CF3, F_SF }, +}; + +static int ina3221_read_curr(struct device *dev, u32 attr, + int channel, long *val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + struct ina3221_input *input = ina->inputs; + u8 reg = ina3221_curr_reg[attr][channel]; + int resistance_uo, voltage_nv; + int regval, ret; + + if (channel > INA3221_CHANNEL3) + resistance_uo = ina->summation_shunt_resistor; + else + resistance_uo = input[channel].shunt_resistor; + + switch (attr) { + case hwmon_curr_input: + if (!ina3221_is_enabled(ina, channel)) + return -ENODATA; + + /* Write CONFIG register to trigger a single-shot measurement */ + if (ina->single_shot) + regmap_write(ina->regmap, INA3221_CONFIG, + ina->reg_config); + + ret = ina3221_wait_for_data(ina); + if (ret) + return ret; + + fallthrough; + case hwmon_curr_crit: + case hwmon_curr_max: + if (!resistance_uo) + return -ENODATA; + + ret = ina3221_read_value(ina, reg, ®val); + if (ret) + return ret; + + /* Scale of shunt voltage: LSB is 40uV (40000nV) */ + voltage_nv = regval * 40000; + /* Return current in mA */ + *val = DIV_ROUND_CLOSEST(voltage_nv, resistance_uo); + return 0; + case hwmon_curr_crit_alarm: + case hwmon_curr_max_alarm: + /* No actual register read if channel is disabled */ + if (!ina3221_is_enabled(ina, channel)) { + /* Return 0 for alert flags */ + *val = 0; + return 0; + } + ret = regmap_field_read(ina->fields[reg], ®val); + if (ret) + return ret; + *val = regval; + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int ina3221_write_chip(struct device *dev, u32 attr, long val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret, idx; + u32 tmp; + + switch (attr) { + case hwmon_chip_samples: + idx = find_closest(val, ina3221_avg_samples, + ARRAY_SIZE(ina3221_avg_samples)); + + tmp = (ina->reg_config & ~INA3221_CONFIG_AVG_MASK) | + (idx << INA3221_CONFIG_AVG_SHIFT); + ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp); + if (ret) + return ret; + + /* Update reg_config accordingly */ + ina->reg_config = tmp; + return 0; + case hwmon_chip_update_interval: + tmp = ina3221_interval_ms_to_conv_time(ina->reg_config, val); + idx = find_closest(tmp, ina3221_conv_time, + ARRAY_SIZE(ina3221_conv_time)); + + /* Update Bus and Shunt voltage conversion times */ + tmp = INA3221_CONFIG_VBUS_CT_MASK | INA3221_CONFIG_VSH_CT_MASK; + tmp = (ina->reg_config & ~tmp) | + (idx << INA3221_CONFIG_VBUS_CT_SHIFT) | + (idx << INA3221_CONFIG_VSH_CT_SHIFT); + ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp); + if (ret) + return ret; + + /* Update reg_config accordingly */ + ina->reg_config = tmp; + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int ina3221_write_curr(struct device *dev, u32 attr, + int channel, long val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + struct ina3221_input *input = ina->inputs; + u8 reg = ina3221_curr_reg[attr][channel]; + int resistance_uo, current_ma, voltage_uv; + int regval; + + if (channel > INA3221_CHANNEL3) + resistance_uo = ina->summation_shunt_resistor; + else + resistance_uo = input[channel].shunt_resistor; + + if (!resistance_uo) + return -EOPNOTSUPP; + + /* clamp current */ + current_ma = clamp_val(val, + INT_MIN / resistance_uo, + INT_MAX / resistance_uo); + + voltage_uv = DIV_ROUND_CLOSEST(current_ma * resistance_uo, 1000); + + /* clamp voltage */ + voltage_uv = clamp_val(voltage_uv, -163800, 163800); + + /* + * Formula to convert voltage_uv to register value: + * regval = (voltage_uv / scale) << shift + * Note: + * The scale is 40uV for all shunt voltage registers + * Shunt Voltage Sum register left-shifts 1 bit + * All other Shunt Voltage registers shift 3 bits + * Results: + * SHUNT_SUM: (1 / 40uV) << 1 = 1 / 20uV + * SHUNT[1-3]: (1 / 40uV) << 3 = 1 / 5uV + */ + if (reg == INA3221_SHUNT_SUM) + regval = DIV_ROUND_CLOSEST(voltage_uv, 20) & 0xfffe; + else + regval = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8; + + return regmap_write(ina->regmap, reg, regval); +} + +static int ina3221_write_enable(struct device *dev, int channel, bool enable) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + u16 config, mask = INA3221_CONFIG_CHx_EN(channel); + u16 config_old = ina->reg_config & mask; + u32 tmp; + int ret; + + config = enable ? mask : 0; + + /* Bypass if enable status is not being changed */ + if (config_old == config) + return 0; + + /* For enabling routine, increase refcount and resume() at first */ + if (enable) { + ret = pm_runtime_resume_and_get(ina->pm_dev); + if (ret < 0) { + dev_err(dev, "Failed to get PM runtime\n"); + return ret; + } + } + + /* Enable or disable the channel */ + tmp = (ina->reg_config & ~mask) | (config & mask); + ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp); + if (ret) + goto fail; + + /* Cache the latest config register value */ + ina->reg_config = tmp; + + /* For disabling routine, decrease refcount or suspend() at last */ + if (!enable) + pm_runtime_put_sync(ina->pm_dev); + + return 0; + +fail: + if (enable) { + dev_err(dev, "Failed to enable channel %d: error %d\n", + channel, ret); + pm_runtime_put_sync(ina->pm_dev); + } + + return ret; +} + +static int ina3221_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + mutex_lock(&ina->lock); + + switch (type) { + case hwmon_chip: + ret = ina3221_read_chip(dev, attr, val); + break; + case hwmon_in: + /* 0-align channel ID */ + ret = ina3221_read_in(dev, attr, channel - 1, val); + break; + case hwmon_curr: + ret = ina3221_read_curr(dev, attr, channel, val); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + mutex_unlock(&ina->lock); + + return ret; +} + +static int ina3221_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + mutex_lock(&ina->lock); + + switch (type) { + case hwmon_chip: + ret = ina3221_write_chip(dev, attr, val); + break; + case hwmon_in: + /* 0-align channel ID */ + ret = ina3221_write_enable(dev, channel - 1, val); + break; + case hwmon_curr: + ret = ina3221_write_curr(dev, attr, channel, val); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + mutex_unlock(&ina->lock); + + return ret; +} + +static int ina3221_read_string(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, const char **str) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int index = channel - 1; + + if (channel == 7) + *str = "sum of shunt voltages"; + else + *str = ina->inputs[index].label; + + return 0; +} + +static umode_t ina3221_is_visible(const void *drvdata, + enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct ina3221_data *ina = drvdata; + const struct ina3221_input *input = NULL; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_samples: + case hwmon_chip_update_interval: + return 0644; + default: + return 0; + } + case hwmon_in: + /* Ignore in0_ */ + if (channel == 0) + return 0; + + switch (attr) { + case hwmon_in_label: + if (channel - 1 <= INA3221_CHANNEL3) + input = &ina->inputs[channel - 1]; + else if (channel == 7) + return 0444; + /* Hide label node if label is not provided */ + return (input && input->label) ? 0444 : 0; + case hwmon_in_input: + return 0444; + case hwmon_in_enable: + return 0644; + default: + return 0; + } + case hwmon_curr: + switch (attr) { + case hwmon_curr_input: + case hwmon_curr_crit_alarm: + case hwmon_curr_max_alarm: + return 0444; + case hwmon_curr_crit: + case hwmon_curr_max: + return 0644; + default: + return 0; + } + default: + return 0; + } +} + +#define INA3221_HWMON_CURR_CONFIG (HWMON_C_INPUT | \ + HWMON_C_CRIT | HWMON_C_CRIT_ALARM | \ + HWMON_C_MAX | HWMON_C_MAX_ALARM) + +static const struct hwmon_channel_info *ina3221_info[] = { + HWMON_CHANNEL_INFO(chip, + HWMON_C_SAMPLES, + HWMON_C_UPDATE_INTERVAL), + HWMON_CHANNEL_INFO(in, + /* 0: dummy, skipped in is_visible */ + HWMON_I_INPUT, + /* 1-3: input voltage Channels */ + HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL, + HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL, + HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL, + /* 4-6: shunt voltage Channels */ + HWMON_I_INPUT, + HWMON_I_INPUT, + HWMON_I_INPUT, + /* 7: summation of shunt voltage channels */ + HWMON_I_INPUT | HWMON_I_LABEL), + HWMON_CHANNEL_INFO(curr, + /* 1-3: current channels*/ + INA3221_HWMON_CURR_CONFIG, + INA3221_HWMON_CURR_CONFIG, + INA3221_HWMON_CURR_CONFIG, + /* 4: summation of current channels */ + HWMON_C_INPUT | HWMON_C_CRIT | HWMON_C_CRIT_ALARM), + NULL +}; + +static const struct hwmon_ops ina3221_hwmon_ops = { + .is_visible = ina3221_is_visible, + .read_string = ina3221_read_string, + .read = ina3221_read, + .write = ina3221_write, +}; + +static const struct hwmon_chip_info ina3221_chip_info = { + .ops = &ina3221_hwmon_ops, + .info = ina3221_info, +}; + +/* Extra attribute groups */ +static ssize_t ina3221_shunt_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int channel = sd_attr->index; + struct ina3221_input *input = &ina->inputs[channel]; + + return snprintf(buf, PAGE_SIZE, "%d\n", input->shunt_resistor); +} + +static ssize_t ina3221_shunt_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int channel = sd_attr->index; + struct ina3221_input *input = &ina->inputs[channel]; + int val; + int ret; + + ret = kstrtoint(buf, 0, &val); + if (ret) + return ret; + + val = clamp_val(val, 1, INT_MAX); + + input->shunt_resistor = val; + + /* Update summation_shunt_resistor for summation channel */ + ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina); + + return count; +} + +/* shunt resistance */ +static SENSOR_DEVICE_ATTR_RW(shunt1_resistor, ina3221_shunt, INA3221_CHANNEL1); +static SENSOR_DEVICE_ATTR_RW(shunt2_resistor, ina3221_shunt, INA3221_CHANNEL2); +static SENSOR_DEVICE_ATTR_RW(shunt3_resistor, ina3221_shunt, INA3221_CHANNEL3); + +static struct attribute *ina3221_attrs[] = { + &sensor_dev_attr_shunt1_resistor.dev_attr.attr, + &sensor_dev_attr_shunt2_resistor.dev_attr.attr, + &sensor_dev_attr_shunt3_resistor.dev_attr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(ina3221); + +static const struct regmap_range ina3221_yes_ranges[] = { + regmap_reg_range(INA3221_CONFIG, INA3221_BUS3), + regmap_reg_range(INA3221_SHUNT_SUM, INA3221_SHUNT_SUM), + regmap_reg_range(INA3221_MASK_ENABLE, INA3221_MASK_ENABLE), +}; + +static const struct regmap_access_table ina3221_volatile_table = { + .yes_ranges = ina3221_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(ina3221_yes_ranges), +}; + +static const struct regmap_config ina3221_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + + .cache_type = REGCACHE_RBTREE, + .volatile_table = &ina3221_volatile_table, +}; + +static int ina3221_probe_child_from_dt(struct device *dev, + struct device_node *child, + struct ina3221_data *ina) +{ + struct ina3221_input *input; + u32 val; + int ret; + + ret = of_property_read_u32(child, "reg", &val); + if (ret) { + dev_err(dev, "missing reg property of %pOFn\n", child); + return ret; + } else if (val > INA3221_CHANNEL3) { + dev_err(dev, "invalid reg %d of %pOFn\n", val, child); + return ret; + } + + input = &ina->inputs[val]; + + /* Log the disconnected channel input */ + if (!of_device_is_available(child)) { + input->disconnected = true; + return 0; + } + + /* Save the connected input label if available */ + of_property_read_string(child, "label", &input->label); + + /* Overwrite default shunt resistor value optionally */ + if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", &val)) { + if (val < 1 || val > INT_MAX) { + dev_err(dev, "invalid shunt resistor value %u of %pOFn\n", + val, child); + return -EINVAL; + } + input->shunt_resistor = val; + } + + return 0; +} + +static int ina3221_probe_from_dt(struct device *dev, struct ina3221_data *ina) +{ + const struct device_node *np = dev->of_node; + struct device_node *child; + int ret; + + /* Compatible with non-DT platforms */ + if (!np) + return 0; + + ina->single_shot = of_property_read_bool(np, "ti,single-shot"); + + for_each_child_of_node(np, child) { + ret = ina3221_probe_child_from_dt(dev, child, ina); + if (ret) { + of_node_put(child); + return ret; + } + } + + return 0; +} + +static int ina3221_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct ina3221_data *ina; + struct device *hwmon_dev; + int i, ret; + + ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL); + if (!ina) + return -ENOMEM; + + ina->regmap = devm_regmap_init_i2c(client, &ina3221_regmap_config); + if (IS_ERR(ina->regmap)) { + dev_err(dev, "Unable to allocate register map\n"); + return PTR_ERR(ina->regmap); + } + + for (i = 0; i < F_MAX_FIELDS; i++) { + ina->fields[i] = devm_regmap_field_alloc(dev, + ina->regmap, + ina3221_reg_fields[i]); + if (IS_ERR(ina->fields[i])) { + dev_err(dev, "Unable to allocate regmap fields\n"); + return PTR_ERR(ina->fields[i]); + } + } + + for (i = 0; i < INA3221_NUM_CHANNELS; i++) + ina->inputs[i].shunt_resistor = INA3221_RSHUNT_DEFAULT; + + ret = ina3221_probe_from_dt(dev, ina); + if (ret) { + dev_err(dev, "Unable to probe from device tree\n"); + return ret; + } + + /* The driver will be reset, so use reset value */ + ina->reg_config = INA3221_CONFIG_DEFAULT; + + /* Clear continuous bit to use single-shot mode */ + if (ina->single_shot) + ina->reg_config &= ~INA3221_CONFIG_MODE_CONTINUOUS; + + /* Disable channels if their inputs are disconnected */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) { + if (ina->inputs[i].disconnected) + ina->reg_config &= ~INA3221_CONFIG_CHx_EN(i); + } + + /* Initialize summation_shunt_resistor for summation channel control */ + ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina); + + ina->pm_dev = dev; + mutex_init(&ina->lock); + dev_set_drvdata(dev, ina); + + /* Enable PM runtime -- status is suspended by default */ + pm_runtime_enable(ina->pm_dev); + + /* Initialize (resume) the device */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) { + if (ina->inputs[i].disconnected) + continue; + /* Match the refcount with number of enabled channels */ + ret = pm_runtime_get_sync(ina->pm_dev); + if (ret < 0) + goto fail; + } + + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, ina, + &ina3221_chip_info, + ina3221_groups); + if (IS_ERR(hwmon_dev)) { + dev_err(dev, "Unable to register hwmon device\n"); + ret = PTR_ERR(hwmon_dev); + goto fail; + } + + return 0; + +fail: + pm_runtime_disable(ina->pm_dev); + pm_runtime_set_suspended(ina->pm_dev); + /* pm_runtime_put_noidle() will decrease the PM refcount until 0 */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) + pm_runtime_put_noidle(ina->pm_dev); + mutex_destroy(&ina->lock); + + return ret; +} + +static int ina3221_remove(struct i2c_client *client) +{ + struct ina3221_data *ina = dev_get_drvdata(&client->dev); + int i; + + pm_runtime_disable(ina->pm_dev); + pm_runtime_set_suspended(ina->pm_dev); + + /* pm_runtime_put_noidle() will decrease the PM refcount until 0 */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) + pm_runtime_put_noidle(ina->pm_dev); + + mutex_destroy(&ina->lock); + + return 0; +} + +static int __maybe_unused ina3221_suspend(struct device *dev) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + /* Save config register value and enable cache-only */ + ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); + if (ret) + return ret; + + /* Set to power-down mode for power saving */ + ret = regmap_update_bits(ina->regmap, INA3221_CONFIG, + INA3221_CONFIG_MODE_MASK, + INA3221_CONFIG_MODE_POWERDOWN); + if (ret) + return ret; + + regcache_cache_only(ina->regmap, true); + regcache_mark_dirty(ina->regmap); + + return 0; +} + +static int __maybe_unused ina3221_resume(struct device *dev) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + regcache_cache_only(ina->regmap, false); + + /* Software reset the chip */ + ret = regmap_field_write(ina->fields[F_RST], true); + if (ret) { + dev_err(dev, "Unable to reset device\n"); + return ret; + } + + /* Restore cached register values to hardware */ + ret = regcache_sync(ina->regmap); + if (ret) + return ret; + + /* Restore config register value to hardware */ + ret = regmap_write(ina->regmap, INA3221_CONFIG, ina->reg_config); + if (ret) + return ret; + + /* Initialize summation channel control */ + if (ina->summation_shunt_resistor) { + /* + * Take all three channels into summation by default + * Shunt measurements of disconnected channels should + * be 0, so it does not matter for summation. + */ + ret = regmap_update_bits(ina->regmap, INA3221_MASK_ENABLE, + INA3221_MASK_ENABLE_SCC_MASK, + INA3221_MASK_ENABLE_SCC_MASK); + if (ret) { + dev_err(dev, "Unable to control summation channel\n"); + return ret; + } + } + + return 0; +} + +static const struct dev_pm_ops ina3221_pm = { + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(ina3221_suspend, ina3221_resume, NULL) +}; + +static const struct of_device_id ina3221_of_match_table[] = { + { .compatible = "ti,wb_ina3221", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ina3221_of_match_table); + +static const struct i2c_device_id ina3221_ids[] = { + { "wb_ina3221", 0 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(i2c, ina3221_ids); + +static struct i2c_driver ina3221_i2c_driver = { + .probe_new = ina3221_probe, + .remove = ina3221_remove, + .driver = { + .name = INA3221_DRIVER_NAME, + .of_match_table = ina3221_of_match_table, + .pm = &ina3221_pm, + }, + .id_table = ina3221_ids, +}; +module_i2c_driver(ina3221_i2c_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Texas Instruments INA3221 HWMon Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_isl68137.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_isl68137.c new file mode 100644 index 000000000000..2797a831bd66 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_isl68137.c @@ -0,0 +1,572 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Hardware monitoring driver for Renesas Digital Multiphase Voltage Regulators + * + * Copyright (c) 2017 Google Inc + * Copyright (c) 2020 Renesas Electronics America + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_pmbus.h" + +#define ISL68137_VOUT_AVS (0x30) +#define RAA_DMPVR2_READ_VMON (0xc8) +#define WRITE_PROTECT_CLOSE (0x00) +#define WRITE_PROTECT_OPEN (0x40) + +static int g_wb_isl68137_debug = 0; +static int g_wb_isl68137_error = 0; + +module_param(g_wb_isl68137_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_isl68137_error, int, S_IRUGO | S_IWUSR); + +#define WB_ISL68137_VERBOSE(fmt, args...) do { \ + if (g_wb_isl68137_debug) { \ + printk(KERN_INFO "[WB_ISL68137][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_ISL68137_ERROR(fmt, args...) do { \ + if (g_wb_isl68137_error) { \ + printk(KERN_ERR "[WB_ISL68137][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +enum chips { + isl68137, + isl68220, + isl68221, + isl68222, + isl68223, + isl68224, + isl68225, + isl68226, + isl68227, + isl68229, + isl68233, + isl68239, + isl69222, + isl69223, + isl69224, + isl69225, + isl69227, + isl69228, + isl69234, + isl69236, + isl69239, + isl69242, + isl69243, + isl69247, + isl69248, + isl69254, + isl69255, + isl69256, + isl69259, + isl69260, + isl69268, + isl69269, + isl69298, + raa228000, + raa228004, + raa228006, + raa228228, + raa229001, + raa229004, +}; + +enum variants { + raa_dmpvr1_2rail, + raa_dmpvr2_1rail, + raa_dmpvr2_2rail, + raa_dmpvr2_2rail_nontc, + raa_dmpvr2_3rail, + raa_dmpvr2_hv, +}; + +static const struct i2c_device_id raa_dmpvr_id[]; + +static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client, + int page, + char *buf) +{ + int val = wb_pmbus_read_byte_data(client, page, PMBUS_OPERATION); + + return sprintf(buf, "%d\n", + (val & ISL68137_VOUT_AVS) == ISL68137_VOUT_AVS ? 1 : 0); +} + +static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client, + int page, + const char *buf, size_t count) +{ + int rc, op_val; + bool result; + + rc = kstrtobool(buf, &result); + if (rc) + return rc; + + op_val = result ? ISL68137_VOUT_AVS : 0; + + /* + * Writes to VOUT setpoint over AVSBus will persist after the VRM is + * switched to PMBus control. Switching back to AVSBus control + * restores this persisted setpoint rather than re-initializing to + * PMBus VOUT_COMMAND. Writing VOUT_COMMAND first over PMBus before + * enabling AVS control is the workaround. + */ + if (op_val == ISL68137_VOUT_AVS) { + rc = wb_pmbus_read_word_data(client, page, 0xff, + PMBUS_VOUT_COMMAND); + if (rc < 0) + return rc; + + rc = wb_pmbus_write_word_data(client, page, PMBUS_VOUT_COMMAND, + rc); + if (rc < 0) + return rc; + } + + rc = wb_pmbus_update_byte_data(client, page, PMBUS_OPERATION, + ISL68137_VOUT_AVS, op_val); + + return (rc < 0) ? rc : count; +} + +static ssize_t isl68137_avs_enable_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + + return isl68137_avs_enable_show_page(client, attr->index, buf); +} + +static ssize_t isl68137_avs_enable_store(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + + return isl68137_avs_enable_store_page(client, attr->index, buf, count); +} + +static ssize_t isl68137_avs_vout_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + int ret, vout_cmd, vout; + + mutex_lock(&data->update_lock); + vout_cmd = wb_pmbus_read_word_data(client, attr->index, 0xff, PMBUS_VOUT_COMMAND); + if (vout_cmd < 0) { + WB_ISL68137_ERROR("%d-%04x: read page%d vout command reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, attr->index, PMBUS_VOUT_COMMAND, ret); + mutex_unlock(&data->update_lock); + return vout_cmd; + } + vout = vout_cmd * 1000; + WB_ISL68137_VERBOSE("%d-%04x: page%d, vout: %d, vout_cmd: 0x%x\n", client->adapter->nr, + client->addr, attr->index, vout, vout_cmd); + mutex_unlock(&data->update_lock); + return snprintf(buf, PAGE_SIZE, "%d\n", vout); +} + +static ssize_t isl68137_avs_vout_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + int vout, vout_max, vout_min; + int ret, vout_cmd, vout_cmd_set; + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + ret = kstrtoint(buf, 0, &vout); + if (ret) { + WB_ISL68137_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + + vout_max = data->vout_max[attr->index]; + vout_min = data->vout_min[attr->index]; + if ((vout > vout_max) || (vout < vout_min)) { + WB_ISL68137_ERROR("%d-%04x: vout value: %d, out of range [%d, %d] \n", client->adapter->nr, + client->addr, vout, vout_min, vout_max); + return -EINVAL; + } + + /* calc VOUT_COMMAND set value */ + vout_cmd_set = vout / 1000; + if (vout_cmd_set > 0xffff) { + WB_ISL68137_ERROR("%d-%04x: invalid value, vout %d, vout_cmd_set: 0x%x\n", + client->adapter->nr, client->addr, vout, vout_cmd_set); + return -EINVAL; + } + + mutex_lock(&data->update_lock); + + /* close write protect */ + ret = wb_pmbus_write_byte_data(client, attr->index, PMBUS_WRITE_PROTECT, WRITE_PROTECT_CLOSE); + if (ret < 0) { + WB_ISL68137_ERROR("%d-%04x: close page%d write protect failed, ret: %d\n", client->adapter->nr, + client->addr, attr->index, ret); + mutex_unlock(&data->update_lock); + return ret; + } + + /* set VOUT_COMMAND */ + ret = wb_pmbus_write_word_data(client, attr->index, PMBUS_VOUT_COMMAND, vout_cmd_set); + if (ret < 0) { + WB_ISL68137_ERROR("%d-%04x: set page%d vout cmd reg: 0x%x, value: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, attr->index, PMBUS_VOUT_COMMAND, vout_cmd_set, ret); + goto error; + } + + /* read back VOUT_COMMAND */ + vout_cmd = wb_pmbus_read_word_data(client, attr->index, 0xff, PMBUS_VOUT_COMMAND); + if (vout_cmd < 0) { + ret = vout_cmd; + WB_ISL68137_ERROR("%d-%04x: read page%d vout command reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, attr->index, PMBUS_VOUT_COMMAND, ret); + goto error; + } + + /* compare vout_cmd and vout_cmd_set */ + if (vout_cmd != vout_cmd_set) { + ret = -EIO; + WB_ISL68137_ERROR("%d-%04x: vout cmd value check error, vout cmd read: 0x%x, vout cmd set: 0x%x\n", + client->adapter->nr, client->addr, vout_cmd, vout_cmd_set); + goto error; + } + + /* open write protect */ + wb_pmbus_write_byte_data(client, attr->index, PMBUS_WRITE_PROTECT, WRITE_PROTECT_OPEN); + mutex_unlock(&data->update_lock); + WB_ISL68137_VERBOSE("%d-%04x: set page%d vout cmd success, vout %d, vout_cmd_set: 0x%x\n", + client->adapter->nr, client->addr, attr->index, vout, vout_cmd_set); + return count; +error: + wb_pmbus_write_byte_data(client, attr->index, PMBUS_WRITE_PROTECT, WRITE_PROTECT_OPEN); + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t isl68137_avs_vout_max_store(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + int ret, vout_threshold; + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + ret = kstrtoint(buf, 0, &vout_threshold); + if (ret) { + WB_ISL68137_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + + WB_ISL68137_VERBOSE("%d-%04x: vout%d max threshold: %d", client->adapter->nr, client->addr, + attr->index, vout_threshold); + + data->vout_max[attr->index] = vout_threshold; + return count; +} + +static ssize_t isl68137_avs_vout_max_show(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + return snprintf(buf, PAGE_SIZE, "%d\n", data->vout_max[attr->index]); +} + +static ssize_t isl68137_avs_vout_min_store(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + int ret, vout_threshold; + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + ret = kstrtoint(buf, 0, &vout_threshold); + if (ret) { + WB_ISL68137_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + + WB_ISL68137_VERBOSE("%d-%04x: vout%d min threshold: %d", client->adapter->nr, client->addr, + attr->index, vout_threshold); + + data->vout_min[attr->index] = vout_threshold; + return count; +} + +static ssize_t isl68137_avs_vout_min_show(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + + if ((attr->index < 0) || (attr->index >= PMBUS_PAGES)) { + WB_ISL68137_ERROR("%d-%04x: invalid index: %d \n", client->adapter->nr, client->addr, + attr->index); + return -EINVAL; + } + + return snprintf(buf, PAGE_SIZE, "%d\n", data->vout_min[attr->index]); +} + +static SENSOR_DEVICE_ATTR_RW(avs0_enable, isl68137_avs_enable, 0); +static SENSOR_DEVICE_ATTR_RW(avs1_enable, isl68137_avs_enable, 1); + +static SENSOR_DEVICE_ATTR_RW(avs0_vout, isl68137_avs_vout, 0); +static SENSOR_DEVICE_ATTR_RW(avs1_vout, isl68137_avs_vout, 1); +static SENSOR_DEVICE_ATTR_RW(avs0_vout_max, isl68137_avs_vout_max, 0); +static SENSOR_DEVICE_ATTR_RW(avs0_vout_min, isl68137_avs_vout_min, 0); +static SENSOR_DEVICE_ATTR_RW(avs1_vout_max, isl68137_avs_vout_max, 1); +static SENSOR_DEVICE_ATTR_RW(avs1_vout_min, isl68137_avs_vout_min, 1); + +static struct attribute *enable_attrs[] = { + &sensor_dev_attr_avs0_enable.dev_attr.attr, + &sensor_dev_attr_avs1_enable.dev_attr.attr, + NULL, +}; + +static struct attribute *avs_ctrl_attrs[] = { + &sensor_dev_attr_avs0_vout.dev_attr.attr, + &sensor_dev_attr_avs1_vout.dev_attr.attr, + &sensor_dev_attr_avs0_vout_max.dev_attr.attr, + &sensor_dev_attr_avs0_vout_min.dev_attr.attr, + &sensor_dev_attr_avs1_vout_max.dev_attr.attr, + &sensor_dev_attr_avs1_vout_min.dev_attr.attr, + NULL, +}; + +static const struct attribute_group enable_group = { + .attrs = enable_attrs, +}; + +static const struct attribute_group avs_ctrl_group = { + .attrs = avs_ctrl_attrs, +}; + +static const struct attribute_group *isl68137_attribute_groups[] = { + &enable_group, + &avs_ctrl_group, + NULL, +}; + +static int raa_dmpvr2_read_word_data(struct i2c_client *client, int page, + int phase, int reg) +{ + int ret; + + switch (reg) { + case PMBUS_VIRT_READ_VMON: + ret = wb_pmbus_read_word_data(client, page, phase, + RAA_DMPVR2_READ_VMON); + break; + default: + ret = -ENODATA; + break; + } + + return ret; +} + +static struct pmbus_driver_info raa_dmpvr_info = { + .pages = 3, + .format[PSC_VOLTAGE_IN] = direct, + .format[PSC_VOLTAGE_OUT] = direct, + .format[PSC_CURRENT_IN] = direct, + .format[PSC_CURRENT_OUT] = direct, + .format[PSC_POWER] = direct, + .format[PSC_TEMPERATURE] = direct, + .m[PSC_VOLTAGE_IN] = 1, + .b[PSC_VOLTAGE_IN] = 0, + .R[PSC_VOLTAGE_IN] = 2, + .m[PSC_VOLTAGE_OUT] = 1, + .b[PSC_VOLTAGE_OUT] = 0, + .R[PSC_VOLTAGE_OUT] = 3, + .m[PSC_CURRENT_IN] = 1, + .b[PSC_CURRENT_IN] = 0, + .R[PSC_CURRENT_IN] = 2, + .m[PSC_CURRENT_OUT] = 1, + .b[PSC_CURRENT_OUT] = 0, + .R[PSC_CURRENT_OUT] = 1, + .m[PSC_POWER] = 1, + .b[PSC_POWER] = 0, + .R[PSC_POWER] = 0, + .m[PSC_TEMPERATURE] = 1, + .b[PSC_TEMPERATURE] = 0, + .R[PSC_TEMPERATURE] = 0, + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN + | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT + | PMBUS_HAVE_VMON, + .func[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT + | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT + | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, + .func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT + | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT + | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, +}; + +static int isl68137_probe(struct i2c_client *client) +{ + struct pmbus_driver_info *info; + + info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + memcpy(info, &raa_dmpvr_info, sizeof(*info)); + + switch (i2c_match_id(raa_dmpvr_id, client)->driver_data) { + case raa_dmpvr1_2rail: + info->pages = 2; + info->R[PSC_VOLTAGE_IN] = 3; + info->func[0] &= ~PMBUS_HAVE_VMON; + info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT + | PMBUS_HAVE_POUT; + info->groups = isl68137_attribute_groups; + break; + case raa_dmpvr2_1rail: + info->pages = 1; + info->read_word_data = raa_dmpvr2_read_word_data; + break; + case raa_dmpvr2_2rail_nontc: + info->func[0] &= ~PMBUS_HAVE_TEMP3; + info->func[1] &= ~PMBUS_HAVE_TEMP3; + fallthrough; + case raa_dmpvr2_2rail: + info->pages = 2; + info->read_word_data = raa_dmpvr2_read_word_data; + break; + case raa_dmpvr2_3rail: + info->read_word_data = raa_dmpvr2_read_word_data; + break; + case raa_dmpvr2_hv: + info->pages = 1; + info->R[PSC_VOLTAGE_IN] = 1; + info->m[PSC_VOLTAGE_OUT] = 2; + info->R[PSC_VOLTAGE_OUT] = 2; + info->m[PSC_CURRENT_IN] = 2; + info->m[PSC_POWER] = 2; + info->R[PSC_POWER] = -1; + info->read_word_data = raa_dmpvr2_read_word_data; + break; + default: + return -ENODEV; + } + + return wb_pmbus_do_probe(client, info); +} + +static const struct i2c_device_id raa_dmpvr_id[] = { + {"wb_isl68127", raa_dmpvr1_2rail}, + {"wb_isl68137", raa_dmpvr1_2rail}, + {"wb_isl68220", raa_dmpvr2_2rail}, + {"wb_isl68221", raa_dmpvr2_3rail}, + {"wb_isl68222", raa_dmpvr2_2rail}, + {"wb_isl68223", raa_dmpvr2_2rail}, + {"wb_isl68224", raa_dmpvr2_3rail}, + {"wb_isl68225", raa_dmpvr2_2rail}, + {"wb_isl68226", raa_dmpvr2_3rail}, + {"wb_isl68227", raa_dmpvr2_1rail}, + {"wb_isl68229", raa_dmpvr2_3rail}, + {"wb_isl68233", raa_dmpvr2_2rail}, + {"wb_isl68239", raa_dmpvr2_3rail}, + + {"wb_isl69222", raa_dmpvr2_2rail}, + {"wb_isl69223", raa_dmpvr2_3rail}, + {"wb_isl69224", raa_dmpvr2_2rail}, + {"wb_isl69225", raa_dmpvr2_2rail}, + {"wb_isl69227", raa_dmpvr2_3rail}, + {"wb_isl69228", raa_dmpvr2_3rail}, + {"wb_isl69234", raa_dmpvr2_2rail}, + {"wb_isl69236", raa_dmpvr2_2rail}, + {"wb_isl69239", raa_dmpvr2_3rail}, + {"wb_isl69242", raa_dmpvr2_2rail}, + {"wb_isl69243", raa_dmpvr2_1rail}, + {"wb_isl69247", raa_dmpvr2_2rail}, + {"wb_isl69248", raa_dmpvr2_2rail}, + {"wb_isl69254", raa_dmpvr2_2rail}, + {"wb_isl69255", raa_dmpvr2_2rail}, + {"wb_isl69256", raa_dmpvr2_2rail}, + {"wb_isl69259", raa_dmpvr2_2rail}, + {"wb_isl69260", raa_dmpvr2_2rail}, + {"wb_isl69268", raa_dmpvr2_2rail}, + {"wb_isl69269", raa_dmpvr2_3rail}, + {"wb_isl69298", raa_dmpvr2_2rail}, + + {"wb_raa228000", raa_dmpvr2_hv}, + {"wb_raa228004", raa_dmpvr2_hv}, + {"wb_raa228006", raa_dmpvr2_hv}, + {"wb_raa228228", raa_dmpvr2_2rail_nontc}, + {"wb_raa229001", raa_dmpvr2_2rail}, + {"wb_raa229004", raa_dmpvr2_2rail}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, raa_dmpvr_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver isl68137_driver = { + .driver = { + .name = "wb_isl68137", + }, + .probe_new = isl68137_probe, + .remove = wb_pmbus_do_remove, + .id_table = raa_dmpvr_id, +}; + +module_i2c_driver(isl68137_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PMBus driver for Renesas digital multiphase voltage regulators"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.c new file mode 100644 index 000000000000..b8291c553688 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.c @@ -0,0 +1,987 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * lm75.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998, 1999 Frodo Looijaard + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_lm75.h" + +/* + * This driver handles the LM75 and compatible digital temperature sensors. + */ + +enum lm75_type { /* keep sorted in alphabetical order */ + adt75, + ds1775, + ds75, + ds7505, + g751, + lm75, + lm75a, + lm75b, + max6625, + max6626, + max31725, + mcp980x, + pct2075, + stds75, + stlm75, + tcn75, + tmp100, + tmp101, + tmp105, + tmp112, + tmp175, + tmp275, + tmp75, + tmp75b, + tmp75c, +}; + +/** + * struct lm75_params - lm75 configuration parameters. + * @set_mask: Bits to set in configuration register when configuring + * the chip. + * @clr_mask: Bits to clear in configuration register when configuring + * the chip. + * @default_resolution: Default number of bits to represent the temperature + * value. + * @resolution_limits: Limit register resolution. Optional. Should be set if + * the resolution of limit registers does not match the + * resolution of the temperature register. + * @resolutions: List of resolutions associated with sample times. + * Optional. Should be set if num_sample_times is larger + * than 1, and if the resolution changes with sample times. + * If set, number of entries must match num_sample_times. + * @default_sample_time:Sample time to be set by default. + * @num_sample_times: Number of possible sample times to be set. Optional. + * Should be set if the number of sample times is larger + * than one. + * @sample_times: All the possible sample times to be set. Mandatory if + * num_sample_times is larger than 1. If set, number of + * entries must match num_sample_times. + */ + +struct lm75_params { + u8 set_mask; + u8 clr_mask; + u8 default_resolution; + u8 resolution_limits; + const u8 *resolutions; + unsigned int default_sample_time; + u8 num_sample_times; + const unsigned int *sample_times; +}; +#if 0 +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; +#endif +/* The LM75 registers */ +#define LM75_REG_TEMP 0x00 +#define LM75_REG_CONF 0x01 +#define LM75_REG_HYST 0x02 +#define LM75_REG_MAX 0x03 +#define PCT2075_REG_IDLE 0x04 +#define LM75_TEMP_INVALID_RETRY_TIMES (3) + +/* Each client has this additional data */ +struct lm75_data { + struct i2c_client *client; + struct regmap *regmap; + struct regulator *vs; + u8 orig_conf; + u8 current_conf; + u8 resolution; /* In bits, 9 to 16 */ + unsigned int sample_time; /* In ms */ + enum lm75_type kind; + const struct lm75_params *params; +}; + +/*-----------------------------------------------------------------------*/ + +static const u8 lm75_sample_set_masks[] = { 0 << 5, 1 << 5, 2 << 5, 3 << 5 }; + +#define LM75_SAMPLE_CLEAR_MASK (3 << 5) + +/* The structure below stores the configuration values of the supported devices. + * In case of being supported multiple configurations, the default one must + * always be the first element of the array + */ +static const struct lm75_params device_params[] = { + [adt75] = { + .clr_mask = 1 << 5, /* not one-shot mode */ + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [ds1775] = { + .clr_mask = 3 << 5, + .set_mask = 2 << 5, /* 11-bit mode */ + .default_resolution = 11, + .default_sample_time = 500, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 125, 250, 500, 1000 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [ds75] = { + .clr_mask = 3 << 5, + .set_mask = 2 << 5, /* 11-bit mode */ + .default_resolution = 11, + .default_sample_time = 600, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 150, 300, 600, 1200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [stds75] = { + .clr_mask = 3 << 5, + .set_mask = 2 << 5, /* 11-bit mode */ + .default_resolution = 11, + .default_sample_time = 600, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 150, 300, 600, 1200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [stlm75] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 6, + }, + [ds7505] = { + .set_mask = 3 << 5, /* 12-bit mode*/ + .default_resolution = 12, + .default_sample_time = 200, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 25, 50, 100, 200 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [g751] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [lm75] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [lm75a] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [lm75b] = { + .default_resolution = 11, + .default_sample_time = MSEC_PER_SEC / 10, + }, + [max6625] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 7, + }, + [max6626] = { + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 7, + .resolution_limits = 9, + }, + [max31725] = { + .default_resolution = 16, + .default_sample_time = MSEC_PER_SEC / 20, + }, + [tcn75] = { + .default_resolution = 9, + .default_sample_time = MSEC_PER_SEC / 18, + }, + [pct2075] = { + .default_resolution = 11, + .default_sample_time = MSEC_PER_SEC / 10, + .num_sample_times = 31, + .sample_times = (unsigned int []){ 100, 200, 300, 400, 500, 600, + 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, + 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, + 2800, 2900, 3000, 3100 }, + }, + [mcp980x] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode */ + .default_resolution = 12, + .resolution_limits = 9, + .default_sample_time = 240, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 30, 60, 120, 240 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp100] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode */ + .default_resolution = 12, + .default_sample_time = 320, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 40, 80, 160, 320 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp101] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode */ + .default_resolution = 12, + .default_sample_time = 320, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 40, 80, 160, 320 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp105] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp112] = { + .set_mask = 3 << 5, /* 8 samples / second */ + .clr_mask = 1 << 7, /* no one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 125, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 125, 250, 1000, 4000 }, + }, + [tmp175] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp275] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp75] = { + .set_mask = 3 << 5, /* 12-bit mode */ + .clr_mask = 1 << 7, /* not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = 220, + .num_sample_times = 4, + .sample_times = (unsigned int []){ 28, 55, 110, 220 }, + .resolutions = (u8 []) {9, 10, 11, 12 }, + }, + [tmp75b] = { /* not one-shot mode, Conversion rate 37Hz */ + .clr_mask = 1 << 7 | 3 << 5, + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 37, + .sample_times = (unsigned int []){ MSEC_PER_SEC / 37, + MSEC_PER_SEC / 18, + MSEC_PER_SEC / 9, MSEC_PER_SEC / 4 }, + .num_sample_times = 4, + }, + [tmp75c] = { + .clr_mask = 1 << 5, /*not one-shot mode*/ + .default_resolution = 12, + .default_sample_time = MSEC_PER_SEC / 12, + } +}; + +/* input temp threshold check */ +typedef struct lm75_temp_threshold_s { + int chip_type; + int temp_max; + int temp_min; +} lm75_temp_threshold_t; + +static lm75_temp_threshold_t g_lm75_temp_threshold_info[] = { + { + .chip_type = lm75, + .temp_max = 125000, + .temp_min = -55000, + }, +}; + +/*-----------------------------------------------------------------------*/ +static int lm75_input_temp_check(struct lm75_data *data, int input_val) +{ + int i, size; + + size = ARRAY_SIZE(g_lm75_temp_threshold_info); + + for (i = 0; i < size; i++) { + if (g_lm75_temp_threshold_info[i].chip_type == data->kind) { + if ((input_val > g_lm75_temp_threshold_info[i].temp_max) + || (input_val < g_lm75_temp_threshold_info[i].temp_min)) { + dev_dbg(&data->client->dev, "input temp: %d not in range[%d, %d]\n", + input_val, g_lm75_temp_threshold_info[i].temp_min, + g_lm75_temp_threshold_info[i].temp_max); + return -EINVAL; + } + dev_dbg(&data->client->dev, "input temp: %d in range[%d, %d]", input_val, + g_lm75_temp_threshold_info[i].temp_min, g_lm75_temp_threshold_info[i].temp_max); + return 0; + } + } + return 0; +} + +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +static int lm75_write_config(struct lm75_data *data, u8 set_mask, + u8 clr_mask) +{ + u8 value; + + clr_mask |= LM75_SHUTDOWN; + value = data->current_conf & ~clr_mask; + value |= set_mask; + + if (data->current_conf != value) { + s32 err; + + err = i2c_smbus_write_byte_data(data->client, LM75_REG_CONF, + value); + if (err) + return err; + data->current_conf = value; + } + return 0; +} + +static int lm75_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, + long *val) +{ + struct lm75_data *data = dev_get_drvdata(dev); + unsigned int regval; + int err, reg, i, ret; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_update_interval: + *val = data->sample_time; + break; + default: + return -EINVAL; + } + break; + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + reg = LM75_REG_TEMP; + break; + case hwmon_temp_max: + reg = LM75_REG_MAX; + break; + case hwmon_temp_max_hyst: + reg = LM75_REG_HYST; + break; + default: + return -EINVAL; + } + for (i = 0; i < LM75_TEMP_INVALID_RETRY_TIMES; i++) { + err = regmap_read(data->regmap, reg, ®val); + if (err < 0) { + return err; + } + *val = lm75_reg_to_mc(regval, data->resolution); + if (attr != LM75_REG_TEMP) { + return 0; + } + /* do input_temp_check */ + ret = lm75_input_temp_check(data, *val); + if (ret == 0) { /* input temp check ok */ + return 0; + } + if ((i + 1) < LM75_TEMP_INVALID_RETRY_TIMES) { + msleep(data->sample_time); + } + } + dev_info(&data->client->dev, "temp_input value: %ld invalid\n", *val); + return -EINVAL; + default: + return -EINVAL; + } + return 0; +} + +static int lm75_write_temp(struct device *dev, u32 attr, long temp) +{ + struct lm75_data *data = dev_get_drvdata(dev); + u8 resolution; + int reg; + + switch (attr) { + case hwmon_temp_max: + reg = LM75_REG_MAX; + break; + case hwmon_temp_max_hyst: + reg = LM75_REG_HYST; + break; + default: + return -EINVAL; + } + + /* + * Resolution of limit registers is assumed to be the same as the + * temperature input register resolution unless given explicitly. + */ + if (data->params->resolution_limits) + resolution = data->params->resolution_limits; + else + resolution = data->resolution; + + temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + temp = DIV_ROUND_CLOSEST(temp << (resolution - 8), + 1000) << (16 - resolution); + + return regmap_write(data->regmap, reg, (u16)temp); +} + +static int lm75_update_interval(struct device *dev, long val) +{ + struct lm75_data *data = dev_get_drvdata(dev); + unsigned int reg; + u8 index; + s32 err; + + index = find_closest(val, data->params->sample_times, + (int)data->params->num_sample_times); + + switch (data->kind) { + default: + err = lm75_write_config(data, lm75_sample_set_masks[index], + LM75_SAMPLE_CLEAR_MASK); + if (err) + return err; + + data->sample_time = data->params->sample_times[index]; + if (data->params->resolutions) + data->resolution = data->params->resolutions[index]; + break; + case tmp112: + err = regmap_read(data->regmap, LM75_REG_CONF, ®); + if (err < 0) + return err; + reg &= ~0x00c0; + reg |= (3 - index) << 6; + err = regmap_write(data->regmap, LM75_REG_CONF, reg); + if (err < 0) + return err; + data->sample_time = data->params->sample_times[index]; + break; + case pct2075: + err = i2c_smbus_write_byte_data(data->client, PCT2075_REG_IDLE, + index + 1); + if (err) + return err; + data->sample_time = data->params->sample_times[index]; + break; + } + return 0; +} + +static int lm75_write_chip(struct device *dev, u32 attr, long val) +{ + switch (attr) { + case hwmon_chip_update_interval: + return lm75_update_interval(dev, val); + default: + return -EINVAL; + } + return 0; +} + +static int lm75_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + switch (type) { + case hwmon_chip: + return lm75_write_chip(dev, attr, val); + case hwmon_temp: + return lm75_write_temp(dev, attr, val); + default: + return -EINVAL; + } + return 0; +} + +static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct lm75_data *config_data = data; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_update_interval: + if (config_data->params->num_sample_times > 1) + return 0644; + return 0444; + } + break; + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + return 0444; + case hwmon_temp_max: + case hwmon_temp_max_hyst: + return 0644; + } + break; + default: + break; + } + return 0; +} + +static const struct hwmon_channel_info *lm75_info[] = { + HWMON_CHANNEL_INFO(chip, + HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL), + HWMON_CHANNEL_INFO(temp, + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), + NULL +}; + +static const struct hwmon_ops lm75_hwmon_ops = { + .is_visible = lm75_is_visible, + .read = lm75_read, + .write = lm75_write, +}; + +static const struct hwmon_chip_info lm75_chip_info = { + .ops = &lm75_hwmon_ops, + .info = lm75_info, +}; + +static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg) +{ + return reg != LM75_REG_TEMP; +} + +static bool lm75_is_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg == LM75_REG_TEMP || reg == LM75_REG_CONF; +} + +static const struct regmap_config lm75_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .max_register = PCT2075_REG_IDLE, + .writeable_reg = lm75_is_writeable_reg, + .volatile_reg = lm75_is_volatile_reg, + .val_format_endian = REGMAP_ENDIAN_BIG, + .cache_type = REGCACHE_RBTREE, + .use_single_read = true, + .use_single_write = true, +}; + +static void lm75_disable_regulator(void *data) +{ + struct lm75_data *lm75 = data; + + regulator_disable(lm75->vs); +} + +static void lm75_remove(void *data) +{ + struct lm75_data *lm75 = data; + struct i2c_client *client = lm75->client; + + i2c_smbus_write_byte_data(client, LM75_REG_CONF, lm75->orig_conf); +} + +static const struct i2c_device_id lm75_ids[]; + +static int lm75_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct lm75_data *data; + int status, err; + enum lm75_type kind; + + if (client->dev.of_node) + kind = (enum lm75_type)of_device_get_match_data(&client->dev); + else + kind = i2c_match_id(lm75_ids, client)->driver_data; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return -EIO; + + data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + data->kind = kind; + + data->vs = devm_regulator_get(dev, "vs"); + if (IS_ERR(data->vs)) + return PTR_ERR(data->vs); + + data->regmap = devm_regmap_init_i2c(client, &lm75_regmap_config); + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + + /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. + * Then tweak to be more precise when appropriate. + */ + + data->params = &device_params[data->kind]; + + /* Save default sample time and resolution*/ + data->sample_time = data->params->default_sample_time; + data->resolution = data->params->default_resolution; + + /* Enable the power */ + err = regulator_enable(data->vs); + if (err) { + dev_err(dev, "failed to enable regulator: %d\n", err); + return err; + } + + err = devm_add_action_or_reset(dev, lm75_disable_regulator, data); + if (err) + return err; + + /* Cache original configuration */ + status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(dev, "Can't read config? %d\n", status); + return status; + } + data->orig_conf = status; + data->current_conf = status; + + err = lm75_write_config(data, data->params->set_mask, + data->params->clr_mask); + if (err) + return err; + + err = devm_add_action_or_reset(dev, lm75_remove, data); + if (err) + return err; + + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, + data, &lm75_chip_info, + NULL); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name); + + return 0; +} + +static const struct i2c_device_id lm75_ids[] = { + { "wb_adt75", adt75, }, + { "wb_ds1775", ds1775, }, + { "wb_ds75", ds75, }, + { "wb_ds7505", ds7505, }, + { "wb_g751", g751, }, + { "wb_lm75", lm75, }, + { "wb_lm75a", lm75a, }, + { "wb_lm75b", lm75b, }, + { "wb_max6625", max6625, }, + { "wb_max6626", max6626, }, + { "wb_max31725", max31725, }, + { "wb_max31726", max31725, }, + { "wb_mcp980x", mcp980x, }, + { "wb_pct2075", pct2075, }, + { "wb_stds75", stds75, }, + { "wb_stlm75", stlm75, }, + { "wb_tcn75", tcn75, }, + { "wb_tmp100", tmp100, }, + { "wb_tmp101", tmp101, }, + { "wb_tmp105", tmp105, }, + { "wb_tmp112", tmp112, }, + { "wb_tmp175", tmp175, }, + { "wb_tmp275", tmp275, }, + { "wb_tmp75", tmp75, }, + { "wb_tmp75b", tmp75b, }, + { "wb_tmp75c", tmp75c, }, + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, lm75_ids); + +static const struct of_device_id __maybe_unused lm75_of_match[] = { + { + .compatible = "adi,adt75", + .data = (void *)adt75 + }, + { + .compatible = "dallas,ds1775", + .data = (void *)ds1775 + }, + { + .compatible = "dallas,ds75", + .data = (void *)ds75 + }, + { + .compatible = "dallas,ds7505", + .data = (void *)ds7505 + }, + { + .compatible = "gmt,g751", + .data = (void *)g751 + }, + { + .compatible = "national,lm75", + .data = (void *)lm75 + }, + { + .compatible = "national,lm75a", + .data = (void *)lm75a + }, + { + .compatible = "national,lm75b", + .data = (void *)lm75b + }, + { + .compatible = "maxim,max6625", + .data = (void *)max6625 + }, + { + .compatible = "maxim,max6626", + .data = (void *)max6626 + }, + { + .compatible = "maxim,max31725", + .data = (void *)max31725 + }, + { + .compatible = "maxim,max31726", + .data = (void *)max31725 + }, + { + .compatible = "maxim,mcp980x", + .data = (void *)mcp980x + }, + { + .compatible = "nxp,pct2075", + .data = (void *)pct2075 + }, + { + .compatible = "st,stds75", + .data = (void *)stds75 + }, + { + .compatible = "st,stlm75", + .data = (void *)stlm75 + }, + { + .compatible = "microchip,tcn75", + .data = (void *)tcn75 + }, + { + .compatible = "ti,tmp100", + .data = (void *)tmp100 + }, + { + .compatible = "ti,tmp101", + .data = (void *)tmp101 + }, + { + .compatible = "ti,tmp105", + .data = (void *)tmp105 + }, + { + .compatible = "ti,tmp112", + .data = (void *)tmp112 + }, + { + .compatible = "ti,tmp175", + .data = (void *)tmp175 + }, + { + .compatible = "ti,tmp275", + .data = (void *)tmp275 + }, + { + .compatible = "ti,tmp75", + .data = (void *)tmp75 + }, + { + .compatible = "ti,tmp75b", + .data = (void *)tmp75b + }, + { + .compatible = "ti,tmp75c", + .data = (void *)tmp75c + }, + { }, +}; +MODULE_DEVICE_TABLE(of, lm75_of_match); + +#define LM75A_ID 0xA1 +#if 0 +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm75_detect(struct i2c_client *new_client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int i; + int conf, hyst, os; + bool is_lm75a = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + /* + * Now, we do the remaining detection. There is no identification- + * dedicated register so we have to rely on several tricks: + * unused bits, registers cycling over 8-address boundaries, + * addresses 0x04-0x07 returning the last read value. + * The cycling+unused addresses combination is not tested, + * since it would significantly slow the detection down and would + * hardly add any value. + * + * The National Semiconductor LM75A is different than earlier + * LM75s. It has an ID byte of 0xaX (where X is the chip + * revision, with 1 being the only revision in existence) in + * register 7, and unused registers return 0xff rather than the + * last read value. + * + * Note that this function only detects the original National + * Semiconductor LM75 and the LM75A. Clones from other vendors + * aren't detected, on purpose, because they are typically never + * found on PC hardware. They are found on embedded designs where + * they can be instantiated explicitly so detection is not needed. + * The absence of identification registers on all these clones + * would make their exhaustive detection very difficult and weak, + * and odds are that the driver would bind to unsupported devices. + */ + + /* Unused bits */ + conf = i2c_smbus_read_byte_data(new_client, 1); + if (conf & 0xe0) + return -ENODEV; + + /* First check for LM75A */ + if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { + /* + * LM75A returns 0xff on unused registers so + * just to be sure we check for that too. + */ + if (i2c_smbus_read_byte_data(new_client, 4) != 0xff + || i2c_smbus_read_byte_data(new_client, 5) != 0xff + || i2c_smbus_read_byte_data(new_client, 6) != 0xff) + return -ENODEV; + is_lm75a = 1; + hyst = i2c_smbus_read_byte_data(new_client, 2); + os = i2c_smbus_read_byte_data(new_client, 3); + } else { /* Traditional style LM75 detection */ + /* Unused addresses */ + hyst = i2c_smbus_read_byte_data(new_client, 2); + if (i2c_smbus_read_byte_data(new_client, 4) != hyst + || i2c_smbus_read_byte_data(new_client, 5) != hyst + || i2c_smbus_read_byte_data(new_client, 6) != hyst + || i2c_smbus_read_byte_data(new_client, 7) != hyst) + return -ENODEV; + os = i2c_smbus_read_byte_data(new_client, 3); + if (i2c_smbus_read_byte_data(new_client, 4) != os + || i2c_smbus_read_byte_data(new_client, 5) != os + || i2c_smbus_read_byte_data(new_client, 6) != os + || i2c_smbus_read_byte_data(new_client, 7) != os) + return -ENODEV; + } + /* + * It is very unlikely that this is a LM75 if both + * hysteresis and temperature limit registers are 0. + */ + if (hyst == 0 && os == 0) + return -ENODEV; + + /* Addresses cycling */ + for (i = 8; i <= 248; i += 40) { + if (i2c_smbus_read_byte_data(new_client, i + 1) != conf + || i2c_smbus_read_byte_data(new_client, i + 2) != hyst + || i2c_smbus_read_byte_data(new_client, i + 3) != os) + return -ENODEV; + if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) + != LM75A_ID) + return -ENODEV; + } + + strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); + + return 0; +} +#endif + +#ifdef CONFIG_PM +static int lm75_suspend(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + + status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status | LM75_SHUTDOWN; + i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); + return 0; +} + +static int lm75_resume(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + + status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status & ~LM75_SHUTDOWN; + i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); + return 0; +} + +static const struct dev_pm_ops lm75_dev_pm_ops = { + .suspend = lm75_suspend, + .resume = lm75_resume, +}; +#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) +#else +#define LM75_DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + +static struct i2c_driver lm75_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "wb_lm75", + .of_match_table = of_match_ptr(lm75_of_match), + .pm = LM75_DEV_PM_OPS, + }, + .probe_new = lm75_probe, + .id_table = lm75_ids, + /* .detect = lm75_detect, */ + /* .address_list = normal_i2c, */ +}; + +module_i2c_driver(lm75_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("LM75 driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.h new file mode 100644 index 000000000000..a398171162a8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_lm75.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * lm75.h - Part of lm_sensors, Linux kernel modules for hardware monitoring + * Copyright (c) 2003 Mark M. Hoffman + */ + +/* + * This file contains common code for encoding/decoding LM75 type + * temperature readings, which are emulated by many of the chips + * we support. As the user is unlikely to load more than one driver + * which contains this code, we don't worry about the wasted space. + */ + +#include + +/* straight from the datasheet */ +#define LM75_TEMP_MIN (-55000) +#define LM75_TEMP_MAX 125000 +#define LM75_SHUTDOWN 0x01 + +/* + * TEMP: 0.001C/bit (-55C to +125C) + * REG: (0.5C/bit, two's complement) << 7 + */ +static inline u16 LM75_TEMP_TO_REG(long temp) +{ + int ntemp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + + ntemp += (ntemp < 0 ? -250 : 250); + return (u16)((ntemp / 500) << 7); +} + +static inline int LM75_TEMP_FROM_REG(u16 reg) +{ + /* + * use integer division instead of equivalent right shift to + * guarantee arithmetic shift and preserve the sign + */ + return ((s16)reg / 128) * 500; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus.h new file mode 100644 index 000000000000..9fb2c9017ae6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus.h @@ -0,0 +1,535 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * wb_pmbus.h - Common defines and structures for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + */ + +#ifndef WB_PMBUS_H +#define WB_PMBUS_H + +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +/* + * Registers + */ +enum pmbus_regs { + PMBUS_PAGE = 0x00, + PMBUS_OPERATION = 0x01, + PMBUS_ON_OFF_CONFIG = 0x02, + PMBUS_CLEAR_FAULTS = 0x03, + PMBUS_PHASE = 0x04, + + PMBUS_WRITE_PROTECT = 0x10, + + PMBUS_CAPABILITY = 0x19, + PMBUS_QUERY = 0x1A, + + PMBUS_VOUT_MODE = 0x20, + PMBUS_VOUT_COMMAND = 0x21, + PMBUS_VOUT_TRIM = 0x22, + PMBUS_VOUT_CAL_OFFSET = 0x23, + PMBUS_VOUT_MAX = 0x24, + PMBUS_VOUT_MARGIN_HIGH = 0x25, + PMBUS_VOUT_MARGIN_LOW = 0x26, + PMBUS_VOUT_TRANSITION_RATE = 0x27, + PMBUS_VOUT_DROOP = 0x28, + PMBUS_VOUT_SCALE_LOOP = 0x29, + PMBUS_VOUT_SCALE_MONITOR = 0x2A, + + PMBUS_COEFFICIENTS = 0x30, + PMBUS_POUT_MAX = 0x31, + + PMBUS_FAN_CONFIG_12 = 0x3A, + PMBUS_FAN_COMMAND_1 = 0x3B, + PMBUS_FAN_COMMAND_2 = 0x3C, + PMBUS_FAN_CONFIG_34 = 0x3D, + PMBUS_FAN_COMMAND_3 = 0x3E, + PMBUS_FAN_COMMAND_4 = 0x3F, + + PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, + PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, + PMBUS_VOUT_OV_WARN_LIMIT = 0x42, + PMBUS_VOUT_UV_WARN_LIMIT = 0x43, + PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, + PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, + PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, + PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, + PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, + PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, + PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, + PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, + PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, + + PMBUS_OT_FAULT_LIMIT = 0x4F, + PMBUS_OT_FAULT_RESPONSE = 0x50, + PMBUS_OT_WARN_LIMIT = 0x51, + PMBUS_UT_WARN_LIMIT = 0x52, + PMBUS_UT_FAULT_LIMIT = 0x53, + PMBUS_UT_FAULT_RESPONSE = 0x54, + PMBUS_VIN_OV_FAULT_LIMIT = 0x55, + PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, + PMBUS_VIN_OV_WARN_LIMIT = 0x57, + PMBUS_VIN_UV_WARN_LIMIT = 0x58, + PMBUS_VIN_UV_FAULT_LIMIT = 0x59, + + PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, + PMBUS_IIN_OC_WARN_LIMIT = 0x5D, + + PMBUS_POUT_OP_FAULT_LIMIT = 0x68, + PMBUS_POUT_OP_WARN_LIMIT = 0x6A, + PMBUS_PIN_OP_WARN_LIMIT = 0x6B, + + PMBUS_STATUS_BYTE = 0x78, + PMBUS_STATUS_WORD = 0x79, + PMBUS_STATUS_VOUT = 0x7A, + PMBUS_STATUS_IOUT = 0x7B, + PMBUS_STATUS_INPUT = 0x7C, + PMBUS_STATUS_TEMPERATURE = 0x7D, + PMBUS_STATUS_CML = 0x7E, + PMBUS_STATUS_OTHER = 0x7F, + PMBUS_STATUS_MFR_SPECIFIC = 0x80, + PMBUS_STATUS_FAN_12 = 0x81, + PMBUS_STATUS_FAN_34 = 0x82, + + PMBUS_READ_VIN = 0x88, + PMBUS_READ_IIN = 0x89, + PMBUS_READ_VCAP = 0x8A, + PMBUS_READ_VOUT = 0x8B, + PMBUS_READ_IOUT = 0x8C, + PMBUS_READ_TEMPERATURE_1 = 0x8D, + PMBUS_READ_TEMPERATURE_2 = 0x8E, + PMBUS_READ_TEMPERATURE_3 = 0x8F, + PMBUS_READ_FAN_SPEED_1 = 0x90, + PMBUS_READ_FAN_SPEED_2 = 0x91, + PMBUS_READ_FAN_SPEED_3 = 0x92, + PMBUS_READ_FAN_SPEED_4 = 0x93, + PMBUS_READ_DUTY_CYCLE = 0x94, + PMBUS_READ_FREQUENCY = 0x95, + PMBUS_READ_POUT = 0x96, + PMBUS_READ_PIN = 0x97, + + PMBUS_REVISION = 0x98, + PMBUS_MFR_ID = 0x99, + PMBUS_MFR_MODEL = 0x9A, + PMBUS_MFR_REVISION = 0x9B, + PMBUS_MFR_LOCATION = 0x9C, + PMBUS_MFR_DATE = 0x9D, + PMBUS_MFR_SERIAL = 0x9E, + + PMBUS_MFR_VIN_MIN = 0xA0, + PMBUS_MFR_VIN_MAX = 0xA1, + PMBUS_MFR_IIN_MAX = 0xA2, + PMBUS_MFR_PIN_MAX = 0xA3, + PMBUS_MFR_VOUT_MIN = 0xA4, + PMBUS_MFR_VOUT_MAX = 0xA5, + PMBUS_MFR_IOUT_MAX = 0xA6, + PMBUS_MFR_POUT_MAX = 0xA7, + + PMBUS_IC_DEVICE_ID = 0xAD, + PMBUS_IC_DEVICE_REV = 0xAE, + + PMBUS_MFR_MAX_TEMP_1 = 0xC0, + PMBUS_MFR_MAX_TEMP_2 = 0xC1, + PMBUS_MFR_MAX_TEMP_3 = 0xC2, + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ + PMBUS_VIRT_BASE = 0x100, + PMBUS_VIRT_READ_TEMP_AVG, + PMBUS_VIRT_READ_TEMP_MIN, + PMBUS_VIRT_READ_TEMP_MAX, + PMBUS_VIRT_RESET_TEMP_HISTORY, + PMBUS_VIRT_READ_VIN_AVG, + PMBUS_VIRT_READ_VIN_MIN, + PMBUS_VIRT_READ_VIN_MAX, + PMBUS_VIRT_RESET_VIN_HISTORY, + PMBUS_VIRT_READ_IIN_AVG, + PMBUS_VIRT_READ_IIN_MIN, + PMBUS_VIRT_READ_IIN_MAX, + PMBUS_VIRT_RESET_IIN_HISTORY, + PMBUS_VIRT_READ_PIN_AVG, + PMBUS_VIRT_READ_PIN_MIN, + PMBUS_VIRT_READ_PIN_MAX, + PMBUS_VIRT_RESET_PIN_HISTORY, + PMBUS_VIRT_READ_POUT_AVG, + PMBUS_VIRT_READ_POUT_MIN, + PMBUS_VIRT_READ_POUT_MAX, + PMBUS_VIRT_RESET_POUT_HISTORY, + PMBUS_VIRT_READ_VOUT_AVG, + PMBUS_VIRT_READ_VOUT_MIN, + PMBUS_VIRT_READ_VOUT_MAX, + PMBUS_VIRT_RESET_VOUT_HISTORY, + PMBUS_VIRT_READ_IOUT_AVG, + PMBUS_VIRT_READ_IOUT_MIN, + PMBUS_VIRT_READ_IOUT_MAX, + PMBUS_VIRT_RESET_IOUT_HISTORY, + PMBUS_VIRT_READ_TEMP2_AVG, + PMBUS_VIRT_READ_TEMP2_MIN, + PMBUS_VIRT_READ_TEMP2_MAX, + PMBUS_VIRT_RESET_TEMP2_HISTORY, + + PMBUS_VIRT_READ_VMON, + PMBUS_VIRT_VMON_UV_WARN_LIMIT, + PMBUS_VIRT_VMON_OV_WARN_LIMIT, + PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + PMBUS_VIRT_STATUS_VMON, + + /* + * RPM and PWM Fan control + * + * Drivers wanting to expose PWM control must define the behaviour of + * PMBUS_VIRT_PWM_[1-4] and PMBUS_VIRT_PWM_ENABLE_[1-4] in the + * {read,write}_word_data callback. + * + * pmbus core provides a default implementation for + * PMBUS_VIRT_FAN_TARGET_[1-4]. + * + * TARGET, PWM and PWM_ENABLE members must be defined sequentially; + * pmbus core uses the difference between the provided register and + * it's _1 counterpart to calculate the FAN/PWM ID. + */ + PMBUS_VIRT_FAN_TARGET_1, + PMBUS_VIRT_FAN_TARGET_2, + PMBUS_VIRT_FAN_TARGET_3, + PMBUS_VIRT_FAN_TARGET_4, + PMBUS_VIRT_PWM_1, + PMBUS_VIRT_PWM_2, + PMBUS_VIRT_PWM_3, + PMBUS_VIRT_PWM_4, + PMBUS_VIRT_PWM_ENABLE_1, + PMBUS_VIRT_PWM_ENABLE_2, + PMBUS_VIRT_PWM_ENABLE_3, + PMBUS_VIRT_PWM_ENABLE_4, + + /* Samples for average + * + * Drivers wanting to expose functionality for changing the number of + * samples used for average values should implement support in + * {read,write}_word_data callback for either PMBUS_VIRT_SAMPLES if it + * applies to all types of measurements, or any number of specific + * PMBUS_VIRT_*_SAMPLES registers to allow for individual control. + */ + PMBUS_VIRT_SAMPLES, + PMBUS_VIRT_IN_SAMPLES, + PMBUS_VIRT_CURR_SAMPLES, + PMBUS_VIRT_POWER_SAMPLES, + PMBUS_VIRT_TEMP_SAMPLES, +}; + +/* + * OPERATION + */ +#define PB_OPERATION_CONTROL_ON BIT(7) + +/* + * WRITE_PROTECT + */ +#define PB_WP_ALL BIT(7) /* all but WRITE_PROTECT */ +#define PB_WP_OP BIT(6) /* all but WP, OPERATION, PAGE */ +#define PB_WP_VOUT BIT(5) /* all but WP, OPERATION, PAGE, VOUT, ON_OFF */ + +#define PB_WP_ANY (PB_WP_ALL | PB_WP_OP | PB_WP_VOUT) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT BIT(4) +#define PB_CAPABILITY_ERROR_CHECK BIT(7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1)) +#define PB_FAN_2_RPM BIT(2) +#define PB_FAN_2_INSTALLED BIT(3) +#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5)) +#define PB_FAN_1_RPM BIT(6) +#define PB_FAN_1_INSTALLED BIT(7) + +enum pmbus_fan_mode { percent = 0, rpm }; + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE BIT(0) +#define PB_STATUS_CML BIT(1) +#define PB_STATUS_TEMPERATURE BIT(2) +#define PB_STATUS_VIN_UV BIT(3) +#define PB_STATUS_IOUT_OC BIT(4) +#define PB_STATUS_VOUT_OV BIT(5) +#define PB_STATUS_OFF BIT(6) +#define PB_STATUS_BUSY BIT(7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN BIT(8) +#define PB_STATUS_OTHER BIT(9) +#define PB_STATUS_FANS BIT(10) +#define PB_STATUS_POWER_GOOD_N BIT(11) +#define PB_STATUS_WORD_MFR BIT(12) +#define PB_STATUS_INPUT BIT(13) +#define PB_STATUS_IOUT_POUT BIT(14) +#define PB_STATUS_VOUT BIT(15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING BIT(0) +#define PB_POUT_OP_FAULT BIT(1) +#define PB_POWER_LIMITING BIT(2) +#define PB_CURRENT_SHARE_FAULT BIT(3) +#define PB_IOUT_UC_FAULT BIT(4) +#define PB_IOUT_OC_WARNING BIT(5) +#define PB_IOUT_OC_LV_FAULT BIT(6) +#define PB_IOUT_OC_FAULT BIT(7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT BIT(4) +#define PB_VOLTAGE_UV_WARNING BIT(5) +#define PB_VOLTAGE_OV_WARNING BIT(6) +#define PB_VOLTAGE_OV_FAULT BIT(7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING BIT(0) +#define PB_IIN_OC_WARNING BIT(1) +#define PB_IIN_OC_FAULT BIT(2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT BIT(4) +#define PB_TEMP_UT_WARNING BIT(5) +#define PB_TEMP_OT_WARNING BIT(6) +#define PB_TEMP_OT_FAULT BIT(7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING BIT(0) +#define PB_FAN_AIRFLOW_FAULT BIT(1) +#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2) +#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3) +#define PB_FAN_FAN2_WARNING BIT(4) +#define PB_FAN_FAN1_WARNING BIT(5) +#define PB_FAN_FAN2_FAULT BIT(6) +#define PB_FAN_FAN1_FAULT BIT(7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) +#define PB_CML_FAULT_OTHER_COMM BIT(1) +#define PB_CML_FAULT_PROCESSOR BIT(3) +#define PB_CML_FAULT_MEMORY BIT(4) +#define PB_CML_FAULT_PACKET_ERROR BIT(5) +#define PB_CML_FAULT_INVALID_DATA BIT(6) +#define PB_CML_FAULT_INVALID_COMMAND BIT(7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_PWM, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ +#define PMBUS_PHASES 8 /* Maximum number of phases per page */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN BIT(0) +#define PMBUS_HAVE_VCAP BIT(1) +#define PMBUS_HAVE_VOUT BIT(2) +#define PMBUS_HAVE_IIN BIT(3) +#define PMBUS_HAVE_IOUT BIT(4) +#define PMBUS_HAVE_PIN BIT(5) +#define PMBUS_HAVE_POUT BIT(6) +#define PMBUS_HAVE_FAN12 BIT(7) +#define PMBUS_HAVE_FAN34 BIT(8) +#define PMBUS_HAVE_TEMP BIT(9) +#define PMBUS_HAVE_TEMP2 BIT(10) +#define PMBUS_HAVE_TEMP3 BIT(11) +#define PMBUS_HAVE_STATUS_VOUT BIT(12) +#define PMBUS_HAVE_STATUS_IOUT BIT(13) +#define PMBUS_HAVE_STATUS_INPUT BIT(14) +#define PMBUS_HAVE_STATUS_TEMP BIT(15) +#define PMBUS_HAVE_STATUS_FAN12 BIT(16) +#define PMBUS_HAVE_STATUS_FAN34 BIT(17) +#define PMBUS_HAVE_VMON BIT(18) +#define PMBUS_HAVE_STATUS_VMON BIT(19) +#define PMBUS_HAVE_PWM12 BIT(20) +#define PMBUS_HAVE_PWM34 BIT(21) +#define PMBUS_HAVE_SAMPLES BIT(22) + +#define PMBUS_PHASE_VIRTUAL BIT(30) /* Phases on this page are virtual */ +#define PMBUS_PAGE_VIRTUAL BIT(31) /* Page is virtual */ + +enum pmbus_data_format { linear = 0, direct, vid }; +enum vrm_version { vr11 = 0, vr12, vr13, imvp9, amd625mv }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + u8 phases[PMBUS_PAGES]; /* Number of phases per page */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + enum vrm_version vrm_version[PMBUS_PAGES]; /* vrm version per page */ + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + u32 pfunc[PMBUS_PHASES];/* Functionality, per phase */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int phase, + int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); + + /* Regulator functionality, if supported by this chip driver. */ + int num_regulators; + const struct regulator_desc *reg_desc; + + /* custom attributes */ + const struct attribute_group **groups; +}; + +/* Regulator ops */ + +extern const struct regulator_ops wb_pmbus_regulator_ops; + +/* Macro for filling in array of struct regulator_desc */ +#define PMBUS_REGULATOR(_name, _id) \ + [_id] = { \ + .name = (_name # _id), \ + .id = (_id), \ + .of_match = of_match_ptr(_name # _id), \ + .regulators_node = of_match_ptr("regulators"), \ + .ops = &wb_pmbus_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +struct pmbus_data { + struct device *dev; + struct device *hwmon_dev; + + u32 flags; /* from platform data */ + + int exponent[PMBUS_PAGES]; /* linear mode: exponent for output voltages */ + + const struct pmbus_driver_info *info; + + int max_attributes; + int num_attributes; + struct attribute_group group; + const struct attribute_group **groups; + struct dentry *debugfs; /* debugfs device directory */ + + struct pmbus_sensor *sensors; + + struct mutex update_lock; + + bool has_status_word; /* device uses STATUS_WORD register */ + int (*read_status)(struct i2c_client *client, int page); + + s16 currpage; /* current page, -1 for unknown/unset */ + s16 currphase; /* current phase, 0xff for all, -1 for unknown/unset */ + int vout_max[PMBUS_PAGES]; /* pmbus maximum output voltage */ + int vout_min[PMBUS_PAGES]; /* pmbus minimum output voltage */ +}; + +/* Function declarations */ +void wb_pmbus_clear_cache(struct i2c_client *client); +int wb_pmbus_set_page(struct i2c_client *client, int page, int phase); +int wb_pmbus_read_word_data(struct i2c_client *client, int page, int phase, + u8 reg); +int wb_pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, + u16 word); +int wb_pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int wb_pmbus_write_byte(struct i2c_client *client, int page, u8 value); +int wb_pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, + u8 value); +int wb_pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, + u8 mask, u8 value); +void wb_pmbus_clear_faults(struct i2c_client *client); +bool wb_pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool wb_pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int wb_pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info); +int wb_pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *wb_pmbus_get_driver_info(struct i2c_client + *client); +int wb_pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode); +int wb_pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode); +int wb_pmbus_update_fan(struct i2c_client *client, int page, int id, + u8 config, u8 mask, u16 command); +struct dentry *wb_pmbus_get_debugfs_dir(struct i2c_client *client); + +#endif /* WB_PMBUS_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus_core.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus_core.c new file mode 100644 index 000000000000..bba6ca39cd3c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_pmbus_core.c @@ -0,0 +1,2780 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Hardware monitoring driver for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_pmbus.h" + +/* + * Number of additional attribute pointers to allocate + * with each call to krealloc + */ +#define PMBUS_ATTR_ALLOC_SIZE (32) +#define PMBUS_NAME_SIZE (24) +#define PMBUS_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define PMBUS_RETRY_TIME (3) + +struct pmbus_sensor { + struct pmbus_sensor *next; + char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ + struct device_attribute attribute; + u8 page; /* page number */ + u8 phase; /* phase number, 0xff for all phases */ + u16 reg; /* register */ + enum pmbus_sensor_classes class; /* sensor class */ + bool update; /* runtime sensor update needed */ + bool convert; /* Whether or not to apply linear/vid/direct */ + int data; /* Sensor data. + Negative if there was a read error */ +}; +#define to_pmbus_sensor(_attr) \ + container_of(_attr, struct pmbus_sensor, attribute) + +struct pmbus_boolean { + char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ + struct sensor_device_attribute attribute; + struct pmbus_sensor *s1; + struct pmbus_sensor *s2; +}; +#define to_pmbus_boolean(_attr) \ + container_of(_attr, struct pmbus_boolean, attribute) + +struct pmbus_label { + char name[PMBUS_NAME_SIZE]; /* sysfs label name */ + struct device_attribute attribute; + char label[PMBUS_NAME_SIZE]; /* label */ +}; +#define to_pmbus_label(_attr) \ + container_of(_attr, struct pmbus_label, attribute) + +/* Macros for converting between sensor index and register/page/status mask */ + +#define PB_STATUS_MASK 0xffff +#define PB_REG_SHIFT 16 +#define PB_REG_MASK 0x3ff +#define PB_PAGE_SHIFT 26 +#define PB_PAGE_MASK 0x3f + +#define pb_reg_to_index(page, reg, mask) (((page) << PB_PAGE_SHIFT) | \ + ((reg) << PB_REG_SHIFT) | (mask)) + +#define pb_index_to_page(index) (((index) >> PB_PAGE_SHIFT) & PB_PAGE_MASK) +#define pb_index_to_reg(index) (((index) >> PB_REG_SHIFT) & PB_REG_MASK) +#define pb_index_to_mask(index) ((index) & PB_STATUS_MASK) + +struct pmbus_debugfs_entry { + struct i2c_client *client; + u8 page; + u8 reg; +}; + +static const int pmbus_fan_rpm_mask[] = { + PB_FAN_1_RPM, + PB_FAN_2_RPM, + PB_FAN_1_RPM, + PB_FAN_2_RPM, +}; + +static const int pmbus_fan_config_registers[] = { + PMBUS_FAN_CONFIG_12, + PMBUS_FAN_CONFIG_12, + PMBUS_FAN_CONFIG_34, + PMBUS_FAN_CONFIG_34 +}; + +static const int pmbus_fan_command_registers[] = { + PMBUS_FAN_COMMAND_1, + PMBUS_FAN_COMMAND_2, + PMBUS_FAN_COMMAND_3, + PMBUS_FAN_COMMAND_4, +}; + +void wb_pmbus_clear_cache(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor *sensor; + + for (sensor = data->sensors; sensor; sensor = sensor->next) + sensor->data = -ENODATA; +} +EXPORT_SYMBOL_GPL(wb_pmbus_clear_cache); + +static int wb_pmbus_set_page_tmp(struct i2c_client *client, int page, int phase) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int rv; + + if (page < 0) + return 0; + + if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL) && + data->info->pages > 1 && page != data->currpage) { + rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); + if (rv < 0) + return rv; + + rv = i2c_smbus_read_byte_data(client, PMBUS_PAGE); + if (rv < 0) + return rv; + + if (rv != page) + return -EIO; + } + data->currpage = page; + + if (data->info->phases[page] && data->currphase != phase && + !(data->info->func[page] & PMBUS_PHASE_VIRTUAL)) { + rv = i2c_smbus_write_byte_data(client, PMBUS_PHASE, + phase); + if (rv) + return rv; + } + data->currphase = phase; + + return 0; +} + +int wb_pmbus_set_page(struct i2c_client *client, int page, int phase) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_set_page_tmp(client, page, phase); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_set_page failed, page=%d, phase=%d, rv=%d\n", + page, phase, rv); + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_set_page); + +static int wb_pmbus_write_byte_tmp(struct i2c_client *client, int page, u8 value) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, 0xff); + if (rv < 0) + return rv; + + return i2c_smbus_write_byte(client, value); +} + +int wb_pmbus_write_byte(struct i2c_client *client, int page, u8 value) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_write_byte_tmp(client, page, value); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_write_byte failed, page=%d, value=0x%x, rv: %d\n", + page, value, rv); + return rv; +} + +EXPORT_SYMBOL_GPL(wb_pmbus_write_byte); + +/* + * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->write_byte) { + status = info->write_byte(client, page, value); + if (status != -ENODATA) + return status; + } + return wb_pmbus_write_byte(client, page, value); +} + +static int wb_pmbus_write_word_data_tmp(struct i2c_client *client, int page, u8 reg, + u16 word) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, 0xff); + if (rv < 0) + return rv; + + return i2c_smbus_write_word_data(client, reg, word); +} + +int wb_pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, + u16 word) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_write_word_data_tmp(client, page, reg, word); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_write_word_data failed, page: %d, reg: 0x%x, value: 0x%x, rv: %d\n", + page, reg, word, rv); + return rv; + +} +EXPORT_SYMBOL_GPL(wb_pmbus_write_word_data); + +static int pmbus_write_virt_reg(struct i2c_client *client, int page, int reg, + u16 word) +{ + int bit; + int id; + int rv; + + switch (reg) { + case PMBUS_VIRT_FAN_TARGET_1 ... PMBUS_VIRT_FAN_TARGET_4: + id = reg - PMBUS_VIRT_FAN_TARGET_1; + bit = pmbus_fan_rpm_mask[id]; + rv = wb_pmbus_update_fan(client, page, id, bit, bit, word); + break; + default: + rv = -ENXIO; + break; + } + + return rv; +} + +/* + * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, + u16 word) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->write_word_data) { + status = info->write_word_data(client, page, reg, word); + if (status != -ENODATA) + return status; + } + + if (reg >= PMBUS_VIRT_BASE) + return pmbus_write_virt_reg(client, page, reg, word); + + return wb_pmbus_write_word_data(client, page, reg, word); +} + +int wb_pmbus_update_fan(struct i2c_client *client, int page, int id, + u8 config, u8 mask, u16 command) +{ + int from; + int rv; + u8 to; + + from = wb_pmbus_read_byte_data(client, page, + pmbus_fan_config_registers[id]); + if (from < 0) + return from; + + to = (from & ~mask) | (config & mask); + if (to != from) { + rv = wb_pmbus_write_byte_data(client, page, + pmbus_fan_config_registers[id], to); + if (rv < 0) + return rv; + } + + return _pmbus_write_word_data(client, page, + pmbus_fan_command_registers[id], command); +} +EXPORT_SYMBOL_GPL(wb_pmbus_update_fan); + +static int wb_pmbus_read_word_data_tmp(struct i2c_client *client, int page, int phase, u8 reg) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, phase); + if (rv < 0) + return rv; + + return i2c_smbus_read_word_data(client, reg); +} + +int wb_pmbus_read_word_data(struct i2c_client *client, int page, int phase, u8 reg) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_read_word_data_tmp(client, page, phase, reg); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_read_word_data failed, page: %d, phase: %d, reg: 0x%x, rv: %d\n", + page, phase, reg, rv); + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_read_word_data); + +static int pmbus_read_virt_reg(struct i2c_client *client, int page, int reg) +{ + int rv; + int id; + + switch (reg) { + case PMBUS_VIRT_FAN_TARGET_1 ... PMBUS_VIRT_FAN_TARGET_4: + id = reg - PMBUS_VIRT_FAN_TARGET_1; + rv = wb_pmbus_get_fan_rate_device(client, page, id, rpm); + break; + default: + rv = -ENXIO; + break; + } + + return rv; +} + +/* + * _pmbus_read_word_data() is similar to wb_pmbus_read_word_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_read_word_data(struct i2c_client *client, int page, + int phase, int reg) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->read_word_data) { + status = info->read_word_data(client, page, phase, reg); + if (status != -ENODATA) + return status; + } + + if (reg >= PMBUS_VIRT_BASE) + return pmbus_read_virt_reg(client, page, reg); + + return wb_pmbus_read_word_data(client, page, phase, reg); +} + +/* Same as above, but without phase parameter, for use in check functions */ +static int __pmbus_read_word_data(struct i2c_client *client, int page, int reg) +{ + return _pmbus_read_word_data(client, page, 0xff, reg); +} + +static int wb_pmbus_read_byte_data_tmp(struct i2c_client *client, int page, u8 reg) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, 0xff); + if (rv < 0) + return rv; + + return i2c_smbus_read_byte_data(client, reg); +} + +int wb_pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_read_byte_data_tmp(client, page, reg); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_read_byte_data failed, page: %d, reg: 0x%x, rv: %d\n", + page, reg, rv); + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_read_byte_data); + +static int wb_pmbus_write_byte_data_tmp(struct i2c_client *client, int page, u8 reg, u8 value) +{ + int rv; + + rv = wb_pmbus_set_page(client, page, 0xff); + if (rv < 0) + return rv; + + return i2c_smbus_write_byte_data(client, reg, value); +} + +int wb_pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, u8 value) +{ + int rv, i; + struct device *dev = &client->dev; + + for (i = 0; i < PMBUS_RETRY_TIME; i++) { + rv = wb_pmbus_write_byte_data_tmp(client, page, reg, value); + if(rv >= 0){ + return rv; + } + if ((i + 1) < PMBUS_RETRY_TIME) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + } + dev_dbg(dev, "wb_pmbus_write_byte_data failed, page: %d, reg: 0x%x, value: 0x%x, rv: %d\n", + page, reg, value, rv); + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_write_byte_data); + +int wb_pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, + u8 mask, u8 value) +{ + unsigned int tmp; + int rv; + + rv = wb_pmbus_read_byte_data(client, page, reg); + if (rv < 0) + return rv; + + tmp = (rv & ~mask) | (value & mask); + + if (tmp != rv) + rv = wb_pmbus_write_byte_data(client, page, reg, tmp); + + return rv; +} +EXPORT_SYMBOL_GPL(wb_pmbus_update_byte_data); + +/* + * _pmbus_read_byte_data() is similar to wb_pmbus_read_byte_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->read_byte_data) { + status = info->read_byte_data(client, page, reg); + if (status != -ENODATA) + return status; + } + return wb_pmbus_read_byte_data(client, page, reg); +} + +static struct pmbus_sensor *pmbus_find_sensor(struct pmbus_data *data, int page, + int reg) +{ + struct pmbus_sensor *sensor; + + for (sensor = data->sensors; sensor; sensor = sensor->next) { + if (sensor->page == page && sensor->reg == reg) + return sensor; + } + + return ERR_PTR(-EINVAL); +} + +static int pmbus_get_fan_rate(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode, + bool from_cache) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + bool want_rpm, have_rpm; + struct pmbus_sensor *s; + int config; + int reg; + + want_rpm = (mode == rpm); + + if (from_cache) { + reg = want_rpm ? PMBUS_VIRT_FAN_TARGET_1 : PMBUS_VIRT_PWM_1; + s = pmbus_find_sensor(data, page, reg + id); + if (IS_ERR(s)) + return PTR_ERR(s); + + return s->data; + } + + config = wb_pmbus_read_byte_data(client, page, + pmbus_fan_config_registers[id]); + if (config < 0) + return config; + + have_rpm = !!(config & pmbus_fan_rpm_mask[id]); + if (want_rpm == have_rpm) + return wb_pmbus_read_word_data(client, page, 0xff, + pmbus_fan_command_registers[id]); + + /* Can't sensibly map between RPM and PWM, just return zero */ + return 0; +} + +int wb_pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode) +{ + return pmbus_get_fan_rate(client, page, id, mode, false); +} +EXPORT_SYMBOL_GPL(wb_pmbus_get_fan_rate_device); + +int wb_pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id, + enum pmbus_fan_mode mode) +{ + return pmbus_get_fan_rate(client, page, id, mode, true); +} +EXPORT_SYMBOL_GPL(wb_pmbus_get_fan_rate_cached); + +static void pmbus_clear_fault_page(struct i2c_client *client, int page) +{ + _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); +} + +void wb_pmbus_clear_faults(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int i; + + for (i = 0; i < data->info->pages; i++) + pmbus_clear_fault_page(client, i); +} +EXPORT_SYMBOL_GPL(wb_pmbus_clear_faults); + +static int pmbus_check_status_cml(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int status, status2; + + status = data->read_status(client, -1); + if (status < 0 || (status & PB_STATUS_CML)) { + status2 = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); + if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND)) + return -EIO; + } + return 0; +} + +static bool pmbus_check_register(struct i2c_client *client, + int (*func)(struct i2c_client *client, + int page, int reg), + int page, int reg) +{ + int rv; + struct pmbus_data *data = i2c_get_clientdata(client); + + rv = func(client, page, reg); + if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) + rv = pmbus_check_status_cml(client); + pmbus_clear_fault_page(client, -1); + return rv >= 0; +} + +static bool pmbus_check_status_register(struct i2c_client *client, int page) +{ + int status; + struct pmbus_data *data = i2c_get_clientdata(client); + + status = data->read_status(client, page); + if (status >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK) && + (status & PB_STATUS_CML)) { + status = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); + if (status < 0 || (status & PB_CML_FAULT_INVALID_COMMAND)) + status = -EIO; + } + + pmbus_clear_fault_page(client, -1); + return status >= 0; +} + +bool wb_pmbus_check_byte_register(struct i2c_client *client, int page, int reg) +{ + return pmbus_check_register(client, _pmbus_read_byte_data, page, reg); +} +EXPORT_SYMBOL_GPL(wb_pmbus_check_byte_register); + +bool wb_pmbus_check_word_register(struct i2c_client *client, int page, int reg) +{ + return pmbus_check_register(client, __pmbus_read_word_data, page, reg); +} +EXPORT_SYMBOL_GPL(wb_pmbus_check_word_register); + +const struct pmbus_driver_info *wb_pmbus_get_driver_info(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + + return data->info; +} +EXPORT_SYMBOL_GPL(wb_pmbus_get_driver_info); + +static int pmbus_read_status_byte(struct i2c_client *client, int page) +{ + return _pmbus_read_byte_data(client, page, PMBUS_STATUS_BYTE); +} + +static int pmbus_read_status_word(struct i2c_client *client, int page) +{ + return _pmbus_read_word_data(client, page, 0xff, PMBUS_STATUS_WORD); +} + +static int pmbus_get_status(struct i2c_client *client, int page, int reg) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int status; + + switch (reg) { + case PMBUS_STATUS_WORD: + status = data->read_status(client, page); + if ((status < 0) || (data->has_status_word && (status == 0xffff)) + || (!data->has_status_word && (status == 0xff))) { + if (data->has_status_word) { + data->read_status = pmbus_read_status_byte; + } else { + data->read_status = pmbus_read_status_word; + } + data->has_status_word = !data->has_status_word; + status = data->read_status(client, page); + } + break; + default: + status = _pmbus_read_byte_data(client, page, reg); + break; + } + if (status < 0) + wb_pmbus_clear_faults(client); + return status; +} + +static void pmbus_update_sensor_data(struct i2c_client *client, struct pmbus_sensor *sensor) +{ + if (sensor->data < 0 || sensor->update) + sensor->data = _pmbus_read_word_data(client, sensor->page, + sensor->phase, sensor->reg); +} + +/* + * Convert linear sensor values to milli- or micro-units + * depending on sensor type. + */ +static s64 pmbus_reg2data_linear(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + s16 exponent; + s32 mantissa; + s64 val; + + if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ + exponent = data->exponent[sensor->page]; + mantissa = (u16) sensor->data; + } else { /* LINEAR11 */ + exponent = ((s16)sensor->data) >> 11; + mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5; + } + + val = mantissa; + + /* scale result to milli-units for all sensors except fans */ + if (sensor->class != PSC_FAN) + val = val * 1000LL; + + /* scale result to micro-units for power sensors */ + if (sensor->class == PSC_POWER) + val = val * 1000LL; + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val; +} + +/* + * Convert direct sensor values to milli- or micro-units + * depending on sensor type. + */ +static s64 pmbus_reg2data_direct(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + s64 b, val = (s16)sensor->data; + s32 m, R; + + m = data->info->m[sensor->class]; + b = data->info->b[sensor->class]; + R = data->info->R[sensor->class]; + + if (m == 0) + return 0; + + /* X = 1/m * (Y * 10^-R - b) */ + R = -R; + /* scale result to milli-units for everything but fans */ + if (!(sensor->class == PSC_FAN || sensor->class == PSC_PWM)) { + R += 3; + b *= 1000; + } + + /* scale result to micro-units for power sensors */ + if (sensor->class == PSC_POWER) { + R += 3; + b *= 1000; + } + + while (R > 0) { + val *= 10; + R--; + } + while (R < 0) { + val = div_s64(val + 5LL, 10L); /* round closest */ + R++; + } + + val = div_s64(val - b, m); + return val; +} + +/* + * Convert VID sensor values to milli- or micro-units + * depending on sensor type. + */ +static s64 pmbus_reg2data_vid(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + long val = sensor->data; + long rv = 0; + + switch (data->info->vrm_version[sensor->page]) { + case vr11: + if (val >= 0x02 && val <= 0xb2) + rv = DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100); + break; + case vr12: + if (val >= 0x01) + rv = 250 + (val - 1) * 5; + break; + case vr13: + if (val >= 0x01) + rv = 500 + (val - 1) * 10; + break; + case imvp9: + if (val >= 0x01) + rv = 200 + (val - 1) * 10; + break; + case amd625mv: + if (val >= 0x0 && val <= 0xd8) + rv = DIV_ROUND_CLOSEST(155000 - val * 625, 100); + break; + } + return rv; +} + +static s64 pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) +{ + s64 val; + + if (!sensor->convert) + return sensor->data; + + switch (data->info->format[sensor->class]) { + case direct: + val = pmbus_reg2data_direct(data, sensor); + break; + case vid: + val = pmbus_reg2data_vid(data, sensor); + break; + case linear: + default: + val = pmbus_reg2data_linear(data, sensor); + break; + } + return val; +} + +#define MAX_MANTISSA (1023 * 1000) +#define MIN_MANTISSA (511 * 1000) + +static u16 pmbus_data2reg_linear(struct pmbus_data *data, + struct pmbus_sensor *sensor, s64 val) +{ + s16 exponent = 0, mantissa; + bool negative = false; + + /* simple case */ + if (val == 0) + return 0; + + if (sensor->class == PSC_VOLTAGE_OUT) { + /* LINEAR16 does not support negative voltages */ + if (val < 0) + return 0; + + /* + * For a static exponents, we don't have a choice + * but to adjust the value to it. + */ + if (data->exponent[sensor->page] < 0) + val <<= -data->exponent[sensor->page]; + else + val >>= data->exponent[sensor->page]; + val = DIV_ROUND_CLOSEST_ULL(val, 1000); + return clamp_val(val, 0, 0xffff); + } + + if (val < 0) { + negative = true; + val = -val; + } + + /* Power is in uW. Convert to mW before converting. */ + if (sensor->class == PSC_POWER) + val = DIV_ROUND_CLOSEST_ULL(val, 1000); + + /* + * For simplicity, convert fan data to milli-units + * before calculating the exponent. + */ + if (sensor->class == PSC_FAN) + val = val * 1000LL; + + /* Reduce large mantissa until it fits into 10 bit */ + while (val >= MAX_MANTISSA && exponent < 15) { + exponent++; + val >>= 1; + } + /* Increase small mantissa to improve precision */ + while (val < MIN_MANTISSA && exponent > -15) { + exponent--; + val <<= 1; + } + + /* Convert mantissa from milli-units to units */ + mantissa = clamp_val(DIV_ROUND_CLOSEST_ULL(val, 1000), 0, 0x3ff); + + /* restore sign */ + if (negative) + mantissa = -mantissa; + + /* Convert to 5 bit exponent, 11 bit mantissa */ + return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800); +} + +static u16 pmbus_data2reg_direct(struct pmbus_data *data, + struct pmbus_sensor *sensor, s64 val) +{ + s64 b; + s32 m, R; + + m = data->info->m[sensor->class]; + b = data->info->b[sensor->class]; + R = data->info->R[sensor->class]; + + /* Power is in uW. Adjust R and b. */ + if (sensor->class == PSC_POWER) { + R -= 3; + b *= 1000; + } + + /* Calculate Y = (m * X + b) * 10^R */ + if (!(sensor->class == PSC_FAN || sensor->class == PSC_PWM)) { + R -= 3; /* Adjust R and b for data in milli-units */ + b *= 1000; + } + val = val * m + b; + + while (R > 0) { + val *= 10; + R--; + } + while (R < 0) { + val = div_s64(val + 5LL, 10L); /* round closest */ + R++; + } + + return (u16)clamp_val(val, S16_MIN, S16_MAX); +} + +static u16 pmbus_data2reg_vid(struct pmbus_data *data, + struct pmbus_sensor *sensor, s64 val) +{ + val = clamp_val(val, 500, 1600); + + return 2 + DIV_ROUND_CLOSEST_ULL((1600LL - val) * 100LL, 625); +} + +static u16 pmbus_data2reg(struct pmbus_data *data, + struct pmbus_sensor *sensor, s64 val) +{ + u16 regval; + + if (!sensor->convert) + return val; + + switch (data->info->format[sensor->class]) { + case direct: + regval = pmbus_data2reg_direct(data, sensor, val); + break; + case vid: + regval = pmbus_data2reg_vid(data, sensor, val); + break; + case linear: + default: + regval = pmbus_data2reg_linear(data, sensor, val); + break; + } + return regval; +} + +/* + * Return boolean calculated from converted data. + * defines a status register index and mask. + * The mask is in the lower 8 bits, the register index is in bits 8..23. + * + * The associated pmbus_boolean structure contains optional pointers to two + * sensor attributes. If specified, those attributes are compared against each + * other to determine if a limit has been exceeded. + * + * If the sensor attribute pointers are NULL, the function returns true if + * (status[reg] & mask) is true. + * + * If sensor attribute pointers are provided, a comparison against a specified + * limit has to be performed to determine the boolean result. + * In this case, the function returns true if v1 >= v2 (where v1 and v2 are + * sensor values referenced by sensor attribute pointers s1 and s2). + * + * To determine if an object exceeds upper limits, specify = . + * To determine if an object exceeds lower limits, specify = . + * + * If a negative value is stored in any of the referenced registers, this value + * reflects an error code which will be returned. + */ +static int pmbus_get_boolean(struct i2c_client *client, struct pmbus_boolean *b, + int index) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor *s1 = b->s1; + struct pmbus_sensor *s2 = b->s2; + u16 mask = pb_index_to_mask(index); + u8 page = pb_index_to_page(index); + u16 reg = pb_index_to_reg(index); + int ret, status; + u16 regval; + + mutex_lock(&data->update_lock); + status = pmbus_get_status(client, page, reg); + if (status < 0) { + ret = status; + goto unlock; + } + + if (s1) + pmbus_update_sensor_data(client, s1); + if (s2) + pmbus_update_sensor_data(client, s2); + + regval = status & mask; + if (s1 && s2) { + s64 v1, v2; + + if (s1->data < 0) { + ret = s1->data; + goto unlock; + } + if (s2->data < 0) { + ret = s2->data; + goto unlock; + } + + v1 = pmbus_reg2data(data, s1); + v2 = pmbus_reg2data(data, s2); + ret = !!(regval && v1 >= v2); + } else { + ret = !!regval; + } +unlock: + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t pmbus_show_boolean(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct pmbus_boolean *boolean = to_pmbus_boolean(attr); + struct i2c_client *client = to_i2c_client(dev->parent); + int val; + + val = pmbus_get_boolean(client, boolean, attr->index); + if (val < 0) + return val; + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t pmbus_show_sensor(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + ssize_t ret; + + mutex_lock(&data->update_lock); + pmbus_update_sensor_data(client, sensor); + if (sensor->data < 0) + ret = sensor->data; + else + ret = snprintf(buf, PAGE_SIZE, "%lld\n", pmbus_reg2data(data, sensor)); + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t pmbus_set_sensor(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); + ssize_t rv = count; + s64 val; + int ret; + u16 regval; + + if (kstrtos64(buf, 10, &val) < 0) + return -EINVAL; + + mutex_lock(&data->update_lock); + regval = pmbus_data2reg(data, sensor, val); + ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); + if (ret < 0) + rv = ret; + else + sensor->data = regval; + mutex_unlock(&data->update_lock); + return rv; +} + +static ssize_t pmbus_show_label(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct pmbus_label *label = to_pmbus_label(da); + + return snprintf(buf, PAGE_SIZE, "%s\n", label->label); +} + +static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr) +{ + if (data->num_attributes >= data->max_attributes - 1) { + int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE; + void *new_attrs = devm_krealloc(data->dev, data->group.attrs, + new_max_attrs * sizeof(void *), + GFP_KERNEL); + if (!new_attrs) + return -ENOMEM; + data->group.attrs = new_attrs; + data->max_attributes = new_max_attrs; + } + + data->group.attrs[data->num_attributes++] = attr; + data->group.attrs[data->num_attributes] = NULL; + return 0; +} + +static void pmbus_dev_attr_init(struct device_attribute *dev_attr, + const char *name, + umode_t mode, + ssize_t (*show)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*store)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count)) +{ + sysfs_attr_init(&dev_attr->attr); + dev_attr->attr.name = name; + dev_attr->attr.mode = mode; + dev_attr->show = show; + dev_attr->store = store; +} + +static void pmbus_attr_init(struct sensor_device_attribute *a, + const char *name, + umode_t mode, + ssize_t (*show)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*store)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count), + int idx) +{ + pmbus_dev_attr_init(&a->dev_attr, name, mode, show, store); + a->index = idx; +} + +static int pmbus_add_boolean(struct pmbus_data *data, + const char *name, const char *type, int seq, + struct pmbus_sensor *s1, + struct pmbus_sensor *s2, + u8 page, u16 reg, u16 mask) +{ + struct pmbus_boolean *boolean; + struct sensor_device_attribute *a; + + if (WARN((s1 && !s2) || (!s1 && s2), "Bad s1/s2 parameters\n")) + return -EINVAL; + + boolean = devm_kzalloc(data->dev, sizeof(*boolean), GFP_KERNEL); + if (!boolean) + return -ENOMEM; + + a = &boolean->attribute; + + snprintf(boolean->name, sizeof(boolean->name), "%s%d_%s", + name, seq, type); + boolean->s1 = s1; + boolean->s2 = s2; + pmbus_attr_init(a, boolean->name, 0444, pmbus_show_boolean, NULL, + pb_reg_to_index(page, reg, mask)); + + return pmbus_add_attribute(data, &a->dev_attr.attr); +} + +static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, + const char *name, const char *type, + int seq, int page, int phase, + int reg, + enum pmbus_sensor_classes class, + bool update, bool readonly, + bool convert) +{ + struct pmbus_sensor *sensor; + struct device_attribute *a; + + sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) + return NULL; + a = &sensor->attribute; + + if (type) + snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", + name, seq, type); + else + snprintf(sensor->name, sizeof(sensor->name), "%s%d", + name, seq); + + if (data->flags & PMBUS_WRITE_PROTECTED) + readonly = true; + + sensor->page = page; + sensor->phase = phase; + sensor->reg = reg; + sensor->class = class; + sensor->update = update; + sensor->convert = convert; + sensor->data = -ENODATA; + pmbus_dev_attr_init(a, sensor->name, + readonly ? 0444 : 0644, + pmbus_show_sensor, pmbus_set_sensor); + + if (pmbus_add_attribute(data, &a->attr)) + return NULL; + + sensor->next = data->sensors; + data->sensors = sensor; + + return sensor; +} + +static int pmbus_add_label(struct pmbus_data *data, + const char *name, int seq, + const char *lstring, int index, int phase) +{ + struct pmbus_label *label; + struct device_attribute *a; + + label = devm_kzalloc(data->dev, sizeof(*label), GFP_KERNEL); + if (!label) + return -ENOMEM; + + a = &label->attribute; + + snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq); + if (!index) { + if (phase == 0xff) + strncpy(label->label, lstring, + sizeof(label->label) - 1); + else + snprintf(label->label, sizeof(label->label), "%s.%d", + lstring, phase); + } else { + if (phase == 0xff) + snprintf(label->label, sizeof(label->label), "%s%d", + lstring, index); + else + snprintf(label->label, sizeof(label->label), "%s%d.%d", + lstring, index, phase); + } + + pmbus_dev_attr_init(a, label->name, 0444, pmbus_show_label, NULL); + return pmbus_add_attribute(data, &a->attr); +} + +/* + * Search for attributes. Allocate sensors, booleans, and labels as needed. + */ + +/* + * The pmbus_limit_attr structure describes a single limit attribute + * and its associated alarm attribute. + */ +struct pmbus_limit_attr { + u16 reg; /* Limit register */ + u16 sbit; /* Alarm attribute status bit */ + bool update; /* True if register needs updates */ + bool low; /* True if low limit; for limits with compare + functions only */ + const char *attr; /* Attribute name */ + const char *alarm; /* Alarm attribute name */ +}; + +/* + * The pmbus_sensor_attr structure describes one sensor attribute. This + * description includes a reference to the associated limit attributes. + */ +struct pmbus_sensor_attr { + u16 reg; /* sensor register */ + u16 gbit; /* generic status bit */ + u8 nlimit; /* # of limit registers */ + enum pmbus_sensor_classes class;/* sensor class */ + const char *label; /* sensor label */ + bool paged; /* true if paged sensor */ + bool update; /* true if update needed */ + bool compare; /* true if compare function needed */ + u32 func; /* sensor mask */ + u32 sfunc; /* sensor status mask */ + int sreg; /* status register */ + const struct pmbus_limit_attr *limit;/* limit registers */ +}; + +/* + * Add a set of limit attributes and, if supported, the associated + * alarm attributes. + * returns 0 if no alarm register found, 1 if an alarm register was found, + * < 0 on errors. + */ +static int pmbus_add_limit_attrs(struct i2c_client *client, + struct pmbus_data *data, + const struct pmbus_driver_info *info, + const char *name, int index, int page, + struct pmbus_sensor *base, + const struct pmbus_sensor_attr *attr) +{ + const struct pmbus_limit_attr *l = attr->limit; + int nlimit = attr->nlimit; + int have_alarm = 0; + int i, ret; + struct pmbus_sensor *curr; + + for (i = 0; i < nlimit; i++) { + if (wb_pmbus_check_word_register(client, page, l->reg)) { + curr = pmbus_add_sensor(data, name, l->attr, index, + page, 0xff, l->reg, attr->class, + attr->update || l->update, + false, true); + if (!curr) + return -ENOMEM; + if (l->sbit && (info->func[page] & attr->sfunc)) { + ret = pmbus_add_boolean(data, name, + l->alarm, index, + attr->compare ? l->low ? curr : base + : NULL, + attr->compare ? l->low ? base : curr + : NULL, + page, attr->sreg, l->sbit); + if (ret) + return ret; + have_alarm = 1; + } + } + l++; + } + return have_alarm; +} + +static int pmbus_add_sensor_attrs_one(struct i2c_client *client, + struct pmbus_data *data, + const struct pmbus_driver_info *info, + const char *name, + int index, int page, int phase, + const struct pmbus_sensor_attr *attr, + bool paged) +{ + struct pmbus_sensor *base; + bool upper = !!(attr->gbit & 0xff00); /* need to check STATUS_WORD */ + int ret; + + if (attr->label) { + ret = pmbus_add_label(data, name, index, attr->label, + paged ? page + 1 : 0, phase); + if (ret) + return ret; + } + base = pmbus_add_sensor(data, name, "input", index, page, phase, + attr->reg, attr->class, true, true, true); + if (!base) + return -ENOMEM; + /* No limit and alarm attributes for phase specific sensors */ + if (attr->sfunc && phase == 0xff) { + ret = pmbus_add_limit_attrs(client, data, info, name, + index, page, base, attr); + if (ret < 0) + return ret; + /* + * Add generic alarm attribute only if there are no individual + * alarm attributes, if there is a global alarm bit, and if + * the generic status register (word or byte, depending on + * which global bit is set) for this page is accessible. + */ + if (!ret && attr->gbit && + (!upper || (upper && data->has_status_word)) && + pmbus_check_status_register(client, page)) { + ret = pmbus_add_boolean(data, name, "alarm", index, + NULL, NULL, + page, PMBUS_STATUS_WORD, + attr->gbit); + if (ret) + return ret; + } + } + return 0; +} + +static bool pmbus_sensor_is_paged(const struct pmbus_driver_info *info, + const struct pmbus_sensor_attr *attr) +{ + int p; + + if (attr->paged) + return true; + + /* + * Some attributes may be present on more than one page despite + * not being marked with the paged attribute. If that is the case, + * then treat the sensor as being paged and add the page suffix to the + * attribute name. + * We don't just add the paged attribute to all such attributes, in + * order to maintain the un-suffixed labels in the case where the + * attribute is only on page 0. + */ + for (p = 1; p < info->pages; p++) { + if (info->func[p] & attr->func) + return true; + } + return false; +} + +static int pmbus_add_sensor_attrs(struct i2c_client *client, + struct pmbus_data *data, + const char *name, + const struct pmbus_sensor_attr *attrs, + int nattrs) +{ + const struct pmbus_driver_info *info = data->info; + int index, i; + int ret; + + index = 1; + for (i = 0; i < nattrs; i++) { + int page, pages; + bool paged = pmbus_sensor_is_paged(info, attrs); + + pages = paged ? info->pages : 1; + for (page = 0; page < pages; page++) { + if (!(info->func[page] & attrs->func)) + continue; + ret = pmbus_add_sensor_attrs_one(client, data, info, + name, index, page, + 0xff, attrs, paged); + if (ret) + return ret; + index++; + if (info->phases[page]) { + int phase; + + for (phase = 0; phase < info->phases[page]; + phase++) { + if (!(info->pfunc[phase] & attrs->func)) + continue; + ret = pmbus_add_sensor_attrs_one(client, + data, info, name, index, page, + phase, attrs, paged); + if (ret) + return ret; + index++; + } + } + } + attrs++; + } + return 0; +} + +static const struct pmbus_limit_attr vin_limit_attrs[] = { + { + .reg = PMBUS_VIN_UV_WARN_LIMIT, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_VOLTAGE_UV_WARNING, + }, { + .reg = PMBUS_VIN_UV_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_VOLTAGE_UV_FAULT, + }, { + .reg = PMBUS_VIN_OV_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_VOLTAGE_OV_WARNING, + }, { + .reg = PMBUS_VIN_OV_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_VOLTAGE_OV_FAULT, + }, { + .reg = PMBUS_VIRT_READ_VIN_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_VIN_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_VIN_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_VIN_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_VIN_MIN, + .attr = "rated_min", + }, { + .reg = PMBUS_MFR_VIN_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr vmon_limit_attrs[] = { + { + .reg = PMBUS_VIRT_VMON_UV_WARN_LIMIT, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_VOLTAGE_UV_WARNING, + }, { + .reg = PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_VOLTAGE_UV_FAULT, + }, { + .reg = PMBUS_VIRT_VMON_OV_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_VOLTAGE_OV_WARNING, + }, { + .reg = PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_VOLTAGE_OV_FAULT, + } +}; + +static const struct pmbus_limit_attr vout_limit_attrs[] = { + { + .reg = PMBUS_VOUT_UV_WARN_LIMIT, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_VOLTAGE_UV_WARNING, + }, { + .reg = PMBUS_VOUT_UV_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_VOLTAGE_UV_FAULT, + }, { + .reg = PMBUS_VOUT_OV_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_VOLTAGE_OV_WARNING, + }, { + .reg = PMBUS_VOUT_OV_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_VOLTAGE_OV_FAULT, + }, { + .reg = PMBUS_VIRT_READ_VOUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_VOUT_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_VOUT_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_VOUT_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_VOUT_MIN, + .attr = "rated_min", + }, { + .reg = PMBUS_MFR_VOUT_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_sensor_attr voltage_attributes[] = { + { + .reg = PMBUS_READ_VIN, + .class = PSC_VOLTAGE_IN, + .label = "vin", + .func = PMBUS_HAVE_VIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sreg = PMBUS_STATUS_INPUT, + .gbit = PB_STATUS_VIN_UV, + .limit = vin_limit_attrs, + .nlimit = ARRAY_SIZE(vin_limit_attrs), + }, { + .reg = PMBUS_VIRT_READ_VMON, + .class = PSC_VOLTAGE_IN, + .label = "vmon", + .func = PMBUS_HAVE_VMON, + .sfunc = PMBUS_HAVE_STATUS_VMON, + .sreg = PMBUS_VIRT_STATUS_VMON, + .limit = vmon_limit_attrs, + .nlimit = ARRAY_SIZE(vmon_limit_attrs), + }, { + .reg = PMBUS_READ_VCAP, + .class = PSC_VOLTAGE_IN, + .label = "vcap", + .func = PMBUS_HAVE_VCAP, + }, { + .reg = PMBUS_READ_VOUT, + .class = PSC_VOLTAGE_OUT, + .label = "vout", + .paged = true, + .func = PMBUS_HAVE_VOUT, + .sfunc = PMBUS_HAVE_STATUS_VOUT, + .sreg = PMBUS_STATUS_VOUT, + .gbit = PB_STATUS_VOUT_OV, + .limit = vout_limit_attrs, + .nlimit = ARRAY_SIZE(vout_limit_attrs), + } +}; + +/* Current attributes */ + +static const struct pmbus_limit_attr iin_limit_attrs[] = { + { + .reg = PMBUS_IIN_OC_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_IIN_OC_WARNING, + }, { + .reg = PMBUS_IIN_OC_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_IIN_OC_FAULT, + }, { + .reg = PMBUS_VIRT_READ_IIN_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_IIN_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_IIN_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_IIN_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_IIN_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr iout_limit_attrs[] = { + { + .reg = PMBUS_IOUT_OC_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_IOUT_OC_WARNING, + }, { + .reg = PMBUS_IOUT_UC_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_IOUT_UC_FAULT, + }, { + .reg = PMBUS_IOUT_OC_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_IOUT_OC_FAULT, + }, { + .reg = PMBUS_VIRT_READ_IOUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_IOUT_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_IOUT_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_IOUT_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_IOUT_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_sensor_attr current_attributes[] = { + { + .reg = PMBUS_READ_IIN, + .class = PSC_CURRENT_IN, + .label = "iin", + .func = PMBUS_HAVE_IIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sreg = PMBUS_STATUS_INPUT, + .gbit = PB_STATUS_INPUT, + .limit = iin_limit_attrs, + .nlimit = ARRAY_SIZE(iin_limit_attrs), + }, { + .reg = PMBUS_READ_IOUT, + .class = PSC_CURRENT_OUT, + .label = "iout", + .paged = true, + .func = PMBUS_HAVE_IOUT, + .sfunc = PMBUS_HAVE_STATUS_IOUT, + .sreg = PMBUS_STATUS_IOUT, + .gbit = PB_STATUS_IOUT_OC, + .limit = iout_limit_attrs, + .nlimit = ARRAY_SIZE(iout_limit_attrs), + } +}; + +/* Power attributes */ + +static const struct pmbus_limit_attr pin_limit_attrs[] = { + { + .reg = PMBUS_PIN_OP_WARN_LIMIT, + .attr = "max", + .alarm = "alarm", + .sbit = PB_PIN_OP_WARNING, + }, { + .reg = PMBUS_VIRT_READ_PIN_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_PIN_MIN, + .update = true, + .attr = "input_lowest", + }, { + .reg = PMBUS_VIRT_READ_PIN_MAX, + .update = true, + .attr = "input_highest", + }, { + .reg = PMBUS_VIRT_RESET_PIN_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_PIN_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr pout_limit_attrs[] = { + { + .reg = PMBUS_POUT_MAX, + .attr = "cap", + .alarm = "cap_alarm", + .sbit = PB_POWER_LIMITING, + }, { + .reg = PMBUS_POUT_OP_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_POUT_OP_WARNING, + }, { + .reg = PMBUS_POUT_OP_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_POUT_OP_FAULT, + }, { + .reg = PMBUS_VIRT_READ_POUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_POUT_MIN, + .update = true, + .attr = "input_lowest", + }, { + .reg = PMBUS_VIRT_READ_POUT_MAX, + .update = true, + .attr = "input_highest", + }, { + .reg = PMBUS_VIRT_RESET_POUT_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_POUT_MAX, + .attr = "rated_max", + }, +}; + +static const struct pmbus_sensor_attr power_attributes[] = { + { + .reg = PMBUS_READ_PIN, + .class = PSC_POWER, + .label = "pin", + .func = PMBUS_HAVE_PIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sreg = PMBUS_STATUS_INPUT, + .gbit = PB_STATUS_INPUT, + .limit = pin_limit_attrs, + .nlimit = ARRAY_SIZE(pin_limit_attrs), + }, { + .reg = PMBUS_READ_POUT, + .class = PSC_POWER, + .label = "pout", + .paged = true, + .func = PMBUS_HAVE_POUT, + .sfunc = PMBUS_HAVE_STATUS_IOUT, + .sreg = PMBUS_STATUS_IOUT, + .limit = pout_limit_attrs, + .nlimit = ARRAY_SIZE(pout_limit_attrs), + } +}; + +/* Temperature atributes */ + +static const struct pmbus_limit_attr temp_limit_attrs[] = { + { + .reg = PMBUS_UT_WARN_LIMIT, + .low = true, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_TEMP_UT_WARNING, + }, { + .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_TEMP_UT_FAULT, + }, { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + }, { + .reg = PMBUS_OT_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_TEMP_OT_FAULT, + }, { + .reg = PMBUS_VIRT_READ_TEMP_MIN, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_TEMP_AVG, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_TEMP_MAX, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_TEMP_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_MAX_TEMP_1, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr temp_limit_attrs2[] = { + { + .reg = PMBUS_UT_WARN_LIMIT, + .low = true, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_TEMP_UT_WARNING, + }, { + .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_TEMP_UT_FAULT, + }, { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + }, { + .reg = PMBUS_OT_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_TEMP_OT_FAULT, + }, { + .reg = PMBUS_VIRT_READ_TEMP2_MIN, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_TEMP2_AVG, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_TEMP2_MAX, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_TEMP2_HISTORY, + .attr = "reset_history", + }, { + .reg = PMBUS_MFR_MAX_TEMP_2, + .attr = "rated_max", + }, +}; + +static const struct pmbus_limit_attr temp_limit_attrs3[] = { + { + .reg = PMBUS_UT_WARN_LIMIT, + .low = true, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_TEMP_UT_WARNING, + }, { + .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_TEMP_UT_FAULT, + }, { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + }, { + .reg = PMBUS_OT_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_TEMP_OT_FAULT, + }, { + .reg = PMBUS_MFR_MAX_TEMP_3, + .attr = "rated_max", + }, +}; + +static const struct pmbus_sensor_attr temp_attributes[] = { + { + .reg = PMBUS_READ_TEMPERATURE_1, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sreg = PMBUS_STATUS_TEMPERATURE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs, + .nlimit = ARRAY_SIZE(temp_limit_attrs), + }, { + .reg = PMBUS_READ_TEMPERATURE_2, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP2, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sreg = PMBUS_STATUS_TEMPERATURE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs2, + .nlimit = ARRAY_SIZE(temp_limit_attrs2), + }, { + .reg = PMBUS_READ_TEMPERATURE_3, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP3, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sreg = PMBUS_STATUS_TEMPERATURE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs3, + .nlimit = ARRAY_SIZE(temp_limit_attrs3), + } +}; + +static const int pmbus_fan_registers[] = { + PMBUS_READ_FAN_SPEED_1, + PMBUS_READ_FAN_SPEED_2, + PMBUS_READ_FAN_SPEED_3, + PMBUS_READ_FAN_SPEED_4 +}; + +static const int pmbus_fan_status_registers[] = { + PMBUS_STATUS_FAN_12, + PMBUS_STATUS_FAN_12, + PMBUS_STATUS_FAN_34, + PMBUS_STATUS_FAN_34 +}; + +static const u32 pmbus_fan_flags[] = { + PMBUS_HAVE_FAN12, + PMBUS_HAVE_FAN12, + PMBUS_HAVE_FAN34, + PMBUS_HAVE_FAN34 +}; + +static const u32 pmbus_fan_status_flags[] = { + PMBUS_HAVE_STATUS_FAN12, + PMBUS_HAVE_STATUS_FAN12, + PMBUS_HAVE_STATUS_FAN34, + PMBUS_HAVE_STATUS_FAN34 +}; + +/* Fans */ + +/* Precondition: FAN_CONFIG_x_y and FAN_COMMAND_x must exist for the fan ID */ +static int pmbus_add_fan_ctrl(struct i2c_client *client, + struct pmbus_data *data, int index, int page, int id, + u8 config) +{ + struct pmbus_sensor *sensor; + + sensor = pmbus_add_sensor(data, "fan", "target", index, page, + 0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN, + false, false, true); + + if (!sensor) + return -ENOMEM; + + if (!((data->info->func[page] & PMBUS_HAVE_PWM12) || + (data->info->func[page] & PMBUS_HAVE_PWM34))) + return 0; + + sensor = pmbus_add_sensor(data, "pwm", NULL, index, page, + 0xff, PMBUS_VIRT_PWM_1 + id, PSC_PWM, + false, false, true); + + if (!sensor) + return -ENOMEM; + + sensor = pmbus_add_sensor(data, "pwm", "enable", index, page, + 0xff, PMBUS_VIRT_PWM_ENABLE_1 + id, PSC_PWM, + true, false, false); + + if (!sensor) + return -ENOMEM; + + return 0; +} + +static int pmbus_add_fan_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + const struct pmbus_driver_info *info = data->info; + int index = 1; + int page; + int ret; + + for (page = 0; page < info->pages; page++) { + int f; + + for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) { + int regval; + + if (!(info->func[page] & pmbus_fan_flags[f])) + break; + + if (!wb_pmbus_check_word_register(client, page, + pmbus_fan_registers[f])) + break; + + /* + * Skip fan if not installed. + * Each fan configuration register covers multiple fans, + * so we have to do some magic. + */ + regval = _pmbus_read_byte_data(client, page, + pmbus_fan_config_registers[f]); + if (regval < 0 || + (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) + continue; + + if (pmbus_add_sensor(data, "fan", "input", index, + page, 0xff, pmbus_fan_registers[f], + PSC_FAN, true, true, true) == NULL) + return -ENOMEM; + + /* Fan control */ + if (wb_pmbus_check_word_register(client, page, + pmbus_fan_command_registers[f])) { + ret = pmbus_add_fan_ctrl(client, data, index, + page, f, regval); + if (ret < 0) + return ret; + } + + /* + * Each fan status register covers multiple fans, + * so we have to do some magic. + */ + if ((info->func[page] & pmbus_fan_status_flags[f]) && + wb_pmbus_check_byte_register(client, + page, pmbus_fan_status_registers[f])) { + int reg; + + if (f > 1) /* fan 3, 4 */ + reg = PMBUS_STATUS_FAN_34; + else + reg = PMBUS_STATUS_FAN_12; + ret = pmbus_add_boolean(data, "fan", + "alarm", index, NULL, NULL, page, reg, + PB_FAN_FAN1_WARNING >> (f & 1)); + if (ret) + return ret; + ret = pmbus_add_boolean(data, "fan", + "fault", index, NULL, NULL, page, reg, + PB_FAN_FAN1_FAULT >> (f & 1)); + if (ret) + return ret; + } + index++; + } + } + return 0; +} + +struct pmbus_samples_attr { + int reg; + char *name; +}; + +struct pmbus_samples_reg { + int page; + struct pmbus_samples_attr *attr; + struct device_attribute dev_attr; +}; + +static struct pmbus_samples_attr pmbus_samples_registers[] = { + { + .reg = PMBUS_VIRT_SAMPLES, + .name = "samples", + }, { + .reg = PMBUS_VIRT_IN_SAMPLES, + .name = "in_samples", + }, { + .reg = PMBUS_VIRT_CURR_SAMPLES, + .name = "curr_samples", + }, { + .reg = PMBUS_VIRT_POWER_SAMPLES, + .name = "power_samples", + }, { + .reg = PMBUS_VIRT_TEMP_SAMPLES, + .name = "temp_samples", + } +}; + +#define to_samples_reg(x) container_of(x, struct pmbus_samples_reg, dev_attr) + +static ssize_t pmbus_show_samples(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int val; + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_samples_reg *reg = to_samples_reg(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + val = _pmbus_read_word_data(client, reg->page, 0xff, reg->attr->reg); + mutex_unlock(&data->update_lock); + if (val < 0) + return val; + + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t pmbus_set_samples(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + int ret; + long val; + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_samples_reg *reg = to_samples_reg(devattr); + struct pmbus_data *data = i2c_get_clientdata(client); + + if (kstrtol(buf, 0, &val) < 0) + return -EINVAL; + + mutex_lock(&data->update_lock); + ret = _pmbus_write_word_data(client, reg->page, reg->attr->reg, val); + mutex_unlock(&data->update_lock); + + return ret ? : count; +} + +static int pmbus_add_samples_attr(struct pmbus_data *data, int page, + struct pmbus_samples_attr *attr) +{ + struct pmbus_samples_reg *reg; + + reg = devm_kzalloc(data->dev, sizeof(*reg), GFP_KERNEL); + if (!reg) + return -ENOMEM; + + reg->attr = attr; + reg->page = page; + + pmbus_dev_attr_init(®->dev_attr, attr->name, 0644, + pmbus_show_samples, pmbus_set_samples); + + return pmbus_add_attribute(data, ®->dev_attr.attr); +} + +static int pmbus_add_samples_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + const struct pmbus_driver_info *info = data->info; + int s; + + if (!(info->func[0] & PMBUS_HAVE_SAMPLES)) + return 0; + + for (s = 0; s < ARRAY_SIZE(pmbus_samples_registers); s++) { + struct pmbus_samples_attr *attr; + int ret; + + attr = &pmbus_samples_registers[s]; + if (!wb_pmbus_check_word_register(client, 0, attr->reg)) + continue; + + ret = pmbus_add_samples_attr(data, 0, attr); + if (ret) + return ret; + } + + return 0; +} + +static int pmbus_find_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + int ret; + + /* Voltage sensors */ + ret = pmbus_add_sensor_attrs(client, data, "in", voltage_attributes, + ARRAY_SIZE(voltage_attributes)); + if (ret) + return ret; + + /* Current sensors */ + ret = pmbus_add_sensor_attrs(client, data, "curr", current_attributes, + ARRAY_SIZE(current_attributes)); + if (ret) + return ret; + + /* Power sensors */ + ret = pmbus_add_sensor_attrs(client, data, "power", power_attributes, + ARRAY_SIZE(power_attributes)); + if (ret) + return ret; + + /* Temperature sensors */ + ret = pmbus_add_sensor_attrs(client, data, "temp", temp_attributes, + ARRAY_SIZE(temp_attributes)); + if (ret) + return ret; + + /* Fans */ + ret = pmbus_add_fan_attributes(client, data); + if (ret) + return ret; + + ret = pmbus_add_samples_attributes(client, data); + return ret; +} + +/* + * Identify chip parameters. + * This function is called for all chips. + */ +static int pmbus_identify_common(struct i2c_client *client, + struct pmbus_data *data, int page) +{ + int vout_mode = -1; + + if (wb_pmbus_check_byte_register(client, page, PMBUS_VOUT_MODE)) + vout_mode = _pmbus_read_byte_data(client, page, + PMBUS_VOUT_MODE); + if (vout_mode >= 0 && vout_mode != 0xff) { + /* + * Not all chips support the VOUT_MODE command, + * so a failure to read it is not an error. + */ + switch (vout_mode >> 5) { + case 0: /* linear mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != linear) + return -ENODEV; + + data->exponent[page] = ((s8)(vout_mode << 3)) >> 3; + break; + case 1: /* VID mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != vid) + return -ENODEV; + break; + case 2: /* direct mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != direct) + return -ENODEV; + break; + default: + return -ENODEV; + } + } + + pmbus_clear_fault_page(client, page); + return 0; +} + +static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, + struct pmbus_driver_info *info) +{ + struct device *dev = &client->dev; + int page, ret, i; + + /* + * Some PMBus chips don't support PMBUS_STATUS_WORD, so try + * to use PMBUS_STATUS_BYTE instead if that is the case. + * Bail out if both registers are not supported. + */ + for(i = 0; i < PMBUS_RETRY_TIME; i++) { + data->read_status = pmbus_read_status_word; + ret = i2c_smbus_read_word_data(client, PMBUS_STATUS_WORD); + if (ret < 0 || ret == 0xffff) { + data->read_status = pmbus_read_status_byte; + ret = i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE); + if (ret < 0 || ret == 0xff) { + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + continue; + } + } else { + data->has_status_word = true; + } + break; + } + + if(i == PMBUS_RETRY_TIME) { + dev_err(dev, "PMBus status register not found\n"); + return -ENODEV; + } + + /* Enable PEC if the controller supports it */ + for(i = 0; i < PMBUS_RETRY_TIME; i++) { + ret = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); + if (ret >= 0) { + break; + } + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + + if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK)) + client->flags |= I2C_CLIENT_PEC; + + /* + * Check if the chip is write protected. If it is, we can not clear + * faults, and we should not try it. Also, in that case, writes into + * limit registers need to be disabled. + */ + for(i = 0; i < PMBUS_RETRY_TIME; i++) { + ret = i2c_smbus_read_byte_data(client, PMBUS_WRITE_PROTECT); + if (ret >= 0) { + break; + } + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + + if (ret > 0 && (ret & PB_WP_ANY)) + data->flags |= PMBUS_WRITE_PROTECTED | PMBUS_SKIP_STATUS_CHECK; + + if (data->info->pages) + wb_pmbus_clear_faults(client); + else + pmbus_clear_fault_page(client, -1); + + if (info->identify) { + ret = (*info->identify)(client, info); + if (ret < 0) { + dev_err(dev, "Chip identification failed\n"); + return ret; + } + } + + if (info->pages <= 0 || info->pages > PMBUS_PAGES) { + dev_err(dev, "Bad number of PMBus pages: %d\n", info->pages); + return -ENODEV; + } + + for (page = 0; page < info->pages; page++) { + ret = pmbus_identify_common(client, data, page); + if (ret < 0) { + dev_err(dev, "Failed to identify chip capabilities\n"); + return ret; + } + } + return 0; +} + +#if IS_ENABLED(CONFIG_REGULATOR) +static int pmbus_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct device *dev = rdev_get_dev(rdev); + struct i2c_client *client = to_i2c_client(dev->parent); + u8 page = rdev_get_id(rdev); + int ret; + + ret = wb_pmbus_read_byte_data(client, page, PMBUS_OPERATION); + if (ret < 0) + return ret; + + return !!(ret & PB_OPERATION_CONTROL_ON); +} + +static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable) +{ + struct device *dev = rdev_get_dev(rdev); + struct i2c_client *client = to_i2c_client(dev->parent); + u8 page = rdev_get_id(rdev); + + return wb_pmbus_update_byte_data(client, page, PMBUS_OPERATION, + PB_OPERATION_CONTROL_ON, + enable ? PB_OPERATION_CONTROL_ON : 0); +} + +static int pmbus_regulator_enable(struct regulator_dev *rdev) +{ + return _pmbus_regulator_on_off(rdev, 1); +} + +static int pmbus_regulator_disable(struct regulator_dev *rdev) +{ + return _pmbus_regulator_on_off(rdev, 0); +} + +const struct regulator_ops wb_pmbus_regulator_ops = { + .enable = pmbus_regulator_enable, + .disable = pmbus_regulator_disable, + .is_enabled = pmbus_regulator_is_enabled, +}; +EXPORT_SYMBOL_GPL(wb_pmbus_regulator_ops); + +static int pmbus_regulator_register(struct pmbus_data *data) +{ + struct device *dev = data->dev; + const struct pmbus_driver_info *info = data->info; + const struct pmbus_platform_data *pdata = dev_get_platdata(dev); + struct regulator_dev *rdev; + int i; + + for (i = 0; i < info->num_regulators; i++) { + struct regulator_config config = { }; + + config.dev = dev; + config.driver_data = data; + + if (pdata && pdata->reg_init_data) + config.init_data = &pdata->reg_init_data[i]; + + rdev = devm_regulator_register(dev, &info->reg_desc[i], + &config); + if (IS_ERR(rdev)) { + dev_err(dev, "Failed to register %s regulator\n", + info->reg_desc[i].name); + return PTR_ERR(rdev); + } + } + + return 0; +} +#else +static int pmbus_regulator_register(struct pmbus_data *data) +{ + return 0; +} +#endif + +static struct dentry *pmbus_debugfs_dir; /* pmbus debugfs directory */ + +#if IS_ENABLED(CONFIG_DEBUG_FS) +static int pmbus_debugfs_get(void *data, u64 *val) +{ + int rc; + struct pmbus_debugfs_entry *entry = data; + + rc = _pmbus_read_byte_data(entry->client, entry->page, entry->reg); + if (rc < 0) + return rc; + + *val = rc; + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops, pmbus_debugfs_get, NULL, + "0x%02llx\n"); + +static int pmbus_debugfs_get_status(void *data, u64 *val) +{ + int rc; + struct pmbus_debugfs_entry *entry = data; + struct pmbus_data *pdata = i2c_get_clientdata(entry->client); + + rc = pdata->read_status(entry->client, entry->page); + if (rc < 0) + return rc; + + *val = rc; + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_status, pmbus_debugfs_get_status, + NULL, "0x%04llx\n"); + +static int pmbus_debugfs_get_pec(void *data, u64 *val) +{ + struct i2c_client *client = data; + + *val = !!(client->flags & I2C_CLIENT_PEC); + + return 0; +} + +static int pmbus_debugfs_set_pec(void *data, u64 val) +{ + int rc; + struct i2c_client *client = data; + + if (!val) { + client->flags &= ~I2C_CLIENT_PEC; + return 0; + } + + if (val != 1) + return -EINVAL; + + rc = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); + if (rc < 0) + return rc; + + if (!(rc & PB_CAPABILITY_ERROR_CHECK)) + return -EOPNOTSUPP; + + client->flags |= I2C_CLIENT_PEC; + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_pec, pmbus_debugfs_get_pec, + pmbus_debugfs_set_pec, "%llu\n"); + +static int pmbus_init_debugfs(struct i2c_client *client, + struct pmbus_data *data) +{ + int i, idx = 0; + char name[PMBUS_NAME_SIZE]; + struct pmbus_debugfs_entry *entries; + + if (!pmbus_debugfs_dir) + return -ENODEV; + + /* + * Create the debugfs directory for this device. Use the hwmon device + * name to avoid conflicts (hwmon numbers are globally unique). + */ + data->debugfs = debugfs_create_dir(dev_name(data->hwmon_dev), + pmbus_debugfs_dir); + if (IS_ERR_OR_NULL(data->debugfs)) { + data->debugfs = NULL; + return -ENODEV; + } + + /* Allocate the max possible entries we need. */ + entries = devm_kcalloc(data->dev, + data->info->pages * 10, sizeof(*entries), + GFP_KERNEL); + if (!entries) + return -ENOMEM; + + debugfs_create_file("pec", 0664, data->debugfs, client, + &pmbus_debugfs_ops_pec); + + for (i = 0; i < data->info->pages; ++i) { + /* Check accessibility of status register if it's not page 0 */ + if (!i || pmbus_check_status_register(client, i)) { + /* No need to set reg as we have special read op. */ + entries[idx].client = client; + entries[idx].page = i; + scnprintf(name, PMBUS_NAME_SIZE, "status%d", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops_status); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_VOUT) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_VOUT; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_vout", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_IOUT) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_IOUT; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_iout", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_INPUT) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_INPUT; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_input", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_TEMP) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_TEMPERATURE; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_temp", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (wb_pmbus_check_byte_register(client, i, PMBUS_STATUS_CML)) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_CML; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_cml", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (wb_pmbus_check_byte_register(client, i, PMBUS_STATUS_OTHER)) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_OTHER; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_other", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (wb_pmbus_check_byte_register(client, i, + PMBUS_STATUS_MFR_SPECIFIC)) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_MFR_SPECIFIC; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_mfr", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_FAN12) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_FAN_12; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_fan12", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + + if (data->info->func[i] & PMBUS_HAVE_STATUS_FAN34) { + entries[idx].client = client; + entries[idx].page = i; + entries[idx].reg = PMBUS_STATUS_FAN_34; + scnprintf(name, PMBUS_NAME_SIZE, "status%d_fan34", i); + debugfs_create_file(name, 0444, data->debugfs, + &entries[idx++], + &pmbus_debugfs_ops); + } + } + + return 0; +} +#else +static int pmbus_init_debugfs(struct i2c_client *client, + struct pmbus_data *data) +{ + return 0; +} +#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ + +int wb_pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info) +{ + struct device *dev = &client->dev; + const struct pmbus_platform_data *pdata = dev_get_platdata(dev); + struct pmbus_data *data; + size_t groups_num = 0; + int ret; + + if (!info) + return -ENODEV; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE + | I2C_FUNC_SMBUS_BYTE_DATA + | I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + if (info->groups) + while (info->groups[groups_num]) + groups_num++; + + data->groups = devm_kcalloc(dev, groups_num + 2, sizeof(void *), + GFP_KERNEL); + if (!data->groups) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->dev = dev; + + if (pdata) + data->flags = pdata->flags; + data->info = info; + data->currpage = -1; + data->currphase = -1; + + ret = pmbus_init_common(client, data, info); + if (ret < 0) + return ret; + + ret = pmbus_find_attributes(client, data); + if (ret) + return ret; + + /* + * If there are no attributes, something is wrong. + * Bail out instead of trying to register nothing. + */ + if (!data->num_attributes) { + dev_err(dev, "No attributes found\n"); + return -ENODEV; + } + + data->groups[0] = &data->group; + memcpy(data->groups + 1, info->groups, sizeof(void *) * groups_num); + data->hwmon_dev = devm_hwmon_device_register_with_groups(dev, + client->name, data, data->groups); + if (IS_ERR(data->hwmon_dev)) { + dev_err(dev, "Failed to register hwmon device\n"); + return PTR_ERR(data->hwmon_dev); + } + + ret = pmbus_regulator_register(data); + if (ret) + return ret; + + ret = pmbus_init_debugfs(client, data); + if (ret) + dev_warn(dev, "Failed to register debugfs\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(wb_pmbus_do_probe); + +int wb_pmbus_do_remove(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + + debugfs_remove_recursive(data->debugfs); + + return 0; +} +EXPORT_SYMBOL_GPL(wb_pmbus_do_remove); + +struct dentry *wb_pmbus_get_debugfs_dir(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + + return data->debugfs; +} +EXPORT_SYMBOL_GPL(wb_pmbus_get_debugfs_dir); + +static int __init pmbus_core_init(void) +{ + pmbus_debugfs_dir = debugfs_create_dir("pmbus", NULL); + if (IS_ERR(pmbus_debugfs_dir)) + pmbus_debugfs_dir = NULL; + + return 0; +} + +static void __exit pmbus_core_exit(void) +{ + debugfs_remove_recursive(pmbus_debugfs_dir); +} + +module_init(pmbus_core_init); +module_exit(pmbus_core_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PMBus core driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tmp401.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tmp401.c new file mode 100644 index 000000000000..4118510b1006 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tmp401.c @@ -0,0 +1,798 @@ +/* tmp401.c + * + * Copyright (C) 2007,2008 Hans de Goede + * Preliminary tmp411 support by: + * Gabriel Konat, Sander Leget, Wouter Willems + * Copyright (C) 2009 Andre Prendel + * + * Cleanup and support for TMP431 and TMP432 by Guenter Roeck + * Copyright (c) 2013 Guenter Roeck + * + * 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. + */ + +/* + * Driver for the Texas Instruments TMP401 SMBUS temperature sensor IC. + * + * Note this IC is in some aspect similar to the LM90, but it has quite a + * few differences too, for example the local temp has a higher resolution + * and thus has 16 bits registers for its value and limit instead of 8 bits. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +/* static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, + 0x4e, 0x4f, I2C_CLIENT_END }; */ + +enum chips { tmp401, tmp411, tmp431, tmp432, tmp435, tmp461 }; + +/* + * The TMP401 registers, note some registers have different addresses for + * reading and writing + */ +#define TMP401_STATUS 0x02 +#define TMP401_CONFIG_READ 0x03 +#define TMP401_CONFIG_WRITE 0x09 +#define TMP401_CONVERSION_RATE_READ 0x04 +#define TMP401_CONVERSION_RATE_WRITE 0x0A +#define TMP401_TEMP_CRIT_HYST 0x21 +#define TMP401_MANUFACTURER_ID_REG 0xFE +#define TMP401_DEVICE_ID_REG 0xFF + +static const u8 TMP401_TEMP_MSB_READ[7][2] = { + { 0x00, 0x01 }, /* temp */ + { 0x06, 0x08 }, /* low limit */ + { 0x05, 0x07 }, /* high limit */ + { 0x20, 0x19 }, /* therm (crit) limit */ + { 0x30, 0x34 }, /* lowest */ + { 0x32, 0x36 }, /* highest */ + { 0, 0x11 }, /* offset */ +}; + +static const u8 TMP401_TEMP_MSB_WRITE[7][2] = { + { 0, 0 }, /* temp (unused) */ + { 0x0C, 0x0E }, /* low limit */ + { 0x0B, 0x0D }, /* high limit */ + { 0x20, 0x19 }, /* therm (crit) limit */ + { 0x30, 0x34 }, /* lowest */ + { 0x32, 0x36 }, /* highest */ + { 0, 0x11 }, /* offset */ +}; + +static const u8 TMP401_TEMP_LSB[7][2] = { + { 0x15, 0x10 }, /* temp */ + { 0x17, 0x14 }, /* low limit */ + { 0x16, 0x13 }, /* high limit */ + { 0, 0 }, /* therm (crit) limit (unused) */ + { 0x31, 0x35 }, /* lowest */ + { 0x33, 0x37 }, /* highest */ + { 0, 0x12 }, /* offset */ +}; + +static const u8 TMP432_TEMP_MSB_READ[4][3] = { + { 0x00, 0x01, 0x23 }, /* temp */ + { 0x06, 0x08, 0x16 }, /* low limit */ + { 0x05, 0x07, 0x15 }, /* high limit */ + { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ +}; + +static const u8 TMP432_TEMP_MSB_WRITE[4][3] = { + { 0, 0, 0 }, /* temp - unused */ + { 0x0C, 0x0E, 0x16 }, /* low limit */ + { 0x0B, 0x0D, 0x15 }, /* high limit */ + { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ +}; + +static const u8 TMP432_TEMP_LSB[3][3] = { + { 0x29, 0x10, 0x24 }, /* temp */ + { 0x3E, 0x14, 0x18 }, /* low limit */ + { 0x3D, 0x13, 0x17 }, /* high limit */ +}; + +/* [0] = fault, [1] = low, [2] = high, [3] = therm/crit */ +static const u8 TMP432_STATUS_REG[] = { + 0x1b, 0x36, 0x35, 0x37 }; + +/* Flags */ +#define TMP401_CONFIG_RANGE BIT(2) +#define TMP401_CONFIG_SHUTDOWN BIT(6) +#define TMP401_STATUS_LOCAL_CRIT BIT(0) +#define TMP401_STATUS_REMOTE_CRIT BIT(1) +#define TMP401_STATUS_REMOTE_OPEN BIT(2) +#define TMP401_STATUS_REMOTE_LOW BIT(3) +#define TMP401_STATUS_REMOTE_HIGH BIT(4) +#define TMP401_STATUS_LOCAL_LOW BIT(5) +#define TMP401_STATUS_LOCAL_HIGH BIT(6) + +/* On TMP432, each status has its own register */ +#define TMP432_STATUS_LOCAL BIT(0) +#define TMP432_STATUS_REMOTE1 BIT(1) +#define TMP432_STATUS_REMOTE2 BIT(2) + +/* Manufacturer / Device ID's */ +#define TMP401_MANUFACTURER_ID 0x55 +#define TMP401_DEVICE_ID 0x11 +#define TMP411A_DEVICE_ID 0x12 +#define TMP411B_DEVICE_ID 0x13 +#define TMP411C_DEVICE_ID 0x10 +#define TMP431_DEVICE_ID 0x31 +#define TMP432_DEVICE_ID 0x32 +#define TMP435_DEVICE_ID 0x35 + +/* + * Driver data (common to all clients) + */ + +static const struct i2c_device_id tmp401_id[] = { + { "wb_tmp401", tmp401 }, + { "wb_tmp411", tmp411 }, + { "wb_tmp431", tmp431 }, + { "wb_tmp432", tmp432 }, + { "wb_tmp435", tmp435 }, + { "wb_tmp461", tmp461 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tmp401_id); + +/* + * Client data (each client gets its own) + */ + +struct tmp401_data { + struct i2c_client *client; + const struct attribute_group *groups[3]; + struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + enum chips kind; + + unsigned int update_interval; /* in milliseconds */ + + /* register values */ + u8 status[4]; + u8 config; + u16 temp[7][3]; + u8 temp_crit_hyst; +}; + +/* + * Sysfs attr show / store functions + */ + +static int tmp401_register_to_temp(u16 reg, u8 config) +{ + int temp = reg; + + if (config & TMP401_CONFIG_RANGE) + temp -= 64 * 256; + + return DIV_ROUND_CLOSEST(temp * 125, 32); +} + +static u16 tmp401_temp_to_register(long temp, u8 config, int zbits) +{ + if (config & TMP401_CONFIG_RANGE) { + temp = clamp_val(temp, -64000, 191000); + temp += 64000; + } else + temp = clamp_val(temp, 0, 127000); + + return DIV_ROUND_CLOSEST(temp * (1 << (8 - zbits)), 1000) << zbits; +} + +static int tmp401_update_device_reg16(struct i2c_client *client, + struct tmp401_data *data) +{ + int i, j, val; + int num_regs = data->kind == tmp411 ? 6 : 4; + int num_sensors = data->kind == tmp432 ? 3 : 2; + + for (i = 0; i < num_sensors; i++) { /* local / r1 / r2 */ + for (j = 0; j < num_regs; j++) { /* temp / low / ... */ + u8 regaddr; + /* + * High byte must be read first immediately followed + * by the low byte + */ + regaddr = data->kind == tmp432 ? + TMP432_TEMP_MSB_READ[j][i] : + TMP401_TEMP_MSB_READ[j][i]; + val = i2c_smbus_read_byte_data(client, regaddr); + if (val < 0) + return val; + data->temp[j][i] = val << 8; + if (j == 3) /* crit is msb only */ + continue; + regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[j][i] + : TMP401_TEMP_LSB[j][i]; + val = i2c_smbus_read_byte_data(client, regaddr); + if (val < 0) + return val; + data->temp[j][i] |= val; + } + } + return 0; +} + +static struct tmp401_data *tmp401_update_device(struct device *dev) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + struct tmp401_data *ret = data; + int i, val; + unsigned long next_update; + + mutex_lock(&data->update_lock); + + next_update = data->last_updated + + msecs_to_jiffies(data->update_interval); + if (time_after(jiffies, next_update) || !data->valid) { + if (data->kind != tmp432) { + /* + * The driver uses the TMP432 status format internally. + * Convert status to TMP432 format for other chips. + */ + val = i2c_smbus_read_byte_data(client, TMP401_STATUS); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->status[0] = + (val & TMP401_STATUS_REMOTE_OPEN) >> 1; + data->status[1] = + ((val & TMP401_STATUS_REMOTE_LOW) >> 2) | + ((val & TMP401_STATUS_LOCAL_LOW) >> 5); + data->status[2] = + ((val & TMP401_STATUS_REMOTE_HIGH) >> 3) | + ((val & TMP401_STATUS_LOCAL_HIGH) >> 6); + data->status[3] = val & (TMP401_STATUS_LOCAL_CRIT + | TMP401_STATUS_REMOTE_CRIT); + } else { + for (i = 0; i < ARRAY_SIZE(data->status); i++) { + val = i2c_smbus_read_byte_data(client, + TMP432_STATUS_REG[i]); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->status[i] = val; + } + } + + val = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->config = val; + val = tmp401_update_device_reg16(client, data); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + val = i2c_smbus_read_byte_data(client, TMP401_TEMP_CRIT_HYST); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->temp_crit_hyst = val; + + data->last_updated = jiffies; + data->valid = 1; + } + +abort: + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t show_temp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int nr = to_sensor_dev_attr_2(devattr)->nr; + int index = to_sensor_dev_attr_2(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%d\n", + tmp401_register_to_temp(data->temp[nr][index], data->config)); +} + +static ssize_t show_temp_crit_hyst(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int temp, index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + mutex_lock(&data->update_lock); + temp = tmp401_register_to_temp(data->temp[3][index], data->config); + temp -= data->temp_crit_hyst * 1000; + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t show_status(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int nr = to_sensor_dev_attr_2(devattr)->nr; + int mask = to_sensor_dev_attr_2(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%d\n", !!(data->status[nr] & mask)); +} + +static ssize_t store_temp(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + int nr = to_sensor_dev_attr_2(devattr)->nr; + int index = to_sensor_dev_attr_2(devattr)->index; + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + long val; + u16 reg; + u8 regaddr; + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + reg = tmp401_temp_to_register(val, data->config, nr == 3 ? 8 : 4); + + mutex_lock(&data->update_lock); + + regaddr = data->kind == tmp432 ? TMP432_TEMP_MSB_WRITE[nr][index] + : TMP401_TEMP_MSB_WRITE[nr][index]; + i2c_smbus_write_byte_data(client, regaddr, reg >> 8); + if (nr != 3) { + regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[nr][index] + : TMP401_TEMP_LSB[nr][index]; + i2c_smbus_write_byte_data(client, regaddr, reg & 0xFF); + } + data->temp[nr][index] = reg; + + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + int temp, index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + long val; + u8 reg; + + if (IS_ERR(data)) + return PTR_ERR(data); + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + if (data->config & TMP401_CONFIG_RANGE) + val = clamp_val(val, -64000, 191000); + else + val = clamp_val(val, 0, 127000); + + mutex_lock(&data->update_lock); + temp = tmp401_register_to_temp(data->temp[3][index], data->config); + val = clamp_val(val, temp - 255000, temp); + reg = ((temp - val) + 500) / 1000; + + i2c_smbus_write_byte_data(data->client, TMP401_TEMP_CRIT_HYST, + reg); + + data->temp_crit_hyst = reg; + + mutex_unlock(&data->update_lock); + + return count; +} + +/* + * Resets the historical measurements of minimum and maximum temperatures. + * This is done by writing any value to any of the minimum/maximum registers + * (0x30-0x37). + */ +static ssize_t reset_temp_history(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + long val; + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + if (val != 1) { + dev_err(dev, + "temp_reset_history value %ld not supported. Use 1 to reset the history!\n", + val); + return -EINVAL; + } + mutex_lock(&data->update_lock); + i2c_smbus_write_byte_data(client, TMP401_TEMP_MSB_WRITE[5][0], val); + data->valid = 0; + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_update_interval(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", data->update_interval); +} + +static ssize_t set_update_interval(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + unsigned long val; + int err, rate; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + /* + * For valid rates, interval can be calculated as + * interval = (1 << (7 - rate)) * 125; + * Rounded rate is therefore + * rate = 7 - __fls(interval * 4 / (125 * 3)); + * Use clamp_val() to avoid overflows, and to ensure valid input + * for __fls. + */ + val = clamp_val(val, 125, 16000); + rate = 7 - __fls(val * 4 / (125 * 3)); + mutex_lock(&data->update_lock); + i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, rate); + data->update_interval = (1 << (7 - rate)) * 125; + mutex_unlock(&data->update_lock); + + return count; +} + +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); +static SENSOR_DEVICE_ATTR_2(temp1_min, S_IWUSR | S_IRUGO, show_temp, + store_temp, 1, 0); +static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp, + store_temp, 2, 0); +static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IWUSR | S_IRUGO, show_temp, + store_temp, 3, 0); +static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, + show_temp_crit_hyst, store_temp_crit_hyst, 0); +static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_status, NULL, + 1, TMP432_STATUS_LOCAL); +static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_status, NULL, + 2, TMP432_STATUS_LOCAL); +static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_status, NULL, + 3, TMP432_STATUS_LOCAL); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1); +static SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp, + store_temp, 1, 1); +static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp, + store_temp, 2, 1); +static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IWUSR | S_IRUGO, show_temp, + store_temp, 3, 1); +static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, + NULL, 1); +static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_status, NULL, + 0, TMP432_STATUS_REMOTE1); +static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_status, NULL, + 1, TMP432_STATUS_REMOTE1); +static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_status, NULL, + 2, TMP432_STATUS_REMOTE1); +static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_status, NULL, + 3, TMP432_STATUS_REMOTE1); + +static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, + set_update_interval); + +static struct attribute *tmp401_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + + &dev_attr_update_interval.attr, + + NULL +}; + +static const struct attribute_group tmp401_group = { + .attrs = tmp401_attributes, +}; + +/* + * Additional features of the TMP411 chip. + * The TMP411 stores the minimum and maximum + * temperature measured since power-on, chip-reset, or + * minimum and maximum register reset for both the local + * and remote channels. + */ +static SENSOR_DEVICE_ATTR_2(temp1_lowest, S_IRUGO, show_temp, NULL, 4, 0); +static SENSOR_DEVICE_ATTR_2(temp1_highest, S_IRUGO, show_temp, NULL, 5, 0); +static SENSOR_DEVICE_ATTR_2(temp2_lowest, S_IRUGO, show_temp, NULL, 4, 1); +static SENSOR_DEVICE_ATTR_2(temp2_highest, S_IRUGO, show_temp, NULL, 5, 1); +static SENSOR_DEVICE_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, + 0); + +static struct attribute *tmp411_attributes[] = { + &sensor_dev_attr_temp1_highest.dev_attr.attr, + &sensor_dev_attr_temp1_lowest.dev_attr.attr, + &sensor_dev_attr_temp2_highest.dev_attr.attr, + &sensor_dev_attr_temp2_lowest.dev_attr.attr, + &sensor_dev_attr_temp_reset_history.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp411_group = { + .attrs = tmp411_attributes, +}; + +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2); +static SENSOR_DEVICE_ATTR_2(temp3_min, S_IWUSR | S_IRUGO, show_temp, + store_temp, 1, 2); +static SENSOR_DEVICE_ATTR_2(temp3_max, S_IWUSR | S_IRUGO, show_temp, + store_temp, 2, 2); +static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IWUSR | S_IRUGO, show_temp, + store_temp, 3, 2); +static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, + NULL, 2); +static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_status, NULL, + 0, TMP432_STATUS_REMOTE2); +static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_status, NULL, + 1, TMP432_STATUS_REMOTE2); +static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_status, NULL, + 2, TMP432_STATUS_REMOTE2); +static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_status, NULL, + 3, TMP432_STATUS_REMOTE2); + +static struct attribute *tmp432_attributes[] = { + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + + NULL +}; + +static const struct attribute_group tmp432_group = { + .attrs = tmp432_attributes, +}; + +/* + * Additional features of the TMP461 chip. + * The TMP461 temperature offset for the remote channel. + */ +static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IWUSR | S_IRUGO, show_temp, + store_temp, 6, 1); + +static struct attribute *tmp461_attributes[] = { + &sensor_dev_attr_temp2_offset.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp461_group = { + .attrs = tmp461_attributes, +}; + +/* + * Begin non sysfs callback code (aka Real code) + */ + +static int tmp401_init_client(struct tmp401_data *data, + struct i2c_client *client) +{ + int config, config_orig, status = 0; + + /* Set the conversion rate to 2 Hz */ + i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); + data->update_interval = 500; + + /* Start conversions (disable shutdown if necessary) */ + config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); + if (config < 0) + return config; + + config_orig = config; + config &= ~TMP401_CONFIG_SHUTDOWN; + + if (config != config_orig) + status = i2c_smbus_write_byte_data(client, + TMP401_CONFIG_WRITE, + config); + + return status; +} + +#if 0 +static int tmp401_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + enum chips kind; + struct i2c_adapter *adapter = client->adapter; + u8 reg; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + /* Detect and identify the chip */ + reg = i2c_smbus_read_byte_data(client, TMP401_MANUFACTURER_ID_REG); + if (reg != TMP401_MANUFACTURER_ID) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG); + + switch (reg) { + case TMP401_DEVICE_ID: + if (client->addr != 0x4c) + return -ENODEV; + kind = tmp401; + break; + case TMP411A_DEVICE_ID: + if (client->addr != 0x4c) + return -ENODEV; + kind = tmp411; + break; + case TMP411B_DEVICE_ID: + if (client->addr != 0x4d) + return -ENODEV; + kind = tmp411; + break; + case TMP411C_DEVICE_ID: + if (client->addr != 0x4e) + return -ENODEV; + kind = tmp411; + break; + case TMP431_DEVICE_ID: + if (client->addr != 0x4c && client->addr != 0x4d) + return -ENODEV; + kind = tmp431; + break; + case TMP432_DEVICE_ID: + if (client->addr != 0x4c && client->addr != 0x4d) + return -ENODEV; + kind = tmp432; + break; + case TMP435_DEVICE_ID: + kind = tmp435; + break; + default: + return -ENODEV; + } + + reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); + if (reg & 0x1b) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, TMP401_CONVERSION_RATE_READ); + /* Datasheet says: 0x1-0x6 */ + if (reg > 15) + return -ENODEV; + + strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE); + + return 0; +} +#endif + +static int tmp401_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + static const char * const names[] = { + "TMP401", "TMP411", "TMP431", "TMP432", "TMP435", "TMP461" + }; + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct tmp401_data *data; + int groups = 0, status; + + data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + mutex_init(&data->update_lock); + data->kind = id->driver_data; + + /* Initialize the TMP401 chip */ + status = tmp401_init_client(data, client); + if (status < 0) + return status; + + /* Register sysfs hooks */ + data->groups[groups++] = &tmp401_group; + + /* Register additional tmp411 sysfs hooks */ + if (data->kind == tmp411) + data->groups[groups++] = &tmp411_group; + + /* Register additional tmp432 sysfs hooks */ + if (data->kind == tmp432) + data->groups[groups++] = &tmp432_group; + + if (data->kind == tmp461) + data->groups[groups++] = &tmp461_group; + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + dev_info(dev, "Detected TI %s chip\n", names[data->kind]); + + return 0; +} + +static struct i2c_driver tmp401_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "wb_tmp401", + }, + .probe = tmp401_probe, + .id_table = tmp401_id, + /* .detect = tmp401_detect, */ + /* .address_list = normal_i2c, */ +}; + +module_i2c_driver(tmp401_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tps53622.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tps53622.c new file mode 100644 index 000000000000..b68196d9f57c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_tps53622.c @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Hardware monitoring driver for Texas Instruments TPS53679 + * + * Copyright (c) 2017 Mellanox Technologies. All rights reserved. + * Copyright (c) 2017 Vadim Pasternak + */ + +#include +#include +#include +#include +#include +#include +#include +#include "wb_pmbus.h" + +enum chips { + tps53647, tps53667, tps53679, tps53681, tps53688, tps53622 +}; + +#define TPS53647_PAGE_NUM 1 + +#define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */ +#define TPS53679_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */ +#define TPS53679_PROT_VR13_10MV 0x04 /* VR13.0 mode, 10-mV DAC */ +#define TPS53679_PROT_IMVP8_5MV 0x05 /* IMVP8 mode, 5-mV DAC */ +#define TPS53679_PROT_VR13_5MV 0x07 /* VR13.0 mode, 5-mV DAC */ +#define TPS53679_PAGE_NUM 2 + +#define TPS53681_DEVICE_ID 0x81 + +#define TPS53681_PMBUS_REVISION 0x33 + +#define TPS53681_MFR_SPECIFIC_20 0xe4 /* Number of phases, per page */ + +static const struct i2c_device_id tps53679_id[]; + +static int tps53679_identify_mode(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + u8 vout_params; + int i, ret; + + for (i = 0; i < info->pages; i++) { + /* Read the register with VOUT scaling value.*/ + ret = wb_pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); + if (ret < 0) + return ret; + + vout_params = ret & GENMASK(4, 0); + + switch (vout_params) { + case TPS53679_PROT_VR13_10MV: + case TPS53679_PROT_VR12_5_10MV: + info->vrm_version[i] = vr13; + break; + case TPS53679_PROT_VR13_5MV: + case TPS53679_PROT_VR12_5MV: + case TPS53679_PROT_IMVP8_5MV: + info->vrm_version[i] = vr12; + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int tps53679_identify_phases(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int ret; + + /* On TPS53681, only channel A provides per-phase output current */ + ret = wb_pmbus_read_byte_data(client, 0, TPS53681_MFR_SPECIFIC_20); + if (ret < 0) + return ret; + info->phases[0] = (ret & 0x07) + 1; + + return 0; +} + +static int tps53679_identify_chip(struct i2c_client *client, + u8 revision, u16 id) +{ + u8 buf[I2C_SMBUS_BLOCK_MAX]; + int ret; + + ret = wb_pmbus_read_byte_data(client, 0, PMBUS_REVISION); + if (ret < 0) + return ret; + if (ret != revision) { + dev_err(&client->dev, "Unexpected PMBus revision 0x%x\n", ret); + return -ENODEV; + } + + ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf); + if (ret < 0) + return ret; + if (ret != 1 || buf[0] != id) { + dev_err(&client->dev, "Unexpected device ID 0x%x\n", buf[0]); + return -ENODEV; + } + return 0; +} + +/* + * Common identification function for chips with multi-phase support. + * Since those chips have special configuration registers, we want to have + * some level of reassurance that we are really talking with the chip + * being probed. Check PMBus revision and chip ID. + */ +static int tps53679_identify_multiphase(struct i2c_client *client, + struct pmbus_driver_info *info, + int pmbus_rev, int device_id) +{ + int ret; + + ret = tps53679_identify_chip(client, pmbus_rev, device_id); + if (ret < 0) + return ret; + + ret = tps53679_identify_mode(client, info); + if (ret < 0) + return ret; + + return tps53679_identify_phases(client, info); +} + +static int tps53679_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + return tps53679_identify_mode(client, info); +} + +static int tps53681_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + return tps53679_identify_multiphase(client, info, + TPS53681_PMBUS_REVISION, + TPS53681_DEVICE_ID); +} + +static int tps53681_read_word_data(struct i2c_client *client, int page, + int phase, int reg) +{ + /* + * For reading the total output current (READ_IOUT) for all phases, + * the chip datasheet is a bit vague. It says "PHASE must be set to + * FFh to access all phases simultaneously. PHASE may also be set to + * 80h readack (!) the total phase current". + * Experiments show that the command does _not_ report the total + * current for all phases if the phase is set to 0xff. Instead, it + * appears to report the current of one of the phases. Override phase + * parameter with 0x80 when reading the total output current on page 0. + */ + if (reg == PMBUS_READ_IOUT && page == 0 && phase == 0xff) + return wb_pmbus_read_word_data(client, page, 0x80, reg); + return -ENODATA; +} + +static struct pmbus_driver_info tps53679_info = { + .format[PSC_VOLTAGE_IN] = linear, + .format[PSC_VOLTAGE_OUT] = vid, + .format[PSC_TEMPERATURE] = linear, + .format[PSC_CURRENT_OUT] = linear, + .format[PSC_POWER] = linear, + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | + PMBUS_HAVE_STATUS_INPUT | + PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | + PMBUS_HAVE_POUT, + .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | + PMBUS_HAVE_POUT, + .pfunc[0] = PMBUS_HAVE_IOUT, + .pfunc[1] = PMBUS_HAVE_IOUT, + .pfunc[2] = PMBUS_HAVE_IOUT, + .pfunc[3] = PMBUS_HAVE_IOUT, + .pfunc[4] = PMBUS_HAVE_IOUT, + .pfunc[5] = PMBUS_HAVE_IOUT, +}; + +static int tps53679_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct pmbus_driver_info *info; + enum chips chip_id; + + if (dev->of_node) + chip_id = (enum chips)of_device_get_match_data(dev); + else + chip_id = i2c_match_id(tps53679_id, client)->driver_data; + + info = devm_kmemdup(dev, &tps53679_info, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + switch (chip_id) { + case tps53647: + case tps53667: + info->pages = TPS53647_PAGE_NUM; + info->identify = tps53679_identify; + break; + case tps53679: + case tps53688: + case tps53622: + info->pages = TPS53679_PAGE_NUM; + info->identify = tps53679_identify; + break; + case tps53681: + info->pages = TPS53679_PAGE_NUM; + info->phases[0] = 6; + info->identify = tps53681_identify; + info->read_word_data = tps53681_read_word_data; + break; + default: + return -ENODEV; + } + + return wb_pmbus_do_probe(client, info); +} + +static const struct i2c_device_id tps53679_id[] = { + {"wb_tps53647", tps53647}, + {"wb_tps53667", tps53667}, + {"wb_tps53679", tps53679}, + {"wb_tps53681", tps53681}, + {"wb_tps53688", tps53688}, + {"wb_tps53622", tps53622}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, tps53679_id); + +static const struct of_device_id __maybe_unused tps53679_of_match[] = { + {.compatible = "ti,wb_tps53647", .data = (void *)tps53647}, + {.compatible = "ti,wb_tps53667", .data = (void *)tps53667}, + {.compatible = "ti,wb_tps53679", .data = (void *)tps53679}, + {.compatible = "ti,wb_tps53681", .data = (void *)tps53681}, + {.compatible = "ti,wb_tps53688", .data = (void *)tps53688}, + {.compatible = "ti,wb_tps53622", .data = (void *)tps53622}, + {} +}; +MODULE_DEVICE_TABLE(of, tps53679_of_match); + +static struct i2c_driver tps53679_driver = { + .driver = { + .name = "wb_tps53622", + .of_match_table = of_match_ptr(tps53679_of_match), + }, + .probe_new = tps53679_probe, + .remove = wb_pmbus_do_remove, + .id_table = tps53679_id, +}; + +module_i2c_driver(tps53679_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PMBus driver for Texas Instruments TPS53679"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ucd9000.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ucd9000.c new file mode 100644 index 000000000000..9b967f141a86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/linux-5.10/wb_ucd9000.c @@ -0,0 +1,675 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Hardware monitoring driver for UCD90xxx Sequencer and System Health + * Controller series + * + * Copyright (C) 2011 Ericsson AB. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_pmbus.h" + +enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd90320, ucd9090, + ucd90910 }; + +#define UCD9000_MONITOR_CONFIG 0xd5 +#define UCD9000_NUM_PAGES 0xd6 +#define UCD9000_FAN_CONFIG_INDEX 0xe7 +#define UCD9000_FAN_CONFIG 0xe8 +#define UCD9000_MFR_STATUS 0xf3 +#define UCD9000_GPIO_SELECT 0xfa +#define UCD9000_GPIO_CONFIG 0xfb +#define UCD9000_DEVICE_ID 0xfd + +/* GPIO CONFIG bits */ +#define UCD9000_GPIO_CONFIG_ENABLE BIT(0) +#define UCD9000_GPIO_CONFIG_OUT_ENABLE BIT(1) +#define UCD9000_GPIO_CONFIG_OUT_VALUE BIT(2) +#define UCD9000_GPIO_CONFIG_STATUS BIT(3) +#define UCD9000_GPIO_INPUT 0 +#define UCD9000_GPIO_OUTPUT 1 + +#define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07) +#define UCD9000_MON_PAGE(x) ((x) & 0x1f) + +#define UCD9000_MON_VOLTAGE 1 +#define UCD9000_MON_TEMPERATURE 2 +#define UCD9000_MON_CURRENT 3 +#define UCD9000_MON_VOLTAGE_HW 4 + +#define UCD9000_NUM_FAN 4 + +#define UCD9000_GPIO_NAME_LEN 16 +#define UCD9090_NUM_GPIOS 23 +#define UCD901XX_NUM_GPIOS 26 +#define UCD90320_NUM_GPIOS 84 +#define UCD90910_NUM_GPIOS 26 + +#define UCD9000_DEBUGFS_NAME_LEN 24 +#define UCD9000_GPI_COUNT 8 +#define UCD90320_GPI_COUNT 32 + +#define UCD9000_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define UCD9000_RETRY_TIME (3) +#define WB_DEV_NAME_MAX_LEN (64) + +static int g_wb_ucd9000_debug = 0; +static int g_wb_ucd9000_error = 0; + +module_param(g_wb_ucd9000_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_ucd9000_error, int, S_IRUGO | S_IWUSR); + +#define WB_UDC9000_VERBOSE(fmt, args...) do { \ + if (g_wb_ucd9000_debug) { \ + printk(KERN_INFO "[WB_UCD9000][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_UDC9000_ERROR(fmt, args...) do { \ + if (g_wb_ucd9000_error) { \ + printk(KERN_ERR "[WB_UCD9000][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct ucd9000_data { + u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX]; + struct pmbus_driver_info info; +#ifdef CONFIG_GPIOLIB + struct gpio_chip gpio; +#endif + struct dentry *debugfs; +}; +#define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info) + +struct ucd9000_debugfs_entry { + struct i2c_client *client; + u8 index; +}; + +static int wb_i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values) +{ + int rv, i; + + for(i = 0; i < UCD9000_RETRY_TIME; i++) { + rv = i2c_smbus_read_block_data(client, command, values); + if(rv >= 0){ + return rv; + } + usleep_range(UCD9000_RETRY_SLEEP_TIME, UCD9000_RETRY_SLEEP_TIME + 1); + } + WB_UDC9000_ERROR("read_block_data failed. nr:%d, addr:0x%x, reg:0x%x, rv:%d.", + client->adapter->nr, client->addr, command, rv); + return rv; +} + +static int ucd9000_get_fan_config(struct i2c_client *client, int fan) +{ + int fan_config = 0; + struct ucd9000_data *data + = to_ucd9000_data(wb_pmbus_get_driver_info(client)); + + if (data->fan_data[fan][3] & 1) + fan_config |= PB_FAN_2_INSTALLED; /* Use lower bit position */ + + /* Pulses/revolution */ + fan_config |= (data->fan_data[fan][3] & 0x06) >> 1; + + return fan_config; +} + +static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg) +{ + int ret = 0; + int fan_config; + + switch (reg) { + case PMBUS_FAN_CONFIG_12: + if (page > 0) + return -ENXIO; + + ret = ucd9000_get_fan_config(client, 0); + if (ret < 0) + return ret; + fan_config = ret << 4; + ret = ucd9000_get_fan_config(client, 1); + if (ret < 0) + return ret; + fan_config |= ret; + ret = fan_config; + break; + case PMBUS_FAN_CONFIG_34: + if (page > 0) + return -ENXIO; + + ret = ucd9000_get_fan_config(client, 2); + if (ret < 0) + return ret; + fan_config = ret << 4; + ret = ucd9000_get_fan_config(client, 3); + if (ret < 0) + return ret; + fan_config |= ret; + ret = fan_config; + break; + default: + ret = -ENODATA; + break; + } + return ret; +} + +static const struct i2c_device_id ucd9000_id[] = { + {"wb_ucd9000", ucd9000}, + {"wb_ucd90120", ucd90120}, + {"wb_ucd90124", ucd90124}, + {"wb_ucd90160", ucd90160}, + {"wb_ucd90320", ucd90320}, + {"wb_ucd9090", ucd9090}, + {"wb_ucd90910", ucd90910}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ucd9000_id); + +static const struct of_device_id __maybe_unused ucd9000_of_match[] = { + { + .compatible = "ti,wb_ucd9000", + .data = (void *)ucd9000 + }, + { + .compatible = "ti,wb_ucd90120", + .data = (void *)ucd90120 + }, + { + .compatible = "ti,wb_ucd90124", + .data = (void *)ucd90124 + }, + { + .compatible = "ti,wb_ucd90160", + .data = (void *)ucd90160 + }, + { + .compatible = "ti,wb_ucd90320", + .data = (void *)ucd90320 + }, + { + .compatible = "ti,wb_ucd9090", + .data = (void *)ucd9090 + }, + { + .compatible = "ti,wb_ucd90910", + .data = (void *)ucd90910 + }, + { }, +}; +MODULE_DEVICE_TABLE(of, ucd9000_of_match); + +#ifdef CONFIG_GPIOLIB +static int ucd9000_gpio_read_config(struct i2c_client *client, + unsigned int offset) +{ + int ret; + + /* No page set required */ + ret = i2c_smbus_write_byte_data(client, UCD9000_GPIO_SELECT, offset); + if (ret < 0) + return ret; + + return i2c_smbus_read_byte_data(client, UCD9000_GPIO_CONFIG); +} + +static int ucd9000_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct i2c_client *client = gpiochip_get_data(gc); + int ret; + + ret = ucd9000_gpio_read_config(client, offset); + if (ret < 0) + return ret; + + return !!(ret & UCD9000_GPIO_CONFIG_STATUS); +} + +static void ucd9000_gpio_set(struct gpio_chip *gc, unsigned int offset, + int value) +{ + struct i2c_client *client = gpiochip_get_data(gc); + int ret; + + ret = ucd9000_gpio_read_config(client, offset); + if (ret < 0) { + dev_dbg(&client->dev, "failed to read GPIO %d config: %d\n", + offset, ret); + return; + } + + if (value) { + if (ret & UCD9000_GPIO_CONFIG_STATUS) + return; + + ret |= UCD9000_GPIO_CONFIG_STATUS; + } else { + if (!(ret & UCD9000_GPIO_CONFIG_STATUS)) + return; + + ret &= ~UCD9000_GPIO_CONFIG_STATUS; + } + + ret |= UCD9000_GPIO_CONFIG_ENABLE; + + /* Page set not required */ + ret = i2c_smbus_write_byte_data(client, UCD9000_GPIO_CONFIG, ret); + if (ret < 0) { + dev_dbg(&client->dev, "Failed to write GPIO %d config: %d\n", + offset, ret); + return; + } + + ret &= ~UCD9000_GPIO_CONFIG_ENABLE; + + ret = i2c_smbus_write_byte_data(client, UCD9000_GPIO_CONFIG, ret); + if (ret < 0) + dev_dbg(&client->dev, "Failed to write GPIO %d config: %d\n", + offset, ret); +} + +static int ucd9000_gpio_get_direction(struct gpio_chip *gc, + unsigned int offset) +{ + struct i2c_client *client = gpiochip_get_data(gc); + int ret; + + ret = ucd9000_gpio_read_config(client, offset); + if (ret < 0) + return ret; + + return !(ret & UCD9000_GPIO_CONFIG_OUT_ENABLE); +} + +static int ucd9000_gpio_set_direction(struct gpio_chip *gc, + unsigned int offset, bool direction_out, + int requested_out) +{ + struct i2c_client *client = gpiochip_get_data(gc); + int ret, config, out_val; + + ret = ucd9000_gpio_read_config(client, offset); + if (ret < 0) + return ret; + + if (direction_out) { + out_val = requested_out ? UCD9000_GPIO_CONFIG_OUT_VALUE : 0; + + if (ret & UCD9000_GPIO_CONFIG_OUT_ENABLE) { + if ((ret & UCD9000_GPIO_CONFIG_OUT_VALUE) == out_val) + return 0; + } else { + ret |= UCD9000_GPIO_CONFIG_OUT_ENABLE; + } + + if (out_val) + ret |= UCD9000_GPIO_CONFIG_OUT_VALUE; + else + ret &= ~UCD9000_GPIO_CONFIG_OUT_VALUE; + + } else { + if (!(ret & UCD9000_GPIO_CONFIG_OUT_ENABLE)) + return 0; + + ret &= ~UCD9000_GPIO_CONFIG_OUT_ENABLE; + } + + ret |= UCD9000_GPIO_CONFIG_ENABLE; + config = ret; + + /* Page set not required */ + ret = i2c_smbus_write_byte_data(client, UCD9000_GPIO_CONFIG, config); + if (ret < 0) + return ret; + + config &= ~UCD9000_GPIO_CONFIG_ENABLE; + + return i2c_smbus_write_byte_data(client, UCD9000_GPIO_CONFIG, config); +} + +static int ucd9000_gpio_direction_input(struct gpio_chip *gc, + unsigned int offset) +{ + return ucd9000_gpio_set_direction(gc, offset, UCD9000_GPIO_INPUT, 0); +} + +static int ucd9000_gpio_direction_output(struct gpio_chip *gc, + unsigned int offset, int val) +{ + return ucd9000_gpio_set_direction(gc, offset, UCD9000_GPIO_OUTPUT, + val); +} + +static void ucd9000_probe_gpio(struct i2c_client *client, + const struct i2c_device_id *mid, + struct ucd9000_data *data) +{ + int rc; + + switch (mid->driver_data) { + case ucd9090: + data->gpio.ngpio = UCD9090_NUM_GPIOS; + break; + case ucd90120: + case ucd90124: + case ucd90160: + data->gpio.ngpio = UCD901XX_NUM_GPIOS; + break; + case ucd90320: + data->gpio.ngpio = UCD90320_NUM_GPIOS; + break; + case ucd90910: + data->gpio.ngpio = UCD90910_NUM_GPIOS; + break; + default: + return; /* GPIO support is optional. */ + } + + /* + * Pinmux support has not been added to the new gpio_chip. + * This support should be added when possible given the mux + * behavior of these IO devices. + */ + data->gpio.label = client->name; + data->gpio.get_direction = ucd9000_gpio_get_direction; + data->gpio.direction_input = ucd9000_gpio_direction_input; + data->gpio.direction_output = ucd9000_gpio_direction_output; + data->gpio.get = ucd9000_gpio_get; + data->gpio.set = ucd9000_gpio_set; + data->gpio.can_sleep = true; + data->gpio.base = -1; + data->gpio.parent = &client->dev; + + rc = devm_gpiochip_add_data(&client->dev, &data->gpio, client); + if (rc) + dev_warn(&client->dev, "Could not add gpiochip: %d\n", rc); +} +#else +static void ucd9000_probe_gpio(struct i2c_client *client, + const struct i2c_device_id *mid, + struct ucd9000_data *data) +{ +} +#endif /* CONFIG_GPIOLIB */ + +#ifdef CONFIG_DEBUG_FS +static int ucd9000_get_mfr_status(struct i2c_client *client, u8 *buffer) +{ + int ret = wb_pmbus_set_page(client, 0, 0xff); + + if (ret < 0) + return ret; + + return wb_i2c_smbus_read_block_data(client, UCD9000_MFR_STATUS, buffer); +} + +static int ucd9000_debugfs_show_mfr_status_bit(void *data, u64 *val) +{ + struct ucd9000_debugfs_entry *entry = data; + struct i2c_client *client = entry->client; + u8 buffer[I2C_SMBUS_BLOCK_MAX]; + int ret, i; + + ret = ucd9000_get_mfr_status(client, buffer); + if (ret < 0) + return ret; + + /* + * GPI fault bits are in sets of 8, two bytes from end of response. + */ + i = ret - 3 - entry->index / 8; + if (i >= 0) + *val = !!(buffer[i] & BIT(entry->index % 8)); + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(ucd9000_debugfs_mfr_status_bit, + ucd9000_debugfs_show_mfr_status_bit, NULL, "%1lld\n"); + +static ssize_t ucd9000_debugfs_read_mfr_status(struct file *file, + char __user *buf, size_t count, + loff_t *ppos) +{ + struct i2c_client *client = file->private_data; + u8 buffer[I2C_SMBUS_BLOCK_MAX]; + char str[(I2C_SMBUS_BLOCK_MAX * 2) + 2]; + char *res; + int rc; + + rc = ucd9000_get_mfr_status(client, buffer); + if (rc < 0) + return rc; + + res = bin2hex(str, buffer, min(rc, I2C_SMBUS_BLOCK_MAX)); + *res++ = '\n'; + *res = 0; + + return simple_read_from_buffer(buf, count, ppos, str, res - str); +} + +static const struct file_operations ucd9000_debugfs_show_mfr_status_fops = { + .llseek = noop_llseek, + .read = ucd9000_debugfs_read_mfr_status, + .open = simple_open, +}; + +static int ucd9000_init_debugfs(struct i2c_client *client, + const struct i2c_device_id *mid, + struct ucd9000_data *data) +{ + struct dentry *debugfs; + struct ucd9000_debugfs_entry *entries; + int i, gpi_count; + char name[UCD9000_DEBUGFS_NAME_LEN]; + + debugfs = wb_pmbus_get_debugfs_dir(client); + if (!debugfs) + return -ENOENT; + + data->debugfs = debugfs_create_dir(client->name, debugfs); + if (!data->debugfs) + return -ENOENT; + + /* + * Of the chips this driver supports, only the UCD9090, UCD90160, + * UCD90320, and UCD90910 report GPI faults in their MFR_STATUS + * register, so only create the GPI fault debugfs attributes for those + * chips. + */ + if (mid->driver_data == ucd9090 || mid->driver_data == ucd90160 || + mid->driver_data == ucd90320 || mid->driver_data == ucd90910) { + gpi_count = mid->driver_data == ucd90320 ? UCD90320_GPI_COUNT + : UCD9000_GPI_COUNT; + entries = devm_kcalloc(&client->dev, + gpi_count, sizeof(*entries), + GFP_KERNEL); + if (!entries) + return -ENOMEM; + + for (i = 0; i < gpi_count; i++) { + entries[i].client = client; + entries[i].index = i; + scnprintf(name, UCD9000_DEBUGFS_NAME_LEN, + "gpi%d_alarm", i + 1); + debugfs_create_file(name, 0444, data->debugfs, + &entries[i], + &ucd9000_debugfs_mfr_status_bit); + } + } + + scnprintf(name, UCD9000_DEBUGFS_NAME_LEN, "mfr_status"); + debugfs_create_file(name, 0444, data->debugfs, client, + &ucd9000_debugfs_show_mfr_status_fops); + + return 0; +} +#else +static int ucd9000_init_debugfs(struct i2c_client *client, + const struct i2c_device_id *mid, + struct ucd9000_data *data) +{ + return 0; +} +#endif /* CONFIG_DEBUG_FS */ + +static int ucd9000_probe(struct i2c_client *client) +{ + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; + char wb_device_name[WB_DEV_NAME_MAX_LEN]; + struct ucd9000_data *data; + struct pmbus_driver_info *info; + const struct i2c_device_id *mid; + enum chips chip; + int i, ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA)) + return -ENODEV; + + ret = wb_i2c_smbus_read_block_data(client, UCD9000_DEVICE_ID, + block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read device ID\n"); + return ret; + } + block_buffer[ret] = '\0'; + dev_info(&client->dev, "Device ID %s\n", block_buffer); + + mem_clear(wb_device_name, sizeof(wb_device_name)); + snprintf(wb_device_name, sizeof(wb_device_name), "wb_%s", block_buffer); + + for (mid = ucd9000_id; mid->name[0]; mid++) { + if (!strncasecmp(mid->name, wb_device_name, strlen(mid->name))) + break; + } + if (!mid->name[0]) { + dev_err(&client->dev, "Unsupported device\n"); + return -ENODEV; + } + + if (client->dev.of_node) + chip = (enum chips)of_device_get_match_data(&client->dev); + else + chip = mid->driver_data; + + if (chip != ucd9000 && strcmp(client->name, mid->name) != 0) + dev_notice(&client->dev, + "Device mismatch: Configured %s, detected %s\n", + client->name, mid->name); + + data = devm_kzalloc(&client->dev, sizeof(struct ucd9000_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + info = &data->info; + + ret = i2c_smbus_read_byte_data(client, UCD9000_NUM_PAGES); + if (ret < 0) { + dev_err(&client->dev, + "Failed to read number of active pages\n"); + return ret; + } + info->pages = ret; + if (!info->pages) { + dev_err(&client->dev, "No pages configured\n"); + return -ENODEV; + } + + /* The internal temperature sensor is always active */ + info->func[0] = PMBUS_HAVE_TEMP; + + /* Everything else is configurable */ + ret = wb_i2c_smbus_read_block_data(client, UCD9000_MONITOR_CONFIG, + block_buffer); + if (ret <= 0) { + dev_err(&client->dev, "Failed to read configuration data\n"); + return -ENODEV; + } + for (i = 0; i < ret; i++) { + int page = UCD9000_MON_PAGE(block_buffer[i]); + + if (page >= info->pages) + continue; + + switch (UCD9000_MON_TYPE(block_buffer[i])) { + case UCD9000_MON_VOLTAGE: + case UCD9000_MON_VOLTAGE_HW: + info->func[page] |= PMBUS_HAVE_VOUT + | PMBUS_HAVE_STATUS_VOUT; + break; + case UCD9000_MON_TEMPERATURE: + info->func[page] |= PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_STATUS_TEMP; + break; + case UCD9000_MON_CURRENT: + info->func[page] |= PMBUS_HAVE_IOUT + | PMBUS_HAVE_STATUS_IOUT; + break; + default: + break; + } + } + + /* Fan configuration */ + if (mid->driver_data == ucd90124) { + for (i = 0; i < UCD9000_NUM_FAN; i++) { + i2c_smbus_write_byte_data(client, + UCD9000_FAN_CONFIG_INDEX, i); + ret = wb_i2c_smbus_read_block_data(client, + UCD9000_FAN_CONFIG, + data->fan_data[i]); + if (ret < 0) + return ret; + } + i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0); + + info->read_byte_data = ucd9000_read_byte_data; + info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 + | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34; + } + + ucd9000_probe_gpio(client, mid, data); + + ret = wb_pmbus_do_probe(client, info); + if (ret) + return ret; + + ret = ucd9000_init_debugfs(client, mid, data); + if (ret) + dev_warn(&client->dev, "Failed to register debugfs: %d\n", + ret); + + return 0; +} + +/* This is the driver that will be inserted */ +static struct i2c_driver ucd9000_driver = { + .driver = { + .name = "wb_ucd9000", + .of_match_table = of_match_ptr(ucd9000_of_match), + }, + .probe_new = ucd9000_probe, + .remove = wb_pmbus_do_remove, + .id_table = ucd9000_id, +}; + +module_i2c_driver(ucd9000_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_cpld_i2c_ocores.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_cpld_i2c_ocores.c deleted file mode 100755 index 7115fdabec1d..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_cpld_i2c_ocores.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - * i2c-ocores.c: I2C bus driver for OpenCores I2C controller - * (http://www.opencores.org/projects.cgi/web/i2c/overview). - * - * Peter Korsgaard - * - * Support for the GRLIB port of the controller by - * Andreas Larsson - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define OCORES_FLAG_POLL BIT(0) - -struct ocores_i2c { - void __iomem *base; - u32 reg_shift; - u32 reg_io_width; - unsigned long flags; - wait_queue_head_t wait; - struct i2c_adapter adap; - struct i2c_msg *msg; - int pos; - int nmsgs; - int state; /* see STATE_ */ - spinlock_t process_lock; - int clock_khz; - void (*setreg)(struct ocores_i2c *i2c, int reg, u8 value); - u8 (*getreg)(struct ocores_i2c *i2c, int reg); -}; - -/* registers */ -#define OCI2C_PRELOW 0x0 -#define OCI2C_PREHIGH 0x1 -#define OCI2C_CONTROL 0x2 -#define OCI2C_DATA 0x3 -#define OCI2C_CMD 0x4 /* write only */ -#define OCI2C_STATUS 0x4 /* read only, same address as OCI2C_CMD */ - -#define OCI2C_TRAN_REV 0x14 -#define OCI2C_CMD_REV 0x18 - - -#define OCI2C_CTRL_IEN 0x40 -#define OCI2C_CTRL_EN 0x80 - -#define OCI2C_CMD_START 0x91 -#define OCI2C_CMD_STOP 0x41 -#define OCI2C_CMD_READ 0x21 -#define OCI2C_CMD_WRITE 0x11 -#define OCI2C_CMD_READ_ACK 0x21 -#define OCI2C_CMD_READ_NACK 0x29 -#define OCI2C_CMD_IACK 0x01 - -#define OCI2C_STAT_IF 0x01 -#define OCI2C_STAT_TIP 0x02 -#define OCI2C_STAT_ARBLOST 0x20 -#define OCI2C_STAT_BUSY 0x40 -#define OCI2C_STAT_NACK 0x80 - -#define STATE_DONE 0 -#define STATE_START 1 -#define STATE_WRITE 2 -#define STATE_READ 3 -#define STATE_ERROR 4 - -#define TYPE_OCORES 0 -#define TYPE_GRLIB 1 -#define OCI2C_WAIT_SLEEP 40 - -int g_lpc_cpld_i2c_debug = 0; -int g_lpc_cpld_i2c_irq = 0; -int g_lpc_cpld_i2c_error = 0; - -module_param(g_lpc_cpld_i2c_debug, int, S_IRUGO | S_IWUSR); -module_param(g_lpc_cpld_i2c_error, int, S_IRUGO | S_IWUSR); -module_param(g_lpc_cpld_i2c_irq, int, S_IRUGO | S_IWUSR); - -int g_irq_dump_debug = 0; -module_param(g_irq_dump_debug, int, S_IRUGO | S_IWUSR); -#define LPC_CPLD_I2C_DEBUG_DUMP(fmt, args...) do { \ - if (g_irq_dump_debug) { \ - printk(KERN_ERR ""fmt, ## args); \ - } \ -} while (0) -int g_irq_invalid_cnt = 0; -module_param(g_irq_invalid_cnt, int, S_IRUGO | S_IWUSR); -#define LPC_CPLD_I2C_DEBUG_XFER(fmt, args...) do { \ - if (g_lpc_cpld_i2c_irq) { \ - printk(KERN_ERR "[LPC_CPLD_I2C_OCORES][XFER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define LPC_CPLD_I2C_DEBUG_VERBOSE(fmt, args...) do { \ - if (g_lpc_cpld_i2c_debug) { \ - printk(KERN_ERR "[LPC_CPLD_I2C_OCORES][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define LPC_CPLD_I2C_DEBUG_ERROR(fmt, args...) do { \ - if (g_lpc_cpld_i2c_error) { \ - printk(KERN_ERR "[LPC_CPLD_I2C_OCORES][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -static int g_lpc_cpld_i2c_irq_flag = 1; - -module_param(g_lpc_cpld_i2c_irq_flag, int, S_IRUGO | S_IWUSR); - -static void oc_debug_dump_reg(struct ocores_i2c *i2c); -static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u8 value) -{ - u64 base = (u64)i2c->base; - - outb(value, (u16)base + reg); -} - -static inline u8 oc_getreg_8(struct ocores_i2c *i2c, int reg) -{ - u64 base = (u64)i2c->base; - - return inb((u16)base + reg); -} - -static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) -{ - i2c->setreg(i2c, reg, value); -} - -static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) -{ - u8 status; - - status = i2c->getreg(i2c, reg); - return status; -} - -#define LPC_CPLD_I2C_SPIN_LOCK(lock, flags) spin_lock_irqsave(&(lock), (flags)) -#define LPC_CPLD_I2C_SPIN_UNLOCK(lock, flags) spin_unlock_irqrestore(&(lock), (flags)) - -static void ocores_process(struct ocores_i2c *i2c, u8 stat) -{ - struct i2c_msg *msg = i2c->msg; - - LPC_CPLD_I2C_DEBUG_XFER("Enter nr %d.\n", i2c->adap.nr); - - /* - * If we spin here is because we are in timeout, so we are going - * to be in STATE_ERROR. See ocores_process_timeout() - */ - if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { - /* stop has been sent */ - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); - wake_up(&i2c->wait); - LPC_CPLD_I2C_DEBUG_XFER("stop has been sent, exit.\n"); - goto out; - } - - /* error */ - if (stat & OCI2C_STAT_ARBLOST) { - i2c->state = STATE_ERROR; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - LPC_CPLD_I2C_DEBUG_XFER("error, exit.\n"); - goto out; - } - - if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { - i2c->state = - (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; - - if (stat & OCI2C_STAT_NACK) { - i2c->state = STATE_ERROR; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - LPC_CPLD_I2C_DEBUG_XFER("OCI2C_STAT_NACK, exit.\n"); - goto out; - } - } else - msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); - - /* end of msg */ - if (i2c->pos == msg->len) { - LPC_CPLD_I2C_DEBUG_XFER("Enter end of msg.\n"); - i2c->nmsgs--; - i2c->msg++; - i2c->pos = 0; - msg = i2c->msg; - - if (i2c->nmsgs) { /* end? */ - /* send start */ - if (!(msg->flags & I2C_M_NOSTART)) { - u8 addr = (msg->addr << 1); - - if (msg->flags & I2C_M_RD) - addr |= 1; - - i2c->state = STATE_START; - - oc_setreg(i2c, OCI2C_DATA, addr); - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); - LPC_CPLD_I2C_DEBUG_XFER("send start, exit.\n"); - goto out; - } - - i2c->state = (msg->flags & I2C_M_RD) - ? STATE_READ : STATE_WRITE; - } else { - i2c->state = STATE_DONE; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - LPC_CPLD_I2C_DEBUG_XFER("send OCI2C_CMD_STOP, exit.\n"); - goto out; - } - } - - if (i2c->state == STATE_READ) { - oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? - OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); - } else { - oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); - } - -out: - LPC_CPLD_I2C_DEBUG_XFER("normal, exit nr %d.\n", i2c->adap.nr); -} - -static irqreturn_t ocores_isr(int irq, void *dev_id) -{ - struct ocores_i2c *i2c = dev_id; - unsigned long flags; - u8 stat; - if (!i2c) { - return IRQ_NONE; - } - - LPC_CPLD_I2C_SPIN_LOCK(i2c->process_lock, flags); - stat = oc_getreg(i2c, OCI2C_STATUS); - - if (!(stat & OCI2C_STAT_IF)) { - g_irq_invalid_cnt++; - LPC_CPLD_I2C_SPIN_UNLOCK(i2c->process_lock, flags); - return IRQ_NONE; - } - - LPC_CPLD_I2C_DEBUG_XFER("Enter, irq %d nr %d addr 0x%x.\n", irq, i2c->adap.nr, i2c->msg->addr); - ocores_process(i2c, stat); - LPC_CPLD_I2C_DEBUG_XFER("Leave, irq %d nr %d addr 0x%x.\n", irq, i2c->adap.nr, i2c->msg->addr); - LPC_CPLD_I2C_SPIN_UNLOCK(i2c->process_lock, flags); - - return IRQ_HANDLED; -} - -/** - * Process timeout event - * @i2c: ocores I2C device instance - */ -static void ocores_process_timeout(struct ocores_i2c *i2c) -{ - unsigned long flags; - - LPC_CPLD_I2C_SPIN_LOCK(i2c->process_lock, flags); - i2c->state = STATE_ERROR; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - mdelay(1); - LPC_CPLD_I2C_SPIN_UNLOCK(i2c->process_lock, flags); - -} - -/** - * Wait until something change in a given register - * @i2c: ocores I2C device instance - * @reg: register to query - * @mask: bitmask to apply on register value - * @val: expected result - * @timeout: timeout in jiffies - * - * Timeout is necessary to avoid to stay here forever when the chip - * does not answer correctly. - * - * Return: 0 on success, -ETIMEDOUT on timeout - */ -static int ocores_wait(struct ocores_i2c *i2c, - int reg, u8 mask, u8 val, - const unsigned long timeout) -{ - u8 status; - unsigned long j, jiffies_tmp; - unsigned int usleep; - usleep = OCI2C_WAIT_SLEEP; - j = jiffies + timeout; - while (1) { - jiffies_tmp = jiffies; - status = oc_getreg(i2c, reg); - - if ((status & mask) == val) - break; - - if (time_after(jiffies_tmp, j)) { - LPC_CPLD_I2C_DEBUG_XFER("STATUS timeout, mask[0x%x] val[0x%x] status[0x%x]\n", mask, val, status); - return -ETIMEDOUT; - } - usleep_range(usleep,usleep + 1); - } - return 0; -} - -/** - * Wait until is possible to process some data - * @i2c: ocores I2C device instance - * - * Used when the device is in polling mode (interrupts disabled). - * - * Return: 0 on success, -ETIMEDOUT on timeout - */ -static int ocores_poll_wait(struct ocores_i2c *i2c) -{ - u8 mask; - int err; - - if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { - /* transfer is over */ - mask = OCI2C_STAT_BUSY; - } else { - /* on going transfer */ - mask = OCI2C_STAT_TIP; - udelay((8 * 1000) / i2c->clock_khz); - } - - /* - * once we are here we expect to get the expected result immediately - * so if after 1ms we timeout then something is broken. - */ - err = ocores_wait(i2c, OCI2C_STATUS, mask, 0, msecs_to_jiffies(100)); - if (err) { - LPC_CPLD_I2C_DEBUG_XFER("STATUS timeout, bit 0x%x did not clear in 1ms, err %d\n", mask, err); - } - - return err; -} - - -/** - * It handles an IRQ-less transfer - * @i2c: ocores I2C device instance - * - * Even if IRQ are disabled, the I2C OpenCore IP behavior is exactly the same - * (only that IRQ are not produced). This means that we can re-use entirely - * ocores_isr(), we just add our polling code around it. - * - * It can run in atomic context - */ -static int ocores_process_polling(struct ocores_i2c *i2c) -{ - irqreturn_t ret; - int err; - while (1) { - err = ocores_poll_wait(i2c); - if (err) { - i2c->state = STATE_ERROR; - break; /* timeout */ - } - - ret = ocores_isr(-1, i2c); - if (ret == IRQ_NONE) - break; /* all messages have been transfered */ - } - return err; -} - -static int ocores_xfer_core(struct ocores_i2c *i2c, - struct i2c_msg *msgs, int num, - bool polling) -{ - int ret; - unsigned long flags; - u8 ctrl; - - LPC_CPLD_I2C_DEBUG_XFER("Enter.polling %d\n", polling); - LPC_CPLD_I2C_SPIN_LOCK(i2c->process_lock, flags); - ctrl = oc_getreg(i2c, OCI2C_CONTROL); - if (polling) - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~OCI2C_CTRL_IEN); - else - oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN); - - i2c->msg = msgs; - i2c->pos = 0; - i2c->nmsgs = num; - i2c->state = STATE_START; - - oc_setreg(i2c, OCI2C_DATA, - (i2c->msg->addr << 1) | - ((i2c->msg->flags & I2C_M_RD) ? 1:0)); - - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); - LPC_CPLD_I2C_SPIN_UNLOCK(i2c->process_lock, flags); - - if (polling) { - ret = ocores_process_polling(i2c); - if (ret) { /* timeout */ - ocores_process_timeout(i2c); - return -ETIMEDOUT; - } - } else { - ret = wait_event_timeout(i2c->wait, - (i2c->state == STATE_ERROR) || - (i2c->state == STATE_DONE), HZ); - if (ret == 0) { - ocores_process_timeout(i2c); - return -ETIMEDOUT; - } - } - - return (i2c->state == STATE_DONE) ? num : -EIO; -} - -static int ocores_xfer_polling(struct i2c_adapter *adap, - struct i2c_msg *msgs, int num) -{ - LPC_CPLD_I2C_DEBUG_XFER("Enter.\n"); - return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, true); -} - -static int ocores_xfer(struct i2c_adapter *adap, - struct i2c_msg *msgs, int num) -{ - struct ocores_i2c *i2c = i2c_get_adapdata(adap); - - if (i2c->flags & OCORES_FLAG_POLL) - return ocores_xfer_polling(adap, msgs, num); - return ocores_xfer_core(i2c, msgs, num, false); -} - -static void ocores_init(struct ocores_i2c *i2c) -{ - int prescale; - u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); - - LPC_CPLD_I2C_DEBUG_XFER("Enter.\n"); - spin_lock_init(&i2c->process_lock); - - /* make sure the device is disabled */ - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); - - prescale = (i2c->clock_khz / (5*100)) - 1; - oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); - oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); - LPC_CPLD_I2C_DEBUG_VERBOSE("i2c->base 0x%p, i2c->clock_khz %d, prescale 0x%x.\n", i2c->base, i2c->clock_khz, prescale); - - /* Init the device */ - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); - oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); -} - - -static u32 ocores_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static const struct i2c_algorithm ocores_algorithm = { - .master_xfer = ocores_xfer, - .functionality = ocores_func, -}; - -static struct i2c_adapter ocores_adapter = { - .owner = THIS_MODULE, - .name = "rg-cpld-ocrore-i2c", - .class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED, - .algo = &ocores_algorithm, -}; - -static const struct of_device_id ocores_i2c_match[] = { - { - .compatible = "opencores,rg-cpld-ocrore-i2c", - .data = (void *)TYPE_OCORES, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, ocores_i2c_match); - -#ifdef CONFIG_OF -/* Read and write functions for the GRLIB port of the controller. Registers are - * 32-bit big endian and the PRELOW and PREHIGH registers are merged into one - * register. The subsequent registers has their offset decreased accordingly. */ -static u8 oc_getreg_grlib(struct ocores_i2c *i2c, int reg) -{ - u32 rd; - int rreg = reg; - if (reg != OCI2C_PRELOW) - rreg--; - rd = ioread32be(i2c->base + (rreg << i2c->reg_shift)); - if (reg == OCI2C_PREHIGH) - return (u8)(rd >> 8); - else - return (u8)rd; -} - -static void oc_setreg_grlib(struct ocores_i2c *i2c, int reg, u8 value) -{ - u32 curr, wr; - int rreg = reg; - if (reg != OCI2C_PRELOW) - rreg--; - if (reg == OCI2C_PRELOW || reg == OCI2C_PREHIGH) { - curr = ioread32be(i2c->base + (rreg << i2c->reg_shift)); - if (reg == OCI2C_PRELOW) - wr = (curr & 0xff00) | value; - else - wr = (((u32)value) << 8) | (curr & 0xff); - } else { - wr = value; - } - iowrite32be(wr, i2c->base + (rreg << i2c->reg_shift)); -} - -static int ocores_i2c_of_probe(struct platform_device *pdev, - struct ocores_i2c *i2c) -{ - struct device_node *np = pdev->dev.of_node; - const struct of_device_id *match; - u32 val; - - LPC_CPLD_I2C_DEBUG_VERBOSE("Enter ocores_i2c_of_probe.\n"); - if (of_property_read_u32(np, "reg-shift", &i2c->reg_shift)) { - /* no 'reg-shift', check for deprecated 'regstep' */ - if (!of_property_read_u32(np, "regstep", &val)) { - if (!is_power_of_2(val)) { - dev_err(&pdev->dev, "invalid regstep %d\n", - val); - return -EINVAL; - } - i2c->reg_shift = ilog2(val); - dev_warn(&pdev->dev, - "regstep property deprecated, use reg-shift\n"); - } - } - - if (of_property_read_u32(np, "clock-frequency", &val)) { - dev_err(&pdev->dev, - "Missing required parameter 'clock-frequency'\n"); - return -ENODEV; - } - i2c->clock_khz = val / 1000; - - of_property_read_u32(pdev->dev.of_node, "reg-io-width", - &i2c->reg_io_width); - - match = of_match_node(ocores_i2c_match, pdev->dev.of_node); - if (match && (long)match->data == TYPE_GRLIB) { - dev_dbg(&pdev->dev, "GRLIB variant of i2c-ocores\n"); - i2c->setreg = oc_setreg_grlib; - i2c->getreg = oc_getreg_grlib; - } - - return 0; -} -#else -#define ocores_i2c_of_probe(pdev,i2c) -ENODEV -#endif - -static void oc_debug_dump_reg(struct ocores_i2c *i2c) -{ - if (i2c) { - LPC_CPLD_I2C_DEBUG_DUMP("base: %p.\n", i2c->base); - LPC_CPLD_I2C_DEBUG_DUMP("reg_shift: %d.\n", i2c->reg_shift); - LPC_CPLD_I2C_DEBUG_DUMP("reg_io_width: %d.\n", i2c->reg_io_width); - LPC_CPLD_I2C_DEBUG_DUMP("adap.nr: %d.\n", i2c->adap.nr); - LPC_CPLD_I2C_DEBUG_DUMP("msg: %p.\n", i2c->msg); - if (i2c->msg) { - LPC_CPLD_I2C_DEBUG_DUMP("msg->buf: %p.\n", i2c->msg->buf); - LPC_CPLD_I2C_DEBUG_DUMP("msg->addr: 0x%x.\n", i2c->msg->addr); - LPC_CPLD_I2C_DEBUG_DUMP("msg->flags: 0x%x.\n", i2c->msg->flags); - LPC_CPLD_I2C_DEBUG_DUMP("msg->len: %d.\n", i2c->msg->len); - } else { - LPC_CPLD_I2C_DEBUG_DUMP("msg: %p is null.\n", i2c->msg); - } - - LPC_CPLD_I2C_DEBUG_DUMP("pos: %d.\n", i2c->pos); - LPC_CPLD_I2C_DEBUG_DUMP("nmsgs: %d.\n", i2c->nmsgs); - LPC_CPLD_I2C_DEBUG_DUMP("state: %d.\n", i2c->state); - LPC_CPLD_I2C_DEBUG_DUMP("clock_khz: %d.\n", i2c->clock_khz); - LPC_CPLD_I2C_DEBUG_DUMP("setreg: %p.\n", i2c->setreg); - LPC_CPLD_I2C_DEBUG_DUMP("getreg: %p.\n", i2c->getreg); - if (i2c->getreg) { - LPC_CPLD_I2C_DEBUG_DUMP("OCI2C_PRELOW: 0x%02x.\n", oc_getreg(i2c, OCI2C_PRELOW)); - LPC_CPLD_I2C_DEBUG_DUMP("OCI2C_PREHIGH: 0x%02x.\n", oc_getreg(i2c, OCI2C_PREHIGH)); - LPC_CPLD_I2C_DEBUG_DUMP("OCI2C_CONTROL: 0x%02x.\n", oc_getreg(i2c, OCI2C_CONTROL)); - LPC_CPLD_I2C_DEBUG_DUMP("OCI2C_DATA: 0x%02x.\n", oc_getreg(i2c, OCI2C_DATA)); - LPC_CPLD_I2C_DEBUG_DUMP("OCI2C_CMD: 0x%02x.\n", oc_getreg(i2c, OCI2C_CMD)); - LPC_CPLD_I2C_DEBUG_DUMP("OCI2C_STATUS: 0x%02x.\n", oc_getreg(i2c, OCI2C_STATUS)); - } else { - LPC_CPLD_I2C_DEBUG_DUMP("getreg: %p is null.\n", i2c->getreg); - } - } else { - LPC_CPLD_I2C_DEBUG_DUMP("i2c %p is null.\n", i2c); - } -} - -void oc_debug_dump_reg_exception(void) -{ - int bus_beg, bus_end, bus; - struct i2c_adapter *adap; - struct ocores_i2c *adap_data; - - bus_beg = 1; - bus_end = 14; - for (bus = bus_beg; bus <= bus_end; bus++) { - adap = i2c_get_adapter(bus); - if (adap) { - adap_data = (struct ocores_i2c *)i2c_get_adapdata(adap); - if (adap_data) { - LPC_CPLD_I2C_DEBUG_DUMP("bus %d call oc_debug_dump_reg begin.\n", bus); - oc_debug_dump_reg(adap_data); - LPC_CPLD_I2C_DEBUG_DUMP("bus %d call oc_debug_dump_reg end.\n", bus); - } else { - LPC_CPLD_I2C_DEBUG_DUMP("bus %d i2c_get_adapdata null.\n", bus); - } - i2c_put_adapter(adap); - } else { - LPC_CPLD_I2C_DEBUG_DUMP("bus %d i2c_get_adapter null.\n", bus); - } - } -} - -static ssize_t show_oc_debug_value(struct device *dev, struct device_attribute *da, char *buf) -{ - oc_debug_dump_reg_exception(); - return 0; -} - -static SENSOR_DEVICE_ATTR(oc_debug, S_IRUGO | S_IWUSR, show_oc_debug_value, NULL, 0x15); - -static struct attribute *oc_debug_sysfs_attrs[] = { - &sensor_dev_attr_oc_debug.dev_attr.attr, - NULL -}; - -static const struct attribute_group oc_debug_sysfs_group = { - .attrs = oc_debug_sysfs_attrs, -}; - -static void oc_debug_sysfs_init(struct platform_device *pdev) -{ - int ret; - - ret = sysfs_create_group(&pdev->dev.kobj, &oc_debug_sysfs_group); - LPC_CPLD_I2C_DEBUG_VERBOSE("sysfs_create_group ret %d.\n", ret); - return; -} - -static void oc_debug_sysfs_exit(struct platform_device *pdev) -{ - sysfs_remove_group(&pdev->dev.kobj, (const struct attribute_group *)&oc_debug_sysfs_group); - LPC_CPLD_I2C_DEBUG_VERBOSE("sysfs_remove_group.\n"); - return; -} - -static int rg_ocores_i2c_probe(struct platform_device *pdev) -{ - struct ocores_i2c *i2c; - struct rg_ocores_cpld_i2c_platform_data *pdata; - struct resource *res; - int irq; - int ret; - int i; - - LPC_CPLD_I2C_DEBUG_VERBOSE("Enter.\n"); - - i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); - if (!i2c) { - LPC_CPLD_I2C_DEBUG_ERROR("devm_kzalloc failed.\n"); - return -ENOMEM; - } - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!res) { - LPC_CPLD_I2C_DEBUG_ERROR("can't fetch device resource info\n"); - return -ENOMEM; - } - - i2c->base = (void __iomem *)res->start; - LPC_CPLD_I2C_DEBUG_VERBOSE("i2c->base is %p., res->end[%d]\n", i2c->base, (int)res->end); - - pdata = dev_get_platdata(&pdev->dev); - if (pdata) { - i2c->reg_shift = pdata->reg_shift; - i2c->reg_io_width = pdata->reg_io_width; - i2c->clock_khz = pdata->clock_khz; - } else { - ret = ocores_i2c_of_probe(pdev, i2c); - if (ret) - return ret; - } - - LPC_CPLD_I2C_DEBUG_VERBOSE("data: shift[%d], width[%d], clock_khz[%d] i2c_irq_flag=%d\n", - pdata->reg_shift, pdata->reg_io_width, pdata->clock_khz, pdata->i2c_irq_flag); - - if (i2c->reg_io_width == 0) - i2c->reg_io_width = 1; /* Set to default value */ - - - if (!i2c->setreg || !i2c->getreg) { - switch (i2c->reg_io_width) { - case 1: - i2c->setreg = oc_setreg_8; - i2c->getreg = oc_getreg_8; - break; - default: - dev_err(&pdev->dev, "Unsupported I/O width (%d)\n", - i2c->reg_io_width); - return -EINVAL; - } - } - - init_waitqueue_head(&i2c->wait); - - irq = platform_get_irq(pdev, 0); - LPC_CPLD_I2C_DEBUG_VERBOSE("get irq %d, ENXIO[%d]", irq, ENXIO); - if (irq == -ENXIO) { - i2c->flags |= OCORES_FLAG_POLL; - } else if(g_lpc_cpld_i2c_irq_flag){ - ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, - pdev->name, i2c); - if (ret) { - dev_err(&pdev->dev, "Cannot claim IRQ\n"); - } - - if(pdata->i2c_irq_flag) { - g_lpc_cpld_i2c_irq_flag = 0; - } - } - - ocores_init(i2c); - - /* hook up driver to tree */ - platform_set_drvdata(pdev, i2c); - i2c->adap = ocores_adapter; - i2c_set_adapdata(&i2c->adap, i2c); - i2c->adap.dev.parent = &pdev->dev; - i2c->adap.dev.of_node = pdev->dev.of_node; - - /* add i2c adapter to i2c tree */ - ret = i2c_add_adapter(&i2c->adap); - if (ret) { - dev_err(&pdev->dev, "Failed to add adapter\n"); - return ret; - } - - /* add in known devices to the bus */ - if (pdata) { - LPC_CPLD_I2C_DEBUG_VERBOSE("i2c device %d.\n", pdata->num_devices); - for (i = 0; i < pdata->num_devices; i++) - i2c_new_device(&i2c->adap, pdata->devices + i); - } - - oc_debug_sysfs_init(pdev); - return 0; -} - -static int rg_ocores_i2c_remove(struct platform_device *pdev) -{ - struct ocores_i2c *i2c = platform_get_drvdata(pdev); - - /* disable i2c logic */ - oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL) - & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); - - /* remove adapter & data */ - i2c_del_adapter(&i2c->adap); - oc_debug_sysfs_exit(pdev); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int ocores_i2c_suspend(struct device *dev) -{ - struct ocores_i2c *i2c = dev_get_drvdata(dev); - u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); - - /* make sure the device is disabled */ - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); - - return 0; -} - -static int ocores_i2c_resume(struct device *dev) -{ - struct ocores_i2c *i2c = dev_get_drvdata(dev); - - ocores_init(i2c); - - return 0; -} - -static SIMPLE_DEV_PM_OPS(ocores_i2c_pm, ocores_i2c_suspend, ocores_i2c_resume); -#define OCORES_I2C_PM (&ocores_i2c_pm) -#else -#define OCORES_I2C_PM NULL -#endif - -static struct platform_driver ocores_i2c_driver = { - .probe = rg_ocores_i2c_probe, - .remove = rg_ocores_i2c_remove, - .driver = { - .owner = THIS_MODULE, - .name = "rg-cpld-ocrore-i2c", - .of_match_table = ocores_i2c_match, - .pm = OCORES_I2C_PM, - }, -}; - -module_platform_driver(ocores_i2c_driver); - -MODULE_AUTHOR("Peter Korsgaard "); -MODULE_DESCRIPTION("OpenCores I2C bus driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ocores-i2c"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_cpld_i2c_ocores.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_cpld_i2c_ocores.h deleted file mode 100755 index baf6a916b11a..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_cpld_i2c_ocores.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _LPC_CPLD_I2C_OCORES_H -#define _LPC_CPLD_I2C_OCORES_H - -struct rg_ocores_cpld_i2c_platform_data { - u32 reg_shift; /* register offset shift value */ - u32 reg_io_width; /* register io read/write width */ - u32 clock_khz; /* input clock in kHz */ - u8 num_devices; /* number of devices in the devices list */ - u8 i2c_irq_flag; - struct i2c_board_info const *devices; /* devices connected to the bus */ -}; - -#endif /* _LPC_CPLD_I2C_OCORES_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_dbg.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_dbg.c deleted file mode 100755 index 9c43bcee5c4a..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_dbg.c +++ /dev/null @@ -1,534 +0,0 @@ -#include -#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 19, 0) -#include -#endif - -#include -#include /* Wd're doing kernel work */ -#include /* specifically, a module */ -#include -#include /* Need for the macros */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lpc_dbg.h" - -typedef struct rg_lpc_device_s { - u16 base; - u16 size; - u8 type; - u8 id; - u8 lpc_pci_addr; -} rg_lpc_device_t; - -typedef enum rg_lpc_dev_type_s { - LPC_DEVICE_CPLD = 1, - LPC_DEVICE_FPGA = 2, -} rg_lpc_dev_type_t; - -#define MAX_LPC_DEV_NUM (4) -#define LPC_PCI_CFG_BASE(__lgir) ((0x84) + ((__lgir) * 4)) -#define MAX_CPLD_REG_SIZE (0x100) -#define MAX_FPGA_REG_SIZE (0x100) //# fix compile actual value 0x10000 -#define LPC_GET_CPLD_ID(addr) ((addr >> 16) & 0xff) -#define LPC_GET_CPLD_OFFSET(addr) ((addr) & 0xff) - -int lpc_dbg_verbose = 0; -int lpc_dbg_error = 0; -int lpc_dbg_info = 0; -module_param(lpc_dbg_verbose, int, S_IRUGO | S_IWUSR); -module_param(lpc_dbg_error, int, S_IRUGO | S_IWUSR); -module_param(lpc_dbg_info, int, S_IRUGO | S_IWUSR); - - -#define LPC_DBG_VERBOSE(fmt, args...) do { \ - if (lpc_dbg_verbose) { \ - printk(KERN_ERR "[LPC_DBG][VERBOSE][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define LPC_DBG_ERROR(fmt, args...) do { \ - if (lpc_dbg_error) { \ - printk(KERN_ERR "[LPC_DBG][ERROR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define LPC_DBG_INFO(fmt, args...) do { \ - if (lpc_dbg_info) { \ - printk(KERN_ERR ""fmt, ## args); \ - } \ -} while (0) - -static rg_lpc_device_t g_rg_lpc_dev_default[] = { - {.base = 0x700, .size = MAX_CPLD_REG_SIZE, .type = LPC_DEVICE_CPLD, .id = 0, .lpc_pci_addr = 0x84}, - {.base = 0x900, .size = MAX_CPLD_REG_SIZE, .type = LPC_DEVICE_CPLD, .id = 1, .lpc_pci_addr = 0x88}, - {.base = 0xb00, .size = MAX_CPLD_REG_SIZE, .type = LPC_DEVICE_CPLD, .id = 2, .lpc_pci_addr = 0x90}, -}; - -static rg_lpc_device_t *g_rg_lpc_dev = g_rg_lpc_dev_default; - -static rg_lpc_device_t* lpc_get_device_info(int type, int id) -{ - int i; - int size; - - size = ARRAY_SIZE(g_rg_lpc_dev_default); - for (i = 0; i < size; i++) { - if ((g_rg_lpc_dev[i].type == type) && (g_rg_lpc_dev[i].id == id)) { - return &g_rg_lpc_dev[i]; - } - } - - return NULL; -} - - -int lpc_cpld_read(int address, u8 *val) -{ - int cpld_id; - rg_lpc_device_t *info; - - cpld_id = LPC_GET_CPLD_ID(address); - info = lpc_get_device_info(LPC_DEVICE_CPLD, cpld_id); - if (info == NULL) { - LPC_DBG_ERROR("lpc_get_device_info addr 0x%x id %d failed.\r\n", address, cpld_id); - return -1; - } - - *val = inb(info->base + LPC_GET_CPLD_OFFSET(address)); - LPC_DBG_VERBOSE("Leave info->base 0x%x, addr 0x%x, cpld_id %d, val 0x%x.\r\n", info->base, address, cpld_id, *val); - return 0; -} - -int lpc_cpld_write(int address, u8 reg_val) -{ - int cpld_id; - rg_lpc_device_t *info; - - cpld_id = LPC_GET_CPLD_ID(address); - info = lpc_get_device_info(LPC_DEVICE_CPLD, cpld_id); - if (info == NULL) { - LPC_DBG_ERROR("lpc_get_device_info addr 0x%x id %d failed.\r\n", address, cpld_id); - return -1; - } - - outb(reg_val, info->base + LPC_GET_CPLD_OFFSET(address)); - LPC_DBG_VERBOSE("Leave info->base 0x%x, addr 0x%x, cpld_id %d, val 0x%x.\r\n", info->base, address, cpld_id, reg_val); - return 0; -} - -int lpc_fpga_read(int address, u8 *val) -{ - return -1; -} - -int lpc_fpga_write(int address, u8 reg_val) -{ - return -1; -} - -static ssize_t lpc_misc_cpld_dev_read (struct file *file, char __user *buf, size_t count, - loff_t *offset) -{ - int ret; - u8 value8[MAX_CPLD_REG_SIZE]; - int i; - - if ((count > MAX_CPLD_REG_SIZE) - || ((LPC_GET_CPLD_OFFSET(file->f_pos) + count) > MAX_CPLD_REG_SIZE)) { - return -EFAULT; - } - - for (i = 0; i < count; i++) { - ret = lpc_cpld_read((int)(file->f_pos + i), &value8[i]); - if (ret) { - LPC_DBG_ERROR("lpc_cpld_read i %d addr 0x%x failed ret %d.\n", - i, ((unsigned int)file->f_pos + i), ret); - return i; - } - } - - if (copy_to_user(buf, value8, count)) { - return -EFAULT; - } - - return count; -} - - -static ssize_t lpc_misc_cpld_dev_write (struct file *file, const char __user *buf, size_t count, - loff_t *offset) -{ - u8 value8[MAX_CPLD_REG_SIZE]; - int i; - int ret; - - if ((count > MAX_CPLD_REG_SIZE) - || ((LPC_GET_CPLD_OFFSET(file->f_pos) + count) > MAX_CPLD_REG_SIZE)) { - return -EFAULT; - } - - if (copy_from_user(value8, buf, count)) { - return -EFAULT; - } - - for (i = 0; i < count; i++) { - ret = lpc_cpld_write((int)(file->f_pos + i), value8[i]); - if (ret) { - LPC_DBG_ERROR("lpc_cpld_write i %d addr 0x%x value 0x%x failed ret %d.\n", - i, (unsigned int)file->f_pos + i, value8[i], ret); - return i; - } - } - - return count; -} - - -static loff_t lpc_misc_cpld_dev_llseek(struct file *file, loff_t offset, int origin) -{ - loff_t ret; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,36) - mutex_lock(&file->f_path.dentry->d_inode->i_mutex); -#else - /* do noting add tjm */ - inode_lock(file_inode(file)); -#endif - - switch (origin) { - case 0: - file->f_pos = offset; - ret = file->f_pos; - break; - case 1: - file->f_pos += offset; - ret = file->f_pos; - break; - default: - ret = -EINVAL; - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,36) - mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); -#else - /* do noting add tjm */ - inode_unlock(file_inode(file)); -#endif - - - return ret; -} - - -static long lpc_misc_cpld_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - return -1; -} - -static int lpc_misc_cpld_dev_open(struct inode *inode, struct file *file) -{ - file->private_data = NULL; - file->f_pos = 0; - return 0; - -} - -static int lpc_misc_cpld_dev_release(struct inode *inode, struct file *file) -{ - file->private_data = NULL; - file->f_pos = 0; - return 0; -} - -static const struct file_operations lpc_misc_cpld_dev_fops = { - .owner = THIS_MODULE, - .llseek = lpc_misc_cpld_dev_llseek, - .read = lpc_misc_cpld_dev_read, - .write = lpc_misc_cpld_dev_write, - .unlocked_ioctl = lpc_misc_cpld_dev_ioctl, - .open = lpc_misc_cpld_dev_open, - .release = lpc_misc_cpld_dev_release, -}; - -static ssize_t lpc_misc_fpga_dev_read (struct file *file, char __user *buf, size_t count, - loff_t *offset) -{ - int ret; - u8 value8[MAX_FPGA_REG_SIZE]; - int i; - - if ((count > MAX_FPGA_REG_SIZE) || ((file->f_pos + count) > MAX_FPGA_REG_SIZE)) { - return -EFAULT; - } - - for (i = 0; i < count; i++) { - ret = lpc_fpga_read((int)(file->f_pos + i), &value8[i]); - if (ret) { - LPC_DBG_ERROR("lpc_fpga_read i %d addr 0x%x failed ret %d.\n", - i, ((unsigned int)file->f_pos + i), ret); - return i; - } - - } - - if (copy_to_user(buf, value8, count)) { - return -EFAULT; - } - - return count; -} - - -static ssize_t lpc_misc_fpga_dev_write (struct file *file, const char __user *buf, size_t count, - loff_t *offset) -{ - int ret; - u8 value8[MAX_FPGA_REG_SIZE]; - int i; - - if ((count > MAX_FPGA_REG_SIZE) || ((file->f_pos + count) > MAX_FPGA_REG_SIZE)) { - return -EFAULT; - } - - if (copy_from_user(value8, buf, count)) { - return -EFAULT; - } - - for (i = 0; i < count; i++) { - ret = lpc_fpga_write((int)(file->f_pos + i), value8[i]); - if (ret) { - LPC_DBG_ERROR("lpc_fpga_write i %d addr 0x%x value 0x%x failed ret %d.\n", - i, (int)(file->f_pos + i), value8[i], ret); - return i; - } - } - - return count; -} - - -static loff_t lpc_misc_fpga_dev_llseek(struct file *file, loff_t offset, int origin) -{ - loff_t ret; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,36) - mutex_lock(&file->f_path.dentry->d_inode->i_mutex); -#else - /* do noting add tjm */ - inode_lock(file_inode(file)); -#endif - - switch (origin) { - case 0: - file->f_pos = offset; - ret = file->f_pos; - break; - case 1: - file->f_pos += offset; - ret = file->f_pos; - break; - default: - ret = -EINVAL; - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,36) - mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); -#else - /* do noting add tjm */ - inode_unlock(file_inode(file)); -#endif - - - return ret; -} - - -static long lpc_misc_fpga_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - return -1; -} - -static int lpc_misc_fpga_dev_open(struct inode *inode, struct file *file) -{ - file->private_data = NULL; - file->f_pos = 0; - return 0; - -} - -static int lpc_misc_fpga_dev_release(struct inode *inode, struct file *file) -{ - file->private_data = NULL; - file->f_pos = 0; - return 0; -} - -static const struct file_operations lpc_misc_fpga_dev_fops = { - .owner = THIS_MODULE, - .llseek = lpc_misc_fpga_dev_llseek, - .read = lpc_misc_fpga_dev_read, - .write = lpc_misc_fpga_dev_write, - .unlocked_ioctl = lpc_misc_fpga_dev_ioctl, - .open = lpc_misc_fpga_dev_open, - .release = lpc_misc_fpga_dev_release, -}; - -static struct miscdevice lpc_misc_cpld_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "lpc_cpld", - .fops = &lpc_misc_cpld_dev_fops, -}; - -static struct miscdevice lpc_misc_fpga_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "lpc_fpga", - .fops = &lpc_misc_fpga_dev_fops, -}; - -static int lpc_misc_drv_init(void) -{ - if (misc_register(&lpc_misc_cpld_dev) != 0) { - LPC_DBG_ERROR("Register %s failed.\r\n", lpc_misc_cpld_dev.name); - return -ENXIO; - } - - if (misc_register(&lpc_misc_fpga_dev) != 0) { - LPC_DBG_ERROR("Register %s failed.\r\n", lpc_misc_fpga_dev.name); - return -ENXIO; - } - return 0; -} - -static void lpc_misc_drv_exit(void) -{ - misc_deregister(&lpc_misc_cpld_dev); - misc_deregister(&lpc_misc_fpga_dev); -} - -#define LPC_MAKE_PCI_IO_RANGE(__base) ((0xfc0001) | ((__base) & (0xFFFC))) - -static int lpc_pci_cfg_init(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int i; - int size; - - size = ARRAY_SIZE(g_rg_lpc_dev_default); - - for (i = 0; i < size; i++) { - pci_write_config_dword(pdev, g_rg_lpc_dev[i].lpc_pci_addr, LPC_MAKE_PCI_IO_RANGE(g_rg_lpc_dev[i].base)); - LPC_DBG_VERBOSE("set lpc pci cfg[addr: 0x%x, value:0x%x].\n", LPC_PCI_CFG_BASE(i), LPC_MAKE_PCI_IO_RANGE(g_rg_lpc_dev[i].base)); - if (!request_region(g_rg_lpc_dev[i].base, g_rg_lpc_dev[i].size, "rg_lpc")) { - LPC_DBG_ERROR("request_region [0x%x][0x%x] failed!\n", g_rg_lpc_dev[i].base, g_rg_lpc_dev[i].size); - return -EBUSY; - } - } - - return 0; -} - -static void lpc_pci_cfg_exit(void) -{ - int i; - int size; - - size = ARRAY_SIZE(g_rg_lpc_dev_default); - for (i = 0; i < size; i++) { - release_region(g_rg_lpc_dev[i].base, g_rg_lpc_dev[i].size); - } - return; -} - -static int rg_lpc_cpld_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int ret; - - LPC_DBG_VERBOSE("Enter.\n"); - ret = lpc_pci_cfg_init(pdev, id); - if (ret) { - LPC_DBG_ERROR("lpc_pci_cfg_init failed ret %d.\n", ret); - return ret; - } - - ret = lpc_misc_drv_init(); - if (ret) { - LPC_DBG_ERROR("lpc_misc_drv_init failed ret %d.\n", ret); - return ret; - } - LPC_DBG_VERBOSE("Leave success\n"); - - return 0; -} - -static void rg_lpc_cpld_remove(struct pci_dev *pdev) -{ - LPC_DBG_VERBOSE("Enter.\n"); - lpc_misc_drv_exit(); - lpc_pci_cfg_exit(); - LPC_DBG_VERBOSE("Leave.\n"); -} - - -#define PCI_VENDOR_ID_D1527_LPC (0x8c54) -#define PCI_VENDOR_ID_C3000_LPC (0x19dc) - -#if 0 -static const struct pci_device_id rg_lpc_cpld_pcidev_id[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_C3000_LPC) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC) }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, rg_lpc_cpld_pcidev_id); - -static struct pci_driver rg_lpc_driver = { - .name = "rg_lpc", - .id_table = rg_lpc_cpld_pcidev_id, - .probe = rg_lpc_cpld_probe, - .remove = rg_lpc_cpld_remove, -}; - -module_pci_driver(rg_lpc_driver); -#else -static int __init lpc_dbg_init(void) -{ - struct pci_dev *pdev = NULL; - int ret; - - LPC_DBG_VERBOSE("Enter.\n"); - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC, pdev); - if (!pdev) { - LPC_DBG_ERROR("pci_get_device(0x8086, 0x8c54) failed!\n"); - return 0; - } - - ret = rg_lpc_cpld_probe(pdev, NULL); - LPC_DBG_VERBOSE("Leave ret %d.\n", ret); - return ret; -} - -static void __exit lpc_dbg_exit(void) -{ - LPC_DBG_VERBOSE("Enter.\n"); - rg_lpc_cpld_remove(NULL); - LPC_DBG_VERBOSE("Leave.\n"); -} - - - -module_init(lpc_dbg_init); -module_exit(lpc_dbg_exit); - -#endif -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("support "); - diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_dbg.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_dbg.h deleted file mode 100755 index d1aad9c90751..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/lpc_dbg.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __ETH_CMD_TYPES_H__ -#define __ETH_CMD_TYPES_H__ - -typedef enum { - ETH_START = 1, - ETH_SHOW, - ETH_SET, - ETH_TEST, - ETH_MAC_REG, - ETH_PHY_REG, -} ether_dbg_top_cmd_t; - -typedef enum { - ETH_MAC_REG_READ = 1, - ETH_MAC_REG_WRITE, - ETH_MAC_REG_CHECK, - ETH_MAC_REG_DUMP_ALL, - ETH_MAC_REG_DUMP_PCI_CFG_ALL, -} ether_mac_reg_cmd_t; - - -#define ETH_DBG_TYPE(cmd1, cmd2, cmd3, cmd4) \ - ((cmd1) | ((cmd2) << 8) | ((cmd3) << 16) | ((cmd4) << 24)) -#define ETH_DBG_PARSE_TYPE(type, cmd1, cmd2, cmd3, cmd4) \ - do {\ - (cmd1) = (type) & 0xff;\ - (cmd2) = ((type) >> 8) & 0xff;\ - (cmd3) = ((type) >> 16) & 0xff;\ - (cmd4) = ((type) >> 24) & 0xff;\ - } while (0) - -typedef struct { - int type; - int length; - unsigned char value[128]; -} ether_msg_t; - - -#endif /* __ETH_CMD_TYPES_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/Makefile new file mode 100644 index 000000000000..369b64605dd3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/Makefile @@ -0,0 +1,20 @@ +pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST)) +pes_parent_dir:=$(shell dirname $(pes_parent_dir)) + +SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "build") print $$9}') +INC = -I./inc + +all : CHECK $(SUBDIRS) +CHECK : + @echo $(pes_parent_dir) + +$(SUBDIRS):ECHO + #@echo $@ + make -C $@ + +ECHO: + @echo $(SUBDIRS) + +.PHONY : clean +clean : + -rm -rf $(SYSFS_OUT_PUT) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/Makefile new file mode 100644 index 000000000000..e516b70b3d92 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/Makefile @@ -0,0 +1,25 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +SUBDIR_CFG = cfg +plat_dfd-objs := dfd_module.o dfd_fan_driver.o \ +dfd_slot_driver.o \ +dfd_sensors_driver.o \ +dfd_psu_driver.o \ +dfd_sff_driver.o \ +$(SUBDIR_CFG)/dfd_cfg.o \ +$(SUBDIR_CFG)/dfd_cfg_adapter.o \ +$(SUBDIR_CFG)/dfd_cfg_file.o \ +$(SUBDIR_CFG)/dfd_cfg_info.o \ +$(SUBDIR_CFG)/dfd_cfg_listnode.o \ + +obj-m := plat_dfd.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/$(SUBDIR_CFG)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/$(SUBDIR_CFG)/.*.cmd $(PWD)/*.mod + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c new file mode 100644 index 000000000000..b0c9e9f6e723 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c @@ -0,0 +1,812 @@ +#include +#include +#include +#include +#include +#include + +#include "../include/dfd_module.h" +#include "../include/dfd_cfg_file.h" +#include "../include/dfd_cfg_listnode.h" +#include "../include/dfd_cfg_info.h" +#include "../include/dfd_cfg_adapter.h" +#include "../include/dfd_cfg.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) _name, +static char *dfd_cfg_item_name[] = { + DFD_CFG_ITEM_ALL +}; + +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) {_index_min, _index_max}, +static index_range_t dfd_cfg_item_index_range[] = { + DFD_CFG_ITEM_ALL +}; + +static lnode_root_t dfd_ko_cfg_list_root; + +static void dfd_ko_cfg_del_space_lf_cr(char *str) +{ + int i, j; + int len; + + len = strlen(str); + for (i = 0; i < len; i++) { + if (str[i] == '\r' || str[i] == '\n' || str[i] == ' ') { + for (j = i; j < len - 1; j++) { + str[j] = str[j + 1]; + } + str[j] = '\0'; + len--; + i--; + } + } +} + +static int dfd_ko_cfg_get_value_from_char(char *value_str, int32_t *value, int line_num) +{ + int value_tmp = 0; + + if (strlen(value_str) == 0) { + DBG_DEBUG(DBG_WARN, "line%d: value str is empty\n", line_num); + *value = DFD_CFG_EMPTY_VALUE; + return 0; + } + + if ((strlen(value_str) > 2) && (value_str[0] == '0') + && (value_str[1] == 'x' || value_str[1] == 'X')) { + value_tmp = (int32_t)simple_strtol(value_str, NULL, 16); + } else { + value_tmp = (int32_t)simple_strtol(value_str, NULL, 10); + } + + *value = value_tmp; + return 0; +} + +static int dfd_ko_cfg_analyse_index(char *index_str, int *index1, int *index2, int line_num) +{ + int rv; + char *index1_begin_char, *index2_begin_char; + + if (index_str[0] != '_') { + DBG_DEBUG(DBG_ERROR, "line%d: no '-' between name and index1\n", line_num); + return -1; + } + + index1_begin_char = index_str; + rv = dfd_ko_cfg_get_value_from_char(++index1_begin_char, index1, line_num); + if (rv < 0) { + return -1; + } + + if (index2 == NULL) { + return 0; + } + + index2_begin_char = strchr(index1_begin_char, '_'); + if (index2_begin_char == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: no '-' between index1 and index2\n", line_num); + return -1; + } else { + rv = dfd_ko_cfg_get_value_from_char(++index2_begin_char, index2, line_num); + if (rv < 0) { + return -1; + } + } + + return 0; +} + +static int dfd_ko_cfg_check_array_index(index_range_t *index_range, int *index1, int *index2, + int line_num) +{ + + if ((*index1 < 0) || (*index1 > index_range->index1_max)) { + DBG_DEBUG(DBG_ERROR, "line%d: index1[%d] invalid, max=%d\n", line_num, *index1, + index_range->index1_max); + return -1; + } + + if (index2 == NULL) { + return 0; + } + + if ((*index2 < 0) || (*index2 > index_range->index2_max)) { + DBG_DEBUG(DBG_ERROR, "line%d: index2[%d] invalid, max=%d\n", line_num, *index2, + index_range->index2_max); + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_get_index(char *index_str, index_range_t *index_range, int *index1, + int *index2, int line_num) +{ + int rv; + + if (index_range->index2_max == INDEX_NOT_EXIST) { + index2 = NULL; + } + + rv = dfd_ko_cfg_analyse_index(index_str, index1, index2, line_num); + if (rv < 0) { + return -1; + } + + rv = dfd_ko_cfg_check_array_index(index_range, index1, index2, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_add_int_item(int key, int value, int line_num) +{ + int rv; + int *int_cfg; + + int_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (int_cfg == NULL) { + + int_cfg = (int *)kmalloc(sizeof(int), GFP_KERNEL); + if (int_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc int fail\n", line_num); + return -1; + } + + *int_cfg = value; + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, int_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add int item[%d] success, key=0x%08x\n", line_num, value, key); + } else { + kfree(int_cfg); + int_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add int item[%d] fail, key=0x%08x rv=%d \n", line_num, value, key, rv); + return -1; + } + } else { + + DBG_DEBUG(DBG_WARN, "line%d: replace int item[%d->%d], key=0x%08x\n", line_num, *int_cfg, value, key); + *int_cfg = value; + } + + return 0; +} + +static int dfd_ko_cfg_analyse_int_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, char *arg_value, + char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int value, key; + char *arg_name_tmp; + + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num); + if (rv < 0) { + return -1; + } + + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_int_item(key, value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_add_str_item(int key, char *str, int line_num) +{ + int rv; + char *str_cfg; + + str_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (str_cfg == NULL) { + + str_cfg = (char *)kmalloc(DFD_CFG_STR_MAX_LEN, GFP_KERNEL); + if (str_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc str[%lu] fail\n", line_num, strlen(str)); + return -1; + } + mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); + strncpy(str_cfg, str, DFD_CFG_STR_MAX_LEN - 1); + + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, str_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add string item[%s] success, key=0x%08x\n", line_num, str_cfg, key); + } else { + kfree(str_cfg); + str_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add string item[%s] fail, key=0x%08x rv=%d \n", line_num, str_cfg, key, rv); + return -1; + } + } else { + DBG_DEBUG(DBG_WARN, "line%d: replace string item[%s->%s], key=0x%08x\n", line_num, str_cfg, str, key); + mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); + strncpy(str_cfg, str, DFD_CFG_STR_MAX_LEN - 1); + } + + return 0; +} + +static int dfd_ko_cfg_analyse_str_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, char *arg_value, + char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int btree_key; + char *arg_name_tmp; + + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + if (strlen(arg_value) >= DFD_CFG_STR_MAX_LEN) { + DBG_DEBUG(DBG_ERROR, "line%d: string item[%s] is too long \n", line_num, arg_value); + return -1; + } + + btree_key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_str_item(btree_key, arg_value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_get_i2c_dev_member(char *member_str, dfd_i2c_dev_mem_t *member, int line_num) +{ + dfd_i2c_dev_mem_t mem_index; + + for (mem_index = DFD_I2C_DEV_MEM_BUS; mem_index < DFD_I2C_DEV_MEM_END; mem_index++) { + if (memcmp(member_str, g_dfd_i2c_dev_mem_str[mem_index], + strlen(g_dfd_i2c_dev_mem_str[mem_index])) == 0) { + *member = mem_index; + return 0; + } + } + + DBG_DEBUG(DBG_ERROR, "line%d: i2c dev member[%s] invalid\n", line_num, member_str); + return -1; +} + +static void dfd_ko_cfg_set_i2c_dev_mem_value(dfd_i2c_dev_t *i2c_dev, dfd_i2c_dev_mem_t member, + int value) +{ + switch (member) { + case DFD_I2C_DEV_MEM_BUS: + i2c_dev->bus = value; + break; + case DFD_I2C_DEV_MEM_ADDR: + i2c_dev->addr = value; + break; + default: + break; + } +} + +static int dfd_ko_cfg_add_i2c_dev_item(int key, dfd_i2c_dev_mem_t member, int value, int line_num) +{ + int rv; + dfd_i2c_dev_t *i2c_dev_cfg; + + i2c_dev_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (i2c_dev_cfg == NULL) { + + i2c_dev_cfg = (dfd_i2c_dev_t *)kmalloc(sizeof(dfd_i2c_dev_t), GFP_KERNEL); + if (i2c_dev_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc i2c_dev fail\n", line_num); + return -1; + } + mem_clear(i2c_dev_cfg, sizeof(dfd_i2c_dev_t)); + + dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value); + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, i2c_dev_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add i2c_dev item[%s=%d] success, key=0x%08x\n", line_num, + g_dfd_i2c_dev_mem_str[member], value, key); + } else { + kfree(i2c_dev_cfg); + i2c_dev_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add i2c_dev item[%s=%d] fail, key=0x%08x rv=%d\n", line_num, + g_dfd_i2c_dev_mem_str[member], value, key, rv); + return -1; + } + } else { + + DBG_DEBUG(DBG_VERBOSE, "line%d: replace i2c_dev item[%s=%d], key=0x%08x\n", line_num, + g_dfd_i2c_dev_mem_str[member], value, key); + dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value); + } + + return 0; +} + +static int dfd_ko_cfg_analyse_i2c_dev_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int value, key; + char *arg_name_tmp; + dfd_i2c_dev_mem_t member; + + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_i2c_dev_member(arg_name_tmp, &member, line_num); + if (rv < 0) { + return -1; + } + + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp += strlen(g_dfd_i2c_dev_mem_str[member]); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num); + if (rv < 0) { + return -1; + } + + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_i2c_dev_item(key, member, value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_get_enum_value_by_str(char *enum_val_str[], int enum_val_end, char *buf) +{ + int i; + int enum_val; + + enum_val = DFD_CFG_INVALID_VALUE; + for (i = 0; i < enum_val_end; i++) { + if (memcmp(buf, enum_val_str[i], strlen(enum_val_str[i])) == 0) { + enum_val = i; + break; + } + } + + return enum_val; +} + +static int dfd_ko_cfg_get_info_ctrl_member(char *member_str, info_ctrl_mem_t *member, int line_num) +{ + info_ctrl_mem_t mem_index; + + for (mem_index = INFO_CTRL_MEM_MODE; mem_index < INFO_CTRL_MEM_END; mem_index++) { + if (memcmp(member_str, g_info_ctrl_mem_str[mem_index], + strlen(g_info_ctrl_mem_str[mem_index])) == 0) { + *member = mem_index; + return 0; + } + } + + DBG_DEBUG(DBG_ERROR, "line%d: info ctrl member[%s] invalid\n", line_num, member_str); + return -1; +} + +static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl_mem_t member, + char *buf_val, int line_num) +{ + switch (member) { + case INFO_CTRL_MEM_MODE: + info_ctrl->mode = dfd_ko_cfg_get_enum_value_by_str(g_info_ctrl_mode_str, INFO_CTRL_MODE_END, buf_val);; + break; + case INFO_CTRL_MEM_INT_CONS: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_cons), line_num); + break; + case INFO_CTRL_MEM_SRC: + info_ctrl->src = dfd_ko_cfg_get_enum_value_by_str(g_info_src_str, INFO_SRC_END, buf_val); + break; + case INFO_CTRL_MEM_FRMT: + info_ctrl->frmt = dfd_ko_cfg_get_enum_value_by_str(g_info_frmt_str, INFO_FRMT_END, buf_val); + break; + case INFO_CTRL_MEM_POLA: + info_ctrl->pola = dfd_ko_cfg_get_enum_value_by_str(g_info_pola_str, INFO_POLA_END, buf_val); + break; + case INFO_CTRL_MEM_FPATH: + mem_clear(info_ctrl->fpath, sizeof(info_ctrl->fpath)); + strncpy(info_ctrl->fpath, buf_val, sizeof(info_ctrl->fpath) - 1); + break; + case INFO_CTRL_MEM_ADDR: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->addr), line_num); + break; + case INFO_CTRL_MEM_LEN: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->len), line_num); + break; + case INFO_CTRL_MEM_BIT_OFFSET: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->bit_offset), line_num); + break; + case INFO_CTRL_MEM_STR_CONS: + mem_clear(info_ctrl->str_cons, sizeof(info_ctrl->str_cons)); + strncpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons) - 1); + break; + case INFO_CTRL_MEM_INT_EXTRA1: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra1), line_num); + break; + case INFO_CTRL_MEM_INT_EXTRA2: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra2), line_num); + break; + default: + break; + } +} + +static int dfd_ko_cfg_add_info_ctrl_item(int key, info_ctrl_mem_t member, char *buf_val, + int line_num) +{ + int rv; + info_ctrl_t *info_ctrl_cfg; + + info_ctrl_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (info_ctrl_cfg == NULL) { + + info_ctrl_cfg = (info_ctrl_t *)kmalloc(sizeof(info_ctrl_t), GFP_KERNEL); + if (info_ctrl_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc info_ctrl fail\n", line_num); + return -1; + } + mem_clear(info_ctrl_cfg, sizeof(info_ctrl_t)); + + dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num); + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, info_ctrl_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add info_ctrl item[%s=%s] success, key=0x%08x\n", line_num, + g_info_ctrl_mem_str[member], buf_val, key); + } else { + kfree(info_ctrl_cfg); + info_ctrl_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add info_ctrl item[%s=%s] fail, key=0x%08x rv=%d\n", line_num, + g_info_ctrl_mem_str[member], buf_val, key, rv); + return -1; + } + } else { + + DBG_DEBUG(DBG_VERBOSE, "line%d: replace info_ctrl item[%s=%s], key=0x%08x\n", line_num, + g_info_ctrl_mem_str[member], buf_val, key); + dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num); + } + + return 0; +} + +static int dfd_ko_cfg_analyse_info_ctrl_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int key; + char *arg_name_tmp; + info_ctrl_mem_t member; + + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_info_ctrl_member(arg_name_tmp, &member, line_num); + if (rv < 0) { + return -1; + } + + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp += strlen(g_info_ctrl_mem_str[member]); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_info_ctrl_item(key, member, arg_value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +static int dfd_ko_cfg_analyse_config(char *arg_name, char*arg_value, int line_num) +{ + int i, rv = 0; + int cfg_item_num; + + cfg_item_num = sizeof(dfd_cfg_item_name) / sizeof(dfd_cfg_item_name[0]); + for (i = 0; i < cfg_item_num; i++) { + if (memcmp(arg_name, dfd_cfg_item_name[i], strlen(dfd_cfg_item_name[i])) == 0){ + if (DFD_CFG_ITEM_IS_INT(i)) { + rv = dfd_ko_cfg_analyse_int_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_STRING(i)) { + rv = dfd_ko_cfg_analyse_str_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_I2C_DEV(i)) { + rv = dfd_ko_cfg_analyse_i2c_dev_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_INFO_CTRL(i)) { + rv = dfd_ko_cfg_analyse_info_ctrl_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else { + rv = -1; + } + break; + } + } + + return rv; +} + +static int dfd_ko_cfg_cut_config_line(char *config_line, char *arg_name, char *arg_value) +{ + int i, j = 0, k = 0; + int len, name_value_flag = 0; + + len = strlen(config_line); + for (i = 0; i < len; i++) { + if (config_line[i] == '=') { + name_value_flag = 1; + continue; + } + + if (name_value_flag == 0) { + arg_name[j++] = config_line[i]; + } else { + arg_value[k++] = config_line[i]; + } + } + + if (name_value_flag == 0) { + return -1; + } else { + return 0; + } +} + +static int dfd_ko_cfg_analyse_config_line(char *config_line, int line_num) +{ + int rv; + char arg_name[DFD_CFG_NAME_MAX_LEN] = {0}; + char arg_value[DFD_CFG_VALUE_MAX_LEN] = {0}; + + dfd_ko_cfg_del_space_lf_cr(config_line); + + if (strlen(config_line) == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: space line\n", line_num); + return 0; + } + + if (config_line[0] == '#') { + DBG_DEBUG(DBG_VERBOSE, "line%d: comment line[%s]\n", line_num, config_line); + return 0; + } + + rv = dfd_ko_cfg_cut_config_line(config_line, arg_name, arg_value); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: [%s]no '=' between name and value\n", line_num, config_line); + return -1; + } + + DBG_DEBUG(DBG_VERBOSE, "line%d: config_line[%s] name[%s] value[%s]\n", line_num, config_line, arg_name, arg_value); + return dfd_ko_cfg_analyse_config(arg_name, arg_value, line_num); +} + +static int dfd_ko_cfg_analyse_config_file(char *fpath) +{ + int rv; + int line_num = 1; + kfile_ctrl_t kfile_ctrl; + char config_line[DFD_CFG_CMDLINE_MAX_LEN] = {0}; + + rv = kfile_open(fpath, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", fpath, rv); + return -1; + } + + while(kfile_gets(config_line, sizeof(config_line), &kfile_ctrl) > 0){ + rv = dfd_ko_cfg_analyse_config_line(config_line, line_num++); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "!!!!file[%s] config line[%d %s] analyse fail\n", fpath, line_num - 1, + config_line); + break; + } + + (void)mem_clear(config_line, sizeof(config_line)); + + } + kfile_close(&kfile_ctrl); + + return rv; +} + +void *dfd_ko_cfg_get_item(int key) +{ + return lnode_find_node(&dfd_ko_cfg_list_root, key); +} + +static void dfd_ko_cfg_print_item(int key, const void *cfg) +{ + int item_id; + dfd_i2c_dev_t *i2c_dev; + info_ctrl_t *info_ctrl; + + if (cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return; + } + printk(KERN_INFO "**************************\n"); + printk(KERN_INFO "key=0x%08x\n", key); + + item_id = DFD_CFG_ITEM_ID(key); + if (DFD_CFG_ITEM_IS_INT(item_id)) { + printk(KERN_INFO "int=%d\n", *((int *)cfg)); + } else if (DFD_CFG_ITEM_IS_I2C_DEV(item_id)) { + i2c_dev = (dfd_i2c_dev_t *)cfg; + printk(KERN_INFO ".bus=0x%02x\n", i2c_dev->bus); + printk(KERN_INFO ".addr=0x%02x\n", i2c_dev->addr); + } else if (DFD_CFG_ITEM_IS_INFO_CTRL(item_id)) { + info_ctrl = (info_ctrl_t *)cfg; + printk(KERN_INFO ".mode=%s\n", g_info_ctrl_mode_str[info_ctrl->mode]); + printk(KERN_INFO ".int_cons=%d\n", info_ctrl->int_cons); + printk(KERN_INFO ".src=%s\n", g_info_src_str[info_ctrl->src]); + printk(KERN_INFO ".frmt=%s\n", g_info_frmt_str[info_ctrl->frmt]); + printk(KERN_INFO ".pola=%s\n", g_info_pola_str[info_ctrl->pola]); + printk(KERN_INFO ".fpath=%s\n", info_ctrl->fpath); + printk(KERN_INFO ".addr=0x%02x\n", info_ctrl->addr); + printk(KERN_INFO ".len=%d\n", info_ctrl->len); + printk(KERN_INFO ".bit_offset=%d\n", info_ctrl->bit_offset); + } else { + printk(KERN_INFO "item[%d] error!\n", item_id); + } +} + +void dfd_ko_cfg_show_item(int key) +{ + void *cfg; + + cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (cfg == 0) { + printk(KERN_INFO "item[0x%08x] not exist\n", key); + return; + } + + dfd_ko_cfg_print_item(key, cfg); +} + +static int dfd_get_my_dev_type_by_file(void) +{ + struct file *fp; + loff_t pos; + int card_type; + char buf[DFD_PID_BUF_LEN]; + int ret; + + fp= filp_open(DFD_PUB_CARDTYPE_FILE, O_RDONLY, 0); + if (IS_ERR(fp)) { + DBG_DEBUG(DBG_VERBOSE, "open file fail!\n"); + return -1; + } + mem_clear(buf, DFD_PID_BUF_LEN); + pos = 0; + ret = kernel_read(fp, buf, DFD_PRODUCT_ID_LENGTH + 1, &pos); + if (ret < 0) { + DBG_DEBUG(DBG_VERBOSE, "kernel_read failed, path=%s, addr=0, size=%d, ret=%d\n", + DFD_PUB_CARDTYPE_FILE, DFD_PRODUCT_ID_LENGTH + 1, ret); + filp_close(fp, NULL); + return -1; + } + + card_type = simple_strtoul(buf, NULL, 10); + DBG_DEBUG(DBG_VERBOSE, "card_type 0x%x.\n", card_type); + + filp_close(fp, NULL); + return card_type; +} + +static int drv_get_my_dev_type(void) +{ + static int type = -1; + + if (type > 0) { + return type; + } + type = dfd_get_my_dev_type_by_file(); + DBG_DEBUG(DBG_VERBOSE, "ko board type %d\n", type); + return type; +} + +static int dfd_ko_cfg_init(void) +{ + int rv; + int card_type; + char file_name[32] = {0}; + char fpath[128] = {0}; + kfile_ctrl_t kfile_ctrl; + + rv = lnode_init_root(&dfd_ko_cfg_list_root); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "init list root fail, rv=%d\n", rv); + return -1; + } + + card_type = drv_get_my_dev_type(); + if (card_type > 0) { + snprintf(fpath, sizeof(fpath), "%s0x%x", DFD_KO_CFG_FILE_DIR, card_type); + rv = kfile_open(fpath, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_VERBOSE, "open config file[%s] fail, rv=%d, maybe not exist\n", + fpath, rv); + + rv = kfile_open(DFD_KO_CFG_FILE_NAME, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", DFD_KO_CFG_FILE_NAME, + rv); + return -1; + } + DBG_DEBUG(DBG_ERROR, "get config file from: %s, success.\n", DFD_KO_CFG_FILE_NAME); + } else { + DBG_DEBUG(DBG_VERBOSE, "get config file from: %s, success.\n", fpath); + } + } else { + DBG_DEBUG(DBG_VERBOSE, "get board id failed, try to get config file from: %s\n", + DFD_KO_CFG_FILE_NAME); + + rv = kfile_open(DFD_KO_CFG_FILE_NAME, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", DFD_KO_CFG_FILE_NAME, rv); + return -1; + } + DBG_DEBUG(DBG_ERROR, "get config file from: %s, success.\n", DFD_KO_CFG_FILE_NAME); + } + + while (kfile_gets(file_name, sizeof(file_name), &kfile_ctrl) > 0) { + + dfd_ko_cfg_del_space_lf_cr(file_name); + mem_clear(fpath, sizeof(fpath)); + snprintf(fpath, sizeof(fpath), "%s%s.cfg", DFD_KO_CFG_FILE_DIR, file_name); + DBG_DEBUG(DBG_VERBOSE, ">>>>start parsing config file[%s]\n", fpath); + + rv = dfd_ko_cfg_analyse_config_file(fpath); + if (rv < 0) { + break; + } + } + kfile_close(&kfile_ctrl); + + return 0; +} + +int32_t dfd_dev_cfg_init(void) +{ + return dfd_ko_cfg_init(); +} + +void dfd_dev_cfg_exit(void) +{ + lnode_free_list(&dfd_ko_cfg_list_root); + return; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c new file mode 100644 index 000000000000..1d5ca7072f8f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c @@ -0,0 +1,351 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "../include/dfd_module.h" +#include "../include/dfd_cfg_file.h" +#include "../include/dfd_cfg.h" +#include "../include/dfd_cfg_adapter.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +char *g_dfd_i2c_dev_mem_str[DFD_I2C_DEV_MEM_END] = { + ".bus", + ".addr", +}; + +static dfd_i2c_dev_t* dfd_ko_get_cpld_i2c_dev(int sub_slot, int cpld_id) +{ + int key; + dfd_i2c_dev_t *i2c_dev; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_I2C_DEV, sub_slot, cpld_id); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld[%d] i2c dev config fail, key=0x%08x\n", cpld_id, key); + return NULL; + } + + return i2c_dev; +} + +static int32_t dfd_ko_i2c_smbus_transfer(int read_write, int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int rv; + struct i2c_adapter *i2c_adap; + union i2c_smbus_data data; + + i2c_adap = i2c_get_adapter(bus); + if (i2c_adap == NULL) { + DBG_DEBUG(DBG_ERROR, "get i2c bus[%d] adapter fail\n", bus); + return -DFD_RV_DEV_FAIL; + } + + if (read_write == I2C_SMBUS_WRITE) { + data.byte = *buf; + } else { + data.byte = 0; + } + rv = i2c_smbus_xfer(i2c_adap, addr, 0, read_write, offset, I2C_SMBUS_BYTE_DATA, &data); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer fail, rv=%d\n", + bus, addr, offset, size, read_write, rv); + rv = -DFD_RV_DEV_FAIL; + } else { + DBG_DEBUG(DBG_VERBOSE, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer success\n", + bus, addr, offset, size, read_write); + rv = DFD_RV_OK; + } + + if (read_write == I2C_SMBUS_READ) { + if (rv == DFD_RV_OK) { + *buf = data.byte; + } else { + *buf = 0; + } + } + + i2c_put_adapter(i2c_adap); + return rv; +} + +static int32_t dfd_ko_i2c_read_data(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_READ, bus, addr, offset, buf, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d]cpld read[offset=0x%x] fail, rv %d\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d]cpld read[offset=0x%x] success, value=0x%x\n", + i, addr, *buf); + break; + } + } + return rv; +} + +static int32_t dfd_ko_i2c_write_data(int bus, int addr, int offset, uint8_t data, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_WRITE, bus, addr, offset, &data, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d]cpld write[offset=0x%x] fail, rv=%d\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d]cpld write[offset=0x%x, data=%d] success\n", i, addr, data); + break; + } + } + + return rv; +} + +static int32_t dfd_ko_cpld_i2c_read(int32_t addr, uint8_t *buf) +{ + int rv; + int sub_slot, cpld_id, cpld_addr; + dfd_i2c_dev_t *i2c_dev; + + if (buf == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INDEX_INVALID; + } + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + cpld_addr = DFD_KO_CPLD_GET_INDEX(addr); + + i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id); + if (i2c_dev == NULL) { + return -DFD_RV_DEV_NOTSUPPORT; + } + rv = dfd_ko_i2c_read_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, buf, sizeof(uint8_t)); + + return rv; +} + +static int32_t dfd_ko_cpld_i2c_write(int32_t addr, uint8_t data) +{ + int rv; + int sub_slot, cpld_id, cpld_addr; + dfd_i2c_dev_t *i2c_dev; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + cpld_addr = DFD_KO_CPLD_GET_INDEX(addr); + + i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id); + if (i2c_dev == NULL) { + return -DFD_RV_DEV_NOTSUPPORT; + } + + rv = dfd_ko_i2c_write_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, data, sizeof(uint8_t)); + + return rv; +} + +static int32_t dfd_ko_cpld_io_read(int32_t addr, uint8_t *buf) +{ + int cpld_id, sub_slot, offset; + int key; + int *tmp; + uint16_t io_port; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + offset = DFD_KO_CPLD_GET_INDEX(addr); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id); + tmp = dfd_ko_cfg_get_item(key); + if (tmp == NULL) { + DBG_DEBUG(DBG_ERROR,"get cpld io base config fail, key=0x%08x\n", key); + return -1; + } + + io_port = (u16)(*tmp) + offset; + *buf = inb(io_port); + DBG_DEBUG(DBG_VERBOSE, "read cpld io port addr 0x%x, data 0x%x\n", io_port, *buf); + + return DFD_RV_OK; + +} + +static int32_t dfd_ko_cpld_io_write(int32_t addr, uint8_t data) +{ + int cpld_id, sub_slot, offset; + int key; + int *tmp; + uint16_t io_port; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + offset = DFD_KO_CPLD_GET_INDEX(addr); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id); + tmp = dfd_ko_cfg_get_item(key); + if (tmp == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld io base config fail, key=0x%08x\n", key); + return -1; + } + + io_port = (u16)(*tmp) + offset; + DBG_DEBUG(DBG_VERBOSE, "write cpld io port addr 0x%x, data 0x%x\n", io_port, data); + outb(data, (u16)io_port); + + return DFD_RV_OK; +} + +static int dfd_cfg_get_cpld_mode(int sub_slot, int cpld_id, int *mode) +{ + int key; + char *name; + + if (mode == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_TYPE_ERR; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_MODE, sub_slot, cpld_id); + name = dfd_ko_cfg_get_item(key); + if (name == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld[%d] mode info ctrl fail, key=0x%08x\n", cpld_id, key); + return -DFD_RV_NODE_FAIL; + } + + DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode_name %s.\n", cpld_id, name); + if (!strncmp(name, DFD_KO_CPLD_MODE_I2C_STRING, strlen(DFD_KO_CPLD_MODE_I2C_STRING))) { + *mode = DFD_CPLD_MODE_I2C; + } else if (!strncmp(name, DFD_KO_CPLD_MODE_LPC_STRING, strlen(DFD_KO_CPLD_MODE_LPC_STRING))) { + *mode = DFD_CPLD_MODE_LPC; + } else { + + *mode = DFD_CPLD_MODE_I2C; + } + + DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode %d.\n", cpld_id, *mode); + return 0; +} + +int32_t dfd_ko_cpld_read(int32_t addr, uint8_t *buf) +{ + int ret; + int sub_slot, cpld_id; + int cpld_mode; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + + ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode); + if (ret) { + DBG_DEBUG(DBG_WARN, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default i2c mode.\n", sub_slot, cpld_id); + cpld_mode = DFD_CPLD_MODE_I2C; + } + + if (cpld_mode == DFD_CPLD_MODE_I2C) { + ret = dfd_ko_cpld_i2c_read(addr, buf); + } else if (cpld_mode == DFD_CPLD_MODE_LPC) { + ret = dfd_ko_cpld_io_read(addr, buf); + } else { + DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, *buf, ret); + return ret; +} + +int32_t dfd_ko_cpld_write(int32_t addr, uint8_t val) +{ + int ret; + int sub_slot, cpld_id, cpld_mode; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + + ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode); + if (ret) { + DBG_DEBUG(DBG_ERROR, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default local_bus mode.\n", sub_slot, cpld_id); + cpld_mode = DFD_CPLD_MODE_I2C; + } + + if (cpld_mode == DFD_CPLD_MODE_I2C) { + ret = dfd_ko_cpld_i2c_write(addr, val); + } else if (cpld_mode == DFD_CPLD_MODE_LPC) { + ret = dfd_ko_cpld_io_write(addr, val); + } else { + DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, val, ret); + return ret; +} + +int32_t dfd_ko_i2c_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + + for (i = 0; i < size; i++) { + rv = dfd_ko_i2c_read_data(bus, addr, offset, &buf[i], sizeof(uint8_t)); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_read[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n", + bus, addr, offset, rv); + return rv; + } + offset++; + } + + return size; +} + +int32_t dfd_ko_i2c_write(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + + for (i = 0; i < size; i++) { + rv = dfd_ko_i2c_write_data(bus, addr, offset, buf[i], sizeof(uint8_t)); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_write[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n", + bus, addr, offset, rv); + return rv; + } + offset++; + } + + return size; + +} + +int32_t dfd_ko_read_file(char *fpath, int32_t addr, uint8_t *val, int32_t read_bytes) +{ + int32_t ret; + struct file *filp; + loff_t pos; + + if ((fpath == NULL) || (val == NULL) || (addr < 0) || (read_bytes < 0)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, addr=%d read_bytes=%d\n", addr, read_bytes); + return -DFD_RV_INDEX_INVALID; + } + + filp = filp_open(fpath, O_RDONLY, 0); + if (IS_ERR(filp)){ + DBG_DEBUG(DBG_ERROR, "open file[%s] fail\n", fpath); + return -DFD_RV_DEV_FAIL; + } + + pos = addr; + ret = kernel_read(filp, val, read_bytes, &pos); + if (ret < 0) { + DBG_DEBUG(DBG_ERROR, "kernel_read failed, path=%s, addr=%d, size=%d, ret=%d\n", fpath, addr, read_bytes, ret); + ret = -DFD_RV_DEV_FAIL; + } + + filp_close(filp, NULL); + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c new file mode 100644 index 000000000000..8d77759ba7e0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../include/dfd_cfg_file.h" +#include "../include/dfd_module.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +struct getdents_callback { + struct dir_context ctx; + const char *obj_name; + char *match_name; + int dir_len; + int found; +}; + +int kfile_open(char *fname, kfile_ctrl_t *kfile_ctrl) +{ + int ret; + struct file *filp; + loff_t pos; + + if ((fname == NULL) || (kfile_ctrl == NULL)) { + return KFILE_RV_INPUT_ERR; + } + + filp = filp_open(fname, O_RDONLY, 0); + if (IS_ERR(filp)){ + return KFILE_RV_OPEN_FAIL; + } + + kfile_ctrl->size = filp->f_inode->i_size; + + kfile_ctrl->buf = kmalloc(kfile_ctrl->size, GFP_KERNEL); + if (kfile_ctrl->buf == NULL) { + ret = KFILE_RV_MALLOC_FAIL; + goto close_fp; + } + mem_clear(kfile_ctrl->buf, kfile_ctrl->size); + + pos = 0; + ret = kernel_read(filp, kfile_ctrl->buf, kfile_ctrl->size, &pos); + if (ret < 0) { + ret = KFILE_RV_RD_FAIL; + goto free_buf; + } + + kfile_ctrl->pos = 0; + + ret = KFILE_RV_OK; + goto close_fp; + +free_buf: + kfree(kfile_ctrl->buf); + kfile_ctrl->buf = NULL; + +close_fp: + filp_close(filp, NULL); + return ret; +} + +void kfile_close(kfile_ctrl_t *kfile_ctrl) +{ + if (kfile_ctrl == NULL) { + return; + } + + kfile_ctrl->size = 0; + kfile_ctrl->pos = 0; + if (kfile_ctrl->buf) { + kfree(kfile_ctrl->buf); + kfile_ctrl->buf = NULL; + } +} + +int kfile_gets(char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl) +{ + int i; + int has_cr = 0; + + if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL) + || (kfile_ctrl->size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + mem_clear(buf, buf_size); + for (i = 0; i < buf_size; i++) { + + if (kfile_ctrl->pos >= kfile_ctrl->size) { + break; + } + + if (has_cr) { + break; + } + + if (IS_CR(kfile_ctrl->buf[kfile_ctrl->pos])) { + has_cr = 1; + } + + buf[i] = kfile_ctrl->buf[kfile_ctrl->pos]; + kfile_ctrl->pos++; + } + + return i; +} + +int kfile_read(int32_t addr, char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl) +{ + int i; + + if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL) + || (kfile_ctrl->size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + if ((addr < 0) || (addr >= kfile_ctrl->size)) { + return KFILE_RV_ADDR_ERR; + } + + mem_clear(buf, buf_size); + + kfile_ctrl->pos = addr; + for (i = 0; i < buf_size; i++) { + + if (kfile_ctrl->pos >= kfile_ctrl->size) { + break; + } + + buf[i] = kfile_ctrl->buf[kfile_ctrl->pos]; + kfile_ctrl->pos++; + } + + return i; +} + +static int kfile_filldir_one(struct dir_context *ctx, const char * name, int len, + loff_t pos, u64 ino, unsigned int d_type) +{ + struct getdents_callback *buf ; + int result; + buf = container_of(ctx, struct getdents_callback, ctx); + result = 0; + if (strncmp(buf->obj_name, name, strlen(buf->obj_name)) == 0) { + if (buf->dir_len < len) { + DBG_DEBUG(DBG_ERROR, "match ok. dir name:%s, but buf_len %d small than dir len %d.\n", + name, buf->dir_len, len); + buf->found = 0; + return -1; + } + mem_clear(buf->match_name, buf->dir_len); + memcpy(buf->match_name, name, len); + buf->found = 1; + result = -1; + } + return result; +} + +int kfile_iterate_dir(const char *dir_path, const char *obj_name, char *match_name, int len) +{ + int ret; + struct file *dir; + struct getdents_callback buffer = { + .ctx.actor = kfile_filldir_one, + }; + + if(!dir_path || !obj_name || !match_name) { + DBG_DEBUG(DBG_ERROR, "params error. \n"); + return KFILE_RV_INPUT_ERR; + } + buffer.obj_name = obj_name; + buffer.match_name = match_name; + buffer.dir_len = len; + buffer.found = 0; + + dir = filp_open(dir_path, O_RDONLY, 0); + if (IS_ERR(dir)) { + DBG_DEBUG(DBG_ERROR, "filp_open error, dir path:%s\n", dir_path); + return KFILE_RV_OPEN_FAIL; + } + ret = iterate_dir(dir, &buffer.ctx); + if (buffer.found) { + DBG_DEBUG(DBG_VERBOSE, "match ok, dir name:%s\n", match_name); + filp_close(dir, NULL); + return DFD_RV_OK; + } + filp_close(dir, NULL); + return -DFD_RV_NODE_FAIL; +} + +#if 0 + +int kfile_write(char *fpath, int32_t addr, char *buf, int buf_size) +{ + int ret = KFILE_RV_OK; + struct file *filp; + mm_segment_t old_fs; + int wlen; + + if ((fpath == NULL) || (buf == NULL) || (buf_size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + if (addr < 0) { + return KFILE_RV_ADDR_ERR; + } + + filp = filp_open(fpath, O_RDWR, 0); + if (IS_ERR(filp)){ + return KFILE_RV_OPEN_FAIL; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + filp->f_op->llseek(filp,0,0); + filp->f_pos = addr; + + wlen = filp->f_op->write(filp, buf, buf_size, &(filp->f_pos)); + if (wlen < 0) { + ret = KFILE_RV_WR_FAIL; + } + + filp->f_op->llseek(filp,0,0); + set_fs(old_fs); + filp_close(filp, NULL); + + return ret; +} +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c new file mode 100644 index 000000000000..5dae1539a116 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c @@ -0,0 +1,587 @@ +#include +#include +#include + +#include "../include/dfd_module.h" +#include "../include/dfd_cfg_adapter.h" +#include "../include/dfd_cfg.h" +#include "../include/dfd_cfg_info.h" +#include "../include/dfd_cfg_file.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +#define DFD_HWMON_NAME "hwmon" +#define DFD_GET_CPLD_VOLATGE_CODE_VALUE(value) ((value >> 4)& 0xfff) +#define DFD_GET_CPLD_VOLATGE_REAL_VALUE(code_val, k) ((code_val * 16 * 33 * k) / ((65536 - 5000) * 10)) + +char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END] = { + ".mode", + ".int_cons", + ".src", + ".frmt", + ".pola", + ".fpath", + ".addr", + ".len", + ".bit_offset", + ".str_cons", + ".int_extra1", + ".int_extra2", +}; + +char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END] = { + "none", + "config", + "constant", + "tlv", + "str_constant", +}; + +char *g_info_src_str[INFO_SRC_END] = { + "none", + "cpld", + "fpga", + "other_i2c", + "file", +}; + +char *g_info_frmt_str[INFO_FRMT_END] = { + "none", + "bit", + "byte", + "num_bytes", + "num_str", + "num_buf", + "buf", +}; + +char *g_info_pola_str[INFO_POLA_END] = { + "none", + "positive", + "negative", +}; + +static int dfd_read_info_from_cpld(int32_t addr, int read_bytes, uint8_t *val) +{ + int i, rv; + + for (i = 0; i < read_bytes; i++) { + rv = dfd_ko_cpld_read(addr, &(val[i])); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "read info[addr=0x%x read_bytes=%d] from cpld fail, reading_byte=%d rv=%d\n", + addr, read_bytes, i, rv); + return rv; + } + addr++; + } + + return read_bytes; +} + +static int dfd_write_info_to_cpld(int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask) +{ + int rv; + uint8_t val_tmp; + + if (bit_mask != 0xff) { + rv = dfd_ko_cpld_read(addr, &val_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "read original info[addr=0x%x] from cpld fail, rv=%d\n", addr, rv); + return -1; + } + + val_tmp = (val_tmp & (~bit_mask)) | (val[0] & bit_mask); + } else { + val_tmp = val[0]; + } + + rv = dfd_ko_cpld_write(addr, val_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "write info[addr=0x%x val=0x%x] to cpld fail, rv=%d\n", addr, val_tmp, rv); + return -1; + } + + return 0; +} + +static int dfd_read_info(info_src_t src, char *fpath, int32_t addr, int read_bytes, uint8_t *val) +{ + int rv = 0; + + switch (src) { + case INFO_SRC_CPLD: + rv = dfd_read_info_from_cpld(addr, read_bytes, val); + break; + case INFO_SRC_FPGA: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support read info from fpga\n"); + break; + case INFO_SRC_OTHER_I2C: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support read info from other i2c\n"); + break; + case INFO_SRC_FILE: + rv = dfd_ko_read_file(fpath, addr, val, read_bytes); + break; + default: + rv = -1; + DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src); + break; + } + + return rv; +} + +static int dfd_write_info(info_src_t src, char *fpath, int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask) +{ + int rv = 0; + + switch (src) { + case INFO_SRC_CPLD: + rv = dfd_write_info_to_cpld(addr, write_bytes, val, bit_mask); + break; + case INFO_SRC_FPGA: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to fpga\n"); + break; + case INFO_SRC_OTHER_I2C: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to other i2c\n"); + break; + case INFO_SRC_FILE: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to file\n"); + break; + default: + rv = -1; + DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src); + break; + } + + return rv; +} + +int dfd_info_get_int(int key, int *ret, info_num_buf_to_value_f pfun) +{ + int i, rv; + int read_bytes, readed_bytes, int_tmp; + uint8_t byte_tmp, val[INFO_INT_MAX_LEN + 1] = {0}; + info_ctrl_t *info_ctrl; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (ret == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08x\n", key); + return -DFD_RV_INDEX_INVALID; + } + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if (info_ctrl->mode == INFO_CTRL_MODE_CONS) { + *ret = info_ctrl->int_cons; + return DFD_RV_OK; + } else if (info_ctrl->mode == INFO_CTRL_MODE_TLV) { + return INFO_CTRL_MODE_TLV; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + + if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] bit_offsest[%d] invalid\n", + key, info_ctrl->bit_offset); + return -DFD_RV_TYPE_ERR; + } + + read_bytes = 1; + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt) || IS_INFO_FRMT_NUM_STR(info_ctrl->frmt) + || IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) { + + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + read_bytes = info_ctrl->len; + } else { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] info format[%d] error\n", key, info_ctrl->frmt); + return -DFD_RV_TYPE_ERR; + } + + readed_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, read_bytes, &(val[0])); + if (readed_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read int info[key=0x%08x src=%s frmt=%s fpath=%s addr=0x%x read_bytes=%d] fail, rv=%d\n", + key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, read_bytes, readed_bytes); + return -DFD_RV_DEV_FAIL; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + + if (info_ctrl->pola == INFO_POLA_NEGA) { + val[0] = ~val[0]; + } + + byte_tmp = (val[0] >> info_ctrl->bit_offset) & (~(0xff << info_ctrl->len)); + + if (pfun) { + rv = pfun(&byte_tmp, sizeof(byte_tmp), &int_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] bit process fail, rv=%d\n", key, rv); + return rv; + } + } else { + int_tmp = (int)byte_tmp; + } + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) { + + int_tmp = 0; + for (i = 0; i < info_ctrl->len; i++) { + if (info_ctrl->pola == INFO_POLA_NEGA) { + int_tmp |= val[info_ctrl->len - i - 1]; + } else { + int_tmp |= val[i]; + } + + if (i != (info_ctrl->len - 1)) { + int_tmp <<= 8; + } + } + } else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) { + + val[readed_bytes] = '\0'; + int_tmp = simple_strtol((char *)(&(val[0])), NULL, 10); + } else { + if (pfun == NULL) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] number buf process function is null\n", key); + return -DFD_RV_INDEX_INVALID; + } + + rv = pfun(val, readed_bytes, &int_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] number buf process fail, rv=%d\n", key, rv); + return rv; + } + } + + *ret = int_tmp; + DBG_DEBUG(DBG_VERBOSE, "read int info[key=0x%08x src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d] success, ret=%d\n", + key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola], + info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, *ret); + return DFD_RV_OK; +} + +int dfd_info_get_buf(int key, uint8_t *buf, int buf_len, info_buf_to_buf_f pfun) +{ + int rv; + int read_bytes, buf_real_len; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + info_ctrl_t *info_ctrl; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (buf == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08x\n", key); + return -DFD_RV_INDEX_INVALID; + } + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if (info_ctrl->mode != INFO_CTRL_MODE_CFG) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] mode[%d] invalid\n", key, info_ctrl->mode); + return -DFD_RV_TYPE_ERR; + } + + if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len) + || (buf_len <= info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] format=%d or len=%d invlaid, buf_len=%d\n", + key, info_ctrl->frmt, info_ctrl->len, buf_len); + return -DFD_RV_TYPE_ERR; + } + + read_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, buf_tmp); + if (read_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read buf info[key=0x%08x src=%s frmt=%s fpath=%s addr=0x%x len=%d] fail, rv=%d\n", + key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, info_ctrl->len, read_bytes); + return -DFD_RV_DEV_FAIL; + } + + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] buf process fail, rv=%d\n", key, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + } else { + buf_real_len = read_bytes; + memcpy(buf, buf_tmp, read_bytes); + } + + return buf_real_len; +} + +static int dfd_2key_info_get_buf(info_ctrl_t *info_ctrl, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun) +{ + int rv; + int read_bytes, buf_real_len; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + char temp_fpath[INFO_FPATH_MAX_LEN]; + + if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len) + || (buf_len <= info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "key_path info ctrl format=%d or len=%d invlaid, buf_len=%d\n", + info_ctrl->frmt, info_ctrl->len, buf_len); + return -DFD_RV_TYPE_ERR; + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + rv = kfile_iterate_dir(info_ctrl->fpath, DFD_HWMON_NAME, buf_tmp, INFO_BUF_MAX_LEN); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dir patch:%s ,can find name %s dir \n", + info_ctrl->fpath, DFD_HWMON_NAME); + return -DFD_RV_NO_NODE; + } + mem_clear(temp_fpath, sizeof(temp_fpath)); + snprintf(temp_fpath, sizeof(temp_fpath), "%s%s/%s", + info_ctrl->fpath, buf_tmp, info_ctrl->str_cons); + DBG_DEBUG(DBG_VERBOSE, "match ok path = %s \n", temp_fpath); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + + read_bytes = dfd_read_info(info_ctrl->src, temp_fpath, info_ctrl->addr, info_ctrl->len, buf_tmp); + if (read_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read buf info[src=%s frmt=%s fpath=%s addr=0x%x len=%d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_src_str[info_ctrl->frmt], temp_fpath, + info_ctrl->addr, info_ctrl->len, read_bytes); + return -DFD_RV_DEV_FAIL; + } + + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len, info_ctrl); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl buf process fail, rv=%d\n", rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + } else { + buf_real_len = read_bytes; + memcpy(buf, buf_tmp, buf_real_len); + } + return buf_real_len; +} + +int dfd_info_set_int(int key, int val) +{ + int rv; + int write_bytes; + uint8_t byte_tmp, bit_mask; + info_ctrl_t *info_ctrl; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key))) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08x\n", key); + return -DFD_RV_INDEX_INVALID; + } + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if (info_ctrl->mode != INFO_CTRL_MODE_CFG) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] mode[%d] warnning\n", key, info_ctrl->mode); + return -DFD_RV_TYPE_ERR; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + + if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] bit_offsest[%d] invalid\n", + key, info_ctrl->bit_offset); + return -DFD_RV_TYPE_ERR; + } + + write_bytes = 1; + + byte_tmp = (uint8_t)(val & 0xff); + byte_tmp <<= info_ctrl->bit_offset; + if (info_ctrl->pola == INFO_POLA_NEGA) { + byte_tmp = ~byte_tmp; + } + + bit_mask = (~(0xff << info_ctrl->len)) << info_ctrl->bit_offset; + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) { + + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + + write_bytes = 1; + + byte_tmp = (uint8_t)(val & 0xff); + + bit_mask = 0xff; + } else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) { + + DBG_DEBUG(DBG_ERROR, "not support str int set\n"); + return -1; + } else if (IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) { + + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + + write_bytes = 1; + + byte_tmp = (uint8_t)(val & 0xff); + + bit_mask = 0xff; + } else { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] format[%d] error\n", key, info_ctrl->frmt); + return -DFD_RV_TYPE_ERR; + } + + rv = dfd_write_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, write_bytes, + &byte_tmp, bit_mask); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "write int info[src=%s frmt=%s fpath=%s addr=0x%x len=%d val=%d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, info_ctrl->len, val, rv); + return -DFD_RV_DEV_FAIL; + } + + DBG_DEBUG(DBG_VERBOSE, "write int info[src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d val=%d] success\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola], + info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, val); + return DFD_RV_OK; +} + +static int dfd_info_get_cpld_voltage(int key, int *value) +{ + int rv, addr_tmp; + int vol_ref_tmp, vol_ref; + int vol_curr_tmp, vol_curr; + info_ctrl_t *info_ctrl; + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + rv = dfd_info_get_int(key, &vol_curr_tmp, NULL); + if(rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld current voltage error, addr:0x%x, rv =%d\n", info_ctrl->addr, rv); + return rv; + } + vol_curr_tmp = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_curr_tmp); + if(info_ctrl->addr == info_ctrl->int_extra1) { + + vol_curr = DFD_GET_CPLD_VOLATGE_REAL_VALUE(vol_curr_tmp, info_ctrl->int_extra2); + } else { + + addr_tmp = info_ctrl->addr; + info_ctrl->addr = info_ctrl->int_extra1; + rv = dfd_info_get_int(key, &vol_ref_tmp, NULL); + info_ctrl->addr = addr_tmp; + if(rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld reference voltage error, addr:0x%x rv:%d\n", info_ctrl->addr, rv); + return rv; + } + vol_ref = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_ref_tmp); + vol_curr = (vol_curr_tmp * info_ctrl->int_extra2) / vol_ref; + } + *value = vol_curr; + return DFD_RV_OK; +} + +static int dfd_info_get_sensor_value(int key, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun) +{ + int rv, buf_real_len; + int value; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + info_ctrl_t *info_ctrl; + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_ERROR, "get info ctrl fail, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if ( DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_IN && info_ctrl->src == INFO_SRC_CPLD) { + + rv = dfd_info_get_cpld_voltage(key, &value); + if(rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld voltage failed.key=0x%08x, rv:%d\n", key, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + DBG_DEBUG(DBG_VERBOSE, "get cpld voltage ok, value:%d\n", value); + mem_clear(buf_tmp, sizeof(buf_tmp)); + snprintf(buf_tmp, sizeof(buf_tmp), "%d\n", value); + buf_real_len = strlen(buf_tmp); + if(buf_len <= buf_real_len) { + DBG_DEBUG(DBG_ERROR, "length not enough.buf_len:%d,need length:%d\n", buf_len, buf_real_len); + return -DFD_RV_DEV_FAIL; + } + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, strlen(buf_tmp), buf, &buf_real_len, info_ctrl); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "deal date error.org value:%s, buf_len:%d, rv=%d\n", + buf_tmp, buf_len, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + } else { + memcpy(buf, buf_tmp, buf_real_len); + } + return buf_real_len; + } + + DBG_DEBUG(DBG_ERROR, "not support mode. key:0x%08x\n", key); + return -DFD_RV_MODE_NOTSUPPORT; +} + +int dfd_info_get_sensor(uint32_t key, char *buf, int buf_len, info_hwmon_buf_f pfun) +{ + info_ctrl_t *key_info_ctrl; + int rv; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || + (buf == NULL) || buf_len <= 0) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key_path=0x%08x, buf_len:%d.\n", + key, buf_len); + return -DFD_RV_INVALID_VALUE; + } + + key_info_ctrl = dfd_ko_cfg_get_item(key); + if (key_info_ctrl == NULL) { + DBG_DEBUG(DBG_ERROR, "key_path info error, key=0x%08x\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(buf, buf_len); + + if (key_info_ctrl->mode == INFO_CTRL_MODE_SRT_CONS) { + snprintf(buf, buf_len, "%s\n", key_info_ctrl->str_cons); + DBG_DEBUG(DBG_VERBOSE, "get sensor value through string config, key=0x%08x, value:%s\n", key, buf); + return strlen(buf); + } + + if (key_info_ctrl->mode == INFO_CTRL_MODE_CFG && key_info_ctrl->src == INFO_SRC_FILE) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon, key:0x%08x\n", key); + rv = dfd_2key_info_get_buf(key_info_ctrl, buf, buf_len, pfun); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon failed, key:0x%08x, rv:%d\n", key, rv); + } + return rv; + } + rv = dfd_info_get_sensor_value(key, buf, buf_len, pfun); + if( rv < 0) { + DBG_DEBUG(DBG_ERROR, "get sensor value failed, key=0x%08x, rv:%d.\n", key, rv); + } + return rv; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c new file mode 100644 index 000000000000..d6fd7e104c9f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c @@ -0,0 +1,82 @@ +#include +#include + +#include "../include/dfd_cfg_listnode.h" +#include "../../dev_sysfs/include/sysfs_common.h" + +void *lnode_find_node(lnode_root_t *root, int key) +{ + lnode_node_t *lnode; + + if (root == NULL){ + return NULL; + } + + list_for_each_entry(lnode, &(root->root), lst) { + if (lnode->key == key) { + return lnode->data; + } + } + + return NULL; +} + +int lnode_insert_node(lnode_root_t *root, int key, void *data) +{ + lnode_node_t *lnode; + void *data_tmp; + + if ((root == NULL) || (data == NULL)) { + return LNODE_RV_INPUT_ERR; + } + + data_tmp = lnode_find_node(root, key); + if (data_tmp != NULL) { + return LNODE_RV_NODE_EXIST; + } + + lnode = kmalloc(sizeof(lnode_node_t), GFP_KERNEL); + if (lnode == NULL) { + return LNODE_RV_NOMEM; + } + + lnode->key = key; + lnode->data = data; + list_add_tail(&(lnode->lst), &(root->root)); + + return LNODE_RV_OK; +} + +int lnode_init_root(lnode_root_t *root) +{ + if (root == NULL) { + return LNODE_RV_INPUT_ERR; + } + + INIT_LIST_HEAD(&(root->root)); + + return LNODE_RV_OK; +} + +void lnode_free_list(lnode_root_t *root) +{ + lnode_node_t *lnode, *lnode_next; + + if (root == NULL){ + return ; + } + + list_for_each_entry_safe(lnode, lnode_next, &(root->root), lst) { + if ( lnode->data ) { + kfree(lnode->data); + lnode->data = NULL; + lnode->key = 0; + } + list_del(&lnode->lst); + kfree(lnode); + lnode = NULL; + } + + return ; + +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c new file mode 100644 index 000000000000..efc322046c07 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c @@ -0,0 +1,170 @@ +#include +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_adapter.h" +#include "./include/dfd_cfg_info.h" +#include "../dev_sysfs/include/sysfs_common.h" + +#define FAN_SIZE (256) + +int g_dfd_fan_dbg_level = 0; +module_param(g_dfd_fan_dbg_level, int, S_IRUGO | S_IWUSR); + +int dfd_get_fan_roll_status(unsigned int fan_index, unsigned int motor_index) +{ + int key, ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_ROLL_STATUS, fan_index, motor_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan roll status error, fan:%d,motor:%d\n", + fan_index, motor_index); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan%u motor%u get fan roll status success, status:%d.\n", + fan_index, motor_index, status); + return status; +} + +int dfd_get_fan_present_status(unsigned int fan_index) +{ + int key, ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_PRESENT_STATUS, WB_MAIN_DEV_FAN, fan_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan%u get present status error, key:0x%x\n", fan_index, key); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan%u get present status success, status:%d.\n", fan_index, status); + return status; +} + +ssize_t dfd_get_fan_speed(unsigned int fan_index, unsigned int motor_index,unsigned int *speed) +{ + int key, ret, speed_tmp; + + if (speed == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SPEED, fan_index, motor_index); + ret = dfd_info_get_int(key, &speed_tmp, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan speed error, key:0x%x,ret:%d\n",key, ret); + return ret; + } + + if (speed_tmp == 0 || speed_tmp == 0xffff) { + *speed = 0; + } else { + *speed = 15000000 / speed_tmp; + } + return DFD_RV_OK; +} + +int dfd_set_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int level) +{ + int key, ret; + + if (level < 0 || level > 0xff) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, can not set fan speed level: %d.\n", + fan_index, motor_index, level); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, motor_index); + ret = dfd_info_set_int(key, level); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, set fan level 0x%02x error, key:0x%x,ret:%d\n", + fan_index, motor_index, level, key, ret); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, set fan speed level 0x%02x success.\n", + fan_index, motor_index, level); + return DFD_RV_OK; +} + +int dfd_set_fan_pwm(unsigned int fan_index, unsigned int motor_index, int pwm) +{ + int ret, data; + + if (pwm < 0 || pwm > 100) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, can't set pwm: %d.\n", + fan_index, motor_index, pwm); + return -DFD_RV_INVALID_VALUE; + } + + data = pwm * 255 / 100; + ret = dfd_set_fan_speed_level(fan_index, motor_index, data); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, set fan ratio:%d error, ret:%d\n", + fan_index, motor_index, data, ret); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, set fan ratio %d success.\n", + fan_index, motor_index, data); + return DFD_RV_OK; +} + +int dfd_get_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int *level) +{ + int key, ret, speed_level; + + if (level == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, motor_index); + ret = dfd_info_get_int(key, &speed_level, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, get fan speed level error, key:0x%x,ret:%d\n", + fan_index, motor_index, key, ret); + return ret; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, get fan speed level success, value:0x%02x.\n", + fan_index, motor_index, speed_level); + *level = speed_level; + return DFD_RV_OK; +} + +int dfd_get_fan_pwm(unsigned int fan_index, unsigned int motor_index, int *pwm) +{ + int ret, level; + + if (pwm == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + ret = dfd_get_fan_speed_level(fan_index, motor_index, &level); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, get fan pwm error, ret:%d\n", + fan_index, motor_index, ret); + return ret; + } + + if ((level * 100) % 255 > 0) { + *pwm = level * 100 / 255 + 1; + } else { + *pwm = level * 100 / 255; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, get fan pwm success, value:%d.\n", + fan_index, motor_index, *pwm); + return DFD_RV_OK; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_module.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_module.c new file mode 100644 index 000000000000..9e5b00b795de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_module.c @@ -0,0 +1,95 @@ +#include + +#include "../dev_sysfs/include/sysfs_common.h" +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_fan_driver.h" +#include "./include/dfd_slot_driver.h" +#include "./include/dfd_sensors_driver.h" +#include "./include/dfd_psu_driver.h" +#include "./include/dfd_sff_driver.h" + +typedef enum dfd_dev_init_fail_s { + DFD_KO_INIT_CPLD_FAIL = 1, + DFD_KO_INIT_FPGA_FAIL = 2, + DFD_KO_INIT_IRQ_FAIL = 3, + DFD_KO_INIT_CFG_FAIL = 4, + DFD_KO_INIT_DATA_FAIL = 5, +} dfd_dev_init_fail_t; + +int g_dfd_dbg_level = 0; + +int dfd_get_dev_number(unsigned int main_dev_id, unsigned int minor_dev_id) +{ + int key,dev_num; + int *p_dev_num; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_NUM, main_dev_id, minor_dev_id); + p_dev_num = dfd_ko_cfg_get_item(key); + if (p_dev_num == NULL) { + DBG_DEBUG(DBG_ERROR, "get device number failed, key:0x%x\n",key); + return -DFD_RV_DEV_NOTSUPPORT; + } + dev_num = *p_dev_num; + DBG_DEBUG(DBG_VERBOSE, "get device number ok, number:%d\n",dev_num); + return dev_num; +} + +static struct switch_drivers_t switch_drivers= { + .get_dev_number = dfd_get_dev_number, + /* fan */ + .get_fan_speed = dfd_get_fan_speed, + .get_fan_pwm = dfd_get_fan_pwm, + .set_fan_pwm = dfd_set_fan_pwm, + .get_fan_present_status = dfd_get_fan_present_status, + .get_fan_roll_status = dfd_get_fan_roll_status, + .get_fan_speed_level = dfd_get_fan_speed_level, + .set_fan_speed_level = dfd_set_fan_speed_level, + /* slot */ + .get_slot_present_status = dfd_get_slot_present_status, + /* sensors */ + .get_temp_info = dfd_get_temp_info, + .get_voltage_info = dfd_get_voltage_info, + /* psu */ + .get_psu_present_status = dfd_get_psu_present_status, + .get_psu_output_status = dfd_get_psu_output_status, + .get_psu_alert_status = dfd_get_psu_alert_status, + /* sff */ + .get_sff_cpld_info = dfd_get_sff_cpld_info, + .get_sff_dir_name = dfd_get_sff_dir_name, +}; + +struct switch_drivers_t * dfd_plat_driver_get(void) { + return &switch_drivers; +} + +static int32_t __init dfd_dev_init(void) +{ + int ret; + + DBG_DEBUG(DBG_VERBOSE, "Enter.\n"); + + ret = dfd_dev_cfg_init(); + if (ret != 0) { + DBG_DEBUG(DBG_ERROR, "dfd_dev_cfg_init failed ret %d.\n", ret); + ret = -DFD_KO_INIT_CFG_FAIL; + return ret; + } + + DBG_DEBUG(DBG_VERBOSE, "success.\n"); + return 0; +} + +static void __exit dfd_dev_exit(void) +{ + DBG_DEBUG(DBG_VERBOSE, "dfd_dev_exit.\n"); + dfd_dev_cfg_exit(); + return ; +} + +module_init(dfd_dev_init); +module_exit(dfd_dev_exit); +module_param(g_dfd_dbg_level, int, S_IRUGO | S_IWUSR); +EXPORT_SYMBOL(dfd_plat_driver_get); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c new file mode 100644 index 000000000000..55e2e4339ae7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c @@ -0,0 +1,70 @@ +#include +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_adapter.h" +#include "./include/dfd_cfg_info.h" +#include "../dev_sysfs/include/sysfs_common.h" + +#define PSU_SIZE (256) + +typedef enum dfd_psu_status_e { + DFD_PSU_PRESENT_STATUS = 0, + DFD_PSU_OUTPUT_STATUS = 1, + DFD_PSU_ALERT_STATUS = 2, +} dfd_psu_status_t; + +int g_dfd_psu_dbg_level = 0; +module_param(g_dfd_psu_dbg_level, int, S_IRUGO | S_IWUSR); + +int dfd_get_psu_present_status(unsigned int psu_index) +{ + int ret, present_key, present_status; + + present_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_PRESENT_STATUS); + ret = dfd_info_get_int(present_key, &present_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "dfd_get_psu_present_status error. psu_index:%d, ret:%d\n", + psu_index, ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "dfd_get_psu_present_status success. psu_index:%d, status:%d\n", + psu_index, present_status); + return present_status; +} + +int dfd_get_psu_output_status(unsigned int psu_index) +{ + int ret, output_key, output_status; + + output_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_OUTPUT_STATUS); + ret = dfd_info_get_int(output_key, &output_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "dfd_get_psu_output_status error. psu_index:%d, ret:%d\n", + psu_index, ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "dfd_get_psu_output_status success. psu_index:%d, status:%d\n", + psu_index, output_status); + return output_status; +} + +int dfd_get_psu_alert_status(unsigned int psu_index) +{ + int ret, alert_key, alert_status; + + alert_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_ALERT_STATUS); + ret = dfd_info_get_int(alert_key, &alert_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "dfd_get_psu_alert_status error. psu_index:%d, ret:%d\n", + psu_index, ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "dfd_get_psu_alert_status success. psu_index:%d, status:%d\n", + psu_index, alert_status); + return alert_status; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c new file mode 100644 index 000000000000..bfca20290efb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c @@ -0,0 +1,149 @@ +#include +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_adapter.h" +#include "./include/dfd_cfg_info.h" +#include "./include/dfd_cfg_file.h" +#include "../dev_sysfs/include/sysfs_common.h" + +#define DFD_GET_TEMP_SENSOR_KEY1(dev_index, temp_index) \ + (((dev_index & 0xff) << 8) | (temp_index & 0xff)) +#define DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, temp_type) \ + (((main_dev_id & 0x0f) << 4) | (temp_type & 0x0f)) +#define DFD_FORMAT_STR_MAX_LEN (32) + +int g_dfd_sensor_dbg_level = 0; +module_param(g_dfd_sensor_dbg_level, int, S_IRUGO | S_IWUSR); + +static int dfd_deal_hwmon_buf(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, info_ctrl_t *info_ctrl) +{ + int i, tmp_len; + int exp, decimal, divisor; + int org_value, tmp_value; + int div_result, div_mod; + char fmt_str[DFD_FORMAT_STR_MAX_LEN]; + + exp = info_ctrl->int_cons; + decimal = info_ctrl->bit_offset; + + if (exp <= 0) { + DBG_DEBUG(DBG_VERBOSE, "exponent %d, don't need transform. buf_len:%d, buf_len_new:%d\n", + exp, buf_len, *buf_len_new); + snprintf(buf_new, *buf_len_new, "%s", buf); + *buf_len_new = strlen(buf_new); + return DFD_RV_OK; + } + divisor = 1; + for (i = 0; i < exp; i++) { + divisor *= 10; + } + org_value = simple_strtol(buf, NULL, 10); + if (org_value < 0) { + tmp_value = 0 - org_value; + } else { + tmp_value = org_value; + } + div_result = tmp_value / divisor; + div_mod = tmp_value % divisor; + DBG_DEBUG(DBG_VERBOSE, "exp:%d, decimal:%d, original value:%d, divisor:%d, result :%d, mod:%d\n", + exp, decimal, org_value, divisor, div_result, div_mod); + + mem_clear(fmt_str, sizeof(fmt_str)); + if (org_value < 0) { + snprintf(fmt_str, sizeof(fmt_str), "-%%d.%%0%dd\n",exp); + } else { + snprintf(fmt_str, sizeof(fmt_str), "%%d.%%0%dd\n",exp); + } + DBG_DEBUG(DBG_VERBOSE, "format string:%s",fmt_str); + snprintf(buf_new, *buf_len_new, fmt_str, div_result, div_mod); + *buf_len_new = strlen(buf_new); + tmp_len = *buf_len_new; + + if ( decimal > 0) { + for(i = 0; i < *buf_len_new; i++) { + if (buf_new[i] == '.') { + if( i + decimal + 2 <= *buf_len_new ) { + buf_new[i + decimal + 1 ] = '\n'; + buf_new[i + decimal + 2 ] = '\0'; + *buf_len_new = strlen(buf_new); + DBG_DEBUG(DBG_VERBOSE, "deal decimal[%d] ok, str len:%d, value:%s\n", + decimal, *buf_len_new, buf_new); + } + break; + } + } + if (tmp_len == *buf_len_new) { + DBG_DEBUG(DBG_WARN, "deal decimal[%d] failed, use original value:%s\n", decimal, buf_new); + } + } + return DFD_RV_OK; +} + +static int dfd_get_sensor_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t sensor_type, + uint8_t sensor_index, uint8_t sensor_attr, char *buf) +{ + uint32_t key; + uint16_t key_index1; + uint8_t key_index2; + int rv; + info_hwmon_buf_f pfunc; + + key_index1 = DFD_GET_TEMP_SENSOR_KEY1(dev_index, sensor_index); + key_index2 = DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, sensor_attr); + if (sensor_type == WB_MINOR_DEV_TEMP ) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_TEMP, key_index1, key_index2); + } else if (sensor_type == WB_MINOR_DEV_IN) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_IN, key_index1, key_index2); + } else { + DFD_SENSOR_DEBUG(DBG_ERROR, "unknow sensor type:%d.\n",sensor_type); + return -DFD_RV_INVALID_VALUE; + } + + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get sensor info.main_dev_id:%d, dev_index:0x%x, sensor_index:0x%x, sensor_attr:0x%x, key:0x%x,\n", + main_dev_id, dev_index, sensor_index, sensor_attr, key); + + pfunc = dfd_deal_hwmon_buf; + mem_clear(buf, PAGE_SIZE); + rv = dfd_info_get_sensor(key, buf, PAGE_SIZE, pfunc); + return rv; +} + +ssize_t dfd_get_temp_info(uint8_t main_dev_id, uint8_t dev_index, + uint8_t temp_index, uint8_t temp_attr, char *buf) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error. buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_TEMP, temp_index, temp_attr, buf); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get temp info error. rv:%d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get temp info ok.value:%s\n", buf); + } + return rv; +} + +ssize_t dfd_get_voltage_info(uint8_t main_dev_id, uint8_t dev_index, + uint8_t in_index, uint8_t in_attr, char *buf) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error. buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_IN, in_index, in_attr, buf); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get voltage info error. rv:%d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get voltage info ok.value:%s\n", buf); + } + return rv; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c new file mode 100644 index 000000000000..5c1faff975b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c @@ -0,0 +1,56 @@ +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_info.h" +#include "./include/dfd_cfg_adapter.h" +#include "../dev_sysfs/include/sysfs_common.h" + +int g_dfd_sff_dbg_level = 0; +module_param(g_dfd_sff_dbg_level, int, S_IRUGO | S_IWUSR); + +ssize_t dfd_get_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, char *buf, int len) +{ + int key, ret, value; + + if(buf == NULL) { + DFD_SFF_DEBUG(DBG_ERROR, "param error, buf is NULL. sff_index:%d, cpld_reg_type:%d.\n", + sff_index, cpld_reg_type); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_CPLD_REG, sff_index, cpld_reg_type); + ret = dfd_info_get_int(key, &value, NULL); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "get sff cpld reg error, key:0x%x,ret:%d.\n", key, ret); + return ret; + } + + mem_clear(buf, len); + return (ssize_t)snprintf(buf, len, "%d\n", value); +} + +ssize_t dfd_get_sff_dir_name(unsigned int sff_index, char *buf, int buf_len) +{ + int key; + char *sff_dir_name; + + if (buf == NULL) { + DFD_SFF_DEBUG(DBG_ERROR, "param error. buf is NULL.sff index:%d", sff_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, buf_len); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_DIR_NAME, sff_index, 0); + sff_dir_name = dfd_ko_cfg_get_item(key); + if (sff_dir_name == NULL) { + DFD_SFF_DEBUG(DBG_ERROR, "sff dir name config error, key=0x%08x\n", key); + return -DFD_RV_NODE_FAIL; + } + + DFD_SFF_DEBUG(DBG_VERBOSE, "%s\n", sff_dir_name); + snprintf(buf, buf_len, "%s", sff_dir_name); + return strlen(buf); + +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c new file mode 100644 index 000000000000..69c82adabef0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c @@ -0,0 +1,27 @@ +#include +#include + +#include "./include/dfd_module.h" +#include "./include/dfd_cfg.h" +#include "./include/dfd_cfg_adapter.h" +#include "./include/dfd_cfg_info.h" +#include "../dev_sysfs/include/sysfs_common.h" + +#define SLOT_SIZE (256) + +int g_dfd_slot_dbg_level = 0; +module_param(g_dfd_slot_dbg_level, int, S_IRUGO | S_IWUSR); + +int dfd_get_slot_present_status(unsigned int slot_index) +{ + int key, ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_PRESENT_STATUS, WB_MAIN_DEV_SLOT, slot_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "get slot status error, key:0x%x\n",key); + return ret; + } + return status; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h new file mode 100644 index 000000000000..062654d01504 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h @@ -0,0 +1,97 @@ +#ifndef __DFD_CFG_H__ +#define __DFD_CFG_H__ + +#include + +#define DFD_KO_CFG_FILE_NAME "/etc/plat_sysfs_cfg/cfg_file_name" +#define DFD_KO_CFG_FILE_DIR "/etc/plat_sysfs_cfg/" +#define DFD_PUB_CARDTYPE_FILE "/sys/module/platform_common/parameters/dfd_my_type" + +#define DFD_CFG_CMDLINE_MAX_LEN (256) +#define DFD_CFG_NAME_MAX_LEN (256) +#define DFD_CFG_VALUE_MAX_LEN (256) +#define DFD_CFG_STR_MAX_LEN (64) +#define DFD_CFG_CPLD_NUM_MAX (16) +#define DFD_PRODUCT_ID_LENGTH (8) +#define DFD_PID_BUF_LEN (32) +#define DFD_TEMP_NAME_BUF_LEN (32) + +#define DFD_CFG_EMPTY_VALUE (-1) +#define DFD_CFG_INVALID_VALUE (0) + +#define DFD_CFG_KEY(item, index1, index2) \ + ((((item) & 0xff) << 24) | (((index1) & 0xffff) << 8) | ((index2) & 0xff)) +#define DFD_CFG_ITEM_ID(key) (((key) >> 24) & 0xff) +#define DFD_CFG_INDEX1(key) (((key) >> 8) & 0xffff) +#define DFD_CFG_INDEX2(key) ((key)& 0xff) + +#define INDEX_NOT_EXIST (-1) +#define INDEX1_MAX (0xffff) +#define INDEX2_MAX (0xff) + +#define DFD_CFG_ITEM_ALL \ + DFD_CFG_ITEM(DFD_CFG_ITEM_NONE, "none", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DEV_NUM, "dev_num", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_LPC_DEV, "cpld_lpc_dev", INDEX1_MAX, DFD_CFG_CPLD_NUM_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_INT_END, "end_int", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_MODE, "mode_cpld", INDEX1_MAX, DFD_CFG_CPLD_NUM_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SFF_DIR_NAME, "sff_dir_name", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_STRING_END, "end_string", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_I2C_DEV, "cpld_i2c_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_OTHER_I2C_DEV, "other_i2c_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_I2C_DEV_END, "end_i2c_dev", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_ROLL_STATUS, "fan_roll_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_SPEED, "fan_speed", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_RATIO, "fan_ratio", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DEV_PRESENT_STATUS, "dev_present_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_STATUS, "psu_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_TEMP, "hwmon_temp", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_IN, "hwmon_in", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SFF_CPLD_REG, "sff_cpld_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_INFO_CTRL_END, "end_info_ctrl", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) _id, +typedef enum dfd_cfg_item_id_s { + DFD_CFG_ITEM_ALL +} dfd_cfg_item_id_t; + +#define DFD_CFG_ITEM_IS_INT(item_id) \ + (((item_id) > DFD_CFG_ITEM_NONE) && ((item_id) < DFD_CFG_ITEM_INT_END)) + +#define DFD_CFG_ITEM_IS_STRING(item_id) \ + (((item_id) > DFD_CFG_ITEM_INT_END) && ((item_id) < DFD_CFG_ITEM_STRING_END)) + +#define DFD_CFG_ITEM_IS_I2C_DEV(item_id) \ + (((item_id) > DFD_CFG_ITEM_STRING_END) && ((item_id) < DFD_CFG_ITEM_I2C_DEV_END)) + +#define DFD_CFG_ITEM_IS_INFO_CTRL(item_id) \ + (((item_id) > DFD_CFG_ITEM_I2C_DEV_END) && ((item_id) < DFD_CFG_ITEM_INFO_CTRL_END)) + +typedef struct index_range_s { + int index1_max; + int index2_max; +} index_range_t; + +typedef struct val_convert_node_s { + struct list_head lst; + int int_val; + char str_val[DFD_CFG_STR_MAX_LEN]; + int index1; + int index2; +} val_convert_node_t; + +void *dfd_ko_cfg_get_item(int key); + +void dfd_ko_cfg_show_item(int key); + +int32_t dfd_dev_cfg_init(void); + +void dfd_dev_cfg_exit(void); + +#endif /* __DFD_CFG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h new file mode 100644 index 000000000000..70d8b536c437 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h @@ -0,0 +1,46 @@ +#ifndef __DFD_CFG_ADAPTER_H__ +#define __DFD_CFG_ADAPTER_H__ + +#define DFD_KO_CPLD_I2C_RETRY_SLEEP (10) /* ms */ +#define DFD_KO_CPLD_I2C_RETRY_TIMES (50 / DFD_KO_CPLD_I2C_RETRY_SLEEP) + +#define DFD_KO_CPLD_GET_SLOT(addr) ((addr >> 24) & 0xff) +#define DFD_KO_CPLD_GET_ID(addr) ((addr >> 16) & 0xff) +#define DFD_KO_CPLD_GET_INDEX(addr) (addr & 0xffff) +#define DFD_KO_CPLD_MODE_I2C_STRING "i2c" +#define DFD_KO_CPLD_MODE_LPC_STRING "lpc" + +typedef struct dfd_i2c_dev_s { + int bus; + int addr; +} dfd_i2c_dev_t; + +typedef enum dfd_i2c_dev_mem_s { + DFD_I2C_DEV_MEM_BUS, + DFD_I2C_DEV_MEM_ADDR, + DFD_I2C_DEV_MEM_END +} dfd_i2c_dev_mem_t; + +typedef enum cpld_mode_e { + DFD_CPLD_MODE_I2C, + DFD_CPLD_MODE_LPC, +} cpld_mode_t; + +typedef enum i2c_mode_e { + DFD_I2C_MODE_NORMAL_I2C, + DFD_I2C_MODE_SMBUS, +} i2c_mode_t; + +extern char *g_dfd_i2c_dev_mem_str[DFD_I2C_DEV_MEM_END]; + +int32_t dfd_ko_cpld_read(int32_t addr, uint8_t *buf); + +int32_t dfd_ko_cpld_write(int32_t addr, uint8_t val); + +int32_t dfd_ko_i2c_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size); + +int32_t dfd_ko_i2c_write(int bus, int addr, int offset, uint8_t *buf, uint32_t size); + +int32_t dfd_ko_read_file(char *fpath, int32_t addr, uint8_t *val, int32_t read_bytes); + +#endif /* __DFD_CFG_ADAPTER_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h new file mode 100644 index 000000000000..50d7a42d5564 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h @@ -0,0 +1,37 @@ +#ifndef __DFD_CFG_FILE_H__ +#define __DFD_CFG_FILE_H__ + +#include + +#define KFILE_RV_OK (0) +#define KFILE_RV_INPUT_ERR (-1) +#define KFILE_RV_STAT_FAIL (-2) +#define KFILE_RV_OPEN_FAIL (-3) +#define KFILE_RV_MALLOC_FAIL (-4) +#define KFILE_RV_RD_FAIL (-5) +#define KFILE_RV_ADDR_ERR (-6) +#define KFILE_RV_WR_FAIL (-7) + +#define IS_CR(c) ((c) == '\n') + +typedef struct kfile_ctrl_s { + int32_t size; + int32_t pos; + char *buf; +} kfile_ctrl_t; + +int kfile_open(char *fname, kfile_ctrl_t *kfile_ctrl); + +void kfile_close(kfile_ctrl_t *kfile_ctrl); + +int kfile_gets(char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl); + +int kfile_read(int32_t addr, char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl); + +int kfile_iterate_dir(const char *dir_path, const char *obj_name, char *match_name, int len); + +#if 0 + +int kfile_write(char *fpath, int32_t addr, char *buf, int buf_size); +#endif +#endif /* __DFD_CFG_FILE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h new file mode 100644 index 000000000000..dc1ed17651b9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h @@ -0,0 +1,109 @@ +#ifndef __DFD_CFG_INFO_H__ +#define __DFD_CFG_INFO_H__ + +#include + +typedef int (*info_num_buf_to_value_f)(uint8_t *num_buf, int buf_len, int *num_val); + +typedef int (*info_buf_to_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new); + +#define IS_INFO_FRMT_BIT(frmt) ((frmt) == INFO_FRMT_BIT) +#define IS_INFO_FRMT_BYTE(frmt) (((frmt) == INFO_FRMT_BYTE) || ((frmt) == INFO_FRMT_NUM_BYTES)) +#define IS_INFO_FRMT_NUM_STR(frmt) ((frmt) == INFO_FRMT_NUM_STR) +#define IS_INFO_FRMT_NUM_BUF(frmt) ((frmt) == INFO_FRMT_NUM_BUF) +#define IS_INFO_FRMT_BUF(frmt) ((frmt) == INFO_FRMT_BUF) + +#define INFO_INT_MAX_LEN (32) +#define INFO_INT_LEN_VALAID(len) (((len) > 0) && ((len) < INFO_INT_MAX_LEN)) + +#define INFO_BUF_MAX_LEN (128) +#define INFO_BUF_LEN_VALAID(len) (((len) > 0) && ((len) < INFO_BUF_MAX_LEN)) + +#define INFO_BIT_OFFSET_VALID(bit_offset) (((bit_offset) >= 0) && ((bit_offset) < 8)) + +typedef enum info_ctrl_mode_e { + INFO_CTRL_MODE_NONE, + INFO_CTRL_MODE_CFG, + INFO_CTRL_MODE_CONS, + INFO_CTRL_MODE_TLV, + INFO_CTRL_MODE_SRT_CONS, + INFO_CTRL_MODE_END +} info_ctrl_mode_t; + +typedef enum info_frmt_e { + INFO_FRMT_NONE, + INFO_FRMT_BIT, + INFO_FRMT_BYTE, + INFO_FRMT_NUM_BYTES, + INFO_FRMT_NUM_STR, + INFO_FRMT_NUM_BUF, + INFO_FRMT_BUF, + INFO_FRMT_END +} info_frmt_t; + +typedef enum info_src_e { + INFO_SRC_NONE, + INFO_SRC_CPLD, + INFO_SRC_FPGA, + INFO_SRC_OTHER_I2C, + INFO_SRC_FILE, + INFO_SRC_END +} info_src_t; + +typedef enum info_pola_e { + INFO_POLA_NONE, + INFO_POLA_POSI, + INFO_POLA_NEGA, + INFO_POLA_END +} info_pola_t; + +#define INFO_FPATH_MAX_LEN (128) +#define INFO_STR_CONS_MAX_LEN (64) +typedef struct info_ctrl_s { + info_ctrl_mode_t mode; + int32_t int_cons; + info_src_t src; + info_frmt_t frmt; + info_pola_t pola; + char fpath[INFO_FPATH_MAX_LEN]; + int32_t addr; + int32_t len; + int32_t bit_offset; + char str_cons[INFO_STR_CONS_MAX_LEN]; + int32_t int_extra1; + int32_t int_extra2; +} info_ctrl_t; + +typedef enum info_ctrl_mem_s { + INFO_CTRL_MEM_MODE, + INFO_CTRL_MEM_INT_CONS, + INFO_CTRL_MEM_SRC, + INFO_CTRL_MEM_FRMT, + INFO_CTRL_MEM_POLA, + INFO_CTRL_MEM_FPATH, + INFO_CTRL_MEM_ADDR, + INFO_CTRL_MEM_LEN, + INFO_CTRL_MEM_BIT_OFFSET, + INFO_CTRL_MEM_STR_CONS, + INFO_CTRL_MEM_INT_EXTRA1, + INFO_CTRL_MEM_INT_EXTRA2, + INFO_CTRL_MEM_END +} info_ctrl_mem_t; + +typedef int (*info_hwmon_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, info_ctrl_t *info_ctrl); + +extern char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END]; +extern char *g_info_src_str[INFO_SRC_END]; +extern char *g_info_frmt_str[INFO_FRMT_END]; +extern char *g_info_pola_str[INFO_POLA_END]; +extern char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END]; + +int dfd_info_get_int(int key, int *ret, info_num_buf_to_value_f pfun); + +int dfd_info_get_buf(int key, uint8_t *buf, int buf_len, info_buf_to_buf_f pfun); + +int dfd_info_set_int(int key, int val); + +int dfd_info_get_sensor(uint32_t key, char *buf, int buf_len, info_hwmon_buf_f pfun); + +#endif /* __DFD_CFG_INFO_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h new file mode 100644 index 000000000000..955dfa96e42e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h @@ -0,0 +1,30 @@ +#ifndef __DFD_CFG_LISTNODE_H__ +#define __DFD_CFG_LISTNODE_H__ + +#include + +#define LNODE_RV_OK (0) +#define LNODE_RV_INPUT_ERR (-1) +#define LNODE_RV_NODE_EXIST (-2) +#define LNODE_RV_NOMEM (-3) + +typedef struct lnode_root_s { + struct list_head root; +} lnode_root_t; + +typedef struct lnode_node_s { + struct list_head lst; + + int key; + void *data; +} lnode_node_t; + +void *lnode_find_node(lnode_root_t *root, int key); + +int lnode_insert_node(lnode_root_t *root, int key, void *data); + +int lnode_init_root(lnode_root_t *root); + +void lnode_free_list(lnode_root_t *root); + +#endif /* __DFD_CFG_LISTNODE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h new file mode 100644 index 000000000000..1065fd9eed3f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h @@ -0,0 +1,18 @@ +#ifndef _DFD_FAN_DRIVER_H_ +#define _DFD_FAN_DRIVER_H_ + +ssize_t dfd_get_fan_speed(unsigned int fan_index, unsigned int motor_index,unsigned int *speed); + +int dfd_set_fan_pwm(unsigned int fan_index, unsigned int motor_index, int pwm); + +int dfd_get_fan_pwm(unsigned int fan_index, unsigned int motor_index, int *pwm); + +int dfd_get_fan_present_status(unsigned int fan_index); + +int dfd_get_fan_roll_status(unsigned int fan_index, unsigned int motor_index); + +int dfd_get_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int *level); + +int dfd_set_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int level); + +#endif /* _DFD_FAN_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h new file mode 100644 index 000000000000..a547255cf3ab --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h @@ -0,0 +1,96 @@ +#ifndef __DFD_MODULE_H__ +#define __DFD_MODULE_H__ + +typedef enum dfd_rv_s { + DFD_RV_OK = 0, + DFD_RV_INIT_ERR = 1, + DFD_RV_SLOT_INVALID = 2, + DFD_RV_MODE_INVALID = 3, + DFD_RV_MODE_NOTSUPPORT = 4, + DFD_RV_TYPE_ERR = 5, + DFD_RV_DEV_NOTSUPPORT = 6, + DFD_RV_DEV_FAIL = 7, + DFD_RV_INDEX_INVALID = 8, + DFD_RV_NO_INTF = 9, + DFD_RV_NO_NODE = 10, + DFD_RV_NODE_FAIL = 11, + DFD_RV_INVALID_VALUE = 12, + DFD_RV_NO_MEMORY = 13, +} dfd_rv_t; + +typedef enum { + DBG_VERBOSE = 0x01, + DBG_WARN = 0x02, + DBG_ERROR = 0x04, +} dbg_level_t; + +extern int g_dfd_dbg_level; +extern int g_dfd_fan_dbg_level; +extern int g_dfd_slot_dbg_level; +extern int g_dfd_sensor_dbg_level; +extern int g_dfd_psu_dbg_level; +extern int g_dfd_sff_dbg_level; + +#define DBG_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_FAN_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_fan_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SLOT_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_slot_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SENSOR_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sensor_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_PSU_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_psu_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SFF_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sff_dbg_level & level) { \ + if(level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +int dfd_get_dev_number(unsigned int main_dev_id, unsigned int minor_dev_id); + +#endif /* __DFD_MODULE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h new file mode 100644 index 000000000000..ce7199660557 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h @@ -0,0 +1,10 @@ +#ifndef _DFD_PSU_DRIVER_H_ +#define _DFD_PSU_DRIVER_H_ + +int dfd_get_psu_present_status(unsigned int psu_index); + +int dfd_get_psu_output_status(unsigned int psu_index); + +int dfd_get_psu_alert_status(unsigned int psu_index); + +#endif /* _DFD_PSU_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h new file mode 100644 index 000000000000..16733b26029f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h @@ -0,0 +1,10 @@ +#ifndef _DFD_SENSORS_DRIVER_H_ +#define _DFD_SENSORS_DRIVER_H_ + +ssize_t dfd_get_temp_info(uint8_t main_dev_id, uint8_t dev_index, + uint8_t temp_index, uint8_t temp_attr, char *buf); + +ssize_t dfd_get_voltage_info(uint8_t main_dev_id, uint8_t dev_index, + uint8_t in_index, uint8_t in_attr, char *buf); + +#endif /* _DFD_SENSORS_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h new file mode 100644 index 000000000000..7107b72ee4b2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h @@ -0,0 +1,8 @@ +#ifndef _DFD_SFF_DRIVER_H_ +#define _DFD_SFF_DRIVER_H_ + +ssize_t dfd_get_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, char *buf, int len); + +ssize_t dfd_get_sff_dir_name(unsigned int sff_index, char *buf, int buf_len); + +#endif /* _DFD_SFF_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h new file mode 100644 index 000000000000..c68caecd2e66 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h @@ -0,0 +1,6 @@ +#ifndef _DFD_SLOT_DRIVER_H_ +#define _DFD_SLOT_DRIVER_H_ + +int dfd_get_slot_present_status(unsigned int slot_index); + +#endif /* _DFD_SLOT_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/Makefile b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/Makefile new file mode 100644 index 000000000000..1a1044bb1fe8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/Makefile @@ -0,0 +1,21 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +KBUILD_EXTRA_SYMBOLS += $(PLAT_SYSFS_DIR)/dev_cfg/Module.symvers + +obj-m := plat_switch.o +obj-m += plat_fan.o +obj-m += plat_psu.o +obj-m += plat_sff.o +obj-m += plat_sensor.o +obj-m += plat_slot.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/*.mod + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h new file mode 100644 index 000000000000..bbd813e87114 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h @@ -0,0 +1,86 @@ +#ifndef _PLAT_SWITCH_H_ +#define _PLAT_SWITCH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +enum LOG_LEVEL{ + INFO = 0x1, + ERR = 0x2, + DBG = 0x4, + ALL = 0xf +}; + +#define LOG_INFO(_prefix, fmt, args...) \ + do { \ + if (g_loglevel & INFO) \ + { \ + printk( KERN_INFO _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ + } while (0) + +#define LOG_ERR(_prefix, fmt, args...) \ + do { \ + if (g_loglevel & ERR) \ + { \ + printk( KERN_ERR _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ + } while (0) + +#define LOG_DBG(_prefix, fmt, args...) \ + do { \ + if (g_loglevel & DBG) \ + { \ + printk( KERN_DEBUG _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ + } while (0) + +#define check_pfun(p) \ + do { \ + if (p == NULL) { \ + printk( KERN_ERR "%s, %s = NULL.\n", __FUNCTION__, #p); \ + return -ENOSYS; \ + } \ + }while(0) + +#define check_p(p) check_pfun(p) + +#define to_switch_obj(x) container_of(x, struct switch_obj, kobj) +#define to_switch_attr(x) container_of(x, struct switch_attribute, attr) +#define to_switch_device_attr(x) container_of(x, struct switch_device_attribute, switch_attr) + +#define SWITCH_ATTR(_name, _mode, _show, _store, _type) \ + { .switch_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type } + +#define SWITCH_DEVICE_ATTR(_name, _mode, _show, _store, _type) \ +struct switch_device_attribute switch_dev_attr_##_name \ + = SWITCH_ATTR(_name, _mode, _show, _store, _type) + +struct switch_obj { + struct kobject kobj; + unsigned int index; +}; + +/* a custom attribute that works just for a struct switch_obj. */ +struct switch_attribute { + struct attribute attr; + ssize_t (*show)(struct switch_obj *foo, struct switch_attribute *attr, char *buf); + ssize_t (*store)(struct switch_obj *foo, struct switch_attribute *attr, const char *buf, size_t count); +}; + +struct switch_device_attribute { + struct switch_attribute switch_attr; + int type; +}; + +extern struct switch_obj *wb_plat_kobject_create(const char *name, struct kobject *parent); +extern void wb_plat_kobject_delete(struct switch_obj **obj); + +#endif /* _PLAT_SWITCH_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h new file mode 100644 index 000000000000..5b73731e1fbf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h @@ -0,0 +1,90 @@ +#ifndef _SYSFS_COMMON_H_ +#define _SYSFS_COMMON_H_ + +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define DIR_NAME_MAX_LEN (64) + +#define WB_SYSFS_DEV_ERROR "NA" +/* sysfs directory name */ +#define FAN_SYSFS_NAME "fan" +#define PSU_SYSFS_NAME "psu" +#define SLOT_SYSFS_NAME "slot" +#define VOLTAGE_SYSFS_NAME "in" +#define TEMP_SYSFS_NAME "temp" +#define SFF_SYSFS_NAME "sff" + +typedef enum wb_main_dev_type_e { + WB_MAIN_DEV_MAINBOARD = 0, + WB_MAIN_DEV_FAN = 1, + WB_MAIN_DEV_PSU = 2, + WB_MAIN_DEV_SFF = 3, + WB_MAIN_DEV_CPLD = 4, + WB_MAIN_DEV_SLOT = 5, +} wb_main_dev_type_t; + +typedef enum wb_minor_dev_type_e { + WB_MINOR_DEV_NONE = 0, /* None */ + WB_MINOR_DEV_TEMP = 1, + WB_MINOR_DEV_IN = 2, + WB_MINOR_DEV_CURR = 3, + WB_MINOR_DEV_POWER = 4, + WB_MINOR_DEV_MOTOR = 5, + WB_MINOR_DEV_PSU = 6, +} wb_minor_dev_type_t; + +typedef enum wb_sensor_type_e { + WB_SENSOR_INPUT = 0, + WB_SENSOR_ALIAS = 1, + WB_SENSOR_TYPE = 2, + WB_SENSOR_MAX = 3, + WB_SENSOR_MAX_HYST = 4, + WB_SENSOR_MIN = 5, + WB_SENSOR_CRIT = 6, +} wb_sensor_type_t; + +typedef enum wb_sff_cpld_attr_e { + WB_SFF_POWER_ON = 0x01, + WB_SFF_TX_FAULT, + WB_SFF_TX_DIS, + WB_SFF_PRE_N, + WB_SFF_RX_LOS, + WB_SFF_RESET, + WB_SFF_LPMODE, + WB_SFF_MODULE_PRESENT, + WB_SFF_INTERRUPT, +} wb_sff_cpld_attr_t; + +struct switch_drivers_t{ + /* device */ + int (*get_dev_number) (unsigned int main_dev_id, unsigned int minor_dev_id); + /* fan */ + int (*get_fan_number) (void); + ssize_t (*get_fan_speed) (unsigned int fan_index, unsigned int motor_index, unsigned int *speed); + int (*get_fan_pwm) (unsigned int fan_index, unsigned int motor_index, int *pwm); + int (*set_fan_pwm) (unsigned int fan_index, unsigned int motor_index, int pwm); + int (*get_fan_present_status)(unsigned int fan_index); + int (*get_fan_roll_status)(unsigned int fan_index, unsigned int motor_index); + int (*get_fan_speed_level)(unsigned int fan_index, unsigned int motor_index, int *level); + int (*set_fan_speed_level)(unsigned int fan_index, unsigned int motor_index, int level); + /* slot */ + int (*get_slot_present_status) (unsigned int slot_index); + /* sensors */ + ssize_t (*get_temp_info)( uint8_t main_dev_id, uint8_t dev_index, + uint8_t temp_index, uint8_t temp_attr, char *buf); + ssize_t (*get_voltage_info)( uint8_t main_dev_id, uint8_t dev_index, + uint8_t in_index, uint8_t in_attr, char *buf); + /* psu */ + int (*get_psu_present_status)(unsigned int psu_index); + int (*get_psu_output_status)(unsigned int psu_index); + int (*get_psu_alert_status)(unsigned int psu_index); + /* sff */ + ssize_t (*get_sff_cpld_info)( unsigned int sff_index, int cpld_reg_type, char *buf, int len); + ssize_t (*get_sff_dir_name)(unsigned int sff_index, char *buf, int buf_len); +}; + +extern struct switch_drivers_t * dfd_plat_driver_get(void); + +#endif /*_SYSFS_COMMON_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_fan.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_fan.c new file mode 100644 index 000000000000..d841f2547b6f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_fan.c @@ -0,0 +1,505 @@ +/* + * plat_fan.c + * Original Author: support 2020-02-17 + * + * This module create fan kobjects and attributes in /sys/wb_plat/fan + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define FAN_INFO(fmt, args...) LOG_INFO("fan: ", fmt, ##args) +#define FAN_ERR(fmt, args...) LOG_ERR("fan: ", fmt, ##args) +#define FAN_DBG(fmt, args...) LOG_DBG("fan: ", fmt, ##args) + +struct motor_obj_t{ + struct switch_obj *obj; +}; + +struct fan_obj_t{ + unsigned int motor_number; + struct motor_obj_t *motor; + struct switch_obj *obj; +}; + +struct fan_t{ + unsigned int fan_number; + struct fan_obj_t *fan; +}; + +static int g_loglevel = 0; +static struct fan_t g_fan; +static struct switch_obj *g_fan_obj = NULL; +static struct switch_drivers_t *g_drv = NULL; + +static ssize_t fan_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_fan.fan_number); +} + +static ssize_t fan_motor_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int index; + + index = obj->index; + FAN_DBG("fan_motor_number_show,fan index:%d\n",index); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_fan.fan[index-1].motor_number); +} + +static ssize_t fan_roll_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + int ret; + + check_p(g_drv); + check_p(g_drv->get_fan_roll_status); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + fan_index = p_obj->index; + motor_index = obj->index; + + ret = g_drv->get_fan_roll_status(fan_index, motor_index); + if (ret < 0 ) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t fan_present_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + int ret; + + fan_index = obj->index; + FAN_DBG("fan_present_status_show, fan index:%d\n",fan_index); + check_p(g_drv); + check_p(g_drv->get_fan_present_status); + + ret = g_drv->get_fan_present_status(fan_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t fan_speed_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index, motor_index, speed; + int ret; + struct switch_obj *p_obj; + + check_p(g_drv); + check_p(g_drv->get_fan_speed); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + fan_index = p_obj->index; + motor_index = obj->index; + + ret = g_drv->get_fan_speed(fan_index, motor_index, &speed); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", speed); +} + +static ssize_t fan_motor_ratio_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + int ret, pwm; + + check_p(g_drv); + check_p(g_drv->get_fan_pwm); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + fan_index = p_obj->index; + motor_index = obj->index; + ret = g_drv->get_fan_pwm(fan_index, motor_index, &pwm); + + if (ret < 0 ) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", pwm); +} + +static ssize_t fan_motor_ratio_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + int ret, pwm; + + check_p(g_drv); + check_p(g_drv->set_fan_pwm); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + fan_index = p_obj->index; + motor_index = obj->index; + sscanf(buf, "%d", &pwm); + + if (pwm < 0 || pwm > 100) { + FAN_ERR("can not set pwm = %d.\n", pwm); + return -EINVAL; + } + ret = g_drv->set_fan_pwm(fan_index, motor_index, pwm); + if (ret < 0) { + FAN_ERR("can not set pwm = %d.\n", pwm); + return -EIO; + } + return count; +} + +/************************************fan dir and attrs*******************************************/ +static struct switch_attribute fan_number_att = __ATTR(num_fans, S_IRUGO, fan_number_show, NULL); + +static struct attribute *fan_dir_attrs[] = { + &fan_number_att.attr, + NULL, +}; + +static struct attribute_group fan_root_attr_group = { + .attrs = fan_dir_attrs, +}; + +/*******************************fan1 fan2 dir and attrs*******************************************/ +static struct switch_attribute fan_num_motors_att = __ATTR(num_motors, S_IRUGO, fan_motor_number_show, NULL); +static struct switch_attribute fan_present_att = __ATTR(present, S_IRUGO, fan_present_status_show, NULL); + +static struct attribute *fan_attrs[] = { + &fan_num_motors_att.attr, + &fan_present_att.attr, + NULL, +}; + +static struct attribute_group fan_attr_group = { + .attrs = fan_attrs, +}; + +/*******************************motor0 motor1 dir and attrs*******************************************/ +static struct switch_attribute motor_speed_att = __ATTR(speed, S_IRUGO, fan_speed_show, NULL); +static struct switch_attribute motor_status_att = __ATTR(status, S_IRUGO, fan_roll_status_show, NULL); +static struct switch_attribute motor_ratio_att = __ATTR(ratio, S_IRUGO | S_IWUSR, fan_motor_ratio_show, fan_motor_ratio_store); + +static struct attribute *motor_attrs[] = { + &motor_speed_att.attr, + &motor_status_att.attr, + &motor_ratio_att.attr, + NULL, +}; + +static struct attribute_group motor_attr_group = { + .attrs = motor_attrs, +}; + +static void fanindex_single_motor_remove_kobj_and_attrs(struct fan_obj_t * curr_fan, unsigned int motor_index) +{ + struct motor_obj_t *curr_motor; /* point to motor0 motor1...*/ + + curr_motor = &curr_fan->motor[motor_index]; + if (curr_motor->obj) { + sysfs_remove_group(&curr_motor->obj->kobj, &motor_attr_group); + wb_plat_kobject_delete(&curr_motor->obj); + FAN_DBG("delete fan:%d motor%d.\n", curr_fan->obj->index, motor_index); + } + return; +} + +static int fanindex_single_motor_create_kobj_and_attrs(struct fan_obj_t * curr_fan, unsigned int motor_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct motor_obj_t *curr_motor; /* point to motor0 motor1...*/ + + FAN_DBG("create fan_index:%d, motor%d ...\n", curr_fan->obj->index, motor_index); + + curr_motor = &curr_fan->motor[motor_index]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "motor%d", motor_index); + curr_motor->obj = wb_plat_kobject_create(name, &curr_fan->obj->kobj); + if (!curr_motor->obj) { + FAN_ERR("create fan_index:%d, motor%d object error!\n", curr_fan->obj->index, motor_index); + return -EBADRQC; + } + curr_motor->obj->index = motor_index; + if (sysfs_create_group(&curr_motor->obj->kobj, &motor_attr_group) != 0) { + FAN_ERR("create fan_index:%d, motor%d attrs error.\n", curr_fan->obj->index, motor_index); + wb_plat_kobject_delete(&curr_motor->obj); + return -EBADRQC; + } + FAN_DBG("create fan_index:%d, motor%d ok.\n", curr_fan->obj->index, motor_index); + return 0; +} + +static int fanindex_motor_create_kobj_and_attrs(struct fan_obj_t * curr_fan, int motor_num) +{ + int motor_index, i; + + curr_fan->motor = kzalloc(sizeof(struct motor_obj_t) * motor_num, GFP_KERNEL); + if (!curr_fan->motor) { + FAN_ERR("kzalloc motor error, fan index = %d, motor number = %d.\n", curr_fan->obj->index, motor_num); + return -ENOMEM; + } + curr_fan->motor_number = motor_num; + for (motor_index = 0; motor_index < motor_num; motor_index++) { + if (fanindex_single_motor_create_kobj_and_attrs(curr_fan, motor_index) != 0) { + goto motor_error; + } + } + return 0; +motor_error: + for(i = motor_index - 1; i >= 0; i--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, i); + } + if(curr_fan->motor) { + kfree(curr_fan->motor); + curr_fan->motor = NULL; + } + return -EBADRQC; +} + +static void fanindex_motor_remove_kobj_and_attrs(struct fan_obj_t *curr_fan, int motor_num) +{ + int motor_index; + + for (motor_index = motor_num - 1; motor_index >= 0; motor_index--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, motor_index); + } + return; +} + +static int fan_motor_create(void) +{ + int fan_num, motor_num; + unsigned int fan_index, i; + struct fan_obj_t *curr_fan; /* point to fan1 fan2...*/ + + check_p(g_drv->get_dev_number); + + motor_num = g_drv->get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_MOTOR); + if (motor_num <= 0) { + FAN_ERR("get fan motor number error, motor_num:%d error.\n", motor_num); + return -ENODEV; + } + + fan_num = g_fan.fan_number; + for (fan_index = 1; fan_index <= fan_num; fan_index++) { + curr_fan = &g_fan.fan[fan_index - 1]; + if (fanindex_motor_create_kobj_and_attrs(curr_fan, motor_num) != 0) { + goto error; + } + } + return 0; +error: + for (i = fan_index - 1; i > 0; i--) { + curr_fan = &g_fan.fan[i - 1]; + motor_num = curr_fan->motor_number; + fanindex_motor_remove_kobj_and_attrs(curr_fan, motor_num); + } + return -EBADRQC; +} + +static void fan_motor_remove(void) +{ + unsigned int fan_index; + struct fan_obj_t *curr_fan; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + curr_fan = &g_fan.fan[fan_index - 1]; + if (curr_fan->motor) { + fanindex_motor_remove_kobj_and_attrs(curr_fan, curr_fan->motor_number); + kfree(curr_fan->motor); + curr_fan->motor = NULL; + curr_fan->motor_number = 0; + } + } + } + return; +} + +static void fan_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct fan_obj_t *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + if (curr_fan->obj) { + sysfs_remove_group(&curr_fan->obj->kobj, &fan_attr_group); + wb_plat_kobject_delete(&curr_fan->obj); + FAN_DBG("delete fan%d.\n", index); + } + return; +} + +static int fan_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct fan_obj_t *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + FAN_DBG("create fan%d ...\n", index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "fan%d", index); + curr_fan->obj = wb_plat_kobject_create(name, parent); + if (!curr_fan->obj) { + FAN_ERR("create fan%d object error!\n", index); + return -EBADRQC; + } + curr_fan->obj->index = index; + if (sysfs_create_group(&curr_fan->obj->kobj, &fan_attr_group) != 0) { + FAN_ERR("create fan%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_fan->obj); + return -EBADRQC; + } + FAN_DBG("create fan%d ok.\n", index); + return 0; +} + +static int fan_sub_create_kobj_and_attrs(struct kobject *parent, int fan_num) +{ + unsigned int fan_index, i; + + g_fan.fan = kzalloc(sizeof(struct fan_obj_t) * fan_num, GFP_KERNEL); + if (!g_fan.fan) { + FAN_ERR("kzalloc fan.fan error, fan number = %d.\n", fan_num); + return -ENOMEM; + } + + for (fan_index = 1; fan_index <= fan_num; fan_index++) { + if(fan_sub_single_create_kobj_and_attrs(parent, fan_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = fan_index - 1; i > 0; i--) { + fan_sub_single_remove_kobj_and_attrs(i); + } + if (g_fan.fan) { + kfree(g_fan.fan); + g_fan.fan = NULL; + } + return -EBADRQC; +} + +static int fan_sub_create(void) +{ + int ret, fan_num; + + check_p(g_drv->get_dev_number); + fan_num = g_drv->get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_NONE); + if (fan_num < 0) { + FAN_ERR("fan number = %d error.\n", fan_num); + return -EINVAL; + } + g_fan.fan_number = fan_num; + ret = fan_sub_create_kobj_and_attrs(&g_fan_obj->kobj, fan_num); + return ret; +} + +static void fan_sub_remove(void) +{ + unsigned int fan_index; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + fan_sub_single_remove_kobj_and_attrs(fan_index); + } + kfree(g_fan.fan); + } + mem_clear(&g_fan, sizeof(struct fan_t)); + return; +} + +static int fan_root_create(void) +{ + g_fan_obj = wb_plat_kobject_create("fan", NULL); + if (!g_fan_obj) { + FAN_ERR("wb_plat_kobject_create fan error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_fan_obj->kobj, &fan_root_attr_group) != 0) { + wb_plat_kobject_delete(&g_fan_obj); + FAN_ERR("create fan dir attrs error!\n"); + return -EBADRQC; + } + FAN_DBG("wb_plat_kobject_create fan directory and attribute success.\n"); + return 0; +} + +static void fan_root_remove(void) +{ + if (g_fan_obj) { + sysfs_remove_group(&g_fan_obj->kobj, &fan_root_attr_group); + wb_plat_kobject_delete(&g_fan_obj); + FAN_DBG("delete fan root success\n"); + } + + return; +} + +static int fan_init(void) +{ + int ret; + + FAN_INFO("fan_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = fan_root_create(); + if (ret < 0) { + goto fan_root_error; + } + + ret = fan_sub_create(); + if (ret < 0) { + goto fan_sub_error; + } + + ret = fan_motor_create(); + if (ret < 0) { + goto fan_motor_error; + } + + FAN_INFO("fan_init ok.\n"); + return 0; +fan_motor_error: + fan_sub_remove(); +fan_sub_error: + fan_root_remove(); +fan_root_error: + return ret; +} + +static void fan_exit(void) +{ + fan_motor_remove(); + fan_sub_remove(); + fan_root_remove(); + FAN_INFO("fan_exit ok.\n"); + return ; +} + +module_init(fan_init); +module_exit(fan_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("fan sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_psu.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_psu.c new file mode 100644 index 000000000000..af3b414314ff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_psu.c @@ -0,0 +1,430 @@ +/* + * plat_psu.c + * Original Author: support 2020-02-17 + * + * This module create psu kobjects and attributes in /sys/wb_plat/psu + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define PSU_INFO(fmt, args...) LOG_INFO("psu: ", fmt, ##args) +#define PSU_ERR(fmt, args...) LOG_ERR("psu: ", fmt, ##args) +#define PSU_DBG(fmt, args...) LOG_DBG("psu: ", fmt, ##args) + +struct temp_obj_t{ + struct switch_obj *obj; +}; + +struct psu_obj_t{ + unsigned int temp_number; + struct temp_obj_t *temp; + struct switch_obj *obj; +}; + +struct psu_t{ + unsigned int psu_number; + struct psu_obj_t *psu; +}; + +static int g_loglevel = 0; +static struct psu_t g_psu; +static struct switch_obj *g_psu_obj = NULL; +static struct switch_drivers_t *g_drv = NULL; + +static ssize_t psu_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_psu.psu_number); +} + +static ssize_t psu_present_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + psu_index = obj->index; + PSU_DBG("psu_present_status_show, psu index:%d\n",psu_index); + check_p(g_drv); + check_p(g_drv->get_psu_present_status); + + ret = g_drv->get_psu_present_status(psu_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t psu_output_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + psu_index = obj->index; + PSU_DBG("psu_output_status_show, psu index:%d\n",psu_index); + check_p(g_drv); + check_p(g_drv->get_psu_output_status); + + ret = g_drv->get_psu_output_status(psu_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t psu_alert_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + psu_index = obj->index; + PSU_DBG("psu_alert_status_show, psu index:%d\n",psu_index); + check_p(g_drv); + check_p(g_drv->get_psu_alert_status); + + ret = g_drv->get_psu_alert_status(psu_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +/************************************psu dir and attrs*******************************************/ +static struct switch_attribute psu_number_att = __ATTR(num_psus, S_IRUGO, psu_number_show, NULL); + +static struct attribute *psu_dir_attrs[] = { + &psu_number_att.attr, + NULL, +}; + +static struct attribute_group psu_root_attr_group = { + .attrs = psu_dir_attrs, +}; + +/*******************************psu1 psu2 dir and attrs*******************************************/ +static struct switch_attribute psu_present_status_att = __ATTR(present, S_IRUGO, psu_present_status_show, NULL); +static struct switch_attribute psu_output_status_att = __ATTR(output, S_IRUGO, psu_output_status_show, NULL); +static struct switch_attribute psu_alert_status_att = __ATTR(alert, S_IRUGO, psu_alert_status_show, NULL); + +static struct attribute *psu_attrs[] = { + &psu_present_status_att.attr, + &psu_output_status_att.attr, + &psu_alert_status_att.attr, + NULL, +}; + +static struct attribute_group psu_attr_group = { + .attrs = psu_attrs, +}; + +/*******************************psu temp0 temp1 dir and attrs*******************************************/ +static struct attribute *psu_temp_attrs[] = { + NULL, +}; + +static struct attribute_group psu_temp_attr_group = { + .attrs = psu_temp_attrs, +}; + +static void psuindex_single_temp_remove_kobj_and_attrs(struct psu_obj_t * curr_psu, unsigned int temp_index) +{ + + struct temp_obj_t *curr_temp; /* point to temp0 temp1...*/ + + curr_temp = &curr_psu->temp[temp_index]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &psu_temp_attr_group); + wb_plat_kobject_delete(&curr_temp->obj); + PSU_DBG("delete psu:%d temp%d.\n", curr_psu->obj->index, temp_index); + } + return; +} + +static int psuindex_single_temp_create_kobj_and_attrs(struct psu_obj_t * curr_psu, unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct temp_obj_t *curr_temp; /* point to temp0 temp1...*/ + + PSU_DBG("create psu_index:%d, temp%d ...\n", curr_psu->obj->index, temp_index); + + curr_temp = &curr_psu->temp[temp_index]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp%d", temp_index); + curr_temp->obj = wb_plat_kobject_create(name, &curr_psu->obj->kobj); + if (!curr_temp->obj) { + PSU_ERR("create psu_index:%d, temp%d object error!\n", curr_psu->obj->index, temp_index); + return -EBADRQC; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &psu_temp_attr_group) != 0) { + PSU_ERR("create psu_index:%d, temp%d attrs error.\n", curr_psu->obj->index, temp_index); + wb_plat_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + PSU_DBG("create psu_index:%d, temp%d ok.\n", curr_psu->obj->index, temp_index); + return 0; +} + +static int psuindex_temp_create_kobj_and_attrs(struct psu_obj_t * curr_psu, int temp_num) +{ + int temp_index, i; + + curr_psu->temp = kzalloc(sizeof(struct temp_obj_t) * temp_num, GFP_KERNEL); + if (!curr_psu->temp) { + PSU_ERR("kzalloc temp error, psu index = %d, temp number = %d.\n", curr_psu->obj->index, temp_num); + return -ENOMEM; + } + curr_psu->temp_number = temp_num; + for (temp_index = 0; temp_index < temp_num; temp_index++) { + if (psuindex_single_temp_create_kobj_and_attrs(curr_psu, temp_index) != 0) { + goto temp_error; + } + } + return 0; +temp_error: + for (i = temp_index - 1; i >= 0; i--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, i); + } + if (curr_psu->temp) { + kfree(curr_psu->temp); + curr_psu->temp = NULL; + } + return -EBADRQC; +} + +static void psuindex_temp_remove_kobj_and_attrs(struct psu_obj_t * curr_psu, int temp_num) +{ + unsigned int temp_index; + + for (temp_index = temp_num - 1; temp_index >= 0; temp_index--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, temp_index); + } + return; +} + +static int psu_temp_create(void) +{ + int psu_num, temp_num; + unsigned int psu_index, i; + struct psu_obj_t *curr_psu; /* point to psu1 psu2...*/ + + check_p(g_drv->get_dev_number); + temp_num = g_drv->get_dev_number(WB_MAIN_DEV_PSU, WB_MINOR_DEV_TEMP); + if (temp_num <= 0) { + PSU_INFO("psu temp_num:%d, don't need creat temp directory.\n", temp_num); + return 0; + } + + psu_num = g_psu.psu_number; + for(psu_index = 1; psu_index <= psu_num; psu_index++) { + curr_psu = &g_psu.psu[psu_index - 1]; + if(psuindex_temp_create_kobj_and_attrs(curr_psu, temp_num) != 0) { + goto error; + } + } + return 0; +error: + for(i = psu_index - 1; i > 0; i--) { + curr_psu = &g_psu.psu[i - 1]; + temp_num = curr_psu->temp_number; + psuindex_temp_remove_kobj_and_attrs(curr_psu, temp_num); + } + return -EBADRQC; +} + +static void psu_temp_remove(void) +{ + unsigned int psu_index; + struct psu_obj_t *curr_psu; + + if (g_psu.psu) { + for (psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + curr_psu = &g_psu.psu[psu_index - 1]; + if (curr_psu->temp) { + psuindex_temp_remove_kobj_and_attrs(curr_psu,curr_psu->temp_number); + kfree(curr_psu->temp); + curr_psu->temp = NULL; + curr_psu->temp_number = 0; + } + } + } + return; +} + +static void psu_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct psu_obj_t *curr_psu; + + curr_psu = &g_psu.psu[index - 1]; + if (curr_psu->obj) { + sysfs_remove_group(&curr_psu->obj->kobj, &psu_attr_group); + wb_plat_kobject_delete(&curr_psu->obj); + PSU_DBG("delete psu%d.\n", index); + } + return; +} + +static int psu_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct psu_obj_t *curr_psu; + + curr_psu = &g_psu.psu[index-1]; + PSU_DBG("create psu%d ...\n", index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "%s%d",PSU_SYSFS_NAME, index); + curr_psu->obj = wb_plat_kobject_create(name, parent); + if (!curr_psu->obj) { + PSU_ERR("create psu%d object error!\n", index); + return -EBADRQC; + } + curr_psu->obj->index = index; + if (sysfs_create_group(&curr_psu->obj->kobj, &psu_attr_group) != 0) { + PSU_ERR("create psu%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_psu->obj); + return -EBADRQC; + } + PSU_DBG("create psu%d ok.\n", index); + return 0; +} + +static int psu_sub_create_kobj_and_attrs(struct kobject *parent, int psu_num) +{ + unsigned int psu_index, i; + + g_psu.psu = kzalloc(sizeof(struct psu_obj_t) * psu_num, GFP_KERNEL); + if (!g_psu.psu) { + PSU_ERR("kzalloc psu.psu error, psu number = %d.\n", psu_num); + return -ENOMEM; + } + + for (psu_index = 1; psu_index <= psu_num; psu_index++) { + if (psu_sub_single_create_kobj_and_attrs(parent, psu_index) != 0) { + goto error; + } + } + return 0; +error: + for(i = psu_index - 1; i > 0; i--) { + psu_sub_single_remove_kobj_and_attrs(i); + } + if(g_psu.psu) { + kfree(g_psu.psu); + g_psu.psu = NULL; + } + return -EBADRQC; +} + +static int psu_sub_create(void) +{ + int ret, psu_num; + + check_p(g_drv->get_dev_number); + psu_num = g_drv->get_dev_number(WB_MAIN_DEV_PSU, WB_MINOR_DEV_NONE); + if (psu_num < 0) { + PSU_ERR("psu number = %d error.\n", psu_num); + return -EINVAL; + } + g_psu.psu_number = psu_num; + ret = psu_sub_create_kobj_and_attrs(&g_psu_obj->kobj, psu_num); + return ret; +} + +static void psu_sub_remove(void) +{ + unsigned int psu_index; + + if (g_psu.psu) { + for (psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + psu_sub_single_remove_kobj_and_attrs(psu_index); + } + kfree(g_psu.psu); + } + mem_clear(&g_psu, sizeof(struct psu_t)); + return ; +} + +static int psu_root_create(void) +{ + g_psu_obj = wb_plat_kobject_create(PSU_SYSFS_NAME, NULL); + if (!g_psu_obj) { + PSU_ERR("wb_plat_kobject_create psu error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_psu_obj->kobj, &psu_root_attr_group) != 0) { + wb_plat_kobject_delete(&g_psu_obj); + PSU_ERR("create psu dir attrs error!\n"); + return -EBADRQC; + } + PSU_DBG("wb_plat_kobject_create psu directory and attribute success.\n"); + return 0; +} + +static void psu_root_remove(void) +{ + if (g_psu_obj) { + sysfs_remove_group(&g_psu_obj->kobj, &psu_root_attr_group); + wb_plat_kobject_delete(&g_psu_obj); + PSU_DBG("delete psu root success\n"); + } + return; +} + +static int wb_psu_init(void) +{ + int ret; + + PSU_INFO("wb_psu_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = psu_root_create(); + if (ret < 0) { + goto psu_root_error; + } + + ret = psu_sub_create(); + if (ret < 0) { + goto psu_sub_error; + } + + ret = psu_temp_create(); + if (ret < 0) { + goto psu_temp_error; + } + + PSU_INFO("wb_psu_init ok.\n"); + return 0; +psu_temp_error: + psu_sub_remove(); +psu_sub_error: + psu_root_remove(); +psu_root_error: + return ret; +} + +static void wb_psu_exit(void) +{ + psu_temp_remove(); + psu_sub_remove(); + psu_root_remove(); + PSU_INFO("wb_psu_exit ok.\n"); + return ; +} + +module_init(wb_psu_init); +module_exit(wb_psu_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("psu sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c new file mode 100644 index 000000000000..04b764e82df9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c @@ -0,0 +1,457 @@ +/* + * plat_sensor.c + * Original Author: support 2020-02-17 + * + * This module create sensor kobjects and attributes in /sys/wb_plat/sensor + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define SENSOR_INFO(fmt, args...) LOG_INFO("sensor: ", fmt, ##args) +#define SENSOR_ERR(fmt, args...) LOG_ERR("sensor: ", fmt, ##args) +#define SENSOR_DBG(fmt, args...) LOG_DBG("sensor: ", fmt, ##args) + +struct sensor_t { + unsigned int in_number; + unsigned int temp_number; + struct sensor_in_t *in; + struct sensor_temp_t *temp; +}; + +struct sensor_temp_t { + struct switch_obj *obj; +}; + +struct sensor_in_t { + struct switch_obj *obj; +}; + +static int g_loglevel = 0; +static struct switch_drivers_t *g_drv = NULL; +static struct sensor_t g_sensor; +static struct switch_obj *g_sensor_obj = NULL; + +static ssize_t sensor_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_sensor.temp_number); +} + +static ssize_t sensor_in_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_sensor.in_number); +} + +static ssize_t sensor_voltage_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int in_index; + int ret; + struct switch_device_attribute *in_attr; + + check_p(g_drv); + check_p(g_drv->get_voltage_info); + in_index = obj->index; + + in_attr = to_switch_device_attr(attr); + check_p(in_attr); + SENSOR_DBG("sensor_in_show, in index:0x%x, in type:0x%x\n",in_index, in_attr->type); + ret = g_drv->get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, in_index, in_attr->type, buf); + if (ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t sensor_temp_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + int ret; + struct switch_device_attribute *temp_attr; + + check_p(g_drv); + check_p(g_drv->get_temp_info); + temp_index = obj->index; + + temp_attr = to_switch_device_attr(attr); + check_p(temp_attr); + SENSOR_DBG("sensor_temp_show, temp index:0x%x, temp type:0x%x\n", temp_index, temp_attr->type); + ret = g_drv->get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, temp_attr->type, buf); + if (ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return ret; +} + +/************************************sensor dir and attrs*******************************************/ +static struct switch_attribute num_temp_att = __ATTR(num_temp_sensors, S_IRUGO, sensor_temp_number_show, NULL); +static struct switch_attribute num_in_att = __ATTR(num_in_sensors, S_IRUGO, sensor_in_number_show, NULL); + +static struct attribute *sensor_dir_attrs[] = { + &num_temp_att.attr, + &num_in_att.attr, + NULL, +}; + +static struct attribute_group sensor_root_attr_group = { + .attrs = sensor_dir_attrs, +}; + +/*******************************temp0 temp1 dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(temp_input, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_INPUT); +static SWITCH_DEVICE_ATTR(temp_alias, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_ALIAS); +static SWITCH_DEVICE_ATTR(temp_type, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_TYPE); +static SWITCH_DEVICE_ATTR(temp_max, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_MAX); +static SWITCH_DEVICE_ATTR(temp_max_hyst, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_MAX_HYST); +static SWITCH_DEVICE_ATTR(temp_min, S_IRUGO, sensor_temp_show, NULL, WB_SENSOR_MIN); + +static struct attribute *sensor_temp_attrs[] = { + &switch_dev_attr_temp_input.switch_attr.attr, + &switch_dev_attr_temp_alias.switch_attr.attr, + &switch_dev_attr_temp_type.switch_attr.attr, + &switch_dev_attr_temp_max.switch_attr.attr, + &switch_dev_attr_temp_max_hyst.switch_attr.attr, + &switch_dev_attr_temp_min.switch_attr.attr, + NULL, +}; + +static struct attribute_group sensor_temp_attr_group = { + .attrs = sensor_temp_attrs, +}; + +/*******************************in0 in1 dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(in_input, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_INPUT); +static SWITCH_DEVICE_ATTR(in_alias, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_ALIAS); +static SWITCH_DEVICE_ATTR(in_type, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_TYPE); +static SWITCH_DEVICE_ATTR(in_max, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_MAX); +static SWITCH_DEVICE_ATTR(in_min, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_MIN); +static SWITCH_DEVICE_ATTR(in_crit, S_IRUGO, sensor_voltage_show, NULL, WB_SENSOR_CRIT); + +static struct attribute *sensor_in_attrs[] = { + &switch_dev_attr_in_input.switch_attr.attr, + &switch_dev_attr_in_alias.switch_attr.attr, + &switch_dev_attr_in_type.switch_attr.attr, + &switch_dev_attr_in_max.switch_attr.attr, + &switch_dev_attr_in_min.switch_attr.attr, + &switch_dev_attr_in_crit.switch_attr.attr, + NULL, +}; + +static struct attribute_group sensor_in_attr_group = { + .attrs = sensor_in_attrs, +}; + +static int sensor_in_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct sensor_in_t *curr_sensor; + + curr_sensor = &g_sensor.in[index - 1]; + SENSOR_DBG("create sensor in%d ...\n", index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "in%d", index); + curr_sensor->obj = wb_plat_kobject_create(name, parent); + if (!curr_sensor->obj) { + SENSOR_ERR("create sensor in%d object error!\n", index); + return -EBADRQC; + } + curr_sensor->obj->index = index; + if (sysfs_create_group(&curr_sensor->obj->kobj, &sensor_in_attr_group) != 0) { + SENSOR_ERR("create sensor in%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_sensor->obj); + return -EBADRQC; + } + SENSOR_DBG("create sensor in%d ok.\n", index); + return 0; + +} + +static void sensor_in_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sensor_in_t *curr_in; + + curr_in = &g_sensor.in[index - 1]; + if (curr_in->obj) { + sysfs_remove_group(&curr_in->obj->kobj, &sensor_in_attr_group); + wb_plat_kobject_delete(&curr_in->obj); + SENSOR_DBG("delete in%d.\n", index); + } + return; +} + +static int sensor_temp_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct sensor_temp_t *curr_sensor; + + curr_sensor = &g_sensor.temp[index - 1]; + SENSOR_DBG("create sensor temp%d ...\n", index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp%d", index); + curr_sensor->obj = wb_plat_kobject_create(name, parent); + if (!curr_sensor->obj) { + SENSOR_ERR("create sensor temp%d object error!\n", index); + return -EBADRQC; + } + curr_sensor->obj->index = index; + if (sysfs_create_group(&curr_sensor->obj->kobj, &sensor_temp_attr_group) != 0) { + SENSOR_ERR("create sensor temp%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_sensor->obj); + return -EBADRQC; + } + SENSOR_DBG("create sensor temp%d ok.\n", index); + return 0; + +} + +static void sensor_temp_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sensor_temp_t *curr_temp; + + curr_temp = &g_sensor.temp[index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &sensor_temp_attr_group); + wb_plat_kobject_delete(&curr_temp->obj); + SENSOR_DBG("delete temp%d.\n", index); + } + return; +} + +static int sensor_temp_sub_create_kobj_and_attrs(struct kobject *parent, int temp_num) +{ + unsigned int temp_index, i; + + g_sensor.temp = kzalloc(sizeof(struct sensor_temp_t) * temp_num, GFP_KERNEL); + if (!g_sensor.temp ) { + SENSOR_ERR("kzalloc g_sensor.temp error, temp number = %d.\n", temp_num); + return -ENOMEM; + } + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (sensor_temp_sub_single_create_kobj_and_attrs(parent, temp_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = temp_index - 1; i > 0; i--) { + sensor_temp_sub_single_remove_kobj_and_attrs(i); + } + + if (g_sensor.temp) { + kfree(g_sensor.temp); + g_sensor.temp = NULL; + } + return -EBADRQC; +} + +static int sensor_in_sub_create_kobj_and_attrs(struct kobject *parent, int in_num) +{ + unsigned int in_index, i; + + g_sensor.in = kzalloc(sizeof(struct sensor_in_t) * in_num, GFP_KERNEL); + if (!g_sensor.in) { + SENSOR_ERR("kzalloc g_sensor.in error, in number = %d.\n", in_num); + return -ENOMEM; + } + + for (in_index = 1; in_index <= in_num; in_index++) { + if (sensor_in_sub_single_create_kobj_and_attrs(parent, in_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = in_index - 1; i > 0; i--) { + sensor_in_sub_single_remove_kobj_and_attrs(i); + } + + if (g_sensor.in) { + kfree(g_sensor.in); + g_sensor.in = NULL; + } + return -EBADRQC; +} + +static int sensor_temp_sub_create(void) +{ + int ret, temp_num; + + check_p(g_drv->get_dev_number); + temp_num = g_drv->get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_TEMP); + g_sensor.temp_number = temp_num; + if (temp_num <= 0) { + SENSOR_DBG("Warning:sensor temp number = %d \n", temp_num); + return 0; + } + ret = sensor_temp_sub_create_kobj_and_attrs(&g_sensor_obj->kobj, temp_num); + return ret; +} + +static int sensor_in_sub_create(void) +{ + int ret, in_num; + + check_p(g_drv->get_dev_number); + in_num = g_drv->get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_IN); + g_sensor.in_number = in_num; + + if (in_num <= 0) { + SENSOR_DBG("Warning:sensor in number = %d \n", in_num); + return 0; + } + ret = sensor_in_sub_create_kobj_and_attrs(&g_sensor_obj->kobj, in_num); + return ret; +} + +static void temp_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sensor_temp_t * curr_temp; + + curr_temp = &g_sensor.temp[index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &sensor_temp_attr_group); + wb_plat_kobject_delete(&curr_temp->obj); + SENSOR_DBG("delete sensor temp%d.\n", index); + } + return; +} + +static void in_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sensor_in_t * curr_in; + + curr_in = &g_sensor.in[index - 1]; + if (curr_in->obj) { + sysfs_remove_group(&curr_in->obj->kobj, &sensor_in_attr_group); + wb_plat_kobject_delete(&curr_in->obj); + SENSOR_DBG("delete sensor in%d.\n", index); + } + return; +} + +static void sensor_temp_sub_remove(void) +{ + unsigned int temp_index; + + if (g_sensor.temp) { + for (temp_index = g_sensor.temp_number; temp_index > 0; temp_index--) { + temp_sub_single_remove_kobj_and_attrs(temp_index); + } + kfree(g_sensor.temp); + g_sensor.temp = NULL; + } + return; +} + +static void sensor_in_sub_remove(void) +{ + unsigned int in_index; + + if (g_sensor.in) { + for (in_index = g_sensor.in_number; in_index > 0; in_index--) { + in_sub_single_remove_kobj_and_attrs(in_index); + } + kfree(g_sensor.in); + g_sensor.in = NULL; + } + return; +} + +static void sensor_sub_remove(void) +{ + sensor_temp_sub_remove(); + sensor_in_sub_remove(); +} + +static int sensor_sub_create(void) +{ + int ret; + /* temp creat */ + ret = sensor_temp_sub_create(); + if (ret < 0) { + goto temp_err; + } + /* Voltage creat */ + ret = sensor_in_sub_create(); + if (ret < 0) { + goto in_err; + } + return 0; +in_err: + sensor_temp_sub_remove(); +temp_err: + return ret; +} +static void sensor_root_remove(void) +{ + if (g_sensor_obj) { + sysfs_remove_group(&g_sensor_obj->kobj, &sensor_root_attr_group); + wb_plat_kobject_delete(&g_sensor_obj); + SENSOR_DBG("delete sensor root success\n"); + } + + return; +} + +static int sensor_root_create(void) +{ + g_sensor_obj = wb_plat_kobject_create("sensor", NULL); + if (!g_sensor_obj) { + SENSOR_ERR("wb_plat_kobject_create sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_sensor_obj->kobj, &sensor_root_attr_group) != 0) { + wb_plat_kobject_delete(&g_sensor_obj); + SENSOR_ERR("create sensor dir attrs error!\n"); + return -EBADRQC; + } + SENSOR_DBG("wb_plat_kobject_create sensor directory and attribute success.\n"); + return 0; +} + +static int wb_sensor_init(void) +{ + int ret; + + SENSOR_INFO("wb_sensor_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = sensor_root_create(); + if (ret < 0) { + goto sensor_root_error; + } + + ret = sensor_sub_create(); + if (ret < 0) { + goto sensor_sub_error; + } + SENSOR_INFO("sensor_init ok.\n"); + return 0; +sensor_sub_error: + sensor_root_remove(); +sensor_root_error: + return ret; +} + +static void wb_sensor_exit(void) +{ + sensor_sub_remove(); + sensor_root_remove(); + SENSOR_INFO("sensor_exit ok.\n"); + return; +} + +module_init(wb_sensor_init); +module_exit(wb_sensor_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("sensors sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sff.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sff.c new file mode 100644 index 000000000000..8f09c551f62c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_sff.c @@ -0,0 +1,291 @@ +/* + * plat_sff.c + * Original Author: support 2020-02-17 + * + * This module create sff kobjects and attributes in /sys/wb_plat/sff + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define SFF_INFO(fmt, args...) LOG_INFO("sff: ", fmt, ##args) +#define SFF_ERR(fmt, args...) LOG_ERR("sff: ", fmt, ##args) +#define SFF_DBG(fmt, args...) LOG_DBG("sff: ", fmt, ##args) + +struct sff_obj_t{ + struct switch_obj *sff_obj; + struct bin_attribute bin; + int sff_creat_bin_flag; +}; + +struct sff_t{ + unsigned int sff_number; + struct sff_obj_t *sff; +}; + +static int g_loglevel = 0; +static struct sff_t g_sff; +static struct switch_obj *g_sff_obj = NULL; +static struct switch_drivers_t *g_drv = NULL; + +static ssize_t sff_cpld_info_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int sff_index; + int ret; + struct switch_device_attribute *sff_cpld_attr; + + check_p(g_drv); + check_p(g_drv->get_sff_cpld_info); + + sff_index = obj->index; + sff_cpld_attr = to_switch_device_attr(attr); + check_p(sff_cpld_attr); + SFF_DBG("sff_cpld_info_show, sff index:0x%x, sff cpld attr type:0x%x\n", sff_index, sff_cpld_attr->type); + ret = g_drv->get_sff_cpld_info(sff_index, sff_cpld_attr->type, buf, PAGE_SIZE); + if(ret < 0) { + SFF_ERR("sff_cpld_info_show error. sff index:0x%x, sff cpld attr type:0x%x, ret:%d\n", + sff_index, sff_cpld_attr->type,ret ); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + SFF_DBG("sff_cpld_info_show ok. sff index:0x%x, sff cpld attr type:0x%x, ret:%d\n", sff_index, sff_cpld_attr->type, ret); + return ret; +} + +static ssize_t sff_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_sff.sff_number); +} + +/************************************sff attrs*******************************************/ +static struct switch_attribute sff_number_att = __ATTR(num_sffs, S_IRUGO, sff_number_show, NULL); +static SWITCH_DEVICE_ATTR(present, S_IRUGO, sff_cpld_info_show, NULL, WB_SFF_MODULE_PRESENT); + +/*******************************xcvr dir and attrs*******************************************/ +static struct attribute *xcvr_dir_attrs[] = { + &sff_number_att.attr, + NULL, +}; + +static struct attribute_group sff_xcvr_attr_group = { + .attrs = xcvr_dir_attrs, +}; + +/*******************************sff dir and attrs*******************************************/ +static struct attribute *sff_attrs[] = { + &switch_dev_attr_present.switch_attr.attr, + NULL, +}; + +static struct attribute_group sff_attr_group = { + .attrs = sff_attrs, +}; + +static int sff_sub_single_create_attrs(unsigned int index) +{ + struct sff_obj_t *curr_sff; + + curr_sff = &g_sff.sff[index-1]; + if (sysfs_create_group(&curr_sff->sff_obj->kobj, &sff_attr_group) != 0) { + SFF_ERR("create sff%d dir attrs error!\n", index); + wb_plat_kobject_delete(&curr_sff->sff_obj); + return -EBADRQC; + } + SFF_DBG("create sff%d dir attrs ok!\n", index); + return 0; +} + +static int sff_sub_single_create_kobj(struct kobject *parent, unsigned int index) +{ + struct sff_obj_t *curr_sff; + char sff_dir_name[DIR_NAME_MAX_LEN]; + int ret; + + check_p(g_drv->get_sff_dir_name); + ret = g_drv->get_sff_dir_name(index, sff_dir_name, sizeof(sff_dir_name)); + if (ret < 0) { + SFF_ERR("sff index:%d, get sff dir name error. please check sff config.\n", index); + return -ENOSYS; + } + + curr_sff = &g_sff.sff[index - 1]; + + curr_sff->sff_obj = wb_plat_kobject_create(sff_dir_name, parent); + if (!curr_sff->sff_obj) { + SFF_ERR("sff index:%d, create %s object error! \n", index, sff_dir_name); + return -EBADRQC; + } + + SFF_DBG("create sff kobj ok. sff index:%d, dir name:%s\n",index, sff_dir_name); + curr_sff->sff_obj->index = index; + + return 0; +} + +static void sff_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sff_obj_t *curr_sff; + + curr_sff = &g_sff.sff[index - 1]; + /* remove sff dir and attr */ + if (curr_sff->sff_obj) { + SFF_DBG("delete sff%d attrs.\n", curr_sff->sff_obj->index); + curr_sff->sff_obj->index = 0; + sysfs_remove_group(&curr_sff->sff_obj->kobj, &sff_attr_group); + wb_plat_kobject_delete(&curr_sff->sff_obj); + } + + return; +} + +static int sff_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + int ret; + + ret = sff_sub_single_create_kobj(parent, index); + if (ret < 0) { + SFF_ERR("sff index:%d, create sff dir error.\n", index); + return ret; + } + + ret = sff_sub_single_create_attrs(index); + if (ret < 0) { + SFF_ERR("sff index:%d, create sff attr error.\n", index); + return ret; + } + return 0; +} + +static int sff_sub_create_kobj_and_attrs(struct kobject *parent, int sff_num) +{ + unsigned int sff_index, i; + + g_sff.sff = kzalloc(sizeof(struct sff_obj_t) * sff_num, GFP_KERNEL); + if (!g_sff.sff) { + SFF_ERR("kzalloc g_sff.sff error, sff number = %d.\n", sff_num); + return -ENOMEM; + } + + for (sff_index = 1; sff_index <= sff_num; sff_index++) { + if (sff_sub_single_create_kobj_and_attrs(parent, sff_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = sff_index - 1; i > 0; i--) { + sff_sub_single_remove_kobj_and_attrs(i); + } + if (g_sff.sff) { + kfree(g_sff.sff); + g_sff.sff = NULL; + } + return -EBADRQC; +} + +static int sff_sub_create(void) +{ + int ret, sff_num; + + check_p(g_drv->get_dev_number); + sff_num = g_drv->get_dev_number(WB_MAIN_DEV_SFF, WB_MINOR_DEV_NONE); + g_sff.sff_number = sff_num; + if (sff_num <= 0) { + SFF_ERR("ERROR. port number:%d\n", sff_num); + return -EINVAL; + } + + ret = sff_sub_create_kobj_and_attrs(&g_sff_obj->kobj, sff_num); + + return ret; +} + +static void sff_sub_remove(void) +{ + unsigned int sff_index; + + if (g_sff.sff) { + for (sff_index = g_sff.sff_number; sff_index > 0; sff_index--) { + sff_sub_single_remove_kobj_and_attrs(sff_index); + } + kfree(g_sff.sff); + } + mem_clear(&g_sff, sizeof(struct sff_t)); + return ; +} + +static int sff_xcvr_create(void) +{ + g_sff_obj = wb_plat_kobject_create(SFF_SYSFS_NAME, NULL); + if (!g_sff_obj) { + SFF_ERR("wb_plat_kobject_create sff error!\n"); + return -ENOMEM; + } + + g_sff_obj->index = 0; + if (sysfs_create_group(&g_sff_obj->kobj, &sff_xcvr_attr_group) != 0) { + wb_plat_kobject_delete(&g_sff_obj); + SFF_ERR("create sff dir attrs error!\n"); + return -EBADRQC; + } + SFF_DBG("wb_plat_kobject_create sff directory and attribute success.\n"); + return 0; +} + +static void sff_xcvr_remove(void) +{ + if (g_sff_obj) { + sysfs_remove_group(&g_sff_obj->kobj, &sff_xcvr_attr_group); + wb_plat_kobject_delete(&g_sff_obj); + SFF_DBG("delete sff root success\n"); + } + + return; +} + +static int wb_sff_init(void) +{ + int ret; + + SFF_INFO("wb_sff_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = sff_xcvr_create(); + if (ret < 0) { + goto sff_root_error; + } + + ret = sff_sub_create(); + if (ret < 0) { + goto sff_sub_error; + } + SFF_INFO("wb_sff_init ok.\n"); + return 0; + +sff_sub_error: + sff_xcvr_remove(); +sff_root_error: + return ret; +} + +static void wb_sff_exit(void) +{ + sff_sub_remove(); + sff_xcvr_remove(); + SFF_INFO("wb_sff_exit ok.\n"); + return ; +} + +module_init(wb_sff_init); +module_exit(wb_sff_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("sff sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_slot.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_slot.c new file mode 100644 index 000000000000..97539a4c24cc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_slot.c @@ -0,0 +1,667 @@ +/* + * plat_slot.c + * Original Author: support 2020-02-17 + * + * This module create sff kobjects and attributes in /sys/wb_plat/slot + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ + +#include + +#include "./include/plat_switch.h" +#include "./include/sysfs_common.h" + +#define SLOT_INFO(fmt, args...) LOG_INFO("slot: ", fmt, ##args) +#define SLOT_ERR(fmt, args...) LOG_ERR("slot: ", fmt, ##args) +#define SLOT_DBG(fmt, args...) LOG_DBG("slot: ", fmt, ##args) + +struct slot_temp_obj_t{ + struct switch_obj *obj; +}; + +struct slot_in_obj_t{ + struct switch_obj *obj; +}; + +struct slot_obj_t{ + unsigned int temp_number; + unsigned int in_number; + struct slot_temp_obj_t *temp; + struct slot_in_obj_t *in; + struct switch_obj *obj; +}; + +struct slot_t{ + unsigned int slot_number; + struct slot_obj_t *slot; +}; + +static int g_loglevel = 0; +static struct slot_t g_slot; +static struct switch_obj *g_slot_obj = NULL; +static struct switch_drivers_t *g_drv = NULL; + +static ssize_t slot_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_slot.slot_number); +} + +static ssize_t slot_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int index; + + index = obj->index; + SLOT_DBG("slot_temp_number_show,slot index:%d\n",index); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_slot.slot[index-1].temp_number); +} + +static ssize_t slot_in_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int index; + + index = obj->index; + SLOT_DBG("slot_in_number_show,slot index:%d\n",index); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_slot.slot[index-1].in_number); +} + +static ssize_t slot_present_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + int ret; + + slot_index = obj->index; + SLOT_DBG("slot_present_status_show, slot index:%d\n",slot_index); + check_p(g_drv); + check_p(g_drv->get_slot_present_status); + + ret = g_drv->get_slot_present_status(slot_index); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret); +} + +static ssize_t slot_voltage_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, in_index; + int ret; + struct switch_obj *p_obj; + struct switch_device_attribute *in_attr; + + check_p(g_drv); + check_p(g_drv->get_voltage_info); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + slot_index = p_obj->index; + in_index = obj->index; + + in_attr = to_switch_device_attr(attr); + check_p(in_attr); + SLOT_DBG("slot_voltage_show, slot index:0x%x, temp index:0x%x, temp type:0x%x\n",slot_index, in_index, in_attr->type); + ret = g_drv->get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, in_index, in_attr->type, buf); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_temp_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + struct switch_device_attribute *temp_attr; + + check_p(g_drv); + check_p(g_drv->get_temp_info); + + p_obj = to_switch_obj(obj->kobj.parent); + check_p(p_obj); + + slot_index = p_obj->index; + temp_index = obj->index; + + temp_attr = to_switch_device_attr(attr); + check_p(temp_attr); + SLOT_DBG("slot_temp_show, slot index:0x%x, temp index:0x%x, temp type:0x%x\n",slot_index, temp_index, temp_attr->type); + ret = g_drv->get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, temp_attr->type, buf); + if(ret < 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", WB_SYSFS_DEV_ERROR); + } + return ret; +} + +/************************************slot dir and attrs*******************************************/ +static struct switch_attribute slot_number_att = __ATTR(num_slots, S_IRUGO, slot_number_show, NULL); + +static struct attribute *slot_dir_attrs[] = { + &slot_number_att.attr, + NULL, +}; + +static struct attribute_group slot_root_attr_group = { + .attrs = slot_dir_attrs, +}; + +/*******************************slot1 slot2 dir and attrs*******************************************/ +static struct switch_attribute num_temp_sensors_att = __ATTR(num_temp_sensors, S_IRUGO, slot_temp_number_show, NULL); +static struct switch_attribute num_in_sensors_att = __ATTR(num_in_sensors, S_IRUGO, slot_in_number_show, NULL); +static struct switch_attribute slot_present_status_att = __ATTR(present, S_IRUGO, slot_present_status_show, NULL); + +static struct attribute *slot_attrs[] = { + &num_temp_sensors_att.attr, + &num_in_sensors_att.attr, + &slot_present_status_att.attr, + NULL, +}; + +static struct attribute_group slot_attr_group = { + .attrs = slot_attrs, +}; + +/*******************************temp dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(temp_alias, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_ALIAS); +static SWITCH_DEVICE_ATTR(temp_type, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_TYPE); +static SWITCH_DEVICE_ATTR(temp_max, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_MAX); +static SWITCH_DEVICE_ATTR(temp_max_hyst, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_MAX_HYST); +static SWITCH_DEVICE_ATTR(temp_min, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_MIN); +static SWITCH_DEVICE_ATTR(temp_input, S_IRUGO, slot_temp_show, NULL, WB_SENSOR_INPUT); + +static struct attribute *temp_attrs[] = { + &switch_dev_attr_temp_alias.switch_attr.attr, + &switch_dev_attr_temp_type.switch_attr.attr, + &switch_dev_attr_temp_max.switch_attr.attr, + &switch_dev_attr_temp_max_hyst.switch_attr.attr, + &switch_dev_attr_temp_min.switch_attr.attr, + &switch_dev_attr_temp_input.switch_attr.attr, + NULL, +}; + +static struct attribute_group temp_attr_group = { + .attrs = temp_attrs, +}; + +/*******************************Voltage dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(in_alias, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_ALIAS); +static SWITCH_DEVICE_ATTR(in_type, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_TYPE); +static SWITCH_DEVICE_ATTR(in_max, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_MAX); +static SWITCH_DEVICE_ATTR(in_crit, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_CRIT); +static SWITCH_DEVICE_ATTR(in_min, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_MIN); +static SWITCH_DEVICE_ATTR(in_input, S_IRUGO, slot_voltage_show, NULL, WB_SENSOR_INPUT); + +static struct attribute *in_attrs[] = { + &switch_dev_attr_in_alias.switch_attr.attr, + &switch_dev_attr_in_type.switch_attr.attr, + &switch_dev_attr_in_max.switch_attr.attr, + &switch_dev_attr_in_crit.switch_attr.attr, + &switch_dev_attr_in_min.switch_attr.attr, + &switch_dev_attr_in_input.switch_attr.attr, + NULL, +}; + +static struct attribute_group in_attr_group = { + .attrs = in_attrs, +}; + +static void slotindex_single_temp_remove_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int temp_index) +{ + + struct slot_temp_obj_t *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_slot->temp[temp_index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &temp_attr_group); + wb_plat_kobject_delete(&curr_temp->obj); + SLOT_DBG("delete slot:%d temp%d.\n", curr_slot->obj->index, temp_index); + } + return; +} + +static int slotindex_single_temp_create_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_temp_obj_t *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_slot->temp[temp_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "%s%d", TEMP_SYSFS_NAME, temp_index); + + curr_temp->obj = wb_plat_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_temp->obj) { + SLOT_ERR("create slot_index:%d, temp%d object error!\n", curr_slot->obj->index, temp_index); + return -EBADRQC; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &temp_attr_group) != 0) { + SLOT_ERR("create slot_index:%d, temp%d attrs error.\n", curr_slot->obj->index, temp_index); + wb_plat_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + SLOT_DBG("create slot_index:%d, temp%d ok.\n", curr_slot->obj->index, temp_index); + return 0; +} + +static void slotindex_temp_remove_kobj_and_attrs(struct slot_obj_t * curr_slot) +{ + int temp_index; + + for(temp_index = curr_slot->temp_number; temp_index > 0; temp_index--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, temp_index); + } + + if(curr_slot->temp) { + kfree(curr_slot->temp); + curr_slot->temp = NULL; + curr_slot->temp_number = 0; + } + return; +} + +static int slotindex_temp_create_kobj_and_attrs(struct slot_obj_t * curr_slot, int temp_num) +{ + int temp_index, i; + + curr_slot->temp_number = temp_num; + curr_slot->temp = kzalloc(sizeof(struct slot_temp_obj_t) * temp_num, GFP_KERNEL); + if (!curr_slot->temp) { + SLOT_ERR("kzalloc slot temp error, slot index = %d, temp number = %d.\n", curr_slot->obj->index, temp_num); + return -ENOMEM; + } + + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (slotindex_single_temp_create_kobj_and_attrs(curr_slot, temp_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = temp_index - 1; i > 0; i--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, i); + } + + if (curr_slot->temp) { + kfree(curr_slot->temp); + curr_slot->temp = NULL; + curr_slot->temp_number = 0; + } + return -EBADRQC; +} + +static void slotindex_single_in_remove_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int in_index) +{ + + struct slot_in_obj_t *curr_in; /* point to in1 in2...*/ + + curr_in = &curr_slot->in[in_index - 1]; + if (curr_in->obj) { + sysfs_remove_group(&curr_in->obj->kobj, &in_attr_group); + wb_plat_kobject_delete(&curr_in->obj); + SLOT_DBG("delete slot:%d in%d.\n", curr_slot->obj->index, in_index); + } + return; +} + +static int slotindex_single_in_create_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int in_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_in_obj_t *curr_in; /* point to in1 in2...*/ + + curr_in = &curr_slot->in[in_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "%s%d", VOLTAGE_SYSFS_NAME, in_index); + curr_in->obj = wb_plat_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_in->obj) { + SLOT_ERR("create slot_index:%d, in%d object error!\n", curr_slot->obj->index, in_index); + return -EBADRQC; + } + curr_in->obj->index = in_index; + if (sysfs_create_group(&curr_in->obj->kobj, &in_attr_group) != 0) { + SLOT_ERR("create slot_index:%d, in%d attrs error.\n", curr_slot->obj->index, in_index); + wb_plat_kobject_delete(&curr_in->obj); + return -EBADRQC; + } + SLOT_DBG("create slot_index:%d, in%d ok.\n", curr_slot->obj->index, in_index); + return 0; +} + +static void slotindex_in_remove_kobj_and_attrs(struct slot_obj_t * curr_slot) +{ + int in_index; + + for(in_index = curr_slot->in_number; in_index > 0; in_index--) { + slotindex_single_in_remove_kobj_and_attrs(curr_slot, in_index); + } + + if(curr_slot->in) { + kfree(curr_slot->in); + curr_slot->in = NULL; + curr_slot->in_number = 0; + } + return; +} + +static int slotindex_in_create_kobj_and_attrs(struct slot_obj_t * curr_slot, int in_num) +{ + int in_index, i; + + curr_slot->in_number = in_num; + curr_slot->in = kzalloc(sizeof(struct slot_in_obj_t) * in_num, GFP_KERNEL); + if (!curr_slot->in) { + SLOT_ERR("kzalloc slot Voltage error, slot index = %d, Voltage number = %d.\n", curr_slot->obj->index, in_num); + return -ENOMEM; + } + + for (in_index = 1; in_index <= in_num; in_index++) { + if (slotindex_single_in_create_kobj_and_attrs(curr_slot, in_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = in_index - 1; i > 0; i++) { + slotindex_single_in_remove_kobj_and_attrs(curr_slot, i); + } + + if (curr_slot->in) { + kfree(curr_slot->in); + curr_slot->in = NULL; + curr_slot->in_number = 0; + } + return -EBADRQC; +} + +static void slotindex_obj_remove_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int obj_id) +{ + switch (obj_id) { + case WB_MINOR_DEV_TEMP: + slotindex_temp_remove_kobj_and_attrs(curr_slot); + break; + case WB_MINOR_DEV_IN: + slotindex_in_remove_kobj_and_attrs(curr_slot); + break; + default: + SLOT_ERR("Unknow obj id:%d\n", obj_id); + } + return ; +} + +static int slotindex_obj_create_kobj_and_attrs(struct slot_obj_t * curr_slot, unsigned int obj_id, int obj_num) +{ + int ret; + + switch (obj_id) { + case WB_MINOR_DEV_TEMP: + ret = slotindex_temp_create_kobj_and_attrs(curr_slot, obj_num); + break; + case WB_MINOR_DEV_IN: + ret = slotindex_in_create_kobj_and_attrs(curr_slot, obj_num); + break; + default: + SLOT_ERR("Unknow obj id:%d\n", obj_id); + ret = -EINVAL; + } + return ret; +} + +static void slot_child_obj_remove_by_id(unsigned int obj_id) +{ + int slot_num; + unsigned int slot_index; + struct slot_obj_t *curr_slot; /* point to slot1 slot2...*/ + + slot_num = g_slot.slot_number; + if (slot_num <= 0 || !g_slot.slot) { + SLOT_DBG("Warning:slot number = %d\n", slot_num); + return; + } + + for(slot_index = slot_num; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_obj_remove_kobj_and_attrs(curr_slot, obj_id); + } + return; +} + +static int slot_child_obj_create_by_id(unsigned int obj_id) +{ + int slot_num, obj_num; + unsigned int slot_index, i; + struct slot_obj_t *curr_slot; /* point to slot1 slot2...*/ + + check_p(g_drv->get_dev_number); + obj_num = g_drv->get_dev_number(WB_MAIN_DEV_SLOT,obj_id); + slot_num = g_slot.slot_number; + if (obj_num <= 0 || slot_num <= 0 || !g_slot.slot) { + SLOT_DBG("Warning:slot number = %d, object number:%d.obj_id:%d\n", slot_num, obj_num, obj_id); + return 0; + } + + for (slot_index = 1; slot_index <= slot_num; slot_index++) { + curr_slot = &g_slot.slot[slot_index - 1]; + if (slotindex_obj_create_kobj_and_attrs(curr_slot, obj_id, obj_num) != 0) { + goto error; + } + } + return 0; +error: + for(i = slot_index - 1; i > 0; i++) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_obj_remove_kobj_and_attrs(curr_slot, obj_id); + } + return -EBADRQC; +} + +static void slot_child_obj_remove(void) +{ + /* temp remove */ + slot_child_obj_remove_by_id(WB_MINOR_DEV_TEMP); + + /* in creat */ + slot_child_obj_remove_by_id(WB_MINOR_DEV_IN); + return; +} + +static int slot_child_obj_create(void) +{ + int ret; + + /* temp creat */ + ret = slot_child_obj_create_by_id(WB_MINOR_DEV_TEMP); + if (ret < 0) { + goto temp_err; + } + /* Voltage creat */ + ret = slot_child_obj_create_by_id(WB_MINOR_DEV_IN); + if(ret < 0) { + goto in_err; + } + return 0; +in_err: + slot_child_obj_remove_by_id(WB_MINOR_DEV_TEMP); +temp_err: + return ret; +} + +static void slot_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct slot_obj_t *curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + if (curr_slot->obj) { + sysfs_remove_group(&curr_slot->obj->kobj, &slot_attr_group); + wb_plat_kobject_delete(&curr_slot->obj); + SLOT_DBG("delete slot%d.\n", index); + } + return; +} + +static int slot_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_obj_t *curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + SLOT_DBG("create %s%d ...\n", SLOT_SYSFS_NAME, index); + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "%s%d", SLOT_SYSFS_NAME, index); + curr_slot->obj = wb_plat_kobject_create(name, parent); + if (!curr_slot->obj) { + SLOT_ERR("create slot%d object error!\n", index); + return -EBADRQC; + } + curr_slot->obj->index = index; + if (sysfs_create_group(&curr_slot->obj->kobj, &slot_attr_group) != 0) { + SLOT_ERR("create slot%d attrs error.\n", index); + wb_plat_kobject_delete(&curr_slot->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%d ok.\n", index); + return 0; +} + +static int slot_sub_create_kobj_and_attrs(struct kobject *parent, int slot_num) +{ + unsigned int slot_index, i; + + g_slot.slot = kzalloc(sizeof(struct slot_obj_t) * slot_num, GFP_KERNEL); + if (!g_slot.slot) { + SLOT_ERR("kzalloc slot.slot error, slot number = %d.\n", slot_num); + return -ENOMEM; + } + + for (slot_index = 1; slot_index <= slot_num; slot_index++) { + if (slot_sub_single_create_kobj_and_attrs(parent, slot_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index - 1; i > 0; i--) { + slot_sub_single_remove_kobj_and_attrs(i); + } + if (g_slot.slot) { + kfree(g_slot.slot); + g_slot.slot = NULL; + } + return -EBADRQC; +} + +/* create slot1 slot2...dir and attrs */ +static int slot_sub_create(void) +{ + int ret, slot_num; + + check_p(g_drv->get_dev_number); + slot_num = g_drv->get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_NONE); + g_slot.slot_number = slot_num; + if (slot_num <= 0) { + SLOT_DBG("Warning:slot number = %d \n", slot_num); + return 0; + } + ret = slot_sub_create_kobj_and_attrs(&g_slot_obj->kobj, slot_num); + return ret; +} + +/** + * slot_sub_remove - delete slot1 slot2...dir and attrs + */ +static void slot_sub_remove(void) +{ + unsigned int slot_index; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + slot_sub_single_remove_kobj_and_attrs(slot_index); + } + kfree(g_slot.slot); + } + mem_clear(&g_slot, sizeof(struct slot_t)); + return ; +} + +/* create slot dir and num_slots attr */ +static int slot_root_create(void) +{ + g_slot_obj = wb_plat_kobject_create(SLOT_SYSFS_NAME, NULL); + if (!g_slot_obj) { + SLOT_ERR("wb_plat_kobject_create slot error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_slot_obj->kobj, &slot_root_attr_group) != 0) { + wb_plat_kobject_delete(&g_slot_obj); + SLOT_ERR("create slot dir attrs error!\n"); + return -EBADRQC; + } + SLOT_DBG("wb_plat_kobject_create slot directory and attribute success.\n"); + return 0; +} + +static void slot_root_remove(void) +{ + if (g_slot_obj) { + sysfs_remove_group(&g_slot_obj->kobj, &slot_root_attr_group); + wb_plat_kobject_delete(&g_slot_obj); + SLOT_DBG("delete slot root success\n"); + } + + return; +} + +static int wb_slot_init(void) +{ + int ret; + + SLOT_INFO("wb_slot_init...\n"); + g_drv = dfd_plat_driver_get(); + check_p(g_drv); + + ret = slot_root_create(); + if (ret < 0) { + goto slot_root_error; + } + + ret = slot_sub_create(); + if (ret < 0) { + goto slot_sub_error; + } + + ret = slot_child_obj_create(); + if (ret < 0) { + goto slot_child_obj_error; + } + + SLOT_INFO("wb_slot_init ok.\n"); + return 0; +slot_child_obj_error: + slot_sub_remove(); +slot_sub_error: + slot_root_remove(); +slot_root_error: + return ret; +} + +static void wb_slot_exit(void) +{ + slot_child_obj_remove(); + slot_sub_remove(); + slot_root_remove(); + SLOT_INFO("wb_slot_exit ok.\n"); + return ; +} + +module_init(wb_slot_init); +module_exit(wb_slot_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("slot sysfs driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_switch.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_switch.c new file mode 100644 index 000000000000..7c71fdb3bd62 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/plat_sysfs/dev_sysfs/plat_switch.c @@ -0,0 +1,135 @@ +/* + * plat_switch.c + * Original Author: support 2020-02-17 + * + * This module create a kset in sysfs called /sys/wb_plat + * Then other switch kobjects are created and assigned to this kset, + * such as "board", "cpld", "fan", "psu", "sff", ... + * + * History + * [Version] [Author] [Date] [Description] + * * v1.0 support 2020-02-17 Initial version + */ +#include "./include/plat_switch.h" + +#define SWITCH_INFO(fmt, args...) LOG_INFO("switch: ", fmt, ##args) +#define SWITCH_ERR(fmt, args...) LOG_ERR("switch: ", fmt, ##args) +#define SWITCH_DBG(fmt, args...) LOG_DBG("switch: ", fmt, ##args) + +static int g_loglevel = 0; + +static ssize_t switch_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct switch_attribute *attribute; + struct switch_obj *device; + + attribute = to_switch_attr(attr); + device = to_switch_obj(kobj); + + if (!attribute->show) + return -ENOSYS; + + return attribute->show(device, attribute, buf); +} + +static ssize_t switch_attr_store(struct kobject *kobj, + struct attribute *attr, const char *buf, size_t len) +{ + struct switch_attribute *attribute; + struct switch_obj *obj; + + attribute = to_switch_attr(attr); + obj = to_switch_obj(kobj); + + if (!attribute->store) + return -ENOSYS; + + return attribute->store(obj, attribute, buf, len); +} + +static const struct sysfs_ops switch_sysfs_ops = { + .show = switch_attr_show, + .store = switch_attr_store, +}; + +static void switch_obj_release(struct kobject *kobj) +{ + struct switch_obj *obj; + + obj = to_switch_obj(kobj); + kfree(obj); +} + +static struct kobj_type switch_ktype = { + .sysfs_ops = &switch_sysfs_ops, + .release = switch_obj_release, + .default_attrs = NULL, +}; + +static struct kset *switch_kset; + +struct switch_obj *wb_plat_kobject_create(const char *name, struct kobject *parent) +{ + struct switch_obj *obj = NULL; + int ret = 0; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) { + SWITCH_DBG("wb_plat_kobject_create %s kzalloc error", name); + return NULL; + } + + obj->kobj.kset = switch_kset; + + ret = kobject_init_and_add(&obj->kobj, &switch_ktype, parent, "%s", name); + if (ret) { + kobject_put(&obj->kobj); + SWITCH_DBG("kobject_init_and_add %s error", name); + return NULL; + } + + return obj; +} + +void wb_plat_kobject_delete(struct switch_obj **obj) +{ + if (*obj) { + SWITCH_DBG("%s delete %s.\n", (*obj)->kobj.parent->name, (*obj)->kobj.name); + kobject_put(&((*obj)->kobj)); + *obj = NULL; + } +} + +static int __init switch_init(void) +{ + SWITCH_INFO("...\n"); + + switch_kset = kset_create_and_add("wb_plat", NULL, NULL); + if (!switch_kset) { + SWITCH_ERR("create switch_kset error.\n"); + return -ENOMEM; + } + + SWITCH_INFO("ok.\n"); + return 0; +} + +static void __exit switch_exit(void) +{ + if (switch_kset) { + kset_unregister(switch_kset); + } + + SWITCH_INFO("ok.\n"); +} + +module_init(switch_init); +module_exit(switch_exit); +EXPORT_SYMBOL(wb_plat_kobject_create); +EXPORT_SYMBOL(wb_plat_kobject_delete); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Switch driver"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common.h new file mode 100644 index 000000000000..9e4a4fae00c1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common.h @@ -0,0 +1,74 @@ +#ifndef __PLATFORM_COMMON_H__ +#define __PLATFORM_COMMON_H__ + +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef enum { + DBG_START, + DBG_VERBOSE, + DBG_KEY, + DBG_WARN, + DBG_ERROR, + DBG_END, +} dbg_level_t; + + typedef struct dfd_i2c_dev_s { + int bus; + int addr; + } dfd_i2c_dev_t; + +typedef struct dfd_dev_head_info_s { + uint8_t ver; + uint8_t flag; + uint8_t hw_ver; + uint8_t type; + int16_t tlv_len; +} dfd_dev_head_info_t; + +typedef struct dfd_dev_tlv_info_s { + uint8_t type; + uint8_t len; + uint8_t data[0]; +} dfd_dev_tlv_info_t; + +typedef enum dfd_dev_info_type_e { + DFD_DEV_INFO_TYPE_MAC = 1, + DFD_DEV_INFO_TYPE_NAME = 2, + DFD_DEV_INFO_TYPE_SN = 3, + DFD_DEV_INFO_TYPE_PWR_CONS = 4, + DFD_DEV_INFO_TYPE_HW_INFO = 5, + DFD_DEV_INFO_TYPE_DEV_TYPE = 6, +} dfd_dev_tlv_type_t; + +extern int debuglevel; +extern s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command); +extern s32 platform_i2c_smbus_read_i2c_block_data(const struct i2c_client *client, + u8 command, u8 length, u8 *values); +extern s32 platform_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command); + +#define DBG_DEBUG(fmt, arg...) do { \ + if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ + printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else if ( debuglevel >= DBG_ERROR ) { \ + printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else { } \ +} while (0) + +#define DBG_INFO(fmt, arg...) do { \ + if ( debuglevel > DBG_KEY) { \ + printk(KERN_INFO "[INFO]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +#define DBG_ERROR(fmt, arg...) do { \ + if ( debuglevel > DBG_START) { \ + printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common_module.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common_module.c new file mode 100644 index 000000000000..62e04b7db837 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/platform_common_module.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,152) +#include +#else +#include +#endif +#include +#include +#include +#include +#include "platform_common.h" +#include "dfd_tlveeprom.h" + +#define PLATFORM_I2C_RETRY_TIMES 3 + +#define DFD_TLVEEPROM_I2C_BUS (0) +#define DFD_TLVEEPROM_I2C_ADDR (0x56) +#define DFD_E2PROM_MAX_LEN (256) +#define DFD_CARDTYPE_EXT_TLVLEN (4) + +#define PLATFORM_CARDTYPE_RETRY_CNT (10) +#define PLATFORM_CARDTYPE_RETRY_TIMES (1000) + +int debuglevel = 0; +module_param(debuglevel, int, S_IRUGO | S_IWUSR); + +static int dfd_my_type = 0; +module_param(dfd_my_type, int, S_IRUGO | S_IWUSR); + +int g_common_debug_error = 0; +module_param(g_common_debug_error, int, S_IRUGO | S_IWUSR); + +int g_common_debug_verbose = 0; +module_param(g_common_debug_verbose, int, S_IRUGO | S_IWUSR); + +uint32_t dfd_my_type_i2c_bus = 0; +module_param(dfd_my_type_i2c_bus, int, S_IRUGO | S_IWUSR); + +uint32_t dfd_my_type_i2c_addr = 0; +module_param(dfd_my_type_i2c_addr, int, S_IRUGO | S_IWUSR); + +#define RUJIE_COMMON_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_common_debug_verbose) { \ + printk(KERN_ERR "[PLATFORM_COMMON][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define RUJIE_COMMON_DEBUG_ERROR(fmt, args...) do { \ + if (g_common_debug_error) { \ + printk(KERN_ERR "[PLATFORM_COMMON][ERROR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static int32_t dfd_i2c_read(char *dev, uint32_t addr, uint32_t offset_addr, unsigned char * +buf, int32_t size) +{ + struct file *fp; + struct i2c_client client; + int i ,j; + int rv; + s32 val_t; + + val_t = -1; + rv = 0; + fp = filp_open(dev, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + DBG_ERROR("i2c open fail.\n"); + RUJIE_COMMON_DEBUG_ERROR("i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = addr; + for (j = 0 ;j < size ;j++){ + for (i = 0; i < PLATFORM_I2C_RETRY_TIMES; i++) { + if ((val_t = i2c_smbus_read_byte_data(&client, (offset_addr + j)))< 0) { + DBG_DEBUG("read try(%d)time offset_addr:%x \n", i, offset_addr); + continue; + } else { + * (buf + j) = val_t; + break; + } + } + if (val_t < 0) { + rv = -1; + break; + } + } + filp_close(fp, NULL); + return rv; +} + +static int dfd_tlvinfo_get_cardtype(void) +{ + char i2c_path[16] = {0}; + int ret; + int cardtype; + u_int8_t eeprom[DFD_E2PROM_MAX_LEN]; + dfd_i2c_dev_t i2c_dev; + uint8_t buf[DFD_CARDTYPE_EXT_TLVLEN]; + uint8_t len; + dfd_tlv_type_t tlv_type; + + if (dfd_my_type_i2c_bus != 0) { + i2c_dev.bus = dfd_my_type_i2c_bus; + } else { + i2c_dev.bus = DFD_TLVEEPROM_I2C_BUS; + } + + if (dfd_my_type_i2c_addr != 0) { + i2c_dev.addr = dfd_my_type_i2c_addr; + } else { + i2c_dev.addr = DFD_TLVEEPROM_I2C_ADDR; + } + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_dev.bus); + RUJIE_COMMON_DEBUG_VERBOSE("Read device eeprom info:(dev:%s, addr:%02x).\n", i2c_path, i2c_dev.addr); + + ret = dfd_i2c_read(i2c_path, i2c_dev.addr, 0, eeprom, DFD_E2PROM_MAX_LEN); + if (ret != 0) { + DBG_ERROR("Read eeprom info error(dev: %s, addr: %02x).\n", i2c_path, i2c_dev.addr); + RUJIE_COMMON_DEBUG_ERROR("Read eeprom info error(dev: %s, addr: %02x).\n", i2c_path, i2c_dev.addr); + return ret; + } + + tlv_type.main_type = TLV_CODE_VENDOR_EXT; + tlv_type.ext_type = DFD_TLVINFO_EXT_TLV_TYPE_DEV_TYPE; + len = sizeof(buf); + mem_clear(buf, len); + ret = dfd_tlvinfo_get_e2prom_info(eeprom, DFD_E2PROM_MAX_LEN, &tlv_type, buf, &len); + if (ret) { + DBG_ERROR("dfd_tlvinfo_get_e2prom_info failed ret %d.\n", ret); + return -1; + } + for (ret = 0; ret < 4; ret++) { + DBG_DEBUG("buf 0x%02x.\n", buf[ret]); + } + + cardtype = ntohl(*((uint32_t *)buf)); + DBG_DEBUG("cardtype 0x%x.\n", cardtype); + return cardtype; +} + +static int __dfd_get_my_card_type(void) +{ + return dfd_tlvinfo_get_cardtype(); +} + +int dfd_get_my_card_type(void) +{ + int type; + int cnt; + + if (dfd_my_type != 0) { + DBG_DEBUG("my_type = 0x%x\r\n", dfd_my_type); + return dfd_my_type; + } + + cnt = PLATFORM_CARDTYPE_RETRY_CNT; + while (cnt--) { + type = __dfd_get_my_card_type(); + if (type < 0) { + RUJIE_COMMON_DEBUG_ERROR("__dfd_get_my_card_type fail cnt %d, ret %d.\n", cnt, type); + msleep(PLATFORM_CARDTYPE_RETRY_TIMES); + continue; + } + RUJIE_COMMON_DEBUG_VERBOSE("success to get type 0x%x.\n", type); + break; + } + + dfd_my_type = type; + return dfd_my_type; +} +EXPORT_SYMBOL(dfd_get_my_card_type); + +static int __init platform_common_init(void) +{ + int ret; + + RUJIE_COMMON_DEBUG_VERBOSE("Enter.\n"); + ret = dfd_get_my_card_type(); + if (ret <= 0) { + RUJIE_COMMON_DEBUG_ERROR("dfd_get_my_card_type failed, ret %d.\n", ret); + printk(KERN_ERR "Warning: Device type get failed, please check the TLV-EEPROM!\n"); + return -1; + } + + RUJIE_COMMON_DEBUG_VERBOSE("Leave success type 0x%x.\n", ret); + return 0; +} + +static void __exit platform_common_exit(void) +{ + RUJIE_COMMON_DEBUG_VERBOSE("Exit.\n"); +} + +module_init(platform_common_init); +module_exit(platform_common_exit); + +MODULE_DESCRIPTION("Platform Support"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/pmbus.h deleted file mode 100755 index 39b778a4734b..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/pmbus.h +++ /dev/null @@ -1,466 +0,0 @@ -/* - * pmbus.h - Common defines and structures for PMBus devices - * - * Copyright (c) 2010, 2011 Ericsson AB. - * Copyright (c) 2012 Guenter Roeck - * - * 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 PMBUS_H -#define PMBUS_H - -#include -#include - -/* - * Registers - */ -enum pmbus_regs { - PMBUS_PAGE = 0x00, - PMBUS_OPERATION = 0x01, - PMBUS_ON_OFF_CONFIG = 0x02, - PMBUS_CLEAR_FAULTS = 0x03, - PMBUS_PHASE = 0x04, - - PMBUS_CAPABILITY = 0x19, - PMBUS_QUERY = 0x1A, - - PMBUS_VOUT_MODE = 0x20, - PMBUS_VOUT_COMMAND = 0x21, - PMBUS_VOUT_TRIM = 0x22, - PMBUS_VOUT_CAL_OFFSET = 0x23, - PMBUS_VOUT_MAX = 0x24, - PMBUS_VOUT_MARGIN_HIGH = 0x25, - PMBUS_VOUT_MARGIN_LOW = 0x26, - PMBUS_VOUT_TRANSITION_RATE = 0x27, - PMBUS_VOUT_DROOP = 0x28, - PMBUS_VOUT_SCALE_LOOP = 0x29, - PMBUS_VOUT_SCALE_MONITOR = 0x2A, - - PMBUS_COEFFICIENTS = 0x30, - PMBUS_POUT_MAX = 0x31, - - PMBUS_FAN_CONFIG_12 = 0x3A, - PMBUS_FAN_COMMAND_1 = 0x3B, - PMBUS_FAN_COMMAND_2 = 0x3C, - PMBUS_FAN_CONFIG_34 = 0x3D, - PMBUS_FAN_COMMAND_3 = 0x3E, - PMBUS_FAN_COMMAND_4 = 0x3F, - - PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, - PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, - PMBUS_VOUT_OV_WARN_LIMIT = 0x42, - PMBUS_VOUT_UV_WARN_LIMIT = 0x43, - PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, - PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, - PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, - PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, - PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, - PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, - PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, - PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, - PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, - - PMBUS_OT_FAULT_LIMIT = 0x4F, - PMBUS_OT_FAULT_RESPONSE = 0x50, - PMBUS_OT_WARN_LIMIT = 0x51, - PMBUS_UT_WARN_LIMIT = 0x52, - PMBUS_UT_FAULT_LIMIT = 0x53, - PMBUS_UT_FAULT_RESPONSE = 0x54, - PMBUS_VIN_OV_FAULT_LIMIT = 0x55, - PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, - PMBUS_VIN_OV_WARN_LIMIT = 0x57, - PMBUS_VIN_UV_WARN_LIMIT = 0x58, - PMBUS_VIN_UV_FAULT_LIMIT = 0x59, - - PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, - PMBUS_IIN_OC_WARN_LIMIT = 0x5D, - - PMBUS_POUT_OP_FAULT_LIMIT = 0x68, - PMBUS_POUT_OP_WARN_LIMIT = 0x6A, - PMBUS_PIN_OP_WARN_LIMIT = 0x6B, - - PMBUS_STATUS_BYTE = 0x78, - PMBUS_STATUS_WORD = 0x79, - PMBUS_STATUS_VOUT = 0x7A, - PMBUS_STATUS_IOUT = 0x7B, - PMBUS_STATUS_INPUT = 0x7C, - PMBUS_STATUS_TEMPERATURE = 0x7D, - PMBUS_STATUS_CML = 0x7E, - PMBUS_STATUS_OTHER = 0x7F, - PMBUS_STATUS_MFR_SPECIFIC = 0x80, - PMBUS_STATUS_FAN_12 = 0x81, - PMBUS_STATUS_FAN_34 = 0x82, - - PMBUS_READ_VIN = 0x88, - PMBUS_READ_IIN = 0x89, - PMBUS_READ_VCAP = 0x8A, - PMBUS_READ_VOUT = 0x8B, - PMBUS_READ_IOUT = 0x8C, - PMBUS_READ_TEMPERATURE_1 = 0x8D, - PMBUS_READ_TEMPERATURE_2 = 0x8E, - PMBUS_READ_TEMPERATURE_3 = 0x8F, - PMBUS_READ_FAN_SPEED_1 = 0x90, - PMBUS_READ_FAN_SPEED_2 = 0x91, - PMBUS_READ_FAN_SPEED_3 = 0x92, - PMBUS_READ_FAN_SPEED_4 = 0x93, - PMBUS_READ_DUTY_CYCLE = 0x94, - PMBUS_READ_FREQUENCY = 0x95, - PMBUS_READ_POUT = 0x96, - PMBUS_READ_PIN = 0x97, - - PMBUS_REVISION = 0x98, - PMBUS_MFR_ID = 0x99, - PMBUS_MFR_MODEL = 0x9A, - PMBUS_MFR_REVISION = 0x9B, - PMBUS_MFR_LOCATION = 0x9C, - PMBUS_MFR_DATE = 0x9D, - PMBUS_MFR_SERIAL = 0x9E, - - /* - * Virtual registers. - * Useful to support attributes which are not supported by standard PMBus - * registers but exist as manufacturer specific registers on individual chips. - * Must be mapped to real registers in device specific code. - * - * Semantics: - * Virtual registers are all word size. - * READ registers are read-only; writes are either ignored or return an error. - * RESET registers are read/write. Reading reset registers returns zero - * (used for detection), writing any value causes the associated history to be - * reset. - * Virtual registers have to be handled in device specific driver code. Chip - * driver code returns non-negative register values if a virtual register is - * supported, or a negative error code if not. The chip driver may return - * -ENODATA or any other error code in this case, though an error code other - * than -ENODATA is handled more efficiently and thus preferred. Either case, - * the calling PMBus core code will abort if the chip driver returns an error - * code when reading or writing virtual registers. - */ - PMBUS_VIRT_BASE = 0x100, - PMBUS_VIRT_READ_TEMP_AVG, - PMBUS_VIRT_READ_TEMP_MIN, - PMBUS_VIRT_READ_TEMP_MAX, - PMBUS_VIRT_RESET_TEMP_HISTORY, - PMBUS_VIRT_READ_VIN_AVG, - PMBUS_VIRT_READ_VIN_MIN, - PMBUS_VIRT_READ_VIN_MAX, - PMBUS_VIRT_RESET_VIN_HISTORY, - PMBUS_VIRT_READ_IIN_AVG, - PMBUS_VIRT_READ_IIN_MIN, - PMBUS_VIRT_READ_IIN_MAX, - PMBUS_VIRT_RESET_IIN_HISTORY, - PMBUS_VIRT_READ_PIN_AVG, - PMBUS_VIRT_READ_PIN_MIN, - PMBUS_VIRT_READ_PIN_MAX, - PMBUS_VIRT_RESET_PIN_HISTORY, - PMBUS_VIRT_READ_POUT_AVG, - PMBUS_VIRT_READ_POUT_MIN, - PMBUS_VIRT_READ_POUT_MAX, - PMBUS_VIRT_RESET_POUT_HISTORY, - PMBUS_VIRT_READ_VOUT_AVG, - PMBUS_VIRT_READ_VOUT_MIN, - PMBUS_VIRT_READ_VOUT_MAX, - PMBUS_VIRT_RESET_VOUT_HISTORY, - PMBUS_VIRT_READ_IOUT_AVG, - PMBUS_VIRT_READ_IOUT_MIN, - PMBUS_VIRT_READ_IOUT_MAX, - PMBUS_VIRT_RESET_IOUT_HISTORY, - PMBUS_VIRT_READ_TEMP2_AVG, - PMBUS_VIRT_READ_TEMP2_MIN, - PMBUS_VIRT_READ_TEMP2_MAX, - PMBUS_VIRT_RESET_TEMP2_HISTORY, - - PMBUS_VIRT_READ_VMON, - PMBUS_VIRT_VMON_UV_WARN_LIMIT, - PMBUS_VIRT_VMON_OV_WARN_LIMIT, - PMBUS_VIRT_VMON_UV_FAULT_LIMIT, - PMBUS_VIRT_VMON_OV_FAULT_LIMIT, - PMBUS_VIRT_STATUS_VMON, - - /* - * RPM and PWM Fan control - * - * Drivers wanting to expose PWM control must define the behaviour of - * PMBUS_VIRT_PWM_[1-4] and PMBUS_VIRT_PWM_ENABLE_[1-4] in the - * {read,write}_word_data callback. - * - * pmbus core provides a default implementation for - * PMBUS_VIRT_FAN_TARGET_[1-4]. - * - * TARGET, PWM and PWM_ENABLE members must be defined sequentially; - * pmbus core uses the difference between the provided register and - * it's _1 counterpart to calculate the FAN/PWM ID. - */ - PMBUS_VIRT_FAN_TARGET_1, - PMBUS_VIRT_FAN_TARGET_2, - PMBUS_VIRT_FAN_TARGET_3, - PMBUS_VIRT_FAN_TARGET_4, - PMBUS_VIRT_PWM_1, - PMBUS_VIRT_PWM_2, - PMBUS_VIRT_PWM_3, - PMBUS_VIRT_PWM_4, - PMBUS_VIRT_PWM_ENABLE_1, - PMBUS_VIRT_PWM_ENABLE_2, - PMBUS_VIRT_PWM_ENABLE_3, - PMBUS_VIRT_PWM_ENABLE_4, -}; - -/* - * OPERATION - */ -#define PB_OPERATION_CONTROL_ON BIT(7) - -/* - * CAPABILITY - */ -#define PB_CAPABILITY_SMBALERT BIT(4) -#define PB_CAPABILITY_ERROR_CHECK BIT(7) - -/* - * VOUT_MODE - */ -#define PB_VOUT_MODE_MODE_MASK 0xe0 -#define PB_VOUT_MODE_PARAM_MASK 0x1f - -#define PB_VOUT_MODE_LINEAR 0x00 -#define PB_VOUT_MODE_VID 0x20 -#define PB_VOUT_MODE_DIRECT 0x40 - -/* - * Fan configuration - */ -#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1)) -#define PB_FAN_2_RPM BIT(2) -#define PB_FAN_2_INSTALLED BIT(3) -#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5)) -#define PB_FAN_1_RPM BIT(6) -#define PB_FAN_1_INSTALLED BIT(7) - -enum pmbus_fan_mode { percent = 0, rpm }; - -/* - * STATUS_BYTE, STATUS_WORD (lower) - */ -#define PB_STATUS_NONE_ABOVE BIT(0) -#define PB_STATUS_CML BIT(1) -#define PB_STATUS_TEMPERATURE BIT(2) -#define PB_STATUS_VIN_UV BIT(3) -#define PB_STATUS_IOUT_OC BIT(4) -#define PB_STATUS_VOUT_OV BIT(5) -#define PB_STATUS_OFF BIT(6) -#define PB_STATUS_BUSY BIT(7) - -/* - * STATUS_WORD (upper) - */ -#define PB_STATUS_UNKNOWN BIT(8) -#define PB_STATUS_OTHER BIT(9) -#define PB_STATUS_FANS BIT(10) -#define PB_STATUS_POWER_GOOD_N BIT(11) -#define PB_STATUS_WORD_MFR BIT(12) -#define PB_STATUS_INPUT BIT(13) -#define PB_STATUS_IOUT_POUT BIT(14) -#define PB_STATUS_VOUT BIT(15) - -/* - * STATUS_IOUT - */ -#define PB_POUT_OP_WARNING BIT(0) -#define PB_POUT_OP_FAULT BIT(1) -#define PB_POWER_LIMITING BIT(2) -#define PB_CURRENT_SHARE_FAULT BIT(3) -#define PB_IOUT_UC_FAULT BIT(4) -#define PB_IOUT_OC_WARNING BIT(5) -#define PB_IOUT_OC_LV_FAULT BIT(6) -#define PB_IOUT_OC_FAULT BIT(7) - -/* - * STATUS_VOUT, STATUS_INPUT - */ -#define PB_VOLTAGE_UV_FAULT BIT(4) -#define PB_VOLTAGE_UV_WARNING BIT(5) -#define PB_VOLTAGE_OV_WARNING BIT(6) -#define PB_VOLTAGE_OV_FAULT BIT(7) - -/* - * STATUS_INPUT - */ -#define PB_PIN_OP_WARNING BIT(0) -#define PB_IIN_OC_WARNING BIT(1) -#define PB_IIN_OC_FAULT BIT(2) - -/* - * STATUS_TEMPERATURE - */ -#define PB_TEMP_UT_FAULT BIT(4) -#define PB_TEMP_UT_WARNING BIT(5) -#define PB_TEMP_OT_WARNING BIT(6) -#define PB_TEMP_OT_FAULT BIT(7) - -/* - * STATUS_FAN - */ -#define PB_FAN_AIRFLOW_WARNING BIT(0) -#define PB_FAN_AIRFLOW_FAULT BIT(1) -#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2) -#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3) -#define PB_FAN_FAN2_WARNING BIT(4) -#define PB_FAN_FAN1_WARNING BIT(5) -#define PB_FAN_FAN2_FAULT BIT(6) -#define PB_FAN_FAN1_FAULT BIT(7) - -/* - * CML_FAULT_STATUS - */ -#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) -#define PB_CML_FAULT_OTHER_COMM BIT(1) -#define PB_CML_FAULT_PROCESSOR BIT(3) -#define PB_CML_FAULT_MEMORY BIT(4) -#define PB_CML_FAULT_PACKET_ERROR BIT(5) -#define PB_CML_FAULT_INVALID_DATA BIT(6) -#define PB_CML_FAULT_INVALID_COMMAND BIT(7) - -enum pmbus_sensor_classes { - PSC_VOLTAGE_IN = 0, - PSC_VOLTAGE_OUT, - PSC_CURRENT_IN, - PSC_CURRENT_OUT, - PSC_POWER, - PSC_TEMPERATURE, - PSC_FAN, - PSC_PWM, - PSC_NUM_CLASSES /* Number of power sensor classes */ -}; - -#define PMBUS_PAGES 32 /* Per PMBus specification */ - -/* Functionality bit mask */ -#define PMBUS_HAVE_VIN BIT(0) -#define PMBUS_HAVE_VCAP BIT(1) -#define PMBUS_HAVE_VOUT BIT(2) -#define PMBUS_HAVE_IIN BIT(3) -#define PMBUS_HAVE_IOUT BIT(4) -#define PMBUS_HAVE_PIN BIT(5) -#define PMBUS_HAVE_POUT BIT(6) -#define PMBUS_HAVE_FAN12 BIT(7) -#define PMBUS_HAVE_FAN34 BIT(8) -#define PMBUS_HAVE_TEMP BIT(9) -#define PMBUS_HAVE_TEMP2 BIT(10) -#define PMBUS_HAVE_TEMP3 BIT(11) -#define PMBUS_HAVE_STATUS_VOUT BIT(12) -#define PMBUS_HAVE_STATUS_IOUT BIT(13) -#define PMBUS_HAVE_STATUS_INPUT BIT(14) -#define PMBUS_HAVE_STATUS_TEMP BIT(15) -#define PMBUS_HAVE_STATUS_FAN12 BIT(16) -#define PMBUS_HAVE_STATUS_FAN34 BIT(17) -#define PMBUS_HAVE_VMON BIT(18) -#define PMBUS_HAVE_STATUS_VMON BIT(19) -#define PMBUS_HAVE_PWM12 BIT(20) -#define PMBUS_HAVE_PWM34 BIT(21) - -#define PMBUS_PAGE_VIRTUAL BIT(31) - -enum pmbus_data_format { linear = 0, direct, vid }; -enum vrm_version { vr11 = 0, vr12, vr13 }; - -struct pmbus_driver_info { - int pages; /* Total number of pages */ - enum pmbus_data_format format[PSC_NUM_CLASSES]; - enum vrm_version vrm_version[PMBUS_PAGES]; - /* - * Support one set of coefficients for each sensor type - * Used for chips providing data in direct mode. - */ - int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ - int b[PSC_NUM_CLASSES]; /* offset */ - int R[PSC_NUM_CLASSES]; /* exponent */ - - u32 func[PMBUS_PAGES]; /* Functionality, per page */ - /* - * The following functions map manufacturing specific register values - * to PMBus standard register values. Specify only if mapping is - * necessary. - * Functions return the register value (read) or zero (write) if - * successful. A return value of -ENODATA indicates that there is no - * manufacturer specific register, but that a standard PMBus register - * may exist. Any other negative return value indicates that the - * register does not exist, and that no attempt should be made to read - * the standard register. - */ - int (*read_byte_data)(struct i2c_client *client, int page, int reg); - int (*read_word_data)(struct i2c_client *client, int page, int reg); - int (*write_word_data)(struct i2c_client *client, int page, int reg, - u16 word); - int (*write_byte)(struct i2c_client *client, int page, u8 value); - /* - * The identify function determines supported PMBus functionality. - * This function is only necessary if a chip driver supports multiple - * chips, and the chip functionality is not pre-determined. - */ - int (*identify)(struct i2c_client *client, - struct pmbus_driver_info *info); - - /* Regulator functionality, if supported by this chip driver. */ - int num_regulators; - const struct regulator_desc *reg_desc; -}; - -/* Regulator ops */ - -extern const struct regulator_ops pmbus_regulator_ops; - -/* Macro for filling in array of struct regulator_desc */ -#define PMBUS_REGULATOR(_name, _id) \ - [_id] = { \ - .name = (_name # _id), \ - .id = (_id), \ - .of_match = of_match_ptr(_name # _id), \ - .regulators_node = of_match_ptr("regulators"), \ - .ops = &pmbus_regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - } - -/* Function declarations */ - -void pmbus_clear_cache(struct i2c_client *client); -int pmbus_set_page(struct i2c_client *client, int page); -int pmbus_read_word_data(struct i2c_client *client, int page, u8 reg); -int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, u16 word); -int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); -int pmbus_write_byte(struct i2c_client *client, int page, u8 value); -int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, - u8 value); -int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, - u8 mask, u8 value); -void pmbus_clear_faults(struct i2c_client *client); -bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); -bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); -int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, - struct pmbus_driver_info *info); -int pmbus_do_remove(struct i2c_client *client); -const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client - *client); -int pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id, - enum pmbus_fan_mode mode); -int pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id, - enum pmbus_fan_mode mode); -int pmbus_update_fan(struct i2c_client *client, int page, int id, - u8 config, u8 mask, u16 command); -struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client); - -#endif /* PMBUS_H */ diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/ragile_common_module.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/ragile_common_module.c deleted file mode 100755 index e4fc735643dd..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/ragile_common_module.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int dfd_my_type = 0; -module_param(dfd_my_type, int, S_IRUGO | S_IWUSR); - -int g_common_debug_error = 0; -module_param(g_common_debug_error, int, S_IRUGO | S_IWUSR); - -int g_common_debug_verbose = 0; -module_param(g_common_debug_verbose, int, S_IRUGO | S_IWUSR); - -#define RAGILE_COMMON_DEBUG_VERBOSE(fmt, args...) do { \ - if (g_common_debug_verbose) { \ - printk(KERN_ERR "[RAGILE_COMMON][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define RAGILE_COMMON_DEBUG_ERROR(fmt, args...) do { \ - if (g_common_debug_error) { \ - printk(KERN_ERR "[RAGILE_COMMON][ERROR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - - -int dfd_get_my_card_type(void) -{ - int type; - int cnt; - - if (dfd_my_type != 0) { - RAGILE_COMMON_DEBUG_VERBOSE("my_type = 0x%x\r\n", dfd_my_type); - return dfd_my_type; - } - - return -1; -} -EXPORT_SYMBOL(dfd_get_my_card_type); - -static int __init ragile_common_init(void) -{ - int ret; - - RAGILE_COMMON_DEBUG_VERBOSE("Enter.\n"); - ret = dfd_get_my_card_type(); - if (ret <= 0) { - RAGILE_COMMON_DEBUG_ERROR("dfd_get_my_card_type failed, ret %d.\n", ret); - printk(KERN_ERR "Warning: Device type get failed, please check the TLV-EEPROM!\n"); - return -1; - } - - RAGILE_COMMON_DEBUG_VERBOSE("Leave success type 0x%x.\n", ret); - return 0; -} - -static void __exit ragile_common_exit(void) -{ - RAGILE_COMMON_DEBUG_VERBOSE("Exit.\n"); -} - -module_init(ragile_common_init); -module_exit(ragile_common_exit); - -MODULE_DESCRIPTION("ragile Platform Support"); -MODULE_AUTHOR("support "); -MODULE_LICENSE("GPL"); - diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/ragile_platform.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/ragile_platform.c deleted file mode 100755 index 5d9908f8c3e2..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/ragile_platform.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * ragile_platform.c - A driver for ragile platform module - * - * Copyright (c) 2019 - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PLATFORM_I2C_RETRY_TIMES (3) - -s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < PLATFORM_I2C_RETRY_TIMES; try ++) { - if ((ret = i2c_smbus_read_byte_data(client, command)) >= 0) - break; - } - return ret; -} -EXPORT_SYMBOL(platform_i2c_smbus_read_byte_data); - -s32 platform_i2c_smbus_read_i2c_block_data(const struct i2c_client *client, - u8 command, u8 length, u8 *values) -{ - int try ; - s32 ret; - - ret = -1; - for (try = 0; try < PLATFORM_I2C_RETRY_TIMES; try ++) { - if ((ret = i2c_smbus_read_i2c_block_data(client, command, length, values)) >= 0) - break; - } - return ret; -} -EXPORT_SYMBOL(platform_i2c_smbus_read_i2c_block_data); - -s32 platform_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < PLATFORM_I2C_RETRY_TIMES; try ++) { - if ((ret = i2c_smbus_read_word_data(client, command)) >= 0) - break; - } - return ret; -} -EXPORT_SYMBOL(platform_i2c_smbus_read_word_data); - -static int __init ragile_platform_init(void) -{ - return 0; -} - -static void __exit ragile_platform_exit(void) -{ - return; -} - -module_init(ragile_platform_init); -module_exit(ragile_platform_exit); - -MODULE_DESCRIPTION("ragile Platform Support"); -MODULE_AUTHOR("support "); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-gpio-xeon.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-gpio-xeon.c deleted file mode 100755 index 84b62c50ab0b..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-gpio-xeon.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * GPIO interface for XEON Super I/O chip - * - * Author: support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License 2 as published - * by the Free Software Foundation. - * - * 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; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GPIO_NAME "xeon-gpio" -#define GPIO_IOSIZE 7 -#define GPIO_BASE 0x500 - -#define GPIO_USE_SEL GPIO_BASE -#define GP_IO_SEL (GPIO_BASE+0x4) -#define GP_LVL (GPIO_BASE+0xC) - -#define GPIO_USE_SEL2 (GPIO_BASE+0x30) -#define GP_IO_SEL2 (GPIO_BASE+0x34) -#define GP_LVL2 (GPIO_BASE+0x38) - -#define GPIO_USE_SEL3 (GPIO_BASE+0x40) -#define GP_IO_SEL3 (GPIO_BASE+0x44) -#define GP_LVL3 (GPIO_BASE+0x48) - - -#define GPIO_BASE_ID 0 -#define BANKSIZE 32 - -#define GPIO_SDA 17 -#define GPIO_SCL 1 - -#define GPIO_XEON_SPIN_LOCK(lock, flags) spin_lock_irqsave(&(lock), (flags)) -#define GPIO_XEON_SPIN_UNLOCK(lock, flags) spin_unlock_irqrestore(&(lock), (flags)) -static DEFINE_SPINLOCK(sio_lock); - -/****************** i2c adapter with gpio ***********************/ - -static struct i2c_gpio_platform_data i2c_pdata = { - .timeout = 200, - .udelay = 10, - .scl_is_output_only = 0, - .sda_is_open_drain = 0, - .scl_is_open_drain = 0, -}; - -static struct gpiod_lookup_table rg_gpio_lookup_table = { - .dev_id = "i2c-gpio", - .table = { - GPIO_LOOKUP(GPIO_NAME, GPIO_SDA, "sda", - GPIO_ACTIVE_HIGH), - GPIO_LOOKUP(GPIO_NAME, GPIO_SCL, "scl", - GPIO_ACTIVE_HIGH), - }, -}; - -static void i2c_gpio_release(struct device *dev) -{ - return; -} - -static struct platform_device i2c_gpio = { - .name = "i2c-gpio", - .num_resources = 0, - .id = -1, - - .dev = { - .platform_data = &i2c_pdata, - .release = i2c_gpio_release, - } -}; - -static int xeon_gpio_get(struct gpio_chip *gc, unsigned gpio_num) -{ - unsigned int data; - unsigned int bank, offset; - unsigned long flags; - - data = 0; - bank = gpio_num / BANKSIZE; - offset = gpio_num % BANKSIZE; - - GPIO_XEON_SPIN_LOCK(sio_lock, flags); - if (bank == 0) { - data = inl(GP_LVL) & (1 << offset); - if (data) { - data = 1; - } - } else if (bank == 1) { - data = inl(GP_LVL2) & (1 << offset); - if (data) { - data = 1; - } - } else if (bank == 2) { - data = inl(GP_LVL3) & (1 << offset); - if (data) { - data = 1; - } - } - GPIO_XEON_SPIN_UNLOCK(sio_lock, flags); - - return data; -} - -static int xeon_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num) -{ - unsigned int data; - unsigned int bank, offset; - unsigned long flags; - - bank = gpio_num / BANKSIZE; - offset = gpio_num % BANKSIZE; - - GPIO_XEON_SPIN_LOCK(sio_lock, flags); - if (bank == 0) { - data = inl(GP_IO_SEL); - data = data | (1 << offset); - outl(data, GP_IO_SEL); - } else if (bank == 1) { - data = inl(GP_IO_SEL2); - data = data | (1 << offset); - outl(data, GP_IO_SEL2); - } else if (bank == 2) { - data = inl(GP_IO_SEL3); - data = data | (1 << offset); - outl(data, GP_IO_SEL3); - } - GPIO_XEON_SPIN_UNLOCK(sio_lock, flags); - - return 0; -} - -static void xeon_gpio_set(struct gpio_chip *gc, - unsigned gpio_num, int val) -{ - unsigned int data; - unsigned int bank, offset; - unsigned long flags; - - bank = gpio_num / BANKSIZE; - offset = gpio_num % BANKSIZE; - - GPIO_XEON_SPIN_LOCK(sio_lock, flags); - if (bank == 0) { - data = inl(GP_LVL); - if (val) { - data = data | (1 << offset); - } else { - data = data & ~(1 << offset); - } - outl(data, GP_LVL); - } else if (bank == 1) { - data = inl(GP_LVL2); - if (val) { - data = data | (1 << offset); - } else { - data = data & ~(1 << offset); - } - outl(data, GP_LVL2); - } else if (bank == 2) { - data = inl(GP_LVL3); - if (val) { - data = data | (1 << offset); - } else { - data = data & ~(1 << offset); - } - outl(data, GP_LVL3); - } - GPIO_XEON_SPIN_UNLOCK(sio_lock, flags); -} - -static int xeon_gpio_direction_out(struct gpio_chip *gc, - unsigned gpio_num, int val) -{ - unsigned int data; - unsigned int bank, offset; - unsigned long flags; - - bank = gpio_num / BANKSIZE; - offset = gpio_num % BANKSIZE; - - GPIO_XEON_SPIN_LOCK(sio_lock, flags); - if (bank == 0) { - data = inl(GP_IO_SEL); - data = data & ~(1 << offset); - outl(data, GP_IO_SEL); - - data = inl(GP_LVL); - if (val) { - data = data | (1 << offset); - } else { - data = data & ~(1 << offset); - } - outl(data, GP_LVL); - } else if (bank == 1) { - data = inl(GP_IO_SEL2); - data = data & ~(1 << offset); - outl(data, GP_IO_SEL2); - - data = inl(GP_LVL2); - if (val) { - data = data | (1 << offset); - } else { - data = data & ~(1 << offset); - } - outl(data, GP_LVL2); - } else if (bank == 2) { - data = inl(GP_IO_SEL3); - data = data & ~(1 << offset); - outl(data, GP_IO_SEL3); - - data = inl(GP_LVL3); - if (val) { - data = data | (1 << offset); - } else { - data = data & ~(1 << offset); - } - outl(data, GP_LVL3); - } - GPIO_XEON_SPIN_UNLOCK(sio_lock, flags); - - return 0; -} - -static int xeon_gpio_request(struct gpio_chip *chip, unsigned int offset) -{ - unsigned int data; - unsigned int bank, tmp_offset; - unsigned long flags; - - bank = offset / BANKSIZE; - tmp_offset = offset % BANKSIZE; - - GPIO_XEON_SPIN_LOCK(sio_lock, flags); - if (bank == 0) { - data = inl(GPIO_USE_SEL); - data = data | (1 << tmp_offset); - outl(data, GPIO_USE_SEL); - } else if (bank == 1) { - data = inl(GPIO_USE_SEL2); - data = data | (1 << tmp_offset); - outl(data, GPIO_USE_SEL2); - } else if (bank == 2) { - data = inl(GPIO_USE_SEL3); - data = data | (1 << tmp_offset); - outl(data, GPIO_USE_SEL3); - } - GPIO_XEON_SPIN_UNLOCK(sio_lock, flags); - return 0; -} - -static void xeon_gpio_free(struct gpio_chip *chip, unsigned int offset) -{ - unsigned int data; - unsigned int bank, tmp_offset; - unsigned long flags; - - bank = offset / BANKSIZE; - tmp_offset = offset % BANKSIZE; - - GPIO_XEON_SPIN_LOCK(sio_lock, flags); - if (bank == 0) { - data = inl(GPIO_USE_SEL); - data = data & ~(1 << tmp_offset); - outl(data, GPIO_USE_SEL); - } else if (bank == 1) { - data = inl(GPIO_USE_SEL2); - data = data & ~(1 << tmp_offset); - outl(data, GPIO_USE_SEL2); - } else if (bank == 2) { - data = inl(GPIO_USE_SEL3); - data = data & ~(1 << tmp_offset); - outl(data, GPIO_USE_SEL3); - } - GPIO_XEON_SPIN_UNLOCK(sio_lock, flags); -} - -static struct gpio_chip xeon_gpio_chip = { - .label = GPIO_NAME, - .owner = THIS_MODULE, - .get = xeon_gpio_get, - .direction_input = xeon_gpio_direction_in, - .set = xeon_gpio_set, - .direction_output = xeon_gpio_direction_out, - .request = xeon_gpio_request, - .free = xeon_gpio_free, -}; - -static int __init xeon_gpio_init(void) -{ - int err; - if (!request_region(GPIO_BASE, GPIO_IOSIZE, GPIO_NAME)) - return -EBUSY; - - xeon_gpio_chip.base = GPIO_BASE_ID; - xeon_gpio_chip.ngpio = 96; - - err = gpiochip_add_data(&xeon_gpio_chip, NULL); - if (err < 0) - goto gpiochip_add_err; - gpiod_add_lookup_table(&rg_gpio_lookup_table); - err = platform_device_register(&i2c_gpio); - if (err < 0) { - goto i2c_get_adapter_err; - } - return 0; - -i2c_get_adapter_err: - gpiod_remove_lookup_table(&rg_gpio_lookup_table); - platform_device_unregister(&i2c_gpio); - gpiochip_remove(&xeon_gpio_chip); - -gpiochip_add_err: - release_region(GPIO_BASE, GPIO_IOSIZE); - return -1; -} - -static void __exit xeon_gpio_exit(void) -{ - gpiod_remove_lookup_table(&rg_gpio_lookup_table); - platform_device_unregister(&i2c_gpio); - mdelay(100); - gpiochip_remove(&xeon_gpio_chip); - release_region(GPIO_BASE, GPIO_IOSIZE); -} - -module_init(xeon_gpio_init); -module_exit(xeon_gpio_exit); - -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("GPIO interface for XEON Super I/O chip"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-i2c-algo-bit.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-i2c-algo-bit.c deleted file mode 100644 index 5e8f2c29d2a0..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-i2c-algo-bit.c +++ /dev/null @@ -1,734 +0,0 @@ -/* ------------------------------------------------------------------------- - * i2c-algo-bit.c i2c driver algorithms for bit-shift adapters - * ------------------------------------------------------------------------- - * Copyright (C) 1995-2000 Simon G. Vogl - - 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. - * ------------------------------------------------------------------------- */ - -/* With some changes from Frodo Looijaard , Kyösti Mälkki - and Jean Delvare */ - -#include -#include -#include -#include -#include -#include -#include - - -/* ----- global defines ----------------------------------------------- */ - -#ifdef DEBUG -#define bit_dbg(level, dev, format, args...) \ - do { \ - if (i2c_debug >= level) \ - dev_dbg(dev, format, ##args); \ - } while (0) -#else -#define bit_dbg(level, dev, format, args...) \ - do {} while (0) -#endif /* DEBUG */ - -/* ----- global variables --------------------------------------------- */ - -static int bit_test; /* see if the line-setting functions work */ -module_param(bit_test, int, S_IRUGO); -MODULE_PARM_DESC(bit_test, "lines testing - 0 off; 1 report; 2 fail if stuck"); - -#ifdef DEBUG -static int i2c_debug = 1; -module_param(i2c_debug, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(i2c_debug, - "debug level - 0 off; 1 normal; 2 verbose; 3 very verbose"); -#endif - -/* --- setting states on the bus with the right timing: --------------- */ - -#define setsda(adap, val) adap->setsda(adap->data, val) -#define setscl(adap, val) adap->setscl(adap->data, val) -#define getsda(adap) adap->getsda(adap->data) -#define getscl(adap) adap->getscl(adap->data) - -static inline void sdalo(struct i2c_algo_bit_data *adap) -{ - setsda(adap, 0); - udelay((adap->udelay + 1) / 2); -} - -static inline void sdahi(struct i2c_algo_bit_data *adap) -{ - setsda(adap, 1); - udelay((adap->udelay + 1) / 2); -} - -static inline void scllo(struct i2c_algo_bit_data *adap) -{ - setscl(adap, 0); - udelay(adap->udelay / 2); -} - -/* - * Raise scl line, and do checking for delays. This is necessary for slower - * devices. - */ -static int sclhi(struct i2c_algo_bit_data *adap) -{ - unsigned long start; - - setscl(adap, 1); - - /* Not all adapters have scl sense line... */ - if (!adap->getscl) - goto done; - - start = jiffies; - while (!getscl(adap)) { - /* This hw knows how to read the clock line, so we wait - * until it actually gets high. This is safer as some - * chips may hold it low ("clock stretching") while they - * are processing data internally. - */ - if (time_after(jiffies, start + adap->timeout)) { - /* Test one last time, as we may have been preempted - * between last check and timeout test. - */ - if (getscl(adap)) - break; - return -ETIMEDOUT; - } - cpu_relax(); - } -#ifdef DEBUG - if (jiffies != start && i2c_debug >= 3) - pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go high\n", - jiffies - start); -#endif - -done: - udelay(adap->udelay); - return 0; -} - - -/* --- other auxiliary functions -------------------------------------- */ -static void i2c_start(struct i2c_algo_bit_data *adap) -{ - /* assert: scl, sda are high */ - setsda(adap, 0); - udelay(adap->udelay); - scllo(adap); -} - -static void i2c_repstart(struct i2c_algo_bit_data *adap) -{ - /* assert: scl is low */ - sdahi(adap); - sclhi(adap); - setsda(adap, 0); - udelay(adap->udelay); - scllo(adap); -} - - -static void i2c_stop(struct i2c_algo_bit_data *adap) -{ - /* assert: scl is low */ - sdalo(adap); - sclhi(adap); - setsda(adap, 1); - udelay(adap->udelay); -} - - - -/* send a byte without start cond., look for arbitration, - check ackn. from slave */ -/* returns: - * 1 if the device acknowledged - * 0 if the device did not ack - * -ETIMEDOUT if an error occurred (while raising the scl line) - */ -static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) -{ - int i; - int sb; - int ack; - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - - /* assert: scl is low */ - for (i = 7; i >= 0; i--) { - sb = (c >> i) & 1; - setsda(adap, sb); - udelay((adap->udelay + 1) / 2); - if (sclhi(adap) < 0) { /* timed out */ - bit_dbg(1, &i2c_adap->dev, - "i2c_outb: 0x%02x, timeout at bit #%d\n", - (int)c, i); - return -ETIMEDOUT; - } - /* FIXME do arbitration here: - * if (sb && !getsda(adap)) -> ouch! Get out of here. - * - * Report a unique code, so higher level code can retry - * the whole (combined) message and *NOT* issue STOP. - */ - scllo(adap); - } - sdahi(adap); - if (sclhi(adap) < 0) { /* timeout */ - bit_dbg(1, &i2c_adap->dev, - "i2c_outb: 0x%02x, timeout at ack\n", (int)c); - return -ETIMEDOUT; - } - - /* read ack: SDA should be pulled down by slave, or it may - * NAK (usually to report problems with the data we wrote). - */ - ack = !getsda(adap); /* ack: sda is pulled low -> success */ - bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, - ack ? "A" : "NA"); - - scllo(adap); - return ack; - /* assert: scl is low (sda undef) */ -} - - -static int i2c_inb(struct i2c_adapter *i2c_adap) -{ - /* read byte via i2c port, without start/stop sequence */ - /* acknowledge is sent in i2c_read. */ - int i; - unsigned char indata = 0; - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - - /* assert: scl is low */ - sdahi(adap); - for (i = 0; i < 8; i++) { - if (sclhi(adap) < 0) { /* timeout */ - bit_dbg(1, &i2c_adap->dev, - "i2c_inb: timeout at bit #%d\n", - 7 - i); - return -ETIMEDOUT; - } - indata *= 2; - if (getsda(adap)) - indata |= 0x01; - setscl(adap, 0); - udelay(i == 7 ? adap->udelay / 2 : adap->udelay); - } - /* assert: scl is low */ - return indata; -} - -/* - * Sanity check for the adapter hardware - check the reaction of - * the bus lines only if it seems to be idle. - */ -static int test_bus(struct i2c_adapter *i2c_adap) -{ - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - const char *name = i2c_adap->name; - int scl, sda, ret; - - if (adap->pre_xfer) { - ret = adap->pre_xfer(i2c_adap); - if (ret < 0) - return -ENODEV; - } - - if (adap->getscl == NULL) - pr_info("%s: Testing SDA only, SCL is not readable\n", name); - - sda = getsda(adap); - scl = (adap->getscl == NULL) ? 1 : getscl(adap); - if (!scl || !sda) { - printk(KERN_WARNING - "%s: bus seems to be busy (scl=%d, sda=%d)\n", - name, scl, sda); - goto bailout; - } - - sdalo(adap); - sda = getsda(adap); - scl = (adap->getscl == NULL) ? 1 : getscl(adap); - if (sda) { - printk(KERN_WARNING "%s: SDA stuck high!\n", name); - goto bailout; - } - if (!scl) { - printk(KERN_WARNING - "%s: SCL unexpected low while pulling SDA low!\n", - name); - goto bailout; - } - - sdahi(adap); - sda = getsda(adap); - scl = (adap->getscl == NULL) ? 1 : getscl(adap); - if (!sda) { - printk(KERN_WARNING "%s: SDA stuck low!\n", name); - goto bailout; - } - if (!scl) { - printk(KERN_WARNING - "%s: SCL unexpected low while pulling SDA high!\n", - name); - goto bailout; - } - - scllo(adap); - sda = getsda(adap); - scl = (adap->getscl == NULL) ? 0 : getscl(adap); - if (scl) { - printk(KERN_WARNING "%s: SCL stuck high!\n", name); - goto bailout; - } - if (!sda) { - printk(KERN_WARNING - "%s: SDA unexpected low while pulling SCL low!\n", - name); - goto bailout; - } - - sclhi(adap); - sda = getsda(adap); - scl = (adap->getscl == NULL) ? 1 : getscl(adap); - if (!scl) { - printk(KERN_WARNING "%s: SCL stuck low!\n", name); - goto bailout; - } - if (!sda) { - printk(KERN_WARNING - "%s: SDA unexpected low while pulling SCL high!\n", - name); - goto bailout; - } - - if (adap->post_xfer) - adap->post_xfer(i2c_adap); - - pr_info("%s: Test OK\n", name); - return 0; -bailout: - sdahi(adap); - sclhi(adap); - - if (adap->post_xfer) - adap->post_xfer(i2c_adap); - - return -ENODEV; -} - -/* ----- Utility functions -*/ - -/* try_address tries to contact a chip for a number of - * times before it gives up. - * return values: - * 1 chip answered - * 0 chip did not answer - * -x transmission error - */ -static int try_address(struct i2c_adapter *i2c_adap, - unsigned char addr, int retries) -{ - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - int i, ret = 0; - - for (i = 0; i <= retries; i++) { - ret = i2c_outb(i2c_adap, addr); - if (ret == 1 || i == retries) - break; - bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); - i2c_stop(adap); - udelay(adap->udelay); - yield(); - bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); - i2c_start(adap); - } - if (i && ret) - bit_dbg(1, &i2c_adap->dev, - "Used %d tries to %s client at 0x%02x: %s\n", i + 1, - addr & 1 ? "read from" : "write to", addr >> 1, - ret == 1 ? "success" : "failed, timeout?"); - return ret; -} - -static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) -{ - const unsigned char *temp = msg->buf; - int count = msg->len; - unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; - int retval; - int wrcount = 0; - - while (count > 0) { - retval = i2c_outb(i2c_adap, *temp); - - /* OK/ACK; or ignored NAK */ - if ((retval > 0) || (nak_ok && (retval == 0))) { - count--; - temp++; - wrcount++; - - /* A slave NAKing the master means the slave didn't like - * something about the data it saw. For example, maybe - * the SMBus PEC was wrong. - */ - } else if (retval == 0) { - dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n"); - return -EIO; - - /* Timeout; or (someday) lost arbitration - * - * FIXME Lost ARB implies retrying the transaction from - * the first message, after the "winning" master issues - * its STOP. As a rule, upper layer code has no reason - * to know or care about this ... it is *NOT* an error. - */ - } else { - dev_err(&i2c_adap->dev, "sendbytes: error %d\n", - retval); - return retval; - } - } - return wrcount; -} - -static int acknak(struct i2c_adapter *i2c_adap, int is_ack) -{ - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - - /* assert: sda is high */ - if (is_ack) /* send ack */ - setsda(adap, 0); - udelay((adap->udelay + 1) / 2); - if (sclhi(adap) < 0) { /* timeout */ - dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n"); - return -ETIMEDOUT; - } - scllo(adap); - return 0; -} - -static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) -{ - int inval; - int rdcount = 0; /* counts bytes read */ - unsigned char *temp = msg->buf; - int count = msg->len; - const unsigned flags = msg->flags; - - while (count > 0) { - inval = i2c_inb(i2c_adap); - if (inval >= 0) { - *temp = inval; - rdcount++; - } else { /* read timed out */ - break; - } - - temp++; - count--; - - /* Some SMBus transactions require that we receive the - transaction length as the first read byte. */ - if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) { - if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { - if (!(flags & I2C_M_NO_RD_ACK)) - acknak(i2c_adap, 0); - dev_err(&i2c_adap->dev, - "readbytes: invalid block length (%d)\n", - inval); - return -EPROTO; - } - /* The original count value accounts for the extra - bytes, that is, either 1 for a regular transaction, - or 2 for a PEC transaction. */ - count += inval; - msg->len += inval; - } - - bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n", - inval, - (flags & I2C_M_NO_RD_ACK) - ? "(no ack/nak)" - : (count ? "A" : "NA")); - - if (!(flags & I2C_M_NO_RD_ACK)) { - inval = acknak(i2c_adap, count); - if (inval < 0) - return inval; - } - } - return rdcount; -} - -/* doAddress initiates the transfer by generating the start condition (in - * try_address) and transmits the address in the necessary format to handle - * reads, writes as well as 10bit-addresses. - * returns: - * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set - * -x an error occurred (like: -ENXIO if the device did not answer, or - * -ETIMEDOUT, for example if the lines are stuck...) - */ -static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) -{ - unsigned short flags = msg->flags; - unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - - unsigned char addr; - int ret, retries; - - retries = nak_ok ? 0 : i2c_adap->retries; - - if (flags & I2C_M_TEN) { - /* a ten bit address */ - addr = 0xf0 | ((msg->addr >> 7) & 0x06); - bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); - /* try extended address code...*/ - ret = try_address(i2c_adap, addr, retries); - if ((ret != 1) && !nak_ok) { - dev_err(&i2c_adap->dev, - "died at extended address code\n"); - return -ENXIO; - } - /* the remaining 8 bit address */ - ret = i2c_outb(i2c_adap, msg->addr & 0xff); - if ((ret != 1) && !nak_ok) { - /* the chip did not ack / xmission error occurred */ - dev_err(&i2c_adap->dev, "died at 2nd address code\n"); - return -ENXIO; - } - if (flags & I2C_M_RD) { - bit_dbg(3, &i2c_adap->dev, - "emitting repeated start condition\n"); - i2c_repstart(adap); - /* okay, now switch into reading mode */ - addr |= 0x01; - ret = try_address(i2c_adap, addr, retries); - if ((ret != 1) && !nak_ok) { - dev_err(&i2c_adap->dev, - "died at repeated address code\n"); - return -EIO; - } - } - } else { /* normal 7bit address */ - addr = i2c_8bit_addr_from_msg(msg); - if (flags & I2C_M_REV_DIR_ADDR) - addr ^= 1; - ret = try_address(i2c_adap, addr, retries); - if ((ret != 1) && !nak_ok) - return -ENXIO; - } - - return 0; -} - -static void bit_i2c_unblock(struct i2c_adapter *i2c_adap) -{ - int i; - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - - for (i = 0; i < 9; i++) { - setscl(adap, 0); - udelay(5); - setscl(adap, 1); - udelay(5); - } - setscl(adap, 0); - setsda(adap, 0); - udelay(5); - setscl(adap, 1); - udelay(5); - setsda(adap, 1); -} - -static int check_bit_i2c_unblock(struct i2c_adapter *i2c_adap) -{ - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - int sda, scl; - - sda = getsda(adap); - scl = getscl(adap); - if ((sda == 0) && scl) { - // I2C_ALGO_BIT_ERROR("SCL is high and SDA is low, send 9 clock to device.\n"); - bit_i2c_unblock(i2c_adap); - } - - sda = getsda(adap); - scl = getscl(adap); - if (sda && scl) { - // I2C_ALGO_BIT_DEBUG("SCL and SDA are both high, i2c level check ok.\n"); - return 0; - } - dev_warn(&i2c_adap->dev, "Check i2c level failed, SCL %s, SDA %s.\n", scl ? "high" : "low", sda ? "high" : "low"); - return -EIO; -} - -static int bit_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], int num) -{ - struct i2c_msg *pmsg; - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - int i, ret; - unsigned short nak_ok; - - if (adap->pre_xfer) { - ret = adap->pre_xfer(i2c_adap); - if (ret < 0) - return ret; - } - - if (check_bit_i2c_unblock(i2c_adap) < 0) { - // I2C_ALGO_BIT_ERROR("check i2c is block.\n"); - return -EIO; - } - - bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); - i2c_start(adap); - for (i = 0; i < num; i++) { - pmsg = &msgs[i]; - nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; - if (!(pmsg->flags & I2C_M_NOSTART)) { - if (i) { - if (msgs[i - 1].flags & I2C_M_STOP) { - bit_dbg(3, &i2c_adap->dev, - "emitting enforced stop/start condition\n"); - i2c_stop(adap); - i2c_start(adap); - } else { - bit_dbg(3, &i2c_adap->dev, - "emitting repeated start condition\n"); - i2c_repstart(adap); - } - } - ret = bit_doAddress(i2c_adap, pmsg); - if ((ret != 0) && !nak_ok) { - bit_dbg(1, &i2c_adap->dev, - "NAK from device addr 0x%02x msg #%d\n", - msgs[i].addr, i); - goto bailout; - } - } - if (pmsg->flags & I2C_M_RD) { - /* read bytes into buffer*/ - ret = readbytes(i2c_adap, pmsg); - if (ret >= 1) - bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n", - ret, ret == 1 ? "" : "s"); - if (ret < pmsg->len) { - if (ret >= 0) - ret = -EIO; - goto bailout; - } - } else { - /* write bytes from buffer */ - ret = sendbytes(i2c_adap, pmsg); - if (ret >= 1) - bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n", - ret, ret == 1 ? "" : "s"); - if (ret < pmsg->len) { - if (ret >= 0) - ret = -EIO; - goto bailout; - } - } - } - ret = i; - -bailout: - bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); - i2c_stop(adap); - - if (adap->post_xfer) - adap->post_xfer(i2c_adap); - return ret; -} - -static u32 bit_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL | - I2C_FUNC_SMBUS_READ_BLOCK_DATA | - I2C_FUNC_SMBUS_BLOCK_PROC_CALL | - I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; -} - - -/* -----exported algorithm data: ------------------------------------- */ - -const struct i2c_algorithm rg_i2c_bit_algo = { - .master_xfer = bit_xfer, - .functionality = bit_func, -}; -EXPORT_SYMBOL(rg_i2c_bit_algo); - -static const struct i2c_adapter_quirks i2c_bit_quirk_no_clk_stretch = { - .flags = I2C_AQ_NO_CLK_STRETCH, -}; - -/* - * registering functions to load algorithms at runtime - */ -static int __i2c_bit_add_bus(struct i2c_adapter *adap, - int (*add_adapter)(struct i2c_adapter *)) -{ - struct i2c_algo_bit_data *bit_adap = adap->algo_data; - int ret; - - if (bit_test) { - ret = test_bus(adap); - if (bit_test >= 2 && ret < 0) - return -ENODEV; - } - - /* register new adapter to i2c module... */ - adap->algo = &rg_i2c_bit_algo; - adap->retries = 3; - if (bit_adap->getscl == NULL) - adap->quirks = &i2c_bit_quirk_no_clk_stretch; - - /* - * We tried forcing SCL/SDA to an initial state here. But that caused a - * regression, sadly. Check Bugzilla #200045 for details. - */ - - ret = add_adapter(adap); - if (ret < 0) - return ret; - - /* Complain if SCL can't be read */ - if (bit_adap->getscl == NULL) { - dev_warn(&adap->dev, "Not I2C compliant: can't read SCL\n"); - dev_warn(&adap->dev, "Bus may be unreliable\n"); - } - return 0; -} - -int rg_i2c_bit_add_bus(struct i2c_adapter *adap) -{ - return __i2c_bit_add_bus(adap, i2c_add_adapter); -} -EXPORT_SYMBOL(rg_i2c_bit_add_bus); - -int rg_i2c_bit_add_numbered_bus(struct i2c_adapter *adap) -{ - return __i2c_bit_add_bus(adap, i2c_add_numbered_adapter); -} -EXPORT_SYMBOL(rg_i2c_bit_add_numbered_bus); - -MODULE_AUTHOR("Simon G. Vogl "); -MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-i2c-gpio.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-i2c-gpio.c deleted file mode 100644 index bce3afac61a5..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg-i2c-gpio.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Bitbanging I2C bus driver using the GPIO API - * - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int rg_i2c_bit_add_numbered_bus(struct i2c_adapter *adap); - -struct i2c_gpio_private_data { - struct gpio_desc *sda; - struct gpio_desc *scl; - struct i2c_adapter adap; - struct i2c_algo_bit_data bit_data; - struct i2c_gpio_platform_data pdata; -#ifdef CONFIG_I2C_GPIO_FAULT_INJECTOR - struct dentry *debug_dir; -#endif -}; - -/* - * Toggle SDA by changing the output value of the pin. This is only - * valid for pins configured as open drain (i.e. setting the value - * high effectively turns off the output driver.) - */ -static void i2c_gpio_setsda_val(void *data, int state) -{ - struct i2c_gpio_private_data *priv = data; - - gpiod_set_value_cansleep(priv->sda, state); -} - -/* - * Toggle SCL by changing the output value of the pin. This is used - * for pins that are configured as open drain and for output-only - * pins. The latter case will break the i2c protocol, but it will - * often work in practice. - */ -static void i2c_gpio_setscl_val(void *data, int state) -{ - struct i2c_gpio_private_data *priv = data; - - gpiod_set_value_cansleep(priv->scl, state); -} - -static int i2c_gpio_getsda(void *data) -{ - struct i2c_gpio_private_data *priv = data; - - return gpiod_get_value_cansleep(priv->sda); -} - -static int i2c_gpio_getscl(void *data) -{ - struct i2c_gpio_private_data *priv = data; - - return gpiod_get_value_cansleep(priv->scl); -} - -#ifdef CONFIG_I2C_GPIO_FAULT_INJECTOR -static struct dentry *i2c_gpio_debug_dir; - -#define setsda(bd, val) ((bd)->setsda((bd)->data, val)) -#define setscl(bd, val) ((bd)->setscl((bd)->data, val)) -#define getsda(bd) ((bd)->getsda((bd)->data)) -#define getscl(bd) ((bd)->getscl((bd)->data)) - -#define WIRE_ATTRIBUTE(wire) \ - static int fops_##wire##_get(void *data, u64 *val) \ -{ \ - struct i2c_gpio_private_data *priv = data; \ - \ - i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ - *val = get##wire(&priv->bit_data); \ - i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ - return 0; \ -} \ -static int fops_##wire##_set(void *data, u64 val) \ -{ \ - struct i2c_gpio_private_data *priv = data; \ - \ - i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ - set##wire(&priv->bit_data, val); \ - i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); \ - return 0; \ -} \ -DEFINE_DEBUGFS_ATTRIBUTE(fops_##wire, fops_##wire##_get, fops_##wire##_set, "%llu\n") - -WIRE_ATTRIBUTE(scl); -WIRE_ATTRIBUTE(sda); - -static void i2c_gpio_incomplete_transfer(struct i2c_gpio_private_data *priv, - u32 pattern, u8 pattern_size) -{ - struct i2c_algo_bit_data *bit_data = &priv->bit_data; - int i; - - i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); - - /* START condition */ - setsda(bit_data, 0); - udelay(bit_data->udelay); - - /* Send pattern, request ACK, don't send STOP */ - for (i = pattern_size - 1; i >= 0; i--) { - setscl(bit_data, 0); - udelay(bit_data->udelay / 2); - setsda(bit_data, (pattern >> i) & 1); - udelay((bit_data->udelay + 1) / 2); - setscl(bit_data, 1); - udelay(bit_data->udelay); - } - - i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER); -} - -static int fops_incomplete_addr_phase_set(void *data, u64 addr) -{ - struct i2c_gpio_private_data *priv = data; - u32 pattern; - - if (addr > 0x7f) - return -EINVAL; - - /* ADDR (7 bit) + RD (1 bit) + Client ACK, keep SDA hi (1 bit) */ - pattern = (addr << 2) | 3; - - i2c_gpio_incomplete_transfer(priv, pattern, 9); - - return 0; -} -DEFINE_DEBUGFS_ATTRIBUTE(fops_incomplete_addr_phase, NULL, fops_incomplete_addr_phase_set, "%llu\n"); - -static int fops_incomplete_write_byte_set(void *data, u64 addr) -{ - struct i2c_gpio_private_data *priv = data; - u32 pattern; - - if (addr > 0x7f) - return -EINVAL; - - /* ADDR (7 bit) + WR (1 bit) + Client ACK (1 bit) */ - pattern = (addr << 2) | 1; - /* 0x00 (8 bit) + Client ACK, keep SDA hi (1 bit) */ - pattern = (pattern << 9) | 1; - - i2c_gpio_incomplete_transfer(priv, pattern, 18); - - return 0; -} -DEFINE_DEBUGFS_ATTRIBUTE(fops_incomplete_write_byte, NULL, fops_incomplete_write_byte_set, "%llu\n"); - -static void i2c_gpio_fault_injector_init(struct platform_device *pdev) -{ - struct i2c_gpio_private_data *priv = platform_get_drvdata(pdev); - - /* - * If there will be a debugfs-dir per i2c adapter somewhen, put the - * 'fault-injector' dir there. Until then, we have a global dir with - * all adapters as subdirs. - */ - if (!i2c_gpio_debug_dir) { - i2c_gpio_debug_dir = debugfs_create_dir("i2c-fault-injector", NULL); - if (!i2c_gpio_debug_dir) - return; - } - - priv->debug_dir = debugfs_create_dir(pdev->name, i2c_gpio_debug_dir); - if (!priv->debug_dir) - return; - - debugfs_create_file_unsafe("scl", 0600, priv->debug_dir, priv, &fops_scl); - debugfs_create_file_unsafe("sda", 0600, priv->debug_dir, priv, &fops_sda); - debugfs_create_file_unsafe("incomplete_address_phase", 0200, priv->debug_dir, - priv, &fops_incomplete_addr_phase); - debugfs_create_file_unsafe("incomplete_write_byte", 0200, priv->debug_dir, - priv, &fops_incomplete_write_byte); -} - -static void i2c_gpio_fault_injector_exit(struct platform_device *pdev) -{ - struct i2c_gpio_private_data *priv = platform_get_drvdata(pdev); - - debugfs_remove_recursive(priv->debug_dir); -} -#else -static inline void i2c_gpio_fault_injector_init(struct platform_device *pdev) {} -static inline void i2c_gpio_fault_injector_exit(struct platform_device *pdev) {} -#endif /* CONFIG_I2C_GPIO_FAULT_INJECTOR*/ - -static void of_i2c_gpio_get_props(struct device_node *np, - struct i2c_gpio_platform_data *pdata) -{ - u32 reg; - - of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay); - - if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", ®)) - pdata->timeout = msecs_to_jiffies(reg); - - pdata->sda_is_open_drain = - of_property_read_bool(np, "i2c-gpio,sda-open-drain"); - pdata->scl_is_open_drain = - of_property_read_bool(np, "i2c-gpio,scl-open-drain"); - pdata->scl_is_output_only = - of_property_read_bool(np, "i2c-gpio,scl-output-only"); -} - -static struct gpio_desc *i2c_gpio_get_desc(struct device *dev, - const char *con_id, - unsigned int index, - enum gpiod_flags gflags) -{ - struct gpio_desc *retdesc; - int ret; - - retdesc = devm_gpiod_get(dev, con_id, gflags); - if (!IS_ERR(retdesc)) { - dev_dbg(dev, "got GPIO from name %s\n", con_id); - return retdesc; - } - - retdesc = devm_gpiod_get_index(dev, NULL, index, gflags); - if (!IS_ERR(retdesc)) { - dev_dbg(dev, "got GPIO from index %u\n", index); - return retdesc; - } - - ret = PTR_ERR(retdesc); - - /* FIXME: hack in the old code, is this really necessary? */ - if (ret == -EINVAL) - retdesc = ERR_PTR(-EPROBE_DEFER); - - /* This happens if the GPIO driver is not yet probed, let's defer */ - if (ret == -ENOENT) - retdesc = ERR_PTR(-EPROBE_DEFER); - - if (PTR_ERR(retdesc) != -EPROBE_DEFER) - dev_err(dev, "error trying to get descriptor: %d\n", ret); - - return retdesc; -} - -static int i2c_gpio_probe(struct platform_device *pdev) -{ - struct i2c_gpio_private_data *priv; - struct i2c_gpio_platform_data *pdata; - struct i2c_algo_bit_data *bit_data; - struct i2c_adapter *adap; - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - enum gpiod_flags gflags; - int ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - adap = &priv->adap; - bit_data = &priv->bit_data; - pdata = &priv->pdata; - - if (np) { - of_i2c_gpio_get_props(np, pdata); - } else { - /* - * If all platform data settings are zero it is OK - * to not provide any platform data from the board. - */ - if (dev_get_platdata(dev)) - memcpy(pdata, dev_get_platdata(dev), sizeof(*pdata)); - } - - /* - * First get the GPIO pins; if it fails, we'll defer the probe. - * If the SDA line is marked from platform data or device tree as - * "open drain" it means something outside of our control is making - * this line being handled as open drain, and we should just handle - * it as any other output. Else we enforce open drain as this is - * required for an I2C bus. - */ - if (pdata->sda_is_open_drain) - gflags = GPIOD_OUT_HIGH; - else - gflags = GPIOD_OUT_HIGH_OPEN_DRAIN; - priv->sda = i2c_gpio_get_desc(dev, "sda", 0, gflags); - if (IS_ERR(priv->sda)) - return PTR_ERR(priv->sda); - - /* - * If the SCL line is marked from platform data or device tree as - * "open drain" it means something outside of our control is making - * this line being handled as open drain, and we should just handle - * it as any other output. Else we enforce open drain as this is - * required for an I2C bus. - */ - if (pdata->scl_is_open_drain) - gflags = GPIOD_OUT_HIGH; - else - gflags = GPIOD_OUT_HIGH_OPEN_DRAIN; - priv->scl = i2c_gpio_get_desc(dev, "scl", 1, gflags); - if (IS_ERR(priv->scl)) - return PTR_ERR(priv->scl); - - if (gpiod_cansleep(priv->sda) || gpiod_cansleep(priv->scl)) - dev_warn(dev, "Slow GPIO pins might wreak havoc into I2C/SMBus bus timing"); - - bit_data->setsda = i2c_gpio_setsda_val; - bit_data->setscl = i2c_gpio_setscl_val; - - if (!pdata->scl_is_output_only) - bit_data->getscl = i2c_gpio_getscl; - bit_data->getsda = i2c_gpio_getsda; - - if (pdata->udelay) - bit_data->udelay = pdata->udelay; - else if (pdata->scl_is_output_only) - bit_data->udelay = 50; /* 10 kHz */ - else - bit_data->udelay = 5; /* 100 kHz */ - - if (pdata->timeout) - bit_data->timeout = pdata->timeout; - else - bit_data->timeout = HZ / 10; /* 100 ms */ - - bit_data->data = priv; - - adap->owner = THIS_MODULE; - if (np) - strlcpy(adap->name, dev_name(dev), sizeof(adap->name)); - else - snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id); - - adap->algo_data = bit_data; - adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; - adap->dev.parent = dev; - adap->dev.of_node = np; - - adap->nr = pdev->id; - ret = rg_i2c_bit_add_numbered_bus(adap); - if (ret) - return ret; - - platform_set_drvdata(pdev, priv); - - /* - * FIXME: using global GPIO numbers is not helpful. If/when we - * get accessors to get the actual name of the GPIO line, - * from the descriptor, then provide that instead. - */ - dev_info(dev, "using lines %u (SDA) and %u (SCL%s)\n", - desc_to_gpio(priv->sda), desc_to_gpio(priv->scl), - pdata->scl_is_output_only - ? ", no clock stretching" : ""); - - i2c_gpio_fault_injector_init(pdev); - - return 0; -} - -static int i2c_gpio_remove(struct platform_device *pdev) -{ - struct i2c_gpio_private_data *priv; - struct i2c_adapter *adap; - - i2c_gpio_fault_injector_exit(pdev); - - priv = platform_get_drvdata(pdev); - adap = &priv->adap; - - i2c_del_adapter(adap); - - return 0; -} - -#if defined(CONFIG_OF) -static const struct of_device_id i2c_gpio_dt_ids[] = { - { .compatible = "rg-i2c-gpio", }, - { /* sentinel */ } -}; - -MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids); -#endif - -static struct platform_driver i2c_gpio_driver = { - .driver = { - .name = "rg-i2c-gpio", - .of_match_table = of_match_ptr(i2c_gpio_dt_ids), - }, - .probe = i2c_gpio_probe, - .remove = i2c_gpio_remove, -}; - -static int __init i2c_gpio_init(void) -{ - int ret; - - ret = platform_driver_register(&i2c_gpio_driver); - if (ret) - printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); - - return ret; -} -subsys_initcall(i2c_gpio_init); - -static void __exit i2c_gpio_exit(void) -{ - platform_driver_unregister(&i2c_gpio_driver); -} -module_exit(i2c_gpio_exit); - -MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); -MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:i2c-gpio"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg_fan.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg_fan.c deleted file mode 100755 index f8a70adeee27..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg_fan.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * rg_fan.c - A driver for control rg_fan base on rg_fan.c - * - * Copyright (c) 1998, 1999 Frodo Looijaard - * Copyright (c) 2019 - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define FAN_SIZE (256) -#define SYS_FAN_BUF_LEN (64) - -typedef enum { - DBG_START, - DBG_VERBOSE, - DBG_KEY, - DBG_WARN, - DBG_ERROR, - DBG_END, -} dbg_level_t; - -static int debuglevel = 0; - -#define DBG_DEBUG(fmt, arg...) \ - do { \ - if (debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ - printk(KERN_INFO "[DEBUG]:<%s, %d>:" fmt, \ - __FUNCTION__, __LINE__, ##arg); \ - } else if (debuglevel >= DBG_ERROR) { \ - printk(KERN_ERR "[DEBUG]:<%s, %d>:" fmt, __FUNCTION__, \ - __LINE__, ##arg); \ - } else { \ - } \ - } while (0) - -#define DBG_ERROR(fmt, arg...) \ - do { \ - if (debuglevel > DBG_START) { \ - printk(KERN_ERR "[ERROR]:<%s, %d>:" fmt, __FUNCTION__, \ - __LINE__, ##arg); \ - } \ - } while (0) - -extern s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command); -extern s32 platform_i2c_smbus_read_i2c_block_data( - const struct i2c_client *client, u8 command, u8 length, u8 *values); -extern s32 platform_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command); - -typedef enum dfd_dev_info_type_e { - DFD_DEV_INFO_TYPE_MAC = 1, - DFD_DEV_INFO_TYPE_NAME = 2, - DFD_DEV_INFO_TYPE_SN = 3, - DFD_DEV_INFO_TYPE_PWR_CONS = 4, - DFD_DEV_INFO_TYPE_HW_INFO = 5, - DFD_DEV_INFO_TYPE_DEV_TYPE = 6, -} dfd_dev_tlv_type_t; - -typedef struct dfd_dev_head_info_s { - uint8_t ver; /* define E2PROM version,default is 0x01 */ - uint8_t flag; /* flag is 0x7E in new version E2PROM */ - uint8_t hw_ver; /* consists of main version and revise version */ - uint8_t type; /* HW type */ - int16_t tlv_len; /* 16 bits */ -} dfd_dev_head_info_t; - -typedef struct dfd_dev_tlv_info_s { - uint8_t type; - uint8_t len; - uint8_t data[0]; -} dfd_dev_tlv_info_t; - -struct fan_data { - struct i2c_client *client; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated[8]; /* In jiffies */ - u8 data[FAN_SIZE]; /* Register value */ -}; - -static ssize_t show_fan_sysfs_tlv_value(struct device *dev, - struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct fan_data *data = i2c_get_clientdata(client); - - dfd_dev_head_info_t info; - uint8_t tmp_tlv_len[sizeof(uint16_t)]; - uint8_t *tlv_data; - dfd_dev_tlv_info_t *tlv; - int type; - int buf_len = SYS_FAN_BUF_LEN - 1; - u8 sysfs_buf[SYS_FAN_BUF_LEN]; - int i; - int ret = 0; - - mutex_lock(&data->update_lock); - memset(sysfs_buf, 0, SYS_FAN_BUF_LEN); - ret = platform_i2c_smbus_read_i2c_block_data( - client, 0, sizeof(dfd_dev_head_info_t), (uint8_t *)&info); - if (ret != sizeof(dfd_dev_head_info_t)) { - DBG_ERROR("fan maybe not set mac or not present0"); - goto exit; - } - - /* transform TLV_LEN */ - memcpy(tmp_tlv_len, (uint8_t *)&info.tlv_len, sizeof(int16_t)); - info.tlv_len = (tmp_tlv_len[0] << 8) + tmp_tlv_len[1]; - - if ((info.tlv_len <= 0) || (info.tlv_len > 0xFF)) { - DBG_ERROR("fan maybe not set mac or not present1"); - goto exit; - } - - type = attr->index; - tlv_data = (uint8_t *)kmalloc(info.tlv_len, GFP_KERNEL); - memset(tlv_data, 0, info.tlv_len); - - if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - for (i = 0; i < info.tlv_len; i += 32) - if (platform_i2c_smbus_read_i2c_block_data(client, - sizeof(dfd_dev_head_info_t) + i, - 32, tlv_data + i) != 32) - break; - } - - DBG_DEBUG("TLV Len:%d\n", (int)sizeof(dfd_dev_tlv_info_t)); - for (tlv = (dfd_dev_tlv_info_t *)tlv_data; - (ulong)tlv < (ulong)tlv_data + info.tlv_len;) { - DBG_DEBUG( - "tlv: %p, tlv->type: 0x%x, tlv->len: 0x%x info->tlv_len: 0x%x\n", - tlv, tlv->type, tlv->len, info.tlv_len); - if (tlv->type == type && buf_len >= tlv->len) { - memcpy((uint8_t *)sysfs_buf, (uint8_t *)tlv->data, - tlv->len); - buf_len = (uint32_t)tlv->len; - break; - } - tlv = (dfd_dev_tlv_info_t *)((uint8_t *)tlv + - sizeof(dfd_dev_tlv_info_t) + - tlv->len); - } - - kfree(tlv_data); - DBG_DEBUG("value: %s \n", sysfs_buf); -exit: - mutex_unlock(&data->update_lock); - return sprintf(buf, "%s\n", sysfs_buf); -} - -static ssize_t show_fan_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct fan_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int i; - - mutex_lock(&data->update_lock); - - if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - for (i = 0; i < FAN_SIZE; i += 32) { - if (platform_i2c_smbus_read_i2c_block_data( - client, i, 32, data->data + i) != 32) - goto exit; - } - } else { - for (i = 0; i < FAN_SIZE; i += 2) { - int word = platform_i2c_smbus_read_word_data(client, i); - if (word < 0) - goto exit; - data->data[i] = word & 0xff; - data->data[i + 1] = word >> 8; - } - } - memcpy(buf, &data->data[0], FAN_SIZE); -exit: - mutex_unlock(&data->update_lock); - return FAN_SIZE; -} - -static SENSOR_DEVICE_ATTR(fan_hw_version, S_IRUGO, show_fan_sysfs_tlv_value, NULL, DFD_DEV_INFO_TYPE_HW_INFO); -static SENSOR_DEVICE_ATTR(fan_sn, S_IRUGO, show_fan_sysfs_tlv_value, NULL, DFD_DEV_INFO_TYPE_SN); -static SENSOR_DEVICE_ATTR(fan_type, S_IRUGO, show_fan_sysfs_tlv_value, NULL, DFD_DEV_INFO_TYPE_NAME); -static SENSOR_DEVICE_ATTR(fan, S_IRUGO, show_fan_value, NULL, 0); - -static struct attribute *fan_sysfs_attrs[] = { - &sensor_dev_attr_fan_hw_version.dev_attr.attr, - &sensor_dev_attr_fan_sn.dev_attr.attr, - &sensor_dev_attr_fan_type.dev_attr.attr, - &sensor_dev_attr_fan.dev_attr.attr, - NULL -}; - -static const struct attribute_group fan_sysfs_group = { - .attrs = fan_sysfs_attrs, -}; - -static int fan_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct fan_data *data; - int status; - - status = -1; - DBG_DEBUG("fan_probe(0x%02x)\n", client->addr); - data = devm_kzalloc(&client->dev, sizeof(struct fan_data), GFP_KERNEL); - if (!data) { - return -ENOMEM; - } - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - status = sysfs_create_group(&client->dev.kobj, &fan_sysfs_group); - if (status != 0) { - DBG_ERROR(" sysfs_create_group err\n"); - return status; - } - return 0; -} - -static int fan_remove(struct i2c_client *client) -{ - sysfs_remove_group(&client->dev.kobj, &fan_sysfs_group); - return 0; -} - -static const struct i2c_device_id fan_id[] = { { "rg_fan", 0 }, {} }; -MODULE_DEVICE_TABLE(i2c, fan_id); - -static struct i2c_driver rg_fan_driver = { - .driver = { - .name = "rg_fan", - }, - .probe = fan_probe, - .remove = fan_remove, - .id_table = fan_id, -}; - -module_i2c_driver(rg_fan_driver); -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("ragile fan driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg_psu.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg_psu.c deleted file mode 100755 index 78abd41cf525..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/modules/rg_psu.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * rg_cpld.c - A driver for pmbus psu - * - * Copyright (c) 2019 - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAGIC_PSU_RATE (0xA7) -#define MAGIC_PSU_OUT_CURRENT (0x8C) -#define MAGIC_PSU_OUT_VOLTAGE (0x8B) -#define MAGIC_PSU_IN_VOLTAGE (0x88) -#define MAGIC_PSU_IN_CURRENT (0x89) -#define MAGIC_PSU_TEMP (0x8D) -#define MAGIC_PSU_TYPE (0x25) -#define MAGIC_PSU_SN (0x38) -#define MAGIC_PSU_HW (0x35) -#define PSU_SIZE (256) - -typedef enum { - DBG_START, - DBG_VERBOSE, - DBG_KEY, - DBG_WARN, - DBG_ERROR, - DBG_END, -} dbg_level_t; - -static int debuglevel = 0; - -#define DBG_DEBUG(fmt, arg...) \ - do { \ - if (debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ - printk(KERN_INFO "[DEBUG]:<%s, %d>:" fmt, \ - __FUNCTION__, __LINE__, ##arg); \ - } else if (debuglevel >= DBG_ERROR) { \ - printk(KERN_ERR "[DEBUG]:<%s, %d>:" fmt, __FUNCTION__, \ - __LINE__, ##arg); \ - } else { \ - } \ - } while (0) - -#define DBG_INFO(fmt, arg...) \ - do { \ - if (debuglevel > DBG_KEY) { \ - printk(KERN_INFO "[INFO]:<%s, %d>:" fmt, __FUNCTION__, \ - __LINE__, ##arg); \ - } \ - } while (0) - -#define DBG_ERROR(fmt, arg...) \ - do { \ - if (debuglevel > DBG_START) { \ - printk(KERN_ERR "[ERROR]:<%s, %d>:" fmt, __FUNCTION__, \ - __LINE__, ##arg); \ - } \ - } while (0) - -static const unsigned short rg_i2c_psu[] = { 0x50, 0x53, 0x58, 0x5b, I2C_CLIENT_END }; - -extern s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command); -extern s32 platform_i2c_smbus_read_i2c_block_data(const struct i2c_client *client, - u8 command, u8 length, u8 *values); - -struct psu_data { - struct i2c_client *client; - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 data[PSU_SIZE]; /* Register value */ -}; - -static ssize_t show_psu_sysfs_value(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_sysfs_15_value(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_psu_value(struct device *dev, struct device_attribute *da, char *buf); - -static SENSOR_DEVICE_ATTR(psu_rate, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_RATE); -static SENSOR_DEVICE_ATTR(psu_out_current, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_OUT_CURRENT); -static SENSOR_DEVICE_ATTR(psu_out_voltage, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_OUT_VOLTAGE); -static SENSOR_DEVICE_ATTR(psu_in_voltage, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_IN_VOLTAGE); -static SENSOR_DEVICE_ATTR(psu_in_current, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_IN_CURRENT); -static SENSOR_DEVICE_ATTR(psu_temp, S_IRUGO, show_psu_sysfs_value, NULL, MAGIC_PSU_TEMP); -static SENSOR_DEVICE_ATTR(psu_type, S_IRUGO, show_sysfs_15_value, NULL, MAGIC_PSU_TYPE); -static SENSOR_DEVICE_ATTR(psu_sn, S_IRUGO, show_sysfs_15_value, NULL, MAGIC_PSU_SN); -static SENSOR_DEVICE_ATTR(psu_hw, S_IRUGO, show_psu_value, NULL, MAGIC_PSU_HW); - -static struct attribute *psu_pmbus_sysfs_attrs[] = { - &sensor_dev_attr_psu_rate.dev_attr.attr, - &sensor_dev_attr_psu_out_current.dev_attr.attr, - &sensor_dev_attr_psu_out_voltage.dev_attr.attr, - &sensor_dev_attr_psu_in_voltage.dev_attr.attr, - &sensor_dev_attr_psu_in_current.dev_attr.attr, - &sensor_dev_attr_psu_temp.dev_attr.attr, - NULL -}; - -static struct attribute *psu_fru_sysfs_attrs[] = { - &sensor_dev_attr_psu_type.dev_attr.attr, - &sensor_dev_attr_psu_sn.dev_attr.attr, - &sensor_dev_attr_psu_hw.dev_attr.attr, - NULL -}; - -static const struct attribute_group psu_pmbus_sysfs_attrs_group = { - .attrs = psu_pmbus_sysfs_attrs, -}; - -static const struct attribute_group psu_fru_sysfs_attrs_group = { - .attrs = psu_fru_sysfs_attrs, -}; - -static ssize_t show_psu_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct psu_data *data = i2c_get_clientdata(client); - int ret; - char psu_buf[PSU_SIZE]; - memset(psu_buf, 0, PSU_SIZE); - mutex_lock(&data->update_lock); - ret = platform_i2c_smbus_read_i2c_block_data(client, attr->index, 2, psu_buf); - if (ret < 0) { - DBG_ERROR("Failed to read psu\n"); - } - DBG_DEBUG("cpld reg pos:0x%x value:0x%02x\n", attr->index, data->data[0]); - mutex_unlock(&data->update_lock); - return snprintf(buf, 3, "%s\n", psu_buf); -} - -static int linear_to_value(short reg, bool v_out) -{ - short exponent; - int mantissa; - long val; - - if (v_out) { - exponent = -9; - mantissa = reg; - } else { - exponent = reg >> 11; - mantissa = (((reg & 0x7ff) << 5)) >> 5; - } - val = mantissa; - val = val * 1000L; - if (exponent >= 0) { - val <<= exponent; - } else { - val >>= -exponent; - } - - return val; -} - -static ssize_t show_psu_sysfs_value(struct device *dev, - struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct psu_data *data = i2c_get_clientdata(client); - int ret; - u8 smbud_buf[PSU_SIZE]; - uint16_t value; - int result; - - ret = -1; - memset(smbud_buf, 0, PSU_SIZE); - mutex_lock(&data->update_lock); - DBG_DEBUG("ret:%d", ret); - ret = platform_i2c_smbus_read_i2c_block_data(client, attr->index, 2, smbud_buf); - if (ret < 0) { - DBG_ERROR("Failed to read psu \n"); - } - value = smbud_buf[1]; - value = value << 8; - value |= smbud_buf[0]; - - if (attr->index == 0x8b) { - result = linear_to_value(value, true); - } else { - result = linear_to_value(value, false); - } - mutex_unlock(&data->update_lock); - return snprintf(buf, PSU_SIZE, "%d\n", result); -} - -static ssize_t show_sysfs_15_value(struct device *dev, - struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct psu_data *data = i2c_get_clientdata(client); - int ret; - u8 smbud_buf[PSU_SIZE]; - - memset(smbud_buf, 0, PSU_SIZE); - mutex_lock(&data->update_lock); - ret = platform_i2c_smbus_read_i2c_block_data(client, attr->index, 15, smbud_buf); - if (ret < 0) { - DBG_ERROR("Failed to read psu\n"); - } - mutex_unlock(&data->update_lock); - return snprintf(buf, PSU_SIZE, "%s\n", smbud_buf); -} - -static ssize_t show_sysfs_13_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct psu_data *data = i2c_get_clientdata(client); - int ret; - u8 smbud_buf[PSU_SIZE]; - - memset(smbud_buf, 0, PSU_SIZE); - mutex_lock(&data->update_lock); - ret = platform_i2c_smbus_read_i2c_block_data(client, attr->index, 13, smbud_buf); - if (ret < 0) { - DBG_ERROR("Failed to read psu \n"); - } - mutex_unlock(&data->update_lock); - return snprintf(buf, PSU_SIZE, "%s\n", smbud_buf); -} - -static int psu_detect(struct i2c_client *new_client, - struct i2c_board_info *info) -{ - struct i2c_adapter *adapter = new_client->adapter; - int conf; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) - return -ENODEV; - conf = platform_i2c_smbus_read_byte_data(new_client, 0); - if (!conf) - return -ENODEV; - - return 0; -} - -static int psu_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct psu_data *data; - int status; - - status = -1; - data = devm_kzalloc(&client->dev, sizeof(struct psu_data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - switch (client->addr) { - case 0x50: - case 0x53: - status = sysfs_create_group(&client->dev.kobj, - &psu_fru_sysfs_attrs_group); - if (status != 0) { - DBG_ERROR("%s %d sysfs_create_group err\n", __func__, __LINE__); - } - break; - case 0x58: - case 0x5b: - status = sysfs_create_group(&client->dev.kobj, - &psu_pmbus_sysfs_attrs_group); - if (status != 0) { - DBG_ERROR("%s %d sysfs_create_group err\n", __func__, __LINE__); - break; - } - break; - default: - break; - } - - return status; -} - -static int psu_remove(struct i2c_client *client) -{ - switch (client->addr) { - case 0x50: - case 0x53: - sysfs_remove_group(&client->dev.kobj, &psu_fru_sysfs_attrs_group); - break; - case 0x58: - case 0x5b: - sysfs_remove_group(&client->dev.kobj, &psu_pmbus_sysfs_attrs_group); - break; - default: - break; - } - return 0; -} - -static const struct i2c_device_id psu_id[] = { - { "rg_psu", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, psu_id); - -static struct i2c_driver rg_psu_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "rg_psu", - }, - .probe = psu_probe, - .remove = psu_remove, - .id_table = psu_id, - .detect = psu_detect, - .address_list = rg_i2c_psu, -}; - -module_i2c_driver(rg_psu_driver); - -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("ragile pmbus psu driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/spi-bitbang-txrx.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/spi-bitbang-txrx.h new file mode 100644 index 000000000000..47bb9b898dfd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/spi-bitbang-txrx.h @@ -0,0 +1,107 @@ +/* + * Mix this utility code with some glue code to get one of several types of + * simple SPI master driver. Two do polled word-at-a-time I/O: + * + * - GPIO/parport bitbangers. Provide chipselect() and txrx_word[](), + * expanding the per-word routines from the inline templates below. + * + * - Drivers for controllers resembling bare shift registers. Provide + * chipselect() and txrx_word[](), with custom setup()/cleanup() methods + * that use your controller's clock and chipselect registers. + * + * Some hardware works well with requests at spi_transfer scope: + * + * - Drivers leveraging smarter hardware, with fifos or DMA; or for half + * duplex (MicroWire) controllers. Provide chipselect() and txrx_bufs(), + * and custom setup()/cleanup() methods. + */ + +/* + * The code that knows what GPIO pins do what should have declared four + * functions, ideally as inlines, before including this header: + * + * void setsck(struct spi_device *, int is_on); + * void setmosi(struct spi_device *, int is_on); + * int getmiso(struct spi_device *); + * void spidelay(unsigned); + * + * setsck()'s is_on parameter is a zero/nonzero boolean. + * + * setmosi()'s is_on parameter is a zero/nonzero boolean. + * + * getmiso() is required to return 0 or 1 only. Any other value is invalid + * and will result in improper operation. + * + * A non-inlined routine would call bitbang_txrx_*() routines. The + * main loop could easily compile down to a handful of instructions, + * especially if the delay is a NOP (to run at peak speed). + * + * Since this is software, the timings may not be exactly what your board's + * chips need ... there may be several reasons you'd need to tweak timings + * in these routines, not just to make it faster or slower to match a + * particular CPU clock rate. + */ + +static inline u32 +bitbang_txrx_be_cpha0(struct spi_device *spi, + unsigned nsecs, unsigned cpol, unsigned flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ + + u32 oldbit = (!(word & (1<<(bits-1)))) << 31; + /* clock starts at inactive polarity */ + for (word <<= (32 - bits); likely(bits); bits--) { + + /* setup MSB (to slave) on trailing edge */ + if ((flags & SPI_MASTER_NO_TX) == 0) { + if ((word & (1 << 31)) != oldbit) { + setmosi(spi, word & (1 << 31)); + oldbit = word & (1 << 31); + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, !cpol); + spidelay(nsecs); + + /* sample MSB (from slave) on leading edge */ + word <<= 1; + if ((flags & SPI_MASTER_NO_RX) == 0) + word |= getmiso(spi); + setsck(spi, cpol); + } + return word; +} + +static inline u32 +bitbang_txrx_be_cpha1(struct spi_device *spi, + unsigned nsecs, unsigned cpol, unsigned flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ + + u32 oldbit = (!(word & (1<<(bits-1)))) << 31; + /* clock starts at inactive polarity */ + for (word <<= (32 - bits); likely(bits); bits--) { + + /* setup MSB (to slave) on leading edge */ + setsck(spi, !cpol); + if ((flags & SPI_MASTER_NO_TX) == 0) { + if ((word & (1 << 31)) != oldbit) { + setmosi(spi, word & (1 << 31)); + oldbit = word & (1 << 31); + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, cpol); + spidelay(nsecs); + + /* sample MSB (from slave) on trailing edge */ + word <<= 1; + if ((flags & SPI_MASTER_NO_RX) == 0) + word |= getmiso(spi); + } + return word; +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_eeprom_93xx46.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_eeprom_93xx46.c new file mode 100644 index 000000000000..2ba7e7912ed5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_eeprom_93xx46.c @@ -0,0 +1,558 @@ +/* + * Driver for 93xx46 EEPROMs + * + * (C) 2011 DENX Software Engineering, Anatolij Gustschin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define OP_START 0x4 +#define OP_WRITE (OP_START | 0x1) +#define OP_READ (OP_START | 0x2) +#define ADDR_EWDS 0x00 +#define ADDR_ERAL 0x20 +#define ADDR_EWEN 0x30 + +static int g_wb_eeprom_93xx46_debug = 0; + +module_param(g_wb_eeprom_93xx46_debug, int, S_IRUGO | S_IWUSR); + +#define SPI_93xx46_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_eeprom_93xx46_debug) { \ + printk(KERN_INFO "[EEPROM-93xx46][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct eeprom_93xx46_devtype_data { + unsigned int quirks; +}; + +static const struct eeprom_93xx46_devtype_data atmel_at93c46d_data = { + .quirks = EEPROM_93XX46_QUIRK_SINGLE_WORD_READ | + EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH, +}; + +struct eeprom_93xx46_dev { + struct spi_device *spi; + struct eeprom_93xx46_platform_data *pdata; + struct mutex lock; + struct nvmem_config nvmem_config; + struct nvmem_device *nvmem; + int addrlen; + int size; +}; + +static inline bool has_quirk_single_word_read(struct eeprom_93xx46_dev *edev) +{ + return edev->pdata->quirks & EEPROM_93XX46_QUIRK_SINGLE_WORD_READ; +} + +static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev) +{ + return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; +} + +static int eeprom_93xx46_read(void *priv, unsigned int off, + void *val, size_t count) +{ + struct eeprom_93xx46_dev *edev = priv; + char *buf = val; + int err = 0; + + if (unlikely(off >= edev->size)) + return 0; + if ((off + count) > edev->size) + count = edev->size - off; + if (unlikely(!count)) + return count; + + mutex_lock(&edev->lock); + + if (edev->pdata->prepare) + edev->pdata->prepare(edev); + + while (count) { + struct spi_message m; + struct spi_transfer t[2] = { { 0 } }; + u16 cmd_addr = OP_READ << edev->addrlen; + size_t nbytes = count; + int bits; + int data_bit; + + if (edev->addrlen == 7) { + cmd_addr |= off & 0x7f; + bits = 10; + data_bit = 8; + if (has_quirk_single_word_read(edev)) + nbytes = 1; + } else { + cmd_addr |= (off >> 1) & 0x3f; + bits = 9; + data_bit = 16; + if (has_quirk_single_word_read(edev)) + nbytes = 2; + } + + dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n", + cmd_addr, edev->spi->max_speed_hz); + + spi_message_init(&m); + + t[0].tx_buf = (char *)&cmd_addr; + t[0].len = 2; + t[0].bits_per_word = bits; + spi_message_add_tail(&t[0], &m); + + t[1].rx_buf = buf; + t[1].len = nbytes; + t[1].bits_per_word = data_bit; + spi_message_add_tail(&t[1], &m); + + err = spi_sync(edev->spi, &m); + /* have to wait at least Tcsl ns */ + ndelay(250); + + if (err) { + dev_err(&edev->spi->dev, "read %zu bytes at %d: err. %d\n", + nbytes, (int)off, err); + break; + } + + buf += nbytes; + off += nbytes; + count -= nbytes; + } + + if (edev->pdata->finish) + edev->pdata->finish(edev); + + mutex_unlock(&edev->lock); + + return err; +} + +static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on) +{ + struct spi_message m; + struct spi_transfer t; + int bits, ret; + u16 cmd_addr; + + cmd_addr = OP_START << edev->addrlen; + if (edev->addrlen == 7) { + cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS) << 1; + bits = 10; + } else { + cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS); + bits = 9; + } + + if (has_quirk_instruction_length(edev)) { + cmd_addr <<= 2; + bits += 2; + } + + dev_dbg(&edev->spi->dev, "ew%s cmd 0x%04x, %d bits\n", + is_on ? "en" : "ds", cmd_addr, bits); + + spi_message_init(&m); + mem_clear(&t, sizeof(t)); + + t.tx_buf = &cmd_addr; + t.len = 2; + t.bits_per_word = bits; + spi_message_add_tail(&t, &m); + + mutex_lock(&edev->lock); + + if (edev->pdata->prepare) + edev->pdata->prepare(edev); + + ret = spi_sync(edev->spi, &m); + /* have to wait at least Tcsl ns */ + ndelay(250); + if (ret) + dev_err(&edev->spi->dev, "erase/write %sable error %d\n", + is_on ? "en" : "dis", ret); + + if (edev->pdata->finish) + edev->pdata->finish(edev); + + mutex_unlock(&edev->lock); + return ret; +} + +static ssize_t +eeprom_93xx46_write_word(struct eeprom_93xx46_dev *edev, + char *buf, unsigned off) +{ + struct spi_message m; + struct spi_transfer t[2]; + int bits, data_len, ret; + u16 cmd_addr; + int data_bit; + + cmd_addr = OP_WRITE << edev->addrlen; + + if (edev->addrlen == 7) { + cmd_addr |= off & 0x7f; + bits = 10; + data_len = 1; + data_bit = 8; + } else { + cmd_addr |= (off >> 1) & 0x3f; + bits = 9; + data_len = 2; + data_bit = 16; + } + + dev_dbg(&edev->spi->dev, "write cmd 0x%x\n", cmd_addr); + + spi_message_init(&m); + mem_clear(t, sizeof(t)); + + t[0].tx_buf = (char *)&cmd_addr; + t[0].len = 2; + t[0].bits_per_word = bits; + spi_message_add_tail(&t[0], &m); + + t[1].tx_buf = buf; + t[1].len = data_len; + t[1].bits_per_word = data_bit; + spi_message_add_tail(&t[1], &m); + + ret = spi_sync(edev->spi, &m); + /* have to wait program cycle time Twc ms */ + mdelay(6); + return ret; +} + +static int eeprom_93xx46_write(void *priv, unsigned int off, + void *val, size_t count) +{ + struct eeprom_93xx46_dev *edev = priv; + char *buf = val; + int i, ret, step = 1; + + if (unlikely(off >= edev->size)) + return -EFBIG; + if ((off + count) > edev->size) + count = edev->size - off; + if (unlikely(!count)) + return count; + + /* only write even number of bytes on 16-bit devices */ + if (edev->addrlen == 6) { + step = 2; + count &= ~1; + } + + /* erase/write enable */ + ret = eeprom_93xx46_ew(edev, 1); + if (ret) + return ret; + + mutex_lock(&edev->lock); + + if (edev->pdata->prepare) + edev->pdata->prepare(edev); + + for (i = 0; i < count; i += step) { + ret = eeprom_93xx46_write_word(edev, &buf[i], off + i); + if (ret) { + dev_err(&edev->spi->dev, "write failed at %d: %d\n", + (int)off + i, ret); + break; + } + } + + if (edev->pdata->finish) + edev->pdata->finish(edev); + + mutex_unlock(&edev->lock); + + /* erase/write disable */ + eeprom_93xx46_ew(edev, 0); + return ret; +} + +static int eeprom_93xx46_eral(struct eeprom_93xx46_dev *edev) +{ + struct eeprom_93xx46_platform_data *pd = edev->pdata; + struct spi_message m; + struct spi_transfer t; + int bits, ret; + u16 cmd_addr; + + cmd_addr = OP_START << edev->addrlen; + if (edev->addrlen == 7) { + cmd_addr |= ADDR_ERAL << 1; + bits = 10; + } else { + cmd_addr |= ADDR_ERAL; + bits = 9; + } + + if (has_quirk_instruction_length(edev)) { + cmd_addr <<= 2; + bits += 2; + } + + dev_dbg(&edev->spi->dev, "eral cmd 0x%04x, %d bits\n", cmd_addr, bits); + + spi_message_init(&m); + mem_clear(&t, sizeof(t)); + + t.tx_buf = &cmd_addr; + t.len = 2; + t.bits_per_word = bits; + spi_message_add_tail(&t, &m); + + mutex_lock(&edev->lock); + + if (edev->pdata->prepare) + edev->pdata->prepare(edev); + + ret = spi_sync(edev->spi, &m); + if (ret) + dev_err(&edev->spi->dev, "erase error %d\n", ret); + /* have to wait erase cycle time Tec ms */ + mdelay(6); + + if (pd->finish) + pd->finish(edev); + + mutex_unlock(&edev->lock); + return ret; +} + +static ssize_t eeprom_93xx46_store_erase(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct eeprom_93xx46_dev *edev = dev_get_drvdata(dev); + int erase = 0, ret; + + sscanf(buf, "%d", &erase); + if (erase) { + ret = eeprom_93xx46_ew(edev, 1); + if (ret) + return ret; + ret = eeprom_93xx46_eral(edev); + if (ret) + return ret; + ret = eeprom_93xx46_ew(edev, 0); + if (ret) + return ret; + } + return count; +} +static DEVICE_ATTR(erase, S_IWUSR, NULL, eeprom_93xx46_store_erase); + +static void select_assert(void *context) +{ + struct eeprom_93xx46_dev *edev = context; + + gpiod_set_value_cansleep(edev->pdata->select, 1); +} + +static void select_deassert(void *context) +{ + struct eeprom_93xx46_dev *edev = context; + + gpiod_set_value_cansleep(edev->pdata->select, 0); +} + +static const struct of_device_id eeprom_93xx46_of_table[] = { + { .compatible = "eeprom-93xx46", }, + { .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, }, + {} +}; +MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table); + +static int eeprom_93xx46_probe_dt(struct spi_device *spi) +{ + const struct of_device_id *of_id = + of_match_device(eeprom_93xx46_of_table, &spi->dev); + struct device_node *np = spi->dev.of_node; + struct eeprom_93xx46_platform_data *pd; + u32 tmp; + int gpio; + enum of_gpio_flags of_flags; + int ret; + + pd = devm_kzalloc(&spi->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; + + ret = of_property_read_u32(np, "data-size", &tmp); + if (ret < 0) { + dev_err(&spi->dev, "data-size property not found\n"); + return ret; + } + + if (tmp == 8) { + pd->flags |= EE_ADDR8; + } else if (tmp == 16) { + pd->flags |= EE_ADDR16; + } else { + dev_err(&spi->dev, "invalid data-size (%d)\n", tmp); + return -EINVAL; + } + + if (of_property_read_bool(np, "read-only")) + pd->flags |= EE_READONLY; + + gpio = of_get_named_gpio_flags(np, "select-gpios", 0, &of_flags); + if (gpio_is_valid(gpio)) { + unsigned long flags = + of_flags == OF_GPIO_ACTIVE_LOW ? GPIOF_ACTIVE_LOW : 0; + + ret = devm_gpio_request_one(&spi->dev, gpio, flags, + "eeprom_93xx46_select"); + if (ret) + return ret; + + pd->select = gpio_to_desc(gpio); + pd->prepare = select_assert; + pd->finish = select_deassert; + + gpiod_direction_output(pd->select, 0); + } + + if (of_id) { + if (of_id->data) { + const struct eeprom_93xx46_devtype_data *data = of_id->data; + + pd->quirks = data->quirks; + } + } + + spi->dev.platform_data = pd; + + return 0; +} + +static int eeprom_93xx46_probe(struct spi_device *spi) +{ + struct eeprom_93xx46_platform_data *pd; + struct eeprom_93xx46_dev *edev; + int err; + + if (spi->dev.of_node) { + err = eeprom_93xx46_probe_dt(spi); + if (err < 0) + return err; + } + + pd = spi->dev.platform_data; + if (!pd) { + dev_err(&spi->dev, "missing platform data\n"); + return -ENODEV; + } + + edev = kzalloc(sizeof(*edev), GFP_KERNEL); + if (!edev) + return -ENOMEM; + + if (pd->flags & EE_ADDR8) + edev->addrlen = 7; + else if (pd->flags & EE_ADDR16) + edev->addrlen = 6; + else { + dev_err(&spi->dev, "unspecified address type\n"); + err = -EINVAL; + goto fail; + } + + mutex_init(&edev->lock); + + edev->spi = spi; + edev->pdata = pd; + + edev->size = 128; + edev->nvmem_config.name = dev_name(&spi->dev); + edev->nvmem_config.dev = &spi->dev; + edev->nvmem_config.read_only = pd->flags & EE_READONLY; + edev->nvmem_config.root_only = true; + edev->nvmem_config.owner = THIS_MODULE; + edev->nvmem_config.compat = true; + edev->nvmem_config.base_dev = &spi->dev; + edev->nvmem_config.reg_read = eeprom_93xx46_read; + edev->nvmem_config.reg_write = eeprom_93xx46_write; + edev->nvmem_config.priv = edev; + edev->nvmem_config.stride = 4; + edev->nvmem_config.word_size = 1; + edev->nvmem_config.size = edev->size; + + edev->nvmem = nvmem_register(&edev->nvmem_config); + if (IS_ERR(edev->nvmem)) { + err = PTR_ERR(edev->nvmem); + goto fail; + } + + if (g_wb_eeprom_93xx46_debug) { + dev_info(&spi->dev, "%d-bit eeprom %s\n", + (pd->flags & EE_ADDR8) ? 8 : 16, + (pd->flags & EE_READONLY) ? "(readonly)" : ""); + } + + if (!(pd->flags & EE_READONLY)) { + if (device_create_file(&spi->dev, &dev_attr_erase)) + dev_err(&spi->dev, "can't create erase interface\n"); + } + + spi_set_drvdata(spi, edev); + return 0; +fail: + kfree(edev); + return err; +} + +static int eeprom_93xx46_remove(struct spi_device *spi) +{ + struct eeprom_93xx46_dev *edev = spi_get_drvdata(spi); + + nvmem_unregister(edev->nvmem); + + if (!(edev->pdata->flags & EE_READONLY)) + device_remove_file(&spi->dev, &dev_attr_erase); + + kfree(edev); + return 0; +} + +static struct spi_driver wb_eeprom_93xx46_driver = { + .driver = { + .name = "wb_93xx46", + .of_match_table = of_match_ptr(eeprom_93xx46_of_table), + }, + .probe = eeprom_93xx46_probe, + .remove = eeprom_93xx46_remove, +}; + +module_spi_driver(wb_eeprom_93xx46_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs"); +MODULE_AUTHOR("support"); +MODULE_ALIAS("spi:93xx46"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_i2c_bus_drv.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_i2c_bus_drv.c new file mode 100644 index 000000000000..c1c4544db1d9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_i2c_bus_drv.c @@ -0,0 +1,1103 @@ +/* + * fpga_i2c_bus_drv.c + * ko to create fpga i2c adapter + */ +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) +#include +#endif +#include +#include +#include +#include +#include +#include +#include "fpga_i2c.h" + +#include +#include + +#define DRV_NAME "wb-fpga-i2c" +#define DRV_VERSION "1.0" +#define DTS_NO_CFG_FLAG (0) + +extern int i2c_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); +extern int i2c_device_func_read(const char *path, uint32_t pos, uint8_t *val, size_t size); +extern int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); + +#define FPGA_I2C_STRETCH_TIMEOUT (0x01) +#define FPGA_I2C_DEADLOCK_FAILED (0x02) +#define FPGA_I2C_SLAVE_NO_RESPOND (0x03) +#define FPGA_I2C_STA_FAIL (0x01) +#define FPGA_I2C_STA_BUSY (0x02) +#define FPGA_I2C_CTL_BG (0x01 << 1) +#define FPGA_I2C_CTL_NO_REG (0x01 << 2) +#define FPGA_I2C_CTL_RD (0x01) +#define FPGA_I2C_CTL_WR (0x00) +#define I2C_READ_MSG_NUM (0x02) +#define I2C_WRITE_MSG_NUM (0x01) +#define FPGA_REG_WIDTH (4) + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) + +int g_wb_fpga_i2c_debug = 0; +int g_wb_fpga_i2c_error = 0; + +module_param(g_wb_fpga_i2c_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_fpga_i2c_error, int, S_IRUGO | S_IWUSR); + +#define FPGA_I2C_VERBOSE(fmt, args...) do { \ + if (g_wb_fpga_i2c_debug) { \ + printk(KERN_INFO "[FPFA_I2C_BUS][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_I2C_ERROR(fmt, args...) do { \ + if (g_wb_fpga_i2c_error) { \ + printk(KERN_ERR "[FPFA_I2C_BUS][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static int fpga_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + FPGA_I2C_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + FPGA_I2C_ERROR("kernel_read failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int fpga_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + FPGA_I2C_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + FPGA_I2C_ERROR("kernel_write failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int fpga_device_write(fpga_i2c_dev_t *fpga_i2c, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (fpga_i2c->i2c_func_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = fpga_file_write(fpga_i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; + default: + FPGA_I2C_ERROR("err func_mode, write failed.\n"); + return -EINVAL; + } + return ret; + +} + +static int fpga_device_read(fpga_i2c_dev_t *fpga_i2c, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (fpga_i2c->i2c_func_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_read(fpga_i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = fpga_file_read(fpga_i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_read(fpga_i2c->dev_name, pos, val, size); + break; + default: + FPGA_I2C_ERROR("err func_mode, read failed.\n"); + return -EINVAL; + } + + return ret; +} + +static int little_endian_dword_to_buf(uint8_t *buf, int len, uint32_t dword) +{ + uint8_t tmp_buf[FPGA_REG_WIDTH]; + + if (len < 4) { + FPGA_I2C_ERROR("Not enough buf, dword to buf: len[%d], dword[0x%x]\n", len, dword); + return -1; + } + + mem_clear(tmp_buf, sizeof(tmp_buf)); + tmp_buf[0] = dword & 0xff; + tmp_buf[1] = (dword >> 8) & 0xff; + tmp_buf[2] = (dword >> 16) & 0xff; + tmp_buf[3] = (dword >> 24) & 0xff; + + memcpy(buf, tmp_buf, sizeof(tmp_buf)); + + return 0; +} + +static int little_endian_buf_to_dword(uint8_t *buf, int len, uint32_t *dword) +{ + int i; + uint32_t dword_tmp; + + if (len != FPGA_REG_WIDTH) { + FPGA_I2C_ERROR("buf length %d error, can't convert to dowrd.\n", len); + return -1; + } + dword_tmp = 0; + for (i = 0; i < FPGA_REG_WIDTH; i++) { + dword_tmp |= (buf[i] << (i * 8)); + } + *dword = dword_tmp; + return 0; +} + +static int fpga_reg_write(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t val) +{ + int ret; + + ret = fpga_device_write(fpga_i2c, addr, &val, sizeof(uint8_t)); + if (ret < 0) { + FPGA_I2C_ERROR("fpga reg write failed, dev name:%s, offset:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, val); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga reg write success, dev name:%s, offset:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, val); + return 0; +} + +static int fpga_reg_read(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t *val) +{ + int ret; + + ret = fpga_device_read(fpga_i2c, addr, val, sizeof(uint8_t)); + if (ret < 0) { + FPGA_I2C_ERROR("fpga reg read failed, dev name:%s, offset:0x%x\n", + fpga_i2c->dev_name, addr); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga reg read success, dev name:%s, offset:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, *val); + return 0; +} + +static int fpga_data_write(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + + ret = fpga_device_write(fpga_i2c, addr, val, size); + if (ret < 0) { + FPGA_I2C_ERROR("fpga data write failed, dev name:%s, offset:0x%x, size:%lu.\n", + fpga_i2c->dev_name, addr, size); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga data write success, dev name:%s, offset:0x%x, size:%lu.\n", + fpga_i2c->dev_name, addr, size); + return 0; +} + +static int fpga_data_read(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t *val, size_t size) +{ + int ret; + + ret = fpga_device_read(fpga_i2c, addr, val, size); + if (ret < 0) { + FPGA_I2C_ERROR("fpga data read failed, dev name:%s, offset:0x%x, size:%lu.\n", + fpga_i2c->dev_name, addr, size); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga data read success, dev name:%s, offset:0x%x, size:%lu.\n", + fpga_i2c->dev_name, addr, size); + return 0; +} + +static int fpga_reg_write_32(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint32_t val) +{ + int ret; + uint8_t buf[FPGA_REG_WIDTH]; + + mem_clear(buf, sizeof(buf)); + little_endian_dword_to_buf(buf, sizeof(buf), val); + ret = fpga_device_write(fpga_i2c, addr, buf, sizeof(buf)); + if (ret < 0) { + FPGA_I2C_ERROR("fpga reg write failed, dev name: %s, offset: 0x%x, value: 0x%x.\n", + fpga_i2c->dev_name, addr, val); + return -EIO; + } + + FPGA_I2C_VERBOSE("fpga reg write success, dev name: %s, offset: 0x%x, value: 0x%x.\n", + fpga_i2c->dev_name, addr, val); + return 0; +} + +static int fpga_reg_read_32(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint32_t *val) +{ + int ret; + uint8_t buf[FPGA_REG_WIDTH]; + + mem_clear(buf, sizeof(buf)); + ret = fpga_device_read(fpga_i2c, addr, buf, sizeof(buf)); + if (ret < 0) { + FPGA_I2C_ERROR("fpga reg read failed, dev name: %s, offset: 0x%x, ret: %d\n", + fpga_i2c->dev_name, addr, ret); + return -EIO; + } + little_endian_buf_to_dword(buf, sizeof(buf), val); + FPGA_I2C_VERBOSE("fpga reg read success, dev name: %s, offset: 0x%x, value: 0x%x.\n", + fpga_i2c->dev_name, addr, *val); + return 0; +} + +static int fpga_i2c_is_busy(fpga_i2c_dev_t *fpga_i2c) +{ + uint8_t val; + int ret; + fpga_i2c_reg_t *reg; + + reg = &fpga_i2c->reg; + ret = fpga_reg_read(fpga_i2c, reg->i2c_status, &val); + if (ret < 0 ) { + FPGA_I2C_ERROR("read fpga i2c status reg failed, reg addr:0x%x, ret:%d.\n", + reg->i2c_status, ret); + return 1; + } + if (val & FPGA_I2C_STA_BUSY) { + FPGA_I2C_ERROR("fpga i2c status busy, reg addr:0x%x, value:0x%x.\n", + reg->i2c_status, val); + return 1; + } else { + return 0; + } +} + +static int fpga_i2c_wait(fpga_i2c_dev_t *fpga_i2c) +{ + int retry_cnt; + + retry_cnt = FPGA_I2C_XFER_TIME_OUT/FPGA_I2C_SLEEP_TIME; + while (retry_cnt--) { + if (fpga_i2c_is_busy(fpga_i2c)) { + usleep_range(FPGA_I2C_SLEEP_TIME, FPGA_I2C_SLEEP_TIME + 1); + } else { + return 0; + } + } + + return -EBUSY; +} + +static int fpga_i2c_check_status(fpga_i2c_dev_t *fpga_i2c) +{ + uint8_t data; + int ret; + fpga_i2c_reg_t *reg; + + reg = &fpga_i2c->reg; + + ret = fpga_reg_read(fpga_i2c, reg->i2c_status, &data); + if (ret) { + FPGA_I2C_ERROR("read fpga i2c status reg failed, reg addr:0x%x, ret:%d.\n", + reg->i2c_status, ret); + return ret; + } + + if (data & FPGA_I2C_STA_FAIL) { + FPGA_I2C_ERROR("fpga i2c status error, reg addr:0x%x, value:%d.\n", + reg->i2c_status, data); + + /* read i2c_err_vec to confirm err type*/ + if (reg->i2c_err_vec != DTS_NO_CFG_FLAG) { + /* read i2c_err_vec reg */ + ret = fpga_reg_read(fpga_i2c, reg->i2c_err_vec, &data); + if (ret) { + FPGA_I2C_ERROR("read fpga i2c err vec reg failed, reg addr:0x%x, ret:%d.\n", + reg->i2c_err_vec, ret); + return ret; + } + FPGA_I2C_VERBOSE("get i2c err vec, reg addr:0x%x, read value:0x%x\n", reg->i2c_err_vec, data); + + /* match i2c_err_vec reg value and err type*/ + switch (data) { + case FPGA_I2C_STRETCH_TIMEOUT: + ret = -ETIMEDOUT; + break; + case FPGA_I2C_DEADLOCK_FAILED: + ret = -EDEADLK; + break; + case FPGA_I2C_SLAVE_NO_RESPOND: + ret = -ENXIO; + break; + default: + FPGA_I2C_ERROR("get i2c err vec value out of range, reg addr:0x%x, read value:0x%x\n", + reg->i2c_err_vec, data); + ret = -EREMOTEIO; + break; + } + return ret; + } else { + FPGA_I2C_VERBOSE("i2c err vec not config, fpga i2c status check return -1\n"); + return -EREMOTEIO; + } + } + return 0; +} + +static int fpga_i2c_do_work(fpga_i2c_dev_t *fpga_i2c, int i2c_addr, + unsigned char *data, uint32_t length, int is_read) +{ + int ret, i; + uint8_t op, i2c_reg_addr_len; + uint8_t *i2c_read_addr_buf; + fpga_i2c_reg_t *reg; + fpga_i2c_reg_addr_t *i2c_addr_desc; + + reg = &fpga_i2c->reg; + + ret = fpga_reg_write(fpga_i2c, reg->i2c_slave, i2c_addr); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c slave reg failed, reg addr:0x%x, value:0x%x, ret:%d.\n", + reg->i2c_slave, i2c_addr, ret); + goto exit; + } + + i2c_addr_desc = &fpga_i2c->i2c_addr_desc; + i2c_reg_addr_len = i2c_addr_desc->reg_addr_len; + i2c_read_addr_buf = &i2c_addr_desc->read_reg_addr[0]; + + if (i2c_reg_addr_len > 0 && i2c_reg_addr_len <= I2C_REG_MAX_WIDTH) { + ret = fpga_data_write(fpga_i2c, reg->i2c_reg, i2c_read_addr_buf, i2c_reg_addr_len); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c offset reg failed, fpga addr:0x%x, reg len:%d, ret:%d\n", + reg->i2c_reg, i2c_reg_addr_len, ret); + for (i = 0; i < i2c_reg_addr_len; i++) { + FPGA_I2C_ERROR("%02d : %02x\n", i, i2c_read_addr_buf[i]); + } + goto exit; + } + } + + ret = fpga_reg_write_32(fpga_i2c, reg->i2c_data_len, length); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c date len reg failed, reg addr:0x%x, value:0x%x, ret:%d.\n", + reg->i2c_data_len, length, ret); + goto exit; + } + + ret = fpga_reg_write(fpga_i2c, reg->i2c_reg_len, i2c_reg_addr_len); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c reg len reg failed, reg addr:0x%x, value:0x%x, ret:%d.\n", + reg->i2c_reg_len, i2c_reg_addr_len, ret); + goto exit; + } + + if (is_read) { + op = FPGA_I2C_CTL_RD | FPGA_I2C_CTL_BG; + } else { + + ret = fpga_data_write(fpga_i2c, reg->i2c_data_buf, data, length); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c date buf failed, reg addr:0x%x, write len:%d, ret:%d.\n", + reg->i2c_data_buf, length, ret); + goto exit; + } + op = FPGA_I2C_CTL_WR | FPGA_I2C_CTL_BG ; + } + + ret = fpga_reg_write(fpga_i2c, reg->i2c_ctrl, op); + if (ret) { + FPGA_I2C_ERROR("write fpga i2c control reg failed, reg addr:0x%x, value:%d, ret:%d.\n", + reg->i2c_ctrl, op, ret); + goto exit; + } + + ret = fpga_i2c_wait(fpga_i2c); + if (ret) { + FPGA_I2C_ERROR("wait fpga i2c status timeout.\n"); + goto exit; + } + + ret = fpga_i2c_check_status(fpga_i2c); + if (ret) { + FPGA_I2C_ERROR("check fpga i2c status error.\n"); + goto exit; + } + + if (is_read) { + + ret = fpga_data_read(fpga_i2c, reg->i2c_data_buf, data, length); + if (ret) { + FPGA_I2C_ERROR("read fpga i2c data buf failed, reg addr:0x%x, read len:%d, ret:%d.\n", + reg->i2c_data_buf, length, ret); + goto exit; + } + } + +exit: + return ret; +} + +static int fpga_i2c_write(fpga_i2c_dev_t *fpga_i2c, int target, + u8 *data, int length, int i2c_msg_num) +{ + int ret, i; + fpga_i2c_reg_addr_t *i2c_addr_desc; + + if (i2c_msg_num == I2C_READ_MSG_NUM) { + + if (length > I2C_REG_MAX_WIDTH) { + FPGA_I2C_ERROR("read reg addr len %d, more than max length.\n", length); + return -EINVAL; + } + + i2c_addr_desc = &fpga_i2c->i2c_addr_desc; + for (i = 0; i < length; i++) { + i2c_addr_desc->read_reg_addr[i] = data[length -i -1]; + FPGA_I2C_VERBOSE("%02d : %02x\n", i, i2c_addr_desc->read_reg_addr[i]); + } + i2c_addr_desc->reg_addr_len = length; + ret = 0; + } else { + + ret = fpga_i2c_do_work(fpga_i2c, target, data, length, 0); + } + + return ret; +} + +/** + * fpga_i2c_read - receive data from the bus. + * @i2c: The struct fpga_i2c_dev_t. + * @target: Target address. + * @data: Pointer to the location to store the datae . + * @length: Length of the data. + * + * The address is sent over the bus, then the data is read. + * + * Returns 0 on success, otherwise a negative errno. + */ +static int fpga_i2c_read(fpga_i2c_dev_t *fpga_i2c, int target, + u8 *data, int length) +{ + int ret, offset_size; + int i, tmp_val; + fpga_i2c_reg_addr_t *i2c_addr_desc; + uint8_t i2c_reg_addr_len; + uint8_t *i2c_read_addr_buf; + + offset_size = 0; + i2c_addr_desc = &fpga_i2c->i2c_addr_desc; + i2c_reg_addr_len = i2c_addr_desc->reg_addr_len; + i2c_read_addr_buf = &i2c_addr_desc->read_reg_addr[0]; + + while (1) { + if (length <= fpga_i2c->reg.i2c_data_buf_len) { + return fpga_i2c_do_work(fpga_i2c, target, data + offset_size, length, 1); + } + + ret = fpga_i2c_do_work(fpga_i2c, target, data + offset_size, fpga_i2c->reg.i2c_data_buf_len, 1); + if (ret != 0) { + FPGA_I2C_ERROR("fpga_i2c_read failed, i2c addr:0x%x, offset:0x%x, ret:%d.\n", + target, offset_size, ret); + return ret; + } + + tmp_val = i2c_read_addr_buf[0]; + tmp_val += fpga_i2c->reg.i2c_data_buf_len; + if (tmp_val > 0xff) { + i2c_read_addr_buf[0] = tmp_val & 0xff; + for (i = 1; i < i2c_reg_addr_len; i++) { + if (i2c_read_addr_buf[i] == 0xff) { + i2c_read_addr_buf[i] = 0; + } else { + i2c_read_addr_buf[i]++; + break; + } + } + } else { + i2c_read_addr_buf[0] = tmp_val & 0xff; + } + offset_size += fpga_i2c->reg.i2c_data_buf_len; + length -= fpga_i2c->reg.i2c_data_buf_len; + } + + return ret; +} + +static void fpga_i2c_reset(fpga_i2c_dev_t *fpga_i2c) { + fpga_i2c_reset_cfg_t *reset_cfg; + uint32_t reset_addr; + + reset_cfg = &fpga_i2c->reset_cfg; + reset_addr = reset_cfg->reset_addr; + if (reset_cfg->reset_delay_b) { + usleep_range(reset_cfg->reset_delay_b, reset_cfg->reset_delay_b + 1); + } + + fpga_reg_write_32(fpga_i2c, reset_addr, reset_cfg->reset_on); + if (reset_cfg->reset_delay) { + usleep_range(reset_cfg->reset_delay, reset_cfg->reset_delay + 1); + } + + fpga_reg_write_32(fpga_i2c, reset_addr, reset_cfg->reset_off); + if (reset_cfg->reset_delay_a) { + usleep_range(reset_cfg->reset_delay_a, reset_cfg->reset_delay_a + 1); + } + + return; +} + +/** + * fpga_i2c_xfer - The driver's master_xfer function. + * @adap: Pointer to the i2c_adapter structure. + * @msgs: Pointer to the messages to be processed. + * @num: Length of the MSGS array. + * + * Returns the number of messages processed, or a negative errno on + * failure. + */ +static int fpga_i2c_adapter_init(fpga_i2c_dev_t *fpga_i2c) +{ + int ret; + fpga_i2c_reg_t *reg; + + reg = &fpga_i2c->reg; + + ret = 0; + ret += fpga_reg_write(fpga_i2c, reg->i2c_scale, fpga_i2c->i2c_scale_value); + ret += fpga_reg_write(fpga_i2c, reg->i2c_filter, fpga_i2c->i2c_filter_value); + ret += fpga_reg_write(fpga_i2c, reg->i2c_stretch, fpga_i2c->i2c_stretch_value); + if (ret < 0) { + FPGA_I2C_ERROR("fpga_i2c_init failed.\n"); + return ret; + } + + FPGA_I2C_VERBOSE("fpga_i2c_init ok.\n"); + return 0; +} + +static int fpga_i2c_params_check(fpga_i2c_dev_t *fpga_i2c) +{ + int ret; + fpga_i2c_reg_t *reg; + uint8_t i2c_scale_value, i2c_filter_value, i2c_stretch_value; + + reg = &fpga_i2c->reg; + ret = 0; + ret += fpga_reg_read(fpga_i2c, reg->i2c_scale, &i2c_scale_value); + ret += fpga_reg_read(fpga_i2c, reg->i2c_filter, &i2c_filter_value); + ret += fpga_reg_read(fpga_i2c, reg->i2c_stretch, &i2c_stretch_value); + if (ret < 0) { + FPGA_I2C_ERROR("read fpga i2c params failed.\n"); + return 1; + } + + if ((i2c_scale_value != fpga_i2c->i2c_scale_value) + || (i2c_filter_value != fpga_i2c->i2c_filter_value) + || (i2c_stretch_value != fpga_i2c->i2c_stretch_value)) { + FPGA_I2C_ERROR("fpga i2c params check error, read value: i2c_scale 0x%x, i2c_filter:0x%x, i2c_stretch:0x%x.\n", + i2c_scale_value, i2c_filter_value, i2c_stretch_value); + FPGA_I2C_ERROR("fpga i2c params check error, config value: i2c_scale 0x%x, i2c_filter:0x%x, i2c_stretch:0x%x.\n", + fpga_i2c->i2c_scale_value, fpga_i2c->i2c_filter_value, fpga_i2c->i2c_stretch_value); + return 1; + } + + FPGA_I2C_VERBOSE("fpga i2c params check ok.\n"); + return 0; +} + +static int fpga_i2c_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct i2c_msg *pmsg; + int i; + int ret; + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_addr_t *i2c_addr_desc; + + fpga_i2c = i2c_get_adapdata(adap); + + if (num != I2C_READ_MSG_NUM && num != I2C_WRITE_MSG_NUM) { + FPGA_I2C_ERROR("unsupport i2c_msg len:%d.\n", num); + return -EINVAL; + } + + if ((num == I2C_WRITE_MSG_NUM) && (msgs[0].len > fpga_i2c->reg.i2c_data_buf_len)) { + FPGA_I2C_ERROR("unsupport i2c_msg type:msg[0].flag:0x%x, buf len:0x%x.\n", + msgs[0].flags, msgs[0].len); + return -EINVAL; + } + + if (num == I2C_READ_MSG_NUM ) { + if ((msgs[0].flags & I2C_M_RD) ||!(msgs[1].flags & I2C_M_RD)) { + FPGA_I2C_ERROR("unsupport i2c_msg type:msg[0].flag:0x%x, msg[1].flag:0x%x.\n", + msgs[0].flags, msgs[1].flags); + return -EINVAL; + } + } + + if (fpga_i2c_is_busy(fpga_i2c)) { + FPGA_I2C_ERROR("fpga i2c adapter %d is busy, do reset.\n", adap->nr); + if (fpga_i2c->reset_cfg.i2c_adap_reset_flag == 1) { + + fpga_i2c_reset(fpga_i2c); + + fpga_i2c_adapter_init(fpga_i2c); + } + return -EAGAIN; + } + + if (fpga_i2c->i2c_params_check && fpga_i2c_params_check(fpga_i2c)) { + FPGA_I2C_ERROR("fpga i2c params check failed, try to reinitialize.\n"); + fpga_i2c_adapter_init(fpga_i2c); + } + + ret = 0; + i2c_addr_desc = &fpga_i2c->i2c_addr_desc; + i2c_addr_desc->reg_addr_len = 0; + mem_clear(i2c_addr_desc->read_reg_addr, sizeof(i2c_addr_desc->read_reg_addr)); + + for (i = 0; ret == 0 && i < num; i++) { + pmsg = &msgs[i]; + FPGA_I2C_VERBOSE("Doing %s %d byte(s) to/from 0x%02x - %d of %d messages\n", + pmsg->flags & I2C_M_RD ? "read" : "write", pmsg->len, pmsg->addr, i + 1, num); + + if (pmsg->flags & I2C_M_RD) { + ret = fpga_i2c_read(fpga_i2c, pmsg->addr, pmsg->buf, pmsg->len); + + if ((pmsg->len == 1) && (pmsg->flags & I2C_M_RECV_LEN)) { + if ((ret != 0) || (pmsg->buf[0] > I2C_SMBUS_BLOCK_MAX)) { + FPGA_I2C_ERROR("smbus block data read failed, ret:%d, read len:%u.\n", + ret, pmsg->buf[0]); + return -EPROTO; + } + pmsg->len = 1 + pmsg->buf[0]; + FPGA_I2C_VERBOSE("smbus block data read, read len:%d.\n", pmsg->len); + ret = fpga_i2c_read(fpga_i2c, pmsg->addr, pmsg->buf, pmsg->len); + } + } else { + ret = fpga_i2c_write(fpga_i2c, pmsg->addr, pmsg->buf, pmsg->len, num); + } + } + + return (ret != 0) ? ret : num; +} + +static u32 fpga_i2c_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static const struct i2c_algorithm fpga_i2c_algo = { + .master_xfer = fpga_i2c_xfer, + .functionality = fpga_i2c_functionality, +}; + +static struct i2c_adapter fpga_i2c_ops = { + .owner = THIS_MODULE, + .name = "wb_fpga_i2c", + .algo = &fpga_i2c_algo, +}; + +static int fpga_i2c_config_init(fpga_i2c_dev_t *fpga_i2c) +{ + int ret = 0, rv = 0; + fpga_i2c_reg_t *reg; + fpga_i2c_reset_cfg_t *reset_cfg; + struct device *dev; + uint32_t i2c_offset_reg, i2c_data_buf_len_reg; + int32_t i2c_offset_val; + + fpga_i2c_bus_device_t *fpga_i2c_bus_device; + + dev = fpga_i2c->dev; + reg = &fpga_i2c->reg; + reset_cfg = &fpga_i2c->reset_cfg; + + i2c_offset_val = 0; + + if (dev->of_node) { + ret = 0; + ret += of_property_read_u32(dev->of_node, "i2c_ext_9548_addr", ®->i2c_ext_9548_addr); + ret += of_property_read_u32(dev->of_node, "i2c_ext_9548_chan", ®->i2c_ext_9548_chan); + ret += of_property_read_u32(dev->of_node, "i2c_slave", ®->i2c_slave); + ret += of_property_read_u32(dev->of_node, "i2c_reg", ®->i2c_reg); + ret += of_property_read_u32(dev->of_node, "i2c_data_len", ®->i2c_data_len); + ret += of_property_read_u32(dev->of_node, "i2c_ctrl", ®->i2c_ctrl); + ret += of_property_read_u32(dev->of_node, "i2c_status", ®->i2c_status); + ret += of_property_read_u32(dev->of_node, "i2c_scale", ®->i2c_scale); + ret += of_property_read_u32(dev->of_node, "i2c_filter", ®->i2c_filter); + ret += of_property_read_u32(dev->of_node, "i2c_stretch", ®->i2c_stretch); + ret += of_property_read_u32(dev->of_node, "i2c_ext_9548_exits_flag", ®->i2c_ext_9548_exits_flag); + ret += of_property_read_u32(dev->of_node, "i2c_reg_len", ®->i2c_reg_len); + ret += of_property_read_u32(dev->of_node, "i2c_in_9548_chan", ®->i2c_in_9548_chan); + ret += of_property_read_u32(dev->of_node, "i2c_data_buf", ®->i2c_data_buf); + ret += of_property_read_string(dev->of_node, "dev_name", &fpga_i2c->dev_name); + ret += of_property_read_u32(dev->of_node, "i2c_scale_value", &fpga_i2c->i2c_scale_value); + ret += of_property_read_u32(dev->of_node, "i2c_filter_value", &fpga_i2c->i2c_filter_value); + ret += of_property_read_u32(dev->of_node, "i2c_stretch_value", &fpga_i2c->i2c_stretch_value); + ret += of_property_read_u32(dev->of_node, "i2c_timeout", &fpga_i2c->i2c_timeout); + ret += of_property_read_u32(dev->of_node, "i2c_func_mode", &fpga_i2c->i2c_func_mode); + ret += of_property_read_u32(dev->of_node, "i2c_reset_addr", &reset_cfg->reset_addr); + ret += of_property_read_u32(dev->of_node, "i2c_reset_on", &reset_cfg->reset_on); + ret += of_property_read_u32(dev->of_node, "i2c_reset_off", &reset_cfg->reset_off); + ret += of_property_read_u32(dev->of_node, "i2c_rst_delay_b", &reset_cfg->reset_delay_b); + ret += of_property_read_u32(dev->of_node, "i2c_rst_delay", &reset_cfg->reset_delay); + ret += of_property_read_u32(dev->of_node, "i2c_rst_delay_a", &reset_cfg->reset_delay_a); + ret += of_property_read_u32(dev->of_node, "i2c_adap_reset_flag", &reset_cfg->i2c_adap_reset_flag); + + if (ret != 0) { + FPGA_I2C_ERROR("dts config error, ret:%d.\n", ret); + ret = -ENXIO; + return ret; + } + + rv = of_property_read_u32(dev->of_node, "i2c_data_buf_len_reg", &i2c_data_buf_len_reg); + if (rv == 0) { + ret = fpga_reg_read_32(fpga_i2c, i2c_data_buf_len_reg, ®->i2c_data_buf_len); + if (ret < 0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c data buf length, reg addr: 0x%x, ret: %d\n", + i2c_data_buf_len_reg, ret); + return ret; + } + FPGA_I2C_VERBOSE("fpga i2c data buf length reg addr: 0x%x, value: %d\n", + i2c_data_buf_len_reg, reg->i2c_data_buf_len); + if (reg->i2c_data_buf_len == 0) { + reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT; + } + } else { + ret = of_property_read_u32(dev->of_node, "i2c_data_buf_len", ®->i2c_data_buf_len); + if (ret != 0) { + reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT; + ret = 0; + } + } + + rv = of_property_read_u32(dev->of_node, "i2c_offset_reg", &i2c_offset_reg); + if (rv == 0) { + ret = fpga_reg_read_32(fpga_i2c, i2c_offset_reg, &i2c_offset_val); + if (ret < 0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c adapter offset value, reg addr: 0x%x, ret: %d\n", + i2c_offset_reg, ret); + return ret; + } + FPGA_I2C_VERBOSE("fpga i2c adapter offset reg addr: 0x%x, value: %d\n", + i2c_offset_reg, i2c_offset_val); + reg->i2c_scale +=i2c_offset_val; + reg->i2c_filter += i2c_offset_val; + reg->i2c_stretch += i2c_offset_val; + reg->i2c_ext_9548_exits_flag += i2c_offset_val; + reg->i2c_ext_9548_addr += i2c_offset_val; + reg->i2c_ext_9548_chan += i2c_offset_val; + reg->i2c_in_9548_chan += i2c_offset_val; + reg->i2c_slave += i2c_offset_val; + reg->i2c_reg += i2c_offset_val; + reg->i2c_reg_len += i2c_offset_val; + reg->i2c_data_len += i2c_offset_val; + reg->i2c_ctrl += i2c_offset_val; + reg->i2c_status += i2c_offset_val; + reg->i2c_data_buf += i2c_offset_val; + } + + ret = of_property_read_u32(dev->of_node, "i2c_err_vec", ®->i2c_err_vec); + if (ret != 0) { + reg->i2c_err_vec = DTS_NO_CFG_FLAG; + FPGA_I2C_VERBOSE("not support i2c_err_vec cfg. ret: %d, set DTS_NO_CFG_FLAG: %d\n", + ret, reg->i2c_err_vec); + ret = 0; /* Not configuring i2c_err_vec is not an error */ + } else { + if (i2c_offset_val != 0) { + reg->i2c_err_vec += i2c_offset_val; + } + } + } else { + if (dev->platform_data == NULL) { + dev_err(fpga_i2c->dev, "Failed to get platform data config.\n"); + ret = -ENXIO; + return ret; + } + fpga_i2c_bus_device = dev->platform_data; + fpga_i2c->dev_name = fpga_i2c_bus_device->dev_name; + fpga_i2c->adap_nr = fpga_i2c_bus_device->adap_nr; + fpga_i2c->i2c_scale_value = fpga_i2c_bus_device->i2c_scale_value; + fpga_i2c->i2c_filter_value = fpga_i2c_bus_device->i2c_filter_value; + fpga_i2c->i2c_stretch_value = fpga_i2c_bus_device->i2c_stretch_value; + fpga_i2c->i2c_timeout = fpga_i2c_bus_device->i2c_timeout; + fpga_i2c->i2c_func_mode = fpga_i2c_bus_device->i2c_func_mode; + fpga_i2c->i2c_params_check = fpga_i2c_bus_device->i2c_func_mode; + + reset_cfg->reset_addr = fpga_i2c_bus_device->i2c_reset_addr; + reset_cfg->reset_on = fpga_i2c_bus_device->i2c_reset_on; + reset_cfg->reset_off = fpga_i2c_bus_device->i2c_reset_off; + reset_cfg->reset_delay_b = fpga_i2c_bus_device->i2c_rst_delay_b; + reset_cfg->reset_delay = fpga_i2c_bus_device->i2c_rst_delay; + reset_cfg->reset_delay_a = fpga_i2c_bus_device->i2c_rst_delay_a; + reset_cfg->i2c_adap_reset_flag = fpga_i2c_bus_device->i2c_adap_reset_flag; + + reg->i2c_ext_9548_addr = fpga_i2c_bus_device->i2c_ext_9548_addr; + reg->i2c_ext_9548_chan = fpga_i2c_bus_device->i2c_ext_9548_chan; + reg->i2c_slave = fpga_i2c_bus_device->i2c_slave; + reg->i2c_reg = fpga_i2c_bus_device->i2c_reg; + reg->i2c_data_len = fpga_i2c_bus_device->i2c_data_len; + reg->i2c_ctrl = fpga_i2c_bus_device->i2c_ctrl; + reg->i2c_status = fpga_i2c_bus_device->i2c_status; + reg->i2c_scale = fpga_i2c_bus_device->i2c_scale; + reg->i2c_filter = fpga_i2c_bus_device->i2c_filter; + reg->i2c_stretch = fpga_i2c_bus_device->i2c_stretch; + reg->i2c_ext_9548_exits_flag = fpga_i2c_bus_device->i2c_ext_9548_exits_flag; + reg->i2c_reg_len = fpga_i2c_bus_device->i2c_reg_len; + reg->i2c_in_9548_chan = fpga_i2c_bus_device->i2c_in_9548_chan; + reg->i2c_data_buf = fpga_i2c_bus_device->i2c_data_buf; + + i2c_data_buf_len_reg = fpga_i2c_bus_device->i2c_data_buf_len_reg; + if (i2c_data_buf_len_reg > 0) { + ret = fpga_reg_read_32(fpga_i2c, i2c_data_buf_len_reg, ®->i2c_data_buf_len); + if (ret < 0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c data buf length, reg addr: 0x%x, ret: %d\n", + i2c_data_buf_len_reg, ret); + return ret; + } + FPGA_I2C_VERBOSE("fpga i2c data buf length reg addr: 0x%x, value: %d\n", + i2c_data_buf_len_reg, reg->i2c_data_buf_len); + if (reg->i2c_data_buf_len == 0) { + reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT; + } + } else { + if (fpga_i2c_bus_device->i2c_data_buf_len == 0) { + reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT; + FPGA_I2C_VERBOSE("not support i2c_data_buf_len cfg, set default_val:%d\n", + reg->i2c_data_buf_len); + } else { + reg->i2c_data_buf_len = fpga_i2c_bus_device->i2c_data_buf_len; + } + } + + i2c_offset_reg = fpga_i2c_bus_device->i2c_offset_reg; + if (i2c_offset_reg > 0) { + rv = fpga_reg_read_32(fpga_i2c, i2c_offset_reg, &i2c_offset_val); + if (rv < 0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c adapter offset value, reg addr: 0x%x, rv: %d\n", + i2c_offset_reg, rv); + return rv; + } + FPGA_I2C_VERBOSE("fpga i2c adapter offset reg addr: 0x%x, value: %d\n", + i2c_offset_reg, i2c_offset_val); + reg->i2c_scale +=i2c_offset_val; + reg->i2c_filter += i2c_offset_val; + reg->i2c_stretch += i2c_offset_val; + reg->i2c_ext_9548_exits_flag += i2c_offset_val; + reg->i2c_ext_9548_addr += i2c_offset_val; + reg->i2c_ext_9548_chan += i2c_offset_val; + reg->i2c_in_9548_chan += i2c_offset_val; + reg->i2c_slave += i2c_offset_val; + reg->i2c_reg += i2c_offset_val; + reg->i2c_reg_len += i2c_offset_val; + reg->i2c_data_len += i2c_offset_val; + reg->i2c_ctrl += i2c_offset_val; + reg->i2c_status += i2c_offset_val; + reg->i2c_data_buf += i2c_offset_val; + } + + if (fpga_i2c_bus_device->i2c_err_vec == 0) { + reg->i2c_err_vec = DTS_NO_CFG_FLAG; + FPGA_I2C_VERBOSE("not support i2c_err_vec cfg, set DTS_NO_CFG_FLAG:%d\n", + reg->i2c_err_vec); + } else { + reg->i2c_err_vec = fpga_i2c_bus_device->i2c_err_vec; + if (i2c_offset_val != 0) { + reg->i2c_err_vec += i2c_offset_val; + } + } + } + + FPGA_I2C_VERBOSE("i2c_ext_9548_addr:0x%x, i2c_ext_9548_chan:0x%x, i2c_slave:0x%x, i2c_reg:0x%x, i2c_data_len:0x%x.\n", + reg->i2c_ext_9548_addr, reg->i2c_ext_9548_chan, reg->i2c_slave, reg->i2c_reg, reg->i2c_data_len); + FPGA_I2C_VERBOSE("i2c_ctrl:0x%x, i2c_status:0x%x, i2c_scale:0x%x, i2c_filter:0x%x, i2c_stretch:0x%x.\n", + reg->i2c_ctrl, reg->i2c_status, reg->i2c_scale, reg->i2c_filter, reg->i2c_stretch); + FPGA_I2C_VERBOSE("i2c_ext_9548_exits_flag:0x%x, i2c_in_9548_chan:0x%x, i2c_data_buf:0x%x, i2c_reg_len:0x%x, i2c_data_buf_len:0x%x.\n", + reg->i2c_ext_9548_exits_flag, reg->i2c_in_9548_chan, reg->i2c_data_buf, reg->i2c_reg_len, reg->i2c_data_buf_len); + FPGA_I2C_VERBOSE("dev_name:%s, i2c_scale_value:0x%x, i2c_filter_value:0x%x, i2c_stretch_value:0x%x, i2c_timeout:0x%x.\n", + fpga_i2c->dev_name, fpga_i2c->i2c_scale_value, fpga_i2c->i2c_filter_value, fpga_i2c->i2c_stretch_value, fpga_i2c->i2c_timeout); + FPGA_I2C_VERBOSE("i2c_reset_addr:0x%x, i2c_reset_on:0x%x, i2c_reset_off:0x%x, i2c_rst_delay_b:0x%x, i2c_rst_delay:0x%x, i2c_rst_delay_a:0x%x.\n", + reset_cfg->reset_addr, reset_cfg->reset_on, reset_cfg->reset_off, reset_cfg->reset_delay_b, reset_cfg->reset_delay, reset_cfg->reset_delay_a); + FPGA_I2C_VERBOSE("i2c_adap_reset_flag:0x%x.\n", reset_cfg->i2c_adap_reset_flag); + FPGA_I2C_VERBOSE("i2c_err_vec:0x%x\n", reg->i2c_err_vec); + + return ret; +} + +static int fpga_i2c_probe(struct platform_device *pdev) +{ + int ret; + fpga_i2c_dev_t *fpga_i2c; + struct device *dev; + + fpga_i2c = devm_kzalloc(&pdev->dev, sizeof(fpga_i2c_dev_t), GFP_KERNEL); + if (!fpga_i2c) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + ret = -ENOMEM; + goto out; + } + + fpga_i2c->dev = &pdev->dev; + + ret = fpga_i2c_config_init(fpga_i2c); + if (ret !=0) { + dev_err(fpga_i2c->dev, "Failed to get fpga i2c dts config.\n"); + goto out; + } + + ret = fpga_i2c_adapter_init(fpga_i2c); + if (ret !=0) { + dev_err(fpga_i2c->dev, "Failed to init fpga i2c adapter.\n"); + goto out; + } + + if (fpga_i2c->dev->of_node) { + fpga_i2c->i2c_params_check = of_property_read_bool(fpga_i2c->dev->of_node, "i2c_params_check"); + } + FPGA_I2C_VERBOSE("fpga i2c params check flag:%d.\n", fpga_i2c->i2c_params_check); + + init_waitqueue_head(&fpga_i2c->queue); + + dev = fpga_i2c->dev; + fpga_i2c->adap = fpga_i2c_ops; + fpga_i2c->adap.timeout = msecs_to_jiffies(fpga_i2c->i2c_timeout); + fpga_i2c->adap.dev.parent = &pdev->dev; + fpga_i2c->adap.dev.of_node = pdev->dev.of_node; + i2c_set_adapdata(&fpga_i2c->adap, fpga_i2c); + platform_set_drvdata(pdev, fpga_i2c); + + if (fpga_i2c->dev->of_node) { + /* adap.nr get from dts aliases */ + ret = i2c_add_adapter(&fpga_i2c->adap); + } else { + fpga_i2c->adap.nr = fpga_i2c->adap_nr; + ret = i2c_add_numbered_adapter(&fpga_i2c->adap); + } + + if (ret < 0) { + dev_info(fpga_i2c->dev, "Failed to add adapter.\n"); + goto fail_add; + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) + of_i2c_register_devices(&fpga_i2c->adap); +#endif + dev_info(fpga_i2c->dev, "registered i2c-%d for %s using mode %d with base address:0x%x, data buf len: %d success.\n", + fpga_i2c->adap.nr, fpga_i2c->dev_name, fpga_i2c->i2c_func_mode, fpga_i2c->reg.i2c_scale, + fpga_i2c->reg.i2c_data_buf_len); + return 0; + +fail_add: + platform_set_drvdata(pdev, NULL); +out: + return ret; +}; + +static int fpga_i2c_remove(struct platform_device *pdev) +{ + fpga_i2c_dev_t *fpga_i2c; + + fpga_i2c = platform_get_drvdata(pdev); + i2c_del_adapter(&fpga_i2c->adap); + platform_set_drvdata(pdev, NULL); + return 0; +}; + +static struct of_device_id fpga_i2c_match[] = { + { + .compatible = "wb-fpga-i2c", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, fpga_i2c_match); + +static struct platform_driver wb_fpga_i2c_driver = { + .probe = fpga_i2c_probe, + .remove = fpga_i2c_remove, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = fpga_i2c_match, + }, +}; + +static int __init wb_fpga_i2c_init(void) +{ + return platform_driver_register(&wb_fpga_i2c_driver); +} + +static void __exit wb_fpga_i2c_exit(void) +{ + platform_driver_unregister(&wb_fpga_i2c_driver); +} + +module_init(wb_fpga_i2c_init); +module_exit(wb_fpga_i2c_exit); +MODULE_DESCRIPTION("fpga i2c adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pca954x_drv.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pca954x_drv.c new file mode 100644 index 000000000000..5845195bb310 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pca954x_drv.c @@ -0,0 +1,525 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fpga_i2c.h" + +extern int i2c_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); + +#define PCA954X_MAX_NCHANS (8) +#define FPGA_INTERNAL_PCA9548 (1) +#define FPGA_EXTERNAL_PCA9548 (2) +#define FPGA_I2C_EXT_9548_EXITS (0x01 << 0) +#define FPGA_I2C_9548_NO_RESET (0x01 << 1) + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) + +int g_fpga_pca954x_debug = 0; +int g_fpga_pca954x_error = 0; + +module_param(g_fpga_pca954x_debug, int, S_IRUGO | S_IWUSR); +module_param(g_fpga_pca954x_error, int, S_IRUGO | S_IWUSR); + +#define FPGA_PCA954X_VERBOSE(fmt, args...) do { \ + if (g_fpga_pca954x_debug) { \ + printk(KERN_INFO "[FPGA_PCA954X][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_PCA954X_ERROR(fmt, args...) do { \ + if (g_fpga_pca954x_error) { \ + printk(KERN_ERR "[FPGA_PCA954X][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +enum pca_type { + pca_9540, + pca_9541, + pca_9542, + pca_9543, + pca_9544, + pca_9545, + pca_9546, + pca_9547, + pca_9548, +}; + +struct pca954x { + enum pca_type type; + struct i2c_adapter *virt_adaps[PCA954X_MAX_NCHANS]; + u8 last_chan; /* last register value */ + uint32_t fpga_9548_flag; + uint32_t fpga_9548_reset_flag; + uint32_t pca9548_base_nr; + struct i2c_client *client; +}; + +struct chip_desc { + u8 nchans; + u8 enable; /* used for muxes only */ + enum muxtype { + pca954x_ismux = 0, + pca954x_isswi + } muxtype; +}; + +/* Provide specs for the PCA954x types we know about */ +static const struct chip_desc chips[] = { + [pca_9540] = { + .nchans = 2, + .enable = 0x4, + .muxtype = pca954x_ismux, + }, + [pca_9541] = { + .nchans = 1, + .muxtype = pca954x_isswi, + }, + [pca_9543] = { + .nchans = 2, + .muxtype = pca954x_isswi, + }, + [pca_9544] = { + .nchans = 4, + .enable = 0x4, + .muxtype = pca954x_ismux, + }, + [pca_9545] = { + .nchans = 4, + .muxtype = pca954x_isswi, + }, + [pca_9547] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + }, + [pca_9548] = { + .nchans = 8, + .muxtype = pca954x_isswi, + }, +}; + +static const struct i2c_device_id fpga_pca954x_id[] = { + { "wb_fpga_pca9540", pca_9540 }, + { "wb_fpga_pca9541", pca_9541 }, + { "wb_fpga_pca9542", pca_9543 }, + { "wb_fpga_pca9543", pca_9543 }, + { "wb_fpga_pca9544", pca_9544 }, + { "wb_fpga_pca9545", pca_9545 }, + { "wb_fpga_pca9546", pca_9545 }, + { "wb_fpga_pca9547", pca_9547 }, + { "wb_fpga_pca9548", pca_9548 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, fpga_pca954x_id); + +static int fpga_file_write(const char *path, int pos, unsigned char *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + FPGA_PCA954X_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + FPGA_PCA954X_ERROR("kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; + +} +static int fpga_device_write(fpga_i2c_dev_t *fpga_i2c, int pos, unsigned char *val, size_t size) +{ + int ret; + + switch (fpga_i2c->i2c_func_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = fpga_file_write(fpga_i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; + default: + FPGA_PCA954X_ERROR("err func mode, write failed.\n"); + return -EINVAL; + } + + return ret; +} + +static int fpga_reg_write(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t val) +{ + int ret; + + ret = fpga_device_write(fpga_i2c, addr, &val, sizeof(uint8_t)); + if (ret < 0) { + FPGA_PCA954X_ERROR("fpga_device_write failed. name:%s, addr:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, val); + return ret; + } + + FPGA_PCA954X_VERBOSE("fpga reg write success, dev name:%s, offset:0x%x, value:0x%x.\n", + fpga_i2c->dev_name, addr, val); + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,7) +static int pca954x_select_chan(struct i2c_adapter *adap, void *client, u32 chan) +{ + struct pca954x *data = i2c_get_clientdata(client); + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_t *reg; + int ret; + u8 regval, i2c_9548_opt; + + while(i2c_parent_is_i2c_adapter(adap)){ + adap = to_i2c_adapter(adap->dev.parent); + } + + FPGA_PCA954X_VERBOSE("root bus:%d, chan:0x%x, 9548 flag:0x%x, 9548 addr:0x%x.\n", + adap->nr, chan, data->fpga_9548_flag, client->addr); + fpga_i2c = i2c_get_adapdata(adap); + reg = &fpga_i2c->reg; + + regval = 1 << chan; + if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) { + ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, regval); + } else { + if (data->fpga_9548_reset_flag == 1) { + i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS & ~(FPGA_I2C_9548_NO_RESET); + } else { + i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS | FPGA_I2C_9548_NO_RESET; + } + FPGA_PCA954X_VERBOSE("fpga pca9548 reset flag:0x%x, opt:0x%x.\n", + data->fpga_9548_reset_flag, i2c_9548_opt); + ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, i2c_9548_opt); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_addr, client->addr); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, regval); + } + + return ret; +} + +static int pca954x_deselect_mux(struct i2c_adapter *adap, void *client, u32 chan) +{ + struct pca954x *data = i2c_get_clientdata(client); + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_t *reg; + int ret; + + while(i2c_parent_is_i2c_adapter(adap)){ + adap = to_i2c_adapter(adap->dev.parent); + } + + fpga_i2c = i2c_get_adapdata(adap); + reg = &fpga_i2c->reg; + /* Deselect active channel */ + data->last_chan = 0; + if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) { + ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, 0); + } else { + + ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, FPGA_I2C_9548_NO_RESET); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, 0); + } + + return ret; +} +#else +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; + struct i2c_adapter *adap; + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_t *reg; + int ret; + u8 regval, i2c_9548_opt; + + adap = muxc->parent; + while(i2c_parent_is_i2c_adapter(adap)){ + adap = to_i2c_adapter(adap->dev.parent); + } + + FPGA_PCA954X_VERBOSE("root bus:%d, chan:0x%x, 9548 flag:0x%x, 9548 addr:0x%x.\n", + adap->nr, chan, data->fpga_9548_flag, client->addr); + fpga_i2c = i2c_get_adapdata(adap); + reg = &fpga_i2c->reg; + + regval = 1 << chan; + if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) { + ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, regval); + } else { + if (data->fpga_9548_reset_flag == 1) { + i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS & ~(FPGA_I2C_9548_NO_RESET); + } else { + i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS | FPGA_I2C_9548_NO_RESET; + } + FPGA_PCA954X_VERBOSE("fpga pca9548 reset flag:0x%x, opt:0x%x.\n", + data->fpga_9548_reset_flag, i2c_9548_opt); + ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, i2c_9548_opt); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_addr, client->addr); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, regval); + } + + return ret; +} + +static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_adapter *adap; + fpga_i2c_dev_t *fpga_i2c; + fpga_i2c_reg_t *reg; + int ret; + + adap = muxc->parent; + while(i2c_parent_is_i2c_adapter(adap)){ + adap = to_i2c_adapter(adap->dev.parent); + } + + fpga_i2c = i2c_get_adapdata(adap); + reg = &fpga_i2c->reg; + ret = 0; + /* Deselect active channel */ + data->last_chan = 0; + + if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) { + ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, 0); + } else { + + ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, FPGA_I2C_9548_NO_RESET); + ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, 0); + } + + return ret; +} +#endif +/* + * I2C init/probing/exit functions + */ +static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + int num, force, class; + struct pca954x *data; + int ret = -ENODEV; + struct device *dev; + int dynamic_nr = 1; + fpga_pca954x_device_t *fpga_pca954x_device; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(4,6,7) + struct i2c_mux_core *muxc; +#endif + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) { + dev_err(&client->dev, "i2c adapter:%d, unsupport I2C_FUNC_SMBUS_BYTE.\n", adap->nr); + goto err; + } + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) + data = kzalloc(sizeof(struct pca954x), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "kzalloc failed.\n"); + ret = -ENOMEM; + goto err; + } + + i2c_set_clientdata(client, data); +#else + muxc = i2c_mux_alloc(adap, &client->dev, + PCA954X_MAX_NCHANS, sizeof(*data), 0, + pca954x_select_chan, pca954x_deselect_mux); + if (!muxc) { + dev_err(&client->dev, "i2c_mux_alloc failed.\n"); + return -ENOMEM; + } + data = i2c_mux_priv(muxc); + i2c_set_clientdata(client, muxc); + data->client = client; +#endif + + dev = &client->dev; + if (dev == NULL) { + dev_err(&client->dev, "dev is NULL.\n"); + ret = -ENODEV; + goto exit_free; + } + + if (dev->of_node == NULL) { + if (client->dev.platform_data == NULL) { + dev_err(&client->dev, "Failed to get 954x platform data config.\n"); + ret = -EINVAL; + goto exit_free; + } + fpga_pca954x_device = client->dev.platform_data; + data->fpga_9548_flag = fpga_pca954x_device->fpga_9548_flag; + data->fpga_9548_reset_flag = fpga_pca954x_device->fpga_9548_reset_flag; + data->pca9548_base_nr = fpga_pca954x_device->pca9548_base_nr; + if (data->pca9548_base_nr == 0) { + + dynamic_nr = 1; + } else { + dynamic_nr = 0; + FPGA_PCA954X_VERBOSE("pca9548_base_nr:%u.\n", data->pca9548_base_nr); + } + } else { + data->type = id->driver_data; + /* BUS ID */ + ret = of_property_read_u32(dev->of_node, "fpga_9548_flag", &data->fpga_9548_flag); + ret += of_property_read_u32(dev->of_node, "fpga_9548_reset_flag", &data->fpga_9548_reset_flag); + if (ret != 0) { + dev_err(&client->dev, "Failed to get 954x dts config, ret:%d.\n", ret); + ret = -EINVAL; + goto exit_free; + } + if (of_property_read_u32(dev->of_node, "pca9548_base_nr", &data->pca9548_base_nr)) { + + dynamic_nr = 1; + FPGA_PCA954X_VERBOSE("pca9548_base_nr not found, use dynamic adap number"); + } else { + dynamic_nr = 0; + FPGA_PCA954X_VERBOSE("pca9548_base_nr:%u.\n", data->pca9548_base_nr); + } + } + + if (data->fpga_9548_flag != FPGA_EXTERNAL_PCA9548 && data->fpga_9548_flag != FPGA_INTERNAL_PCA9548) { + dev_err(&client->dev, "Error: fpga 954x flag config error, value:0x%x.\n", data->fpga_9548_flag); + ret = -EINVAL; + goto exit_free; + } + + data->type = id->driver_data; + data->last_chan = 0; /* force the first selection */ + + /* Now create an adapter for each channel */ + for (num = 0; num < chips[data->type].nchans; num++) { + if (dynamic_nr == 1) { + force = 0; /* dynamic adap number */ + } else { + force = data->pca9548_base_nr + num; + } + class = 0; /* no class by default */ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) + data->virt_adaps[num] = + i2c_add_mux_adapter(adap, &client->dev, client, + force, num, class, pca954x_select_chan, pca954x_deselect_mux); + + if (data->virt_adaps[num] == NULL) { + ret = -ENODEV; + dev_err(&client->dev, "Failed to register multiplexed adapter %d as bus %d\n", + num, force); + goto virt_reg_failed; + } +#else + ret = i2c_mux_add_adapter(muxc, force, num, class); + if (ret) { + dev_err(&client->dev, "Failed to register multiplexed adapter %d as bus %d\n", + num, force); + goto virt_reg_failed; + } +#endif + } /* end for num = 0; num < chips[data->type].nchans... */ + + dev_info(&client->dev, "registered %d multiplexed busses for I2C %s %s\n", + num, chips[data->type].muxtype == pca954x_ismux ? "mux" : "switch", client->name); + + return 0; + +virt_reg_failed: +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) + for (num--; num >= 0; num--) + i2c_del_mux_adapter(data->virt_adaps[num]); +exit_free: + kfree(data); +#else +exit_free: + i2c_mux_del_adapters(muxc); +#endif +err: + return ret; +} + +static int fpga_i2c_pca954x_remove(struct i2c_client *client) +{ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) + struct pca954x *data = i2c_get_clientdata(client); + const struct chip_desc *chip = &chips[data->type]; + int i; + + for (i = 0; i < chip->nchans; ++i) + if (data->virt_adaps[i]) { + i2c_del_mux_adapter(data->virt_adaps[i]); + data->virt_adaps[i] = NULL; + } + + kfree(data); +#else + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + i2c_mux_del_adapters(muxc); +#endif + + return 0; +} + +static struct i2c_driver fpga_i2c_pca954x_driver = { + .driver = { + .name = "wb_fpga_pca954x", + .owner = THIS_MODULE, + }, + .probe = fpga_i2c_pca954x_probe, + .remove = fpga_i2c_pca954x_remove, + .id_table = fpga_pca954x_id, +}; + +static int __init fpga_i2c_pca954x_init(void) +{ + int ret; + + ret = i2c_add_driver(&fpga_i2c_pca954x_driver); + return ret; +} + +static void __exit fpga_i2c_pca954x_exit(void) +{ + i2c_del_driver(&fpga_i2c_pca954x_driver); +} + +module_init(fpga_i2c_pca954x_init); +module_exit(fpga_i2c_pca954x_exit); +MODULE_DESCRIPTION("fpga pca954x driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pcie.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pcie.c new file mode 100644 index 000000000000..aedcc78dab90 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_fpga_pcie.c @@ -0,0 +1,164 @@ +/* + * wb_fpga_pcie.c + * ko to enable fpga pcie + */ +#include +#include +#include +#include +#include + +#define FPGA_MSI_IRQ_NUM (14) +#define FPGA_MSI_IRQ_BEGIN (0) +#define XILINX_FPGA_USE_MSI (0) +#define XILINX_FPGA_NUSE_MSI (1) + +int g_fpga_pcie_dev_debug = 0; +int g_fpga_pcie_dev_error = 0; +module_param(g_fpga_pcie_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_fpga_pcie_dev_error, int, S_IRUGO | S_IWUSR); + +#define FPGA_PCIE_DEV_VERBOSE(fmt, args...) do { \ + if (g_fpga_pcie_dev_debug) { \ + printk(KERN_INFO "[FPGA_PCIE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_PCIE_DEV_ERROR(fmt, args...) do { \ + if (g_fpga_pcie_dev_error) { \ + printk(KERN_ERR "[FPGA_PCIE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef struct wb_fpga_pcie_s { + struct pci_dev *pci_dev; + int driver_data; +} wb_fpga_pcie_t; + +static void fpga_pcie_recover(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct resource *mem_base; + u32 bar0_val; + int ret; + + mem_base = &pdev->resource[0]; + ret = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &bar0_val); + if (ret) { + FPGA_PCIE_DEV_ERROR("pci_read_config_dword failed ret %d.\n", ret); + return; + } + FPGA_PCIE_DEV_VERBOSE("mem_base->start[0x%llx], bar0_val[0x%x], ret %d.\n", + mem_base->start, bar0_val, ret); + + if (bar0_val != mem_base->start) { + ret = pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, mem_base->start); + if (ret) { + FPGA_PCIE_DEV_ERROR("pci_write_config_dword mem_base->start[0x%llx], failed ret %d.\n", mem_base->start, ret); + return; + } + FPGA_PCIE_DEV_VERBOSE("pci_write_config_dword mem_base->start[0x%llx] success.\n", mem_base->start); + } else { + FPGA_PCIE_DEV_VERBOSE("mem_base->start[0x%llx], bar0_val[0x%x], do nothing.\n", + mem_base->start, bar0_val); + } +} + +static int fpga_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int err; + wb_fpga_pcie_t *wb_fpga_pcie; + + FPGA_PCIE_DEV_VERBOSE("Enter vendor 0x%x, subsystem_vendor 0x%x.\n", pdev->vendor, pdev->subsystem_vendor); + + wb_fpga_pcie = devm_kzalloc(&pdev->dev, sizeof(wb_fpga_pcie_t), GFP_KERNEL); + if (!wb_fpga_pcie) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + fpga_pcie_recover(pdev, id); + + /* enable device: ask low-level code to enable I/O and memory */ + FPGA_PCIE_DEV_VERBOSE("start pci_enable_device!\n"); + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Failed to enable pci device, ret:%d.\n", err); + return err; + } + + FPGA_PCIE_DEV_VERBOSE("start pci_set_master!\n"); + pci_set_master(pdev); + + wb_fpga_pcie->driver_data = id->driver_data; + wb_fpga_pcie->pci_dev = pdev; + pci_set_drvdata(pdev, wb_fpga_pcie); + + if (wb_fpga_pcie->driver_data == XILINX_FPGA_USE_MSI) { + FPGA_PCIE_DEV_VERBOSE("start pci_enable_msi_range!\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,152) + err = pci_enable_msi_range(pdev, FPGA_MSI_IRQ_BEGIN + 1, FPGA_MSI_IRQ_NUM); +#else + err = pci_alloc_irq_vectors_affinity(pdev, FPGA_MSI_IRQ_BEGIN + 1, + FPGA_MSI_IRQ_NUM, PCI_IRQ_MSI, NULL); +#endif + if (err != FPGA_MSI_IRQ_NUM) { + FPGA_PCIE_DEV_ERROR("pci_enable_msi_block err %d FPGA_MSI_IRQ_NUM %d.\n", err, + FPGA_MSI_IRQ_NUM); + dev_err(&pdev->dev, "Failed to enable pci msi, ret:%d.\n", err); + return -EINVAL; + } + } + + dev_info(&pdev->dev, "fpga pci device init success.\n"); + return 0; +} + +static void fpga_pcie_remove(struct pci_dev *pdev) +{ + wb_fpga_pcie_t *wb_fpga_pcie; + + FPGA_PCIE_DEV_VERBOSE("fpga_pcie_remove.\n"); + + wb_fpga_pcie = pci_get_drvdata(pdev); + if (wb_fpga_pcie->driver_data == XILINX_FPGA_USE_MSI) { + FPGA_PCIE_DEV_VERBOSE("start pci_disable_msi!\n"); + pci_disable_msi(pdev); + } + + pci_disable_device(pdev); + return; +} + +static const struct pci_device_id fpga_pci_ids[] = { + { PCI_DEVICE(0x10ee, 0x7022), .driver_data = XILINX_FPGA_USE_MSI}, + { PCI_DEVICE(0x10ee, 0x7011), .driver_data = XILINX_FPGA_NUSE_MSI}, + {0} +}; +MODULE_DEVICE_TABLE(pci, fpga_pci_ids); + +static struct pci_driver wb_fpga_pcie_driver = { + .name = "wb_fpga_pcie", + .id_table = fpga_pci_ids,/* only dynamic id's */ + .probe = fpga_pcie_probe, + .remove = fpga_pcie_remove, +}; + +static int __init wb_fpga_pcie_init(void) +{ + + FPGA_PCIE_DEV_VERBOSE("wb_fpga_pcie_init enter!\n"); + return pci_register_driver(&wb_fpga_pcie_driver); +} + +static void __exit wb_fpga_pcie_exit(void) +{ + FPGA_PCIE_DEV_VERBOSE("wb_fpga_pcie_exit enter!\n"); + pci_unregister_driver(&wb_fpga_pcie_driver); + return; +} + +module_init(wb_fpga_pcie_init); +module_exit(wb_fpga_pcie_exit); +MODULE_DESCRIPTION("fpga pcie driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_d1500.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_d1500.c new file mode 100644 index 000000000000..7d5d5da87ea7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_d1500.c @@ -0,0 +1,367 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2011, 2012 Cavium Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GPIO_NAME "wb_gpio_d1500" + +#define GPIO_BASE (0x500) +#define GP_IO_SEL (GPIO_BASE + 0x4) +#define GP_LVL (GPIO_BASE + 0xC) +#define GPI_NMI_EN (GPIO_BASE + 0x28) +#define GPI_NMI_STS (GPIO_BASE + 0x2a) +#define GPI_INV (GPIO_BASE + 0x2c) +#define GPIO_USE_SEL2 (GPIO_BASE + 0x30) +#define GP_IO_SEL2 (GPIO_BASE + 0x34) +#define GP_LVL2 (GPIO_BASE + 0x38) +#define GPI_NMI_EN_2 (GPIO_BASE + 0x3c) +#define GPI_NMI_STS_2 (GPIO_BASE + 0x3e) +#define GPIO_USE_SEL3 (GPIO_BASE + 0x40) +#define GP_IO_SEL3 (GPIO_BASE + 0x44) +#define GP_LVL3 (GPIO_BASE + 0x48) +#define GPI_NMI_EN_3 (GPIO_BASE + 0x50) +#define GPI_NMI_STS_3 (GPIO_BASE + 0x54) + +#define GPIO_BASE_ID (0) +#define BANKSIZE (32) +#define D1500_GPIO_PIN_NUM (96) +#define CELL_NUM (2) + +int g_gpio_d1500_debug = 0; +int g_gpio_d1500_error = 0; +module_param(g_gpio_d1500_debug, int, S_IRUGO | S_IWUSR); +module_param(g_gpio_d1500_error, int, S_IRUGO | S_IWUSR); + +#define GPIO_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_gpio_d1500_debug) { \ + printk(KERN_ERR "[GPIO-D1500][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define GPIO_DEBUG_ERROR(fmt, args...) do { \ + if (g_gpio_d1500_error) { \ + printk(KERN_ERR "[GPIO-D1500][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static DEFINE_SPINLOCK(sio_lock); + +struct gpio_d1500_t { + struct gpio_chip chip; + u64 register_base; +}; + +static int wb_gpio_get(struct gpio_chip *gc, unsigned gpio_num) +{ + u32 data = 0; + unsigned int bank, offset; + unsigned long flags; + + bank = gpio_num / BANKSIZE; + offset = gpio_num % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GP_LVL) & (1 << offset); + if (data) { + data = 1; + } + } else if (bank == 1) { + data = inl(GP_LVL2) & (1 << offset); + if (data) { + data = 1; + } + } else if (bank == 2) { + data = inl(GP_LVL3) & (1 << offset); + if (data) { + data = 1; + } + } + spin_unlock_irqrestore(&sio_lock, flags); + + return data; +} + +static int wb_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num) +{ + u32 data; + unsigned int bank, offset; + unsigned long flags; + + bank = gpio_num / BANKSIZE; + offset = gpio_num % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GP_IO_SEL); + data = data | (1 << offset); + outl(data, GP_IO_SEL); + } else if (bank == 1) { + data = inl(GP_IO_SEL2); + data = data | (1 << offset); + outl(data, GP_IO_SEL2); + } else if (bank == 2) { + data = inl(GP_IO_SEL3); + data = data | (1 << offset); + outl(data, GP_IO_SEL3); + } + spin_unlock_irqrestore(&sio_lock, flags); + + return 0; +} + +static void wb_gpio_set(struct gpio_chip *gc, + unsigned gpio_num, int val) +{ + u32 data; + unsigned int bank, offset; + unsigned long flags; + + bank = gpio_num / BANKSIZE; + offset = gpio_num % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GP_LVL); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL); + } else if (bank == 1) { + data = inl(GP_LVL2); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL2); + } else if (bank == 2) { + data = inl(GP_LVL3); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL3); + } + spin_unlock_irqrestore(&sio_lock, flags); + + return; +} + +static int wb_gpio_direction_out(struct gpio_chip *gc, + unsigned gpio_num, int val) +{ + u32 data; + unsigned int bank, offset; + unsigned long flags; + + bank = gpio_num / BANKSIZE; + offset = gpio_num % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GP_IO_SEL); + data = data & ~(1 << offset); + outl(data, GP_IO_SEL); + + data = inl(GP_LVL); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL); + } else if (bank == 1) { + data = inl(GP_IO_SEL2); + data = data & ~(1 << offset); + outl(data, GP_IO_SEL2); + + data = inl(GP_LVL2); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL2); + } else if (bank == 2) { + data = inl(GP_IO_SEL3); + data = data & ~(1 << offset); + outl(data, GP_IO_SEL3); + + data = inl(GP_LVL3); + if (val) { + data = data | (1 << offset); + } else { + data = data & ~(1 << offset); + } + outl(data, GP_LVL3); + } + spin_unlock_irqrestore(&sio_lock, flags); + + return 0; +} + +#ifdef CONFIG_OF +static int wb_gpio_of_xlate(struct gpio_chip *chip, + const struct of_phandle_args *gpio_desc, + u32 *flags) +{ + if (chip->of_gpio_n_cells < 2) { + return -EINVAL; + } + + if (flags) { + *flags = gpio_desc->args[1]; + } + + return gpio_desc->args[0]; +} +#endif + +static int wb_gpio_request(struct gpio_chip *chip, unsigned int offset) +{ + u32 data; + unsigned int bank, tmp_offset; + unsigned long flags; + + bank = offset / BANKSIZE; + tmp_offset = offset % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GPIO_BASE); + data = data | (1 << tmp_offset); + outl(data, GPIO_BASE); + } else if (bank == 1) { + data = inl(GPIO_USE_SEL2); + data = data | (1 << tmp_offset); + outl(data, GPIO_USE_SEL2); + } else if (bank == 2) { + data = inl(GPIO_USE_SEL3); + data = data | (1 << tmp_offset); + outl(data, GPIO_USE_SEL3); + } + spin_unlock_irqrestore(&sio_lock, flags); + + return 0; +} + +#if 0 +static void wb_gpio_free(struct gpio_chip *chip, unsigned int offset) +{ + u32 data; + unsigned int bank, tmp_offset; + unsigned long flags; + + bank = offset / BANKSIZE; + tmp_offset = offset % BANKSIZE; + + spin_lock_irqsave(&sio_lock, flags); + if (bank == 0) { + data = inl(GPIO_BASE); + data = data & ~(1 << tmp_offset); + outl(data, GPIO_BASE); + } else if (bank == 1) { + data = inl(GPIO_USE_SEL2); + data = data & ~(1 << tmp_offset); + outl(data, GPIO_USE_SEL2); + } else if (bank == 2) { + data = inl(GPIO_USE_SEL3); + data = data & ~(1 << tmp_offset); + outl(data, GPIO_USE_SEL3); + } + + spin_unlock_irqrestore(&sio_lock, flags); + + return; +} +#endif + +static struct gpio_chip wb_gpio_chip = { + .label = GPIO_NAME, + .owner = THIS_MODULE, + .base = GPIO_BASE_ID, + .get = wb_gpio_get, + .direction_input = wb_gpio_direction_in, + .set = wb_gpio_set, + .direction_output = wb_gpio_direction_out, +#ifdef CONFIG_OF + .of_xlate = wb_gpio_of_xlate, +#endif + .request = wb_gpio_request, + .ngpio = D1500_GPIO_PIN_NUM, +#ifdef CONFIG_OF + .of_gpio_n_cells = CELL_NUM, +#endif + .can_sleep = false, +}; + +static int wb_gpio_probe(struct platform_device *pdev) +{ + struct gpio_d1500_t *gpio; + int err; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) { + dev_err(&pdev->dev, "gpio kzalloc failed\n"); + return -ENOMEM; + } + + wb_gpio_chip.parent = &pdev->dev; + gpio->register_base = GPIO_BASE; + gpio->chip = wb_gpio_chip; + pdev->dev.platform_data = &wb_gpio_chip; + err = devm_gpiochip_add_data(&pdev->dev, &wb_gpio_chip, gpio); + if (err) { + dev_err(&pdev->dev, "gpiochip add failed\n"); + return err; + } + + dev_info(&pdev->dev, "register %llu gpio success.\n", gpio->register_base); + + return 0; +} + +static int wb_gpio_remove(struct platform_device *pdev) +{ + dev_info(&pdev->dev, "unregister d1500 gpio success\n"); + return 0; +} + +static const struct of_device_id gpio_d1500_match[] = { + { + .compatible = "wb_gpio_d1500", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, gpio_d1500_match); + +static struct platform_driver wb_gpio_driver = { + .driver = { + .name = GPIO_NAME, + .of_match_table = gpio_d1500_match, + }, + .probe = wb_gpio_probe, + .remove = wb_gpio_remove, +}; + +module_platform_driver(wb_gpio_driver); + +MODULE_DESCRIPTION("d1500 gpio driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_device.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_device.c new file mode 100644 index 000000000000..75f883b5909d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_gpio_device.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +static int g_wb_gpio_device_debug = 0; +static int g_wb_gpio_device_error = 0; + +module_param(g_wb_gpio_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_gpio_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_GPIO_DEVICE_VERBOSE(fmt, args...) do { \ + if (g_wb_gpio_device_debug) { \ + printk(KERN_INFO "[WB_GPIO_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_GPIO_DEVICE_ERROR(fmt, args...) do { \ + if (g_wb_gpio_device_error) { \ + printk(KERN_ERR "[WB_GPIO_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static void wb_gpio_device_release(struct device *dev) +{ + return; +} + +static struct platform_device wb_gpio_d1500_device = { + .name = "wb_gpio_d1500", + .id = -1, + .dev = { + .release = wb_gpio_device_release, + }, +}; + +static int __init wb_gpio_device_init(void) +{ + WB_GPIO_DEVICE_VERBOSE("wb_gpio_device_init enter!\n"); + return platform_device_register(&wb_gpio_d1500_device); +} + +static void __exit wb_gpio_device_exit(void) +{ + WB_GPIO_DEVICE_VERBOSE("wb_gpio_device_exit enter!\n"); + return platform_device_unregister(&wb_gpio_d1500_device); +} + +module_init(wb_gpio_device_init); +module_exit(wb_gpio_device_exit); +MODULE_DESCRIPTION("GPIO Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.c new file mode 100644 index 000000000000..14f85f33f572 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.c @@ -0,0 +1,774 @@ +/* + * wb_io_dev.c + * ko to read/write i2c client through /dev/XXX device + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_i2c_dev.h" + +#define MAX_I2C_DEV_NUM (256) +#define FPGA_MAX_LEN (256) +#define MAX_NAME_SIZE (20) +#define MAX_BUS_WIDTH (16) +#define TRANSFER_WRITE_BUFF (FPGA_MAX_LEN + MAX_BUS_WIDTH) + +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) + +static int g_i2c_dev_debug = 0; +static int g_i2c_dev_error = 0; + +module_param(g_i2c_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_i2c_dev_error, int, S_IRUGO | S_IWUSR); + +#define I2C_DEV_DEBUG_DMESG(fmt, args...) do { \ + if (g_i2c_dev_debug) { \ + printk(KERN_ERR "[I2C_DEV][DEBUG][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define I2C_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_i2c_dev_error) { \ + printk(KERN_ERR "[I2C_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct i2c_dev_info* i2c_dev_arry[MAX_I2C_DEV_NUM]; + +struct i2c_dev_info { + const char *name; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + uint32_t i2c_len; + struct miscdevice misc; + struct i2c_client *client; +}; + +static int transfer_read(struct i2c_client *client, u8 *buf, loff_t regaddr, size_t count) +{ + struct i2c_adapter *adap; + int i; + u8 offset_buf[MAX_BUS_WIDTH]; + struct i2c_msg msgs[2]; + int msgs_num, ret; + struct i2c_dev_info *i2c_dev; + + if (!client) { + I2C_DEV_DEBUG_ERROR("can't get read client\n"); + return -ENODEV; + } + + adap = client->adapter; + if (!adap) { + I2C_DEV_DEBUG_ERROR("can't get read adap\n"); + return -ENODEV; + } + + i2c_dev = i2c_get_clientdata(client); + if (!i2c_dev) { + I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\n"); + return -ENODEV; + } + + i = 0; + + mem_clear(offset_buf, sizeof(offset_buf)); + + switch (i2c_dev->addr_bus_width) { + case WIDTH_4Byte: + offset_buf[i++] = (regaddr >> 24) & 0xFF; + offset_buf[i++] = (regaddr >> 16) & 0xFF; + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + offset_buf[i++] = regaddr & 0xFF; + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\n", + i2c_dev->addr_bus_width); + return -EINVAL; + } + + if (adap->algo->master_xfer) { + mem_clear(msgs, sizeof(msgs)); + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = i2c_dev->addr_bus_width; + msgs[0].buf = offset_buf; + + msgs[1].addr = client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = count; + msgs[1].buf = buf; + + msgs_num = 2; + ret = i2c_transfer(client->adapter, msgs, msgs_num); + if (ret != msgs_num) { + I2C_DEV_DEBUG_ERROR("i2c_transfer read error\n"); + return -EINVAL; + } + } else { + I2C_DEV_DEBUG_ERROR("don't find read master_xfer\n"); + return -EINVAL; + + } + return 0; +} + +static int transfer_write(struct i2c_client *client, u8 *buf, loff_t regaddr, size_t count) +{ + struct i2c_adapter *adap; + int i; + u8 offset_buf[TRANSFER_WRITE_BUFF]; + struct i2c_msg msgs[1]; + int msgs_num, ret; + struct i2c_dev_info *i2c_dev; + + if (!client) { + I2C_DEV_DEBUG_ERROR("can't get write client\n"); + return -ENODEV; + } + + adap = client->adapter; + if (!adap) { + I2C_DEV_DEBUG_ERROR("can't get write adap\n"); + return -ENODEV; + } + + i2c_dev = i2c_get_clientdata(client); + if (!i2c_dev) { + I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\n"); + return -ENODEV; + } + + i = 0; + + mem_clear(offset_buf, sizeof(offset_buf)); + + switch (i2c_dev->addr_bus_width) { + case WIDTH_4Byte: + offset_buf[i++] = (regaddr >> 24) & 0xFF; + offset_buf[i++] = (regaddr >> 16) & 0xFF; + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + offset_buf[i++] = regaddr & 0xFF; + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\n", + i2c_dev->addr_bus_width); + return -EINVAL; + } + + memcpy(offset_buf + i2c_dev->addr_bus_width, buf, count); + + if (adap->algo->master_xfer) { + mem_clear(msgs, sizeof(msgs)); + + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = i2c_dev->addr_bus_width + count; + msgs[0].buf = offset_buf; + + msgs_num = 1; + ret = i2c_transfer(adap, msgs, msgs_num); + if (ret != msgs_num) { + I2C_DEV_DEBUG_ERROR("i2c_transfer write error\n"); + return -EINVAL; + } + } else { + I2C_DEV_DEBUG_ERROR("don't find write master_xfer\n"); + return -EINVAL; + } + + return 0; +} + +static long i2c_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int i2c_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct i2c_dev_info *i2c_dev; + + i2c_dev = i2c_dev_arry[minor]; + if (i2c_dev == NULL) { + return -ENODEV; + } + + file->private_data = i2c_dev; + + return 0; +} + +static int i2c_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static int device_read(struct i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u8 tmp_offset; + u8 val[FPGA_MAX_LEN]; + u32 width, rd_len, per_len, tmp; + u32 max_per_len; + + if (offset > i2c_dev->i2c_len) { + I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, count: %lu, EOF.\n", + offset, i2c_dev->i2c_len, count); + return 0; + } + + if (count > (i2c_dev->i2c_len - offset)) { + I2C_DEV_DEBUG_DMESG("read count out of range. input len:%lu, read len:%u.\n", + count, i2c_dev->i2c_len - offset); + count = i2c_dev->i2c_len - offset; + } + + if (count == 0) { + I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, read len: %lu, EOF.\n", + offset, i2c_dev->i2c_len, count); + return 0; + } + + width = i2c_dev->data_bus_width; + switch (width) { + case WIDTH_4Byte: + tmp_offset = offset & 0x3; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + break; + case WIDTH_2Byte: + tmp_offset = offset & 0x1; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + break; + case WIDTH_1Byte: + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\n", width); + return -EINVAL; + } + + max_per_len = i2c_dev->per_rd_len; + tmp = (width - 1) & count; + rd_len = (tmp == 0) ? count : count + width - tmp; + per_len = (rd_len > max_per_len) ? (max_per_len) : (rd_len); + + mem_clear(val, sizeof(val)); + for (i = 0; i < rd_len; i += per_len) { + ret = transfer_read(i2c_dev->client, val + i, offset + i, per_len); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("read error.read offset = %u\n", (offset + i)); + return -EFAULT; + } + } + + if (width == WIDTH_1Byte) { + memcpy(buf, val, count); + } else { + for (i = 0; i < count; i += width) { + for (j = 0; (j < width) && (i + j < count); j++) { + buf[i + j] = val[i + width - j - 1]; + } + } + } + + return count; +} + +static int device_write(struct i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u8 tmp_offset; + u32 width; + u8 val[FPGA_MAX_LEN]; + u32 wr_len, per_len, tmp; + u32 max_per_len; + + if (offset > i2c_dev->i2c_len) { + I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, count: %lu, EOF.\n", + offset, i2c_dev->i2c_len, count); + return 0; + } + + if (count > (i2c_dev->i2c_len - offset)) { + I2C_DEV_DEBUG_DMESG("read count out of range. input len:%lu, read len:%u.\n", + count, i2c_dev->i2c_len - offset); + count = i2c_dev->i2c_len - offset; + } + + if (count == 0) { + I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, read len: %lu, EOF.\n", + offset, i2c_dev->i2c_len, count); + return 0; + } + + width = i2c_dev->data_bus_width; + switch (width) { + case WIDTH_4Byte: + tmp_offset = offset & 0x3; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + break; + case WIDTH_2Byte: + tmp_offset = offset & 0x1; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + break; + case WIDTH_1Byte: + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\n", width); + return -EINVAL; + } + + mem_clear(val, sizeof(val)); + + if (width == WIDTH_1Byte) { + memcpy(val, buf, count); + } else { + for (i = 0; i < count; i += width) { + for (j = 0; (j < width) && (i + j < count); j++) { + val[i + width - j - 1] = buf[i + j]; + } + } + } + + max_per_len = i2c_dev->per_wr_len; + tmp = (width - 1) & count; + wr_len = (tmp == 0) ? count : count + width - tmp; + per_len = (wr_len > max_per_len) ? (max_per_len) : (wr_len); + + for (i = 0; i < wr_len; i += per_len) { + ret = transfer_write(i2c_dev->client, val + i, offset + i, per_len); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("write error.offset = %u\n", (offset + i)); + return -EFAULT; + } + } + return count; +} + +static ssize_t i2c_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + u8 val[FPGA_MAX_LEN]; + int ret, read_len; + struct i2c_dev_info *i2c_dev; + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("can't get read private_data.n"); + return -EINVAL; + } + + if (count == 0) { + I2C_DEV_DEBUG_ERROR("Invalid params, read count is 0.n"); + return -EINVAL; + } + + if (count > sizeof(val)) { + I2C_DEV_DEBUG_DMESG("read conut %lu exceed max %lu.\n", count, sizeof(val)); + count = sizeof(val); + } + + mem_clear(val, sizeof(val)); + read_len = device_read(i2c_dev, (uint32_t)*offset, val, count); + if (read_len < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, (uint32_t)*offset, count); + return read_len; + } + + if (access_ok(buf, read_len)) { + I2C_DEV_DEBUG_DMESG("user space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + if (copy_to_user(buf, val, read_len)) { + I2C_DEV_DEBUG_ERROR("copy_to_user failed.\n"); + return -EFAULT; + } + } else { + I2C_DEV_DEBUG_DMESG("kernel space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + memcpy(buf, val, read_len); + } + + *offset += read_len; + ret = read_len; + return ret; +} + +static ssize_t i2c_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + int ret; + + I2C_DEV_DEBUG_DMESG("i2c_dev_read_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, to->count, iocb->ki_pos); + ret = i2c_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos); + return ret; +} + +static ssize_t i2c_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) +{ + u8 val[FPGA_MAX_LEN]; + int write_len; + struct i2c_dev_info *i2c_dev; + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("get write private_data error.\n"); + return -EINVAL; + } + + if (count == 0) { + I2C_DEV_DEBUG_ERROR("Invalid params, write count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(val)) { + I2C_DEV_DEBUG_DMESG("write conut %lu exceed max %lu.\n", count, sizeof(val)); + count = sizeof(val); + } + + mem_clear(val, sizeof(val)); + if (access_ok(buf, count)) { + I2C_DEV_DEBUG_DMESG("user space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + if (copy_from_user(val, buf, count)) { + I2C_DEV_DEBUG_ERROR("copy_from_user failed.\n"); + return -EFAULT; + } + } else { + I2C_DEV_DEBUG_DMESG("kernel space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + memcpy(val, buf, count); + } + + write_len = device_write(i2c_dev, (uint32_t)*offset, val, count); + if (write_len < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%llx, len:%lu.\n", + i2c_dev->name, *offset, count); + return write_len; + } + + *offset += write_len; + return write_len; +} + +static ssize_t i2c_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + int ret; + + I2C_DEV_DEBUG_DMESG("i2c_dev_write_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, from->count, iocb->ki_pos); + ret = i2c_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos); + return ret; +} + +static loff_t i2c_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + struct i2c_dev_info *i2c_dev; + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev is NULL, llseek failed.\n"); + return -EINVAL; + } + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + I2C_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + if (offset > i2c_dev->i2c_len) { + I2C_DEV_DEBUG_ERROR("SEEK_SET out of range, offset:%lld, i2c_len:0x%x.\n", + offset, i2c_dev->i2c_len); + ret = - EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (((file->f_pos + offset) > i2c_dev->i2c_len) || ((file->f_pos + offset) < 0)) { + I2C_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld, i2c_len:0x%x.\n", + file->f_pos, offset, i2c_dev->i2c_len); + ret = - EINVAL; + break; + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + I2C_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static const struct file_operations i2c_dev_fops = { + .owner = THIS_MODULE, + .llseek = i2c_dev_llseek, + .read_iter = i2c_dev_read_iter, + .write_iter = i2c_dev_write_iter, + .unlocked_ioctl = i2c_dev_ioctl, + .open = i2c_dev_open, + .release = i2c_dev_release, +}; + +static struct i2c_dev_info * dev_match(const char *path) +{ + struct i2c_dev_info * i2c_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + for (i = 0; i < MAX_I2C_DEV_NUM; i++) { + if (i2c_dev_arry[ i ] == NULL) { + continue; + } + i2c_dev = i2c_dev_arry[ i ]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", i2c_dev->name); + if (!strcmp(path, dev_name)) { + I2C_DEV_DEBUG_DMESG("get dev_name = %s, minor = %d\n", dev_name, i); + return i2c_dev; + } + } + + return NULL; +} + +int i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct i2c_dev_info *i2c_dev = NULL; + int ret; + + if(path == NULL){ + I2C_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + I2C_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > FPGA_MAX_LEN) { + I2C_DEV_DEBUG_ERROR("read conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN); + return -EINVAL; + } + + i2c_dev = dev_match(path); + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_read(i2c_dev, offset, buf, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("fpga i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(i2c_device_func_read); + +int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct i2c_dev_info *i2c_dev = NULL; + int ret; + + if(path == NULL){ + I2C_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + I2C_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > FPGA_MAX_LEN) { + I2C_DEV_DEBUG_ERROR("write conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN); + return -EINVAL; + } + + i2c_dev = dev_match(path); + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_write (i2c_dev, offset, buf, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(i2c_device_func_write); + +static int i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int ret = 0; + struct i2c_dev_info *i2c_dev; + struct miscdevice *misc; + i2c_dev_device_t *i2c_dev_device; + + i2c_dev = devm_kzalloc(&client->dev, sizeof(struct i2c_dev_info), GFP_KERNEL); + if (!i2c_dev) { + dev_err(&client->dev, "devm_kzalloc error. \n"); + return -ENOMEM; + } + + i2c_set_clientdata(client, i2c_dev); + i2c_dev->client = client; + + if (client->dev.of_node) { + + ret += of_property_read_string(client->dev.of_node, "i2c_name", &i2c_dev->name); + ret += of_property_read_u32(client->dev.of_node, "data_bus_width", &i2c_dev->data_bus_width); + ret += of_property_read_u32(client->dev.of_node, "addr_bus_width", &i2c_dev->addr_bus_width); + ret += of_property_read_u32(client->dev.of_node, "per_rd_len", &i2c_dev->per_rd_len); + ret += of_property_read_u32(client->dev.of_node, "per_wr_len", &i2c_dev->per_wr_len); + ret += of_property_read_u32(client->dev.of_node, "i2c_len", &i2c_dev->i2c_len); + if (ret != 0) { + dev_err(&client->dev, "dts config error.ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (client->dev.platform_data == NULL) { + dev_err(&client->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + i2c_dev_device = client->dev.platform_data; + i2c_dev->name = i2c_dev_device->i2c_name; + i2c_dev->data_bus_width = i2c_dev_device->data_bus_width; + i2c_dev->addr_bus_width = i2c_dev_device->addr_bus_width; + i2c_dev->per_rd_len = i2c_dev_device->per_rd_len; + i2c_dev->per_wr_len = i2c_dev_device->per_wr_len; + i2c_dev->i2c_len = i2c_dev_device->i2c_len; + } + + if ((i2c_dev->per_rd_len & (i2c_dev->data_bus_width - 1)) || + (i2c_dev->per_wr_len & (i2c_dev->data_bus_width - 1))) { + dev_err(&client->dev, "Invalid config per_rd_len %d per_wr_len %d data bus_width %d.\n", + i2c_dev->per_rd_len, i2c_dev->per_wr_len, i2c_dev->data_bus_width); + return -ENXIO; + } + + if ((i2c_dev->i2c_len == 0) || (i2c_dev->i2c_len & (i2c_dev->data_bus_width - 1))) { + dev_err(&client->dev, "Invalid config i2c_len %d, data bus_width %d.\n", + i2c_dev->i2c_len, i2c_dev->data_bus_width); + return -ENXIO; + } + + misc = &i2c_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = i2c_dev->name; + misc->fops = &i2c_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&client->dev, "register %s faild.\n", misc->name); + return -ENXIO; + } + + if (misc->minor >= MAX_I2C_DEV_NUM) { + dev_err(&client->dev, "minor number beyond the limit! is %d.\n", misc->minor); + misc_deregister(misc); + return -ENXIO; + } + i2c_dev_arry[misc->minor] = i2c_dev; + + dev_info(&client->dev, "register %u addr_bus_width %u data_bus_width 0x%x i2c_len device %s with %u per_rd_len %u per_wr_len success.\n", + i2c_dev->addr_bus_width, i2c_dev->data_bus_width, i2c_dev->i2c_len, i2c_dev->name, i2c_dev->per_rd_len, i2c_dev->per_wr_len); + + return 0; +} + +static int i2c_dev_remove(struct i2c_client *client) +{ + int i; + for (i = 0; i < MAX_I2C_DEV_NUM; i++) { + if (i2c_dev_arry[i] != NULL) { + misc_deregister(&i2c_dev_arry[i]->misc); + i2c_dev_arry[i] = NULL; + } + } + return 0; +} + +static const struct i2c_device_id i2c_dev_id[] = { + { "wb-i2c-dev", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, i2c_dev_id); + +static const struct of_device_id i2c_dev_of_match[] = { + { .compatible = "wb-i2c-dev" }, + { }, +}; +MODULE_DEVICE_TABLE(of, i2c_dev_of_match); + +static struct i2c_driver i2c_dev_driver = { + .driver = { + .name = "wb-i2c-dev", + .of_match_table = i2c_dev_of_match, + }, + .probe = i2c_dev_probe, + .remove = i2c_dev_remove, + .id_table = i2c_dev_id, +}; +module_i2c_driver(i2c_dev_driver); + +MODULE_DESCRIPTION("i2c dev driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.h new file mode 100644 index 000000000000..9cc95d88e804 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_dev.h @@ -0,0 +1,20 @@ +#ifndef __WB_I2C_DEV_H__ +#define __WB_I2C_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define I2C_DEV_NAME_MAX_LEN (64) + +typedef struct i2c_dev_device_s { + struct i2c_client *client; + uint32_t i2c_bus; + uint32_t i2c_addr; + char i2c_name[I2C_DEV_NAME_MAX_LEN]; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + uint32_t i2c_len; +} i2c_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.c new file mode 100644 index 000000000000..1f69d96bad0b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.c @@ -0,0 +1,1143 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * i2c-ocores.c: I2C bus driver for OpenCores I2C controller + * (https://opencores.org/project/i2c/overview) + * + * Peter Korsgaard + * + * Support for the GRLIB port of the controller by + * Andreas Larsson + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_i2c_ocores.h" + +#define OCORES_FLAG_POLL BIT(0) + +/* registers */ +#define OCI2C_PRELOW (0) +#define OCI2C_PREHIGH (1) +#define OCI2C_CONTROL (2) +#define OCI2C_DATA (3) +#define OCI2C_CMD (4) /* write only */ +#define OCI2C_STATUS (4) /* read only, same address as OCI2C_CMD */ + +#define OCI2C_CTRL_IEN (0x40) +#define OCI2C_CTRL_EN (0x80) + +#define OCI2C_CMD_START (0x91) +#define OCI2C_CMD_STOP (0x41) +#define OCI2C_CMD_READ (0x21) +#define OCI2C_CMD_WRITE (0x11) +#define OCI2C_CMD_READ_ACK (0x21) +#define OCI2C_CMD_READ_NACK (0x29) +#define OCI2C_CMD_IACK (0x01) + +#define OCI2C_STAT_IF (0x01) +#define OCI2C_STAT_TIP (0x02) +#define OCI2C_STAT_ARBLOST (0x20) +#define OCI2C_STAT_BUSY (0x40) +#define OCI2C_STAT_NACK (0x80) + +#define STATE_DONE (0) +#define STATE_START (1) +#define STATE_WRITE (2) +#define STATE_READ (3) +#define STATE_ERROR (4) + +#define TYPE_OCORES (0) +#define TYPE_GRLIB (1) + +#define OCORE_WAIT_SCH (40) +#define REG_IO_WIDTH_1 (1) +#define REG_IO_WIDTH_2 (2) +#define REG_IO_WIDTH_4 (4) + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) + +typedef struct wb_pci_dev_s { + uint32_t domain; + uint32_t bus; + uint32_t slot; + uint32_t fn; +} wb_pci_dev_t; + +/* + * 'process_lock' exists because ocores_process() and ocores_process_timeout() + * can't run in parallel. + */ +struct ocores_i2c { + uint32_t base_addr; + uint32_t reg_shift; + uint32_t reg_io_width; + unsigned long flags; + wait_queue_head_t wait; + struct i2c_adapter adap; + int adap_nr; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; + spinlock_t process_lock; + uint32_t ip_clock_khz; + uint32_t bus_clock_khz; + void (*setreg)(struct ocores_i2c *i2c, int reg, u32 value); + u32 (*getreg)(struct ocores_i2c *i2c, int reg); + const char *dev_name; + uint32_t reg_access_mode; + uint32_t big_endian; + uint32_t irq_offset; + wb_pci_dev_t wb_pci_dev; + struct device *dev; +}; + +int g_wb_ocores_i2c_debug = 0; +int g_wb_ocores_i2c_error = 0; +int g_wb_ocores_i2c_xfer = 0; + +module_param(g_wb_ocores_i2c_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_ocores_i2c_error, int, S_IRUGO | S_IWUSR); +module_param(g_wb_ocores_i2c_xfer, int, S_IRUGO | S_IWUSR); + +#define OCORES_I2C_VERBOSE(fmt, args...) do { \ + if (g_wb_ocores_i2c_debug) { \ + printk(KERN_INFO "[OCORES_I2C][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define OCORES_I2C_ERROR(fmt, args...) do { \ + if (g_wb_ocores_i2c_error) { \ + printk(KERN_ERR "[OCORES_I2C][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define OCORES_I2C_XFER(fmt, args...) do { \ + if (g_wb_ocores_i2c_xfer) { \ + printk(KERN_INFO "[OCORES_I2C][XFER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +extern int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +#if 0 +int __attribute__((weak)) i2c_device_func_read(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak i2c func read\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) i2c_device_func_write(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak i2c func write\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) pcie_device_func_read(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak pcie func read\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) pcie_device_func_write(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak pcie func write\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) io_device_func_read(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak io func read\r\n"); + return -EINVAL; +} + +int __attribute__((weak)) io_device_func_write(const char *path, uint32_t offset, + uint8_t *buf, size_t count) +{ + OCORES_I2C_ERROR("enter __weak io func write\r\n"); + return -EINVAL; +} +#endif +static int ocores_i2c_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + OCORES_I2C_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + OCORES_I2C_ERROR("kernel_read failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int ocores_i2c_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + OCORES_I2C_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + OCORES_I2C_ERROR("kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int ocores_i2c_reg_write(struct ocores_i2c *i2c, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (i2c->reg_access_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = ocores_i2c_file_write(i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(i2c->dev_name, pos, val, size); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_write(i2c->dev_name, pos, val, size); + break; + default: + OCORES_I2C_ERROR("err func_mode, write failed.\n"); + return -EINVAL; + } + + return ret; +} + +static int ocores_i2c_reg_read(struct ocores_i2c *i2c, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (i2c->reg_access_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_read(i2c->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = ocores_i2c_file_read(i2c->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_read(i2c->dev_name, pos, val, size); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_read(i2c->dev_name, pos, val, size); + break; + default: + OCORES_I2C_ERROR("err func_mode, read failed.\n"); + return -EINVAL; + } + + return ret; +} +static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_1]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0Xff); + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_1); + return; +} + +static void oc_setreg_16(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0Xff); + buf_tmp[1] = (value >> 8) & 0xff; + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_2); + return; +} + +static void oc_setreg_32(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0xff); + buf_tmp[1] = (value >> 8) & 0xff; + buf_tmp[2] = (value >> 16) & 0xff; + buf_tmp[3] = (value >> 24) & 0xff; + + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_4); + return; +} + +static void oc_setreg_16be(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value >> 8) & 0xff; + buf_tmp[1] = (value & 0Xff); + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_2); + return; +} + +static void oc_setreg_32be(struct ocores_i2c *i2c, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + buf_tmp[0] = (value >> 24) & 0xff; + buf_tmp[1] = (value >> 16) & 0xff; + buf_tmp[2] = (value >> 8) & 0xff; + buf_tmp[3] = (value & 0xff); + ocores_i2c_reg_write(i2c, pos, buf_tmp, REG_IO_WIDTH_4); + return; +} + +static inline u32 oc_getreg_8(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_1]; + u32 value, pos; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_1); + value = buf_tmp[0]; + + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + + return value; +} + +static inline u32 oc_getreg_16(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 value, pos; + int i; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + mem_clear(buf_tmp, sizeof(buf_tmp)); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_2); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_2 ; i++) { + value |= buf_tmp[i] << (8 * i); + } + + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_getreg_32(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 value, pos; + int i; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + mem_clear(buf_tmp, sizeof(buf_tmp)); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_4); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_4 ; i++) { + value |= buf_tmp[i] << (8 * i); + } + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_getreg_16be(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 value, pos; + int i; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_2); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_2 ; i++) { + value |= buf_tmp[i] << (8 * (REG_IO_WIDTH_2 -i - 1)); + } + + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_getreg_32be(struct ocores_i2c *i2c, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 value, pos; + int i; + + pos = i2c->base_addr + (reg << i2c->reg_shift); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + ocores_i2c_reg_read(i2c, pos, buf_tmp, REG_IO_WIDTH_4); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_4 ; i++) { + value |= buf_tmp[i] << (8 * (REG_IO_WIDTH_4 -i - 1)); + } + + OCORES_I2C_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + i2c->dev_name, i2c->reg_access_mode, pos, value); + return value; + +} + +static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u32 value) +{ + i2c->setreg(i2c, reg, value); + return; +} + +static inline u32 oc_getreg(struct ocores_i2c *i2c, int reg) +{ + return i2c->getreg(i2c, reg); +} + +static int ocores_msg_check(struct i2c_msg *msgs, int num) +{ + int i, ret = 0; + + if (!msgs) { + ret = -EFAULT; + goto out; + } + + for (i = 0; i < num; ++i) { + if (!msgs[i].buf) { + ret = -EFAULT; + goto out; + } + } + +out: + return ret; +} + +static void ocores_process(struct ocores_i2c *i2c, u8 stat) +{ + struct i2c_msg *msg = i2c->msg; + + OCORES_I2C_XFER("Enter nr %d.\n", i2c->adap.nr); + if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + /* stop has been sent */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + wake_up(&i2c->wait); + OCORES_I2C_XFER("stop has been sent, exit.\n"); + goto out; + } + + /* error? */ + if (stat & OCI2C_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + OCORES_I2C_XFER("error exit, lose arbitration.\n"); + goto out; + } + + if (ocores_msg_check(i2c->msg, i2c->nmsgs) != 0) { + OCORES_I2C_XFER("msg buf is NULL\n"); + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + goto out; + } + + if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { + i2c->state = + (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & OCI2C_STAT_NACK) { + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + OCORES_I2C_XFER("OCI2C_STAT_NACK, exit.\n"); + goto out; + } + } else { + msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + OCORES_I2C_XFER("Enter end of msg.\n"); + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { /* end? */ + /* send start? */ + if (!(msg->flags & I2C_M_NOSTART)) { + u8 addr = i2c_8bit_addr_from_msg(msg); + + i2c->state = STATE_START; + + oc_setreg(i2c, OCI2C_DATA, addr); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + OCORES_I2C_XFER("send start, exit.\n"); + goto out; + } + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } else { + i2c->state = STATE_DONE; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + OCORES_I2C_XFER("send OCI2C_CMD_STOP, exit.\n"); + goto out; + } + } + + if (i2c->state == STATE_READ) { + oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? + OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); + } else { + oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); + } + +out: + OCORES_I2C_XFER("normal, exit nr %d.\n", i2c->adap.nr); + return; +} + +static irqreturn_t ocores_isr(int irq, void *dev_id) +{ + struct ocores_i2c *i2c = dev_id; + u8 stat; + unsigned long flags; + + if (!i2c) { + return IRQ_NONE; + } + + spin_lock_irqsave(&i2c->process_lock, flags); + stat = oc_getreg(i2c, OCI2C_STATUS); + if (!(stat & OCI2C_STAT_IF)) { + spin_unlock_irqrestore(&i2c->process_lock, flags); + return IRQ_NONE; + } + OCORES_I2C_XFER("Enter, irq %d nr %d addr 0x%x.\n", irq, i2c->adap.nr, (!i2c->msg)? 0 : i2c->msg->addr); + ocores_process(i2c, stat); + OCORES_I2C_XFER("Leave, irq %d nr %d addr 0x%x.\n", irq, i2c->adap.nr, (!i2c->msg)? 0 : i2c->msg->addr); + spin_unlock_irqrestore(&i2c->process_lock, flags); + + return IRQ_HANDLED; +} + +/** + * Process timeout event + * @i2c: ocores I2C device instance + */ +static void ocores_process_timeout(struct ocores_i2c *i2c) +{ + unsigned long flags; + + spin_lock_irqsave(&i2c->process_lock, flags); + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + mdelay(1); + spin_unlock_irqrestore(&i2c->process_lock, flags); + return; +} + +/** + * Wait until something change in a given register + * @i2c: ocores I2C device instance + * @reg: register to query + * @mask: bitmask to apply on register value + * @val: expected result + * @timeout: timeout in jiffies + * + * Timeout is necessary to avoid to stay here forever when the chip + * does not answer correctly. + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_wait(struct ocores_i2c *i2c, + int reg, u8 mask, u8 val, + const unsigned long timeout) +{ + u8 status; + unsigned long j, jiffies_tmp; + unsigned int usleep; + + usleep = OCORE_WAIT_SCH; + j = jiffies + timeout; + while (1) { + jiffies_tmp = jiffies; + status = oc_getreg(i2c, reg); + + if ((status & mask) == val) { + break; + } + + if (time_after(jiffies_tmp, j)) { + OCORES_I2C_XFER("STATUS timeout, mask[0x%x] val[0x%x] status[0x%x]\n", mask, val, status); + return -ETIMEDOUT; + } + usleep_range(usleep,usleep + 1); + } + return 0; + +} + +/** + * Wait until is possible to process some data + * @i2c: ocores I2C device instance + * + * Used when the device is in polling mode (interrupts disabled). + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_poll_wait(struct ocores_i2c *i2c) +{ + u8 mask; + int err; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* transfer is over */ + mask = OCI2C_STAT_BUSY; + } else { + /* on going transfer */ + mask = OCI2C_STAT_TIP; + /* + * We wait for the data to be transferred (8bit), + * then we start polling on the ACK/NACK bit + */ + udelay((8 * 1000) / i2c->bus_clock_khz); + } + + /* + * once we are here we expect to get the expected result immediately + * so if after 100ms we timeout then something is broken. + */ + err = ocores_wait(i2c, OCI2C_STATUS, mask, 0, msecs_to_jiffies(100)); + if (err) { + OCORES_I2C_XFER("STATUS timeout, bit 0x%x did not clear in 100ms, err %d\n", mask, err); + } + return err; +} + +/** + * It handles an IRQ-less transfer + * @i2c: ocores I2C device instance + * + * Even if IRQ are disabled, the I2C OpenCore IP behavior is exactly the same + * (only that IRQ are not produced). This means that we can re-use entirely + * ocores_isr(), we just add our polling code around it. + * + * It can run in atomic context + */ +static int ocores_process_polling(struct ocores_i2c *i2c) +{ + irqreturn_t ret; + int err; + + while (1) { + err = ocores_poll_wait(i2c); + if (err) { + i2c->state = STATE_ERROR; + break; /* timeout */ + } + + ret = ocores_isr(-1, i2c); + if (ret == IRQ_NONE) { + break; /* all messages have been transferred */ + } + } + + return err; +} + +static int ocores_xfer_core(struct ocores_i2c *i2c, + struct i2c_msg *msgs, int num, + bool polling) +{ + int ret; + u8 ctrl; + unsigned long flags; + + OCORES_I2C_VERBOSE("Enter ocores_xfer_core. polling mode:%d.\n", polling); + spin_lock_irqsave(&i2c->process_lock, flags); + + ctrl = oc_getreg(i2c, OCI2C_CONTROL); + if (polling) { + oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~OCI2C_CTRL_IEN); + } else { + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN); + } + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = STATE_START; + + oc_setreg(i2c, OCI2C_DATA, i2c_8bit_addr_from_msg(i2c->msg)); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + + spin_unlock_irqrestore(&i2c->process_lock, flags); + + if (polling) { + ret = ocores_process_polling(i2c); + if (ret) { + ocores_process_timeout(i2c); + return -ETIMEDOUT; + } + } else { + ret = wait_event_timeout(i2c->wait, + (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ); + if (ret == 0) { + ocores_process_timeout(i2c); + return -ETIMEDOUT; + } + } + + return (i2c->state == STATE_DONE) ? num : -EIO; +} + +static int ocores_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct ocores_i2c *i2c; + int ret; + + OCORES_I2C_VERBOSE("Enter ocores_xfer.\n"); + if (!adap || ocores_msg_check(msgs, num)) { + OCORES_I2C_ERROR("[MAY BE USER SPACE ERROR]:msg buf is NULL\n"); + return -EFAULT; + } + OCORES_I2C_VERBOSE("i2c bus:%d, msgs num:%d.\n", adap->nr, num); + + i2c = i2c_get_adapdata(adap); + + if (i2c->flags & OCORES_FLAG_POLL) { + ret = ocores_xfer_core(i2c, msgs, num, true); + } else { + ret = ocores_xfer_core(i2c, msgs, num, false); + } + + return ret; +} + +static int ocores_init(struct device *dev, struct ocores_i2c *i2c) +{ + int prescale; + int diff; + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* make sure the device is disabled */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); + + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + dev_err(dev, "Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } + + oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); + oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); + + /* Init the device */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); + + return 0; +} + +static u32 ocores_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm ocores_algorithm = { + .master_xfer = ocores_xfer, + .functionality = ocores_func, +}; + +static const struct i2c_adapter ocores_adapter = { + .owner = THIS_MODULE, + .name = "wb-i2c-ocores", + .class = I2C_CLASS_DEPRECATED, + .algo = &ocores_algorithm, +}; + +static const struct of_device_id ocores_i2c_match[] = { + { + .compatible = "opencores,wb-i2c-ocores", + .data = (void *)TYPE_OCORES, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ocores_i2c_match); + +static int fpga_ocores_i2c_get_irq(struct ocores_i2c *i2c) +{ + int devfn, irq; + struct device *dev; + wb_pci_dev_t *wb_pci_dev; + struct pci_dev *pci_dev; + i2c_ocores_device_t *i2c_ocores_device; + int ret; + + dev = i2c->dev; + wb_pci_dev = &i2c->wb_pci_dev; + + if (dev->of_node) { + ret = 0; + ret += of_property_read_u32(dev->of_node, "pci_domain", &wb_pci_dev->domain); + ret += of_property_read_u32(dev->of_node, "pci_bus", &wb_pci_dev->bus); + ret += of_property_read_u32(dev->of_node, "pci_slot", &wb_pci_dev->slot); + ret += of_property_read_u32(dev->of_node, "pci_fn", &wb_pci_dev->fn); + + if (ret != 0) { + OCORES_I2C_ERROR("dts config error, ret:%d.\n", ret); + ret = -EINVAL; + return ret; + } + } else { + if (i2c->dev->platform_data == NULL) { + OCORES_I2C_ERROR("Failed to get platform data config.\n"); + ret = -EINVAL; + return ret; + } + i2c_ocores_device = i2c->dev->platform_data; + wb_pci_dev->domain = i2c_ocores_device->pci_domain; + wb_pci_dev->bus = i2c_ocores_device->pci_bus; + wb_pci_dev->slot = i2c_ocores_device->pci_slot; + wb_pci_dev->fn = i2c_ocores_device->pci_fn; + } + + OCORES_I2C_VERBOSE("pci_domain:0x%x, pci_bus:0x%x, pci_slot:0x%x, pci_fn:0x%x.\n", + wb_pci_dev->domain, wb_pci_dev->bus, wb_pci_dev->slot, wb_pci_dev->fn); + + devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); + if (pci_dev == NULL) { + OCORES_I2C_ERROR("Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bus, devfn); + return -ENODEV; + } + irq = pci_dev->irq + i2c->irq_offset; + OCORES_I2C_VERBOSE("get irq no:%d.\n", irq); + return irq; +} + +static int ocores_i2c_config_init(struct ocores_i2c *i2c) +{ + int ret; + struct device *dev; + i2c_ocores_device_t *i2c_ocores_device; + + dev = i2c->dev; + ret = 0; + + if (dev->of_node) { + ret += of_property_read_string(dev->of_node, "dev_name", &i2c->dev_name); + ret += of_property_read_u32(dev->of_node, "dev_base", &i2c->base_addr); + ret += of_property_read_u32(dev->of_node, "reg_shift", &i2c->reg_shift); + ret += of_property_read_u32(dev->of_node, "reg_io_width", &i2c->reg_io_width); + ret += of_property_read_u32(dev->of_node, "ip_clock_khz", &i2c->ip_clock_khz); + ret += of_property_read_u32(dev->of_node, "bus_clock_khz", &i2c->bus_clock_khz); + ret += of_property_read_u32(dev->of_node, "reg_access_mode", &i2c->reg_access_mode); + + if (ret != 0) { + OCORES_I2C_ERROR("dts config error, ret:%d.\n", ret); + ret = -ENXIO; + return ret; + } + } else { + if (i2c->dev->platform_data == NULL) { + OCORES_I2C_ERROR("Failed to get platform data config.\n"); + ret = -ENXIO; + return ret; + } + i2c_ocores_device = i2c->dev->platform_data; + i2c->dev_name = i2c_ocores_device->dev_name; + i2c->adap_nr = i2c_ocores_device->adap_nr; + i2c->big_endian = i2c_ocores_device->big_endian; + i2c->base_addr = i2c_ocores_device->dev_base; + i2c->reg_shift = i2c_ocores_device->reg_shift; + i2c->reg_io_width = i2c_ocores_device->reg_io_width; + i2c->ip_clock_khz = i2c_ocores_device->ip_clock_khz; + i2c->bus_clock_khz = i2c_ocores_device->bus_clock_khz; + i2c->reg_access_mode = i2c_ocores_device->reg_access_mode; + } + + OCORES_I2C_VERBOSE("name:%s, base:0x%x, reg_shift:0x%x, io_width:0x%x, ip_clock_khz:0x%x, bus_clock_khz:0x%x.\n", + i2c->dev_name, i2c->base_addr, i2c->reg_shift, i2c->reg_io_width, i2c->ip_clock_khz, i2c->bus_clock_khz); + OCORES_I2C_VERBOSE("reg access mode:%d.\n", i2c->reg_access_mode); + return ret; +} + +static int ocores_i2c_probe(struct platform_device *pdev) +{ + struct ocores_i2c *i2c; + int irq, ret; + bool be; + i2c_ocores_device_t *i2c_ocores_device; + + OCORES_I2C_VERBOSE("Enter main probe\n"); + + i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + spin_lock_init(&i2c->process_lock); + + i2c->dev = &pdev->dev; + ret = ocores_i2c_config_init(i2c); + if (ret !=0) { + dev_err(i2c->dev, "Failed to get ocores i2c dts config.\n"); + goto out; + } + + if (i2c->dev->of_node) { + if (of_property_read_u32(i2c->dev->of_node, "big_endian", &i2c->big_endian)) { + + be = 0; + } else { + be = i2c->big_endian; + } + } else { + be = i2c->big_endian; + } + + if (i2c->reg_io_width == 0) { + i2c->reg_io_width = 1; /* Set to default value */ + } + + if (!i2c->setreg || !i2c->getreg) { + switch (i2c->reg_io_width) { + case REG_IO_WIDTH_1: + i2c->setreg = oc_setreg_8; + i2c->getreg = oc_getreg_8; + break; + + case REG_IO_WIDTH_2: + i2c->setreg = be ? oc_setreg_16be : oc_setreg_16; + i2c->getreg = be ? oc_getreg_16be : oc_getreg_16; + break; + + case REG_IO_WIDTH_4: + i2c->setreg = be ? oc_setreg_32be : oc_setreg_32; + i2c->getreg = be ? oc_getreg_32be : oc_getreg_32; + break; + + default: + dev_err(i2c->dev, "Unsupported I/O width (%d)\n", + i2c->reg_io_width); + ret = -EINVAL; + goto out; + } + } + + init_waitqueue_head(&i2c->wait); + irq = -1; + + if (i2c->dev->of_node) { + if (of_property_read_u32(i2c->dev->of_node, "irq_offset", &i2c->irq_offset)) { + + i2c->flags |= OCORES_FLAG_POLL; + } else { + + irq = fpga_ocores_i2c_get_irq(i2c); + if (irq < 0 ) { + dev_err(i2c->dev, "Failed to get ocores i2c irq number, ret: %d.\n", irq); + ret = irq; + goto out; + } + } + } else { + if (i2c->dev->platform_data == NULL) { + + i2c->flags |= OCORES_FLAG_POLL; + OCORES_I2C_VERBOSE("Failed to get platform data config, set OCORES_FLAG_POLL.\n"); + } else { + i2c_ocores_device = i2c->dev->platform_data; + if (i2c_ocores_device->irq_type == 0) { + + i2c->flags |= OCORES_FLAG_POLL; + } else { + + irq = fpga_ocores_i2c_get_irq(i2c); + if (irq < 0 ) { + dev_err(i2c->dev, "Failed to get ocores i2c irq number, ret: %d.\n", irq); + ret = irq; + goto out; + } + } + } + } + + if (!(i2c->flags & OCORES_FLAG_POLL)) { + ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, + pdev->name, i2c); + if (ret) { + dev_err(i2c->dev, "Cannot claim IRQ\n"); + goto out; + } + } + + ret = ocores_init(i2c->dev, i2c); + if (ret) { + goto out; + } + + /* hook up driver to tree */ + platform_set_drvdata(pdev, i2c); + i2c->adap = ocores_adapter; + i2c_set_adapdata(&i2c->adap, i2c); + i2c->adap.dev.parent = &pdev->dev; + i2c->adap.dev.of_node = pdev->dev.of_node; + + if (i2c->dev->of_node) { + /* adap.nr get from dts aliases */ + ret = i2c_add_adapter(&i2c->adap); + } else { + i2c->adap.nr = i2c->adap_nr; + ret = i2c_add_numbered_adapter(&i2c->adap); + } + if (ret) { + goto fail_add; + } + OCORES_I2C_VERBOSE("Main probe out\n"); + dev_info(i2c->dev, "registered i2c-%d for %s with base address:0x%x success.\n", + i2c->adap.nr, i2c->dev_name, i2c->base_addr); + return 0; +fail_add: + platform_set_drvdata(pdev, NULL); +out: + return ret; +} + +static int ocores_i2c_remove(struct platform_device *pdev) +{ + struct ocores_i2c *i2c = platform_get_drvdata(pdev); + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* disable i2c logic */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + /* remove adapter & data */ + i2c_del_adapter(&i2c->adap); + return 0; +} + +static struct platform_driver ocores_i2c_driver = { + .probe = ocores_i2c_probe, + .remove = ocores_i2c_remove, + .driver = { + .name = "wb-ocores-i2c", + .of_match_table = ocores_i2c_match, + }, +}; + +module_platform_driver(ocores_i2c_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("OpenCores I2C bus driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ocores-i2c"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.h new file mode 100644 index 000000000000..acd2710a92f0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_i2c_ocores.h @@ -0,0 +1,28 @@ +#ifndef __WB_I2C_OCORES_H__ +#define __WB_I2C_OCORES_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define I2C_OCORES_DEV_NAME_MAX_LEN (64) + +typedef struct i2c_ocores_device_s { + uint32_t big_endian; + char dev_name[I2C_OCORES_DEV_NAME_MAX_LEN]; + int adap_nr; + uint32_t dev_base; + uint32_t reg_shift; + uint32_t reg_io_width; + uint32_t ip_clock_khz; + uint32_t bus_clock_khz; + uint32_t reg_access_mode; + + uint32_t irq_type; + uint32_t irq_offset; + uint32_t pci_domain; + uint32_t pci_bus; + uint32_t pci_slot; + uint32_t pci_fn; + int device_flag; +} i2c_ocores_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.c new file mode 100644 index 000000000000..4a4bbba0ade5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.c @@ -0,0 +1,571 @@ +/* + * wb_io_dev.c + * ko to read/write ioports through /dev/XXX device + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_io_dev.h" + +#define PROXY_NAME "wb-io-dev" +#define MAX_IO_DEV_NUM (256) +#define IO_RDWR_MAX_LEN (256) +#define MAX_NAME_SIZE (20) +#define IO_INDIRECT_ADDR_H(addr) ((addr >> 8) & 0xff) +#define IO_INDIRECT_ADDR_L(addr) ((addr) & 0xff) +#define IO_INDIRECT_OP_WRITE (0x2) +#define IO_INDIRECT_OP_READ (0X3) + +static int g_io_dev_debug = 0; +static int g_io_dev_error = 0; + +module_param(g_io_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_io_dev_error, int, S_IRUGO | S_IWUSR); + +#define IO_DEV_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_io_dev_debug) { \ + printk(KERN_INFO "[IO_DEV][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define IO_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_io_dev_error) { \ + printk(KERN_ERR "[IO_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef struct wb_io_dev_s { + const char *name; + uint32_t io_base; + uint32_t io_len; + uint32_t indirect_addr; + uint32_t wr_data; + uint32_t addr_low; + uint32_t addr_high; + uint32_t rd_data; + uint32_t opt_ctl; + spinlock_t io_dev_lock; + struct miscdevice misc; +} wb_io_dev_t; + +static wb_io_dev_t* io_dev_arry[MAX_IO_DEV_NUM]; + +static int io_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + wb_io_dev_t *wb_io_dev; + + if (minor >= MAX_IO_DEV_NUM) { + IO_DEV_DEBUG_ERROR("minor out of range, minor = %d.\n", minor); + return -ENODEV; + } + + wb_io_dev = io_dev_arry[minor]; + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("wb_io_dev is NULL, open failed, minor = %d\n", minor); + return -ENODEV; + } + + file->private_data = wb_io_dev; + return 0; +} + +static int io_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + return 0; +} + +uint8_t io_indirect_addressing_read(wb_io_dev_t *wb_io_dev, uint32_t address) +{ + uint8_t addr_l, addr_h, value; + unsigned long flags; + + addr_h = IO_INDIRECT_ADDR_H(address); + addr_l = IO_INDIRECT_ADDR_L(address); + IO_DEV_DEBUG_VERBOSE("read one count, addr = 0x%x\n", address); + + spin_lock_irqsave(&wb_io_dev->io_dev_lock, flags); + + outb(addr_l, wb_io_dev->io_base + wb_io_dev->addr_low); + + outb(addr_h, wb_io_dev->io_base + wb_io_dev->addr_high); + + outb(IO_INDIRECT_OP_READ, wb_io_dev->io_base + wb_io_dev->opt_ctl); + + value = inb(wb_io_dev->io_base + wb_io_dev->rd_data); + + spin_unlock_irqrestore(&wb_io_dev->io_dev_lock, flags); + + return value; +} + +static int io_dev_read_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i; + + if (offset > wb_io_dev->io_len) { + IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, wb_io_dev->io_len); + return 0; + } + + if (count > wb_io_dev->io_len - offset) { + IO_DEV_DEBUG_VERBOSE("read count out of range. input len:%lu, read len:%u.\n", + count, wb_io_dev->io_len - offset); + count = wb_io_dev->io_len - offset; + } + if (wb_io_dev->indirect_addr) { + for (i = 0; i < count; i++) { + buf[i] = io_indirect_addressing_read(wb_io_dev, offset + i); + } + } else { + for (i = 0; i < count; i++) { + buf[i] = inb(wb_io_dev->io_base + offset + i); + } + } + + return count; +} + +static ssize_t io_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + wb_io_dev_t *wb_io_dev; + int ret, read_len; + u8 buf_tmp[IO_RDWR_MAX_LEN]; + + wb_io_dev = file->private_data; + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("wb_io_dev is NULL, read failed.\n"); + return -EINVAL; + } + + if (count == 0) { + IO_DEV_DEBUG_ERROR("Invalid params, read count is 0.n"); + return -EINVAL; + } + + if (count > sizeof(buf_tmp)) { + IO_DEV_DEBUG_VERBOSE("read conut %lu exceed max %lu.\n", count, sizeof(buf_tmp)); + count = sizeof(buf_tmp); + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + read_len = io_dev_read_tmp(wb_io_dev, *offset, buf_tmp, count); + if (read_len < 0) { + IO_DEV_DEBUG_ERROR("io_dev_read_tmp failed, ret:%d.\n", read_len); + return read_len; + } + + if (access_ok(buf, read_len)) { + IO_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + if (copy_to_user(buf, buf_tmp, read_len)) { + IO_DEV_DEBUG_ERROR("copy_to_user failed.\n"); + return -EFAULT; + } + } else { + IO_DEV_DEBUG_VERBOSE("kernel space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + memcpy(buf, buf_tmp, read_len); + } + *offset += read_len; + ret = read_len; + return ret; +} + +static ssize_t io_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + int ret; + + IO_DEV_DEBUG_VERBOSE("io_dev_read_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, to->count, iocb->ki_pos); + ret = io_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos); + return ret; +} + +void io_indirect_addressing_write(wb_io_dev_t *wb_io_dev, uint32_t address, uint8_t reg_val) +{ + uint8_t addr_l, addr_h; + unsigned long flags; + + addr_h = IO_INDIRECT_ADDR_H(address); + addr_l = IO_INDIRECT_ADDR_L(address); + IO_DEV_DEBUG_VERBOSE("write one count, addr = 0x%x\n", address); + + spin_lock_irqsave(&wb_io_dev->io_dev_lock, flags); + + outb(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + + outb(addr_l, wb_io_dev->io_base + wb_io_dev->addr_low); + + outb(addr_h, wb_io_dev->io_base + wb_io_dev->addr_high); + + outb(IO_INDIRECT_OP_WRITE, wb_io_dev->io_base + wb_io_dev->opt_ctl); + + spin_unlock_irqrestore(&wb_io_dev->io_dev_lock, flags); + + return; +} + +static int io_dev_write_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i; + + if (offset > wb_io_dev->io_len) { + IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, wb_io_dev->io_len); + return 0; + } + + if (count > wb_io_dev->io_len - offset) { + IO_DEV_DEBUG_VERBOSE("write count out of range. input len:%lu, write len:%u.\n", + count, wb_io_dev->io_len - offset); + count = wb_io_dev->io_len - offset; + } + if (wb_io_dev->indirect_addr) { + for (i = 0; i < count; i++) { + io_indirect_addressing_write(wb_io_dev, offset + i, buf[i]); + } + } else { + for (i = 0; i < count; i++) { + outb(buf[i], wb_io_dev->io_base + offset + i); + } + } + + return count; +} + +static ssize_t io_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) +{ + wb_io_dev_t *wb_io_dev; + int write_len; + u8 buf_tmp[IO_RDWR_MAX_LEN]; + + wb_io_dev = file->private_data; + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("wb_io_dev is NULL, write failed.\n"); + return -EINVAL; + } + + if (count == 0) { + IO_DEV_DEBUG_ERROR("Invalid params, write count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(buf_tmp)) { + IO_DEV_DEBUG_VERBOSE("write conut %lu exceed max %lu.\n", count, sizeof(buf_tmp)); + count = sizeof(buf_tmp); + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + if (access_ok(buf, count)) { + IO_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + if (copy_from_user(buf_tmp, buf, count)) { + IO_DEV_DEBUG_ERROR("copy_from_user failed.\n"); + return -EFAULT; + } + } else { + IO_DEV_DEBUG_VERBOSE("kernel space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + memcpy(buf_tmp, buf, count); + } + + write_len = io_dev_write_tmp(wb_io_dev, *offset, buf_tmp, count); + if (write_len < 0) { + IO_DEV_DEBUG_ERROR("io_dev_write_tmp failed, ret:%d.\n", write_len); + return write_len; + } + + *offset += write_len; + return write_len; +} + +static ssize_t io_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + int ret; + + IO_DEV_DEBUG_VERBOSE("io_dev_write_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, from->count, iocb->ki_pos); + ret = io_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos); + return ret; +} + +static loff_t io_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + wb_io_dev_t *wb_io_dev; + + wb_io_dev = file->private_data; + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("wb_io_dev is NULL, llseek failed.\n"); + return -EINVAL; + } + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + IO_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + if (offset > wb_io_dev->io_len) { + IO_DEV_DEBUG_ERROR("SEEK_SET out of range, offset:%lld, io_len:0x%x.\n", + offset, wb_io_dev->io_len); + ret = - EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (((file->f_pos + offset) > wb_io_dev->io_len) || ((file->f_pos + offset) < 0)) { + IO_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld, io_len:0x%x.\n", + file->f_pos, offset, wb_io_dev->io_len); + ret = - EINVAL; + break; + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + IO_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static long io_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static const struct file_operations io_dev_fops = { + .owner = THIS_MODULE, + .llseek = io_dev_llseek, + .read_iter = io_dev_read_iter, + .write_iter = io_dev_write_iter, + .unlocked_ioctl = io_dev_ioctl, + .open = io_dev_open, + .release = io_dev_release, +}; + +static wb_io_dev_t *dev_match(const char *path) +{ + wb_io_dev_t *wb_io_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + + for (i = 0; i < MAX_IO_DEV_NUM; i++) { + if (io_dev_arry[i] == NULL) { + continue; + } + wb_io_dev = io_dev_arry[i]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", wb_io_dev->name); + if (!strcmp(path, dev_name)) { + IO_DEV_DEBUG_VERBOSE("get dev_name = %s, minor = %d\n", dev_name, i); + return wb_io_dev; + } + } + + return NULL; +} + +int io_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + wb_io_dev_t *wb_io_dev; + int read_len; + + if (path == NULL) { + IO_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + IO_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + wb_io_dev = dev_match(path); + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("io_dev match failed. dev path = %s", path); + return -EINVAL; + } + + read_len = io_dev_read_tmp(wb_io_dev, offset, buf, count); + if (read_len < 0) { + IO_DEV_DEBUG_ERROR("io_dev_read_tmp failed, ret:%d.\n", read_len); + } + return read_len; +} +EXPORT_SYMBOL(io_device_func_read); + +int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + wb_io_dev_t *wb_io_dev; + int write_len; + + if (path == NULL) { + IO_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + IO_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + wb_io_dev = dev_match(path); + if (wb_io_dev == NULL) { + IO_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + write_len = io_dev_write_tmp(wb_io_dev, offset, buf, count); + if (write_len < 0) { + IO_DEV_DEBUG_ERROR("io_dev_write_tmp failed, ret:%d.\n", write_len); + } + return write_len; +} +EXPORT_SYMBOL(io_device_func_write); + +static int io_dev_probe(struct platform_device *pdev) +{ + int ret; + wb_io_dev_t *wb_io_dev; + struct miscdevice *misc; + io_dev_device_t *io_dev_device; + + wb_io_dev = devm_kzalloc(&pdev->dev, sizeof(wb_io_dev_t), GFP_KERNEL); + if (!wb_io_dev) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + ret = -ENOMEM; + return ret; + } + spin_lock_init(&wb_io_dev->io_dev_lock); + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "io_dev_name", &wb_io_dev->name); + ret += of_property_read_u32(pdev->dev.of_node, "io_base", &wb_io_dev->io_base); + ret += of_property_read_u32(pdev->dev.of_node, "io_len", &wb_io_dev->io_len); + if (of_property_read_bool(pdev->dev.of_node, "indirect_addr")) { + + wb_io_dev->indirect_addr = 1; + ret += of_property_read_u32(pdev->dev.of_node, "wr_data", &wb_io_dev->wr_data); + ret += of_property_read_u32(pdev->dev.of_node, "addr_low", &wb_io_dev->addr_low); + ret += of_property_read_u32(pdev->dev.of_node, "addr_high", &wb_io_dev->addr_high); + ret += of_property_read_u32(pdev->dev.of_node, "rd_data", &wb_io_dev->rd_data); + ret += of_property_read_u32(pdev->dev.of_node, "opt_ctl", &wb_io_dev->opt_ctl); + } else { + + wb_io_dev->indirect_addr = 0; + } + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + io_dev_device = pdev->dev.platform_data; + wb_io_dev->name = io_dev_device->io_dev_name; + wb_io_dev->io_base = io_dev_device->io_base; + wb_io_dev->io_len = io_dev_device->io_len; + wb_io_dev->indirect_addr = io_dev_device->indirect_addr; + if (wb_io_dev->indirect_addr == 1) { + wb_io_dev->wr_data = io_dev_device->wr_data; + wb_io_dev->addr_low = io_dev_device->addr_low; + wb_io_dev->addr_high = io_dev_device->addr_high; + wb_io_dev->rd_data = io_dev_device->rd_data; + wb_io_dev->opt_ctl = io_dev_device->opt_ctl; + } + } + + IO_DEV_DEBUG_VERBOSE("name:%s, io base:0x%x, io len:0x%x, addressing type:%s.\n", + wb_io_dev->name, wb_io_dev->io_base, wb_io_dev->io_len, + wb_io_dev->indirect_addr ? "indirect" : "direct"); + + misc = &wb_io_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = wb_io_dev->name; + misc->fops = &io_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&pdev->dev, "Failed to register %s device.\n", misc->name); + return -ENXIO; + } + if (misc->minor >= MAX_IO_DEV_NUM) { + dev_err(&pdev->dev, "Error: device minor[%d] more than max io device num[%d].\n", + misc->minor, MAX_IO_DEV_NUM); + misc_deregister(misc); + return -EINVAL; + } + io_dev_arry[misc->minor] = wb_io_dev; + dev_info(&pdev->dev, "register %s device [0x%x][0x%x] with minor %d using %s addressing success.\n", + misc->name, wb_io_dev->io_base, wb_io_dev->io_len, misc->minor, + wb_io_dev->indirect_addr ? "indirect" : "direct"); + + return 0; +} + +static int io_dev_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < MAX_IO_DEV_NUM ; i++) { + if (io_dev_arry[i] != NULL) { + misc_deregister(&io_dev_arry[i]->misc); + io_dev_arry[i] = NULL; + } + } + + return 0; +} + +static struct of_device_id io_dev_match[] = { + { + .compatible = "wb-io-dev", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, io_dev_match); + +static struct platform_driver wb_io_dev_driver = { + .probe = io_dev_probe, + .remove = io_dev_remove, + .driver = { + .owner = THIS_MODULE, + .name = PROXY_NAME, + .of_match_table = io_dev_match, + }, +}; + +static int __init wb_io_dev_init(void) +{ + return platform_driver_register(&wb_io_dev_driver); +} + +static void __exit wb_io_dev_exit(void) +{ + platform_driver_unregister(&wb_io_dev_driver); +} + +module_init(wb_io_dev_init); +module_exit(wb_io_dev_exit); +MODULE_DESCRIPTION("IO device driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.h new file mode 100644 index 000000000000..3a1a10f0f20c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_io_dev.h @@ -0,0 +1,21 @@ +#ifndef __WB_IO_DEV_H__ +#define __WB_IO_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define IO_DEV_NAME_MAX_LEN (64) + +typedef struct io_dev_device_s { + char io_dev_name[IO_DEV_NAME_MAX_LEN]; + uint32_t io_base; + uint32_t io_len; + uint32_t indirect_addr; + uint32_t wr_data; + uint32_t addr_low; + uint32_t addr_high; + uint32_t rd_data; + uint32_t opt_ctl; + int device_flag; +} io_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.c new file mode 100644 index 000000000000..c079dc409696 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.c @@ -0,0 +1,166 @@ +/* + * wb_lpc_drv.c + * ko to set lpc pcie config io addr and enable lpc + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_lpc_drv.h" + +#define LPC_DRIVER_NAME "wb-lpc" +#define LPC_MAKE_PCI_IO_RANGE(__base) ((0xfc0001) | ((__base) & (0xFFFC))) + +int g_lpc_dev_debug = 0; +int g_lpc_dev_error = 0; + +module_param(g_lpc_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_lpc_dev_error, int, S_IRUGO | S_IWUSR); + +#define LPC_DEV_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_lpc_dev_debug) { \ + printk(KERN_INFO "[LPC_DEV][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define LPC_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_lpc_dev_error) { \ + printk(KERN_ERR "[LPC_DEV][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef struct wb_lpc_dev_s { + const char *lpc_io_name; + uint32_t domain; + uint32_t bus; + uint32_t slot; + uint32_t fn; + uint32_t lpc_io_base; + uint32_t lpc_io_size; + uint32_t lpc_gen_dec; +} wb_lpc_dev_t; + +static int wb_lpc_probe(struct platform_device *pdev) +{ + int ret, devfn; + wb_lpc_dev_t *wb_lpc_dev; + struct pci_dev *pci_dev; + lpc_drv_device_t *lpc_drv_device; + + wb_lpc_dev = devm_kzalloc(&pdev->dev, sizeof(wb_lpc_dev_t), GFP_KERNEL); + if (!wb_lpc_dev) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + ret = -ENOMEM; + return ret; + } + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "lpc_io_name", &wb_lpc_dev->lpc_io_name); + ret += of_property_read_u32(pdev->dev.of_node, "pci_domain", &wb_lpc_dev->domain); + ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &wb_lpc_dev->bus); + ret += of_property_read_u32(pdev->dev.of_node, "pci_slot", &wb_lpc_dev->slot); + ret += of_property_read_u32(pdev->dev.of_node, "pci_fn", &wb_lpc_dev->fn); + ret += of_property_read_u32(pdev->dev.of_node, "lpc_io_base", &wb_lpc_dev->lpc_io_base); + ret += of_property_read_u32(pdev->dev.of_node, "lpc_io_size", &wb_lpc_dev->lpc_io_size); + ret += of_property_read_u32(pdev->dev.of_node, "lpc_gen_dec", &wb_lpc_dev->lpc_gen_dec); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + lpc_drv_device = pdev->dev.platform_data; + wb_lpc_dev->lpc_io_name = lpc_drv_device->lpc_io_name; + wb_lpc_dev->domain = lpc_drv_device->pci_domain; + wb_lpc_dev->bus = lpc_drv_device->pci_bus; + wb_lpc_dev->slot = lpc_drv_device->pci_slot; + wb_lpc_dev->fn = lpc_drv_device->pci_fn; + wb_lpc_dev->lpc_io_base = lpc_drv_device->lpc_io_base; + wb_lpc_dev->lpc_io_size = lpc_drv_device->lpc_io_size; + wb_lpc_dev->lpc_gen_dec = lpc_drv_device->lpc_gen_dec; + } + + LPC_DEV_DEBUG_VERBOSE("domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u\n", + wb_lpc_dev->domain,wb_lpc_dev->bus, wb_lpc_dev->slot, wb_lpc_dev->fn); + LPC_DEV_DEBUG_VERBOSE("lpc_io_name:%s, lpc_io_base:0x%x, lpc_io_size:%u, lpc_gen_dec:0x%x.\n", + wb_lpc_dev->lpc_io_name, wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size, wb_lpc_dev->lpc_gen_dec); + + devfn = PCI_DEVFN(wb_lpc_dev->slot, wb_lpc_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_lpc_dev->domain, wb_lpc_dev->bus, devfn); + if (pci_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_lpc_dev->domain, wb_lpc_dev->bus, devfn); + return -ENXIO; + } + + pci_write_config_dword(pci_dev, wb_lpc_dev->lpc_gen_dec, LPC_MAKE_PCI_IO_RANGE(wb_lpc_dev->lpc_io_base)); + if (!request_region(wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size, wb_lpc_dev->lpc_io_name)) { + dev_err(&pdev->dev, "Failed to request_region [0x%x][0x%x].\n", wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size); + return -EBUSY; + } + + platform_set_drvdata(pdev, wb_lpc_dev); + + dev_info(&pdev->dev, "lpc request_region [0x%x][0x%x] success.\n", wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size); + + return 0; +} + +static int wb_lpc_remove(struct platform_device *pdev) +{ + wb_lpc_dev_t *wb_lpc_dev; + + wb_lpc_dev = platform_get_drvdata(pdev); + if (wb_lpc_dev) { + release_region(wb_lpc_dev->lpc_io_base , wb_lpc_dev->lpc_io_size); + LPC_DEV_DEBUG_VERBOSE("lpc base:0x%x, len:0x%x.\n", wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size); + } + LPC_DEV_DEBUG_VERBOSE("lpc remove.\n"); + + return 0; +} + +static struct of_device_id lpc_dev_match[] = { + { + .compatible = "wb-lpc", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, lpc_dev_match); + +static struct platform_driver wb_lpc_driver = { + .probe = wb_lpc_probe, + .remove = wb_lpc_remove, + .driver = { + .owner = THIS_MODULE, + .name = LPC_DRIVER_NAME, + .of_match_table = lpc_dev_match, + }, +}; + +static int __init wb_lpc_init(void) +{ + return platform_driver_register(&wb_lpc_driver); +} + +static void __exit wb_lpc_exit(void) +{ + platform_driver_unregister(&wb_lpc_driver); +} + +module_init(wb_lpc_init); +module_exit(wb_lpc_exit); +MODULE_DESCRIPTION("lpc driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.h new file mode 100644 index 000000000000..76e8c32c12e9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_lpc_drv.h @@ -0,0 +1,18 @@ +#ifndef __WB_LPC_DRV_H__ +#define __WB_LPC_DRV_H__ + +#define LPC_IO_NAME_MAX_LEN (64) + +typedef struct lpc_drv_device_s { + char lpc_io_name[LPC_IO_NAME_MAX_LEN]; + int pci_domain; + int pci_bus; + int pci_slot; + int pci_fn; + int lpc_io_base; + int lpc_io_size; + int lpc_gen_dec; + int device_flag; +} lpc_drv_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_mac_bsc.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_mac_bsc.c new file mode 100644 index 000000000000..1e84e65d7b11 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_mac_bsc.c @@ -0,0 +1,660 @@ +/* + * wb_mac_th3.c - A driver for control wb_mac_th3 base on wb_mac.c + * + * Copyright (c) 1998, 1999 Frodo Looijaard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define MAC_TEMP_INVALID (99999999) + +#define MAC_SIZE (256) +#define MAC_TEMP_NUM (16) + +#define MAC_ID_REG (0x02000000) + +typedef enum { + DBG_START, + DBG_VERBOSE, + DBG_KEY, + DBG_WARN, + DBG_ERROR, + DBG_END, +} dbg_level_t; + +typedef enum{ + MAC_TYPE_START, + TD4_X9 = 0xb780, + TD4_X9_8 = 0xb788, + TH3 = 0xb980, + TD3 = 0xb870, + TD4 = 0xb880, + TH4 = 0xb990, + MAC_TYPE_END, +} mac_type; + +typedef struct sensor_regs_s { + int id; + u32 reg; +} sensor_reg_t; + +typedef struct mac_temp_regs_s { + int mac_type; + sensor_reg_t sensor_reg[MAC_TEMP_NUM]; +} mac_temp_reg_t; + +typedef enum { + MAC_TEMP_START, + MAC_TEMP_INDEX1, + MAC_TEMP_INDEX2, + MAC_TEMP_INDEX3, + MAC_TEMP_INDEX4, + MAC_TEMP_INDEX5, + MAC_TEMP_INDEX6, + MAC_TEMP_INDEX7, + MAC_TEMP_INDEX8, + MAC_TEMP_INDEX9, + MAC_TEMP_INDEX10, + MAC_TEMP_INDEX11, + MAC_TEMP_INDEX12, + MAC_TEMP_INDEX13, + MAC_TEMP_INDEX14, + MAC_TEMP_INDEX15, + MAC_TEMP_END, +} mac_hwmon_index; + +static mac_temp_reg_t mac_temp_reg[] = { + { + /* TD3 */ + .mac_type = TD3, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02004700}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02004800}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02004900}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02004a00}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02004b00}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02004c00}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02004d00}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02004e00}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02005200}, + {.id = MAC_TEMP_INDEX10, .reg = 0x02005100}, + {.id = MAC_TEMP_INDEX11, .reg = 0x02005000}, + {.id = MAC_TEMP_INDEX12, .reg = 0x02004f00}, + }, + }, + { + /* TD4 */ + .mac_type = TD4, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02004900}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02004b00}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02004d00}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02004f00}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02005100}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02005300}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02005500}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02005700}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02005900}, + {.id = MAC_TEMP_INDEX10, .reg = 0x02005b00}, + {.id = MAC_TEMP_INDEX11, .reg = 0x02005d00}, + {.id = MAC_TEMP_INDEX12, .reg = 0x02005f00}, + {.id = MAC_TEMP_INDEX13, .reg = 0x02006100}, + {.id = MAC_TEMP_INDEX14, .reg = 0x02006300}, + {.id = MAC_TEMP_INDEX15, .reg = 0x02006500}, + }, + }, + { + /* TD4_X9 */ + .mac_type = TD4_X9, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02005a00}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02005c00}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02005e00}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02006000}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02006200}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02006400}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02006600}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02006800}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02006a00}, + }, + }, + { + /* TD4_X9_8 */ + .mac_type = TD4_X9_8, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02005a00}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02005c00}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02005e00}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02006000}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02006200}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02006400}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02006600}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02006800}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02006a00}, + }, + }, + { + /* TH3 */ + .mac_type = TH3, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x02004a00}, + {.id = MAC_TEMP_INDEX2, .reg = 0x02004b00}, + {.id = MAC_TEMP_INDEX3, .reg = 0x02004c00}, + {.id = MAC_TEMP_INDEX4, .reg = 0x02004d00}, + {.id = MAC_TEMP_INDEX5, .reg = 0x02004e00}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02004f00}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02005000}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02005100}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02005200}, + {.id = MAC_TEMP_INDEX10, .reg = 0x02005300}, + {.id = MAC_TEMP_INDEX11, .reg = 0x02005400}, + {.id = MAC_TEMP_INDEX12, .reg = 0x02005500}, + {.id = MAC_TEMP_INDEX13, .reg = 0x02005600}, + {.id = MAC_TEMP_INDEX14, .reg = 0x02005700}, + {.id = MAC_TEMP_INDEX15, .reg = 0x02005800}, + }, + }, + { + /* TH4 */ + .mac_type = TH4, + .sensor_reg = { + {.id = MAC_TEMP_INDEX1, .reg = 0x0201d800}, + {.id = MAC_TEMP_INDEX2, .reg = 0x0201e000}, + {.id = MAC_TEMP_INDEX3, .reg = 0x0201e800}, + {.id = MAC_TEMP_INDEX4, .reg = 0x0201f000}, + {.id = MAC_TEMP_INDEX5, .reg = 0x0201f800}, + {.id = MAC_TEMP_INDEX6, .reg = 0x02020000}, + {.id = MAC_TEMP_INDEX7, .reg = 0x02020800}, + {.id = MAC_TEMP_INDEX8, .reg = 0x02021000}, + {.id = MAC_TEMP_INDEX9, .reg = 0x02021800}, + {.id = MAC_TEMP_INDEX10, .reg = 0x02022000}, + {.id = MAC_TEMP_INDEX11, .reg = 0x02022800}, + {.id = MAC_TEMP_INDEX12, .reg = 0x02023000}, + {.id = MAC_TEMP_INDEX13, .reg = 0x02023800}, + {.id = MAC_TEMP_INDEX14, .reg = 0x02024000}, + {.id = MAC_TEMP_INDEX15, .reg = 0x02024800}, + }, + }, +}; + +static int debuglevel = 0; +module_param(debuglevel, int, S_IRUGO | S_IWUSR); + +static int mac_pcie_id = MAC_TYPE_START; +module_param(mac_pcie_id, int, S_IRUGO | S_IWUSR); + +#define DBG_DEBUG(fmt, arg...) do { \ + if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ + printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else if ( debuglevel >= DBG_ERROR ) { \ + printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else { } \ +} while (0) + +#define DBG_ERROR(fmt, arg...) do { \ + if ( debuglevel > DBG_START) { \ + printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +struct mac_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct mutex update_lock; + u8 data[MAC_SIZE]; /* Register value */ +}; + +static int wb_i2c_read_one_time(struct i2c_client *client, u8 *recv_buf, int size) +{ + struct i2c_msg msgs[2]; + int ret = 0; + + if ((client == NULL) || (recv_buf == NULL)) { + DBG_DEBUG("i2c_client || recv_buf = NULL\r\n"); + return -1; + } + + mem_clear(msgs, sizeof(msgs)); + + msgs[0].buf = recv_buf; + msgs[0].len = size; + msgs[0].addr = client->addr; + msgs[0].flags |= I2C_M_RD; + + ret = i2c_transfer(client->adapter, msgs, 1); + if (ret < 0) { + return ret; + } + DBG_DEBUG("i2c_transfer, dev_addr 0x%x, size %d.\n", client->addr, size); + + return 0; +} + +static int wb_i2c_write_one_time(struct i2c_client *client, u8 *write_buf, int size) +{ + struct i2c_msg msgs[2]; + int ret = 0; + + if ((client == NULL) || (write_buf == NULL)) { + DBG_DEBUG("i2c_client || write_buf = NULL\r\n"); + return -1; + } + + if ((size <= 0)) { + DBG_DEBUG("size invalid, size %d\n", size); + return -1; + } + + mem_clear(msgs, sizeof(msgs)); + + msgs[0].len = size; + msgs[0].buf = write_buf; + msgs[0].addr = client->addr; + + ret = i2c_transfer(client->adapter, msgs, 1); + if (ret < 0) { + return ret; + } + DBG_DEBUG("i2c_transfer, dev_addr 0x%x, size %d\n", client->addr, size); + + return 0; +} + +static u8 step2_buf1[8] = {0x03, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}; +static u8 step2_buf2[8] = {0x03, 0x21, 0x04, 0x0c, 0x2c, 0x38, 0x02, 0x00}; +static u8 step2_buf3[8] = {0x03, 0x21, 0x04, 0x10, 0x02, 0x00, 0x4a, 0x00}; +static u8 step2_buf4[8] = {0x03, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01}; +static u8 step2_buf5[4] = {0x03, 0x21, 0x04, 0x08}; +static u8 step2_buf6[4] = {0x03, 0x21, 0x04, 0x10}; + +static int getmac_register(struct i2c_client *client, u32 index, int *reg_value) +{ + int i; + int ret = 0; + int value = 0; + unsigned char read_buf[8]; + + if (index == 0) { + DBG_ERROR("invalid index\n"); + return -1; + } + + step2_buf3[7] = index & 0xff; + step2_buf3[6] = (index >> 8) & 0xff; + step2_buf3[5] = (index >> 16) & 0xff; + step2_buf3[4] = (index >> 24) & 0xff; + + ret = wb_i2c_write_one_time(client, step2_buf1, 8); + if (ret < 0) { + DBG_ERROR("write step2_buf1 failed, ret = %d\n", ret); + } + ret = wb_i2c_write_one_time(client, step2_buf2, 8); + if (ret < 0) { + DBG_ERROR("write step2_buf2 failed, ret = %d\n", ret); + } + ret = wb_i2c_write_one_time(client, step2_buf3, 8); + if (ret < 0) { + DBG_ERROR("write step2_buf3 failed, ret = %d\n", ret); + } + ret = wb_i2c_write_one_time(client, step2_buf4, 8); + if (ret < 0) { + DBG_ERROR("write step2_buf4 failed, ret = %d\n", ret); + } + + ret = wb_i2c_write_one_time(client, step2_buf5, 4); + if (ret < 0) { + DBG_ERROR("write step2_buf5 failed, ret = %d\n", ret); + } + ret = wb_i2c_read_one_time(client, read_buf, 4); + if (ret < 0) { + DBG_ERROR("read failed, ret = %d\n", ret); + } + for (i = 0; i < 4; i++) { + DBG_DEBUG("read_buf[%d] = 0x%x \n", i, read_buf[i]); + } + + ret = wb_i2c_write_one_time(client, step2_buf6, 4); + if (ret < 0) { + DBG_ERROR("write step2_buf6 failed, ret = %d\n", ret); + } + + ret = wb_i2c_read_one_time(client, read_buf, 4); + if (ret < 0) { + DBG_ERROR("read failed, ret = %d\n", ret); + return ret; + } + + value = (read_buf[0] << 24)| (read_buf[1] << 16) | (read_buf[2] << 8) | read_buf[3]; + *reg_value = value; + + return ret; +} + +static int mac_calcute(u32 reg, int *temp) +{ + int ret = 0; + u32 tmp = 0; + + switch(mac_pcie_id) { + case TD3: + case TH3: + tmp = reg & 0x3ff; + *temp = 434100 - (tmp * 535); + break; + case TD4: + case TH4: + case TD4_X9: + case TD4_X9_8: + tmp = reg & 0x7ff; + *temp = (356070 - (tmp * 237)); + break; + default: + ret = -1; + DBG_ERROR("read failed, ret = %d\n", ret); + break; + } + + if ((*temp / 1000 < -70) || (*temp / 1000 > 200)) { + ret = -1; + DBG_ERROR("mac temp invalid, temp = %d\n", *temp ); + } + + return ret; +} + +static int find_reg_type(int type, int *type_index) +{ + int i; + int size; + + size = ARRAY_SIZE(mac_temp_reg); + for (i = 0; i < size; i++) { + if (mac_temp_reg[i].mac_type == type) { + *type_index = i; + return 0; + } + } + + return -1; +} + +static sensor_reg_t * find_reg_offset(int type, int index) +{ + int i; + int type_index; + int ret; + + ret = find_reg_type(type, &type_index); + if (ret < 0) { + DBG_ERROR("find_reg_type failed, ret = %d\n", ret); + return NULL; + } + + for (i = 0; i < MAC_TEMP_NUM; i++) { + if (mac_temp_reg[type_index].sensor_reg[i].id == index) { + return &(mac_temp_reg[type_index].sensor_reg[i]); + } + } + + return NULL; +} + +static int get_mactemp(struct i2c_client *client, int index, int *temp) +{ + int ret; + int reg_value; + + if (index == 0) { + DBG_ERROR("invalid index\n"); + return -1; + } + + ret = getmac_register(client, index, ®_value); + if (ret < 0) { + DBG_ERROR("getmac_register failed, ret = %d\n", ret); + return ret; + } + DBG_DEBUG("reg_value = 0x%x \n", reg_value); + + ret = mac_calcute(reg_value, temp); + if (ret < 0) { + DBG_ERROR("mac_calcute failed, ret = %d\n", ret); + return ret; + } + + return 0; +} + +static ssize_t show_mac_temp(struct device *dev, struct device_attribute *da, char *buf) +{ + struct mac_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + u32 index_value = to_sensor_dev_attr_2(da)->index; + sensor_reg_t *t; + int result = 0; + int temp = -MAC_TEMP_INVALID; + + mutex_lock(&data->update_lock); + t = find_reg_offset(mac_pcie_id, index_value); + if (t == NULL) { + temp = -MAC_TEMP_INVALID; + DBG_ERROR("find_reg_offset failed, mac_pcie_id = %d, index_value = %d\n", mac_pcie_id, index_value); + } else { + result = get_mactemp(client, t->reg, &temp); + if (result < 0) { + temp = -MAC_TEMP_INVALID; + DBG_ERROR("get_mactemp failed, ret = %d\n", result); + } + } + + mutex_unlock(&data->update_lock); + return snprintf(buf, MAC_SIZE, "%d\n", temp); +} + +static ssize_t show_mac_max_temp(struct device *dev, struct device_attribute *da, char *buf) +{ + struct mac_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int i; + int result; + int temp = -MAC_TEMP_INVALID; + int type_index; + int tmp; + + mutex_lock(&data->update_lock); + + result = find_reg_type(mac_pcie_id, &type_index); + if (result < 0) { + DBG_ERROR("find_reg_type failed, ret = %d\n", result); + goto exit; + } + + for (i = 0; i < MAC_TEMP_NUM; i++) { + result = get_mactemp(client, mac_temp_reg[type_index].sensor_reg[i].reg, &tmp); + if (result < 0) { + DBG_ERROR("get_mactemp failed, ret = %d\n", result); + tmp = -MAC_TEMP_INVALID; + } + + temp = (temp > tmp) ? temp : tmp; + } + +exit: + mutex_unlock(&data->update_lock); + return snprintf(buf, MAC_SIZE, "%d\n", temp); +} + +static int mac_bsc_init(struct i2c_client *client) +{ + int ret; + int reg_value; + int mac_id = 0; + + ret = getmac_register(client, MAC_ID_REG, ®_value); + if (ret < 0) { + DBG_ERROR("getmac_register failed, ret = %d\n", ret); + return ret; + } + + DBG_DEBUG("reg_value = 0x%x \n", reg_value); + mac_id = reg_value & 0xffff; + return mac_id; +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX1); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX2); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX3); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX4); +static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX5); +static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX6); +static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX7); +static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX8); +static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX9); +static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX10); +static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX11); +static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX12); +static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX13); +static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX14); +static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX15); +static SENSOR_DEVICE_ATTR(temp99_input, S_IRUGO, show_mac_max_temp, NULL, 0); + +static struct attribute *mac_hwmon_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp6_input.dev_attr.attr, + &sensor_dev_attr_temp7_input.dev_attr.attr, + &sensor_dev_attr_temp8_input.dev_attr.attr, + &sensor_dev_attr_temp9_input.dev_attr.attr, + &sensor_dev_attr_temp10_input.dev_attr.attr, + &sensor_dev_attr_temp11_input.dev_attr.attr, + &sensor_dev_attr_temp12_input.dev_attr.attr, + &sensor_dev_attr_temp13_input.dev_attr.attr, + &sensor_dev_attr_temp14_input.dev_attr.attr, + &sensor_dev_attr_temp15_input.dev_attr.attr, + &sensor_dev_attr_temp99_input.dev_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(mac_hwmon); + +static int init_bcs_command(int mac_type) { + int ret; + + ret = 0; + switch (mac_type) { + case TD3: + step2_buf2[5] = 0x38; + break; + case TH3: + case TH4: + case TD4: + case TD4_X9: + case TD4_X9_8: + step2_buf2[5] = 0x40; + break; + default: + ret = -1; + break; + } + return ret; +} + +static int mac_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct mac_data *data; + int mac_type; + int ret; + + mac_type = id->driver_data; + mac_pcie_id = mac_type; + if (init_bcs_command(mac_type) < 0) { + DBG_ERROR("mactype[%x] not support \n", mac_type); + return -1; + }; + + if (mac_type == TD4) { + ret = mac_bsc_init(client); + if (ret < 0) { + DBG_ERROR("mac_bsc_init failed, ret = %d\n", ret); + return -1; + } + mac_type = ret; + mac_pcie_id = mac_type; + } + + DBG_DEBUG("=========mac_probe(%x)===========\n",client->addr); + DBG_DEBUG("mac_type: %x\n", mac_type); + data = devm_kzalloc(&client->dev, sizeof(struct mac_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, mac_hwmon_groups); + if (IS_ERR(data->hwmon_dev)) { + return PTR_ERR(data->hwmon_dev); + } + + return 0; +} + +static int mac_remove(struct i2c_client *client) +{ + struct mac_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + return 0; +} + +static const struct i2c_device_id mac_id[] = { + { "wb_mac_bsc_td3", TD3 }, + { "wb_mac_bsc_td4", TD4 }, + { "wb_mac_bsc_th3", TH3 }, + { "wb_mac_bsc_th4", TH4 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, mac_id); + +static struct i2c_driver wb_mac_bsc_driver = { + .driver = { + .name = "wb_mac_bsc", + }, + .probe = mac_probe, + .remove = mac_remove, + .id_table = mac_id, +}; + +module_i2c_driver(wb_mac_bsc_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("mac bsc driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_optoe.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_optoe.c new file mode 100644 index 000000000000..c09162368ad0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_optoe.c @@ -0,0 +1,1192 @@ +/* + * 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. + * + * The CMIS (Common Management Interface Specification) defines use of + * considerably more pages (at least to page 0xAF), which this driver + * supports. + * + * NOTE: This version of the driver ONLY SUPPORTS BANK 0 PAGES on CMIS + * devices. + * + **/ + +/* #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 +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#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 QSFP_NOT_PAGEABLE (1<<2) +#define CMIS_NOT_PAGEABLE (1<<7) +#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 = 50; + +/* + * 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 +#define CMIS_ADDR 3 + +static const struct i2c_device_id optoe_ids[] = { + { "wb_optoe1", ONE_ADDR }, + { "wb_optoe2", TWO_ADDR }, + { "wb_optoe3", CMIS_ADDR }, + { "wb_sff8436", ONE_ADDR }, + { "wb_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; + + mem_clear(msg, 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; + + /* 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; + uint8_t loc; + 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); + + ret = optoe_eeprom_read(optoe, client, &loc, OPTOE_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_dbg(&client->dev, "Read page register for get now location page failed. ret:%d\n", ret); + return ret; + } + + /* Only when read and now location page is inconsistent, will doing switch page */ + if (loc != page) { + 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; + } + + 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 not_pageable; + 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, CMIS 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 (optoe->dev_class == ONE_ADDR) { + not_pageable = QSFP_NOT_PAGEABLE; + } else { + not_pageable = CMIS_NOT_PAGEABLE; + } + dev_dbg(&client->dev, + "Paging Register: 0x%x; not_pageable mask: 0x%x\n", + regval, not_pageable); + + if (regval & 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) + * And... CMIS spec is 1 i2c address, but puts the pageable + * bit in a different location, so CMIS devices are "3" + */ + + if (kstrtoint(buf, 0, &dev_class) != 0 || + dev_class < 1 || dev_class > 3) + return -EINVAL; + + mutex_lock(&optoe->lock); + if (dev_class == TWO_ADDR) { + /* SFP family */ + /* if it doesn't exist, create 0x51 i2c address */ + if (!optoe->client[1]) { + optoe->client[1] = i2c_new_dummy_device(client->adapter, 0x51); + if (!optoe->client[1]) { + dev_err(&client->dev, + "address 0x51 unavailable\n"); + mutex_unlock(&optoe->lock); + return -EADDRINUSE; + } + } + optoe->bin.size = TWO_ADDR_EEPROM_SIZE; + optoe->num_addresses = 2; + } else { + /* one-address (eg QSFP) and CMIS family */ + /* if it exists, remove 0x51 i2c address */ + if (optoe->client[1]) { + i2c_unregister_device(optoe->client[1]); + optoe->client[1] = NULL; + } + optoe->bin.size = ONE_ADDR_EEPROM_SIZE; + optoe->num_addresses = 1; + } + 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, "wb_optoe1") == 0) || + (strcmp(client->name, "wb_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, "wb_optoe2") == 0) || + (strcmp(client->name, "wb_24c04") == 0)) { + /* SFP family */ + optoe->dev_class = TWO_ADDR; + chip.byte_len = TWO_ADDR_EEPROM_SIZE; + num_addresses = 2; + } else if (strcmp(client->name, "wb_optoe3") == 0) { + /* CMIS spec */ + optoe->dev_class = CMIS_ADDR; + chip.byte_len = ONE_ADDR_EEPROM_SIZE; + num_addresses = 1; + } else { /* those were the only 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]); + optoe->client[1] = NULL; + } + } + + 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 = "wb_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("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.c new file mode 100644 index 000000000000..1f5180ffccdc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.c @@ -0,0 +1,770 @@ +/* + * wb_pcie_dev.c + * ko to read/write pcie iomem and ioports through /dev/XXX device + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_pcie_dev.h" + +#define PROXY_NAME "wb-pci-dev" +#define MAX_NAME_SIZE (20) +#define MAX_PCIE_NUM (256) +#define PCI_RDWR_MAX_LEN (256) +#define PCIE_BUS_WIDTH_1 (1) +#define PCIE_BUS_WIDTH_2 (2) +#define PCIE_BUS_WIDTH_4 (4) + +static int g_pcie_dev_debug = 0; +static int g_pcie_dev_error = 0; + +module_param(g_pcie_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_pcie_dev_error, int, S_IRUGO | S_IWUSR); + +#define PCIE_DEV_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_pcie_dev_debug) { \ + printk(KERN_INFO "[PCIE_DEV][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PCIE_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_pcie_dev_error) { \ + printk(KERN_ERR "[PCIE_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef struct firmware_upg_s { + int upg_ctrl_base; + int upg_flash_base; +} firmware_upg_t; + +typedef struct wb_pci_dev_s { + const char *name; + uint32_t domain; + uint32_t bus; + uint32_t slot; + uint32_t fn; + uint32_t bar; + void __iomem *pci_mem_base; + uint32_t pci_io_base; + uint32_t bar_len; + uint32_t bar_flag; + uint32_t bus_width; + struct miscdevice misc; + void (*setreg)(struct wb_pci_dev_s *wb_pci_dev, int reg, u32 value); + u32 (*getreg)(struct wb_pci_dev_s *wb_pci_dev, int reg); + firmware_upg_t firmware_upg; +} wb_pci_dev_t; + +static wb_pci_dev_t* pcie_dev_arry[MAX_PCIE_NUM]; + +static void pci_dev_setreg_8(wb_pci_dev_t *wb_pci_dev, int reg, u32 value) +{ + u8 w_value; + + w_value = (u8)(value & 0xff); + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + writeb(w_value, wb_pci_dev->pci_mem_base + reg); + } else { + outb(w_value, wb_pci_dev->pci_io_base + reg); + } + return; +} + +static void pci_dev_setreg_16(wb_pci_dev_t *wb_pci_dev, int reg, u32 value) +{ + u16 w_value; + + w_value = (u16)(value & 0xffff); + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + writew(w_value, wb_pci_dev->pci_mem_base + reg); + } else { + outw(w_value, wb_pci_dev->pci_io_base + reg); + } + + return; +} + +static void pci_dev_setreg_32(wb_pci_dev_t *wb_pci_dev, int reg, u32 value) +{ + + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + writel(value, wb_pci_dev->pci_mem_base + reg); + } else { + outl(value, wb_pci_dev->pci_io_base + reg); + } + return; +} + +static inline u32 pci_dev_getreg_8(wb_pci_dev_t *wb_pci_dev, int reg) +{ + u32 value; + + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + value = readb(wb_pci_dev->pci_mem_base + reg); + } else { + value = inb(wb_pci_dev->pci_io_base + reg); + } + + return value; +} + +static inline u32 pci_dev_getreg_16(wb_pci_dev_t *wb_pci_dev, int reg) +{ + u32 value; + + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + value = readw(wb_pci_dev->pci_mem_base + reg); + } else { + value = inw(wb_pci_dev->pci_io_base + reg); + } + + return value; +} + +static inline u32 pci_dev_getreg_32(wb_pci_dev_t *wb_pci_dev, int reg) +{ + u32 value; + + if (wb_pci_dev->bar_flag == IORESOURCE_MEM) { + value = readl(wb_pci_dev->pci_mem_base + reg); + } else { + value = inl(wb_pci_dev->pci_io_base + reg); + } + + return value; +} + +static inline void pci_dev_setreg(wb_pci_dev_t *wb_pci_dev, int reg, u32 value) +{ + wb_pci_dev->setreg(wb_pci_dev, reg, value); +} + +static inline u32 pci_dev_getreg(wb_pci_dev_t *wb_pci_dev, int reg) +{ + return wb_pci_dev->getreg(wb_pci_dev, reg); +} + +static int pci_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + wb_pci_dev_t *wb_pci_dev; + + PCIE_DEV_DEBUG_VERBOSE("inode: %p, file: %p, minor: %u", inode, file, minor); + + if (minor >= MAX_PCIE_NUM) { + PCIE_DEV_DEBUG_ERROR("minor out of range, minor = %d.\n", minor); + return -ENODEV; + } + + wb_pci_dev = pcie_dev_arry[minor]; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, open failed, minor = %d\n", minor); + return -ENODEV; + } + + file->private_data = wb_pci_dev; + return 0; +} + +static int pci_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + return 0; +} + +static int pci_dev_read_tmp(wb_pci_dev_t *wb_pci_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int width, i, j; + u32 val; + + if (offset > wb_pci_dev->bar_len) { + PCIE_DEV_DEBUG_VERBOSE("offset:0x%x, bar len:0x%x, EOF.\n", offset, wb_pci_dev->bar_len); + return 0; + } + + width = wb_pci_dev->bus_width; + + if (offset % width) { + PCIE_DEV_DEBUG_ERROR("pci bus width:%d, offset:0x%x, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + + if (count > wb_pci_dev->bar_len - offset) { + PCIE_DEV_DEBUG_VERBOSE("read count out of range. input len:%lu, read len:%u.\n", + count, wb_pci_dev->bar_len - offset); + count = wb_pci_dev->bar_len - offset; + } + + for (i = 0; i < count; i += width) { + val = pci_dev_getreg(wb_pci_dev, offset + i); + for (j = 0; (j < width) && (i + j < count); j++) { + buf[i + j] = (val >> (8 * j)) & 0xff; + } + } + return count; +} + +static ssize_t pci_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + wb_pci_dev_t *wb_pci_dev; + int ret, read_len; + u8 buf_tmp[PCI_RDWR_MAX_LEN]; + + wb_pci_dev = file->private_data; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, read failed.\n"); + return -EINVAL; + } + + if (count == 0) { + PCIE_DEV_DEBUG_ERROR("Invalid params, read count is 0.n"); + return -EINVAL; + } + + if (count > sizeof(buf_tmp)) { + PCIE_DEV_DEBUG_VERBOSE("read conut %lu exceed max %lu.\n", count, sizeof(buf_tmp)); + count = sizeof(buf_tmp); + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + read_len = pci_dev_read_tmp(wb_pci_dev, *offset, buf_tmp, count); + if (read_len < 0) { + PCIE_DEV_DEBUG_ERROR("pci_dev_read_tmp failed, ret:%d.\n", read_len); + return read_len; + } + if (access_ok(buf, read_len)) { + PCIE_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + if (copy_to_user(buf, buf_tmp, read_len)) { + PCIE_DEV_DEBUG_ERROR("copy_to_user failed.\n"); + return -EFAULT; + } + } else { + PCIE_DEV_DEBUG_VERBOSE("kernel space read, buf: %p, offset: %lld, read conut %lu.\n", + buf, *offset, count); + memcpy(buf, buf_tmp, read_len); + } + *offset += read_len; + ret = read_len; + return ret; +} + +static ssize_t pci_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + int ret; + + PCIE_DEV_DEBUG_VERBOSE("pci_dev_read_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, to->count, iocb->ki_pos); + ret = pci_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos); + return ret; +} + +static int pci_dev_write_tmp(wb_pci_dev_t *wb_pci_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int width, i, j; + u32 val; + + if (offset > wb_pci_dev->bar_len) { + PCIE_DEV_DEBUG_VERBOSE("offset:0x%x, bar len:0x%x, EOF.\n", offset, wb_pci_dev->bar_len); + return 0; + } + + width = wb_pci_dev->bus_width; + + if (offset % width) { + PCIE_DEV_DEBUG_ERROR("pci bus width:%d, offset:0x%x, read size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + + if (count > wb_pci_dev->bar_len - offset) { + PCIE_DEV_DEBUG_VERBOSE("write count out of range. input len:%lu, write len:%u.\n", + count, wb_pci_dev->bar_len - offset); + count = wb_pci_dev->bar_len - offset; + } + + for (i = 0; i < count; i += width) { + val = 0; + for (j = 0; (j < width) && (i + j < count); j++) { + val |= buf[i + j] << (8 * j); + } + pci_dev_setreg(wb_pci_dev, i + offset, val); + } + + return count; +} + +static ssize_t pci_dev_write(struct file *file, const char __user *buf, size_t count, + loff_t *offset) +{ + wb_pci_dev_t *wb_pci_dev; + u8 buf_tmp[PCI_RDWR_MAX_LEN]; + int write_len; + + wb_pci_dev = file->private_data; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, write failed.\n"); + return -EINVAL; + } + + if (count == 0) { + PCIE_DEV_DEBUG_ERROR("Invalid params, write count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(buf_tmp)) { + PCIE_DEV_DEBUG_VERBOSE("write conut %lu exceed max %lu.\n", count, sizeof(buf_tmp)); + count = sizeof(buf_tmp); + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + if (access_ok(buf, count)) { + PCIE_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + if (copy_from_user(buf_tmp, buf, count)) { + PCIE_DEV_DEBUG_ERROR("copy_from_user failed.\n"); + return -EFAULT; + } + } else { + PCIE_DEV_DEBUG_VERBOSE("kernel space write, buf: %p, offset: %lld, write conut %lu.\n", + buf, *offset, count); + memcpy(buf_tmp, buf, count); + } + + write_len = pci_dev_write_tmp(wb_pci_dev, *offset, buf_tmp, count); + if (write_len < 0) { + PCIE_DEV_DEBUG_ERROR("pci_dev_write_tmp failed, ret:%d.\n", write_len); + return write_len; + } + + *offset += write_len; + return write_len; +} + +static ssize_t pci_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + int ret; + + PCIE_DEV_DEBUG_VERBOSE("pci_dev_write_iter, file: %p, count: %lu, offset: %lld\n", + iocb->ki_filp, from->count, iocb->ki_pos); + ret = pci_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos); + return ret; +} + +static loff_t pci_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + wb_pci_dev_t *wb_pci_dev; + + wb_pci_dev = file->private_data; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, llseek failed.\n"); + return -EINVAL; + } + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + PCIE_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + if (offset > wb_pci_dev->bar_len) { + PCIE_DEV_DEBUG_ERROR("SEEK_SET out of range, offset:%lld, bar len:0x%x.\n", + offset, wb_pci_dev->bar_len); + ret = - EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (((file->f_pos + offset) > wb_pci_dev->bar_len) || ((file->f_pos + offset) < 0)) { + PCIE_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld, bar len:0x%x.\n", + file->f_pos, offset, wb_pci_dev->bar_len); + ret = - EINVAL; + break; + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + PCIE_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static long pci_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + wb_pci_dev_t *wb_pci_dev; + void __user *argp; + firmware_upg_t *firmware_upg; + int upg_ctrl_base; + int upg_flash_base; + + PCIE_DEV_DEBUG_VERBOSE("ioctl, cmd=0x%02x, arg=0x%02lx\n",cmd, arg); + + wb_pci_dev = file->private_data; + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("wb_pci_dev is NULL, ioctl failed.\n"); + return -EINVAL; + } + + firmware_upg = &wb_pci_dev->firmware_upg; + + argp = (void __user *)arg; + + switch (cmd) { + case GET_FPGA_UPG_CTL_BASE: + if (firmware_upg->upg_ctrl_base < 0) { + PCIE_DEV_DEBUG_ERROR("dts not adaptive upg_ctrl_base\n"); + return -EFAULT; + } else { + upg_ctrl_base = firmware_upg->upg_ctrl_base; + if (copy_to_user(argp, &upg_ctrl_base, sizeof(upg_ctrl_base))) { + PCIE_DEV_DEBUG_ERROR("upg_ctrl_base copy_from_user failed\n"); + return -EFAULT; + } + } + break; + case GET_FPGA_UPG_FLASH_BASE: + if (firmware_upg->upg_flash_base < 0) { + PCIE_DEV_DEBUG_ERROR("dts not adaptive upg_flash_base\n"); + return -EFAULT; + } else { + upg_flash_base = firmware_upg->upg_flash_base; + if (copy_to_user(argp, &upg_flash_base, sizeof(upg_flash_base))) { + PCIE_DEV_DEBUG_ERROR("upg_flash_base copy_from_user failed\n"); + return -EFAULT; + } + } + break; + default: + PCIE_DEV_DEBUG_ERROR("command unsupported \n"); + return -ENOTTY; + } + + return 0; +} + +static const struct file_operations pcie_dev_fops = { + .owner = THIS_MODULE, + .llseek = pci_dev_llseek, + .read_iter = pci_dev_read_iter, + .write_iter = pci_dev_write_iter, + .unlocked_ioctl = pci_dev_ioctl, + .open = pci_dev_open, + .release = pci_dev_release, +}; + +static wb_pci_dev_t *dev_match(const char *path) +{ + wb_pci_dev_t *wb_pci_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + + for (i = 0; i < MAX_PCIE_NUM; i++) { + if (pcie_dev_arry[i] == NULL) { + continue; + } + wb_pci_dev = pcie_dev_arry[i]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", wb_pci_dev->name); + if (!strcmp(path, dev_name)) { + PCIE_DEV_DEBUG_VERBOSE("get dev_name = %s, minor = %d\n", dev_name, i); + return wb_pci_dev; + } + } + + return NULL; +} + +int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + wb_pci_dev_t *wb_pci_dev; + int read_len; + + if (path == NULL) { + PCIE_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + PCIE_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + wb_pci_dev = dev_match(path); + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + read_len = pci_dev_read_tmp(wb_pci_dev, offset, buf, count); + if (read_len < 0) { + PCIE_DEV_DEBUG_ERROR("pci_dev_read_tmp failed, ret:%d.\n", read_len); + } + return read_len; +} +EXPORT_SYMBOL(pcie_device_func_read); + +int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + wb_pci_dev_t *wb_pci_dev; + int write_len; + + if (path == NULL) { + PCIE_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + PCIE_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + wb_pci_dev = dev_match(path); + if (wb_pci_dev == NULL) { + PCIE_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + write_len = pci_dev_write_tmp(wb_pci_dev, offset, buf, count); + if (write_len < 0) { + PCIE_DEV_DEBUG_ERROR("pci_dev_write_tmp failed, ret:%d.\n", write_len); + } + return write_len; +} +EXPORT_SYMBOL(pcie_device_func_write); + +static int pci_setup_bars(wb_pci_dev_t *wb_pci_dev, struct pci_dev *dev) +{ + int ret; + uint32_t addr, len, flags; + + ret = 0; + addr = pci_resource_start(dev, wb_pci_dev->bar); + len = pci_resource_len(dev, wb_pci_dev->bar); + if (addr == 0 || len == 0) { + PCIE_DEV_DEBUG_ERROR("get bar addr failed. bar:%d, addr:0x%x, len:0x%x.\n", + wb_pci_dev->bar, addr, len); + return -EFAULT; + } + wb_pci_dev->bar_len = len; + + flags = pci_resource_flags(dev, wb_pci_dev->bar); + PCIE_DEV_DEBUG_VERBOSE("bar:%d, flag:0x%08x, phys addr:0x%x, len:0x%x\n", + wb_pci_dev->bar, flags, addr, len); + if (flags & IORESOURCE_MEM) { + wb_pci_dev->bar_flag = IORESOURCE_MEM; + wb_pci_dev->pci_mem_base = ioremap(addr, len); + PCIE_DEV_DEBUG_VERBOSE("pci mem base:%p.\n", wb_pci_dev->pci_mem_base); + } else if (flags & IORESOURCE_IO) { + wb_pci_dev->bar_flag = IORESOURCE_IO; + wb_pci_dev->pci_io_base = addr; + PCIE_DEV_DEBUG_VERBOSE("pci io base:0x%x.\n", wb_pci_dev->pci_io_base); + } else { + PCIE_DEV_DEBUG_ERROR("unknow pci bar flag:0x%08x.\n", flags); + ret = -EINVAL; + } + + return ret; +} + +static int pci_dev_probe(struct platform_device *pdev) +{ + int ret, devfn; + wb_pci_dev_t *wb_pci_dev; + struct pci_dev *pci_dev; + struct miscdevice *misc; + firmware_upg_t *firmware_upg; + pci_dev_device_t *pci_dev_device; + + wb_pci_dev = devm_kzalloc(&pdev->dev, sizeof(wb_pci_dev_t), GFP_KERNEL); + if (!wb_pci_dev) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + ret = -ENOMEM; + return ret; + } + + firmware_upg = &wb_pci_dev->firmware_upg; + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "pci_dev_name", &wb_pci_dev->name); + ret += of_property_read_u32(pdev->dev.of_node, "pci_domain", &wb_pci_dev->domain); + ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &wb_pci_dev->bus); + ret += of_property_read_u32(pdev->dev.of_node, "pci_slot", &wb_pci_dev->slot); + ret += of_property_read_u32(pdev->dev.of_node, "pci_fn", &wb_pci_dev->fn); + ret += of_property_read_u32(pdev->dev.of_node, "pci_bar", &wb_pci_dev->bar); + ret += of_property_read_u32(pdev->dev.of_node, "bus_width", &wb_pci_dev->bus_width); + + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret); + return -ENXIO; + } + + ret = 0; + ret += of_property_read_u32(pdev->dev.of_node, "upg_ctrl_base", &firmware_upg->upg_ctrl_base); + ret += of_property_read_u32(pdev->dev.of_node, "upg_flash_base", &firmware_upg->upg_flash_base); + if (ret != 0) { + PCIE_DEV_DEBUG_VERBOSE("dts don't adaptive fpga upg related, ret:%d.\n", ret); + firmware_upg->upg_ctrl_base = -1; + firmware_upg->upg_flash_base = -1; + } else { + PCIE_DEV_DEBUG_VERBOSE("upg_ctrl_base:0x%04x, upg_flash_base:0x%02x.\n", + firmware_upg->upg_ctrl_base, firmware_upg->upg_flash_base); + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + pci_dev_device = pdev->dev.platform_data; + wb_pci_dev->name = pci_dev_device->pci_dev_name; + wb_pci_dev->domain = pci_dev_device->pci_domain; + wb_pci_dev->bus = pci_dev_device->pci_bus; + wb_pci_dev->slot = pci_dev_device->pci_slot; + wb_pci_dev->fn = pci_dev_device->pci_fn; + wb_pci_dev->bar = pci_dev_device->pci_bar; + wb_pci_dev->bus_width = pci_dev_device->bus_width; + firmware_upg->upg_ctrl_base = pci_dev_device->upg_ctrl_base; + firmware_upg->upg_flash_base = pci_dev_device->upg_flash_base; + PCIE_DEV_DEBUG_VERBOSE("upg_ctrl_base:0x%04x, upg_flash_base:0x%02x.\n", + firmware_upg->upg_ctrl_base, firmware_upg->upg_flash_base); + } + + PCIE_DEV_DEBUG_VERBOSE("name:%s, domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u, bar:%u, bus_width:%d.\n", + wb_pci_dev->name, wb_pci_dev->domain, wb_pci_dev->bus, wb_pci_dev->slot, wb_pci_dev->fn, + wb_pci_dev->bar, wb_pci_dev->bus_width); + + devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); + if (pci_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bus, devfn); + return -ENXIO; + } + ret = pci_setup_bars(wb_pci_dev, pci_dev); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get pci bar address.\n"); + return ret; + } + + if (!wb_pci_dev->setreg || !wb_pci_dev->getreg) { + switch (wb_pci_dev->bus_width) { + case 1: + wb_pci_dev->setreg = pci_dev_setreg_8; + wb_pci_dev->getreg = pci_dev_getreg_8; + break; + + case 2: + wb_pci_dev->setreg = pci_dev_setreg_16; + wb_pci_dev->getreg = pci_dev_getreg_16; + break; + + case 4: + wb_pci_dev->setreg = pci_dev_setreg_32; + wb_pci_dev->getreg = pci_dev_getreg_32; + break; + default: + dev_err(&pdev->dev, "Error: unsupported I/O width (%d).\n", wb_pci_dev->bus_width); + ret = -EINVAL; + goto io_unmap; + } + } + + misc = &wb_pci_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = wb_pci_dev->name; + misc->fops = &pcie_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&pdev->dev, "Failed to register %s device.\n", misc->name); + ret = -ENXIO; + goto io_unmap; + } + if (misc->minor >= MAX_PCIE_NUM) { + dev_err(&pdev->dev, "Error: device minor[%d] more than max pcie num[%d].\n", + misc->minor, MAX_PCIE_NUM); + misc_deregister(misc); + ret = -EINVAL; + goto io_unmap; + } + pcie_dev_arry[misc->minor] = wb_pci_dev; + dev_info(&pdev->dev, "%04x:%02x:%02x.%d[bar%d: %s]: register %s device with minor:%d success.\n", + wb_pci_dev->domain, wb_pci_dev->bus, wb_pci_dev->slot, wb_pci_dev->fn, wb_pci_dev->bar, + wb_pci_dev->bar_flag == IORESOURCE_MEM ? "IORESOURCE_MEM" : "IORESOURCE_IO", + misc->name, misc->minor ); + return 0; + +io_unmap: + if (wb_pci_dev->pci_mem_base) { + iounmap(wb_pci_dev->pci_mem_base); + } + return ret; +} + +static int pci_dev_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < MAX_PCIE_NUM ; i++) { + if (pcie_dev_arry[i] != NULL) { + if (pcie_dev_arry[i]->pci_mem_base) { + iounmap(pcie_dev_arry[i]->pci_mem_base); + } + misc_deregister(&pcie_dev_arry[i]->misc); + pcie_dev_arry[i] = NULL; + } + } + + return 0; +} + +static struct of_device_id pci_dev_match[] = { + { + .compatible = "wb-pci-dev", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, pci_dev_match); + +static struct platform_driver wb_pci_dev_driver = { + .probe = pci_dev_probe, + .remove = pci_dev_remove, + .driver = { + .owner = THIS_MODULE, + .name = PROXY_NAME, + .of_match_table = pci_dev_match, + }, +}; + +static int __init wb_pci_dev_init(void) +{ + return platform_driver_register(&wb_pci_dev_driver); +} + +static void __exit wb_pci_dev_exit(void) +{ + platform_driver_unregister(&wb_pci_dev_driver); +} + +module_init(wb_pci_dev_init); +module_exit(wb_pci_dev_exit); +MODULE_DESCRIPTION("pcie device driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.h new file mode 100644 index 000000000000..9ba0f3b457ea --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_pcie_dev.h @@ -0,0 +1,26 @@ +#ifndef __WB_PCIE_DEV_H__ +#define __WB_PCIE_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define UPG_TYPE 'U' +#define GET_FPGA_UPG_CTL_BASE _IOR(UPG_TYPE, 0, int) +#define GET_FPGA_UPG_FLASH_BASE _IOR(UPG_TYPE, 1, int) + +#define PCI_DEV_NAME_MAX_LEN (64) + +typedef struct pci_dev_device_s { + char pci_dev_name[PCI_DEV_NAME_MAX_LEN]; + int pci_domain; + int pci_bus; + int pci_slot; + int pci_fn; + int pci_bar; + int bus_width; + int upg_ctrl_base; + int upg_flash_base; + int device_flag; +} pci_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.c new file mode 100644 index 000000000000..3fe1c4aa10f5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.c @@ -0,0 +1,749 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_platform_i2c_dev.h" + +#define PROXY_NAME "wb-platform-i2c-dev" +#define MAX_I2C_DEV_NUM (256) +#define FPGA_MAX_LEN (256) +#define MAX_NAME_SIZE (20) +#define MAX_BUS_WIDTH (16) +#define TRANSFER_WRITE_BUFF (FPGA_MAX_LEN + MAX_BUS_WIDTH) + +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) + +int g_i2c_dev_debug = 0; +int g_i2c_dev_error = 0; + +module_param(g_i2c_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_i2c_dev_error, int, S_IRUGO | S_IWUSR); + +#define I2C_DEV_DEBUG_DMESG(fmt, args...) do { \ + if (g_i2c_dev_debug) { \ + printk(KERN_ERR "[I2C_DEV][DEBUG][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define I2C_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_i2c_dev_error) { \ + printk(KERN_ERR "[I2C_DEV][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct platform_i2c_dev_info* i2c_dev_arry[MAX_I2C_DEV_NUM]; + +struct platform_i2c_dev_info { + uint32_t i2c_bus; + uint32_t i2c_addr; + const char *name; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + struct miscdevice misc; +}; + +static int transfer_read(struct platform_i2c_dev_info *i2c_dev, u8 *buf, loff_t regaddr, size_t count) +{ + int i, j; + struct i2c_adapter *adap; + union i2c_smbus_data data; + u8 offset_buf[MAX_BUS_WIDTH]; + struct i2c_msg msgs[2]; + int msgs_num, ret; + u8 offset; + u8 length; + + if (!i2c_dev) { + I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\r\n"); + return -ENODEV; + } + + i = 0; + + mem_clear(offset_buf, sizeof(offset_buf)); + + switch (i2c_dev->addr_bus_width) { + case WIDTH_4Byte: + offset_buf[i++] = (regaddr >> 24) & 0xFF; + offset_buf[i++] = (regaddr >> 16) & 0xFF; + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + offset_buf[i++] = regaddr & 0xFF; + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\r\n", i2c_dev->addr_bus_width); + return -EINVAL; + } + + adap = i2c_get_adapter(i2c_dev->i2c_bus); + if (adap == NULL) { + I2C_DEV_DEBUG_ERROR("get i2c adapter %d faild.\n", i2c_dev->i2c_bus); + return -ENXIO; + } + + if (adap->algo->master_xfer) { + mem_clear(msgs, sizeof(msgs)); + msgs[0].addr = i2c_dev->i2c_addr; + msgs[0].flags = 0; + msgs[0].len = i2c_dev->addr_bus_width; + msgs[0].buf = offset_buf; + + msgs[1].addr = i2c_dev->i2c_addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = count; + msgs[1].buf = buf; + + msgs_num = 2; + ret = i2c_transfer(adap, msgs, msgs_num); + if (ret != msgs_num) { + I2C_DEV_DEBUG_ERROR("i2c_transfer read error\r\n"); + ret = -EFAULT; + goto error_exit; + } + } else { + if (i2c_dev->addr_bus_width == WIDTH_1Byte) { + offset = regaddr & 0xFF; + if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + for (j = 0; j < count; j += I2C_SMBUS_BLOCK_MAX) { + if (count - j > I2C_SMBUS_BLOCK_MAX) { + length = I2C_SMBUS_BLOCK_MAX; + } else { + length = count - j; + } + data.block[0] = length; + ret = adap->algo->smbus_xfer(adap, i2c_dev->i2c_addr, + 0, + I2C_SMBUS_READ, + offset, I2C_SMBUS_I2C_BLOCK_DATA, &data); + if (ret) { + I2C_DEV_DEBUG_ERROR("smbus_xfer read block error, ret = %d\r\n", ret); + ret = -EFAULT; + goto error_exit; + } + memcpy(buf + j, data.block + 1, length); + offset += length; + } + } else { + for (j = 0; j < count; j++) { + ret = adap->algo->smbus_xfer(adap, i2c_dev->i2c_addr, + 0, + I2C_SMBUS_READ, + offset, I2C_SMBUS_BYTE_DATA, &data); + + if (!ret) { + buf[j] = data.byte; + } else { + I2C_DEV_DEBUG_ERROR("smbus_xfer read byte error, ret = %d\r\n", ret); + ret = -EFAULT; + goto error_exit; + } + offset++; + } + } + } else { + I2C_DEV_DEBUG_ERROR("smbus_xfer not support addr_bus_width = %d\r\n", i2c_dev->addr_bus_width); + ret = -EINVAL; + goto error_exit; + } + } + + i2c_put_adapter(adap); + return 0; +error_exit: + i2c_put_adapter(adap); + return ret; +} + +static int transfer_write(struct platform_i2c_dev_info *i2c_dev, u8 *buf, loff_t regaddr, size_t count) +{ + int i, j; + struct i2c_adapter *adap; + union i2c_smbus_data data; + u8 offset_buf[TRANSFER_WRITE_BUFF]; + struct i2c_msg msgs[1]; + int msgs_num, ret; + u8 offset; + u8 length; + + if (!i2c_dev) { + I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\r\n"); + return -ENODEV; + } + + i = 0; + + mem_clear(offset_buf, sizeof(offset_buf)); + + switch (i2c_dev->addr_bus_width) { + case WIDTH_4Byte: + offset_buf[i++] = (regaddr >> 24) & 0xFF; + offset_buf[i++] = (regaddr >> 16) & 0xFF; + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + offset_buf[i++] = (regaddr >> 8) & 0xFF; + offset_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + offset_buf[i++] = regaddr & 0xFF; + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\r\n", i2c_dev->addr_bus_width); + return -EINVAL; + } + + memcpy(offset_buf + i2c_dev->addr_bus_width, buf, count); + + adap = i2c_get_adapter(i2c_dev->i2c_bus); + if (adap == NULL) { + I2C_DEV_DEBUG_ERROR("get i2c adapter %d faild.\n", i2c_dev->i2c_bus); + return -ENXIO; + } + + if (adap->algo->master_xfer) { + mem_clear(msgs, sizeof(msgs)); + + msgs[0].addr = i2c_dev->i2c_addr; + msgs[0].flags = 0; + msgs[0].len = i2c_dev->addr_bus_width + count; + msgs[0].buf = offset_buf; + + msgs_num = 1; + ret = i2c_transfer(adap, msgs, msgs_num); + if (ret != msgs_num) { + I2C_DEV_DEBUG_ERROR("i2c_transfer write error\r\n"); + ret = -EFAULT; + goto error_exit; + } + } else { + if (i2c_dev->addr_bus_width == WIDTH_1Byte) { + offset = regaddr & 0xFF; + if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + for (j = 0; j < count; j += I2C_SMBUS_BLOCK_MAX) { + if (count - j > I2C_SMBUS_BLOCK_MAX) { + length = I2C_SMBUS_BLOCK_MAX; + } else { + length = count - j; + } + data.block[0] = length; + memcpy(data.block + 1, buf + j, length); + ret = adap->algo->smbus_xfer(adap, i2c_dev->i2c_addr, + 0, + I2C_SMBUS_WRITE, + offset, I2C_SMBUS_I2C_BLOCK_DATA, &data); + if (ret) { + I2C_DEV_DEBUG_ERROR("smbus_xfer write block error, ret = %d\r\n", ret); + ret = -EFAULT; + goto error_exit; + } + offset += length; + } + } else { + for (j = 0; j < count; j++) { + data.byte = buf[j]; + ret = adap->algo->smbus_xfer(adap, i2c_dev->i2c_addr, + 0, + I2C_SMBUS_WRITE, + offset, I2C_SMBUS_BYTE_DATA, &data); + if (ret) { + I2C_DEV_DEBUG_ERROR("smbus_xfer write byte error, ret = %d\r\n", ret); + ret = -EFAULT; + goto error_exit; + } + offset += 1; + } + } + } else { + I2C_DEV_DEBUG_ERROR("smbus_xfer not support addr_bus_width = %d\r\n", i2c_dev->addr_bus_width); + ret = -EINVAL; + goto error_exit; + } + } + + i2c_put_adapter(adap); + return 0; +error_exit: + i2c_put_adapter(adap); + return ret; +} + +static long i2c_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int i2c_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct platform_i2c_dev_info *i2c_dev; + + i2c_dev = i2c_dev_arry[minor]; + if (i2c_dev == NULL) { + return -ENODEV; + } + + file->private_data = i2c_dev; + + return 0; +} + +static int i2c_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static int device_read(struct platform_i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, int count) +{ + int i, j, ret; + u8 tmp_offset; + u8 val[FPGA_MAX_LEN]; + u32 width, rd_len, per_len, tmp; + u32 max_per_len; + + width = i2c_dev->data_bus_width; + switch (width) { + case WIDTH_4Byte: + tmp_offset = offset & 0x3; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %d invalid.\r\n", width, offset, count); + return -EINVAL; + } + break; + case WIDTH_2Byte: + tmp_offset = offset & 0x1; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %d invalid.\r\n", width, offset, count); + return -EINVAL; + } + break; + case WIDTH_1Byte: + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\r\n", width); + return -EINVAL; + } + + max_per_len = i2c_dev->per_rd_len; + tmp = (width - 1) & count; + rd_len = (tmp == 0) ? count : count + width - tmp; + per_len = (rd_len > max_per_len) ? (max_per_len) : (rd_len); + + mem_clear(val, sizeof(val)); + for (i = 0; i < rd_len; i += per_len) { + ret = transfer_read(i2c_dev, val + i, offset + i, per_len); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("read error.read offset = %u\r\n", (offset + i)); + return -EFAULT; + } + } + + if (width == WIDTH_1Byte) { + memcpy(buf, val, count); + } else { + for (i = 0; i < count; i += width) { + for (j = 0; (j < width) && (i + j < count); j++) { + buf[i + j] = val[i + width - j - 1]; + } + } + } + + return 0; +} + +static int device_write(struct platform_i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u8 tmp_offset; + u32 width; + u8 val[FPGA_MAX_LEN]; + u32 wr_len, per_len, tmp; + u32 max_per_len; + + width = i2c_dev->data_bus_width; + switch (width) { + case WIDTH_4Byte: + tmp_offset = offset & 0x3; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\r\n", width, offset, count); + return -EINVAL; + } + break; + case WIDTH_2Byte: + tmp_offset = offset & 0x1; + if (tmp_offset) { + I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\r\n", width, offset, count); + return -EINVAL; + } + break; + case WIDTH_1Byte: + break; + default: + I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\r\n", width); + return -EINVAL; + } + + mem_clear(val, sizeof(val)); + + if (width == WIDTH_1Byte) { + memcpy(val, buf, count); + } else { + for (i = 0; i < count; i += width) { + for (j = 0; (j < width) && (i + j < count); j++) { + val[i + width - j - 1] = buf[i + j]; + } + } + } + + max_per_len = i2c_dev->per_wr_len; + tmp = (width - 1) & count; + wr_len = (tmp == 0) ? count : count + width - tmp; + per_len = (wr_len > max_per_len) ? (max_per_len) : (wr_len); + + for (i = 0; i < wr_len; i += per_len) { + ret = transfer_write(i2c_dev, val + i, offset + i, per_len); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("write error.offset = %u\r\n", (offset + i)); + return -EFAULT; + } + } + return 0; +} + +static ssize_t i2c_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + u8 val[FPGA_MAX_LEN]; + int ret; + struct platform_i2c_dev_info *i2c_dev; + + if (count <= 0 || count > sizeof(val)) { + I2C_DEV_DEBUG_ERROR("read conut %lu , beyond max:%lu.\n", count, sizeof(val)); + return -EINVAL; + } + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("can't get read private_data .\r\n"); + return -EINVAL; + } + + ret = device_read(i2c_dev, (uint32_t)*offset, val, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, (uint32_t)*offset, count); + return -EINVAL; + } + + if (copy_to_user(buf, val, count)) { + I2C_DEV_DEBUG_ERROR("copy_to_user error \r\n"); + return -EFAULT; + } else{ + *offset += count; + } + + return count; +} + +static ssize_t i2c_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) +{ + u8 val[FPGA_MAX_LEN]; + int ret; + struct platform_i2c_dev_info *i2c_dev; + + if (count <= 0 || count > sizeof(val)) { + I2C_DEV_DEBUG_ERROR("write conut %lu, beyond max val:%lu.\n", count, sizeof(val)); + return -EINVAL; + } + + i2c_dev = file->private_data; + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("get write private_data error.\r\n"); + return -EINVAL; + } + + mem_clear(val, sizeof(val)); + if (copy_from_user(val, buf, count)) { + I2C_DEV_DEBUG_ERROR("copy_from_user error.\r\n"); + return -EFAULT; + } + + ret = device_write (i2c_dev, (uint32_t)*offset, val, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%llx, len:%lu.\n", + i2c_dev->name, *offset, count); + return -EINVAL; + } + + *offset += count; + return count; +} + +static loff_t i2c_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + I2C_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\r\n", offset); + ret = -EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (file->f_pos + offset < 0) { + I2C_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld.\n", + file->f_pos, offset); + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + I2C_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static const struct file_operations i2c_dev_fops = { + .owner = THIS_MODULE, + .llseek = i2c_dev_llseek, + .read = i2c_dev_read, + .write = i2c_dev_write, + .unlocked_ioctl = i2c_dev_ioctl, + .open = i2c_dev_open, + .release = i2c_dev_release, +}; + +static struct platform_i2c_dev_info * dev_match(const char *path) +{ + struct platform_i2c_dev_info *i2c_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + for (i = 0; i < MAX_I2C_DEV_NUM; i++) { + if (i2c_dev_arry[ i ] == NULL) { + continue; + } + i2c_dev = i2c_dev_arry[ i ]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", i2c_dev->name); + if (!strcmp(path, dev_name)) { + I2C_DEV_DEBUG_DMESG("get dev_name = %s, minor = %d\n", dev_name, i); + return i2c_dev; + } + } + + return NULL; +} + +int platform_i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct platform_i2c_dev_info *i2c_dev = NULL; + int ret; + + if(path == NULL){ + I2C_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + I2C_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > FPGA_MAX_LEN) { + I2C_DEV_DEBUG_ERROR("read conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN); + return -EINVAL; + } + + i2c_dev = dev_match(path); + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_read(i2c_dev, offset, buf, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("fpga i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(platform_i2c_device_func_read); + +int platform_i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct platform_i2c_dev_info *i2c_dev = NULL; + int ret; + + if(path == NULL){ + I2C_DEV_DEBUG_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + I2C_DEV_DEBUG_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > FPGA_MAX_LEN) { + I2C_DEV_DEBUG_ERROR("write conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN); + return -EINVAL; + } + + i2c_dev = dev_match(path); + if (i2c_dev == NULL) { + I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_write (i2c_dev, offset, buf, count); + if (ret < 0) { + I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%x, len:%lu.\n", + i2c_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(platform_i2c_device_func_write); + +static int platform_i2c_dev_probe(struct platform_device *pdev) +{ + int ret = 0; + struct platform_i2c_dev_info *i2c_dev; + struct miscdevice *misc; + platform_i2c_dev_device_t *platform_i2c_dev_device; + + i2c_dev = devm_kzalloc(&pdev->dev, sizeof(struct platform_i2c_dev_info), GFP_KERNEL); + if (!i2c_dev) { + dev_err(&pdev->dev, "devm_kzalloc error. \r\n"); + return -ENOMEM; + } + + if (pdev->dev.of_node) { + + ret += of_property_read_u32(pdev->dev.of_node, "i2c_bus", &i2c_dev->i2c_bus); + ret += of_property_read_u32(pdev->dev.of_node, "i2c_addr", &i2c_dev->i2c_addr); + ret += of_property_read_string(pdev->dev.of_node, "i2c_name", &i2c_dev->name); + ret += of_property_read_u32(pdev->dev.of_node, "data_bus_width", &i2c_dev->data_bus_width); + ret += of_property_read_u32(pdev->dev.of_node, "addr_bus_width", &i2c_dev->addr_bus_width); + ret += of_property_read_u32(pdev->dev.of_node, "per_rd_len", &i2c_dev->per_rd_len); + ret += of_property_read_u32(pdev->dev.of_node, "per_wr_len", &i2c_dev->per_wr_len); + if (ret != 0) { + dev_err(&pdev->dev, "dts config error.ret:%d.\r\n", ret); + return -ENXIO; + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + platform_i2c_dev_device = pdev->dev.platform_data; + i2c_dev->i2c_bus = platform_i2c_dev_device->i2c_bus; + i2c_dev->i2c_addr = platform_i2c_dev_device->i2c_addr; + i2c_dev->name = platform_i2c_dev_device->i2c_name; + i2c_dev->data_bus_width = platform_i2c_dev_device->data_bus_width; + i2c_dev->addr_bus_width = platform_i2c_dev_device->addr_bus_width; + i2c_dev->per_rd_len = platform_i2c_dev_device->per_rd_len; + i2c_dev->per_wr_len = platform_i2c_dev_device->per_wr_len; + } + + if ((i2c_dev->per_rd_len & (i2c_dev->data_bus_width - 1)) || (i2c_dev->per_wr_len & (i2c_dev->data_bus_width - 1))) { + dev_err(&pdev->dev, "Invalid config per_rd_len %d per_wr_len %d data bus_width %d.\r\n", i2c_dev->per_rd_len, + i2c_dev->per_wr_len, i2c_dev->data_bus_width); + return -ENXIO; + } + + misc = &i2c_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = i2c_dev->name; + misc->fops = &i2c_dev_fops; + if (misc_register(misc) != 0) { + dev_err(&pdev->dev, "register %s faild.\r\n", misc->name); + return -ENXIO; + } + + if (misc->minor >= MAX_I2C_DEV_NUM) { + dev_err(&pdev->dev, "minor number beyond the limit! is %d.\r\n", misc->minor); + misc_deregister(misc); + return -ENXIO; + } + i2c_dev_arry[misc->minor] = i2c_dev; + + dev_info(&pdev->dev, "register %u addr_bus_width %u data_bus_width device %s with %u per_rd_len %u per_wr_len success.\r\n", + i2c_dev->addr_bus_width, i2c_dev->data_bus_width, i2c_dev->name, i2c_dev->per_rd_len, i2c_dev->per_wr_len); + + return 0; +} + +static int platform_i2c_dev_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < MAX_I2C_DEV_NUM ; i++) { + if (i2c_dev_arry[i] != NULL) { + misc_deregister(&i2c_dev_arry[i]->misc); + i2c_dev_arry[i] = NULL; + } + } + + return 0; +} + +static const struct of_device_id platform_i2c_dev_of_match[] = { + { .compatible = "wb-platform-i2c-dev" }, + { }, +}; +MODULE_DEVICE_TABLE(of, platform_i2c_dev_of_match); + +static struct platform_driver wb_platform_i2c_dev_driver = { + .probe = platform_i2c_dev_probe, + .remove = platform_i2c_dev_remove, + .driver = { + .owner = THIS_MODULE, + .name = PROXY_NAME, + .of_match_table = platform_i2c_dev_of_match, + }, +}; + +static int __init wb_platform_i2c_dev_init(void) +{ + return platform_driver_register(&wb_platform_i2c_dev_driver); +} + +static void __exit wb_platform_i2c_dev_exit(void) +{ + platform_driver_unregister(&wb_platform_i2c_dev_driver); +} + +module_init(wb_platform_i2c_dev_init); +module_exit(wb_platform_i2c_dev_exit); + +MODULE_DESCRIPTION("platform i2c dev driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.h new file mode 100644 index 000000000000..b5158c9fec57 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_platform_i2c_dev.h @@ -0,0 +1,19 @@ +#ifndef __WB_PLATFORM_I2C_DEV_H__ +#define __WB_PLATFORM_I2C_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define I2C_DEV_NAME_MAX_LEN (64) + +typedef struct platform_i2c_dev_device_s { + uint32_t i2c_bus; + uint32_t i2c_addr; + char i2c_name[I2C_DEV_NAME_MAX_LEN]; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + int device_flag; +} platform_i2c_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_93xx46.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_93xx46.c new file mode 100644 index 000000000000..abc4f1567aec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_93xx46.c @@ -0,0 +1,111 @@ +/* + * EEPROMs access control driver for display configuration EEPROMs + * on DigsyMTC board. + * + * (C) 2011 DENX Software Engineering, Anatolij Gustschin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_SPI_BUS_NUM (0) +#define DEFAULT_SPI_CS_NUM (0) +#define DEFAULT_SPI_HZ (100000) + +#define GPIO_EEPROM_CS (-1) + +int g_wb_spi_93xx46_debug = 0; +int g_wb_spi_93xx46_error = 0; +int spi_bus_num = DEFAULT_SPI_BUS_NUM; +int spi_cs_gpio = GPIO_EEPROM_CS; + +module_param(g_wb_spi_93xx46_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_93xx46_error, int, S_IRUGO | S_IWUSR); +module_param(spi_bus_num, int, S_IRUGO | S_IWUSR); +module_param(spi_cs_gpio, int, S_IRUGO | S_IWUSR); + +#define SPI_93xx46_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_93xx46_debug) { \ + printk(KERN_INFO "[SPI-93xx46][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SPI_93xx46_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_spi_93xx46_error) { \ + printk(KERN_ERR "[SPI-93xx46][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct eeprom_93xx46_platform_data eeprom_data = { + .flags = EE_ADDR16, + .quirks = EEPROM_93XX46_QUIRK_SINGLE_WORD_READ, +}; + +struct spi_board_info eeprom_93xx46_info __initdata = { + .modalias = "wb_93xx46", + .max_speed_hz = DEFAULT_SPI_HZ, + .bus_num = DEFAULT_SPI_BUS_NUM, + .chip_select = DEFAULT_SPI_CS_NUM, + .mode = SPI_MODE_0 | SPI_CS_HIGH, + .controller_data = (void *)GPIO_EEPROM_CS, + .platform_data = &eeprom_data, +}; + +static struct spi_device *g_spi_device; + +static int __init wb_spi_93xx46_init(void) +{ + struct spi_master *master; + + SPI_93xx46_DEBUG_VERBOSE("Enter.\n"); + + eeprom_93xx46_info.bus_num = spi_bus_num; + eeprom_93xx46_info.controller_data = (void *)(long)spi_cs_gpio; + master = spi_busnum_to_master(eeprom_93xx46_info.bus_num); + if (!master) { + SPI_93xx46_DEBUG_ERROR("get bus_num %u spi master failed.\n", + eeprom_93xx46_info.bus_num); + return -EINVAL; + } + + g_spi_device = spi_new_device(master, &eeprom_93xx46_info); + put_device(&master->dev); + if (!g_spi_device) { + SPI_93xx46_DEBUG_ERROR("register spi new device failed.\n"); + return -EPERM; + } + + if (g_wb_spi_93xx46_debug) { + dev_info(&g_spi_device->dev, "register %u bus_num spi 93xx46 eeprom success\n", + eeprom_93xx46_info.bus_num); + } + + return 0; +} + +static void __exit wb_spi_93xx46_exit(void) +{ + spi_unregister_device(g_spi_device); + + if (g_wb_spi_93xx46_debug) { + dev_info(&g_spi_device->dev, "unregister spi 93xx46 eeprom success\n"); + } + + return; +} + +module_init(wb_spi_93xx46_init); +module_exit(wb_spi_93xx46_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("create 93xx46 eeprom device"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.c new file mode 100644 index 000000000000..807663592db4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.c @@ -0,0 +1,583 @@ +/* + * wb_spi_dev.c + * ko to read/write spi device through /dev/XXX device + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_spi_dev.h" + +#define MAX_SPI_DEV_NUM (256) +#define MAX_RW_LEN (256) +#define MAX_NAME_SIZE (20) +#define MAX_ADDR_BUS_WIDTH (4) + +#define TRANSFER_WRITE_BUFF (1 + MAX_ADDR_BUS_WIDTH + MAX_RW_LEN) + +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) + +#define OP_READ (0x3) +#define OP_WRITE (0x2) + +int g_spi_dev_debug = 0; +int g_spi_dev_error = 0; + +module_param(g_spi_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_spi_dev_error, int, S_IRUGO | S_IWUSR); + +#define SPI_DEV_DEBUG(fmt, args...) do { \ + if (g_spi_dev_debug) { \ + printk(KERN_ERR "[SPI_DEV][DEBUG][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SPI_DEV_ERROR(fmt, args...) do { \ + if (g_spi_dev_error) { \ + printk(KERN_ERR "[SPI_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct spi_dev_info* spi_dev_arry[MAX_SPI_DEV_NUM]; + +struct spi_dev_info { + const char *name; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; + struct miscdevice misc; + struct spi_device *spi_device; +}; + +static int transfer_read(struct spi_dev_info *spi_dev, u8 *buf, uint32_t regaddr, size_t count) +{ + int i, ret; + u8 tx_buf[MAX_ADDR_BUS_WIDTH + 1]; + struct spi_message m; + struct spi_transfer xfer[2]; + + i = 0; + mem_clear(tx_buf, sizeof(tx_buf)); + tx_buf[i++] = OP_READ; + + switch (spi_dev->addr_bus_width) { + case WIDTH_4Byte: + tx_buf[i++] = (regaddr >> 24) & 0xFF; + tx_buf[i++] = (regaddr >> 16) & 0xFF; + tx_buf[i++] = (regaddr >> 8) & 0xFF; + tx_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + tx_buf[i++] = (regaddr >> 8) & 0xFF; + tx_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + tx_buf[i++] = regaddr & 0xFF; + break; + default: + SPI_DEV_ERROR("Only support 1,2,4 Byte Width,but set width = %u\n", + spi_dev->addr_bus_width); + return -EINVAL; + } + + mem_clear(xfer, sizeof(xfer)); + spi_message_init(&m); + xfer[0].tx_buf = tx_buf; + xfer[0].len = spi_dev->addr_bus_width + 1; + spi_message_add_tail(&xfer[0], &m); + + xfer[1].rx_buf = buf; + xfer[1].len = count; + spi_message_add_tail(&xfer[1], &m); + + ret = spi_sync(spi_dev->spi_device, &m); + if (ret) { + SPI_DEV_ERROR("transfer_read failed, reg addr:0x%x, len:%lu, ret:%d.\n", + regaddr, count, ret); + return -EIO; + } + return 0; +} + +static int transfer_write(struct spi_dev_info *spi_dev, u8 *buf, uint32_t regaddr, size_t count) +{ + int i, ret; + u8 tx_buf[TRANSFER_WRITE_BUFF]; + struct spi_message m; + struct spi_transfer xfer ; + + i = 0; + mem_clear(tx_buf, sizeof(tx_buf)); + tx_buf[i++] = OP_WRITE; + switch (spi_dev->addr_bus_width) { + case WIDTH_4Byte: + tx_buf[i++] = (regaddr >> 24) & 0xFF; + tx_buf[i++] = (regaddr >> 16) & 0xFF; + tx_buf[i++] = (regaddr >> 8) & 0xFF; + tx_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_2Byte: + tx_buf[i++] = (regaddr >> 8) & 0xFF; + tx_buf[i++] = regaddr & 0xFF; + break; + case WIDTH_1Byte: + tx_buf[i++] = regaddr & 0xFF; + break; + default: + SPI_DEV_ERROR("Only support 1,2,4 Byte Width, but set width = %u\n", + spi_dev->addr_bus_width); + return -EINVAL; + } + + memcpy(tx_buf + i, buf, count); + + mem_clear(&xfer, sizeof(xfer)); + spi_message_init(&m); + xfer.tx_buf = tx_buf; + xfer.len = count + i; + spi_message_add_tail(&xfer, &m); + + ret = spi_sync(spi_dev->spi_device, &m); + if (ret) { + SPI_DEV_ERROR("transfer_write failed, reg addr:0x%x, len:%lu, ret:%d.\n", + regaddr, count, ret); + return -EIO; + } + return 0; +} + +static long spi_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int spi_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct spi_dev_info *spi_dev; + + if (minor >= MAX_SPI_DEV_NUM) { + SPI_DEV_ERROR("minor out of range, minor = %d.\n", minor); + return -ENODEV; + } + + spi_dev = spi_dev_arry[minor]; + if (spi_dev == NULL) { + SPI_DEV_ERROR("spi_dev is NULL, open failed, minor = %d\n", minor); + return -ENODEV; + } + + file->private_data = spi_dev; + + return 0; +} + +static int spi_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static int device_read(struct spi_dev_info *spi_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u8 val[MAX_RW_LEN]; + u32 data_width, rd_len, per_len, tmp; + u32 max_per_len; + + data_width = spi_dev->data_bus_width; + + if (offset % data_width) { + SPI_DEV_ERROR("data bus width:%d, offset:0x%x, read size %lu invalid.\n", + data_width, offset, count); + return -EINVAL; + } + + max_per_len = spi_dev->per_rd_len; + tmp = (data_width - 1) & count; + rd_len = (tmp == 0) ? count : count + data_width - tmp; + per_len = (rd_len > max_per_len) ? (max_per_len) : (rd_len); + + mem_clear(val, sizeof(val)); + for (i = 0; i < rd_len; i += per_len) { + ret = transfer_read(spi_dev, val + i, offset + i, per_len); + if (ret < 0) { + SPI_DEV_ERROR("read error.read offset = %u\n", (offset + i)); + return -EFAULT; + } + } + + if (data_width == WIDTH_1Byte) { + memcpy(buf, val, count); + } else { + for (i = 0; i < count; i += data_width) { + for (j = 0; (j < data_width) && (i + j < count); j++) { + buf[i + j] = val[i + data_width - j - 1]; + } + } + } + + return 0; +} + +static int device_write(struct spi_dev_info *spi_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, j, ret; + u32 data_width; + u8 val[MAX_RW_LEN]; + u32 wr_len, per_len, tmp; + u32 max_per_len; + + data_width = spi_dev->data_bus_width; + + if (offset % data_width) { + SPI_DEV_ERROR("data bus width:%d, offset:0x%x, read size %lu invalid.\n", + data_width, offset, count); + return -EINVAL; + } + mem_clear(val, sizeof(val)); + + if (data_width == WIDTH_1Byte) { + memcpy(val, buf, count); + } else { + for (i = 0; i < count; i += data_width) { + for (j = 0; (j < data_width) && (i + j < count); j++) { + val[i + data_width - j - 1] = buf[i + j]; + } + } + } + + max_per_len = spi_dev->per_wr_len; + tmp = (data_width - 1) & count; + wr_len = (tmp == 0) ? count : count + data_width - tmp; + per_len = (wr_len > max_per_len) ? (max_per_len) : (wr_len); + + for (i = 0; i < wr_len; i += per_len) { + ret = transfer_write(spi_dev, val + i, offset + i, per_len); + if (ret < 0) { + SPI_DEV_ERROR("write error.offset = %u\n", (offset + i)); + return -EFAULT; + } + } + return 0; +} + +static ssize_t spi_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + u8 val[MAX_RW_LEN]; + int ret; + struct spi_dev_info *spi_dev; + + if (count <= 0 || count > sizeof(val)) { + SPI_DEV_ERROR("read conut %lu , beyond max:%lu.\n", count, sizeof(val)); + return -EINVAL; + } + + spi_dev = file->private_data; + if (spi_dev == NULL) { + SPI_DEV_ERROR("can't get read private_data .\n"); + return -EINVAL; + } + + ret = device_read(spi_dev, (uint32_t)*offset, val, count); + if (ret < 0) { + SPI_DEV_ERROR("spi dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + spi_dev->name, (uint32_t)*offset, count); + return -EINVAL; + } + + if (copy_to_user(buf, val, count)) { + SPI_DEV_ERROR("copy_to_user error \n"); + return -EFAULT; + } else{ + *offset += count; + } + + return count; +} + +static ssize_t spi_dev_write(struct file *file, const char __user *buf, + size_t count, loff_t *offset) +{ + u8 val[MAX_RW_LEN]; + int ret; + struct spi_dev_info *spi_dev; + + if (count <= 0 || count > sizeof(val)) { + SPI_DEV_ERROR("write conut %lu, beyond max val:%lu.\n", count, sizeof(val)); + return -EINVAL; + } + + spi_dev = file->private_data; + if (spi_dev == NULL) { + SPI_DEV_ERROR("get write private_data error.\n"); + return -EINVAL; + } + + mem_clear(val, sizeof(val)); + if (copy_from_user(val, buf, count)) { + SPI_DEV_ERROR("copy_from_user error.\n"); + return -EFAULT; + } + + ret = device_write(spi_dev, (uint32_t)*offset, val, count); + if (ret < 0) { + SPI_DEV_ERROR("spi dev write failed, dev name:%s, offset:0x%llx, len:%lu.\n", + spi_dev->name, *offset, count); + return -EINVAL; + } + + *offset += count; + return count; +} + +static loff_t spi_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + SPI_DEV_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (file->f_pos + offset < 0) { + SPI_DEV_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld.\n", + file->f_pos, offset); + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + SPI_DEV_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static const struct file_operations spi_dev_fops = { + .owner = THIS_MODULE, + .llseek = spi_dev_llseek, + .read = spi_dev_read, + .write = spi_dev_write, + .unlocked_ioctl = spi_dev_ioctl, + .open = spi_dev_open, + .release = spi_dev_release, +}; + +static struct spi_dev_info * dev_match(const char *path) +{ + struct spi_dev_info * spi_dev; + char dev_name[MAX_NAME_SIZE]; + int i; + for (i = 0; i < MAX_SPI_DEV_NUM; i++) { + if (spi_dev_arry[ i ] == NULL) { + continue; + } + spi_dev = spi_dev_arry[ i ]; + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", spi_dev->name); + if (!strcmp(path, dev_name)) { + SPI_DEV_DEBUG("get dev_name = %s, minor = %d\n", dev_name, i); + return spi_dev; + } + } + + return NULL; +} + +int spi_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct spi_dev_info *spi_dev = NULL; + int ret; + + if(path == NULL){ + SPI_DEV_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + SPI_DEV_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > MAX_RW_LEN) { + SPI_DEV_ERROR("read conut %lu, beyond max:%d.\n", count, MAX_RW_LEN); + return -EINVAL; + } + + spi_dev = dev_match(path); + if (spi_dev == NULL) { + SPI_DEV_ERROR("spi_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_read(spi_dev, offset, buf, count); + if (ret < 0) { + SPI_DEV_ERROR("spi dev read failed, dev name:%s, offset:0x%x, len:%lu.\n", + spi_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(spi_device_func_read); + +int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct spi_dev_info *spi_dev = NULL; + int ret; + + if(path == NULL){ + SPI_DEV_ERROR("path NULL"); + return -EINVAL; + } + + if(buf == NULL){ + SPI_DEV_ERROR("buf NULL"); + return -EINVAL; + } + + if (count > MAX_RW_LEN) { + SPI_DEV_ERROR("write conut %lu, beyond max:%d.\n", count, MAX_RW_LEN); + return -EINVAL; + } + + spi_dev = dev_match(path); + if (spi_dev == NULL) { + SPI_DEV_ERROR("i2c_dev match failed. dev path = %s", path); + return -EINVAL; + } + + ret = device_write (spi_dev, offset, buf, count); + if (ret < 0) { + SPI_DEV_ERROR("i2c dev write failed, dev name:%s, offset:0x%x, len:%lu.\n", + spi_dev->name, offset, count); + return -EINVAL; + } + + return count; +} +EXPORT_SYMBOL(spi_device_func_write); + +static int spi_dev_probe(struct spi_device *spi) +{ + int ret; + struct spi_dev_info *spi_dev; + struct miscdevice *misc; + spi_dev_device_t *spi_dev_device; + + spi_dev = devm_kzalloc(&spi->dev, sizeof(struct spi_dev_info), GFP_KERNEL); + if (!spi_dev) { + dev_err(&spi->dev, "devm_kzalloc error. \n"); + return -ENOMEM; + } + + spi_set_drvdata(spi, spi_dev); + spi_dev->spi_device = spi; + + if (spi->dev.of_node) { + + ret = 0; + ret += of_property_read_string(spi->dev.of_node, "spi_dev_name", &spi_dev->name); + ret += of_property_read_u32(spi->dev.of_node, "data_bus_width", &spi_dev->data_bus_width); + ret += of_property_read_u32(spi->dev.of_node, "addr_bus_width", &spi_dev->addr_bus_width); + ret += of_property_read_u32(spi->dev.of_node, "per_rd_len", &spi_dev->per_rd_len); + ret += of_property_read_u32(spi->dev.of_node, "per_wr_len", &spi_dev->per_wr_len); + if (ret != 0) { + dev_err(&spi->dev, "dts config error.ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (spi->dev.platform_data == NULL) { + dev_err(&spi->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + spi_dev_device = spi->dev.platform_data; + spi_dev->name = spi_dev_device->spi_dev_name; + spi_dev->data_bus_width = spi_dev_device->data_bus_width; + spi_dev->addr_bus_width = spi_dev_device->addr_bus_width; + spi_dev->per_rd_len = spi_dev_device->per_rd_len; + spi_dev->per_wr_len = spi_dev_device->per_wr_len; + } + + if ((spi_dev->per_rd_len & (spi_dev->data_bus_width - 1)) + || (spi_dev->per_wr_len & (spi_dev->data_bus_width - 1))) { + dev_err(&spi->dev, "Invalid config per_rd_len [%u] per_wr_len [%u] data bus_width [%u], addr bus width [%u].\n", + spi_dev->per_rd_len, spi_dev->per_wr_len, spi_dev->data_bus_width, spi_dev->addr_bus_width); + return -ENXIO; + } + + misc = &spi_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = spi_dev->name; + misc->fops = &spi_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&spi->dev, "register %s faild.\n", misc->name); + return -ENXIO; + } + + if (misc->minor >= MAX_SPI_DEV_NUM) { + dev_err(&spi->dev, "minor number beyond the limit! is %d.\n", misc->minor); + misc_deregister(misc); + return -ENXIO; + } + spi_dev_arry[misc->minor] = spi_dev; + + dev_info(&spi->dev, "register %u data_bus_width %u addr_bus_witdh device %s with %u per_rd_len %u per_wr_len success.\n", + spi_dev->data_bus_width, spi_dev->addr_bus_width, spi_dev->name, spi_dev->per_rd_len, spi_dev->per_wr_len); + + return 0; +} + +static int spi_dev_remove(struct spi_device *spi) +{ + int i; + + for (i = 0; i < MAX_SPI_DEV_NUM; i++) { + if (spi_dev_arry[i] != NULL) { + misc_deregister(&spi_dev_arry[i]->misc); + spi_dev_arry[i] = NULL; + } + } + return 0; +} + +static const struct of_device_id spi_dev_of_match[] = { + { .compatible = "wb-spi-dev" }, + { }, +}; + +MODULE_DEVICE_TABLE(of, spi_dev_of_match); + +static struct spi_driver spi_dev_driver = { + .driver = { + .name = "wb-spi-dev", + .of_match_table = of_match_ptr(spi_dev_of_match), + }, + .probe = spi_dev_probe, + .remove = spi_dev_remove, +}; + +module_spi_driver(spi_dev_driver); + +MODULE_DESCRIPTION("spi dev driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.h new file mode 100644 index 000000000000..6afc0145638d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_dev.h @@ -0,0 +1,16 @@ +#ifndef __WB_SPI_DEV_H__ +#define __WB_SPI_DEV_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define SPI_DEV_NAME_MAX_LEN (64) + +typedef struct spi_dev_device_s { + char spi_dev_name[SPI_DEV_NAME_MAX_LEN]; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t per_rd_len; + uint32_t per_wr_len; +} spi_dev_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio.c new file mode 100644 index 000000000000..16408f067be1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio.c @@ -0,0 +1,477 @@ +/* + * SPI master driver using generic bitbanged GPIO + * + * Copyright (C) 2006,2008 David Brownell + * Copyright (C) 2017 Linus Walleij + * + * 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. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * This bitbanging SPI master driver should help make systems usable + * when a native hardware SPI engine is not available, perhaps because + * its driver isn't yet working or because the I/O pins it requires + * are used for other purposes. + * + * platform_device->driver_data ... points to spi_gpio + * + * spi->controller_state ... reserved for bitbang framework code + * spi->controller_data ... holds chipselect GPIO + * + * spi->master->dev.driver_data ... points to spi_gpio->bitbang + */ + +struct spi_gpio { + struct spi_bitbang bitbang; + struct spi_gpio_platform_data pdata; + struct platform_device *pdev; + struct gpio_desc *sck; + struct gpio_desc *miso; + struct gpio_desc *mosi; + struct gpio_desc **cs_gpios; + bool has_cs; +}; + +/*----------------------------------------------------------------------*/ + +/* + * Because the overhead of going through four GPIO procedure calls + * per transferred bit can make performance a problem, this code + * is set up so that you can use it in either of two ways: + * + * - The slow generic way: set up platform_data to hold the GPIO + * numbers used for MISO/MOSI/SCK, and issue procedure calls for + * each of them. This driver can handle several such busses. + * + * - The quicker inlined way: only helps with platform GPIO code + * that inlines operations for constant GPIOs. This can give + * you tight (fast!) inner loops, but each such bus needs a + * new driver. You'll define a new C file, with Makefile and + * Kconfig support; the C code can be a total of six lines: + * + * #define DRIVER_NAME "myboard_spi2" + * #define SPI_MISO_GPIO 119 + * #define SPI_MOSI_GPIO 120 + * #define SPI_SCK_GPIO 121 + * #define SPI_N_CHIPSEL 4 + * #include "spi-gpio.c" + */ + +#ifndef DRIVER_NAME +#define DRIVER_NAME "wb_spi_gpio" + +#define GENERIC_BITBANG /* vs tight inlines */ + +#endif + +/*----------------------------------------------------------------------*/ + +static inline struct spi_gpio *__pure +spi_to_spi_gpio(const struct spi_device *spi) +{ + const struct spi_bitbang *bang; + struct spi_gpio *spi_gpio; + + bang = spi_master_get_devdata(spi->master); + spi_gpio = container_of(bang, struct spi_gpio, bitbang); + return spi_gpio; +} + +static inline struct spi_gpio_platform_data *__pure +spi_to_pdata(const struct spi_device *spi) +{ + return &spi_to_spi_gpio(spi)->pdata; +} + +/* These helpers are in turn called by the bitbang inlines */ +static inline void setsck(const struct spi_device *spi, int is_on) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + gpiod_set_value_cansleep(spi_gpio->sck, is_on); +} + +static inline void setmosi(const struct spi_device *spi, int is_on) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + gpiod_set_value_cansleep(spi_gpio->mosi, is_on); +} + +static inline int getmiso(const struct spi_device *spi) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + if (spi->mode & SPI_3WIRE) + return !!gpiod_get_value_cansleep(spi_gpio->mosi); + else + return !!gpiod_get_value_cansleep(spi_gpio->miso); +} + +/* + * NOTE: this clocks "as fast as we can". It "should" be a function of the + * requested device clock. Software overhead means we usually have trouble + * reaching even one Mbit/sec (except when we can inline bitops), so for now + * we'll just assume we never need additional per-bit slowdowns. + */ +#define spidelay(nsecs) do {} while (0) + +#include "spi-bitbang-txrx.h" + +/* + * These functions can leverage inline expansion of GPIO calls to shrink + * costs for a txrx bit, often by factors of around ten (by instruction + * count). That is particularly visible for larger word sizes, but helps + * even with default 8-bit words. + * + * REVISIT overheads calling these functions for each word also have + * significant performance costs. Having txrx_bufs() calls that inline + * the txrx_word() logic would help performance, e.g. on larger blocks + * used with flash storage or MMC/SD. There should also be ways to make + * GCC be less stupid about reloading registers inside the I/O loops, + * even without inlined GPIO calls; __attribute__((hot)) on GCC 4.3? + */ + +static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); +} + +static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); +} + +/* + * These functions do not call setmosi or getmiso if respective flag + * (SPI_MASTER_NO_RX or SPI_MASTER_NO_TX) is set, so they are safe to + * call when such pin is not present or defined in the controller. + * A separate set of callbacks is defined to get highest possible + * speed in the generic case (when both MISO and MOSI lines are + * available), as optimiser will remove the checks when argument is + * constant. + */ + +static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + flags = spi->master->flags; + return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + flags = spi->master->flags; + return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + flags = spi->master->flags; + return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); +} + +static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + flags = spi->master->flags; + return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); +} + +/*----------------------------------------------------------------------*/ + +static void spi_gpio_chipselect(struct spi_device *spi, int is_active) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + /* set initial clock line level */ + if (is_active) + gpiod_set_value_cansleep(spi_gpio->sck, spi->mode & SPI_CPOL); + + /* Drive chip select line, if we have one */ + if (spi_gpio->has_cs) { + struct gpio_desc *cs = spi_gpio->cs_gpios[spi->chip_select]; + + /* SPI chip selects are normally active-low */ + gpiod_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); + } +} + +static int spi_gpio_setup(struct spi_device *spi) +{ + struct gpio_desc *cs; + int status = 0; + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + /* + * The CS GPIOs have already been + * initialized from the descriptor lookup. + */ + cs = spi_gpio->cs_gpios[spi->chip_select]; + if (!spi->controller_state && cs) + status = gpiod_direction_output(cs, + !(spi->mode & SPI_CS_HIGH)); + + if (!status) + status = spi_bitbang_setup(spi); + + return status; +} + +static int spi_gpio_set_direction(struct spi_device *spi, bool output) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + if (output) + return gpiod_direction_output(spi_gpio->mosi, 1); + else + return gpiod_direction_input(spi_gpio->mosi); +} + +static void spi_gpio_cleanup(struct spi_device *spi) +{ + spi_bitbang_cleanup(spi); +} + +/* + * It can be convenient to use this driver with pins that have alternate + * functions associated with a "native" SPI controller if a driver for that + * controller is not available, or is missing important functionality. + * + * On platforms which can do so, configure MISO with a weak pullup unless + * there's an external pullup on that signal. That saves power by avoiding + * floating signals. (A weak pulldown would save power too, but many + * drivers expect to see all-ones data as the no slave "response".) + */ +static int spi_gpio_request(struct device *dev, + struct spi_gpio *spi_gpio, + unsigned int num_chipselects, + u16 *mflags) +{ + int i; + + spi_gpio->mosi = devm_gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW); + if (IS_ERR(spi_gpio->mosi)) + return PTR_ERR(spi_gpio->mosi); + if (!spi_gpio->mosi) + /* HW configuration without MOSI pin */ + *mflags |= SPI_MASTER_NO_TX; + + spi_gpio->miso = devm_gpiod_get_optional(dev, "miso", GPIOD_IN); + if (IS_ERR(spi_gpio->miso)) + return PTR_ERR(spi_gpio->miso); + /* + * No setting SPI_MASTER_NO_RX here - if there is only a MOSI + * pin connected the host can still do RX by changing the + * direction of the line. + */ + + spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW); + if (IS_ERR(spi_gpio->sck)) + return PTR_ERR(spi_gpio->sck); + + for (i = 0; i < num_chipselects; i++) { + spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", + i, GPIOD_OUT_HIGH); + if (IS_ERR(spi_gpio->cs_gpios[i])) + return PTR_ERR(spi_gpio->cs_gpios[i]); + } + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id spi_gpio_dt_ids[] = { + { .compatible = "wb-spi-gpio" }, + {} +}; +MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids); + +static int spi_gpio_probe_dt(struct platform_device *pdev) +{ + int ret; + u32 tmp; + struct spi_gpio_platform_data *pdata; + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *of_id = + of_match_device(spi_gpio_dt_ids, &pdev->dev); + + if (!of_id) + return 0; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + ret = of_property_read_u32(np, "num-chipselects", &tmp); + if (ret < 0) { + dev_err(&pdev->dev, "num-chipselects property not found\n"); + goto error_free; + } + + pdata->num_chipselect = tmp; + pdev->dev.platform_data = pdata; + + return 1; + +error_free: + devm_kfree(&pdev->dev, pdata); + return ret; +} +#else +static inline int spi_gpio_probe_dt(struct platform_device *pdev) +{ + return 0; +} +#endif + +static int spi_gpio_probe(struct platform_device *pdev) +{ + int status; + struct spi_master *master; + struct spi_gpio *spi_gpio; + struct spi_gpio_platform_data *pdata; + u16 master_flags = 0; + bool use_of = 0; + + status = spi_gpio_probe_dt(pdev); + if (status < 0) + return status; + if (status > 0) + use_of = 1; + + pdata = dev_get_platdata(&pdev->dev); +#ifdef GENERIC_BITBANG + if (!pdata || (!use_of && !pdata->num_chipselect)) + return -ENODEV; +#endif + + master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio)); + if (!master) + return -ENOMEM; + + spi_gpio = spi_master_get_devdata(master); + + spi_gpio->cs_gpios = devm_kcalloc(&pdev->dev, + pdata->num_chipselect, + sizeof(*spi_gpio->cs_gpios), + GFP_KERNEL); + if (!spi_gpio->cs_gpios) + return -ENOMEM; + + platform_set_drvdata(pdev, spi_gpio); + + /* Determine if we have chip selects connected */ + spi_gpio->has_cs = !!pdata->num_chipselect; + + spi_gpio->pdev = pdev; + if (pdata) + spi_gpio->pdata = *pdata; + + status = spi_gpio_request(&pdev->dev, spi_gpio, + pdata->num_chipselect, &master_flags); + if (status) + return status; + + master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); + master->mode_bits = SPI_3WIRE | SPI_CPHA | SPI_CPOL | SPI_CS_HIGH; + master->flags = master_flags; + master->bus_num = pdev->id; + /* The master needs to think there is a chipselect even if not connected */ + master->num_chipselect = spi_gpio->has_cs ? pdata->num_chipselect : 1; + master->setup = spi_gpio_setup; + master->cleanup = spi_gpio_cleanup; + + if (pdev->dev.of_node) { + master->dev.of_node = pdev->dev.of_node; + } + + spi_gpio->bitbang.master = master; + spi_gpio->bitbang.chipselect = spi_gpio_chipselect; + spi_gpio->bitbang.set_line_direction = spi_gpio_set_direction; + + if ((master_flags & SPI_MASTER_NO_TX) == 0) { + spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; + spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; + spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; + spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3; + } else { + spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0; + spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1; + spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2; + spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3; + } + spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer; + + status = spi_bitbang_start(&spi_gpio->bitbang); + if (status) + spi_master_put(master); + + return status; +} + +static int spi_gpio_remove(struct platform_device *pdev) +{ + struct spi_gpio *spi_gpio; + struct spi_gpio_platform_data *pdata; + + spi_gpio = platform_get_drvdata(pdev); + pdata = dev_get_platdata(&pdev->dev); + + /* stop() unregisters child devices too */ + spi_bitbang_stop(&spi_gpio->bitbang); + + spi_master_put(spi_gpio->bitbang.master); + + return 0; +} + +MODULE_ALIAS("platform:" DRIVER_NAME); + +static struct platform_driver spi_gpio_driver = { + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(spi_gpio_dt_ids), + }, + .probe = spi_gpio_probe, + .remove = spi_gpio_remove, +}; +module_platform_driver(spi_gpio_driver); + +MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO "); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio_device.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio_device.c new file mode 100644 index 000000000000..e70c97b1af9d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_gpio_device.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define DEFAULT_GPIO_SCK (67) +#define DEFAULT_GPIO_MISO (32) +#define DEFAULT_GPIO_MOSI (65) +#define DEFAULT_GPIO_CS (6) +#define DEFAULT_SPI_BUS (0) + +static int sck = DEFAULT_GPIO_SCK; +module_param(sck, int, S_IRUGO | S_IWUSR); + +static int miso = DEFAULT_GPIO_MISO; +module_param(miso, int, S_IRUGO | S_IWUSR); + +static int mosi = DEFAULT_GPIO_MOSI; +module_param(mosi, int, S_IRUGO | S_IWUSR); + +static int cs = DEFAULT_GPIO_CS; +module_param(cs, int, S_IRUGO | S_IWUSR); + +static int bus = DEFAULT_SPI_BUS; +module_param(bus, int, S_IRUGO | S_IWUSR); + +static int g_wb_spi_gpio_device_debug = 0; +static int g_wb_spi_gpio_device_error = 0; + +module_param(g_wb_spi_gpio_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_gpio_device_error, int, S_IRUGO | S_IWUSR); + +static char gpiod_lookup_table_devid[64]; + +#define WB_SPI_GPIO_DEVICE_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_gpio_device_debug) { \ + printk(KERN_INFO "[WB_SPI_GPIO_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_SPI_GPIO_DEVICE_ERROR(fmt, args...) do { \ + if (g_wb_spi_gpio_device_error) { \ + printk(KERN_ERR "[WB_SPI_GPIO_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct gpiod_lookup_table wb_spi_gpio_table = { + .table = { + GPIO_LOOKUP("wb_gpio_d1500", DEFAULT_GPIO_SCK, + "sck", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("wb_gpio_d1500", DEFAULT_GPIO_MOSI, + "mosi", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("wb_gpio_d1500", DEFAULT_GPIO_MISO, + "miso", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("wb_gpio_d1500", DEFAULT_GPIO_CS, + "cs", GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static struct spi_gpio_platform_data spi_pdata = { + .num_chipselect = 1, +}; + +static void spi_gpio_release(struct device *dev) +{ + return; +} + +static struct platform_device wb_spi_gpio_device = { + .name = "wb_spi_gpio", + .num_resources = 0, + .id = -1, + + .dev = { + .platform_data = &spi_pdata, + .release = spi_gpio_release, + } +}; + +static void wb_spi_gpio_table_devid_name_set(void) { + int size; + + size = sizeof(gpiod_lookup_table_devid); + wb_spi_gpio_device.id = bus; + + mem_clear(gpiod_lookup_table_devid, size); + switch (bus) { + case PLATFORM_DEVID_NONE: + snprintf(gpiod_lookup_table_devid, size, "%s", wb_spi_gpio_device.name); + break; + case PLATFORM_DEVID_AUTO: + snprintf(gpiod_lookup_table_devid, size, "%s.%d.auto", wb_spi_gpio_device.name, bus); + break; + default: + snprintf(gpiod_lookup_table_devid, size, "%s.%d", wb_spi_gpio_device.name, bus); + break; + } + + wb_spi_gpio_table.dev_id = gpiod_lookup_table_devid; + return ; +} +static int __init wb_spi_gpio_device_init(void) +{ + int err; + struct gpiod_lookup *p; + + WB_SPI_GPIO_DEVICE_VERBOSE("enter!\n"); + wb_spi_gpio_table.table[0].chip_hwnum = sck; + wb_spi_gpio_table.table[1].chip_hwnum = mosi; + wb_spi_gpio_table.table[2].chip_hwnum = miso; + wb_spi_gpio_table.table[3].chip_hwnum = cs; + wb_spi_gpio_table_devid_name_set(); + WB_SPI_GPIO_DEVICE_VERBOSE("spi gpi device table bus[%d] dev id[%s]\n", bus, wb_spi_gpio_table.dev_id); + for (p = &wb_spi_gpio_table.table[0]; p->key; p++) { + WB_SPI_GPIO_DEVICE_VERBOSE("con_id:%s gpio:%d\n", p->con_id, p->chip_hwnum); + } + + gpiod_add_lookup_table(&wb_spi_gpio_table); + err = platform_device_register(&wb_spi_gpio_device); + if (err < 0) { + printk(KERN_ERR "register spi gpio device fail(%d). \n", err); + gpiod_remove_lookup_table(&wb_spi_gpio_table); + return -1; + } + + return 0; +} + +static void __exit wb_spi_gpio_device_exit(void) +{ + WB_SPI_GPIO_DEVICE_VERBOSE("enter!\n"); + platform_device_unregister(&wb_spi_gpio_device); + gpiod_remove_lookup_table(&wb_spi_gpio_table); +} + +module_init(wb_spi_gpio_device_init); +module_exit(wb_spi_gpio_device_exit); +MODULE_DESCRIPTION("SPI GPIO Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_nor_device.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_nor_device.c new file mode 100644 index 000000000000..4196601f717b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_nor_device.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include + +/* The SPI Bus number that the device is mounted on can be specified manually when this module is loaded */ +#define DEFAULT_SPI_BUS_NUM (0) +#define DEFAULT_SPI_CS_NUM (0) +#define DEFAULT_SPI_HZ (100000) + +int g_wb_spi_nor_dev_debug = 0; +int g_wb_spi_nor_dev_error = 0; +int spi_bus_num = DEFAULT_SPI_BUS_NUM; + +module_param(g_wb_spi_nor_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_nor_dev_error, int, S_IRUGO | S_IWUSR); +module_param(spi_bus_num, int, S_IRUGO | S_IWUSR); + +#define SPI_NOR_DEV_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_nor_dev_debug) { \ + printk(KERN_INFO "[SPI_NOR_DEV][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SPI_NOR_DEV_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_spi_nor_dev_error) { \ + printk(KERN_ERR "[SPI_NOR_DEV][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct spi_board_info spi_nor_device_info __initdata= { + .modalias = "mx25l6405d", + .bus_num = DEFAULT_SPI_BUS_NUM, + .chip_select = DEFAULT_SPI_CS_NUM, + .max_speed_hz = 10 * 1000 * 1000, +}; + +static struct spi_device *g_spi_device; + +static int __init wb_spi_nor_dev_init(void) +{ + struct spi_master *master; + + SPI_NOR_DEV_DEBUG_VERBOSE("Enter.\n"); + + spi_nor_device_info.bus_num = spi_bus_num; + master = spi_busnum_to_master(spi_nor_device_info.bus_num); /* Get the controller according to the SPI Bus number */ + if (!master) { + SPI_NOR_DEV_DEBUG_ERROR("get bus_num %u spi master failed.\n", + spi_nor_device_info.bus_num); + return -EINVAL; + } + + g_spi_device = spi_new_device(master, &spi_nor_device_info); + put_device(&master->dev); + if (!g_spi_device) { + SPI_NOR_DEV_DEBUG_ERROR("register spi new device failed.\n"); + return -EPERM; + } + + if (g_wb_spi_nor_dev_debug) { + dev_info(&g_spi_device->dev, "register %u bus_num spi nor device success\n", + spi_nor_device_info.bus_num); + } + + return 0; +} + +static void __exit wb_spi_nor_dev_exit(void) +{ + spi_unregister_device(g_spi_device); + + if (g_wb_spi_nor_dev_debug) { + dev_info(&g_spi_device->dev, "unregister spi nor device success\n"); + } + + return; +} + +module_init(wb_spi_nor_dev_init); +module_exit(wb_spi_nor_dev_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("create spi nor device"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.c new file mode 100644 index 000000000000..a709427c5b73 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.c @@ -0,0 +1,1025 @@ +/* + * wb_spi_ocores.c + * ko to create ocores spi adapter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_spi_ocores.h" + +#define SPIOC_WAIT_SCH (5) +#define SPIOC_CONF (0x00) +#define SPIOC_LSBF BIT(0) /* 0:MSB 1:LSB */ +#define SPIOC_IDLE_LOW BIT(1) +#define SPIOC_INTREN BIT(2) /* 0:enable 1:disabel */ +#define SPIOC_DIV_MASK (0xf0) +#define SPIOC_MAX_DIV (0x0E) +#define SPIOC_DIV(div) (((div) & 0x0f) << 4) + +#define SPIOC_STS (0x01) +#define SPIOC_INTR_STS BIT(0) +#define SPIOC_BUSY_STS BIT(1) +#define SPIOC_RXNUM_SHIFT (4) +#define SPIOC_RXNUM_MASK (0xf << SPIOC_RXNUM_SHIFT) +/* Just for read */ +#define SPIOC_RXNUM(reg) (((reg) & SPIOC_RXNUM_MASK) >> SPIOC_RXNUM_SHIFT ) + +#define SPIOC_TXTOT_NUM (0x02) +#define SPIOC_TXNUM(reg) ((reg) & 0x0f) +#define SPIOC_TOTNUM(reg) (((reg) & 0x0f) << 4) + +#define SPIOC_TXCTL (0x03) +#define SPIOC_CSLV BIT(0) /* 0:Deassert SPICS 1:Laeve SPICS */ +#define SPIOC_TRSTART BIT(1) +#define SPIOC_CSID_SHIFT (5) +#define SPIOC_CSID_MASK (0x7 << SPIOC_CSID_SHIFT) +/* Just for write */ +#define SPIOC_CSID(id) (((id) << SPIOC_CSID_SHIFT) & SPIOC_CSID_MASK) + +/* Just single byte */ +#define SPIOC_RX(i) ((0x4) + i) +#define SPIOC_TX(i) ((0x4) + i) + +#define SPIOC_MAX_LEN ((unsigned int)8) +#define SPIOC_TXRX_MAX_LEN ((unsigned int)7) + +#define MODEBITS (SPI_CPHA |SPI_CPOL | SPI_LSB_FIRST |SPI_CS_HIGH) + +#define REG_IO_WIDTH_1 (1) +#define REG_IO_WIDTH_2 (2) +#define REG_IO_WIDTH_4 (4) + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) + +int g_spi_oc_debug = 0; +int g_spi_oc_error = 0; + +module_param(g_spi_oc_debug, int, S_IRUGO | S_IWUSR); +module_param(g_spi_oc_error, int, S_IRUGO | S_IWUSR); + +#define SPI_OC_VERBOSE(fmt, args...) do { \ + if (g_spi_oc_debug) { \ + printk(KERN_INFO "[OC_SPI_BUS][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SPI_OC_ERROR(fmt, args...) do { \ + if (g_spi_oc_error) { \ + printk(KERN_ERR "[OC_SPI_BUS][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct spioc { + /* bitbang has to be first */ + struct spi_bitbang bitbang; + int irq; + struct completion done; + unsigned int reamin_len; + unsigned int cur_pos; + unsigned int cur_len; + const u8 *txp; + u8 *rxp; + u8 chip_select; + void (*setreg)(struct spioc *spioc, int reg, u32 value); + u32 (*getreg)(struct spioc *spioc, int reg); + uint32_t bus_num; + const char *dev_name; + uint32_t reg_access_mode; + uint32_t base_addr; + uint32_t reg_shift; + uint32_t reg_io_width; + uint32_t num_chipselect; + uint32_t freq; + uint32_t big_endian; + struct device *dev; + int transfer_busy_flag; +}; + +extern int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); + +static int oc_spi_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + SPI_OC_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + SPI_OC_ERROR("kernel_read failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int oc_spi_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + SPI_OC_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + SPI_OC_ERROR("kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int oc_spi_reg_write(struct spioc *spioc, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (spioc->reg_access_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(spioc->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = oc_spi_file_write(spioc->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(spioc->dev_name, pos, val, size); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_write(spioc->dev_name, pos, val, size); + break; + default: + SPI_OC_ERROR("err func_mode, write failed.\n"); + return -EINVAL; + } + + return ret; +} + +static int oc_spi_reg_read(struct spioc *spioc, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + + switch (spioc->reg_access_mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_read(spioc->dev_name, pos, val, size); + break; + case FILE_MODE: + ret = oc_spi_file_read(spioc->dev_name, pos, val, size); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_read(spioc->dev_name, pos, val, size); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_read(spioc->dev_name, pos, val, size); + break; + default: + SPI_OC_ERROR("err func_mode, read failed.\n"); + return -EINVAL; + } + + return ret; +} + +static void oc_spi_setreg_8(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_1]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0Xff); + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_1); + return; +} + +static void oc_spi_setreg_16(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0Xff); + buf_tmp[1] = (value >> 8) & 0xff; + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_2); + return; +} + +static void oc_spi_setreg_32(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value & 0xff); + buf_tmp[1] = (value >> 8) & 0xff; + buf_tmp[2] = (value >> 16) & 0xff; + buf_tmp[3] = (value >> 24) & 0xff; + + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_4); + return; +} + +static void oc_spi_setreg_16be(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value >> 8) & 0xff; + buf_tmp[1] = (value & 0Xff); + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_2); + return; +} + +static void oc_spi_setreg_32be(struct spioc *spioc, int reg, u32 value) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + buf_tmp[0] = (value >> 24) & 0xff; + buf_tmp[1] = (value >> 16) & 0xff; + buf_tmp[2] = (value >> 8) & 0xff; + buf_tmp[3] = (value & 0xff); + oc_spi_reg_write(spioc, pos, buf_tmp, REG_IO_WIDTH_4); + return; +} + +static inline u32 oc_spi_getreg_8(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_1]; + u32 value, pos; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_1); + value = buf_tmp[0]; + + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + + return value; +} + +static inline u32 oc_spi_getreg_16(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 value, pos; + int i; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + mem_clear(buf_tmp, sizeof(buf_tmp)); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_2); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_2 ; i++) { + value |= buf_tmp[i] << (8 * i); + } + + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_spi_getreg_32(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 value, pos; + int i; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + mem_clear(buf_tmp, sizeof(buf_tmp)); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_4); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_4 ; i++) { + value |= buf_tmp[i] << (8 * i); + } + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_spi_getreg_16be(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_2]; + u32 value, pos; + int i; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_2); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_2 ; i++) { + value |= buf_tmp[i] << (8 * (REG_IO_WIDTH_2 -i - 1)); + } + + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + return value; +} + +static inline u32 oc_spi_getreg_32be(struct spioc *spioc, int reg) +{ + u8 buf_tmp[REG_IO_WIDTH_4]; + u32 value, pos; + int i; + + pos = spioc->base_addr + (reg << spioc->reg_shift); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + oc_spi_reg_read(spioc, pos, buf_tmp, REG_IO_WIDTH_4); + + value = 0; + for (i = 0; i < REG_IO_WIDTH_4 ; i++) { + value |= buf_tmp[i] << (8 * (REG_IO_WIDTH_4 -i - 1)); + } + + SPI_OC_VERBOSE("path:%s, access mode:%d, pos:0x%x, value0x%x.\n", + spioc->dev_name, spioc->reg_access_mode, pos, value); + return value; + +} + +static inline void oc_spi_setreg(struct spioc *spioc, int reg, u32 value) +{ + spioc->setreg(spioc, reg, value); + return; +} + +static inline u32 oc_spi_getreg(struct spioc *spioc, int reg) +{ + return spioc->getreg(spioc, reg); +} + +static int spioc_get_clkdiv(struct spioc *spioc, u32 speed) +{ + u32 rate, div; + + rate = spioc->freq; + SPI_OC_VERBOSE("clk get rate:%u, speed:%u\n", rate, speed); + /* fs = fw/((DIV+2)*2) */ + + if (speed > (rate / 4)) { + div = 0; + SPI_OC_VERBOSE("spi device speed[%u] more than a quarter of clk rate[%u].\n", + speed, rate); + return div; + } + div = (rate/(2 * speed)) - 2; + if (div > SPIOC_MAX_DIV) { + SPI_OC_ERROR("Unsupport spi device speed, div:%u.\n", div); + return -1; + } + SPI_OC_VERBOSE("DIV is:0x%x\n", div); + return div; +} + +static inline int spioc_wait_trans(struct spioc *spioc, const unsigned long timeout) +{ + unsigned long j; + unsigned int sch_time; + u8 reg; + + j = jiffies + timeout; + sch_time = SPIOC_WAIT_SCH; + while (1) { + reg = oc_spi_getreg(spioc, SPIOC_STS); + if (!(reg & SPIOC_BUSY_STS)) { + SPI_OC_VERBOSE("wait ok!\n"); + break; + } + + if (time_after(jiffies, j)) { + return -ETIMEDOUT; + } + + usleep_range(sch_time, sch_time + 1); + } + + return 0; +} + +static void spioc_chipselect(struct spi_device *spi, int is_active) +{ + struct spioc *spioc; + u8 tx_conf; + int ret; + + spioc = spi_master_get_devdata(spi->master); + spioc->transfer_busy_flag = 0; + ret = spioc_wait_trans(spioc, msecs_to_jiffies(100)); + if (ret < 0) { + SPI_OC_ERROR("spi transfer is busy, ret=%d.\n", ret); + spioc->transfer_busy_flag = 1; + return; + } + spioc->chip_select = spi->chip_select; + SPI_OC_VERBOSE("spioc_chipselect:%u, value:%d.\n", spioc->chip_select, is_active); + tx_conf = 0; + tx_conf |= SPIOC_CSID(spioc->chip_select); + if (is_active) { + tx_conf |= SPIOC_CSLV; + } + + SPI_OC_VERBOSE("tx_config:[0x%x]\n", tx_conf); + oc_spi_setreg(spioc, SPIOC_TXCTL, tx_conf); + return; +} + +static void spioc_copy_tx(struct spioc *spioc) +{ + const u8 *src; + int i; + + if (!spioc->txp) { + SPI_OC_ERROR("spioc->txp is NULL.\n"); + return; + } + + src = (u8 *)spioc->txp + spioc->cur_pos; + SPI_OC_VERBOSE("current tx len:0x%x, tx pos:[0x%x]\n", spioc->cur_len, spioc->cur_pos); + + for (i = 0; i < spioc->cur_len; i++) { + SPI_OC_VERBOSE("write %d, val:[0x%x]\n", i, src[i]); + oc_spi_setreg(spioc, SPIOC_TX(i), src[i]); + } +} + +static void spioc_copy_rx(struct spioc *spioc) +{ + u8 *dest; + int i; + + if (!spioc->rxp) { + SPI_OC_ERROR("spioc->rxp is NULL.\n"); + return; + } + + dest = (u8 *)spioc->rxp + spioc->cur_pos; + SPI_OC_VERBOSE("current rx len:0x%x, rx pos:[0x%x]\n", spioc->cur_len, spioc->cur_pos); + + for (i = 0; i < spioc->cur_len; i++) { + dest[i] = oc_spi_getreg(spioc, SPIOC_RX(i)); + SPI_OC_VERBOSE("read %d, val:[0x%x]\n", i, dest[i]); + } +} + +static int spioc_setup_transfer(struct spi_device *spi, struct spi_transfer *transfer) +{ + struct spioc *spioc; + u8 ctrl; + u32 hz; + int div; + + spioc = spi_master_get_devdata(spi->master); + ctrl = 0; + + if (spi->mode & SPI_LSB_FIRST) { + ctrl |= SPIOC_LSBF; + } + + if (!(spi->mode & SPI_CPOL)) { + ctrl |= SPIOC_IDLE_LOW; + } + + if (spioc->irq < 0) { + + ctrl |= SPIOC_INTREN; + } + + if (transfer != NULL) { + hz = transfer->speed_hz; + + if (hz == 0) { + hz = spi->max_speed_hz; + } + } else { + hz = spi->max_speed_hz; + } + + if (hz == 0) { + SPI_OC_ERROR("Unsupport zero speed.\n"); + return -EINVAL; + } + + div = spioc_get_clkdiv(spioc, hz); + if (div < 0) { + SPI_OC_ERROR("get div error, div:%d.\n", div); + return -EINVAL; + } + ctrl |= SPIOC_DIV(div); + + SPI_OC_VERBOSE("ctrl:[0x%x].\n", ctrl); + + oc_spi_setreg(spioc, SPIOC_CONF, ctrl); + return 0; +} + +static int spioc_spi_setup(struct spi_device *spi) +{ + struct spioc *spioc; + + if (!(spi->mode & SPI_CPHA)) { + SPI_OC_ERROR("Unsupport spi device mde:0x%x, SPI_CPHA must be 1.\n", spi->mode); + return -EINVAL; + } + + spioc = spi_master_get_devdata(spi->master); + if (spi->chip_select >= spioc->num_chipselect) { + SPI_OC_ERROR("Spi device chipselect:%u, more than max chipselect:%u.\n", + spi->chip_select, spioc->num_chipselect); + return -EINVAL; + } + SPI_OC_VERBOSE("Support spi device mode:0x%x, chip_select:%u.\n", + spi->mode, spi->chip_select); + return 0; +} + +static int spioc_transfer_start(struct spioc *spioc) +{ + u8 tx_conf; + int ret; + + tx_conf = oc_spi_getreg(spioc, SPIOC_TXCTL); + tx_conf |= SPIOC_TRSTART; + + SPI_OC_VERBOSE("tx_config:[0x%x]\n", tx_conf); + oc_spi_setreg(spioc, SPIOC_TXCTL, tx_conf); + + ret = spioc_wait_trans(spioc, msecs_to_jiffies(100)); + return ret; +} + +static int spioc_tx_start_one(struct spioc *spioc) +{ + unsigned int txlen; + u8 txreg; + int ret; + + if (!spioc->reamin_len) { + SPI_OC_VERBOSE("spioc txlen:[0x0]\n"); + return 0; + } + + spioc->cur_len = spioc->reamin_len > SPIOC_MAX_LEN ? SPIOC_MAX_LEN : spioc->reamin_len; + + txlen = spioc->cur_len; + spioc->reamin_len -= txlen; + SPI_OC_VERBOSE("txlen:[0x%x], tx len remain:[0x%x]\n", txlen, spioc->reamin_len); + + spioc_copy_tx(spioc); + + /* when we only send, txlen == totlen */ + txreg = SPIOC_TXNUM(txlen) | SPIOC_TOTNUM(txlen); + SPI_OC_VERBOSE("txreg:[0x%x]\n", txreg); + oc_spi_setreg(spioc, SPIOC_TXTOT_NUM, txreg); + + ret = spioc_transfer_start(spioc); + if (ret) { + SPI_OC_ERROR("spioc tx rx poll wait for transfer timeout.\n"); + return ret; + } + + if (spioc->reamin_len) { + spioc->cur_pos += txlen; + SPI_OC_VERBOSE("cur_txpos:[0x%x]\n", spioc->cur_pos); + } + + return 0; +} + +static int spioc_rx_start_one(struct spioc *spioc) +{ + unsigned int rxlen; + u8 txtnum; + int ret; + + if (!spioc->reamin_len) { + SPI_OC_VERBOSE("spioc reamin_len:[0x0]\n"); + return 0; + } + + spioc->cur_len = spioc->reamin_len > SPIOC_MAX_LEN ? SPIOC_MAX_LEN : spioc->reamin_len; + + rxlen = spioc->cur_len; + spioc->reamin_len -= rxlen; + SPI_OC_VERBOSE("rxlen:[0x%x], rx len remain:[0x%x]\n", rxlen, spioc->reamin_len); + + /* when we only receive, rxnum=totnum. txnum=0 */ + txtnum = SPIOC_TOTNUM(rxlen); + SPI_OC_VERBOSE("tx total reg:0x%x\n", txtnum); + oc_spi_setreg(spioc, SPIOC_TXTOT_NUM, txtnum); + + ret = spioc_transfer_start(spioc); + if (ret) { + SPI_OC_ERROR("spioc tx rx poll wait for transfer timeout.\n"); + return ret; + } + + spioc_copy_rx(spioc); + + if (spioc->reamin_len) { + spioc->cur_pos += rxlen; + SPI_OC_VERBOSE("cur_rxpos:[0x%x]\n", spioc->cur_pos); + } + + return 0; +} + +static int spioc_tx_rx_start_one(struct spioc *spioc) +{ + unsigned int txlen, total_len; + u8 txreg; + int ret; + + if (!spioc->reamin_len) { + SPI_OC_VERBOSE("spioc reamin_len:[0x0]\n"); + return 0; + } + + spioc->cur_len = spioc->reamin_len > SPIOC_TXRX_MAX_LEN ? SPIOC_TXRX_MAX_LEN : spioc->reamin_len; + + txlen = spioc->cur_len; + spioc->reamin_len -= txlen; + SPI_OC_VERBOSE("tx len:[0x%x], tx len remain:[0x%x]\n", txlen, spioc->reamin_len); + + spioc_copy_tx(spioc); + + total_len = 2 * txlen; /* total_len=txlen + rxlen; rxlen=txlen */ + txreg = SPIOC_TXNUM(txlen) | SPIOC_TOTNUM(total_len); + SPI_OC_VERBOSE("txreg:[0x%x]\n", txreg); + oc_spi_setreg(spioc, SPIOC_TXTOT_NUM, txreg); + + ret = spioc_transfer_start(spioc); + if (ret) { + SPI_OC_ERROR("spioc tx rx poll wait for transfer timeout.\n"); + return ret; + } + + spioc_copy_rx(spioc); + if (spioc->reamin_len) { + spioc->cur_pos += txlen; + SPI_OC_VERBOSE("cur_txrx pos:[0x%x]\n", spioc->cur_pos); + } + return 0; +} + +static int spioc_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) +{ + struct spioc *spioc; + int ret , len; + + if(!t->len || (!t->tx_buf && !t->rx_buf)) { + SPI_OC_ERROR("params error, tx_buf and rx_buf may both NULL, transfer len:0x%x.\n", + t->len); + return 0; + } + + spioc = spi_master_get_devdata(spi->master); + if (spioc->transfer_busy_flag) { + ret = -EBUSY; + goto err; + } + + spioc->txp = t->tx_buf; + spioc->rxp = t->rx_buf; + spioc->reamin_len = t->len; + spioc->cur_len = 0; + spioc->cur_pos = 0; + len = t->len; + ret = 0; + if (spioc->irq >= 0) { + /* use interrupt driven data transfer */ + if (t->tx_buf && t->rx_buf) { + spioc_tx_rx_start_one(spioc); + wait_for_completion(&spioc->done); + } else if (t->tx_buf) { + spioc_tx_start_one(spioc); + wait_for_completion(&spioc->done); + + } else { + spioc_rx_start_one(spioc); + wait_for_completion(&spioc->done); + } + } else { + if (t->tx_buf && t->rx_buf) { + SPI_OC_VERBOSE("start tx rx, len:0x%x\n", t->len); + while (spioc->reamin_len) { + ret = spioc_tx_rx_start_one(spioc); + if (ret) { + goto err; + } + } + } else if (t->tx_buf) { + SPI_OC_VERBOSE("start tx, txlen:0x%x\n", t->len); + while (spioc->reamin_len) { + ret = spioc_tx_start_one(spioc); + if (ret) { + goto err; + } + } + } else { + SPI_OC_VERBOSE("start rx, rxlen:0x%x\n", t->len); + while (spioc->reamin_len) { + ret = spioc_rx_start_one(spioc); + if (ret) { + goto err; + } + } + } + } + SPI_OC_VERBOSE("return num: 0x%x\n", len); + return len; +err: + return ret; +} + +static irqreturn_t spioc_spi_irq(int irq, void *dev) +{ + struct spioc *spioc; + + spioc = dev; + /* gooooohi, interrupt status bit judgment is not done */ + + if (spioc->txp && spioc->rxp) { + if (!spioc->reamin_len) { + complete(&spioc->done); + } else { + spioc_tx_rx_start_one(spioc); + } + } else if (spioc->txp) { + if (!spioc->reamin_len) { + complete(&spioc->done); + } else { + spioc_tx_start_one(spioc); + } + } else if (spioc->rxp){ + if (!spioc->reamin_len) { + complete(&spioc->done); + } else { + spioc_rx_start_one(spioc); + } + } + + return IRQ_HANDLED; +} + +static int ocores_spi_config_init(struct spioc *spioc) +{ + int ret = 0; + struct device *dev; + spi_ocores_device_t *spi_ocores_device; + + dev = spioc->dev; + if (dev->of_node) { + ret += of_property_read_string(dev->of_node, "dev_name", &spioc->dev_name); + ret += of_property_read_u32(dev->of_node, "dev_base", &spioc->base_addr); + ret += of_property_read_u32(dev->of_node, "reg_shift", &spioc->reg_shift); + ret += of_property_read_u32(dev->of_node, "reg_io_width", &spioc->reg_io_width); + ret += of_property_read_u32(dev->of_node, "clock-frequency", &spioc->freq); + ret += of_property_read_u32(dev->of_node, "reg_access_mode", &spioc->reg_access_mode); + ret += of_property_read_u32(dev->of_node, "num_chipselect", &spioc->num_chipselect); + + if (ret != 0) { + SPI_OC_ERROR("dts config error, ret:%d.\n", ret); + ret = -ENXIO; + return ret; + } + } else { + if (spioc->dev->platform_data == NULL) { + SPI_OC_ERROR("platform data config error.\n"); + ret = -ENXIO; + return ret; + } + spi_ocores_device = spioc->dev->platform_data; + spioc->bus_num = spi_ocores_device->bus_num; + spioc->dev_name = spi_ocores_device->dev_name; + spioc->big_endian = spi_ocores_device->big_endian; + spioc->base_addr = spi_ocores_device->dev_base; + spioc->reg_shift = spi_ocores_device->reg_shift; + spioc->reg_io_width = spi_ocores_device->reg_io_width; + spioc->freq = spi_ocores_device->clock_frequency; + spioc->reg_access_mode = spi_ocores_device->reg_access_mode; + spioc->num_chipselect = spi_ocores_device->num_chipselect; + } + + SPI_OC_VERBOSE("name:%s, base:0x%x, reg_shift:0x%x, io_width:0x%x, clock-frequency:0x%x.\n", + spioc->dev_name, spioc->base_addr, spioc->reg_shift, spioc->reg_io_width, spioc->freq); + SPI_OC_VERBOSE("reg access mode:%u, num_chipselect:%u.\n", + spioc->reg_access_mode, spioc->num_chipselect); + return ret; +} + +static int spioc_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct spioc *spioc; + int ret; + bool be; + + ret = -1; + master = spi_alloc_master(&pdev->dev, sizeof(struct spioc)); + if (!master) { + dev_err(&pdev->dev, "Failed to alloc spi master.\n"); + goto out; + } + + spioc = spi_master_get_devdata(master); + platform_set_drvdata(pdev, spioc); + + spioc->dev = &pdev->dev; + ret = ocores_spi_config_init(spioc); + if (ret != 0) { + dev_err(spioc->dev, "Failed to get ocores spi dts config.\n"); + goto free; + } + + if (spioc->dev->of_node) { + if (of_property_read_u32(spioc->dev->of_node, "big_endian", &spioc->big_endian)) { + + be = 0; + } else { + be = spioc->big_endian; + } + } else { + be = spioc->big_endian; + } + + if (spioc->reg_io_width == 0) { + spioc->reg_io_width = 1; /* Set to default value */ + } + + if (!spioc->setreg || !spioc->getreg) { + switch (spioc->reg_io_width) { + case REG_IO_WIDTH_1: + spioc->setreg = oc_spi_setreg_8; + spioc->getreg = oc_spi_getreg_8; + break; + + case REG_IO_WIDTH_2: + spioc->setreg = be ? oc_spi_setreg_16be : oc_spi_setreg_16; + spioc->getreg = be ? oc_spi_getreg_16be : oc_spi_getreg_16; + break; + + case REG_IO_WIDTH_4: + spioc->setreg = be ? oc_spi_setreg_32be : oc_spi_setreg_32; + spioc->getreg = be ? oc_spi_getreg_32be : oc_spi_getreg_32; + break; + + default: + dev_err(spioc->dev, "Unsupported I/O width (%d)\n", spioc->reg_io_width); + ret = -EINVAL; + goto free; + } + } + + /* master state */ + master->num_chipselect = spioc->num_chipselect; + master->mode_bits = MODEBITS; + master->setup = spioc_spi_setup; + if (spioc->dev->of_node) { + master->dev.of_node = pdev->dev.of_node; + } else { + master->bus_num = spioc->bus_num; + } + + /* setup the state for the bitbang driver */ + spioc->bitbang.master = master; + spioc->bitbang.setup_transfer = spioc_setup_transfer; + spioc->bitbang.chipselect = spioc_chipselect; + spioc->bitbang.txrx_bufs = spioc_spi_txrx_bufs; + + /* gooooohi need revision */ + spioc->irq = platform_get_irq(pdev, 0); + if (spioc->irq >= 0) { + SPI_OC_VERBOSE("spi oc use irq, irq number:%d.\n", spioc->irq); + init_completion(&spioc->done); + ret = devm_request_irq(&pdev->dev, spioc->irq, spioc_spi_irq, 0, + pdev->name, spioc); + if (ret) { + dev_err(spioc->dev, "Failed to request irq:%d.\n", spioc->irq); + goto free; + } + } + + ret = spi_bitbang_start(&spioc->bitbang); + if (ret) { + dev_err(spioc->dev, "Failed to start spi bitbang, ret:%d.\n", ret); + goto free; + } + dev_info(spioc->dev, "registered spi-%d for %s with base address:0x%x success.\n", + master->bus_num, spioc->dev_name, spioc->base_addr); + + return ret; +free: + spi_master_put(master); +out: + return ret; +} + +static int spioc_remove(struct platform_device *pdev) +{ + struct spioc *spioc; + struct spi_master *master; + + spioc = platform_get_drvdata(pdev); + master = spioc->bitbang.master; + spi_bitbang_stop(&spioc->bitbang); + platform_set_drvdata(pdev, NULL); + spi_master_put(master); + + return 0; +} + +static const struct of_device_id spioc_match[] = { + { .compatible = "wb-spi-oc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, spioc_match); + +static struct platform_driver spioc_driver = { + .probe = spioc_probe, + .remove = spioc_remove, + .driver = { + .name = "wb-spioc", + .owner = THIS_MODULE, + .of_match_table = spioc_match, + }, +}; + +module_platform_driver(spioc_driver); + +MODULE_DESCRIPTION("spi open core adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.h new file mode 100644 index 000000000000..647ff0c5f9cf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_spi_ocores.h @@ -0,0 +1,21 @@ +#ifndef __WB_SPI_OCORES_H__ +#define __WB_SPI_OCORES_H__ +#include + +#define mem_clear(data, size) memset((data), 0, (size)) +#define SPI_OCORES_DEV_NAME_MAX_LEN (64) + +typedef struct spi_ocores_device_s { + uint32_t bus_num; + uint32_t big_endian; + char dev_name[SPI_OCORES_DEV_NAME_MAX_LEN]; + uint32_t reg_access_mode; + uint32_t dev_base; + uint32_t reg_shift; + uint32_t reg_io_width; + uint32_t clock_frequency; + uint32_t num_chipselect; + int device_flag; +} spi_ocores_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_uio_irq.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_uio_irq.c new file mode 100644 index 000000000000..da2b582443b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_uio_irq.c @@ -0,0 +1,282 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct dfd_irq_s { + int gpio; + int irq_type; + struct uio_info dfd_irq_info; + spinlock_t lock; + struct attribute_group attr_group; +} dfd_irq_t; + +#define DRV_NAME "uio-irq" +#define DRV_VERSION "1.0" +#define ENABLE_VAL (1) +#define DISABLE_VAL (0) + +#define DEBUG_ERR_LEVEL (0x1) +#define DEBUG_WARN_LEVEL (0x2) +#define DEBUG_INFO_LEVEL (0x4) +#define DEBUG_VER_LEVEL (0x8) + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); +#define DEBUG_ERROR(fmt, args...) \ + do { \ + if (debug & DEBUG_ERR_LEVEL) { \ + printk(KERN_ERR "[ERR][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define DEBUG_WARN(fmt, args...) \ + do { \ + if (debug & DEBUG_WARN_LEVEL) { \ + printk(KERN_WARNING "[WARN][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define DEBUG_INFO(fmt, args...) \ + do { \ + if (debug & DEBUG_INFO_LEVEL) { \ + printk(KERN_INFO "[INFO][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define DEBUG_VERBOSE(fmt, args...) \ + do { \ + if (debug & DEBUG_VER_LEVEL) { \ + printk(KERN_DEBUG "[VER][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +static irqreturn_t dfd_genirq_handler(int irq, struct uio_info *dev_info) +{ + disable_irq_nosync(irq); + DEBUG_VERBOSE("handler disable irq"); + return IRQ_HANDLED; +} + +static int dfd_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on) +{ + struct irq_data *irqdata; + + irqdata = irq_get_irq_data(dev_info->irq); + + if (irqd_irq_disabled(irqdata) == !irq_on) { + DEBUG_VERBOSE("irq already disable"); + return 0; + } + if (irq_on) { + DEBUG_VERBOSE("irqcontrol enable irq"); + enable_irq(dev_info->irq); + } else { + DEBUG_VERBOSE("irqcontrol disable irq"); + disable_irq(dev_info->irq); + } + + return 0; +} + +static ssize_t set_irq_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + dfd_irq_t *dfd_irq; + struct uio_info *dev_info; + unsigned long flags; + int ret, val; + + dfd_irq = dev_get_drvdata(dev); + dev_info = &dfd_irq->dfd_irq_info; + + spin_lock_irqsave(&dfd_irq->lock, flags); + + sscanf(buf, "%d", &val); + DEBUG_VERBOSE("set val:%d.\n", val); + + if ((val != ENABLE_VAL) && (val != DISABLE_VAL)) { + DEBUG_ERROR("unsupport val:%d ", val); + ret = -EINVAL; + goto fail; + } + + if (val) { + DEBUG_VERBOSE("sysfs enable irq"); + enable_irq(dev_info->irq); + } else { + DEBUG_VERBOSE("sysfs disable irq"); + disable_irq(dev_info->irq); + } + + spin_unlock_irqrestore(&dfd_irq->lock, flags); + return count; + +fail: + spin_unlock_irqrestore(&dfd_irq->lock, flags); + return ret; +} + +static DEVICE_ATTR(irq_enable, S_IWUSR, NULL, set_irq_enable); + +static struct attribute *irq_attrs[] = { + &dev_attr_irq_enable.attr, + NULL, +}; + +static struct attribute_group irq_attr_group = { + .attrs = irq_attrs, +}; + +static int dfd_irq_probe(struct platform_device *pdev) +{ + u32 gpio, irq_type, pirq_line; + int ret, ret1, ret2; + struct uio_info *dfd_irq_info; + dfd_irq_t *dfd_irq; + + dfd_irq = kzalloc(sizeof(dfd_irq_t), GFP_KERNEL); + if (!dfd_irq) { + dev_err(&pdev->dev, "dfd_irq_t kzalloc failed.\n"); + return -ENOMEM; + } + + dfd_irq_info = &dfd_irq->dfd_irq_info; + dfd_irq_info->version = "1.0"; + dfd_irq_info->name = "uio-irq"; + + /* get pirq line for x86 */ + ret1 = of_property_read_u32(pdev->dev.of_node, "pirq-line", &pirq_line); + if (!ret1) { + DEBUG_VERBOSE("use pirq-line method, pirq-line:%u", pirq_line); + dfd_irq_info->irq = pirq_line; + } + + ret2 = of_property_read_u32(pdev->dev.of_node, "gpio", &gpio); + if (!ret2 && ret1) { + dfd_irq->gpio = gpio; + gpio_request(dfd_irq->gpio, "GPIOA"); + dfd_irq_info->irq = gpio_to_irq(dfd_irq->gpio); + DEBUG_VERBOSE("use gpio:%u, irq num:%ld", gpio, dfd_irq_info->irq); + } else if (ret2 && ret1){ + ret = -ENXIO; + dev_err(&pdev->dev, "no define irq num. ret2:%d, ret1:%d.\n", ret2, ret1); + goto free_mem; + } + + ret = of_property_read_u32(pdev->dev.of_node, "irq_type", &irq_type); + if (!ret && ret1) { + DEBUG_VERBOSE("use irq_type:%u", irq_type); + dfd_irq->irq_type = irq_type; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) + irq_set_irq_type(dfd_irq_info->irq, dfd_irq->irq_type); +#else + set_irq_type(dfd_irq_info->irq, dfd_irq->irq_type); +#endif + } else if (ret && ret1){ + ret = -ENXIO; + dev_err(&pdev->dev, "no define irq type. ret:%d, ret1:%d.\n", ret, ret1); + goto free_mem; + } + + dfd_irq_info->irq_flags = IRQF_SHARED; + dfd_irq_info->handler = dfd_genirq_handler; + dfd_irq_info->irqcontrol = dfd_genirq_irqcontrol; + + if(uio_register_device(&pdev->dev, dfd_irq_info)){ + ret = -ENODEV; + dev_err(&pdev->dev, "uio register failed.\n"); + goto free_mem; + } + + spin_lock_init(&dfd_irq->lock); + + dfd_irq->attr_group = irq_attr_group; + ret = sysfs_create_group(&pdev->dev.kobj, &dfd_irq->attr_group); + if (ret != 0) { + dev_err(&pdev->dev, "sysfs_create_group failed. ret:%d.\n", ret); + goto free_mem; + } + DEBUG_VERBOSE("sysfs create group success\n"); + + platform_set_drvdata(pdev, dfd_irq); + + return 0; + +free_mem: + kfree(dfd_irq); + + return ret; +} + +static int dfd_irq_remove(struct platform_device *pdev) +{ + dfd_irq_t *dfd_irq; + struct uio_info *dfd_irq_info; + + dfd_irq = platform_get_drvdata(pdev); + dfd_irq_info = &dfd_irq->dfd_irq_info; + + uio_unregister_device(dfd_irq_info); + kfree(dfd_irq); + + sysfs_remove_group(&pdev->dev.kobj, &dfd_irq->attr_group); + + return 0; +} + +static struct of_device_id dfd_irq_match[] = { + { + .compatible = "uio-irq", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, dfd_irq_match); + +static struct platform_driver dfd_irq_driver = { + .probe = dfd_irq_probe, + .remove = dfd_irq_remove, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = dfd_irq_match, + }, +}; + +static int __init dfd_irq_init(void) +{ + int ret; + + ret = platform_driver_register(&dfd_irq_driver); + if (ret != 0 ) { + return ret; + } + + return 0; +} + +static void __exit dfd_irq_exit(void) +{ + platform_driver_unregister(&dfd_irq_driver); +} + +module_init(dfd_irq_init); +module_exit(dfd_irq_exit); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.c new file mode 100644 index 000000000000..8c02d981843a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.c @@ -0,0 +1,1038 @@ +/* + * wb_wdt.c + * ko for watchdog function + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb_wdt.h" + +#define GPIO_FEED_WDT_MODE (1) +#define LOGIC_FEED_WDT_MODE (2) + +#define SYMBOL_I2C_DEV_MODE (1) +#define SYMBOL_PCIE_DEV_MODE (2) +#define SYMBOL_IO_DEV_MODE (3) +#define FILE_MODE (4) + +#define ONE_BYTE (1) + +#define WDT_OFF (0) +#define WDT_ON (1) + +#define MS_TO_S (1000) +#define MS_TO_NS (1000 * 1000) + +#define MAX_REG_VAL (255) + +extern int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int io_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); + +int g_wb_wdt_debug = 0; +int g_wb_wdt_error = 0; + +module_param(g_wb_wdt_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_wdt_error, int, S_IRUGO | S_IWUSR); + +#define WDT_VERBOSE(fmt, args...) do { \ + if (g_wb_wdt_debug) { \ + printk(KERN_INFO "[WDT][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WDT_ERROR(fmt, args...) do { \ + if (g_wb_wdt_error) { \ + printk(KERN_ERR "[WDT][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +enum { + HW_ALGO_TOGGLE, + HW_ALGO_LEVEL, +}; + +enum { + WATCHDOG_DEVICE_TYPE = 0, + HRTIMER_TYPE, + THREAD_TYPE, +}; + +typedef struct wb_wdt_priv_s { + + struct task_struct *thread; + struct hrtimer hrtimer; + ktime_t m_kt; + const char *config_dev_name; + uint8_t config_mode; + uint8_t hw_algo; + uint8_t enable_val; + uint8_t disable_val; + uint8_t enable_mask; + uint8_t priv_func_mode; + uint8_t feed_wdt_type; + uint32_t enable_reg; + uint32_t timeout_cfg_reg; + uint32_t timeleft_cfg_reg; + uint32_t hw_margin; + uint32_t feed_time; + uint32_t timer_accuracy; + gpio_wdt_info_t gpio_wdt; + logic_wdt_info_t logic_wdt; + struct device *dev; + const struct attribute_group *sysfs_group; + uint8_t sysfs_index; + struct mutex update_lock; + struct watchdog_device wdd; +}wb_wdt_priv_t; + +static int wdt_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + WDT_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + WDT_ERROR("kernel_read failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int wdt_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + WDT_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, val, size, &tmp_pos); + if (ret < 0) { + WDT_ERROR("kernel_write failed, path=%s, addr=0x%x, size=%ld, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int wb_wdt_read(uint8_t mode, const char *path, + uint32_t offset, uint8_t *buf, size_t count) +{ + int ret; + + switch (mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_read(path, offset, buf, count); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_read(path, offset, buf, count); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_read(path, offset, buf, count); + break; + case FILE_MODE: + ret = wdt_file_read(path, offset, buf, count); + break; + default: + WDT_ERROR("mode %u error, wdt func read failed.\n", mode); + return -EINVAL; + } + + WDT_VERBOSE("wdt func read mode:%u,dev_nam:%s, offset:0x%x, read_val:0x%x, size:%lu.\n", + mode, path, offset, *buf, count); + + return ret; +} + +static int wb_wdt_write(uint8_t mode, const char *path, + uint32_t offset, uint8_t *buf, size_t count) +{ + int ret; + + switch (mode) { + case SYMBOL_I2C_DEV_MODE: + ret = i2c_device_func_write(path, offset, buf, count); + break; + case SYMBOL_PCIE_DEV_MODE: + ret = pcie_device_func_write(path, offset, buf, count); + break; + case SYMBOL_IO_DEV_MODE: + ret = io_device_func_write(path, offset, buf, count); + break; + case FILE_MODE: + ret = wdt_file_write(path, offset, buf, count); + break; + default: + WDT_ERROR("mode %u error, wdt func write failed.\n", mode); + return -EINVAL; + } + + WDT_VERBOSE("wdt func write mode:%u, dev_nam:%s, offset:0x%x, write_val:0x%x, size:%lu.\n", + mode, path, offset, *buf, count); + + return ret; +} + +static int wb_wdt_enable_ctrl(wb_wdt_priv_t *priv, uint8_t flag) +{ + int ret; + uint8_t val; + uint8_t ctrl_val; + + switch (flag) { + case WDT_ON: + ctrl_val = priv->enable_val; + break; + case WDT_OFF: + ctrl_val = priv->disable_val; + break; + default: + WDT_ERROR("unsupport wdt enable ctrl:%u.\n", flag); + return -EINVAL; + } + + ret = wb_wdt_read(priv->priv_func_mode, priv->config_dev_name, + priv->enable_reg, &val, ONE_BYTE); + if (ret < 0) { + dev_err(priv->dev, "read wdt control reg error.\n"); + return ret; + } + + val &= ~priv->enable_mask; + + val |= ctrl_val & priv->enable_mask; + + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->enable_reg, &val, ONE_BYTE); + if (ret < 0) { + dev_err(priv->dev, "write wdt control reg error.\n"); + return ret; + } + + return 0; +} + +static void wdt_hwping(wb_wdt_priv_t *priv) +{ + gpio_wdt_info_t *gpio_wdt; + logic_wdt_info_t *logic_wdt; + uint8_t tmp_val; + int ret; + + if (priv->config_mode == GPIO_FEED_WDT_MODE) { + gpio_wdt = &priv->gpio_wdt; + switch (priv->hw_algo) { + case HW_ALGO_TOGGLE: + gpio_wdt = &priv->gpio_wdt; + gpio_wdt->state = !gpio_wdt->state; + gpio_set_value_cansleep(gpio_wdt->gpio, gpio_wdt->state); + WDT_VERBOSE("gpio toggle wdt work. val:%u\n", gpio_wdt->state); + break; + case HW_ALGO_LEVEL: + gpio_wdt = &priv->gpio_wdt; + /* Pulse */ + gpio_set_value_cansleep(gpio_wdt->gpio, !gpio_wdt->active_low); + udelay(1); + gpio_set_value_cansleep(gpio_wdt->gpio, gpio_wdt->active_low); + WDT_VERBOSE("gpio level wdt work.\n"); + break; + } + } else { + logic_wdt = &priv->logic_wdt; + switch (priv->hw_algo) { + case HW_ALGO_TOGGLE: + logic_wdt->active_val = !logic_wdt->active_val; + ret = wb_wdt_write(logic_wdt->logic_func_mode, logic_wdt->feed_dev_name, + logic_wdt->feed_reg, &logic_wdt->active_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("logic toggle wdt write failed.ret = %d\n", ret); + } + WDT_VERBOSE("logic toggle wdt work.\n"); + break; + case HW_ALGO_LEVEL: + tmp_val = !logic_wdt->active_val; + ret = wb_wdt_write(logic_wdt->logic_func_mode, logic_wdt->feed_dev_name, + logic_wdt->feed_reg, &tmp_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("logic level wdt write first failed.ret = %d\n", ret); + } + udelay(1); + ret = wb_wdt_write(logic_wdt->logic_func_mode, logic_wdt->feed_dev_name, + logic_wdt->feed_reg, &logic_wdt->active_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("logic level wdt write second failed.ret = %d\n", ret); + } + WDT_VERBOSE("logic level wdt work.\n"); + break; + } + } + return; +} + +static enum hrtimer_restart hrtimer_hwping(struct hrtimer *timer) +{ + wb_wdt_priv_t *priv = container_of(timer, wb_wdt_priv_t, hrtimer); + + wdt_hwping(priv); + hrtimer_forward(timer, timer->base->get_time(), priv->m_kt); + return HRTIMER_RESTART; +} + +static int thread_timer_cfg(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct device *dev; + uint32_t hw_margin; + uint32_t feed_time; + uint32_t accuracy; + uint8_t set_time_val; + int ret; + + dev = priv->dev; + + ret = 0; + if (dev->of_node) { + ret += of_property_read_u32(dev->of_node, "feed_time", &priv->feed_time); + if (ret != 0) { + dev_err(dev, "thread Failed to priv dts.\n"); + return -ENXIO; + } + } else { + priv->feed_time = wb_wdt_device->feed_time; + } + WDT_VERBOSE("thread priv->feed_time: %u.\n", priv->feed_time); + + hw_margin = priv->hw_margin; + feed_time = priv->feed_time; + accuracy = priv->timer_accuracy; + + if ((feed_time > (hw_margin / 2)) || (feed_time == 0)) { + dev_err(dev, "thread timer feed_time[%d] should be less than half hw_margin or zero.\n", feed_time); + return -EINVAL; + } + + set_time_val = hw_margin / accuracy; + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->timeout_cfg_reg, &set_time_val, ONE_BYTE); + if (ret < 0) { + dev_err(dev, "set wdt thread timer reg error.\n"); + return ret; + } + return 0; +} + +static int wdt_thread_timer(void *data) +{ + wb_wdt_priv_t *priv = data; + + while (!kthread_should_stop()) { + schedule_timeout_uninterruptible(msecs_to_jiffies(priv->feed_time)); + wdt_hwping(priv); + } + return 0; +} + +static int thread_timer_create(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct task_struct *p; + int ret; + + ret = thread_timer_cfg(priv, wb_wdt_device); + if (ret < 0) { + dev_err(priv->dev, "set wdt thread timer failed.\n"); + return ret; + } + + p = kthread_create(wdt_thread_timer, (void *)priv, "%s", "wb_wdt"); + if (!IS_ERR(p)) { + WDT_VERBOSE("timer thread create success.\n"); + priv->thread = p; + wake_up_process(p); + } else { + dev_err(priv->dev, "timer thread create failed.\n"); + return -ENXIO; + } + + ret = wb_wdt_enable_ctrl(priv, WDT_ON); + if (ret < 0) { + dev_err(priv->dev, "thread enable wdt failed.\n"); + return -ENXIO; + } + + return 0; +} + +static int hrtimer_cfg(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct device *dev; + struct hrtimer *hrtimer; + uint8_t set_time_val; + uint8_t hrtimer_s; + uint32_t hrtimer_ns; + int ret; + uint32_t hw_margin; + uint32_t feed_time; + uint32_t accuracy; + uint32_t max_timeout; + + dev = priv->dev; + + ret = 0; + if (dev->of_node) { + ret += of_property_read_u32(dev->of_node, "feed_time", &priv->feed_time); + if (ret != 0) { + dev_err(dev, "hrtimer Failed to priv dts.\n"); + return -ENXIO; + } + } else { + priv->feed_time = wb_wdt_device->feed_time; + } + WDT_VERBOSE("hrtimer priv->feed_time: %u.\n", priv->feed_time); + + hrtimer = &priv->hrtimer; + hw_margin = priv->hw_margin; + feed_time = priv->feed_time; + accuracy = priv->timer_accuracy; + max_timeout = accuracy * 255; + + if (hw_margin < accuracy || hw_margin > max_timeout) { + dev_err(dev, "hrtimer_hw_margin should be between %u and %u.\n", + accuracy, max_timeout); + return -EINVAL; + } + if ((feed_time > (hw_margin / 2)) || (feed_time == 0)) { + dev_err(dev, "feed_time[%d] should be less than half hw_margin or zeor.\n", feed_time); + return -EINVAL; + } + + hrtimer_s = feed_time / MS_TO_S; + hrtimer_ns = (feed_time % MS_TO_S) * MS_TO_NS; + set_time_val = hw_margin / accuracy; + + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->timeout_cfg_reg, &set_time_val, ONE_BYTE); + if (ret < 0) { + dev_err(dev, "set wdt time reg error.\n"); + return ret; + } + + priv->m_kt = ktime_set(hrtimer_s, hrtimer_ns); + hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer->function = hrtimer_hwping; + hrtimer_start(hrtimer, priv->m_kt, HRTIMER_MODE_REL); + + ret = wb_wdt_enable_ctrl(priv, WDT_ON); + if (ret < 0) { + dev_err(dev, "hrtimer enable wdt failed.\n"); + return -ENXIO; + } + + return 0; +} + +static int wb_wdt_ping(struct watchdog_device *wdd) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + + wdt_hwping(priv); + return 0; +} + +static int wb_wdt_start(struct watchdog_device *wdd) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + int ret; + + ret = wb_wdt_enable_ctrl(priv, WDT_ON); + if (ret < 0) { + WDT_ERROR("start wdt enable failed.\n"); + return -ENXIO; + } + set_bit(WDOG_HW_RUNNING, &wdd->status); + return 0; +} + +static int wb_wdt_stop(struct watchdog_device *wdd) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + int ret; + + ret = wb_wdt_enable_ctrl(priv, WDT_OFF); + if (ret < 0) { + WDT_ERROR("stop wdt enable failed.\n"); + return -ENXIO; + } + clear_bit(WDOG_HW_RUNNING, &wdd->status); + return 0; +} + +static int wb_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + uint32_t timeout_ms; + uint32_t accuracy; + uint8_t set_time_val; + int ret; + + accuracy = priv->timer_accuracy; + timeout_ms = t * 1000; + if (timeout_ms > accuracy * 255) { + WDT_ERROR("set wdt timeout too larger error.timeout_ms:%u\n", timeout_ms); + return -EINVAL; + } + + set_time_val = timeout_ms / accuracy; + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->timeout_cfg_reg, &set_time_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("set wdt timeout reg error, set_time_val:%u ret:%d\n", set_time_val, ret); + return ret; + } + wdd->timeout = t; + + return 0; +} + +static unsigned int wb_wdt_get_timeleft(struct watchdog_device *wdd) +{ + wb_wdt_priv_t *priv = watchdog_get_drvdata(wdd); + unsigned int time_left; + uint32_t accuracy; + uint8_t get_time_val; + int ret; + + accuracy = priv->timer_accuracy; + + ret = wb_wdt_read(priv->priv_func_mode, priv->config_dev_name, + priv->timeleft_cfg_reg, &get_time_val, ONE_BYTE); + if (ret < 0) { + WDT_ERROR("get wdt timeout reg error.ret:%d\n", ret); + return ret; + } + time_left = get_time_val * accuracy / MS_TO_S; + + WDT_VERBOSE("get wdt timeleft %d get_time_val %d accuracy=%d\n", + time_left, get_time_val, accuracy); + return time_left; +} + +static const struct watchdog_info wb_wdt_ident = { + .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, + .firmware_version = 0, + .identity = "CPLD Watchdog", +}; + +static const struct watchdog_ops wb_wdt_ops = { + .owner = THIS_MODULE, + .start = wb_wdt_start, + .stop = wb_wdt_stop, + .ping = wb_wdt_ping, + .set_timeout = wb_wdt_set_timeout, + .get_timeleft = wb_wdt_get_timeleft, +}; + +static int watchdog_device_cfg(wb_wdt_priv_t *priv) +{ + int ret; + uint8_t set_time_val; + + ret = wb_wdt_enable_ctrl(priv, WDT_OFF); + if (ret < 0) { + dev_err(priv->dev, "probe disable wdt failed.\n"); + return -ENXIO; + } + + set_time_val = priv->hw_margin / priv->timer_accuracy; + ret = wb_wdt_write(priv->priv_func_mode, priv->config_dev_name, + priv->timeout_cfg_reg, &set_time_val, ONE_BYTE); + if (ret < 0) { + dev_err(priv->dev, "set wdt time reg error.\n"); + return ret; + } + + watchdog_set_drvdata(&priv->wdd, priv); + + priv->wdd.info = &wb_wdt_ident; + priv->wdd.ops = &wb_wdt_ops; + priv->wdd.bootstatus = 0; + priv->wdd.timeout = priv->hw_margin / MS_TO_S; + priv->wdd.min_timeout = priv->timer_accuracy / MS_TO_S; + priv->wdd.max_timeout = priv->timer_accuracy * MAX_REG_VAL / MS_TO_S; + priv->wdd.parent = priv->dev; + + watchdog_stop_on_reboot(&priv->wdd); + + ret = devm_watchdog_register_device(priv->dev, &priv->wdd); + if (ret != 0) { + dev_err(priv->dev, "cannot register watchdog device (err=%d)\n", ret); + return -ENXIO; + } + + return 0; +} + +static int logic_wdt_init(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct device *dev; + logic_wdt_info_t *logic_wdt; + int ret; + + dev = priv->dev; + logic_wdt = &priv->logic_wdt; + + ret = 0; + if (dev->of_node) { + ret += of_property_read_string(dev->of_node, "feed_dev_name", &logic_wdt->feed_dev_name); + ret += of_property_read_u32(dev->of_node, "feed_reg", &logic_wdt->feed_reg); + ret += of_property_read_u8(dev->of_node, "active_val", &logic_wdt->active_val); + ret += of_property_read_u8(dev->of_node, "logic_func_mode", &logic_wdt->logic_func_mode); + if (ret != 0) { + dev_err(dev, "Failed to logic_wdt dts.\n"); + return -ENXIO; + } + } else { + logic_wdt->feed_dev_name = wb_wdt_device->wdt_config_mode.logic_wdt.feed_dev_name; + logic_wdt->feed_reg = wb_wdt_device->wdt_config_mode.logic_wdt.feed_reg; + logic_wdt->active_val = wb_wdt_device->wdt_config_mode.logic_wdt.active_val; + logic_wdt->logic_func_mode = wb_wdt_device->wdt_config_mode.logic_wdt.logic_func_mode; + } + + logic_wdt->state_val = logic_wdt->active_val; + + WDT_VERBOSE("feed_dev_name:%s, feed_reg:0x%x, active_val:%u, logic_func_mode:%u\n", + logic_wdt->feed_dev_name, logic_wdt->feed_reg, + logic_wdt->active_val, logic_wdt->logic_func_mode); + + return 0; +} + +static int gpio_wdt_init(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) +{ + struct device *dev; + gpio_wdt_info_t *gpio_wdt; + enum of_gpio_flags flags; + uint32_t f = 0; + int ret; + + dev = priv->dev; + gpio_wdt = &priv->gpio_wdt; + + if (dev->of_node) { + gpio_wdt->gpio = of_get_gpio_flags(dev->of_node, 0, &flags); + } else { + gpio_wdt->gpio = wb_wdt_device->wdt_config_mode.gpio_wdt.gpio; + flags = wb_wdt_device->wdt_config_mode.gpio_wdt.flags; + } + if (!gpio_is_valid(gpio_wdt->gpio)) { + dev_err(dev, "gpio is invalid.\n"); + return gpio_wdt->gpio; + } + + gpio_wdt->active_low = flags & OF_GPIO_ACTIVE_LOW; + + if(priv->hw_algo == HW_ALGO_TOGGLE) { + f = GPIOF_IN; + } else { + f = gpio_wdt->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; + } + + ret = devm_gpio_request_one(dev, gpio_wdt->gpio, f, + dev_name(dev)); + if (ret) { + dev_err(dev, "devm_gpio_request_one failed.\n"); + return ret; + } + + gpio_wdt->state = gpio_wdt->active_low; + gpio_direction_output(gpio_wdt->gpio, gpio_wdt->state); + + WDT_VERBOSE("active_low:%d\n", gpio_wdt->active_low); + return 0; +} + +static ssize_t set_wdt_sysfs_value(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + wb_wdt_priv_t *priv = dev_get_drvdata(dev); + int ret, val; + + val = 0; + sscanf(buf, "%d", &val); + WDT_VERBOSE("set wdt, val:%d.\n", val); + + if (val < 0 || val > 255) { + WDT_ERROR("set wdt val %d failed.\n", val); + return -EINVAL; + } + + mutex_lock(&priv->update_lock); + + ret = wb_wdt_enable_ctrl(priv, val); + if (ret < 0) { + WDT_ERROR("set wdt sysfs value:%u failed.\n", val); + goto fail; + } + + WDT_VERBOSE("set wdt sysfs value:%u successed.\n", val); + mutex_unlock(&priv->update_lock); + return count; + +fail: + mutex_unlock(&priv->update_lock); + return ret; +} + +static ssize_t show_wdt_sysfs_value(struct device *dev, + struct device_attribute *da, char *buf) +{ + wb_wdt_priv_t *priv = dev_get_drvdata(dev); + uint8_t val, status; + int ret; + + mutex_lock(&priv->update_lock); + + ret = wb_wdt_read(priv->priv_func_mode, priv->config_dev_name, + priv->enable_reg, &val, ONE_BYTE); + if (ret < 0) { + dev_err(priv->dev, "read wdt enable reg val error.\n"); + goto fail; + } + + val &= priv->enable_mask; + if (val == priv->enable_val) { + status = WDT_ON; + } else if(val == priv->disable_val) { + status = WDT_OFF; + } else { + WDT_ERROR("enable reg read val not match set val, read val:%u, mask:%u, enable_val:%u, disable_val:%u", + val, priv->enable_mask, priv->enable_val, priv->disable_val); + ret = -EIO; + goto fail; + } + + WDT_VERBOSE("read_val:%u, mask:%u, enable_val:%u, disable_val:%u, status:%u", + val, priv->enable_mask, priv->enable_val, priv->disable_val, status); + + mutex_unlock(&priv->update_lock); + return sprintf(buf, "%u\n", status); + +fail: + mutex_unlock(&priv->update_lock); + return ret; +} + +static SENSOR_DEVICE_ATTR(wdt_status, S_IRUGO | S_IWUSR, show_wdt_sysfs_value, set_wdt_sysfs_value, 0); + +static struct attribute *wdt_sysfs_attrs[] = { + &sensor_dev_attr_wdt_status.dev_attr.attr, + NULL +}; + +static const struct attribute_group wdt_sysfs_group = { + .attrs = wdt_sysfs_attrs, +}; + +struct wdt_attr_match_group { + uint8_t index; + const struct attribute_group *attr_group_ptr; +}; + +static struct wdt_attr_match_group g_wdt_attr_match[] = { + {0, &wdt_sysfs_group}, +}; + +static const struct attribute_group *wdt_get_attr_group(uint32_t index) +{ + int i; + struct wdt_attr_match_group *group; + + for (i = 0; i < ARRAY_SIZE(g_wdt_attr_match); i++) { + group = &g_wdt_attr_match[i]; + if (index == group->index) { + WDT_VERBOSE("get wdt attr, index:%u.\n", index); + return group->attr_group_ptr; + } + } + + return NULL; +} + +static int wb_wdt_probe(struct platform_device *pdev) +{ + wb_wdt_priv_t *priv; + int ret; + const char *algo; + wb_wdt_device_t *wb_wdt_device; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + platform_set_drvdata(pdev, priv); + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "config_dev_name", &priv->config_dev_name); + ret += of_property_read_string(pdev->dev.of_node, "hw_algo", &algo); + ret += of_property_read_u8(pdev->dev.of_node, "config_mode", &priv->config_mode); + ret += of_property_read_u8(pdev->dev.of_node, "priv_func_mode", &priv->priv_func_mode); + ret += of_property_read_u8(pdev->dev.of_node, "enable_val", &priv->enable_val); + ret += of_property_read_u8(pdev->dev.of_node, "disable_val", &priv->disable_val); + ret += of_property_read_u8(pdev->dev.of_node, "enable_mask", &priv->enable_mask); + ret += of_property_read_u32(pdev->dev.of_node, "enable_reg", &priv->enable_reg); + ret += of_property_read_u32(pdev->dev.of_node, "timeout_cfg_reg", &priv->timeout_cfg_reg); + ret += of_property_read_u32(pdev->dev.of_node,"hw_margin_ms", &priv->hw_margin); + ret += of_property_read_u8(pdev->dev.of_node,"feed_wdt_type", &priv->feed_wdt_type); + ret += of_property_read_u32(pdev->dev.of_node,"timer_accuracy", &priv->timer_accuracy); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to priv dts.\n"); + return -ENXIO; + } + + priv->sysfs_index = SYSFS_NO_CFG; + of_property_read_u8(pdev->dev.of_node,"sysfs_index", &priv->sysfs_index); + + priv->timeleft_cfg_reg = priv->timeout_cfg_reg; + of_property_read_u32(pdev->dev.of_node,"timeleft_cfg_reg", &priv->timeleft_cfg_reg); + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + wb_wdt_device = pdev->dev.platform_data; + priv->config_dev_name = wb_wdt_device->config_dev_name; + algo = wb_wdt_device->hw_algo; + priv->config_mode = wb_wdt_device->config_mode; + priv->priv_func_mode = wb_wdt_device->priv_func_mode; + priv->enable_val = wb_wdt_device->enable_val; + priv->disable_val = wb_wdt_device->disable_val; + priv->enable_mask = wb_wdt_device->enable_mask; + priv->enable_reg = wb_wdt_device->enable_reg; + priv->timeout_cfg_reg = wb_wdt_device->timeout_cfg_reg; + priv->hw_margin = wb_wdt_device->hw_margin; + priv->timer_accuracy = wb_wdt_device->timer_accuracy; + priv->feed_wdt_type = wb_wdt_device->feed_wdt_type; + priv->sysfs_index = wb_wdt_device->sysfs_index; + priv->timeleft_cfg_reg = wb_wdt_device->timeleft_cfg_reg; + } + + if (!strcmp(algo, "toggle")) { + priv->hw_algo = HW_ALGO_TOGGLE; + } else if (!strcmp(algo, "level")) { + priv->hw_algo = HW_ALGO_LEVEL; + } else { + dev_err(&pdev->dev, "hw_algo config error.must be toggle or level.\n"); + return -EINVAL; + } + + WDT_VERBOSE("config_dev_name:%s, config_mode:%u, priv_func_mode:%u, enable_reg:0x%x, timeout_cfg_reg:0x%x\n", + priv->config_dev_name, priv->config_mode, priv->priv_func_mode, priv->enable_reg, priv->timeout_cfg_reg); + WDT_VERBOSE("timeout_cfg_reg:0x%x, enable_val:%u, disable_val:%u, enable_mask:%u, hw_margin:%u, feed_wdt_type:%u\n", + priv->timeleft_cfg_reg, priv->enable_val, priv->disable_val, priv->enable_mask, priv->hw_margin, priv->feed_wdt_type); + + priv->dev = &pdev->dev; + if (priv->config_mode == GPIO_FEED_WDT_MODE) { + ret = gpio_wdt_init(priv, wb_wdt_device); + if (ret < 0) { + dev_err(&pdev->dev, "init gpio mode wdt failed.\n"); + return -ENXIO; + } + } else if (priv->config_mode == LOGIC_FEED_WDT_MODE) { + ret = logic_wdt_init(priv, wb_wdt_device); + if (ret < 0) { + dev_err(&pdev->dev, "init func mode wdt failed.\n"); + return -ENXIO; + } + } else { + dev_err(&pdev->dev, "unsupport %u config_mode, dts configure error.\n", + priv->config_mode); + return -ENXIO; + } + + switch (priv->feed_wdt_type) { + case WATCHDOG_DEVICE_TYPE: + ret = watchdog_device_cfg(priv); + break; + case HRTIMER_TYPE: + ret = hrtimer_cfg(priv, wb_wdt_device); + break; + case THREAD_TYPE: + ret = thread_timer_create(priv, wb_wdt_device); + break; + default: + dev_err(&pdev->dev, "timer type %u unsupport.\n", priv->feed_wdt_type); + return -EINVAL; + } + if (ret < 0) { + dev_err(&pdev->dev, "init timer feed_wdt_type %u failed.\n", priv->feed_wdt_type); + return -ENXIO; + } + + dev_info(&pdev->dev, "register %s mode, config_mode %u, func_mode %u, %u ms overtime wdt success\n", + algo, priv->config_mode, priv->priv_func_mode, priv->hw_margin); + + if (priv->sysfs_index != SYSFS_NO_CFG) { + + priv->sysfs_group = wdt_get_attr_group(priv->sysfs_index); + if (priv->sysfs_group) { + ret = sysfs_create_group(&pdev->dev.kobj, priv->sysfs_group); + if (ret != 0) { + dev_err(&pdev->dev, "sysfs_create_group failed. ret:%d.\n", ret); + return -ENOMEM; + } + dev_info(&pdev->dev, "sysfs create group success\n"); + } else { + dev_err(&pdev->dev, "failed to find %u index wdt, return NULL.\n", priv->sysfs_index); + return -ENOMEM; + } + + mutex_init(&priv->update_lock); + + dev_info(&pdev->dev, "register %u index wdt sysfs success." ,priv->sysfs_index); + } + + return 0; +} + +static void unregister_action(struct platform_device *pdev) +{ + wb_wdt_priv_t *priv = platform_get_drvdata(pdev); + gpio_wdt_info_t *gpio_wdt; + logic_wdt_info_t *logic_wdt; + int ret; + + ret = wb_wdt_enable_ctrl(priv, WDT_OFF); + if (ret < 0) { + dev_err(&pdev->dev, "remove disable wdt failed.\n"); + } + + if (priv->sysfs_index != SYSFS_NO_CFG) { + sysfs_remove_group(&pdev->dev.kobj, priv->sysfs_group); + } + + if (priv->feed_wdt_type == HRTIMER_TYPE) { + hrtimer_cancel(&priv->hrtimer); + } else if (priv->feed_wdt_type == THREAD_TYPE) { + kthread_stop(priv->thread); + priv->thread = NULL; + } else { + WDT_VERBOSE("wdd type, do nothing.\n"); + } + + if (priv->config_mode == GPIO_FEED_WDT_MODE) { + gpio_wdt = &priv->gpio_wdt; + gpio_set_value_cansleep(gpio_wdt->gpio, !gpio_wdt->active_low); + + if (priv->hw_algo == HW_ALGO_TOGGLE) { + gpio_direction_input(gpio_wdt->gpio); + } + } else { + logic_wdt = &priv->logic_wdt; + logic_wdt->state_val = !logic_wdt->state_val; + ret = wb_wdt_write(logic_wdt->logic_func_mode, logic_wdt->feed_dev_name, + logic_wdt->feed_reg, &logic_wdt->state_val, ONE_BYTE); + if (ret < 0) { + dev_err(&pdev->dev, "set wdt control reg error.\n"); + } + } + + return; +} + +static int wb_wdt_remove(struct platform_device *pdev) +{ + WDT_VERBOSE("enter remove wdt.\n"); + unregister_action(pdev); + dev_info(&pdev->dev, "remove wdt finish.\n"); + + return 0; +} + +static void wb_wdt_shutdown(struct platform_device *pdev) +{ + WDT_VERBOSE("enter shutdown wdt.\n"); + unregister_action(pdev); + dev_info(&pdev->dev, "shutdown wdt finish.\n"); + + return; +} + +static const struct of_device_id wb_wdt_dt_ids[] = { + { .compatible = "wb_wdt", }, + { } +}; +MODULE_DEVICE_TABLE(of, wb_wdt_dt_ids); + +static struct platform_driver wb_wdt_driver = { + .driver = { + .name = "wb_wdt", + .of_match_table = wb_wdt_dt_ids, + }, + .probe = wb_wdt_probe, + .remove = wb_wdt_remove, + .shutdown = wb_wdt_shutdown, +}; + +#ifdef CONFIG_GPIO_WATCHDOG_ARCH_INITCALL +static int __init wb_wdt_init(void) +{ + return platform_driver_register(&wb_wdt_driver); +} +arch_initcall(wb_wdt_init); +#else +module_platform_driver(wb_wdt_driver); +#endif + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("watchdog driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.h b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.h new file mode 100644 index 000000000000..10c30e13f94c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_wdt.h @@ -0,0 +1,46 @@ +#ifndef __WB_WDT_H__ +#define __WB_WDT_H__ + +#include + +#define SYSFS_NO_CFG (0xff) + +typedef struct gpio_wdt_info_s { + int gpio; + enum of_gpio_flags flags; + bool active_low; + bool state; +}gpio_wdt_info_t; + +typedef struct logic_wdt_info_s { + const char *feed_dev_name; + uint8_t logic_func_mode; + uint32_t feed_reg; + uint8_t active_val; + uint8_t state_val; +}logic_wdt_info_t; + +typedef struct wb_wdt_device_s { + int device_flag; + const char *config_dev_name; + uint8_t config_mode; + const char *hw_algo; + uint8_t enable_val; + uint8_t disable_val; + uint8_t enable_mask; + uint8_t priv_func_mode; + uint8_t feed_wdt_type; + uint32_t enable_reg; + uint32_t timeout_cfg_reg; + uint32_t timeleft_cfg_reg; + uint32_t hw_margin; + uint32_t feed_time; + uint32_t timer_accuracy; + union { + gpio_wdt_info_t gpio_wdt; + logic_wdt_info_t logic_wdt; + } wdt_config_mode; + uint8_t sysfs_index; +} wb_wdt_device_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_xdpe132g5c.c b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_xdpe132g5c.c new file mode 100644 index 000000000000..edc12d34b6e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/modules/wb_xdpe132g5c.c @@ -0,0 +1,574 @@ +/* + * xdpe132g5c_i2c_drv.c + * + * This module create sysfs to set AVS and create hwmon to get out power + * through xdpe132g5c I2C address. + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-09-17 Initial version + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WB_I2C_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define WB_I2C_RETRY_TIME (10) +#define WB_XDPE_I2C_PAGE_ADDR (0xff) +#define WB_XDPE_I2C_VOUT_MODE (0x40) +#define WB_XDPE_I2C_VOUT_COMMAND (0x42) +#define WB_XDPE_I2C_VOUT_PAGE (0x06) +#define WB_XDPE_VOUT_MAX_THRESHOLD ((0xFFFF * 1000L * 1000L) / (256)) +#define WB_XDPE_VOUT_MIN_THRESHOLD (0) + +static int g_wb_xdpe_debug = 0; +static int g_wb_xdpe_error = 0; + +module_param(g_wb_xdpe_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_xdpe_error, int, S_IRUGO | S_IWUSR); + +#define WB_XDPE_VERBOSE(fmt, args...) do { \ + if (g_wb_xdpe_debug) { \ + printk(KERN_INFO "[WB_XDPE][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_XDPE_ERROR(fmt, args...) do { \ + if (g_wb_xdpe_error) { \ + printk(KERN_ERR "[WB_XDPE][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct xdpe_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct mutex update_lock; + long vout_max; + long vout_min; +}; + +typedef struct xdpe_vout_data_s { + u8 vout_mode; + int vout_precision; +} xdpe_vout_data_t; + +static xdpe_vout_data_t g_xdpe_vout_group[] = { + {.vout_mode = 0x18, .vout_precision = 256}, + {.vout_mode = 0x17, .vout_precision = 512}, + {.vout_mode = 0x16, .vout_precision = 1024}, + {.vout_mode = 0x15, .vout_precision = 2048}, + {.vout_mode = 0x14, .vout_precision = 4096}, +}; + +static s32 wb_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_read_byte_data(client, command); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_write_byte_data(client, command, value); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_read_word_data(client, command); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, + u16 value) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_write_word_data(client, command, value); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static long calc_power_linear11_data(int data) +{ + s16 exponent; + s32 mantissa; + long val; + + exponent = ((s16)data) >> 11; + mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; + val = mantissa; + val = val * 1000L * 1000L; + + if (exponent >= 0) { + val <<= exponent; + } else { + val >>= -exponent; + } + return val; +} + +static int read_xdpe_power_value(const struct i2c_client *client, u8 page, u8 reg, long *value) +{ + int ret, data; + + ret = wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, page); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: set xdpe page%u failed, ret: %d\n", client->adapter->nr, + client->addr, page, ret); + return ret; + } + data = wb_i2c_smbus_read_word_data(client, reg); + if (data < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe page%u reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, page, reg, data); + return data; + } + *value = calc_power_linear11_data(data); + WB_XDPE_VERBOSE("%d-%04x: page%u reg: 0x%x rd_data: 0x%x, decode linear11 value: %ld\n", + client->adapter->nr, client->addr, page, reg, data, *value); + return 0; +} + +static ssize_t xdpe_power_value_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + int ret, ori_page; + u16 sensor_h, sensor_l; + u8 page, reg; + struct sensor_device_attribute *attr; + struct i2c_client *client; + struct xdpe_data *data; + long value1, value2; + + data = dev_get_drvdata(dev); + client = data->client; + attr = to_sensor_dev_attr(da); + sensor_h = ((attr->index) >> 16) & 0xffff; + sensor_l = (attr->index) & 0xffff; + + mutex_lock(&data->update_lock); + + ori_page = wb_i2c_smbus_read_byte_data(client, WB_XDPE_I2C_PAGE_ADDR); + if (ori_page < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe origin page failed, ret: %d\n", client->adapter->nr, + client->addr, ori_page); + mutex_unlock(&data->update_lock); + return ori_page; + } + value1 = 0; + value2 = 0; + + if (sensor_h) { + page = (sensor_h >> 8) & 0xff; + reg = sensor_h & 0xff; + ret = read_xdpe_power_value(client, page, reg, &value1); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe sensor high sensor page%u reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, page, reg, ret); + goto error; + } + WB_XDPE_VERBOSE("%d-%04x: read xdpe sensor high sensor page%u reg: 0x%x success, value: %ld\n", + client->adapter->nr, client->addr, page, reg, value1); + } + + page = (sensor_l >> 8) & 0xff; + reg = sensor_l & 0xff; + ret = read_xdpe_power_value(client, page, reg, &value2); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe sensor low sensor page%u reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, page, reg, ret); + goto error; + } + WB_XDPE_VERBOSE("%d-%04x: read xdpe sensor low sensor page%u reg: 0x%x success, value: %ld\n", + client->adapter->nr, client->addr, page, reg, value2); + + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + return snprintf(buf, PAGE_SIZE, "%ld\n", value1 + value2); +error: + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + return ret; +} + +static int xdpe_get_vout_precision(const struct i2c_client *client, int *vout_precision) +{ + int i, vout_mode, a_size; + + vout_mode = wb_i2c_smbus_read_byte_data(client, WB_XDPE_I2C_VOUT_MODE); + if (vout_mode < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe vout mode reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, WB_XDPE_I2C_VOUT_MODE, vout_mode); + return vout_mode; + } + + a_size = ARRAY_SIZE(g_xdpe_vout_group); + for (i = 0; i < a_size; i++) { + if (g_xdpe_vout_group[i].vout_mode == vout_mode) { + *vout_precision = g_xdpe_vout_group[i].vout_precision; + WB_XDPE_VERBOSE("%d-%04x: match, vout mode: 0x%x, precision: %d\n", + client->adapter->nr, client->addr, vout_mode, *vout_precision); + break; + } + } + if (i == a_size) { + WB_XDPE_ERROR("%d-%04x: invalid vout mode: 0x%x\n",client->adapter->nr, client->addr, + vout_mode); + return -EINVAL; + } + return 0; +} + +static ssize_t xdpe_avs_vout_show(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret, ori_page, vout_cmd, vout_precision; + struct i2c_client *client; + struct xdpe_data *data; + long vout; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + ori_page = wb_i2c_smbus_read_byte_data(client, WB_XDPE_I2C_PAGE_ADDR); + if (ori_page < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe origin page failed, ret: %d\n", client->adapter->nr, + client->addr, ori_page); + mutex_unlock(&data->update_lock); + return ori_page; + } + + ret = wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, WB_XDPE_I2C_VOUT_PAGE); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: set xdpe avs vout page%u failed, ret: %d\n", client->adapter->nr, + client->addr, WB_XDPE_I2C_VOUT_PAGE, ret); + goto error; + } + + ret = xdpe_get_vout_precision(client, &vout_precision); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: get xdpe avs vout precision failed, ret: %d\n", + client->adapter->nr, client->addr, ret); + goto error; + } + + vout_cmd = wb_i2c_smbus_read_word_data(client, WB_XDPE_I2C_VOUT_COMMAND); + if (vout_cmd < 0) { + ret = vout_cmd; + WB_XDPE_ERROR("%d-%04x: read xdpe vout command reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, WB_XDPE_I2C_VOUT_COMMAND, ret); + goto error; + } + + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + + vout = vout_cmd * 1000L * 1000L / vout_precision; + WB_XDPE_VERBOSE("%d-%04x: vout: %ld, vout_cmd: 0x%x, precision: %d\n", client->adapter->nr, + client->addr, vout, vout_cmd, vout_precision); + return snprintf(buf, PAGE_SIZE, "%ld\n", vout); +error: + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t xdpe_avs_vout_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int ret, ori_page, vout_cmd, vout_cmd_set, vout_precision; + struct i2c_client *client; + struct xdpe_data *data; + long vout, vout_max, vout_min; + + client = to_i2c_client(dev); + ret = kstrtol(buf, 10, &vout); + if (ret) { + WB_XDPE_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + + data = i2c_get_clientdata(client); + vout_max = data->vout_max; + vout_min = data->vout_min; + if ((vout > vout_max) || (vout < vout_min)) { + WB_XDPE_ERROR("%d-%04x: vout value: %ld, out of range [%ld, %ld] \n", client->adapter->nr, + client->addr, vout, vout_min, vout_max); + return -EINVAL; + } + + mutex_lock(&data->update_lock); + + ori_page = wb_i2c_smbus_read_byte_data(client, WB_XDPE_I2C_PAGE_ADDR); + if (ori_page < 0) { + WB_XDPE_ERROR("%d-%04x: read xdpe origin page failed, ret: %d\n", client->adapter->nr, + client->addr, ori_page); + mutex_unlock(&data->update_lock); + return ori_page; + } + + ret = wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, WB_XDPE_I2C_VOUT_PAGE); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: set xdpe avs vout page%u failed, ret: %d\n", client->adapter->nr, + client->addr, WB_XDPE_I2C_VOUT_PAGE, ret); + goto error; + } + + ret = xdpe_get_vout_precision(client, &vout_precision); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: get xdpe avs vout precision failed, ret: %d\n", + client->adapter->nr, client->addr, ret); + goto error; + } + + vout_cmd_set = (vout * vout_precision) / (1000L * 1000L); + if (vout_cmd_set > 0xffff) { + WB_XDPE_ERROR("%d-%04x: invalid value, vout %ld, vout_precision: %d, vout_cmd_set: 0x%x\n", + client->adapter->nr, client->addr, vout, vout_precision, vout_cmd_set); + ret = -EINVAL; + goto error; + } + ret = wb_i2c_smbus_write_word_data(client, WB_XDPE_I2C_VOUT_COMMAND, vout_cmd_set); + if (ret < 0) { + WB_XDPE_ERROR("%d-%04x: set xdpe vout cmd reg: 0x%x, value: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, WB_XDPE_I2C_VOUT_COMMAND, vout_cmd_set, ret); + goto error; + } + + vout_cmd = wb_i2c_smbus_read_word_data(client, WB_XDPE_I2C_VOUT_COMMAND); + if (vout_cmd < 0) { + ret = vout_cmd; + WB_XDPE_ERROR("%d-%04x: read xdpe vout command reg: 0x%x failed, ret: %d\n", + client->adapter->nr, client->addr, WB_XDPE_I2C_VOUT_COMMAND, ret); + goto error; + } + if (vout_cmd != vout_cmd_set) { + ret = -EIO; + WB_XDPE_ERROR("%d-%04x: vout cmd value check error, vout cmd read: 0x%x, vout cmd set: 0x%x\n", + client->adapter->nr, client->addr, vout_cmd, vout_cmd_set); + goto error; + + } + + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + WB_XDPE_VERBOSE("%d-%04x: set vout cmd success, vout %ld, vout_precision: %d, vout_cmd_set: 0x%x\n", + client->adapter->nr, client->addr, vout, vout_precision, vout_cmd_set); + return count; +error: + wb_i2c_smbus_write_byte_data(client, WB_XDPE_I2C_PAGE_ADDR, ori_page); + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t xdpe_avs_vout_max_show(struct device *dev, struct device_attribute *da, char *buf) +{ + struct i2c_client *client; + struct xdpe_data *data; + long vout_max; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + vout_max = data->vout_max; + return snprintf(buf, PAGE_SIZE, "%ld\n", vout_max); +} + +static ssize_t xdpe_avs_vout_max_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int ret; + struct i2c_client *client; + struct xdpe_data *data; + long vout_max; + + client = to_i2c_client(dev); + ret = kstrtol(buf, 10, &vout_max); + if (ret) { + WB_XDPE_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + WB_XDPE_VERBOSE("%d-%04x: vout max threshold: %ld", client->adapter->nr, client->addr, + vout_max); + data = i2c_get_clientdata(client); + data->vout_max = vout_max; + return count; +} + +static ssize_t xdpe_avs_vout_min_show(struct device *dev, struct device_attribute *da, char *buf) +{ + struct i2c_client *client; + struct xdpe_data *data; + long vout_min; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + vout_min = data->vout_min; + return snprintf(buf, PAGE_SIZE, "%ld\n", vout_min); +} + +static ssize_t xdpe_avs_vout_min_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int ret; + struct i2c_client *client; + struct xdpe_data *data; + long vout_min; + + client = to_i2c_client(dev); + ret = kstrtol(buf, 10, &vout_min); + if (ret) { + WB_XDPE_ERROR("%d-%04x: invalid value: %s \n", client->adapter->nr, client->addr, buf); + return -EINVAL; + } + WB_XDPE_VERBOSE("%d-%04x: vout min threshold: %ld", client->adapter->nr, client->addr, + vout_min); + data = i2c_get_clientdata(client); + data->vout_min = vout_min; + return count; +} + +/* xdpe hwmon */ +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO ,xdpe_power_value_show, NULL, 0x072c); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO ,xdpe_power_value_show, NULL, 0x0b2c); +static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO ,xdpe_power_value_show, NULL, 0x072c0b2c); + +static struct attribute *xdpe_hwmon_attrs[] = { + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_power3_input.dev_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(xdpe_hwmon); + +/* xdpe sysfs */ +static SENSOR_DEVICE_ATTR(avs_vout, S_IRUGO | S_IWUSR, xdpe_avs_vout_show, xdpe_avs_vout_store, 0); +static SENSOR_DEVICE_ATTR(avs_vout_max, S_IRUGO | S_IWUSR, xdpe_avs_vout_max_show, xdpe_avs_vout_max_store, 0); +static SENSOR_DEVICE_ATTR(avs_vout_min, S_IRUGO | S_IWUSR, xdpe_avs_vout_min_show, xdpe_avs_vout_min_store, 0); + +static struct attribute *xdpe132g5c_sysfs_attrs[] = { + &sensor_dev_attr_avs_vout.dev_attr.attr, + &sensor_dev_attr_avs_vout_max.dev_attr.attr, + &sensor_dev_attr_avs_vout_min.dev_attr.attr, + NULL, +}; + +static const struct attribute_group xdpe132g5c_sysfs_attrs_group = { + .attrs = xdpe132g5c_sysfs_attrs, +}; + +static int xdpe132g5c_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct xdpe_data *data; + int ret; + + WB_XDPE_VERBOSE("bus: %d, addr: 0x%02x do probe.\n", client->adapter->nr, client->addr); + data = devm_kzalloc(&client->dev, sizeof(struct xdpe_data), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + ret = sysfs_create_group(&client->dev.kobj, &xdpe132g5c_sysfs_attrs_group); + if (ret != 0) { + dev_err(&client->dev, "Create xdpe132g5c sysfs failed, ret: %d\n", ret); + return ret; + } + data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, + xdpe_hwmon_groups); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &xdpe132g5c_sysfs_attrs_group); + dev_err(&client->dev, "Failed to register xdpe hwmon device, ret: %d\n", ret); + return ret; + } + data->vout_max = WB_XDPE_VOUT_MAX_THRESHOLD; + data->vout_min = WB_XDPE_VOUT_MIN_THRESHOLD; + dev_info(&client->dev, "xdpe132g5c probe success\n"); + return 0; +} + +static int xdpe132g5c_remove(struct i2c_client *client) +{ + struct xdpe_data *data; + + WB_XDPE_VERBOSE("bus: %d, addr: 0x%02x do remove\n", client->adapter->nr, client->addr); + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &xdpe132g5c_sysfs_attrs_group); + return 0; +} + +static const struct i2c_device_id xdpe132g5c_id[] = { + {"wb_xdpe132g5c", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, xdpe132g5c_id); + +static const struct of_device_id __maybe_unused xdpe132g5c_of_match[] = { + {.compatible = "infineon,wb_xdpe132g5c"}, + {} +}; +MODULE_DEVICE_TABLE(of, xdpe132g5c_of_match); + +static struct i2c_driver wb_xdpe132g5c_driver = { + .driver = { + .name = "wb_xdpe132g5c", + .of_match_table = of_match_ptr(xdpe132g5c_of_match), + }, + .probe = xdpe132g5c_probe, + .remove = xdpe132g5c_remove, + .id_table = xdpe132g5c_id, +}; + +module_i2c_driver(wb_xdpe132g5c_driver); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("I2C driver for Infineon XDPE132 family"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/auto_update.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/auto_update.py new file mode 100755 index 000000000000..838e64f6b417 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/auto_update.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python3 + +try: + import os + import json + import logging + import sys + from sonic_py_common import device_info + from sonic_platform.platform import Platform +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + +PLATFORM_COMPONENTS_FILE = "platform_components.json" +CHASSIS_KEY = "chassis" +COMPONENT_KEY = "component" +FIRMWARE_KEY = "firmware" +VERSION_KEY = "version" +chassis_component_map = {} +current_chassis_component_map = {} +current_chassis = Platform().get_chassis() + + +def parse_component_section(section, component): + if not isinstance(component, dict): + logging.error("dictionary is expected: key=%s", COMPONENT_KEY) + return False + + if not component: + return False + + missing_key = None + chassis_component_map[section] = {} + + for key1, value1 in component.items(): + if not isinstance(value1, dict): + logging.error("dictionary is expected: key=%s", key1) + return False + + if value1: + if len(value1) < 1 or len(value1) > 3: + logging.error("unexpected number of records: key=%s", key1) + return False + + if FIRMWARE_KEY not in value1: + missing_key = FIRMWARE_KEY + break + + for key2, value2 in value1.items(): + if not isinstance(value2, str): + logging.error("string is expected: key=%s", key2) + return False + + chassis_component_map[section][key1] = value1 + + if missing_key is not None: + logging.error("\"%s\" key hasn't been found", missing_key) + return False + + return True + + +def parse_chassis_section(chassis): + if not isinstance(chassis, dict): + logging.error("dictionary is expected: key=%s", CHASSIS_KEY) + return False + + if not chassis: + logging.error("dictionary is empty: key=%s", CHASSIS_KEY) + return False + + if len(chassis) != 1: + logging.error("unexpected number of records: key=%s", CHASSIS_KEY) + return False + + for key, value in chassis.items(): + if not isinstance(value, dict): + logging.error("dictionary is expected: key=%s", key) + return False + + if not value: + logging.error("dictionary is empty: key=%s", key) + return False + + if COMPONENT_KEY not in value: + logging.error("\"%s\" key hasn't been found", COMPONENT_KEY) + return False + + if len(value) != 1: + logging.error("unexpected number of records: key=%s", key) + return False + + return parse_component_section(key, value[COMPONENT_KEY]) + + return False + + +def get_platform_components_path(): + PLATFORM_COMPONENTS_PATH_TEMPLATE = "/usr/share/sonic/device/{}/{}" + PLATFORM_COMPONENTS_FILE_PATH = PLATFORM_COMPONENTS_PATH_TEMPLATE.format( + device_info.get_platform(), PLATFORM_COMPONENTS_FILE) + return PLATFORM_COMPONENTS_FILE_PATH + + +def parse_platform_components(): + platform_components_path = get_platform_components_path() + with open(platform_components_path) as platform_components: + data = json.load(platform_components) + + if not isinstance(data, dict): + logging.error("dictionary is expected: key=root") + return False + + if not data: + logging.error("dictionary is empty: key=root") + return False + + if CHASSIS_KEY not in data: + logging.error("\"%s\" key hasn't been found", CHASSIS_KEY) + return False + + return parse_chassis_section(data[CHASSIS_KEY]) + + +def get_current_chassis_component_map(): + chassis_name = current_chassis.get_name() + current_chassis_component_map[chassis_name] = {} + + component_list = current_chassis.get_all_components() + for component in component_list: + component_name = component.get_name() + current_chassis_component_map[chassis_name][component_name] = component + + return current_chassis_component_map + + +def get_upgrade_dict(): + upgrade_dict = {} + firmware_version_current = "" + firmware_version_available = "" + + if not parse_platform_components(): + logging.error("Reading platform_components.json i, ion exception") + sys.exit(1) + + if not get_current_chassis_component_map(): + logging.error("Reading firmware i, ion from the driver is abnormal") + sys.exit(1) + + chassis_name = current_chassis.get_name() + diff_keys = set(chassis_component_map.keys()) ^ set(current_chassis_component_map.keys()) + if diff_keys: + logging.error("%s names mismatch: keys=%s", chassis_name, str(list(diff_keys))) + return None + + for chassis_name, component_map in current_chassis_component_map.items(): + for component_name, component in component_map.items(): + firmware_version_current = component.get_firmware_version() + if component_name in chassis_component_map[chassis_name]: + firmware_version_available = chassis_component_map[chassis_name][component_name][VERSION_KEY] + else: + logging.warning("can't find %s in %s", component_name, PLATFORM_COMPONENTS_FILE) + break + + if not os.path.exists(chassis_component_map[chassis_name][component_name][FIRMWARE_KEY]): + logging.error("%s does not exist", chassis_component_map[chassis_name][component_name][FIRMWARE_KEY]) + break + + if firmware_version_available != firmware_version_current: + upgrade_dict[component_name] = chassis_component_map[chassis_name][component_name][FIRMWARE_KEY] + + return upgrade_dict + + +def auto_upgrade(): + upgrade_result_dict = {} + chassis_name = current_chassis.get_name() + + upgrade_dict = get_upgrade_dict() + if not upgrade_dict: + logging.info("No firmware found for automatic upgrade") + return None + + component_map = current_chassis_component_map[chassis_name] + for value, path in upgrade_dict.items(): + status = component_map[value].install_firmware(path) + if status: + upgrade_result_dict[value] = "success" + logging.info("%s Upgrade Success", value) + else: + upgrade_result_dict[value] = "failed" + logging.error("%s Upgrade Failed", value) + return upgrade_result_dict + + +if __name__ == '__main__': + auto_upgrade() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/avscontrol.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/avscontrol.py index 25874ddb8219..a0a2ccaac938 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/common/script/avscontrol.py +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/avscontrol.py @@ -1,18 +1,22 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- -import click +import sys +import os import time -import traceback -from ragileutil import wait_docker, STARTMODULE, AVSUTIL -from rgutil.logutil import Logger +import syslog +import glob +import click +from platform_config import MAC_DEFAULT_PARAM +from platform_util import getSdkReg, write_sysfs, get_value, get_format_value + + +AVSCTROL_DEBUG_FILE = "/etc/.avscontrol_debug_flag" -try: - from rest.rest import BMCMessage -except ImportError: - pass +AVSCTROLERROR = 1 +AVSCTROLDEBUG = 2 -CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) -logger = Logger("AVSCONTROL", syslog=True) +debuglevel = 0 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} class AliasedGroup(click.Group): @@ -20,72 +24,180 @@ def get_command(self, ctx, cmd_name): rv = click.Group.get_command(self, ctx, cmd_name) if rv is not None: return rv - matches = [x for x in self.list_commands(ctx) if x.startswith(cmd_name)] + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] if not matches: return None - elif len(matches) == 1: + if len(matches) == 1: return click.Group.get_command(self, ctx, matches[0]) - ctx.fail("Too many matches: %s" % ", ".join(sorted(matches))) - - -def do_avs_ctrl(): - index = 0 - url = "/xyz/openbmc_project/hostchannel/attr/MacRov" - while True: - if ( - "avscontrol_restful" in STARTMODULE - and STARTMODULE["avscontrol_restful"] == 1 - ): - try: - # for alibmc rest.py has define get_macrov_value function - get_macrov_value = getattr(BMCMessage(), "get_macrov_value", None) - if callable(get_macrov_value): - macrov_value = int(get_macrov_value()) - else: - macrov_value = int(BMCMessage().getBmcValue(url)) - if macrov_value >= 0: - break - except Exception as e: - time.sleep(2) - continue + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def avscontrol_debug(s): + if AVSCTROLDEBUG & debuglevel: + syslog.openlog("AVSCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def avscontrol_error(s): + if AVSCTROLERROR & debuglevel: + syslog.openlog("AVSCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def avserror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("AVSCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def avsinfo(s): + syslog.openlog("AVSCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_INFO, s) + + +def debug_init(): + global debuglevel + if os.path.exists(AVSCTROL_DEBUG_FILE): + debuglevel = debuglevel | AVSCTROLDEBUG | AVSCTROLERROR + else: + debuglevel = debuglevel & ~(AVSCTROLDEBUG | AVSCTROLERROR) + + +def set_avs_value_sysfs(conf, dcdc_value): + msg = "" + formula = conf.get("formula", None) + loc = conf.get("loc") + locations = glob.glob(loc) + if len(locations) == 0: + msg = "avs sysfs loc: %s not found" % loc + avscontrol_error(msg) + return False, msg + sysfs_loc = locations[0] + avscontrol_debug("set_avs_value_sysfs, loc: %s, origin dcdc value: %s, formula: %s" % + (sysfs_loc, dcdc_value, formula)) + if formula is not None: + dcdc_value = get_format_value(formula % (dcdc_value)) + wr_val = str(dcdc_value) + avscontrol_debug("set_avs_value_sysfs, write val: %s" % wr_val) + ret, log = write_sysfs(sysfs_loc, wr_val) + if ret is False: + msg = "set_avs_value_sysfs failed, msg: %s" % log + avscontrol_error(msg) + return ret, msg + + +def set_avs_value(avs_conf, dcdc_value): + set_avs_way = avs_conf.get("set_avs", {}).get("gettype") + if set_avs_way != "sysfs": + msg = "unsupport set avs value type: %s" % set_avs_way + avscontrol_error(msg) + return False, msg + ret, msg = set_avs_value_sysfs(avs_conf["set_avs"], dcdc_value) + return ret, msg + + +def get_dcdc_value(avs_conf, rov_value): + msg = "" + mac_avs_param = avs_conf.get("mac_avs_param", {}) + if rov_value not in mac_avs_param.keys(): + if avs_conf["type"] == 0: + msg = "VID:0x%x out of range, voltage regulate stop" % rov_value + avsinfo(msg) + return False, msg + dcdc_value = mac_avs_param[avs_conf["default"]] + avsinfo("VID:0x%x out of range, use default VID:0x%x" % (rov_value, dcdc_value)) + else: + dcdc_value = mac_avs_param[rov_value] + return True, dcdc_value + + +def get_rov_value_cpld(avs_conf): + cpld_avs_config = avs_conf["cpld_avs"] + return get_value(cpld_avs_config) + + +def get_rov_value_sdk(avs_conf): + name = avs_conf["sdkreg"] + ret, status = getSdkReg(name) + if ret is False: + return False, status + status = int(status, 16) + # shift operation + if avs_conf["sdktype"] != 0: + status = (status >> avs_conf["macregloc"]) & avs_conf["mask"] + macavs = status + return True, macavs + + +def doAvsCtrol_single(avs_conf): + try: + avs_name = avs_conf.get("name") + rov_source = avs_conf["rov_source"] + if rov_source == 0: + ret, rov_value = get_rov_value_cpld(avs_conf) # get rov from cpld reg else: - if AVSUTIL.mac_adj(): - break + ret, rov_value = get_rov_value_sdk(avs_conf) # get rov from sdk reg + if ret is False: + msg = "%s get rov_value failed, msg: %s" % (avs_name, rov_value) + avscontrol_error(msg) + return False, msg + avscontrol_debug("%s rov_value: 0x%x" % (avs_name, rov_value)) + ret, dcdc_value = get_dcdc_value(avs_conf, rov_value) + if ret is False: + msg = "%s get output voltage value failed, msg: %s" % (avs_name, dcdc_value) + avscontrol_error(msg) + return False, msg + ret, msg = set_avs_value(avs_conf, dcdc_value) + return ret, msg + except Exception as e: + msg = "%s avscontrol raise exception, msg: %s" % (avs_name, str(e)) + avscontrol_error(msg) + return False, msg + + +def doAvsCtrol(avs_conf): + retry_time = avs_conf.get("retry", 10) + for i in range(retry_time): + debug_init() + ret, log = doAvsCtrol_single(avs_conf) + if ret is True: + return True, log + time.sleep(1) + return False, log - index += 1 - if index >= 10: - logger.error("%%DEV_MONITOR-AVS: MAC Voltage adjust failed.") - exit(-1) - logger.info("%%AVSCONTROL success") - exit(0) +def run(): + # wait 30s for device steady + time.sleep(30) + errcnt = 0 + msg = "" + for item in MAC_DEFAULT_PARAM: + status, log = doAvsCtrol(item) + if status is False: + errcnt += 1 + msg += log -def run(interval): - while True: - try: - if wait_docker(timeout=0) == True: - time.sleep(10) # w10s - do_avs_ctrl() - time.sleep(interval) - except Exception as e: - traceback.print_exc() - print(e) + if errcnt == 0: + avsinfo("%%AVSCONTROL success") + sys.exit(0) + avserror("%%DEV_MONITOR-AVS: MAC Voltage adjust failed.") + avserror("%%DEV_MONITOR-AVS: errmsg: %s" % msg) + sys.exit(1) @click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) def main(): - """device operator""" - pass + '''device operator''' @main.command() def start(): - """start AVS control""" - logger.info("%%AVSCONTROL start") - interval = 5 - run(interval) + '''start AVS control''' + avsinfo("%%AVSCONTROL start") + run() -##device_i2c operation -if __name__ == "__main__": +if __name__ == '__main__': main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/dev_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/dev_monitor.py new file mode 100755 index 000000000000..e13377b80fe9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/dev_monitor.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python3 +import sys +import os +import time +import syslog +import traceback +import click +from platform_config import DEV_MONITOR_PARAM +from platform_util import io_rd, wbi2cget + + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +DEVMONITOR_DEBUG_FILE = "/etc/.devmonitor_debug_flag" + +debuglevel = 0 + + +def debug_init(): + global debuglevel + if os.path.exists(DEVMONITOR_DEBUG_FILE): + debuglevel = 1 + else: + debuglevel = 0 + + +def devwarninglog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def devcriticallog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def deverror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def devinfo(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_INFO, s) + + +def devdebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if debuglevel == 1: + syslog.openlog("DEVMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +class DevMonitor(): + + def getpresentstatus(self, param): + try: + ret = {} + ret["status"] = '' + gettype = param.get('gettype') + presentbit = param.get('presentbit') + okval = param.get('okval') + if gettype == "io": + io_addr = param.get('io_addr') + val = io_rd(io_addr) + if val is None: + ret["status"] = "NOT OK" + return ret + retval = val + else: + bus = param.get('bus') + loc = param.get('loc') + offset = param.get('offset') + ind, val = wbi2cget(bus, loc, offset) + if ind is not True: + ret["status"] = "NOT OK" + return ret + retval = val + val_t = (int(retval, 16) & (1 << presentbit)) >> presentbit + if val_t != okval: + ret["status"] = "ABSENT" + else: + ret["status"] = "PRESENT" + except Exception as e: + ret["status"] = "NOT OK" + deverror("getpresentstatus error") + deverror(str(e)) + return ret + + def removeDev(self, bus, loc): + cmd = "echo 0x%02x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (loc, bus) + devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc) + if os.path.exists(devpath): + os.system(cmd) + + def addDev(self, name, bus, loc): + if name == "lm75": + time.sleep(0.1) + cmd = "echo %s 0x%02x > /sys/bus/i2c/devices/i2c-%d/new_device" % (name, loc, bus) + devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc) + if os.path.exists(devpath) is False: + os.system(cmd) + + def checkattr(self, bus, loc, attr): + try: + attrpath = "/sys/bus/i2c/devices/%d-%04x/%s" % (bus, loc, attr) + if os.path.exists(attrpath): + return True + except Exception as e: + deverror("checkattr error") + deverror(str(e)) + return False + + def monitor(self, ret): + totalerr = 0 + for item in ret: + try: + name = item.get('name') + itemattr = '%sattr' % name + val_t = getattr(DevMonitor, itemattr, None) + if val_t == 'OK': + continue + present = item.get('present', None) + devices = item.get('device') + err_t = 0 + for item_dev in devices: + item_devattr = '%s' % (item_dev['id']) + val_t = getattr(DevMonitor, item_devattr, None) + if val_t == 'OK': + continue + devname = item_dev.get('name') + bus = item_dev.get('bus') + loc = item_dev.get('loc') + attr = item_dev.get('attr') + if self.checkattr(bus, loc, attr) is False: + err_t -= 1 + setattr(DevMonitor, item_devattr, 'NOT OK') + if present is not None: + presentstatus = self.getpresentstatus(present) + devdebuglog("%s present status:%s" % (name, presentstatus.get('status'))) + if presentstatus.get('status') == 'PRESENT': + self.removeDev(bus, loc) + time.sleep(0.1) + self.addDev(devname, bus, loc) + else: + self.removeDev(bus, loc) + time.sleep(0.1) + self.addDev(devname, bus, loc) + else: + setattr(DevMonitor, item_devattr, 'OK') + val_t = getattr(DevMonitor, item_devattr, None) + devdebuglog("%s status %s" % (item_devattr, val_t)) + if err_t == 0: + setattr(DevMonitor, itemattr, 'OK') + else: + totalerr -= 1 + setattr(DevMonitor, itemattr, 'NOT OK') + val_t = getattr(DevMonitor, itemattr, None) + devdebuglog("%s status %s" % (itemattr, val_t)) + except Exception as e: + totalerr -= 1 + deverror("monitor error") + deverror(str(e)) + return totalerr + + def psusmonitor(self): + psus_conf = DEV_MONITOR_PARAM.get('psus') + if psus_conf is None: + return 0 + psusattr = 'psusattr' + val_t = getattr(DevMonitor, psusattr, None) + if val_t == 'OK': + return 0 + ret = self.monitor(psus_conf) + if ret == 0: + setattr(DevMonitor, psusattr, 'OK') + else: + setattr(DevMonitor, psusattr, 'NOT OK') + val_t = getattr(DevMonitor, psusattr, None) + devdebuglog("psusattr:value:%s" % (val_t)) + return ret + + def fansmonitor(self): + fans_conf = DEV_MONITOR_PARAM.get('fans') + if fans_conf is None: + return 0 + fansattr = 'fansattr' + val_t = getattr(DevMonitor, fansattr, None) + if val_t == 'OK': + return 0 + ret = self.monitor(fans_conf) + if ret == 0: + setattr(DevMonitor, fansattr, 'OK') + else: + setattr(DevMonitor, fansattr, 'NOT OK') + val_t = getattr(DevMonitor, fansattr, None) + devdebuglog("fansattr:value:%s" % (val_t)) + return ret + + def slotsmonitor(self): + slots_conf = DEV_MONITOR_PARAM.get('slots') + if slots_conf is None: + return 0 + slotsattr = 'slotsattr' + val_t = getattr(DevMonitor, slotsattr, None) + if val_t == 'OK': + return 0 + ret = self.monitor(slots_conf) + if ret == 0: + setattr(DevMonitor, slotsattr, 'OK') + else: + setattr(DevMonitor, slotsattr, 'NOT OK') + val_t = getattr(DevMonitor, slotsattr, None) + devdebuglog("slotsattr:value:%s" % (val_t)) + return ret + + def othersmonitor(self): + others_conf = DEV_MONITOR_PARAM.get('others') + if others_conf is None: + return 0 + othersattr = 'othersattr' + val_t = getattr(DevMonitor, othersattr, None) + if val_t == 'OK': + return 0 + ret = self.monitor(others_conf) + if ret == 0: + setattr(DevMonitor, othersattr, 'OK') + else: + setattr(DevMonitor, othersattr, 'NOT OK') + val_t = getattr(DevMonitor, othersattr, None) + devdebuglog("othersattr:value:%s" % (val_t)) + return ret + + +def doDevMonitor(devMonitor): + ret_t = 0 + ret_t += devMonitor.psusmonitor() + ret_t += devMonitor.fansmonitor() + ret_t += devMonitor.slotsmonitor() + ret_t += devMonitor.othersmonitor() + return ret_t + + +def run(interval, devMonitor): + # devMonitor.devattrinit() + while True: + try: + debug_init() + ret = doDevMonitor(devMonitor) + except Exception as e: + traceback.print_exc() + deverror(str(e)) + ret = -1 + if ret == 0: + time.sleep(5) + devinfo("dev_monitor finished!") + sys.exit(0) + time.sleep(interval) + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''device operator''' + + +@main.command() +def start(): + '''start device monitor''' + devinfo("dev_monitor start") + devMonitor = DevMonitor() + interval = DEV_MONITOR_PARAM.get('polling_time', 10) + run(interval, devMonitor) + + +@main.command() +def stop(): + '''stop device monitor ''' + devinfo("stop") + + +# device_i2c operation +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/device_i2c.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/device_i2c.py deleted file mode 100755 index cca9f0393db7..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/script/device_i2c.py +++ /dev/null @@ -1,345 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: UTF-8 -*- - -import click -import os -import time -from ragileconfig import GLOBALCONFIG, GLOBALINITPARAM, GLOBALINITCOMMAND, MAC_LED_RESET, STARTMODULE, i2ccheck_params -from ragileutil import rgpciwr, os_system, rgi2cset, io_wr - -CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help']) - -class AliasedGroup(click.Group): - def get_command(self, ctx, cmd_name): - rv = click.Group.get_command(self, ctx, cmd_name) - if rv is not None: - return rv - matches = [x for x in self.list_commands(ctx) - if x.startswith(cmd_name)] - if not matches: - return None - elif len(matches) == 1: - return click.Group.get_command(self, ctx, matches[0]) - ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) - -def log_os_system(cmd): - u'''execute shell command''' - status, output = os_system(cmd) - if status: - print(output) - return status, output - -def write_sysfs_value(reg_name, value): - u'''write sysfs file''' - mb_reg_file = "/sys/bus/i2c/devices/" + reg_name - if (not os.path.isfile(mb_reg_file)): - print(mb_reg_file, 'not found !') - return False - try: - with open(mb_reg_file, 'w') as fd: - fd.write(value) - except Exception as error: - return False - return True - -def check_driver(): - u'''whether there is driver start with rg''' - status, output = log_os_system("lsmod | grep rg | wc -l") - #System execution error - if status: - return False - if output.isdigit() and int(output) > 0: - return True - else: - return False - -def get_pid(name): - ret = [] - for dirname in os.listdir('/proc'): - if dirname == 'curproc': - continue - try: - with open('/proc/{}/cmdline'.format(dirname), mode='r') as fd: - content = fd.read() - except Exception: - continue - if name in content: - ret.append(dirname) - return ret - -def start_avs_ctrl(): - cmd = "nohup avscontrol.py start >/dev/null 2>&1 &" - rets = get_pid("avscontrol.py") - if len(rets) == 0: - os.system(cmd) - -def start_fan_ctrl(): - if STARTMODULE['fancontrol'] == 1: - cmd = "nohup fancontrol.py start >/dev/null 2>&1 &" - rets = get_pid("fancontrol.py") - if len(rets) == 0: - os.system(cmd) - -def starthal_fanctrl(): - if STARTMODULE.get('hal_fanctrl',0) == 1: - cmd = "nohup hal_fanctrl.py start >/dev/null 2>&1 &" - rets = get_pid("hal_fanctrl.py") - if len(rets) == 0: - os.system(cmd) - -def starthal_ledctrl(): - if STARTMODULE.get('hal_ledctrl',0) == 1: - cmd = "nohup hal_ledctrl.py start >/dev/null 2>&1 &" - rets = get_pid("hal_ledctrl.py") - if len(rets) == 0: - os.system(cmd) - -def start_dev_monitor(): - if STARTMODULE.get('dev_monitor',0) == 1: - cmd = "nohup dev_monitor.py start >/dev/null 2>&1 &" - rets = get_pid("dev_monitor.py") - if len(rets) == 0: - os.system(cmd) - -def start_slot_monitor(): - if STARTMODULE.get('slot_monitor',0) == 1: - cmd = "nohup slot_monitor.py start >/dev/null 2>&1 &" - rets = get_pid("slot_monitor.py") - if len(rets) == 0: - os.system(cmd) - -def stop_fan_ctrl(): - u'''disable fan timer service''' - if STARTMODULE['fancontrol'] == 1: - rets = get_pid("fancontrol.py") # - for ret in rets: - cmd = "kill "+ ret - os.system(cmd) - return True - -def stophal_ledctrl(): - if STARTMODULE.get('hal_ledctrl',0) == 1: - rets = get_pid("hal_ledctrl.py") - for ret in rets: - cmd = "kill "+ ret - os.system(cmd) - return True - - -def stop_dev_monitor(): - u'''disable the fan timer service''' - if STARTMODULE.get('dev_monitor',0) == 1: - rets = get_pid("dev_monitor.py") # - for ret in rets: - cmd = "kill "+ ret - os.system(cmd) - return True - -def stop_slot_monitor(): - u'''disable slot timer service''' - if STARTMODULE.get('slot_monitor',0) == 1: - rets = get_pid("slot_monitor.py") # - for ret in rets: - cmd = "kill "+ ret - os.system(cmd) - return True - -def rm_dev(bus, loc): - cmd = "echo 0x%02x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (loc, bus) - devpath = "/sys/bus/i2c/devices/%d-%04x"%(bus, loc) - if os.path.exists(devpath): - log_os_system(cmd) - -def add_dev(name, bus, loc): - if name == "lm75": - time.sleep(0.1) - pdevpath = "/sys/bus/i2c/devices/i2c-%d/" % (bus) - for i in range(1, 100):#wait for mother-bus generation,maximum wait time is 10s - if os.path.exists(pdevpath) == True: - break - time.sleep(0.1) - if i % 10 == 0: - click.echo("%%DEVICE_I2C-INIT: %s not found, wait 0.1 second ! i %d " % (pdevpath,i)) - - cmd = "echo %s 0x%02x > /sys/bus/i2c/devices/i2c-%d/new_device" % (name, loc, bus) - devpath = "/sys/bus/i2c/devices/%d-%04x"%(bus, loc) - if os.path.exists(devpath) == False: - os.system(cmd) - -def removedevs(): - devs = GLOBALCONFIG["DEVS"] - for index in range(len(devs)-1, -1, -1 ): - rm_dev(devs[index]["bus"] , devs[index]["loc"]) - -def adddevs(): - devs = GLOBALCONFIG["DEVS"] - for dev in range(0, devs.__len__()): - add_dev(devs[dev]["name"], devs[dev]["bus"] , devs[dev]["loc"]) - -def checksignaldriver(name): - modisexistcmd = "lsmod | grep %s | wc -l" % name - status, output = log_os_system(modisexistcmd) - #System execution error - if status: - return False - if output.isdigit() and int(output) > 0: - return True - else: - return False - -def adddriver(name, delay): - cmd = "modprobe %s" % name - if delay != 0: - time.sleep(delay) - if checksignaldriver(name) != True: - log_os_system(cmd) - -def removedriver(name, delay): - realname = name.lstrip().split(" ")[0]; - cmd = "rmmod -f %s" % realname - if checksignaldriver(realname): - log_os_system(cmd) - -def removedrivers(): - u'''remove all drivers''' - if GLOBALCONFIG is None: - click.echo("%%DEVICE_I2C-INIT: load global config failed.") - return - drivers = GLOBALCONFIG.get("DRIVERLISTS", None) - if drivers is None: - click.echo("%%DEVICE_I2C-INIT: load driver list failed.") - return - for index in range(len(drivers)-1, -1, -1 ): - delay = 0 - name = "" - if type(drivers[index]) == dict and "delay" in drivers[index]: - name = drivers[index].get("name") - delay = drivers[index]["delay"] - else: - name = drivers[index] - removedriver(name, delay) - -def adddrivers(): - u'''add drivers''' - if GLOBALCONFIG is None: - click.echo("%%DEVICE_I2C-INIT: load global config failed.") - return - drivers = GLOBALCONFIG.get("DRIVERLISTS", None) - if drivers is None: - click.echo("%%DEVICE_I2C-INIT: load driver list failed.") - return - for index in range(0 ,len(drivers)): - delay = 0 - name = "" - if type(drivers[index]) == dict and "delay" in drivers[index]: - name = drivers[index].get("name") - delay = drivers[index]["delay"] - else: - name = drivers[index] - adddriver(name, delay) - -def otherinit(): - for index in GLOBALINITPARAM: - index_type = index.get("type", None) - if index_type == "io": - ret = io_wr(index.get("offset"), index.get("val")) - else: - ret, _ = rgi2cset( - index.get("bus"), - index.get("devaddr"), - index.get("offset"), - index.get("val") - ) - if not ret: - click.echo("%%DEVICE_I2C-INIT: init param %s failed." % index.get("name")) - - for index in GLOBALINITCOMMAND: - log_os_system(index) - -def unload_driver(): - u'''remove devices and drivers''' - stop_dev_monitor() # disable removable device driver monitors - stop_fan_ctrl() # disable fan-control service - removedevs() # remove other devices - removedrivers() # remove drivers - -def reload_driver(): - u'''reload devices and drivers''' - removedevs() # remove other devices - removedrivers() # remove drivers - time.sleep(1) - adddrivers() - adddevs() - - -def i2c_check(bus,retrytime = 6): - try: - i2cpath = "/sys/bus/i2c/devices/" + bus - while retrytime and not os.path.exists(i2cpath): - click.echo("%%DEVICE_I2C-HA: i2c bus abnormal, last bus %s is not exist." % i2cpath) - reload_driver() - retrytime -= 1 - time.sleep(1) - except Exception as e: - click.echo("%%DEVICE_I2C-HA: %s" % str(e)) - return - -def set_mac_leds(data): - '''write pci register''' - pcibus = MAC_LED_RESET.get("pcibus") - slot = MAC_LED_RESET.get("slot") - fn = MAC_LED_RESET.get("fn") - bar = MAC_LED_RESET.get("bar") - offset = MAC_LED_RESET.get("offset") - val = MAC_LED_RESET.get(data, None) - if val is None: - click.echo("%%DEVICE_I2C-INIT: set_mac_leds wrong input") - return - rgpciwr(pcibus, slot, fn, bar, offset, val) - -def load_driver(): - u'''load devices and drivers''' - adddrivers() - adddevs() - if STARTMODULE.get("i2ccheck",0) == 1: #i2c HA - busend = i2ccheck_params.get("busend") - retrytime = i2ccheck_params.get("retrytime") - i2c_check(busend,retrytime) - start_fan_ctrl() # enable fan - starthal_fanctrl() # enable fan control - starthal_ledctrl() # enable LED control - if STARTMODULE['avscontrol'] == 1: - start_avs_ctrl() # avs voltage-adjustment - start_dev_monitor() # enable removable device driver monitors - start_slot_monitor() # slot insertion and removal initialization monitor - otherinit(); # other initialization, QSFP initialization - if STARTMODULE.get("macledreset", 0) == 1: - set_mac_leds("reset") - -@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) -def main(): - '''device operator''' - pass - - -@main.command() -def start(): - '''load device ''' - if check_driver(): - unload_driver() - load_driver() - -@main.command() -def stop(): - '''stop device ''' - unload_driver() - -@main.command() -def restart(): - '''restart device''' - unload_driver() - load_driver() - -if __name__ == '__main__': - u'''device_i2c operation''' - main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/fancontrol.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/fancontrol.py deleted file mode 100755 index 19214b30408e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/script/fancontrol.py +++ /dev/null @@ -1,993 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: UTF-8 -*- -import click -import os -import time -import traceback -import glob -from rgutil.logutil import Logger -from ragileutil import wait_docker - -from ragileconfig import ( - MONITOR_CONST, - FANCTROLDEBUG, - MONITOR_FANS_LED, - DEV_LEDS, - MONITOR_PSU_STATUS, - MONITOR_SYS_PSU_LED, - MONITOR_DEV_STATUS, - MONITOR_FAN_STATUS, - MONITOR_DEV_STATUS_DECODE, - MONITOR_SYS_FAN_LED, - MONITOR_SYS_LED, - fanloc, -) - -from ragileutil import ( - rgi2cget, - get_mac_temp_sysfs, - get_mac_temp, - write_sysfs_value, - get_sysfs_value, - strtoint, - rgi2cset, - io_rd, - rgsysset, -) - - -CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) - -DEBUG_COMMON = 0x01 -DEBUG_LEDCONTROL = 0x02 -DEBUG_FANCONTROL = 0x04 - -LOG_PREFIX = "FANCONTROL" -logger = Logger(LOG_PREFIX, syslog=True, dbg_mask=FANCTROLDEBUG) - - -class AliasedGroup(click.Group): - def get_command(self, ctx, cmd_name): - rv = click.Group.get_command(self, ctx, cmd_name) - if rv is not None: - return rv - matches = [x for x in self.list_commands(ctx) if x.startswith(cmd_name)] - if not matches: - return None - elif len(matches) == 1: - return click.Group.get_command(self, ctx, matches[0]) - ctx.fail("Too many matches: %s" % ", ".join(sorted(matches))) - - -class FanControl(object): - critnum = 0 - - def __init__(self): - self._normal_fans = 0 - self._normal_psus = 0 - self._intemp = -100.0 - self._mac_aver = -100.0 - self._mac_max = -100.0 - # previous temperature - self._pre_intemp = -100 - self._outtemp = -100 - self._boardtemp = -100 - self._cputemp = -1000 - - @property - def normal_fans(self): - return self._normal_fans - - @property - def normal_psus(self): - return self._normal_psus - - @property - def cputemp(self): - return self._cputemp - - @property - def intemp(self): - return self._intemp - - @property - def outtemp(self): - return self._outtemp - - @property - def boardtemp(self): - return self._boardtemp - - @property - def mac_aver(self): - return self._mac_aver - - @property - def preIntemp(self): - return self._pre_intemp - - @property - def mac_max(self): - return self._mac_max - - def sortCallback(self, element): - return element["id"] - - def gettemp(self, ret): - u"""get inlet, outlet, hot-point and cpu temperature""" - temp_conf = MONITOR_DEV_STATUS.get("temperature", None) - - if temp_conf is None: - logger.error("gettemp: config error") - return False - for item_temp in temp_conf: - try: - retval = "" - rval = None - name = item_temp.get("name") - location = item_temp.get("location") - if name == "cpu": - L = [] - for dirpath, dirnames, filenames in os.walk(location): - for file in filenames: - if file.endswith("input"): - L.append(os.path.join(dirpath, file)) - L = sorted(L, reverse=False) - for i in range(len(L)): - nameloc = "%s/temp%d_label" % (location, i + 1) - valloc = "%s/temp%d_input" % (location, i + 1) - with open(nameloc, "r") as fd1: - retval2 = fd1.read() - with open(valloc, "r") as fd2: - retval3 = fd2.read() - ret_t = {} - ret_t["name"] = retval2.strip() - ret_t["value"] = float(retval3) / 1000 - ret.append(ret_t) - logger.debug( - DEBUG_COMMON, - "gettemp %s : %f" % (ret_t["name"], ret_t["value"]), - ) - else: - locations = glob.glob(location) - with open(locations[0], "r") as fd1: - retval = fd1.read() - rval = float(retval) / 1000 - ret_t = {} - ret_t["name"] = name - ret_t["value"] = rval - ret.append(ret_t) - logger.debug( - DEBUG_COMMON, - "gettemp %s : %f" % (ret_t["name"], ret_t["value"]), - ) - except Exception as e: - logger.error("gettemp error:name:%s" % name) - logger.error(str(e)) - return True - - def checkslot(self, ret): - u"""get slot present status""" - slots_conf = MONITOR_DEV_STATUS.get("slots", None) - slotpresent = MONITOR_DEV_STATUS_DECODE.get("slotpresent", None) - - if slots_conf is None or slotpresent is None: - return False - for item_slot in slots_conf: - totalerr = 0 - try: - ret_t = {} - ret_t["id"] = item_slot.get("name") - ret_t["status"] = "" - gettype = item_slot.get("gettype") - presentbit = item_slot.get("presentbit") - if gettype == "io": - io_addr = item_slot.get("io_addr") - val = io_rd(io_addr) - if val is not None: - retval = val - else: - totalerr -= 1 - logger.error( - " %s %s" % (item_slot.get("name"), "lpc read failed"), - ) - else: - bus = item_slot.get("bus") - loc = item_slot.get("loc") - offset = item_slot.get("offset") - ind, val = rgi2cget(bus, loc, offset) - if ind == True: - retval = val - else: - totalerr -= 1 - logger.error( - " %s %s" % (item_slot.get("name"), "i2c read failed"), - ) - if totalerr < 0: - ret_t["status"] = "NOT OK" - ret.append(ret_t) - continue - val_t = (int(retval, 16) & (1 << presentbit)) >> presentbit - logger.debug( - DEBUG_COMMON, - "%s present:%s" % (item_slot.get("name"), slotpresent.get(val_t)), - ) - if val_t != slotpresent.get("okval"): - ret_t["status"] = "ABSENT" - else: - ret_t["status"] = "PRESENT" - except Exception as e: - ret_t["status"] = "NOT OK" - totalerr -= 1 - logger.error("checkslot error") - logger.error(str(e)) - ret.append(ret_t) - return True - - def checkpsu(self, ret): - u"""get psu status present, output and warning""" - psus_conf = MONITOR_DEV_STATUS.get("psus", None) - psupresent = MONITOR_DEV_STATUS_DECODE.get("psupresent", None) - psuoutput = MONITOR_DEV_STATUS_DECODE.get("psuoutput", None) - psualert = MONITOR_DEV_STATUS_DECODE.get("psualert", None) - - if psus_conf is None or psupresent is None or psuoutput is None: - logger.error("checkpsu: config error") - return False - for item_psu in psus_conf: - totalerr = 0 - try: - ret_t = {} - ret_t["id"] = item_psu.get("name") - ret_t["status"] = "" - gettype = item_psu.get("gettype") - presentbit = item_psu.get("presentbit") - statusbit = item_psu.get("statusbit") - alertbit = item_psu.get("alertbit") - if gettype == "io": - io_addr = item_psu.get("io_addr") - val = io_rd(io_addr) - if val is not None: - retval = val - else: - totalerr -= 1 - logger.error( - " %s %s" % (item_psu.get("name"), "lpc read failed"), - ) - else: - bus = item_psu.get("bus") - loc = item_psu.get("loc") - offset = item_psu.get("offset") - ind, val = rgi2cget(bus, loc, offset) - if ind == True: - retval = val - else: - totalerr -= 1 - logger.error( - " %s %s" % (item_psu.get("name"), "i2c read failed"), - ) - if totalerr < 0: - ret_t["status"] = "NOT OK" - ret.append(ret_t) - continue - val_t = (int(retval, 16) & (1 << presentbit)) >> presentbit - val_status = (int(retval, 16) & (1 << statusbit)) >> statusbit - val_alert = (int(retval, 16) & (1 << alertbit)) >> alertbit - logger.debug( - DEBUG_COMMON, - "%s present:%s output:%s alert:%s" - % ( - item_psu.get("name"), - psupresent.get(val_t), - psuoutput.get(val_status), - psualert.get(val_alert), - ), - ) - if ( - val_t != psupresent.get("okval") - or val_status != psuoutput.get("okval") - or val_alert != psualert.get("okval") - ): - totalerr -= 1 - except Exception as e: - totalerr -= 1 - logger.error("checkpsu error") - logger.error(str(e)) - if totalerr < 0: - ret_t["status"] = "NOT OK" - else: - ret_t["status"] = "OK" - ret.append(ret_t) - return True - - def checkfan(self, ret): - u"""get fan status present and roll""" - fans_conf = MONITOR_DEV_STATUS.get("fans", None) - fanpresent = MONITOR_DEV_STATUS_DECODE.get("fanpresent", None) - fanroll = MONITOR_DEV_STATUS_DECODE.get("fanroll", None) - - if fans_conf is None or fanpresent is None or fanroll is None: - logger.error("checkfan: config error") - return False - for item_fan in fans_conf: - totalerr = 0 - try: - ret_t = {} - ret_t["id"] = item_fan.get("name") - ret_t["status"] = "" - presentstatus = item_fan.get("presentstatus") - presentbus = presentstatus.get("bus") - presentloc = presentstatus.get("loc") - presentaddr = presentstatus.get("offset") - presentbit = presentstatus.get("bit") - ind, val = rgi2cget(presentbus, presentloc, presentaddr) - if ind == True: - val_t = (int(val, 16) & (1 << presentbit)) >> presentbit - logger.debug( - DEBUG_COMMON, - "checkfan:%s present status:%s" - % (item_fan.get("name"), fanpresent.get(val_t)), - ) - if val_t != fanpresent.get("okval"): - ret_t["status"] = "ABSENT" - ret.append(ret_t) - continue - else: - logger.error( - "checkfan: %s get present status error." % item_fan.get("name"), - ) - motors = item_fan.get("rollstatus") - for motor in motors: - statusbus = motor.get("bus", None) - statusloc = motor.get("loc", None) - statusaddr = motor.get("offset", None) - statusbit = motor.get("bit", None) - ind, val = rgi2cget(statusbus, statusloc, statusaddr) - if ind == True: - val_t = (int(val, 16) & (1 << statusbit)) >> statusbit - logger.debug( - DEBUG_COMMON, - "checkfan:%s roll status:%s" - % (motor.get("name"), fanroll.get(val_t)), - ) - if val_t != fanroll.get("okval"): - totalerr -= 1 - else: - totalerr -= 1 - logger.error("checkfan: %s " % item_fan.get("name")) - logger.error("get %s status error." % motor["name"]) - except Exception as e: - totalerr -= 1 - logger.error("checkfan error") - logger.error(str(e)) - if totalerr < 0: - ret_t["status"] = "NOT OK" - else: - ret_t["status"] = "OK" - ret.append(ret_t) - return True - - def get_curr_speed(self): - try: - loc = fanloc[0].get("location", "") - sped = get_sysfs_value(loc) - value = strtoint(sped) - return value - except Exception as e: - logger.error("%%policy: get current speedlevel error") - logger.error(str(e)) - return None - - # guarantee the speed is lowest when speed lower than lowest value after speed-adjustment - def check_curr_speed(self): - logger.debug( - DEBUG_FANCONTROL, - "%%policy: guarantee the lowest speed after speed-adjustment", - ) - value = self.get_curr_speed() - if value is None or value == 0: - raise Exception("%%policy: get_curr_speed None") - elif value < MONITOR_CONST.MIN_SPEED: - self.set_fan_speed(MONITOR_CONST.MIN_SPEED) - - def set_fan_speed(self, level): - if level >= MONITOR_CONST.MAX_SPEED: - level = MONITOR_CONST.MAX_SPEED - for item in fanloc: - try: - loc = item.get("location", "") - # write_sysfs_value(loc, "0x%02x" % level) - # pddf support dicimal number - write_sysfs_value(loc, "%d" % level) - except Exception as e: - logger.error(str(e)) - logger.error("%%policy: config fan runlevel error") - self.check_curr_speed() # guaranteed minimum - - def set_fan_max_speed(self): - try: - self.set_fan_speed(MONITOR_CONST.MAX_SPEED) - except Exception as e: - logger.error("%%policy:set_fan_max_speed failed") - logger.error(str(e)) - - def detect_fan_status(self): - """ - fan status check , max speed if fan error - """ - if self.normal_fans < MONITOR_CONST.FAN_TOTAL_NUM: - logger.warn( - "%%DEV_MONITOR-FAN: Normal fan number: %d" % (self.normal_fans), - ) - self.set_fan_max_speed() - return False - return True - - def set_fan_attr(self, val): - u"""set status of each fan""" - for item in val: - fanid = item.get("id") - fanattr = fanid + "status" - fanstatus = item.get("status") - setattr(FanControl, fanattr, fanstatus) - logger.debug( - DEBUG_COMMON, "fanattr:%s,fanstatus:%s" % (fanattr, fanstatus), - ) - - def fan_present_num(self, cur_fan_status): - fanoknum = 0 - for item in cur_fan_status: - if item["status"] == "OK": - fanoknum += 1 - self._normal_fans = fanoknum - logger.debug(DEBUG_COMMON, "normal_fans = %d" % self._normal_fans) - - def get_fan_status(self): - try: - cur_fan_status = [] - ret = self.checkfan(cur_fan_status) - if ret == True: - self.set_fan_attr(cur_fan_status) - self.fan_present_num(cur_fan_status) - logger.debug(DEBUG_COMMON, "%%policy:get_fan_status success") - return 0 - except AttributeError as e: - logger.error(str(e)) - except Exception as e: - logger.error(str(e)) - return -1 - - def normal_psu_num(self, curPsuStatus): - psuoknum = 0 - for item in curPsuStatus: - if item.get("status") == "OK": - psuoknum += 1 - self._normal_psus = psuoknum - logger.debug(DEBUG_COMMON, "normal_psus = %d" % self._normal_psus) - - def get_psu_status(self): - try: - curPsuStatus = [] - ret = self.checkpsu(curPsuStatus) - if ret == True: - self.normal_psu_num(curPsuStatus) - logger.debug(DEBUG_COMMON, "%%policy:get_psu_status success") - return 0 - except AttributeError as e: - logger.error(str(e)) - except Exception as e: - logger.error(str(e)) - return -1 - - def get_monitor_temp(self, temp): - for item in temp: - if item.get("name") == "lm75in": - self._intemp = item.get("value", self._intemp) - if item.get("name") == "lm75out": - self._outtemp = item.get("value", self._outtemp) - if item.get("name") == "lm75hot": - self._boardtemp = item.get("value", self._boardtemp) - if item.get("name") == "Physical id 0": - self._cputemp = item.get("value", self._cputemp) - logger.debug( - DEBUG_COMMON, - "intemp:%f, outtemp:%f, boadrtemp:%f, cputemp:%f" - % (self._intemp, self._outtemp, self._boardtemp, self._cputemp), - ) - - def get_temp_status(self): - try: - monitortemp = [] - ret = self.gettemp(monitortemp) - if ret == True: - self.get_monitor_temp(monitortemp) - logger.debug(DEBUG_COMMON, "%%policy:get_temp_status success") - return 0 - except AttributeError as e: - logger.error(str(e)) - except Exception as e: - logger.error(str(e)) - return -1 - - def get_mac_status_bcmcmd(self): - try: - if wait_docker(timeout=0) == True: - sta, ret = get_mac_temp() - if sta == True: - self._mac_aver = float(ret.get("average", self._mac_aver)) - self._mac_max = float(ret.get("maximum", self._mac_max)) - logger.debug( - DEBUG_COMMON, - "mac_aver:%f, mac_max:%f" % (self.mac_aver, self._mac_max), - ) - else: - logger.debug(DEBUG_COMMON, "%%policy:get_mac_status_bcmcmd failed") - else: - logger.debug(DEBUG_COMMON, "%%policy:get_mac_status_bcmcmd SDK not OK") - return 0 - except AttributeError as e: - logger.error(str(e)) - return -1 - - def get_mac_status_sysfs(self, conf): - try: - sta, ret = get_mac_temp_sysfs(conf) - if sta == True: - self._mac_aver = float(ret) / 1000 - self._mac_max = float(ret) / 1000 - logger.debug( - DEBUG_COMMON, - "mac_aver:%f, mac_max:%f" % (self.mac_aver, self._mac_max), - ) - elif conf.get("try_bcmcmd", 0) == 1: - logger.debug( - DEBUG_COMMON, "get sysfs mac temp failed.try to use bcmcmd", - ) - self.get_mac_status_bcmcmd() - else: - logger.debug(DEBUG_COMMON, "%%policy:get_mac_status_sysfs failed") - return 0 - except AttributeError as e: - logger.error(str(e)) - return -1 - - def get_mac_status(self): - try: - mactempconf = MONITOR_DEV_STATUS.get("mac_temp", None) - if mactempconf is not None: - self.get_mac_status_sysfs(mactempconf) - else: - self.get_mac_status_bcmcmd() - return 0 - except AttributeError as e: - logger.error(str(e)) - return -1 - - def set_slot_attr(self, val): - u"""set each slot present status attribute""" - for item in val: - slotid = item.get("id") - slotattr = slotid + "status" - slotstatus = item.get("status") - setattr(FanControl, slotattr, slotstatus) - logger.debug( - DEBUG_COMMON, "slotattr:%s,slotstatus:%s" % (slotattr, slotstatus), - ) - - def get_slot_status(self): - try: - curSlotStatus = [] - ret = self.checkslot(curSlotStatus) - if ret == True: - self.set_slot_attr(curSlotStatus) - logger.debug(DEBUG_COMMON, "%%policy:get_slot_status success") - except AttributeError as e: - logger.error(str(e)) - return 0 - - def fanctrol(self): # fan speed-adjustment - try: - if self.preIntemp <= -1000: - self.preIntemp = self.intemp - logger.debug( - DEBUG_FANCONTROL, - "%%policy:previous temperature[%.2f] , current temperature[%.2f]" - % (self.preIntemp, self.intemp), - ) - if self.intemp < MONITOR_CONST.TEMP_MIN: - logger.debug( - DEBUG_FANCONTROL, - "%%policy:inlet %.2f minimum temperature: %.2f" - % (self.intemp, MONITOR_CONST.TEMP_MIN), - ) - self.set_fan_speed(MONITOR_CONST.DEFAULT_SPEED) # default level - elif self.intemp >= MONITOR_CONST.TEMP_MIN and self.intemp > self.preIntemp: - logger.debug(DEBUG_FANCONTROL, "%%policy:increase temperature") - self.policy_speed(self.intemp) - elif ( - self.intemp >= MONITOR_CONST.TEMP_MIN - and (self.preIntemp - self.intemp) > MONITOR_CONST.MONITOR_FALL_TEMP - ): - logger.debug( - DEBUG_FANCONTROL, - "%%policy:temperature reduce over %d degree" - % MONITOR_CONST.MONITOR_FALL_TEMP, - ) - self.policy_speed(self.intemp) - else: - speed = ( - self.get_curr_speed() - ) # set according to current speed, prevent fan watch-dog - if speed is not None: - self.set_fan_speed(speed) - logger.debug(DEBUG_FANCONTROL, "%%policy:change nothing") - except Exception as e: - logger.error("%%policy: fancontrol error") - - def start_fan_ctrl(self): - """ - start speed-adjustment - """ - self.check_crit() - if ( - self.critnum == 0 - and self.check_warn() == False - and self.detect_fan_status() == True - ): - self.fanctrol() - self.check_dev_err() - logger.debug( - DEBUG_FANCONTROL, - "%%policy: speed after speed-adjustment is %0x" % (self.get_curr_speed()), - ) - - def policy_speed(self, temp): # fan speed-adjustment algorithm - logger.debug(DEBUG_FANCONTROL, "%%policy:fan speed-adjustment algorithm") - sped_level = MONITOR_CONST.DEFAULT_SPEED + MONITOR_CONST.K * ( - temp - MONITOR_CONST.TEMP_MIN - ) - self.set_fan_speed(sped_level) - self.preIntemp = self.intemp - - def board_moni_msg(self, ledcontrol=False): - ret_t = 0 - try: - ret_t += ( - self.get_fan_status() - ) # get fan status, get number of fan which status is OK - ret_t += ( - self.get_temp_status() - ) # get inlet, outlet, hot-point temperature, CPU temperature - ret_t += self.get_mac_status() # get MAC highest and average temperature - if ledcontrol == True: - ret_t += self.get_slot_status() # get slot present status - ret_t += self.get_psu_status() # get psu status - if ret_t == 0: - return True - except Exception as e: - logger.error(str(e)) - return False - - # device error algorithm Tmac-Tin≥50℃, or Tmac-Tin≤-50℃ - def check_dev_err(self): - try: - if (self.mac_aver - self.intemp) >= MONITOR_CONST.MAC_UP_TEMP or ( - self.mac_aver - self.intemp - ) <= MONITOR_CONST.MAC_LOWER_TEMP: - logger.debug( - DEBUG_FANCONTROL, "%%DEV_MONITOR-TEMP: MAC temp get failed.", - ) - value = self.get_curr_speed() - if MONITOR_CONST.MAC_ERROR_SPEED >= value: - self.set_fan_speed(MONITOR_CONST.MAC_ERROR_SPEED) - else: - self.set_fan_max_speed() - else: - pass - except Exception as e: - logger.error("%%policy:check_dev_err failed") - logger.error(str(e)) - - def check_temp_warn(self): - u"""check whether temperature above the normal alarm value""" - try: - if ( - self._mac_aver >= MONITOR_CONST.MAC_WARNING_THRESHOLD - or self._outtemp >= MONITOR_CONST.OUTTEMP_WARNING_THRESHOLD - or self._boardtemp >= MONITOR_CONST.BOARDTEMP_WARNING_THRESHOLD - or self._cputemp >= MONITOR_CONST.CPUTEMP_WARNING_THRESHOLD - or self._intemp >= MONITOR_CONST.INTEMP_WARNING_THRESHOLD - ): - logger.debug( - DEBUG_COMMON, - "check whether temperature above the normal alarm value", - ) - return True - except Exception as e: - logger.error("%%policy: check_temp_warn failed") - logger.error(str(e)) - return False - - def check_temp_crit(self): - u"""check whether temperature above the critical alarm value""" - try: - if self._mac_aver >= MONITOR_CONST.MAC_CRITICAL_THRESHOLD or ( - self._outtemp >= MONITOR_CONST.OUTTEMP_CRITICAL_THRESHOLD - and self._boardtemp >= MONITOR_CONST.BOARDTEMP_CRITICAL_THRESHOLD - and self._cputemp >= MONITOR_CONST.CPUTEMP_CRITICAL_THRESHOLD - and self._intemp >= MONITOR_CONST.INTEMP_CRITICAL_THRESHOLD - ): - logger.debug( - DEBUG_COMMON, "temperature above the critical alarm value", - ) - return True - except Exception as e: - logger.error("%%policy: check_temp_crit failed") - logger.error(str(e)) - return False - - def check_fan_status(self): - u"""check fan status""" - for item in MONITOR_FAN_STATUS: - maxoknum = item.get("maxOkNum") - minoknum = item.get("minOkNum") - status = item.get("status") - if self.normal_fans >= minoknum and self.normal_fans <= maxoknum: - logger.debug( - DEBUG_COMMON, - "check_fan_status:normal_fans:%d,status:%s" - % (self.normal_fans, status), - ) - return status - logger.debug( - DEBUG_COMMON, "check_fan_status Error:normal_fans:%d" % (self.normal_fans), - ) - return None - - def check_psu_status(self): - u"""check psu status""" - for item in MONITOR_PSU_STATUS: - maxoknum = item.get("maxOkNum") - minoknum = item.get("minOkNum") - status = item.get("status") - if self.normal_psus >= minoknum and self.normal_psus <= maxoknum: - logger.debug( - DEBUG_COMMON, - "check_psu_status:normal_psus:%d,status:%s" - % (self.normal_psus, status), - ) - return status - logger.debug( - DEBUG_COMMON, "check_psu_status Error:normal_psus:%d" % (self.normal_psus), - ) - return None - - def deal_sys_led_status(self): - u"""set up SYSLED according to temperature, fan and psu status""" - try: - fanstatus = self.check_fan_status() - psustatus = self.check_psu_status() - if ( - self.check_temp_crit() == True - or fanstatus == "red" - or psustatus == "red" - ): - status = "red" - elif ( - self.check_temp_warn() == True - or fanstatus == "yellow" - or psustatus == "yellow" - ): - status = "yellow" - else: - status = "green" - self.set_sys_leds(status) - logger.debug( - DEBUG_LEDCONTROL, - "%%ledcontrol:deal_sys_led_status success, status:%s," % status, - ) - except Exception as e: - logger.error(str(e)) - - def deal_sys_fan_led_status(self): - u"""light panel fan led according to status""" - try: - status = self.check_fan_status() - if status is not None: - self.set_sys_fan_leds(status) - logger.debug( - DEBUG_LEDCONTROL, - "%%ledcontrol:deal_sys_fan_led_status success, status:%s," % status, - ) - except Exception as e: - logger.error("%%ledcontrol:deal_sys_led_status error") - logger.error(str(e)) - - def deal_psu_led_status(self): - u"""set up PSU-LED according to psu status""" - try: - status = self.check_psu_status() - if status is not None: - self.set_sys_psu_leds(status) - logger.debug( - DEBUG_LEDCONTROL, - "%%ledcontrol:deal_psu_led_status success, status:%s," % status, - ) - except Exception as e: - logger.error("%%ledcontrol:deal_psu_led_status error") - logger.error(str(e)) - - def deal_fan_led_status(self): - u"""light fan led according to fan status""" - for item in MONITOR_FANS_LED: - try: - index = MONITOR_FANS_LED.index(item) + 1 - fanattr = "fan%dstatus" % index - val_t = getattr(FanControl, fanattr, None) - if val_t == "NOT OK": - rgi2cset(item["bus"], item["devno"], item["addr"], item["red"]) - elif val_t == "OK": - rgi2cset(item["bus"], item["devno"], item["addr"], item["green"]) - else: - pass - logger.debug( - DEBUG_LEDCONTROL, - "%%ledcontrol:dealLocFanLed success.fanattr:%s, status:%s" - % (fanattr, val_t), - ) - except Exception as e: - logger.error("%%ledcontrol:deal_fan_led_status error") - logger.error(str(e)) - - def dealSlotLedStatus(self): - u"""light slot status led according to slot present status""" - slotLedList = DEV_LEDS.get("SLOTLED", []) - for item in slotLedList: - try: - index = slotLedList.index(item) + 1 - slotattr = "slot%dstatus" % index - val_t = getattr(FanControl, slotattr, None) - if val_t == "PRESENT": - rgi2cset(item["bus"], item["devno"], item["addr"], item["green"]) - logger.debug( - DEBUG_LEDCONTROL, - "%%ledcontrol:dealSlotLedStatus success.slotattr:%s, status:%s" - % (slotattr, val_t), - ) - except Exception as e: - logger.error("%%ledcontrol:dealSlotLedStatus error") - logger.error(str(e)) - - def setled(self, item, color): - if item.get("type", "i2c") == "sysfs": - rgsysset(item["cmdstr"], item.get(color)) - else: - mask = item.get("mask", 0xFF) - ind, val = rgi2cget(item["bus"], item["devno"], item["addr"]) - if ind == True: - setval = (int(val, 16) & ~mask) | item.get(color) - rgi2cset(item["bus"], item["devno"], item["addr"], setval) - else: - logger.error("led %s" % "i2c read failed") - - def set_sys_leds(self, color): - for item in MONITOR_SYS_LED: - self.setled(item, color) - - def set_sys_fan_leds(self, color): - for item in MONITOR_SYS_FAN_LED: - self.setled(item, color) - - def set_sys_psu_leds(self, color): - for item in MONITOR_SYS_PSU_LED: - self.setled(item, color) - - def check_warn(self): - try: - if self.check_temp_warn() == True: - logger.debug(DEBUG_FANCONTROL, "anti-shake start") - time.sleep(MONITOR_CONST.SHAKE_TIME) - logger.debug(DEBUG_FANCONTROL, "anti-shake end") - self.board_moni_msg() # re-read - if self.check_temp_warn() == True: - logger.warn("%%DEV_MONITOR-TEMP:The temperature of device is over warning value.") - self.set_fan_max_speed() # fan full speed - return True - except Exception as e: - logger.error("%%policy: check_warn failed") - logger.error(str(e)) - return False - - def check_crit(self): - try: - if self.check_temp_crit() == True: - logger.debug(DEBUG_FANCONTROL, "anti-shake start") - time.sleep(MONITOR_CONST.SHAKE_TIME) - logger.debug(DEBUG_FANCONTROL, "anti-shake end") - self.board_moni_msg() # re-read - if self.check_temp_crit() == True: - logger.crit( - "%%DEV_MONITOR-TEMP:The temperature of device is over critical value.", - ) - self.set_fan_max_speed() # fan full speed - self.critnum += 1 # anti-shake - if self.critnum >= MONITOR_CONST.CRITICAL_NUM: - os.system("reboot") - logger.debug(DEBUG_FANCONTROL, "crit times:%d" % self.critnum) - else: - self.critnum = 0 - else: - self.critnum = 0 - except Exception as e: - logger.error("%%policy: check_crit failed") - logger.error(str(e)) - - -def callback(): - pass - - -def do_fan_ctrl(fanctrl): - ret = fanctrl.board_moni_msg() - if ret == True: - logger.debug(DEBUG_FANCONTROL, "%%policy:start_fan_ctrl") - fanctrl.start_fan_ctrl() - else: - fanctrl.set_fan_max_speed() - logger.debug(DEBUG_FANCONTROL, "%%policy:board_moni_msg error") - - -def do_led_ctrl(fanctrl): - fanctrl.board_moni_msg(ledcontrol=True) # get status - fanctrl.deal_sys_led_status() # light system led - fanctrl.deal_sys_fan_led_status() # light panel fan led - fanctrl.deal_fan_led_status() # light fan led - fanctrl.deal_psu_led_status() # light psu led - fanctrl.dealSlotLedStatus() # light slot status led - logger.debug(DEBUG_LEDCONTROL, "%%ledcontrol:do_led_ctrl success") - - -def run(interval, fanctrl): - loop = 0 - # waitForDocker() - while True: - try: - if loop % MONITOR_CONST.MONITOR_INTERVAL == 0: # fan speed-adjustment - logger.debug(DEBUG_FANCONTROL, "%%policy:fanctrl") - do_fan_ctrl(fanctrl) - else: - logger.debug( - DEBUG_LEDCONTROL, "%%ledcontrol:start ledctrol" - ) # LED control - do_led_ctrl(fanctrl) - time.sleep(interval) - loop += interval - except Exception as e: - traceback.print_exc() - logger.error(str(e)) - - -@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) -def main(): - """device operator""" - pass - - -@main.command() -def start(): - """start fan control""" - logger.info("FAN CTRL START") - fanctrl = FanControl() - interval = MONITOR_CONST.MONITOR_INTERVAL / 30 - run(interval, fanctrl) - - -@main.command() -def stop(): - """stop fan control """ - logger.info("FAN CTRL STOP") - - -##device_i2c operation -if __name__ == "__main__": - main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/generate_airflow.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/generate_airflow.py new file mode 100755 index 000000000000..29d18e7b2688 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/generate_airflow.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- +''' +generate board air flow according to fan and psu air flow +write resulet to AIRFLOW_RESULT_FILE, file format: +{ + "FAN1": { + "model":"M1HFAN I-F", + "airflow":"intake", + }, + "PSU1": { + "model":"CSU550AP-3-500", + "airflow":"intake", + }, + "board":"intake" +} +''' +import os +import syslog +import json +from platform_config import AIR_FLOW_CONF, AIRFLOW_RESULT_FILE +from platform_util import dev_file_read, byteTostr +from eepromutil.fru import ipmifru +from eepromutil.fantlv import fan_tlv + + +AIRFLOW_DEBUG_FILE = "/etc/.airflow_debug_flag" + +AIRFLOWERROR = 1 +AIRFLOWDEBUG = 2 + +debuglevel = 0 + + +def airflow_info(s): + syslog.openlog("AIRFLOW", syslog.LOG_PID) + syslog.syslog(syslog.LOG_INFO, s) + + +def airflow_error(s): + syslog.openlog("AIRFLOW", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def airflow_debug(s): + if AIRFLOWDEBUG & debuglevel: + syslog.openlog("AIRFLOW", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def airflow_debug_error(s): + if AIRFLOWERROR & debuglevel: + syslog.openlog("AIRFLOW", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def debug_init(): + global debuglevel + try: + with open(AIRFLOW_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + +def get_model_fru(device, eeprom): + try: + fru = ipmifru() + fru.decodeBin(eeprom) + dev_name = device.get("name") + area = device.get("area") + field = device.get("field") + tmp_area = getattr(fru, area, None) + if tmp_area is None: + msg = "%s fru %s area config error" % (dev_name, area) + return False, msg + model = getattr(tmp_area, field, None) + if model is None: + msg = "%s get model error, area: %s, field: %s" % (dev_name, area, field) + return False, msg + airflow_debug("%s get model success, model: %s" % (dev_name, model)) + return True, model + except Exception as e: + return False, str(e) + + +def get_model_fantlv(device, eeprom): + try: + dev_name = device.get("name") + tlv = fan_tlv() + rets = tlv.decode(eeprom) + if len(rets) == 0: + msg = "%s decode fantlv eeprom info error" % dev_name + return False, msg + + field = device.get("field") + for fantlv_item in rets: + if fantlv_item.get("name") == field: + return True, fantlv_item["value"] + msg = "%s get model error, field: %s not found" % (dev_name, field) + return False, msg + except Exception as e: + return False, str(e) + + +def get_device_modele(device): + e2_type = device.get("e2_type") + dev_name = device.get("name") + support_e2_type = ("fru", "fantlv") + if e2_type not in support_e2_type: + msg = "%s unsupport e2_type: %s" % (dev_name, e2_type) + return False, msg + + e2_path = device.get("e2_path") + e2_size = device.get("e2_size", 256) + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + msg = "%s eeprom read error, eeprom path: %s, msg: %s" % (dev_name, e2_path, binval_bytes) + return False, msg + + binval = byteTostr(binval_bytes) + if e2_type == "fru": + return get_model_fru(device, binval) + return get_model_fantlv(device, binval) + + +def get_board_air_flow(fan_intake_num, fan_exhaust_num, psu_intake_num, psu_exhaust_num): + airflow_debug("fan_intake_num: %d, fan_exhaust_num: %d, psu_intake_num: %d, psu_exhaust_num: %d" % + (fan_intake_num, fan_exhaust_num, psu_intake_num, psu_exhaust_num)) + + if fan_intake_num == 0 and fan_exhaust_num == 0 and psu_intake_num == 0 and psu_exhaust_num == 0: + airflow_error("get all fans and psus air flow failed") + return "N/A" + + if fan_intake_num > fan_exhaust_num: + airflow_debug("fan intake number %d more than fan exhaust number %s, set board air flow: intake") + return "intake" + + if fan_intake_num < fan_exhaust_num: + airflow_debug("fan intake number less than fan exhaust number, set board air flow: exhaust") + return "exhaust" + + airflow_debug("fan intake number equal to exhaust number, check psu air flow") + + if psu_intake_num > psu_exhaust_num: + airflow_debug("psu intake number more than psu exhaust number, set board air flow: intake") + return "intake" + + if psu_intake_num < psu_exhaust_num: + airflow_debug("psu intake number less than psu exhaust number, set board air flow: exhaust") + return "exhaust" + + airflow_debug("fan and psu intake and exhaust number equal, return intake") + return "intake" + + +def generate_airflow(): + fan_intake_list = [] + fan_exhaust_list = [] + psu_intake_list = [] + psu_exhaust_list = [] + ret = {} + fans = AIR_FLOW_CONF.get("fans", []) + psus = AIR_FLOW_CONF.get("psus", []) + + for fan in fans: + dev_name = fan.get("name") + air_flow = "N/A" + status, model = get_device_modele(fan) + if status is False: + ret[dev_name] = {"model": "N/A", "airflow": "N/A"} + airflow_error(model) + continue + model = model.strip() + airflowconifg = AIR_FLOW_CONF[fan["decode"]] + for key, value in airflowconifg.items(): + if model in value: + air_flow = key + ret[dev_name] = {"model": model, "airflow": air_flow} + airflow_debug("%s model: %s, airflow: %s" % (dev_name, model, air_flow)) + if air_flow == "intake": + fan_intake_list.append(fan.get("name")) + elif air_flow == "exhaust": + fan_exhaust_list.append(fan.get("name")) + + airflow_debug("fan_intake_list: %s" % fan_intake_list) + airflow_debug("fan_exhaust_list: %s" % fan_exhaust_list) + + for psu in psus: + dev_name = psu.get("name") + air_flow = "N/A" + status, model = get_device_modele(psu) + if status is False: + ret[dev_name] = {"model": "N/A", "airflow": "N/A"} + airflow_error(model) + continue + model = model.strip() + airflowconifg = AIR_FLOW_CONF[psu["decode"]] + for key, value in airflowconifg.items(): + if model in value: + air_flow = key + ret[dev_name] = {"model": model, "airflow": air_flow} + airflow_debug("%s model: %s, airflow: %s" % (dev_name, model, air_flow)) + if air_flow == "intake": + psu_intake_list.append(psu.get("name")) + elif air_flow == "exhaust": + psu_exhaust_list.append(psu.get("name")) + + airflow_debug("psu_intake_list: %s" % psu_intake_list) + airflow_debug("psu_exhaust_list: %s" % psu_exhaust_list) + + fan_intake_num = len(fan_intake_list) + fan_exhaust_num = len(fan_exhaust_list) + psu_intake_num = len(psu_intake_list) + psu_exhaust_num = len(psu_exhaust_list) + + board_airflow = get_board_air_flow(fan_intake_num, fan_exhaust_num, psu_intake_num, psu_exhaust_num) + airflow_debug("board_airflow: %s" % board_airflow) + ret["board"] = board_airflow + ret_json = json.dumps(ret, ensure_ascii=False, indent=4) + + out_file_dir = os.path.dirname(AIRFLOW_RESULT_FILE) + if len(out_file_dir) != 0: + cmd = "mkdir -p %s" % out_file_dir + os.system(cmd) + os.system("sync") + with open(AIRFLOW_RESULT_FILE, "w") as fd: + fd.write(ret_json) + os.system("sync") + + +if __name__ == '__main__': + debug_init() + airflow_debug("enter main") + generate_airflow() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_fanctrl.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_fanctrl.py new file mode 100755 index 000000000000..7722b111f944 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_fanctrl.py @@ -0,0 +1,1135 @@ +#!/usr/bin/env python3 +import os +import subprocess +import time +import syslog +import traceback +from plat_hal.interface import interface +from plat_hal.baseutil import baseutil +from algorithm.pid import pid +from algorithm.openloop import openloop +from algorithm.hysteresis import hysteresis + + +SWITCH_TEMP = "SWITCH_TEMP" +INLET_TEMP = "INLET_TEMP" +BOARD_TEMP = "BOARD_TEMP" +OUTLET_TEMP = "OUTLET_TEMP" +CPU_TEMP = "CPU_TEMP" + +FANCTROL_DEBUG_FILE = "/etc/.fancontrol_debug_flag" +# coordination with REBOOT_CAUSE_PARA +OTP_SWITCH_REBOOT_JUDGE_FILE = "/etc/.otp_reboot_flag" +OTP_OTHER_REBOOT_JUDGE_FILE = OTP_SWITCH_REBOOT_JUDGE_FILE + +FANCTROLERROR = 1 +FANCTROLDEBUG = 2 +FANAIRFLOWDEBUG = 4 + +debuglevel = 0 + +F2B_AIR_FLOW = "intake" +B2F_AIR_FLOW = "exhaust" +ONIE_E2_NAME = "ONIE_E2" + +TEMP_REBOOT_CRIT_SWITCH_FLAG = 1 +TEMP_REBOOT_CRIT_OTHER_FLAG = 2 + + +def fancontrol_debug(s): + if FANCTROLDEBUG & debuglevel: + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def fancontrol_error(s): + if FANCTROLERROR & debuglevel: + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def fanairflow_debug(s): + if FANAIRFLOWDEBUG & debuglevel: + syslog.openlog("AIR_FLOW_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def fancontrol_warn(s): + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_WARNING, s) + + +def fancontrol_crit(s): + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_CRIT, s) + + +def fancontrol_alert(s): + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_ALERT, s) + + +def fancontrol_emerg(s): + syslog.openlog("FANCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_EMERG, s) + + +def exec_os_cmd(cmd): + status, output = subprocess.getstatusoutput(cmd) + if status: + print(output) + return status, output + + +def debug_init(): + global debuglevel + try: + with open(FANCTROL_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + +error_temp = -9999 # get temp error +invalid_temp = -10000 # get temp invalid +PRE_FAN_NOK_UNKNOWN = "UNKNOWN" + + +class DevFan(object): + + def __init__(self, name, hal_interface): + self.__name = name + self.origin_name = None + self.display_name = None + self.air_flow = None + self.air_flow_inconsistent = False + self.int_case = hal_interface + + @property + def name(self): + return self.__name + + def get_fan_rotor_number(self): + return self.int_case.get_fan_rotor_number(self.name) + + def get_fan_presence(self): + return self.int_case.get_fan_presence(self.name) + + def get_fan_rotor_status(self, rotor_name): + return self.int_case.get_fan_rotor_status(self.name, rotor_name) + + def get_fan_fru_info(self): + return self.int_case.get_fan_fru_info(self.name) + + @property + def na_ret(self): + return self.int_case.na_ret + + def update_fru_info(self): + try: + dic = self.get_fan_fru_info() + self.origin_name = dic["PN"] + self.air_flow = dic["AirFlow"] + self.display_name = dic["DisplayName"] + except Exception as e: + fanairflow_debug("update %s fru info error, msg: %s" % (self.name, str(e))) + self.origin_name = self.na_ret + self.air_flow = self.na_ret + self.display_name = self.na_ret + + +class DevPsu(object): + + def __init__(self, name, hal_interface): + self.__name = name + self.origin_name = None + self.display_name = None + self.air_flow = None + self.air_flow_inconsistent = False + self.int_case = hal_interface + + @property + def name(self): + return self.__name + + def get_psu_fru_info(self): + return self.int_case.get_psu_fru_info(self.name) + + @property + def na_ret(self): + return self.int_case.na_ret + + def update_fru_info(self): + try: + dic = self.get_psu_fru_info() + self.origin_name = dic["PN"] + self.air_flow = dic["AirFlow"] + self.display_name = dic["DisplayName"] + except Exception as e: + fanairflow_debug("update %s fru info error, msg: %s" % (self.name, str(e))) + self.origin_name = self.na_ret + self.air_flow = self.na_ret + self.display_name = self.na_ret + + +class fancontrol(object): + __int_case = None + + __pwm = 0x80 + + def __init__(self): + self.int_case = interface() + self.__config = baseutil.get_monitor_config() + self.__pid_config = self.__config["pid"] + self.__hyst_config = self.__config.get("hyst", {}) + self.__temps_threshold_config = self.__config["temps_threshold"] + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['temp'] = 0 + temp_threshold['fail_num'] = 0 + temp_threshold['warning_num'] = 0 # temp warning times + temp_threshold['critical_num'] = 0 # temp critical times + temp_threshold['emergency_num'] = 0 # temp emergency times + temp_threshold.setdefault('ignore_threshold', 0) # default temp threshold on + temp_threshold.setdefault('invalid', invalid_temp) + temp_threshold.setdefault('error', error_temp) + + self.__otp_reboot_judge_file_config = self.__config.get("otp_reboot_judge_file", None) + if self.__otp_reboot_judge_file_config is None: + self.__otp_switch_reboot_judge_file = OTP_SWITCH_REBOOT_JUDGE_FILE + self.__otp_other_reboot_judge_file = OTP_OTHER_REBOOT_JUDGE_FILE + else: + self.__otp_switch_reboot_judge_file = self.__otp_reboot_judge_file_config.get( + "otp_switch_reboot_judge_file", OTP_SWITCH_REBOOT_JUDGE_FILE) + self.__otp_other_reboot_judge_file = self.__otp_reboot_judge_file_config.get( + "otp_other_reboot_judge_file", OTP_OTHER_REBOOT_JUDGE_FILE) + + self.__fan_rotor_error_num = {} + self.__fan_present_status = {} # {"FAN1":0, "FAN2":1...} 1:present, 0:absent + self.__fan_rotate_status = {} # {"FAN1":0, "FAN2":1...} 1:OK, 0:NOT OK + self.__fan_repair_flag = {} # {"FAN1":0, "FAN2":1...} 1:repair, 0:give up + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + self.__fan_present_status[fan_name] = 1 # present + self.__fan_rotate_status[fan_name] = 1 # OK + self.__fan_repair_flag[fan_name] = 1 # repair + rotor_num = self.get_rotor_number(fan_name) + tmp_fan = {} + for j in range(rotor_num): + rotor_name = "Rotor" + str(j + 1) + tmp_fan[rotor_name] = 0 # not error + self.__fan_rotor_error_num[fan_name] = tmp_fan + + self.__fancontrol_para = self.__config["fancontrol_para"] + self.__interval = self.__fancontrol_para.get("interval", 5) + self.__fan_status_interval = self.__fancontrol_para.get("fan_status_interval", 0) + self.__max_pwm = self.__fancontrol_para.get("max_pwm", 0xff) + self.__min_pwm = self.__fancontrol_para.get("min_pwm", 0x80) + self.__abnormal_pwm = self.__fancontrol_para.get("abnormal_pwm", 0xbb) + self.__warning_pwm = self.__fancontrol_para.get("warning_pwm", 0xff) + self.__temp_invalid_pid_pwm = self.__fancontrol_para.get("temp_invalid_pid_pwm", 0x80) + self.__temp_error_pid_pwm = self.__fancontrol_para.get("temp_error_pid_pwm", 0x80) + self.__temp_fail_num = self.__fancontrol_para.get("temp_fail_num", 3) + self.__check_temp_fail = self.__fancontrol_para.get("check_temp_fail", []) + self.__temp_warning_num = self.__fancontrol_para.get("temp_warning_num", 3) + self.__temp_critical_num = self.__fancontrol_para.get("temp_critical_num", 3) + self.__temp_emergency_num = self.__fancontrol_para.get("temp_emergency_num", 3) + self.__temp_warning_countdown = self.__fancontrol_para.get("temp_warning_countdown", 60) + self.__temp_critical_countdown = self.__fancontrol_para.get("temp_critical_countdown", 60) + self.__temp_emergency_countdown = self.__fancontrol_para.get("temp_emergency_countdown", 60) + self.__rotor_error_count = self.__fancontrol_para.get("rotor_error_count", 6) + self.__inlet_mac_diff = self.__fancontrol_para.get("inlet_mac_diff", 50) + self.__check_crit_reboot_flag = self.__fancontrol_para.get("check_crit_reboot_flag", 1) + self.__check_emerg_reboot_flag = self.__fancontrol_para.get("check_emerg_reboot_flag", 1) + self.__check_crit_reboot_num = self.__fancontrol_para.get("check_crit_reboot_num", 3) + self.__check_crit_sleep_time = self.__fancontrol_para.get("check_crit_sleep_time", 20) + self.__check_emerg_reboot_num = self.__fancontrol_para.get("check_emerg_reboot_num", 3) + self.__check_emerg_sleep_time = self.__fancontrol_para.get("check_emerg_sleep_time", 20) + self.__check_temp_emergency = self.__fancontrol_para.get("check_temp_emergency", 0) + self.__check_temp_critical = self.__fancontrol_para.get("check_temp_critical", 1) + self.__check_temp_warning = self.__fancontrol_para.get("check_temp_warning", 1) + self.__check_temp_emergency_reboot = self.__fancontrol_para.get("check_temp_emergency_reboot", []) + self.__psu_absent_fullspeed_num = self.__fancontrol_para.get("psu_absent_fullspeed_num", 1) + self.__fan_absent_fullspeed_num = self.__fancontrol_para.get("fan_absent_fullspeed_num", 1) + self.__rotor_error_fullspeed_num = self.__fancontrol_para.get("rotor_error_fullspeed_num", 1) + self.__psu_fan_control = self.__fancontrol_para.get("psu_fan_control", 1) # default control psu fan + self.__fan_plug_in_pwm = self.__fancontrol_para.get("fan_plug_in_pwm", 0x80) + self.__fan_plug_in_default_countdown = self.__fancontrol_para.get("fan_plug_in_default_countdown", 0) + self.__deal_fan_error_policy = self.__fancontrol_para.get("deal_fan_error", 0) + self.__deal_fan_error_conf = self.__fancontrol_para.get("deal_fan_error_conf", {}) + self.__deal_fan_error_default_countdown = self.__deal_fan_error_conf.get("countdown", 0) + + self.__warning_countdown = 0 # temp warning flag for normal fancontrol + self.__critical_countdown = 0 # temp critical flag for normal fancontrol + self.__emergency_countdown = 0 # temp emergency flag for normal fancontrol + self.__fan_plug_in_countdown = 0 # fan plug in flag for normal fancontrol + self.__deal_fan_error_countdown = 0 + self.__fan_absent_num = 0 + self.__fan_nok_num = 0 + self.__pre_fan_nok = PRE_FAN_NOK_UNKNOWN + self.openloop = openloop() + self.pid = pid() + self.hyst = hysteresis() + self.__pwm = self.__min_pwm + + self.__board_air_flow = "" + self.__fan_air_flow_monitor = self.__fancontrol_para.get("fan_air_flow_monitor", 0) + self.__psu_air_flow_monitor = self.__fancontrol_para.get("psu_air_flow_monitor", 0) + self.__air_flow_correct_fan_pwm = self.__fancontrol_para.get("air_flow_correct_fan_pwm", 0xff) + self.__air_flow_correct_psu_pwm = self.__fancontrol_para.get("air_flow_correct_psu_pwm", 0xff) + self.__air_flow_error_fan_pwm = self.__fancontrol_para.get("air_flow_error_fan_pwm", 0) + self.__air_flow_error_psu_pwm = self.__fancontrol_para.get("air_flow_error_psu_pwm", 0) + self.fan_air_flow_inconsistent_flag = False + self.psu_air_flow_inconsistent_flag = False + self.air_flow_inconsistent_flag = False + self.fan_obj_list = [] + self.psu_obj_list = [] + + @property + def na_ret(self): + return self.int_case.na_ret + + def get_onie_e2_obj(self, name): + return self.int_case.get_onie_e2_obj(name) + + @property + def board_air_flow(self): + air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) + if self.__board_air_flow not in air_flow_tuple: + self.__board_air_flow = self.int_case.get_device_airflow(ONIE_E2_NAME) + fanairflow_debug("board_air_flow: %s" % self.__board_air_flow) + return self.__board_air_flow + + @property + def fan_air_flow_monitor(self): + return self.__fan_air_flow_monitor + + @property + def psu_air_flow_monitor(self): + return self.__psu_air_flow_monitor + + @property + def air_flow_correct_fan_pwm(self): + return self.__air_flow_correct_fan_pwm + + @property + def air_flow_correct_psu_pwm(self): + return self.__air_flow_correct_psu_pwm + + @property + def air_flow_error_fan_pwm(self): + return self.__air_flow_error_fan_pwm + + @property + def air_flow_error_psu_pwm(self): + return self.__air_flow_error_psu_pwm + + def get_para(self, t): + para = self.__pid_config.get(t) + return para + + def update_over_temp_threshold_num(self): + for temp_threshold in self.__temps_threshold_config.values(): + if temp_threshold['ignore_threshold']: + continue + emergency_threshold = temp_threshold.get('emergency', None) + critical_threshold = temp_threshold.get('critical', None) + warning_threshold = temp_threshold.get('warning', None) + fancontrol_debug("%s warning = %s, critical = %s, emergency = %s" % + (temp_threshold['name'], warning_threshold, critical_threshold, emergency_threshold)) + + if emergency_threshold is not None and temp_threshold['temp'] >= emergency_threshold: + temp_threshold['emergency_num'] += 1 + else: + temp_threshold['emergency_num'] = 0 + + if critical_threshold is not None and temp_threshold['temp'] >= critical_threshold: + temp_threshold['critical_num'] += 1 + else: + temp_threshold['critical_num'] = 0 + + if warning_threshold is not None and temp_threshold['temp'] >= warning_threshold: + temp_threshold['warning_num'] += 1 + else: + temp_threshold['warning_num'] = 0 + + fancontrol_debug("%s warning_num = %d, critical_num = %d, emergency_num = %d" % + (temp_threshold['name'], temp_threshold['warning_num'], temp_threshold['critical_num'], temp_threshold.get("emergency_num"))) + + def get_monitor_temp(self): + sensorlist = self.int_case.get_temp_info() + + for temp_threshold in self.__temps_threshold_config.values(): + sensor = sensorlist.get(temp_threshold['name']) + if sensor["Value"] is None or int(sensor["Value"]) == self.int_case.error_ret: + temp_threshold['fail_num'] += 1 + fancontrol_error("get %s failed, fail_num = %d" % (temp_threshold['name'], temp_threshold['fail_num'])) + else: + temp_threshold['fail_num'] = 0 + temp_threshold.setdefault('fix', 0) + temp_threshold['temp'] = sensor["Value"] + temp_threshold['fix'] + fancontrol_debug("%s = %d" % (temp_threshold['name'], temp_threshold['temp'])) + self.update_over_temp_threshold_num() + + def is_temp_warning(self): + warning_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + if temp_threshold['ignore_threshold']: + continue + if temp_threshold['warning_num'] >= self.__temp_warning_num: + warning_flag = True + fancontrol_warn("%%FANCONTROL-4-TEMP_HIGH: %s temperature %sC is larger than warning threshold %sC." % + (temp_threshold['name'], temp_threshold['temp'], temp_threshold.get('warning'))) + return warning_flag + + def checkTempWarning(self): + try: + if self.is_temp_warning(): + self.__warning_countdown = self.__temp_warning_countdown + fancontrol_debug("temp is over warning") + return True + if self.__warning_countdown > 0: + self.__warning_countdown -= 1 + return False + except Exception as e: + fancontrol_error("%%policy: checkTempWarning failed") + fancontrol_error(str(e)) + return False + + def checkTempWarningCountdown(self): + if self.__warning_countdown > 0: + return True + return False + + def is_temp_critical(self): + critical_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['critical_flag'] = False + if temp_threshold['ignore_threshold']: + continue + if temp_threshold['critical_num'] >= self.__temp_critical_num: + critical_flag = True + temp_threshold['critical_flag'] = True + fancontrol_crit("%%FANCONTROL-2-TEMP_HIGH: %s temperature %sC is larger than critical threshold %sC." % + (temp_threshold['name'], temp_threshold['temp'], temp_threshold.get('critical'))) + return critical_flag + + def checkTempCritical(self): + try: + if self.is_temp_critical(): + self.__critical_countdown = self.__temp_critical_countdown + fancontrol_debug("temp is over critical") + return True + if self.__critical_countdown > 0: + self.__critical_countdown -= 1 + return False + except Exception as e: + fancontrol_error("%%policy: checkTempCrit failed") + fancontrol_error(str(e)) + return False + + def is_temp_emergency(self): + emergency_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['emergency_flag'] = False + if temp_threshold['ignore_threshold']: + continue + if temp_threshold['emergency_num'] >= self.__temp_emergency_num: + emergency_flag = True + temp_threshold['emergency_flag'] = True + fancontrol_alert("%%FANCONTROL-1-TEMP_HIGH: %s temperature %sC is larger than emergency threshold %sC." % + (temp_threshold['name'], temp_threshold['temp'], temp_threshold.get('emergency'))) + return emergency_flag + + def checkTempEmergency(self): + try: + if self.is_temp_emergency(): + self.__emergency_countdown = self.__temp_emergency_countdown + fancontrol_debug("temp is over emergency") + return True + if self.__emergency_countdown > 0: + self.__emergency_countdown -= 1 + return False + except Exception as e: + fancontrol_error("%%policy: checkTempEmergency failed") + fancontrol_error(str(e)) + return False + + def checkTempCriticalCountdown(self): + if self.__critical_countdown > 0: + return True + return False + + def checkTempEmergencyCountdown(self): + if self.__emergency_countdown > 0: + return True + return False + + def checkTempRebootCrit(self): + try: + if self.is_temp_critical(): + temp_dict = dict(self.__temps_threshold_config) + tmp = temp_dict.get(SWITCH_TEMP) + if tmp['critical_flag'] is True: + fancontrol_debug("switch temp is over reboot critical") + return TEMP_REBOOT_CRIT_SWITCH_FLAG + del temp_dict[SWITCH_TEMP] + for temp_items in temp_dict.values(): + if temp_items['ignore_threshold']: + continue + if temp_items['critical_flag'] is False: + return 0 + + fancontrol_debug("other temp is over reboot critical") + return TEMP_REBOOT_CRIT_OTHER_FLAG + except Exception as e: + fancontrol_error("%%policy: checkTempRebootCrit failed") + fancontrol_error(str(e)) + return 0 + + def checkCritReboot(self): + try: + reboot_flag = self.checkTempRebootCrit() + if reboot_flag > 0: + self.set_all_fan_speed_pwm(self.__max_pwm) + for i in range(self.__check_crit_reboot_num): + time.sleep(self.__check_crit_sleep_time) + self.get_monitor_temp() + reboot_flag = self.checkTempRebootCrit() + if reboot_flag > 0: + fancontrol_emerg("%%FANCONTROL-0-TEMP_EMERG: The temperature of device over reboot critical value lasts for %d seconds." % + (self.__check_crit_sleep_time * (i + 1))) + continue + fancontrol_debug("The temperature of device is not over reboot critical value.") + break + if reboot_flag > 0: + fancontrol_emerg( + "%%FANCONTROL-0-TEMP_EMERG: The temperature of device over reboot critical value, system is going to reboot now.") + for temp_threshold in self.__temps_threshold_config.values(): + fancontrol_emerg( + "%%FANCONTROL-TEMP_EMERG: %s temperature: %sC." % + (temp_threshold['name'], temp_threshold['temp'])) + if reboot_flag == TEMP_REBOOT_CRIT_SWITCH_FLAG: + create_judge_file = "touch %s" % self.__otp_switch_reboot_judge_file + else: + create_judge_file = "touch %s" % self.__otp_other_reboot_judge_file + exec_os_cmd(create_judge_file) + exec_os_cmd("sync") + time.sleep(3) + os.system("/sbin/reboot") + except Exception as e: + fancontrol_error("%%policy: checkCritReboot failed") + fancontrol_error(str(e)) + + def checkTempRebootEmerg(self): + try: + if self.is_temp_emergency(): + temp_emerg_reboot_flag = False + for temp_list in self.__check_temp_emergency_reboot: + for temp in temp_list: + tmp = self.__temps_threshold_config.get(temp) + if tmp['emergency_flag'] is False: + fancontrol_debug("temp_list %s, temp: %s not emergency" % (temp_list, temp)) + temp_emerg_reboot_flag = False + break + temp_emerg_reboot_flag = True + if temp_emerg_reboot_flag is True: + fancontrol_debug("temp_list %s, all temp is over emergency reboot" % temp_list) + return True + except Exception as e: + fancontrol_error("%%policy: checkTempRebootEmerg failed") + fancontrol_error(str(e)) + return False + + def checkEmergReboot(self): + try: + reboot_flag = False + if self.checkTempRebootEmerg() is True: + self.set_all_fan_speed_pwm(self.__max_pwm) + for i in range(self.__check_emerg_reboot_num): + time.sleep(self.__check_emerg_sleep_time) + self.get_monitor_temp() + if self.checkTempRebootEmerg() is True: + fancontrol_emerg("%%FANCONTROL-0-TEMP_EMERG: The temperature of device over reboot emergency value lasts for %d seconds." % + (self.__check_emerg_sleep_time * (i + 1))) + reboot_flag = True + continue + fancontrol_debug("The temperature of device is not over reboot emergency value.") + reboot_flag = False + break + if reboot_flag is True: + fancontrol_emerg( + "%%FANCONTROL-0-TEMP_EMERG: The temperature of device over reboot emergency value, system is going to reboot now.") + for temp_threshold in self.__temps_threshold_config.values(): + fancontrol_emerg( + "%%FANCONTROL-0-TEMP_EMERG: %s temperature: %sC." % + (temp_threshold['name'], temp_threshold['temp'])) + create_judge_file = "touch %s" % OTP_SWITCH_REBOOT_JUDGE_FILE + exec_os_cmd(create_judge_file) + exec_os_cmd("sync") + time.sleep(3) + os.system("/sbin/reboot") + except Exception as e: + fancontrol_error("%%policy: checkEmergReboot failed") + fancontrol_error(str(e)) + + def get_fan_total_number(self): + return self.int_case.get_fan_total_number() + + def get_rotor_number(self, fan_name): + return self.int_case.get_fan_rotor_number(fan_name) + + def get_fan_presence(self, fan_name): + return self.int_case.get_fan_presence(fan_name) + + def get_fan_rotor_status(self, fan_name, rotor_name): + return self.int_case.get_fan_rotor_status(fan_name, rotor_name) + + def get_psu_total_number(self): + return self.int_case.get_psu_total_number() + + def get_psu_presence(self, psu_name): + return self.int_case.get_psu_presence(psu_name) + + def get_psu_input_output_status(self, psu_name): + return self.int_case.get_psu_input_output_status(psu_name) + + def checkFanPresence(self): + absent_num = 0 + + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + rotor_num = self.get_rotor_number(fan_name) + tmp_fan = self.__fan_rotor_error_num.get(fan_name) + status = self.get_fan_presence(fan_name) + if status is False: + absent_num = absent_num + 1 + self.__fan_present_status[fan_name] = 0 + fancontrol_debug("%s absent" % fan_name) + else: + if self.__fan_present_status[fan_name] == 0: # absent -> present + self.__pre_fan_nok = PRE_FAN_NOK_UNKNOWN + self.__fan_plug_in_countdown = self.__fan_plug_in_default_countdown + self.__fan_repair_flag[fan_name] = 1 + for j in range(rotor_num): + rotor_name = "Rotor" + str(j + 1) + tmp_fan[rotor_name] = 0 + self.__fan_present_status[fan_name] = 1 + fancontrol_debug("%s presence" % fan_name) + return absent_num + + def checkFanRotorStatus(self): + err_num = 0 + self.__fan_nok_num = 0 + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + rotor_num = self.get_rotor_number(fan_name) + tmp_fan = self.__fan_rotor_error_num.get(fan_name) + fan_rotor_err_cnt = 0 + for j in range(rotor_num): + rotor_name = "Rotor" + str(j + 1) + status = self.get_fan_rotor_status(fan_name, rotor_name) + if status is True: + tmp_fan[rotor_name] = 0 + fancontrol_debug("%s %s ok" % (fan_name, rotor_name)) + else: + tmp_fan[rotor_name] += 1 + if tmp_fan[rotor_name] >= self.__rotor_error_count: + err_num = err_num + 1 + fan_rotor_err_cnt += 1 + fancontrol_debug("%s %s error" % (fan_name, rotor_name)) + fancontrol_debug("%s %s error %d times" % (fan_name, rotor_name, tmp_fan[rotor_name])) + if fan_rotor_err_cnt == 0: + self.__fan_rotate_status[fan_name] = 1 # FAN is ok + else: + self.__fan_rotate_status[fan_name] = 0 # FAN is not ok + self.__fan_nok_num += 1 + fancontrol_debug("fan not ok number:%d." % self.__fan_nok_num) + return err_num + + def checkPsuPresence(self): + absent_num = 0 + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + status = self.get_psu_presence(psu_name) + if status is False: + absent_num = absent_num + 1 + fancontrol_debug("%s absent" % psu_name) + else: + fancontrol_debug("%s presence" % psu_name) + return absent_num + + def checkPsuStatus(self): + err_num = 0 + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + status = self.get_psu_input_output_status(psu_name) + if status is False: + err_num = err_num + 1 + fancontrol_debug("%s error" % psu_name) + else: + fancontrol_debug("%s ok" % psu_name) + return err_num + + def checkDevError(self): + pwm = self.__min_pwm + switchtemp = self.__temps_threshold_config.get(SWITCH_TEMP)['temp'] + inlettemp = self.__temps_threshold_config.get(INLET_TEMP)['temp'] + temp_diff = abs(switchtemp - inlettemp) + fancontrol_debug("|switchtemp - inlettemp| = %d" % temp_diff) + if temp_diff >= self.__inlet_mac_diff: + fancontrol_debug("temp_diff is over than inlet_mac_diff(%d)" % self.__inlet_mac_diff) + if self.__pwm > self.__abnormal_pwm: + pwm = self.__max_pwm + else: + pwm = self.__abnormal_pwm + return pwm + + def checktempfail(self): + pwm = self.__min_pwm + for temp in self.__check_temp_fail: + temp_name = temp.get("temp_name") + temp_fail_num = self.__temps_threshold_config.get(temp_name)['fail_num'] + if temp_fail_num >= self.__temp_fail_num: + pwm = self.__abnormal_pwm + fancontrol_debug("%s temp_fail_num = %d" % (temp_name, temp_fail_num)) + fancontrol_debug("self.__temp_fail_num = %d" % self.__temp_fail_num) + return pwm + + def abnormal_check(self): + pwm_list = [] + pwm_min = self.__min_pwm + pwm_list.append(pwm_min) + + if self.__check_temp_emergency == 1: + status = self.checkTempEmergency() + if status is True: + over_emerg_pwm = self.__max_pwm + pwm_list.append(over_emerg_pwm) + fancontrol_debug("over_emerg_pwm = 0x%x" % over_emerg_pwm) + # do reset check + if self.__check_emerg_reboot_flag == 1: + self.checkEmergReboot() + else: + if self.checkTempEmergencyCountdown() is True: # temp lower than emergency in 5 min + over_emerg_countdown_pwm = self.__max_pwm + pwm_list.append(over_emerg_countdown_pwm) + fancontrol_debug("TempEmergencyCountdown: %d, over_emerg_countdown_pwm = 0x%x" % + (self.__emergency_countdown, over_emerg_countdown_pwm)) + + if self.__check_temp_critical == 1: + status = self.checkTempCritical() + if status is True: + over_crit_pwm = self.__max_pwm + pwm_list.append(over_crit_pwm) + fancontrol_debug("over_crit_pwm = 0x%x" % over_crit_pwm) + # do reset check + if self.__check_crit_reboot_flag == 1: + self.checkCritReboot() + else: + if self.checkTempCriticalCountdown() is True: # temp lower than critical in 5 min + over_crit_countdown_pwm = self.__max_pwm + pwm_list.append(over_crit_countdown_pwm) + fancontrol_debug("TempCriticalCountdown: %d, over_crit_countdown_pwm = 0x%x" % + (self.__critical_countdown, over_crit_countdown_pwm)) + + if self.__check_temp_warning == 1: + status = self.checkTempWarning() + if status is True: + over_warn_pwm = self.__warning_pwm + pwm_list.append(over_warn_pwm) + fancontrol_debug("over_warn_pwm = 0x%x" % over_warn_pwm) + else: + if self.checkTempWarningCountdown() is True: # temp lower than warning in 5 min + over_warn_countdown_pwm = self.__warning_pwm + pwm_list.append(over_warn_countdown_pwm) + fancontrol_debug("TempWarningCountdown: %d, over_warn_countdown_pwm = 0x%x" % + (self.__warning_countdown, over_warn_countdown_pwm)) + + self.__fan_absent_num = self.checkFanPresence() + if self.__fan_absent_num >= self.__fan_absent_fullspeed_num: + fan_absent_pwm = self.__max_pwm + pwm_list.append(fan_absent_pwm) + fancontrol_debug("fan_absent_pwm = 0x%x" % fan_absent_pwm) + + rotor_err_num = self.checkFanRotorStatus() + if rotor_err_num >= self.__rotor_error_fullspeed_num: + rotor_err_pwm = self.__max_pwm + pwm_list.append(rotor_err_pwm) + fancontrol_debug("rotor_err_pwm = 0x%x" % rotor_err_pwm) + + psu_absent_num = self.checkPsuPresence() + if psu_absent_num >= self.__psu_absent_fullspeed_num: + psu_absent_pwm = self.__max_pwm + pwm_list.append(psu_absent_pwm) + fancontrol_debug("psu_absent_pwm = 0x%x" % psu_absent_pwm) + + dev_err_pwm = self.checkDevError() + pwm_list.append(dev_err_pwm) + fancontrol_debug("dev_err_pwm = 0x%x" % dev_err_pwm) + + temp_fail_pwm = self.checktempfail() + pwm_list.append(temp_fail_pwm) + fancontrol_debug("temp_fail_pwm = 0x%x" % temp_fail_pwm) + + pwm = max(pwm_list) + return pwm + + def get_error_fan(self): + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + if self.__fan_rotate_status[fan_name] == 0: + return fan_name + return None + + def fan_error_update_pwm(self, fan_pwm_dict): + try: + fancontrol_debug("enter deal fan error policy") + ori_fan_pwm_dict = fan_pwm_dict.copy() + + err_fan_name = self.get_error_fan() + if err_fan_name is None: + fancontrol_debug("fan name is None, do nothing.") + return ori_fan_pwm_dict + + if self.__fan_repair_flag[err_fan_name] == 0: + fancontrol_debug("%s already repaired, do nothing." % err_fan_name) + return ori_fan_pwm_dict + + if self.__pre_fan_nok != err_fan_name: + fancontrol_debug( + "not ok fan change from %s to %s, update countdown." % + (self.__pre_fan_nok, err_fan_name)) + self.__deal_fan_error_countdown = self.__deal_fan_error_default_countdown + if self.__pre_fan_nok != PRE_FAN_NOK_UNKNOWN: + fancontrol_debug( + "%s repaire success, %s NOT OK, try to repaire." % + (self.__pre_fan_nok, err_fan_name)) + self.__fan_repair_flag[self.__pre_fan_nok] = 0 + self.__pre_fan_nok = err_fan_name + + if self.__deal_fan_error_countdown > 0: + self.__deal_fan_error_countdown -= 1 + fancontrol_debug("%s repaire, countdown %d." % (err_fan_name, self.__deal_fan_error_countdown)) + + if self.__deal_fan_error_countdown == 0: + self.__fan_repair_flag[err_fan_name] = 0 + fancontrol_debug("%s set repaire fail flag, use origin pwm." % err_fan_name) + return ori_fan_pwm_dict + + fan_err_pwm_conf_list = self.__deal_fan_error_conf[err_fan_name] + for item in fan_err_pwm_conf_list: + fan_pwm_dict[item["name"]] = item["pwm"] + fancontrol_debug("fan pwm update, fan pwm dict:%s" % fan_pwm_dict) + + return fan_pwm_dict + except Exception as e: + fancontrol_error("%%policy: deal_fan_error raise Exception:%s" % str(e)) + self.__pre_fan_nok = PRE_FAN_NOK_UNKNOWN + return ori_fan_pwm_dict + + def get_fan_pwm_dict(self, default_pwm): + fan_pwm_dict = {} + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_pwm_dict[fan_name] = default_pwm + if self.__deal_fan_error_policy: + if self.__fan_absent_num == 0 and self.__fan_nok_num == 1: + fan_pwm_dict = self.fan_error_update_pwm(fan_pwm_dict) + else: + if self.__pre_fan_nok != PRE_FAN_NOK_UNKNOWN and self.__fan_rotate_status[self.__pre_fan_nok] == 1: + fancontrol_debug("%s repaire success." % (self.__pre_fan_nok)) + self.__fan_repair_flag[self.__pre_fan_nok] = 0 + self.__pre_fan_nok = PRE_FAN_NOK_UNKNOWN + return fan_pwm_dict + + def get_psu_pwm_dict(self, default_pwm): + psu_pwm_dict = {} + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + psu_pwm_dict[psu_name] = default_pwm + return psu_pwm_dict + + def check_board_air_flow(self): + board_air_flow = self.board_air_flow + air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) + if board_air_flow not in air_flow_tuple: + fanairflow_debug("get board air flow error, value [%s]" % board_air_flow) + return False + fanairflow_debug("board air flow check ok: %s" % board_air_flow) + return True + + def check_fan_air_flow(self): + if self.fan_air_flow_monitor: + fanairflow_debug("open air flow monitor, check fan air flow") + ret = self.check_board_air_flow() + if ret is False: + fanairflow_debug("get board air flow error, set fan_air_flow_inconsistent_flag False") + self.fan_air_flow_inconsistent_flag = False + return + air_flow_inconsistent_flag_tmp = False + for fan_obj in self.fan_obj_list: + fan_obj.update_fru_info() + fanairflow_debug("%s origin name: [%s], display name: [%s] air flow [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow)) + if fan_obj.air_flow == self.na_ret: + fanairflow_debug("%s get air flow failed, set air_flow_inconsistent flag False" % fan_obj.name) + fan_obj.air_flow_inconsistent = False + continue + if fan_obj.air_flow != self.board_air_flow: + fanairflow_debug("%s air flow error, origin name: [%s], display name: [%s], fan air flow [%s], board air flow [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow)) + air_flow_inconsistent_flag_tmp = True + fan_obj.air_flow_inconsistent = True + else: + fanairflow_debug("%s air flow check ok, origin name: [%s], display name: [%s], fan air flow: [%s], board air flow: [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow)) + fan_obj.air_flow_inconsistent = False + self.fan_air_flow_inconsistent_flag = air_flow_inconsistent_flag_tmp + else: + fanairflow_debug("air flow monitor not open, set fan_air_flow_inconsistent_flag False") + self.fan_air_flow_inconsistent_flag = False + return + + def check_psu_air_flow(self): + if self.psu_air_flow_monitor: + fanairflow_debug("open air flow monitor, check psu air flow") + ret = self.check_board_air_flow() + if ret is False: + fanairflow_debug("get board air flow error, set psu_air_flow_inconsistent_flag False") + self.psu_air_flow_inconsistent_flag = False + return + air_flow_inconsistent_flag_tmp = False + for psu_obj in self.psu_obj_list: + psu_obj.update_fru_info() + fanairflow_debug("%s origin name: [%s], display name: [%s] air flow [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow)) + if psu_obj.air_flow == self.na_ret: + fanairflow_debug("%s get air flow failed, set air_flow_inconsistent flag False" % psu_obj.name) + psu_obj.air_flow_inconsistent = False + continue + if psu_obj.air_flow != self.board_air_flow: + fanairflow_debug("%s air flow error, origin name: [%s], display name: [%s], psu air flow [%s], board air flow [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow)) + air_flow_inconsistent_flag_tmp = True + psu_obj.air_flow_inconsistent = True + else: + fanairflow_debug("%s air flow check ok, origin name: [%s], display name: [%s], psu air flow: [%s], board air flow: [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow)) + psu_obj.air_flow_inconsistent = False + self.psu_air_flow_inconsistent_flag = air_flow_inconsistent_flag_tmp + else: + fanairflow_debug("air flow monitor not open, set psu_air_flow_inconsistent_flag False") + self.psu_air_flow_inconsistent_flag = False + return + + def do_fancontrol(self): + pwm_list = [] + pwm_min = self.__min_pwm + pwm_list.append(pwm_min) + + # first check air flow + self.check_fan_air_flow() + self.check_psu_air_flow() + if self.fan_air_flow_inconsistent_flag is True or self.psu_air_flow_inconsistent_flag is True: + self.air_flow_inconsistent_flag = True + else: + self.air_flow_inconsistent_flag = False + fanairflow_debug("check_air_flow, air_flow_inconsistent_flag: %s" % self.air_flow_inconsistent_flag) + # get_monitor_temp + self.get_monitor_temp() + fancontrol_debug("last_pwm = 0x%x" % self.__pwm) + # openloop + inlettemp = self.__temps_threshold_config.get(INLET_TEMP)['temp'] + linear_value = self.openloop.linear_cacl(inlettemp) + if linear_value is None: + linear_value = self.__min_pwm + pwm_list.append(linear_value) + fancontrol_debug("linear_value = 0x%x" % linear_value) + + curve_value = self.openloop.curve_cacl(inlettemp) + if curve_value is None: + curve_value = self.__min_pwm + pwm_list.append(curve_value) + fancontrol_debug("curve_value = 0x%x" % curve_value) + + # hyst + for hyst_index in self.__hyst_config.values(): + temp_name = hyst_index.get("name") + hyst_flag = hyst_index.get("flag", 0) + if hyst_flag == 0: + fancontrol_debug("%s hyst flag is 0, do nothing" % temp_name) + continue + tmp_temp = int(self.__temps_threshold_config.get(temp_name)['temp']) # make sure temp is int + hyst_value = self.hyst.cacl(temp_name, tmp_temp) + if hyst_value is None: + hyst_value = self.__min_pwm + pwm_list.append(hyst_value) + fancontrol_debug("%s hyst_value = 0x%x" % (temp_name, hyst_value)) + + # pid + for pid_index in self.__pid_config.values(): + temp_name = pid_index.get("name") + pid_flag = pid_index.get("flag", 0) + if pid_flag == 0: + fancontrol_debug("%s pid flag is 0, do nothing" % temp_name) + continue + tmp_temp = self.__temps_threshold_config.get(temp_name)['temp'] + if tmp_temp is not None: + tmp_temp = int(tmp_temp) # make sure temp is int + invalid_temp_val = self.__temps_threshold_config.get(temp_name)['invalid'] + error_temp_val = self.__temps_threshold_config.get(temp_name)['error'] + if tmp_temp == invalid_temp_val: # temp is invalid + temp = None + self.pid.cacl(self.__pwm, temp_name, temp) # temp invalid, PID need to record None + pid_value = self.__temp_invalid_pid_pwm + fancontrol_debug("%s is invalid, pid_value = 0x%x" % (temp_name, pid_value)) + fancontrol_debug("temp = %d, invalid_temp = %d" % (tmp_temp, invalid_temp_val)) + elif tmp_temp == error_temp_val: # temp is error + temp = None + self.pid.cacl(self.__pwm, temp_name, temp) # temp error, PID need to record None + pid_value = self.__temp_error_pid_pwm + fancontrol_debug("%s is error, pid_value = 0x%x" % (temp_name, pid_value)) + fancontrol_debug("temp = %d, error_temp = %d" % (tmp_temp, error_temp_val)) + else: + pid_value = self.pid.cacl(self.__pwm, temp_name, tmp_temp) + else: # temp get failed + pid_value = self.pid.cacl(self.__pwm, temp_name, tmp_temp) + if pid_value is None: + pid_value = self.__min_pwm + pwm_list.append(pid_value) + fancontrol_debug("%s pid_value = 0x%x" % (temp_name, pid_value)) + + # abnormal + abnormal_value = self.abnormal_check() + pwm_list.append(abnormal_value) + fancontrol_debug("abnormal_value = 0x%x" % abnormal_value) + + if self.__fan_plug_in_countdown > 0 and self.__fan_absent_num == 0: + fancontrol_debug("fan plug in countdown %d, set plug in pwm: 0x%x" % + (self.__fan_plug_in_countdown, self.__fan_plug_in_pwm)) + self.__pwm = self.__fan_plug_in_pwm + self.__fan_plug_in_countdown -= 1 + else: + self.__pwm = max(pwm_list) + fancontrol_debug("__pwm = 0x%x\n" % self.__pwm) + if self.air_flow_inconsistent_flag is True: + fanairflow_debug("air flow inconsistent, set all fan speed pwm") + self.set_all_fan_speed_pwm(self.__pwm) + else: + fanairflow_debug("air flow consistent, deal fan error policy") + fan_pwm_dict = self.get_fan_pwm_dict(self.__pwm) + psu_pwm_dict = self.get_psu_pwm_dict(self.__pwm) + self.set_fan_pwm_independent(fan_pwm_dict, psu_pwm_dict) + + def run(self): + start_time = time.time() + while True: + try: + debug_init() + if self.__fan_status_interval > 0 and self.__fan_status_interval < self.__interval: + delta_time = time.time() - start_time + if delta_time >= self.__interval or delta_time < 0: + self.do_fancontrol() + start_time = time.time() + else: + self.checkFanPresence() + time.sleep(self.__fan_status_interval) + else: + self.do_fancontrol() + time.sleep(self.__interval) + except Exception as e: + traceback.print_exc() + fancontrol_error(str(e)) + + def set_all_fan_speed_pwm(self, pwm): + fan_pwm_dict = {} + psu_pwm_dict = {} + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_pwm_dict[fan_name] = pwm + + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + psu_pwm_dict[psu_name] = pwm + self.set_fan_pwm_independent(fan_pwm_dict, psu_pwm_dict) + + def set_fan_pwm_independent(self, fan_pwm_dict, psu_pwm_dict): + if self.air_flow_inconsistent_flag is True: + for psu_obj in self.psu_obj_list: + if psu_obj.air_flow_inconsistent is True: + psu_pwm_dict[psu_obj.name] = self.air_flow_error_psu_pwm + fanairflow_debug("%s air flow error, origin name: [%s], display name: [%s], psu air flow: [%s], board air flow: [%s], set psu pwm: 0x%x" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow, self.air_flow_error_psu_pwm)) + else: + psu_pwm_dict[psu_obj.name] = self.air_flow_correct_psu_pwm + fanairflow_debug("%s air flow correct, origin name: [%s], display name: [%s], psu air flow: [%s], board air flow: [%s], set psu pwm: 0x%x" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow, self.air_flow_correct_psu_pwm)) + + for fan_obj in self.fan_obj_list: + if fan_obj.air_flow_inconsistent is True: + fan_pwm_dict[fan_obj.name] = self.air_flow_error_fan_pwm + fanairflow_debug("%s air flow error, origin name: [%s], display name: [%s], fan air flow: [%s], board air flow: [%s], set fan pwm: 0x%x" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow, self.air_flow_error_fan_pwm)) + else: + fan_pwm_dict[fan_obj.name] = self.air_flow_correct_fan_pwm + fanairflow_debug("%s air flow correct, origin name: [%s], display name: [%s], fan air flow: [%s], board air flow: [%s], set fan pwm: 0x%x" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow, self.air_flow_correct_fan_pwm)) + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + self.fan_set_speed_pwm_by_name(fan_name, fan_pwm_dict[fan_name]) + if self.__psu_fan_control == 1: + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + self.psu_set_speed_pwm_by_name(psu_name, psu_pwm_dict[psu_name]) + + def fan_set_speed_pwm_by_name(self, fan_name, pwm): + duty = round(pwm * 100 / 255) + rotor_len = self.get_rotor_number(fan_name) + for i in range(rotor_len): + val = self.int_case.set_fan_speed_pwm(fan_name, i + 1, duty) + if val != 0: + fancontrol_error("%s rotor%d: %d" % (fan_name, i + 1, val)) + + def psu_set_speed_pwm_by_name(self, psu_name, pwm): + duty = round(pwm * 100 / 255) + status = self.int_case.set_psu_fan_speed_pwm(psu_name, int(duty)) + if status is not True: + fancontrol_error("set %s speed fail" % psu_name) + + def fan_obj_init(self): + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_obj = DevFan(fan_name, self.int_case) + self.fan_obj_list.append(fan_obj) + fanairflow_debug("fan object initialize success") + + def psu_obj_init(self): + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + psu_obj = DevPsu(psu_name, self.int_case) + self.psu_obj_list.append(psu_obj) + fanairflow_debug("psu object initialize success") + + +if __name__ == '__main__': + debug_init() + fancontrol_debug("enter main") + fan_control = fancontrol() + fan_control.fan_obj_init() + fan_control.psu_obj_init() + fan_control.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_ledctrl.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_ledctrl.py new file mode 100755 index 000000000000..c21fd3c1f585 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_ledctrl.py @@ -0,0 +1,830 @@ +#!/usr/bin/env python3 +import time +import syslog +import traceback +from plat_hal.interface import interface +from plat_hal.baseutil import baseutil +try: + import abc +except ImportError as error: + raise ImportError(str(error) + " - required module not found") from error + +SWITCH_TEMP = "SWITCH_TEMP" +F2B_AIR_FLOW = "intake" +B2F_AIR_FLOW = "exhaust" +ONIE_E2_NAME = "ONIE_E2" + +# status +STATUS_PRESENT = "PRESENT" +STATUS_ABSENT = "ABSENT" +STATUS_OK = "OK" +STATUS_NOT_OK = "NOT OK" +STATUS_FAILED = "FAILED" +STATUS_UNKNOWN = "UNKNOWN" + +LEDCTROL_DEBUG_FILE = "/etc/.ledcontrol_debug_flag" + +LEDCTROLERROR = 1 +LEDCTROLDEBUG = 2 + +debuglevel = 0 +# led status defined +COLOR_GREEN = 1 +COLOR_AMBER = 2 +COLOR_RED = 3 +LED_STATUS_DICT = {COLOR_GREEN: "green", COLOR_AMBER: "amber", COLOR_RED: "red"} + + +def ledcontrol_debug(s): + if LEDCTROLDEBUG & debuglevel: + syslog.openlog("LEDCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def ledcontrol_error(s): + if LEDCTROLERROR & debuglevel: + syslog.openlog("LEDCONTROL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def air_flow_warn(s): + syslog.openlog("AIR_FLOW_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_WARNING, s) + + +def air_flow_error(s): + syslog.openlog("AIR_FLOW_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_ERR, s) + + +def air_flow_emerg(s): + syslog.openlog("AIR_FLOW_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_EMERG, s) + + +def debug_init(): + global debuglevel + try: + with open(LEDCTROL_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + +class DevBase(object): + __metaclass__ = abc.ABCMeta + + def __init__(self, name, air_flow_monitor): + self.__name = name + self.__air_flow_monitor = air_flow_monitor + self.present = STATUS_UNKNOWN + self.status = STATUS_UNKNOWN + self.status_summary = STATUS_UNKNOWN + self.origin_name = STATUS_UNKNOWN + self.display_name = STATUS_UNKNOWN + self.air_flow = STATUS_UNKNOWN + self.led_status = COLOR_GREEN + + @property + def name(self): + return self.__name + + @property + def air_flow_monitor(self): + return self.__air_flow_monitor + + @abc.abstractmethod + def get_present(self): + """ + Gets the present status of PSU/FAN + + Returns: + A string, e.g. 'PRESENT, ABSENT, FAILED' + """ + raise NotImplementedError + + @abc.abstractmethod + def get_status(self): + """ + Gets the status of PSU/FAN + + Returns: + A string, e.g. 'OK, NOT OK, FAILED' + """ + raise NotImplementedError + + @abc.abstractmethod + def update_dev_info(self): + """ + update status and fru info of PSU/FAN + + include present, status, status_summary, part_model_name, product_name, air_flow + """ + raise NotImplementedError + + @abc.abstractmethod + def set_module_led(self, color): + """ + set PSU/FAN module LED status + + Args: + color: A string representing the color with which to set the + PSU/FAN module LED status + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + +class DevPsu(DevBase): + + def __init__(self, name, air_flow_monitor, hal_interface): + super(DevPsu, self).__init__(name, air_flow_monitor) + self.int_case = hal_interface + + def get_psu_presence(self): + return self.int_case.get_psu_presence(self.name) + + def get_psu_input_output_status(self): + return self.int_case.get_psu_input_output_status(self.name) + + def get_psu_fru_info(self): + return self.int_case.get_psu_fru_info(self.name) + + @property + def na_ret(self): + return self.int_case.na_ret + + def get_present(self): + try: + status = self.get_psu_presence() + if status is True: + return STATUS_PRESENT + if status is False: + return STATUS_ABSENT + except Exception as e: + ledcontrol_error("get %s present status error, msg: %s" % (self.name, str(e))) + return STATUS_FAILED + + def get_status(self): + try: + status = self.get_psu_input_output_status() + if status is True: + return STATUS_OK + if status is False: + return STATUS_NOT_OK + except Exception as e: + ledcontrol_error("get %s status error, msg: %s" % (self.name, str(e))) + return STATUS_FAILED + + def update_dev_info(self): + try: + # update status + self.present = self.get_present() + if self.present != STATUS_PRESENT: + self.status = STATUS_UNKNOWN + self.status_summary = self.present + else: + self.status = self.get_status() + self.status_summary = self.status + # update fru info if need air flow monitor + if self.air_flow_monitor: + dic = self.get_psu_fru_info() + self.origin_name = dic["PN"] + self.air_flow = dic["AirFlow"] + self.display_name = dic["DisplayName"] + except Exception as e: + ledcontrol_error("update %s info error, msg: %s" % (self.name, str(e))) + self.present = STATUS_FAILED + self.status = STATUS_FAILED + self.status_summary = STATUS_FAILED + self.origin_name = self.na_ret + self.air_flow = self.na_ret + self.display_name = self.na_ret + + def set_module_led(self, color): + """ + set PSU module LED is not support, always return True + """ + return True + + +class DevFan(DevBase): + + def __init__(self, name, air_flow_monitor, hal_interface): + super(DevFan, self).__init__(name, air_flow_monitor) + self.int_case = hal_interface + + def get_fan_rotor_number(self): + return self.int_case.get_fan_rotor_number(self.name) + + def get_fan_presence(self): + return self.int_case.get_fan_presence(self.name) + + def get_fan_rotor_status(self, rotor_name): + return self.int_case.get_fan_rotor_status(self.name, rotor_name) + + def get_fan_fru_info(self): + return self.int_case.get_fan_fru_info(self.name) + + @property + def na_ret(self): + return self.int_case.na_ret + + def get_present(self): + try: + status = self.get_fan_presence() + if status is True: + return STATUS_PRESENT + if status is False: + return STATUS_ABSENT + except Exception as e: + ledcontrol_error("get %s present status error, msg: %s" % (self.name, str(e))) + return STATUS_FAILED + + def get_status(self): + try: + rotor_num = self.get_fan_rotor_number() + err_motor_num = 0 + for j in range(rotor_num): + rotor_name = "Rotor" + str(j + 1) + roll_status = self.get_fan_rotor_status(rotor_name) + if roll_status is not True: + err_motor_num += 1 + ledcontrol_debug("%s %s error, status %s" % (self.name, rotor_name, roll_status)) + else: + ledcontrol_debug("%s %s ok" % (self.name, rotor_name)) + if err_motor_num > 0: + return STATUS_NOT_OK + return STATUS_OK + except Exception as e: + ledcontrol_error("get %s status error, msg: %s" % (self.name, str(e))) + return STATUS_FAILED + + def update_dev_info(self): + try: + # update status + self.present = self.get_present() + if self.present != STATUS_PRESENT: + self.status = STATUS_UNKNOWN + self.status_summary = self.present + else: + self.status = self.get_status() + self.status_summary = self.status + # update fru info if need air flow monitor + if self.air_flow_monitor: + dic = self.get_fan_fru_info() + self.origin_name = dic["PN"] + self.air_flow = dic["AirFlow"] + self.display_name = dic["DisplayName"] + except Exception as e: + ledcontrol_error("update %s fru info error, msg: %s" % (self.name, str(e))) + self.present = STATUS_FAILED + self.status = STATUS_FAILED + self.status_summary = STATUS_FAILED + self.origin_name = self.na_ret + self.air_flow = self.na_ret + self.display_name = self.na_ret + + def set_module_led(self, color): + ret = self.int_case.set_fan_led(self.name, color) + if ret == 0: + return True + return False + + +class ledcontrol(object): + + def __init__(self): + self.fan_obj_list = [] + self.psu_obj_list = [] + self.board_psu_led_status = COLOR_GREEN + self.board_fan_led_status = COLOR_GREEN + self.__board_air_flow = "" + self.int_case = interface() + self.__config = baseutil.get_monitor_config() + self.__temps_threshold_config = self.__config["temps_threshold"] + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['temp'] = 0 + temp_threshold['fail_num'] = 0 + self.__ledcontrol_para = self.__config["ledcontrol_para"] + self.__interval = self.__ledcontrol_para.get("interval", 5) + self.__checkpsu = self.__ledcontrol_para.get("checkpsu", 0) + self.__checkfan = self.__ledcontrol_para.get("checkfan", 0) + self.__psu_amber_num = self.__ledcontrol_para.get("psu_amber_num") + self.__fan_amber_num = self.__ledcontrol_para.get("fan_amber_num") + self.__psu_air_flow_amber_num = self.__ledcontrol_para.get("psu_air_flow_amber_num", 0) + self.__fan_air_flow_amber_num = self.__ledcontrol_para.get("fan_air_flow_amber_num", 0) + self.__board_sys_led = self.__ledcontrol_para.get("board_sys_led", []) + self.__board_psu_led = self.__ledcontrol_para.get("board_psu_led", []) + self.__board_fan_led = self.__ledcontrol_para.get("board_fan_led", []) + self.__psu_air_flow_monitor = self.__ledcontrol_para.get("psu_air_flow_monitor", 0) + self.__fan_air_flow_monitor = self.__ledcontrol_para.get("fan_air_flow_monitor", 0) + self.__fan_mix_list = self.__ledcontrol_para.get("fan_mix_list", []) + + @property + def na_ret(self): + return self.int_case.na_ret + + @property + def checkpsu(self): + return self.__checkpsu + + @property + def checkfan(self): + return self.__checkfan + + @property + def psu_amber_num(self): + return self.__psu_amber_num + + @property + def fan_amber_num(self): + return self.__fan_amber_num + + @property + def psu_air_flow_amber_num(self): + return self.__psu_air_flow_amber_num + + @property + def fan_air_flow_amber_num(self): + return self.__fan_air_flow_amber_num + + @property + def psu_air_flow_monitor(self): + return self.__psu_air_flow_monitor + + @property + def fan_air_flow_monitor(self): + return self.__fan_air_flow_monitor + + @property + def board_sys_led(self): + return self.__board_sys_led + + @property + def board_psu_led(self): + return self.__board_psu_led + + @property + def board_fan_led(self): + return self.__board_fan_led + + @property + def fan_mix_list(self): + return self.__fan_mix_list + + @property + def interval(self): + return self.__interval + + def get_fan_total_number(self): + return self.int_case.get_fan_total_number() + + def get_psu_total_number(self): + return self.int_case.get_psu_total_number() + + def get_onie_e2_obj(self, name): + return self.int_case.get_onie_e2_obj(name) + + def set_led_color(self, led_name, color): + try: + ret = self.int_case.set_led_color(led_name, color) + except Exception as e: + ledcontrol_error("set %s led %s error, msg: %s" % (led_name, color, str(e))) + ret = False + return ret + + def set_sys_led(self, color): + for led in self.board_sys_led: + led_name = led.get("led_name") + ret = self.set_led_color(led_name, color) + if ret is True: + ledcontrol_debug("set %s success, color:%s," % (led_name, color)) + else: + ledcontrol_debug("set %s failed, color:%s," % (led_name, color)) + + def set_psu_led(self, color): + for led in self.board_psu_led: + led_name = led.get("led_name") + ret = self.set_led_color(led_name, color) + if ret is True: + ledcontrol_debug("set %s success, color:%s," % (led_name, color)) + else: + ledcontrol_debug("set %s failed, color:%s," % (led_name, color)) + + def set_fan_led(self, color): + for led in self.board_fan_led: + led_name = led.get("led_name") + ret = self.set_led_color(led_name, color) + if ret is True: + ledcontrol_debug("set %s success, color:%s," % (led_name, color)) + else: + ledcontrol_debug("set %s failed, color:%s," % (led_name, color)) + + def set_fan_module_led(self): + for fan_obj in self.fan_obj_list: + color = LED_STATUS_DICT.get(fan_obj.led_status) + ret = fan_obj.set_module_led(color) + if ret is True: + ledcontrol_debug("set %s module led success, color: %s," % (fan_obj.name, color)) + else: + ledcontrol_debug("set %s module led failed, color: %s," % (fan_obj.name, color)) + + @property + def board_air_flow(self): + air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) + if self.__board_air_flow not in air_flow_tuple: + self.__board_air_flow = self.int_case.get_device_airflow(ONIE_E2_NAME) + ledcontrol_debug("board_air_flow: %s" % self.__board_air_flow) + return self.__board_air_flow + + def update_psu_info(self): + for psu_obj in self.psu_obj_list: + psu_obj.update_dev_info() + ledcontrol_debug("%s present: [%s], status: [%s] status_summary [%s]" % + (psu_obj.name, psu_obj.present, psu_obj.status, psu_obj.status_summary)) + if psu_obj.air_flow_monitor: + ledcontrol_debug("%s origin name: [%s], display name: [%s] air flow [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow)) + + def update_fan_info(self): + for fan_obj in self.fan_obj_list: + fan_obj.update_dev_info() + ledcontrol_debug("%s present: [%s], status: [%s] status_summary [%s]" % + (fan_obj.name, fan_obj.present, fan_obj.status, fan_obj.status_summary)) + if fan_obj.air_flow_monitor: + ledcontrol_debug("%s origin name: [%s], display name: [%s] air flow [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow)) + + def get_monitor_temp(self): + sensorlist = self.int_case.get_temp_info() + + for temp_threshold in self.__temps_threshold_config.values(): + sensor = sensorlist.get(temp_threshold['name']) + if sensor["Value"] is None: + temp_threshold['fail_num'] += 1 + ledcontrol_error("get %s failed, fail_num = %d" % (temp_threshold['name'], temp_threshold['fail_num'])) + else: + temp_threshold['fail_num'] = 0 + temp_threshold.setdefault('fix', 0) + temp_threshold['temp'] = sensor["Value"] + temp_threshold['fix'] + ledcontrol_debug("%s = %d" % (temp_threshold['name'], temp_threshold['temp'])) + ledcontrol_debug("warning = %d, critical = %d" % (temp_threshold['warning'], temp_threshold['critical'])) + + def is_temp_warning(self): + warning_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + if temp_threshold['temp'] >= temp_threshold['warning']: + warning_flag = True + ledcontrol_debug("%s is over warning" % temp_threshold['name']) + ledcontrol_debug( + "%s = %d, warning = %d" % + (temp_threshold['name'], + temp_threshold['temp'], + temp_threshold['warning'])) + return warning_flag + + def checkTempWarning(self): + try: + if self.is_temp_warning(): + ledcontrol_debug("temp is over warning") + return True + except Exception as e: + ledcontrol_error("%%policy: checkTempWarning failed") + ledcontrol_error(str(e)) + return False + + def is_temp_critical(self): + critical_flag = False + for temp_threshold in self.__temps_threshold_config.values(): + temp_threshold['critical_flag'] = False + if temp_threshold['temp'] >= temp_threshold['critical']: + critical_flag = True + temp_threshold['critical_flag'] = True + ledcontrol_debug("%s is over critical" % temp_threshold['name']) + ledcontrol_debug( + "%s = %d, critical = %d" % + (temp_threshold['name'], + temp_threshold['temp'], + temp_threshold['critical'])) + return critical_flag + + def checkTempCrit(self): + try: + if self.is_temp_critical(): + temp_dict = dict(self.__temps_threshold_config) + tmp = temp_dict.get(SWITCH_TEMP) + if tmp['critical_flag'] is True: + ledcontrol_debug("temp is over critical") + return True + + del temp_dict[SWITCH_TEMP] + for temp_items in temp_dict.values(): + if temp_items['critical_flag'] is False: + return False + + ledcontrol_debug("temp is over critical") + return True + except Exception as e: + ledcontrol_error("%%policy: checkTempCrit failed") + ledcontrol_error(str(e)) + return False + + def check_board_air_flow(self): + board_air_flow = self.board_air_flow + air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) + if board_air_flow not in air_flow_tuple: + air_flow_error("%%AIR_FLOW_MONITOR-3-BOARD: Get board air flow failed, value: %s." % board_air_flow) + return False + ledcontrol_debug("board air flow check ok: %s" % board_air_flow) + return True + + def get_monitor_fan_status(self): + fanerrnum = 0 + for fan_obj in self.fan_obj_list: + status = fan_obj.status_summary + ledcontrol_debug("%s status: %s" % (fan_obj.name, status)) + if status != STATUS_OK: + fan_obj.led_status = COLOR_RED + fanerrnum += 1 + else: + fan_obj.led_status = COLOR_GREEN + ledcontrol_debug("fan error number: %d" % fanerrnum) + + if fanerrnum == 0: + fan_led_status = COLOR_GREEN + elif fanerrnum <= self.fan_amber_num: + fan_led_status = COLOR_AMBER + else: + fan_led_status = COLOR_RED + ledcontrol_debug("monitor fan status, set fan led: %s" % LED_STATUS_DICT.get(fan_led_status)) + return fan_led_status + + def get_monitor_psu_status(self): + psuerrnum = 0 + for psu_obj in self.psu_obj_list: + status = psu_obj.status_summary + ledcontrol_debug("%s status: %s" % (psu_obj.name, status)) + if status != STATUS_OK: + psu_obj.led_status = COLOR_RED + psuerrnum += 1 + else: + psu_obj.led_status = COLOR_GREEN + ledcontrol_debug("psu error number: %d" % psuerrnum) + + if psuerrnum == 0: + psu_led_status = COLOR_GREEN + elif psuerrnum <= self.psu_amber_num: + psu_led_status = COLOR_AMBER + else: + psu_led_status = COLOR_RED + ledcontrol_debug("monitor psu status, set psu led: %s" % LED_STATUS_DICT.get(psu_led_status)) + return psu_led_status + + def get_monitor_fan_air_flow(self): + if self.fan_air_flow_monitor == 0: + ledcontrol_debug("fan air flow monitor not open, default green") + return COLOR_GREEN + + ret = self.check_board_air_flow() + if ret is False: + ledcontrol_debug("check board air flow error, skip fan air flow monitor.") + return COLOR_GREEN + + fan_led_status_list = [] + fan_air_flow_ok_obj_list = [] + fan_air_flow_ok_set = set() + fan_module_led_list = [] + fan_air_flow_err_num = 0 + for fan_obj in self.fan_obj_list: + if fan_obj.present != STATUS_PRESENT: + fan_module_led_list.append(COLOR_GREEN) + continue + if fan_obj.air_flow == self.na_ret: + air_flow_warn("%%AIR_FLOW_MONITOR-4-FAN: %s get air flow failed, fan model: %s, air flow: %s." % + (fan_obj.name, fan_obj.display_name, fan_obj.air_flow)) + led_status = COLOR_AMBER + fan_module_led_list.append(led_status) + elif fan_obj.air_flow != self.board_air_flow: + air_flow_emerg("%%AIR_FLOW_MONITOR-0-FAN: %s air flow error, fan model: %s, fan air flow: %s, board air flow: %s." % + (fan_obj.name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow)) + led_status = COLOR_RED + fan_air_flow_err_num += 1 + else: + fan_air_flow_ok_obj_list.append(fan_obj) + fan_air_flow_ok_set.add(fan_obj.origin_name) + ledcontrol_debug("%s air flow check ok, origin name: [%s], display name: [%s], fan air flow: [%s], board air flow: [%s]" % + (fan_obj.name, fan_obj.origin_name, fan_obj.display_name, fan_obj.air_flow, self.board_air_flow)) + led_status = COLOR_GREEN + fan_module_led_list.append(led_status) + if led_status > fan_obj.led_status: + fan_obj.led_status = led_status + if len(fan_module_led_list) != 0: + fan_led_status = max(fan_module_led_list) + fan_led_status_list.append(fan_led_status) + # check fan mixing + if len(fan_air_flow_ok_set) > 1 and fan_air_flow_ok_set not in self.fan_mix_list: + for fan_obj in fan_air_flow_ok_obj_list: + air_flow_warn("%%AIR_FLOW_MONITOR-4-FAN: %s mixing, fan model: %s, air flow: %s." % + (fan_obj.name, fan_obj.origin_name, fan_obj.air_flow)) + fan_led_status = COLOR_AMBER + fan_led_status_list.append(fan_led_status) + # check fan air flow error number + if fan_air_flow_err_num == 0: + fan_led_status = COLOR_GREEN + elif fan_air_flow_err_num <= self.fan_air_flow_amber_num: + fan_led_status = COLOR_AMBER + else: + fan_led_status = COLOR_RED + fan_led_status_list.append(fan_led_status) + + fan_led_status = max(fan_led_status_list) + ledcontrol_debug("monitor fan air flow, set fan led: %s" % LED_STATUS_DICT.get(fan_led_status)) + return fan_led_status + + def get_monitor_psu_air_flow(self): + if self.psu_air_flow_monitor == 0: + ledcontrol_debug("psu air flow monitor not open, default green") + return COLOR_GREEN + + ret = self.check_board_air_flow() + if ret is False: + ledcontrol_debug("check board air flow error, skip psu air flow monitor.") + return COLOR_GREEN + + psu_led_status_list = [] + psu_module_led_list = [] + psu_air_flow_err_num = 0 + for psu_obj in self.psu_obj_list: + if psu_obj.present != STATUS_PRESENT: + psu_module_led_list.append(COLOR_GREEN) + continue + if psu_obj.air_flow == self.na_ret: + air_flow_warn("%%AIR_FLOW_MONITOR-4-PSU: %s get air flow failed, psu model: %s, air flow: %s." % + (psu_obj.name, psu_obj.display_name, psu_obj.air_flow)) + led_status = COLOR_AMBER + psu_module_led_list.append(led_status) + elif psu_obj.air_flow != self.board_air_flow: + air_flow_emerg("%%AIR_FLOW_MONITOR-0-PSU: %s air flow error, psu model: %s, psu air flow: %s, board air flow: %s." % + (psu_obj.name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow)) + led_status = COLOR_RED + psu_air_flow_err_num += 1 + else: + ledcontrol_debug("%s psu air flow check ok, origin name: [%s], display name: [%s], psu air flow: [%s], board air flow: [%s]" % + (psu_obj.name, psu_obj.origin_name, psu_obj.display_name, psu_obj.air_flow, self.board_air_flow)) + led_status = COLOR_GREEN + psu_module_led_list.append(led_status) + if led_status > psu_obj.led_status: + psu_obj.led_status = led_status + + if len(psu_module_led_list) != 0: + psu_led_status = max(psu_module_led_list) + psu_led_status_list.append(psu_led_status) + + # check fan air flow error number + if psu_air_flow_err_num == 0: + psu_led_status = COLOR_GREEN + elif psu_air_flow_err_num <= self.psu_air_flow_amber_num: + psu_led_status = COLOR_AMBER + else: + psu_led_status = COLOR_RED + psu_led_status_list.append(psu_led_status) + + psu_led_status = max(psu_led_status_list) + ledcontrol_debug("monitor psu air flow, set psu led: %s" % LED_STATUS_DICT.get(psu_led_status)) + return psu_led_status + + def get_temp_sys_led_status(self): + if self.checkTempCrit() is True: + sys_led_status = COLOR_RED + elif self.checkTempWarning() is True: + sys_led_status = COLOR_AMBER + else: + sys_led_status = COLOR_GREEN + ledcontrol_debug("monitor temperature, set sys led: %s" % LED_STATUS_DICT.get(sys_led_status)) + return sys_led_status + + def get_sys_led_follow_fan_status(self): + + if self.checkfan: + sys_led_status = self.board_fan_led_status + ledcontrol_debug("sys led follow fan led, set sys led: %s" % LED_STATUS_DICT.get(sys_led_status)) + else: + sys_led_status = COLOR_GREEN + ledcontrol_debug("sys led don't follow fan led, set default green") + return sys_led_status + + def get_sys_led_follow_psu_status(self): + if self.checkpsu: + sys_led_status = self.board_psu_led_status + ledcontrol_debug("sys led follow psu led, set sys led: %s" % LED_STATUS_DICT.get(sys_led_status)) + else: + sys_led_status = COLOR_GREEN + ledcontrol_debug("sys led don't follow psu led, set default green") + return sys_led_status + + def dealSysLedStatus(self): + sys_led_status_list = [] + # get_monitor_temp + self.get_monitor_temp() + + # monitor temp get sys led status + sys_led_status = self.get_temp_sys_led_status() + sys_led_status_list.append(sys_led_status) + + # check sys led follow fan led status + sys_led_status = self.get_sys_led_follow_fan_status() + sys_led_status_list.append(sys_led_status) + + # check sys led follow psu led status + sys_led_status = self.get_sys_led_follow_psu_status() + sys_led_status_list.append(sys_led_status) + + sys_led_status = max(sys_led_status_list) + sys_led_color = LED_STATUS_DICT.get(sys_led_status) + + # set sys led + self.set_sys_led(sys_led_color) + + def dealFanLedStatus(self): + fan_led_status_list = [] + # update fan info + self.update_fan_info() + + # monitor fan status first + fan_led_status = self.get_monitor_fan_status() + fan_led_status_list.append(fan_led_status) + + # monitor fan air flow + fan_led_status = self.get_monitor_fan_air_flow() + fan_led_status_list.append(fan_led_status) + + self.board_fan_led_status = max(fan_led_status_list) + fan_led_color = LED_STATUS_DICT.get(self.board_fan_led_status) + + # set fan led + self.set_fan_led(fan_led_color) + # set fan module led + self.set_fan_module_led() + + def dealPsuLedStatus(self): + psu_led_status_list = [] + # update psu info + self.update_psu_info() + + # monitor psu status first + psu_led_status = self.get_monitor_psu_status() + psu_led_status_list.append(psu_led_status) + + # monitor psu air flow + psu_led_status = self.get_monitor_psu_air_flow() + psu_led_status_list.append(psu_led_status) + + self.board_psu_led_status = max(psu_led_status_list) + psu_led_color = LED_STATUS_DICT.get(self.board_psu_led_status) + + # set psu led + self.set_psu_led(psu_led_color) + + def do_ledcontrol(self): + self.dealPsuLedStatus() + self.dealFanLedStatus() + self.dealSysLedStatus() + + def fan_obj_init(self): + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_obj = DevFan(fan_name, self.fan_air_flow_monitor, self.int_case) + self.fan_obj_list.append(fan_obj) + ledcontrol_debug("fan object initialize success") + + def psu_obj_init(self): + psu_num = self.get_psu_total_number() + for i in range(psu_num): + psu_name = "PSU" + str(i + 1) + psu_obj = DevPsu(psu_name, self.psu_air_flow_monitor, self.int_case) + self.psu_obj_list.append(psu_obj) + ledcontrol_debug("psu object initialize success") + + def run(self): + while True: + try: + debug_init() + self.do_ledcontrol() + time.sleep(self.interval) + except Exception as e: + traceback.print_exc() + ledcontrol_error(str(e)) + + +if __name__ == '__main__': + debug_init() + ledcontrol_debug("enter main") + led_control = ledcontrol() + led_control.fan_obj_init() + led_control.psu_obj_init() + led_control.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_pltfm.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_pltfm.py new file mode 100755 index 000000000000..b724e77dcb1f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/hal_pltfm.py @@ -0,0 +1,475 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import inspect +import sys +import json +import time +from plat_hal.interface import interface + + +class Command(): + def __init__(self, name, f): + self.name = name + self.f = f + self.paramcount = self.f.__code__.co_argcount + + def dofun(self, args): + fn = self.f.__call__ + fn(*args) + + +class Group(): + def __init__(self, name, f): + self.groups = [] + self.commands = [] + self.name = name + self.f = f + + def add_groups(self, command): + self.groups.append(command) + + def add_commands(self, commnad): + x = Command(commnad.__name__, commnad) + self.commands.append(x) + + def find_valuebyname(self, name): + for item in self.groups: + if name == item.name: + return item + for item in self.commands: + if name == item.name: + return item + return None + + def deal(self, args): + if len(args) <= 0: + return self.print_help() + funclevel = args[0] + val = self.find_valuebyname(funclevel) + if val is None: + return self.print_help() + if isinstance(val, Command): + if len(args) < (val.paramcount + 1): + return self.print_help() + inputargs = args[1: (1 + val.paramcount)] + return val.dofun(inputargs) + if isinstance(val, Group): + args = args[1:] + return val.deal(args) + return self.print_help() + + def get_max(self, arr): + lentmp = 0 + for ar in arr: + lentmp = len(ar) if (len(ar) > lentmp) else lentmp + return lentmp + + def print_help(self): + + namesize = [] + for item in self.groups: + namesize.append(item.name) + for item in self.commands: + namesize.append(item.name) + maxvalue = self.get_max(namesize) + + if len(self.groups) > 0: + print("Groups:") + for item in self.groups: + print(" %-*s %s" % (maxvalue, item.name, item.f.__doc__ or '')) + if len(self.commands) > 0: + print("Commands:") + for item in self.commands: + print(" %-*s %s" % (maxvalue, item.name, item.f.__doc__ or '')) + + +class clival(): + @staticmethod + def Fire(val=None): + group = Group("top", 'mainlevel') + clival.iterGroup(val, group) + # context = {} + # caller = inspect.stack()[1] + # caller_frame = caller[0] + # caller_globals = caller_frame.f_globals + # caller_locals = caller_frame.f_locals + # context.update(caller_globals) + # context.update(caller_locals) + args = sys.argv[1:] + group.deal(args) + + @staticmethod + def iterGroup(val, group): + for key, item in val.items(): + if item is None: # first level + if inspect.isfunction(key): + group.add_commands(key) + else: + group1 = Group(key.__name__, key) + clival.iterGroup(item, group1) + group.add_groups(group1) + + +def psu(): + r'''test psu ''' + + +def fan(): + r'''test fan ''' + + +def sensor(): + r'''test sensor ''' + + +def dcdc(): + r'''test dcdc ''' + + +def led(): + r'''test led ''' + + +def e2(): + r'''test onie eeprom ''' + + +def temps(): + r'''test temps sensor''' + + +int_case = interface() + + +def get_total_number(): + r'''psu get_total_number ''' + print("=================get_total_number======================") + print(int_case.get_psu_total_number()) + + +def get_presence(): + r'''psu get_presence ''' + print("=================get_presence======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(int_case.get_psu_presence(psu_item.name)) + + +def get_fru_info(): + r'''psu get_fru_info ''' + print("=================get_fru_info======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(json.dumps(int_case.get_psu_fru_info(psu_item.name), ensure_ascii=False, indent=4)) + + +def get_status(): + r'''psu get_status ''' + print("=================get_status======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(json.dumps(int_case.get_psu_status(psu_item.name), ensure_ascii=False, indent=4)) + + +def set_psu_fan_speed_pwm(realspeed): + r'''set_psu_fan_speed_pwm''' + print("=================set_psu_fan_speed_pwm======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(int_case.set_psu_fan_speed_pwm(psu_item.name, int(realspeed))) + + +def get_psu_fan_speed_pwm(): + r'''get_psu_fan_speed_pwm''' + print("=================get_psu_fan_speed_pwm======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(json.dumps(int_case.get_psu_fan_speed_pwm(psu_item.name))) + + +def get_psu_power_status(): + r'''psu get_psu_power_status ''' + print("=================get_psu_power_status======================") + psus = int_case.get_psus() + for psu_item in psus: + print(psu_item.name, end=' ') + print(json.dumps(int_case.get_psu_power_status(psu_item.name), ensure_ascii=False, indent=4)) + + +def get_info_all(): + r'''psu get_info_all ''' + print("=================get_info_all======================") + print(json.dumps(int_case.get_psu_info_all(), ensure_ascii=False, indent=4)) + + +def fan_get_total_number(): + print("=================get_info_all======================") + print(json.dumps(int_case.get_fan_total_number(), ensure_ascii=False, indent=4)) + + +def fan_get_rotor_number(): + r'''fan_get_rotor_number''' + print("=================fan_get_rotor_number======================") + fans = int_case.get_fans() + for fan_item in fans: + print(fan_item.name, end=' ') + print(int_case.get_fan_rotor_number(fan_item.name)) + + +def fan_get_speed(): + r'''fan_get_speed''' + print("=================fan_get_speed======================") + fans = int_case.get_fans() + for fan_item in fans: + rotors = fan_item.rotor_list + for rotor in rotors: + index = rotors.index(rotor) + print("%s rotor%d" % (fan_item.name, index + 1), end=' ') + print(int_case.get_fan_speed(fan_item.name, index + 1)) + + +def fan_get_speed_pwm(): + r'''fan_get_speed_pwm''' + print("=================fan_get_speed_pwm======================") + fans = int_case.get_fans() + for fan_item in fans: + rotors = fan_item.rotor_list + for rotor in rotors: + index = rotors.index(rotor) + print("%s rotor%d" % (fan_item.name, index + 1), end=' ') + print(int_case.get_fan_speed_pwm(fan_item.name, index + 1)) + + +def fan_set_speed_pwm(pwm): + r'''fan_set_speed_pwm''' + print("=================fan_set_speed_pwm======================") + fans = int_case.get_fans() + for fan_item in fans: + rotors = fan_item.rotor_list + for rotor in rotors: + index = rotors.index(rotor) + print("%s %s" % (fan_item.name, rotor.name), end=' ') + val = int_case.set_fan_speed_pwm(fan_item.name, index + 1, pwm) + print(val) + + +def fan_get_watchdog_status(): + r'''fan_get_watchdog_status''' + print("=================fan_get_watchdog_status======================") + print(int_case.get_fan_watchdog_status()) + + +def fan_enable_watchdog(): + r'''fan_enable_watchdog''' + print("=================fan_enable_watchdog======================") + print('enable', int_case.enable_fan_watchdog()) + + +def fan_disable_watchdog(): + r'''fan_disable_watchdog''' + print("=================fan_disable_watchdog======================") + print('disable', int_case.enable_fan_watchdog(enable=False)) + + +def fan_get_speed1(): + r'''fan_get_speed''' + print("=================fan_get_speed======================") + fans = int_case.get_fans() + for fan_item in fans: + rotors = fan_item.rotor_list + for rotor in rotors: + print("%s %s" % (fan_item.name, rotor.name), end=' ') + print(int_case.get_fan_speed(fan_item.name, rotor.name)) + + +def fan_feed_watchdog(): + r'''fan_feed_watchdog''' + print("=================fan_feed_watchdog======================") + fan_get_speed() + print(int_case.feed_fan_watchdog()) + time.sleep(2) + fan_get_speed() + + +def fan_set_led(color): + r'''fan_set_led''' + print("=================fan_set_led======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(color, int_case.set_fan_led(fan_item.name, color)) + +def fan_get_led(): + r'''fan_get_led''' + print("=================fan_get_led======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(int_case.get_fan_led(fan_item.name)) + + +def fan_get_presence(): + r'''fan_get_presence''' + print("=================fan_get_presence======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(int_case.get_fan_presence(fan_item.name)) + + +def fan_get_fru_info(): + r'''fan_get_fru_info''' + print("=================fan_get_fru_info======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(json.dumps(int_case.get_fan_info(fan_item.name), ensure_ascii=False, indent=4)) + + +def fan_get_status(): + r'''fan_get_status''' + print("=================fan_get_status======================") + fans = int_case.get_fans() + for fan_item in fans: + print("%s" % fan_item.name) + print(json.dumps(int_case.get_fan_status(fan_item.name), ensure_ascii=False, indent=4)) + + +def fan_get_info_all(): + r'''fan_get_info_all''' + print("=================fan_get_info_all======================") + print(json.dumps(int_case.get_fan_info_all(), ensure_ascii=False, indent=4)) + + +def get_sensor_info(): + r'''get_sensor_info''' + print("=================get_sensor_info======================") + print(json.dumps(int_case.get_sensor_info(), ensure_ascii=False, indent=4)) + + +def get_dcdc_all_info(): + r'''get_dcdc_all_info''' + print("=================get_dcdc_all_info======================") + print(json.dumps(int_case.get_dcdc_all_info(), ensure_ascii=False, indent=4)) + + +def set_all_led_color(color): + r'''set_all_led_color color''' + print("=================set_all_led_color======================") + leds = int_case.get_leds() + for led_item in leds: + print("%s" % led_item.name) + print(color, int_case.set_led_color(led_item.name, color)) + + +def get_all_led_color(): + r'''get_all_led_color''' + print("=================get_all_led_color======================") + leds = int_case.get_leds() + for led_item in leds: + print("%s" % led_item.name) + print(int_case.get_led_color(led_item.name)) + + +def set_single_led_color(led_name, color): + r'''set_single_led_color led_name color''' + print("=================set_single_led_color======================") + leds = int_case.get_leds() + for led_item in leds: + if led_name == led_item.name: + print("%s" % led_item.name) + print(color, int_case.set_led_color(led_item.name, color)) + + +def get_single_led_color(led_name): + r'''get_single_led_color''' + print("=================get_single_led_color======================") + leds = int_case.get_leds() + for led_item in leds: + if led_name == led_item.name: + print("%s" % led_item.name) + print(int_case.get_led_color(led_item.name)) + + +def get_onie_e2_path(): + r'''get_onie_e2_path''' + print("=================get_onie_e2_path======================") + path = int_case.get_onie_e2_path("ONIE_E2") + print("%s" % path) + + +def get_device_airflow(): + r'''get_device_airflow''' + print("=================get_device_airflow======================") + airflow = int_case.get_device_airflow("ONIE_E2") + print("%s" % airflow) + + +def get_temps_sensor(): + r'''get_temps_sensor''' + print("=================get_temps_sensor======================") + temp_list = int_case.get_temps() + for temp in temp_list: + print("id: %s, name: %s, API name: %s, value: %s" % (temp.temp_id, temp.name, temp.api_name, temp.Value)) + + +def run_cli_man(): + clival.Fire( + { + psu: { + get_total_number: None, + get_presence: None, + get_fru_info: None, + set_psu_fan_speed_pwm: None, + get_psu_fan_speed_pwm: None, + get_status: None, + get_psu_power_status: None, + get_info_all: None + }, + fan: { + fan_get_total_number: None, + fan_get_rotor_number: None, + fan_get_speed: None, + fan_get_speed_pwm: None, + fan_set_speed_pwm: None, + fan_get_watchdog_status: None, + fan_enable_watchdog: None, + fan_disable_watchdog: None, + fan_feed_watchdog: None, + fan_set_led: None, + fan_get_led: None, + fan_get_presence: None, + fan_get_fru_info: None, + fan_get_status: None, + fan_get_info_all: None + }, + sensor: { + get_sensor_info: None + }, + dcdc: { + get_dcdc_all_info: None + }, + led: { + set_all_led_color: None, + set_single_led_color: None, + get_all_led_color: None, + get_single_led_color: None, + }, + e2: { + get_onie_e2_path: None, + get_device_airflow: None, + }, + temps: { + get_temps_sensor: None, + } + } + ) + + +if __name__ == '__main__': + run_cli_man() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor.py new file mode 100755 index 000000000000..33d5bfba64e6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor.py @@ -0,0 +1,144 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +import os +import time +import syslog +from plat_hal.interface import interface +from plat_hal.baseutil import baseutil +from platform_util import io_rd, wbi2cget + +INTELLIGENT_MONITOR_DEBUG_FILE = "/etc/.intelligent_monitor_debug" + +debuglevel = 0 + + +def monitor_syslog_debug(s): + if debuglevel: + syslog.openlog("INTELLIGENT_MONITOR_DEBUG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def monitor_syslog(s): + syslog.openlog("INTELLIGENT_MONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def pmon_syslog_notice(s): + syslog.openlog("PMON_SYSLOG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_NOTICE, s) + + +class IntelligentMonitor(): + def __init__(self): + self.dcdc_dict = {} + self.int_case = interface() + self.__config = baseutil.get_monitor_config() + self.__intelligent_monitor_para = self.__config.get('intelligent_monitor_para', {}) + self.__interval = self.__intelligent_monitor_para.get('interval', 60) + self.__dcdc_whitelist = self.__config.get('dcdc_monitor_whitelist', {}) + self.__error_ret = self.int_case.error_ret + + @property + def error_ret(self): + return self.__error_ret + + @property + def interval(self): + return self.__interval + + def debug_init(self): + global debuglevel + if os.path.exists(INTELLIGENT_MONITOR_DEBUG_FILE): + debuglevel = 1 + else: + debuglevel = 0 + + def dcdc_whitelist_check(self, dcdc_name): + try: + check_item = self.__dcdc_whitelist.get(dcdc_name, {}) + if len(check_item) == 0: + return False + gettype = check_item.get("gettype", None) + checkbit = check_item.get("checkbit", None) + okval = check_item.get("okval", None) + if gettype is None or checkbit is None or okval is None: + monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s config error. gettype:%s, checkbit:%s, okval:%s' % + (dcdc_name, gettype, checkbit, okval)) + return False + if gettype == "io": + io_addr = check_item.get('io_addr', None) + val = io_rd(io_addr) + if val is not None: + retval = val + else: + monitor_syslog( + '%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s io_rd error. io_addr:%s' % + (dcdc_name, io_addr)) + return False + elif gettype == "i2c": + bus = check_item.get('bus', None) + addr = check_item.get('addr', None) + offset = check_item.get('offset', None) + ind, val = wbi2cget(bus, addr, offset) + if ind is True: + retval = val + else: + monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s i2cget error. bus:%s, addr:%s, offset:%s' % + (dcdc_name, bus, addr, offset)) + return False + else: + monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s gettype not support' % dcdc_name) + return False + + val_t = (int(retval, 16) & (1 << checkbit)) >> checkbit + if val_t != okval: + return False + return True + except Exception as e: + monitor_syslog('%%WHITELIST_CHECK: %s check error, msg: %s.' % (dcdc_name, str(e))) + return False + + def update_dcdc_status(self): + try: + self.dcdc_dict = self.int_case.get_dcdc_all_info() + for dcdc_name, item in self.dcdc_dict.items(): + ret = self.dcdc_whitelist_check(dcdc_name) + if ret is False: + if item['Value'] == self.error_ret: + monitor_syslog( + '%%INTELLIGENT_MONITOR-3-DCDC_SENSOR_FAILED: The value of %s read failed.' % + (dcdc_name)) + elif float(item['Value']) > float(item['Max']): + pmon_syslog_notice('%%PMON-5-VOLTAGE_HIGH: %s voltage %.3f%s is larger than max threshold %.3f%s.' % + (dcdc_name, float(item['Value']), item['Unit'], float(item['Max']), item['Unit'])) + elif float(item['Value']) < float(item['Min']): + pmon_syslog_notice('%%PMON-5-VOLTAGE_LOW: %s voltage %.3f%s is lower than min threshold %.3f%s.' % + (dcdc_name, float(item['Value']), item['Unit'], float(item['Min']), item['Unit'])) + else: + monitor_syslog_debug('%%INTELLIGENT_MONITOR-6-DCDC_SENSOR_OK: %s normal, value is %.3f%s.' % + (dcdc_name, item['Value'], item['Unit'])) + else: + monitor_syslog_debug( + '%%INTELLIGENT_MONITOR-6-DCDC_WHITELIST_CHECK: %s is in dcdc whitelist, not monitor voltage' % + dcdc_name) + continue + except Exception as e: + monitor_syslog('%%INTELLIGENT_MONITOR-3-EXCEPTION: update dcdc sensors status error, msg: %s.' % (str(e))) + + def doWork(self): + self.update_dcdc_status() + + def run(self): + while True: + try: + self.debug_init() + self.doWork() + time.sleep(self.interval) + except Exception as e: + monitor_syslog('%%INTELLIGENT_MONITOR-3-EXCEPTION: %s.' % (str(e))) + + +if __name__ == '__main__': + intelligent_monitor = IntelligentMonitor() + intelligent_monitor.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor/monitor_fan.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor/monitor_fan.py new file mode 100755 index 000000000000..c84319f3b798 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/intelligent_monitor/monitor_fan.py @@ -0,0 +1,284 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +import os +import time +import logging +from logging.handlers import RotatingFileHandler + +from plat_hal.interface import interface +from plat_hal.baseutil import baseutil + + +DEBUG_FILE = "/etc/.monitor_fan_debug_flag" + +LOG_FILE = "/var/log/intelligent_monitor/monitor_fan_log" + +E2_NAME = "ONIE_E2" + + +def _init_logger(): + if not os.path.exists(LOG_FILE): + os.system("mkdir -p %s" % os.path.dirname(LOG_FILE)) + os.system("sync") + handler = RotatingFileHandler(filename=LOG_FILE, maxBytes=5 * 1024 * 1024, backupCount=1) + formatter = logging.Formatter("%(asctime)s %(levelname)s %(filename)s[%(funcName)s][%(lineno)s]: %(message)s") + handler.setFormatter(formatter) + logger = logging.getLogger(__name__) + logger.setLevel(logging.INFO) + logger.addHandler(handler) + return logger + + +class Fan(object): + + def __init__(self, name, hal_interface): + self.name = name + self.fan_dict = {} + self.int_case = hal_interface + self.update_time = 0 + self.pre_present = False + self.pre_status = True + self.plugin_cnt = 0 + self.plugout_cnt = 0 + self.status_normal_cnt = 0 + self.status_error_cnt = 0 + + def fan_dict_update(self): + local_time = time.time() + if not self.fan_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + self.fan_dict = self.int_case.get_fan_info(self.name) + + def get_model(self): + self.fan_dict_update() + return self.fan_dict["NAME"] + + def get_serial(self): + self.fan_dict_update() + return self.fan_dict["SN"] + + def get_presence(self): + return self.int_case.get_fan_presence(self.name) + + def get_rotor_speed(self, rotor_name): + """ + 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) + """ + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor pwm + value = fan_dir[rotor_name]["Speed"] + max_speed = fan_dir[rotor_name]["SpeedMax"] + + if isinstance(value, str) or value is None: + return 0 + pwm = value * 100 / max_speed + if pwm > 100: + pwm = 100 + elif pwm < 0: + pwm = 0 + return int(pwm) + + def get_rotor_speed_tolerance(self, rotor_name): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + # The default tolerance value is fixed as 30% + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor tolerance + tolerance = fan_dir[rotor_name]["Tolerance"] + + if isinstance(tolerance, str) or tolerance is None: + return 30 + return tolerance + + 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) + """ + pwm = self.int_case.get_fan_speed_pwm(self.name, 0) + return int(pwm) + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + if not self.get_presence(): + return False + + rotor_num = self.int_case.get_fan_rotor_number(self.name) + for i in range(rotor_num): + rotor_name = "Rotor" + str(i + 1) + speed = self.get_rotor_speed(rotor_name) + tolerance = self.get_rotor_speed_tolerance(rotor_name) + target = self.get_target_speed() + if (speed - target) > target * tolerance / 100: + return False + if (target - speed) > target * tolerance / 100: + return False + + return True + + def get_direction(self): + """ + Retrieves the fan airflow direction + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Notes: + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. + """ + self.fan_dict_update() + return self.fan_dict["AirFlow"] + + +class MonitorFan(object): + + def __init__(self): + self.int_case = interface() + self.logger = _init_logger() + self.fan_obj_list = [] + self.__config = baseutil.get_monitor_config() + self.__monitor_fan_config = self.__config.get("monitor_fan_para", {}) + self.__present_interval = self.__monitor_fan_config.get("present_interval", 0.5) + self.__status_interval = self.__monitor_fan_config.get("status_interval", 5) + self.__present_check_cnt = self.__monitor_fan_config.get("present_check_cnt", 3) + self.__status_check_cnt = self.__monitor_fan_config.get("status_check_cnt", 3) + + def debug_init(self): + if os.path.exists(DEBUG_FILE): + self.logger.setLevel(logging.DEBUG) + else: + self.logger.setLevel(logging.INFO) + + def get_fan_total_number(self): + return self.int_case.get_fan_total_number() + + def get_device_airflow(self): + return self.int_case.get_device_airflow(E2_NAME) + + def fan_obj_init(self): + fan_num = self.get_fan_total_number() + for i in range(fan_num): + fan_name = "FAN" + str(i + 1) + fan_obj = Fan(fan_name, self.int_case) + self.fan_obj_list.append(fan_obj) + self.logger.info("fan object initialize success") + + def fan_airflow_check(self, fan_obj): + fan_airflow = fan_obj.get_direction() + device_airflow = self.get_device_airflow() + if fan_airflow != device_airflow: + self.logger.error("%s airflow[%s] not match device airflow[%s]", fan_obj.name, fan_airflow, device_airflow) + else: + self.logger.debug("%s airflow[%s] match device airflow[%s]", fan_obj.name, fan_airflow, device_airflow) + + def fan_plug_in_out_check(self, fan_obj): + present = fan_obj.get_presence() + if present is True: + self.logger.debug("%s is present", fan_obj.name) + else: + self.logger.debug("%s is absent", fan_obj.name) + + if present != fan_obj.pre_present: + if present is True: + fan_obj.plugin_cnt += 1 + fan_obj.plugout_cnt = 0 + if fan_obj.plugin_cnt >= self.__present_check_cnt: + fan_obj.pre_present = True + self.logger.info("%s [serial:%s] is plugin", fan_obj.name, fan_obj.get_serial()) + self.fan_airflow_check(fan_obj) + else: + fan_obj.plugin_cnt = 0 + fan_obj.plugout_cnt += 1 + if fan_obj.plugout_cnt >= self.__present_check_cnt: + fan_obj.pre_present = False + self.logger.info("%s is plugout", fan_obj.name) + else: + fan_obj.plugin_cnt = 0 + fan_obj.plugout_cnt = 0 + self.logger.debug("%s present status is not change", fan_obj.name) + + def fan_status_check(self, fan_obj): + status = fan_obj.get_status() + if status is True: + self.logger.debug("%s is normal", fan_obj.name) + else: + self.logger.debug("%s is error", fan_obj.name) + + if status != fan_obj.pre_status: + if status is True: + fan_obj.status_normal_cnt += 1 + fan_obj.status_error_cnt = 0 + if fan_obj.status_normal_cnt >= self.__status_check_cnt: + fan_obj.pre_status = True + self.logger.info( + "%s [serial:%s] is form error change to normal", + fan_obj.name, + fan_obj.get_serial()) + else: + fan_obj.status_normal_cnt = 0 + fan_obj.status_error_cnt += 1 + if fan_obj.status_error_cnt >= self.__status_check_cnt: + fan_obj.pre_status = False + self.logger.info( + "%s [serial:%s] is form normal change to error", + fan_obj.name, + fan_obj.get_serial()) + else: + fan_obj.status_normal_cnt = 0 + fan_obj.status_error_cnt = 0 + self.logger.debug("%s status is not change", fan_obj.name) + + def checkFanPresence(self): + for fan_obj in self.fan_obj_list: + self.fan_plug_in_out_check(fan_obj) + + def checkFanStatus(self): + for fan_obj in self.fan_obj_list: + self.fan_status_check(fan_obj) + + def run(self): + start_time = time.time() + while True: + try: + self.debug_init() + delta_time = time.time() - start_time + if self.__present_interval <= self.__status_interval: + if delta_time >= self.__status_interval or delta_time < 0: + self.checkFanStatus() + start_time = time.time() + else: + self.checkFanPresence() + time.sleep(self.__present_interval) + else: + if delta_time >= self.__present_interval or delta_time < 0: + self.checkFanPresence() + start_time = time.time() + else: + self.checkFanStatus() + time.sleep(self.__status_interval) + except Exception as e: + self.logger.error('EXCEPTION: %s.', str(e)) + + +if __name__ == '__main__': + monitor_fan = MonitorFan() + monitor_fan.fan_obj_init() + monitor_fan.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_common.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_common.py new file mode 100755 index 000000000000..4fe0beec44d5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_common.py @@ -0,0 +1,178 @@ +#!/usr/bin/python3 + +__all__ = [ + "BLACKLIST_DRIVERS", + "DRIVERLISTS", + "DEVICE", + "STARTMODULE", + "MAC_LED_RESET", + "MAC_DEFAULT_PARAM", + "DEV_MONITOR_PARAM", + "SLOT_MONITOR_PARAM", + "MANUINFO_CONF", + "REBOOT_CTRL_PARAM", + "PMON_SYSLOG_STATUS", + "OPTOE", + "REBOOT_CAUSE_PARA", + "UPGRADE_SUMMARY", + "WARM_UPGRADE_PARAM", + "WARM_UPG_FLAG", + "WARM_UPGRADE_STARTED_FLAG", + "PLATFORM_E2_CONF", + "AIR_FLOW_CONF", + "AIRFLOW_RESULT_FILE", + "INIT_PARAM_PRE", + "INIT_COMMAND_PRE", + "INIT_PARAM", + "INIT_COMMAND", + "MONITOR_TEMP_MIN", + "MONITOR_K", + "MONITOR_MAC_IN", + "MONITOR_DEFAULT_SPEED", + "MONITOR_MAX_SPEED", + "MONITOR_MIN_SPEED", + "MONITOR_MAC_ERROR_SPEED", + "MONITOR_FAN_TOTAL_NUM", + "MONITOR_MAC_UP_TEMP", + "MONITOR_MAC_LOWER_TEMP", + "MONITOR_MAC_MAX_TEMP", + "MONITOR_FALL_TEMP", + "MONITOR_MAC_WARNING_THRESHOLD", + "MONITOR_OUTTEMP_WARNING_THRESHOLD", + "MONITOR_BOARDTEMP_WARNING_THRESHOLD", + "MONITOR_CPUTEMP_WARNING_THRESHOLD", + "MONITOR_INTEMP_WARNING_THRESHOLD", + "MONITOR_MAC_CRITICAL_THRESHOLD", + "MONITOR_OUTTEMP_CRITICAL_THRESHOLD", + "MONITOR_BOARDTEMP_CRITICAL_THRESHOLD", + "MONITOR_CPUTEMP_CRITICAL_THRESHOLD", + "MONITOR_INTEMP_CRITICAL_THRESHOLD", + "MONITOR_CRITICAL_NUM", + "MONITOR_SHAKE_TIME", + "MONITOR_INTERVAL", + "MONITOR_LED_INTERVAL", + "MONITOR_PID_FLAG", + "MONITOR_MAC_SOURCE_SYSFS", + "MONITOR_MAC_SOURCE_PATH", + "MONITOR_PID_MODULE", + "PSU_FAN_FOLLOW", + "MONITOR_SYS_LED", + "MONITOR_SYS_FAN_LED", + "MONITOR_FANS_LED", + "MONITOR_SYS_PSU_LED", + "MONITOR_FAN_STATUS", + "MONITOR_PSU_STATUS", + "MONITOR_DEV_STATUS", + "MONITOR_DEV_STATUS_DECODE", + "DEV_LEDS", + "fanloc" +] + +# driver blacklist parameter +BLACKLIST_DRIVERS = [] + +# driver list parameter +DRIVERLISTS = [] + +# device list parameter +DEVICE = [] + +# start module parameters +STARTMODULE = {} + +# mac led reset parameter +MAC_LED_RESET = {} + +# avscontrol parameter +MAC_DEFAULT_PARAM = [] + +# dev_monitor parameter +DEV_MONITOR_PARAM = {} + +# slot_monitor parameter +SLOT_MONITOR_PARAM = {} + +# platform_manufacturer parameter +MANUINFO_CONF = {} + +# reboot_ctrl parameter +REBOOT_CTRL_PARAM = {} + +# pmon_syslog parameter +PMON_SYSLOG_STATUS = {} + +# sfp optoe device parameter +OPTOE = [] + +# reboot_cause parameter +REBOOT_CAUSE_PARA = [] + +# upgrade parameter +UPGRADE_SUMMARY = {} + +# warm_uprade parameter +WARM_UPGRADE_PARAM = {} +WARM_UPG_FLAG = "/etc/sonic/.warm_upg_flag" +WARM_UPGRADE_STARTED_FLAG = "/etc/sonic/.doing_warm_upg" + +# platform_e2 parameter +PLATFORM_E2_CONF = {} + +# generate_airflow parameter +AIR_FLOW_CONF = {} +AIRFLOW_RESULT_FILE = "/etc/sonic/.airflow" + +# Initialization parameters +INIT_PARAM_PRE = [] +INIT_COMMAND_PRE = [] +INIT_PARAM = [] +INIT_COMMAND = [] + +################################ fancontrol parameter################################### +MONITOR_TEMP_MIN = 38 +MONITOR_K = 11 +MONITOR_MAC_IN = 35 +MONITOR_DEFAULT_SPEED = 0x60 +MONITOR_MAX_SPEED = 0xFF +MONITOR_MIN_SPEED = 0x60 +MONITOR_MAC_ERROR_SPEED = 0XBB +MONITOR_FAN_TOTAL_NUM = 4 +MONITOR_MAC_UP_TEMP = 50 +MONITOR_MAC_LOWER_TEMP = -50 +MONITOR_MAC_MAX_TEMP = 100 # + +MONITOR_FALL_TEMP = 4 +MONITOR_MAC_WARNING_THRESHOLD = 100 +MONITOR_OUTTEMP_WARNING_THRESHOLD = 85 +MONITOR_BOARDTEMP_WARNING_THRESHOLD = 85 +MONITOR_CPUTEMP_WARNING_THRESHOLD = 85 +MONITOR_INTEMP_WARNING_THRESHOLD = 70 + +MONITOR_MAC_CRITICAL_THRESHOLD = 105 +MONITOR_OUTTEMP_CRITICAL_THRESHOLD = 90 +MONITOR_BOARDTEMP_CRITICAL_THRESHOLD = 90 +MONITOR_CPUTEMP_CRITICAL_THRESHOLD = 100 +MONITOR_INTEMP_CRITICAL_THRESHOLD = 80 +MONITOR_CRITICAL_NUM = 3 +MONITOR_SHAKE_TIME = 20 +MONITOR_INTERVAL = 60 +MONITOR_LED_INTERVAL = 2 +MONITOR_PID_FLAG = 0 + +MONITOR_MAC_SOURCE_SYSFS = 0 +MONITOR_MAC_SOURCE_PATH = None + +MONITOR_PID_MODULE = {} + +PSU_FAN_FOLLOW = {} + +MONITOR_SYS_LED = [] +MONITOR_SYS_FAN_LED = [] +MONITOR_FANS_LED = [] +MONITOR_SYS_PSU_LED = [] +MONITOR_FAN_STATUS = [] +MONITOR_PSU_STATUS = [] +MONITOR_DEV_STATUS = {} +MONITOR_DEV_STATUS_DECODE = {} +DEV_LEDS = {} +fanloc = [] diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_config.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_config.py new file mode 100755 index 000000000000..004a64c72233 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_config.py @@ -0,0 +1,184 @@ +#!/usr/bin/python3 + +import sys +import os +from wbutil.baseutil import get_machine_info +from wbutil.baseutil import get_platform_info +from wbutil.baseutil import get_board_id + +__all__ = [ + "MAILBOX_DIR", + "PLATFORM_GLOBALCONFIG", + "GLOBALCONFIG", + "STARTMODULE", + "MAC_LED_RESET", + "MAC_DEFAULT_PARAM", + "DEV_MONITOR_PARAM", + "SLOT_MONITOR_PARAM", + "MANUINFO_CONF", + "REBOOT_CTRL_PARAM", + "PMON_SYSLOG_STATUS", + "REBOOT_CAUSE_PARA", + "UPGRADE_SUMMARY", + "WARM_UPGRADE_PARAM", + "WARM_UPG_FLAG", + "WARM_UPGRADE_STARTED_FLAG", + "PLATFORM_E2_CONF", + "AIR_FLOW_CONF", + "AIRFLOW_RESULT_FILE", + "GLOBALINITPARAM", + "GLOBALINITCOMMAND", + "GLOBALINITPARAM_PRE", + "GLOBALINITCOMMAND_PRE", + "MONITOR_CONST", + "PSU_FAN_FOLLOW", + "MONITOR_SYS_LED", + "MONITOR_FANS_LED", + "MONITOR_SYS_FAN_LED", + "MONITOR_SYS_PSU_LED", + "MONITOR_FAN_STATUS", + "MONITOR_PSU_STATUS", + "MONITOR_DEV_STATUS", + "MONITOR_DEV_STATUS_DECODE", + "DEV_LEDS", + "fanloc" +] + + +def getdeviceplatform(): + x = get_platform_info(get_machine_info()) + if x is not None: + filepath = "/usr/share/sonic/device/" + x + return filepath + return None + + +platform = get_platform_info(get_machine_info()) +board_id = get_board_id(get_machine_info()) +platformpath = getdeviceplatform() +MAILBOX_DIR = "/sys/bus/i2c/devices/" +grtd_productfile = (platform + "_config").replace("-", "_") +common_productfile = "platform_common" +platform_configfile = (platform + "_" + board_id + "_config").replace("-", "_") # platfrom + board_id +configfile_pre = "/usr/local/bin/" +sys.path.append(platformpath) +sys.path.append(configfile_pre) + +############################################################################################ +if os.path.exists(configfile_pre + platform_configfile + ".py"): + module_product = __import__(platform_configfile, globals(), locals(), [], 0) +elif os.path.exists(configfile_pre + grtd_productfile + ".py"): + module_product = __import__(grtd_productfile, globals(), locals(), [], 0) +elif os.path.exists(configfile_pre + common_productfile + ".py"): + module_product = __import__(common_productfile, globals(), locals(), [], 0) +else: + print("config file not exist") + sys.exit(-1) +############################################################################################ + +PLATFORM_GLOBALCONFIG = { + "DRIVERLISTS": module_product.DRIVERLISTS, + "OPTOE": module_product.OPTOE, + "DEVS": module_product.DEVICE, + "BLACKLIST_DRIVERS": module_product.BLACKLIST_DRIVERS +} +GLOBALCONFIG = PLATFORM_GLOBALCONFIG + +# start module parameters +STARTMODULE = module_product.STARTMODULE + +# mac led reset parameter +MAC_LED_RESET = module_product.MAC_LED_RESET + +# avscontrol parameter +MAC_DEFAULT_PARAM = module_product.MAC_DEFAULT_PARAM + +# dev_monitor parameter +DEV_MONITOR_PARAM = module_product.DEV_MONITOR_PARAM + +# slot_monitor parameter +SLOT_MONITOR_PARAM = module_product.SLOT_MONITOR_PARAM + +# platform_manufacturer parameter +MANUINFO_CONF = module_product.MANUINFO_CONF + +# reboot_ctrl parameter +REBOOT_CTRL_PARAM = module_product.REBOOT_CTRL_PARAM + +# pmon_syslog parameter +PMON_SYSLOG_STATUS = module_product.PMON_SYSLOG_STATUS + +# reboot_cause parameter +REBOOT_CAUSE_PARA = module_product.REBOOT_CAUSE_PARA + +# upgrade parameter +UPGRADE_SUMMARY = module_product.UPGRADE_SUMMARY + +# warm_uprade parameter +WARM_UPGRADE_PARAM = module_product.WARM_UPGRADE_PARAM +WARM_UPG_FLAG = module_product.WARM_UPG_FLAG +WARM_UPGRADE_STARTED_FLAG = module_product.WARM_UPGRADE_STARTED_FLAG + +# platform_e2 parameter +PLATFORM_E2_CONF = module_product.PLATFORM_E2_CONF + +# generate_airflow parameter +AIR_FLOW_CONF = module_product.AIR_FLOW_CONF +AIRFLOW_RESULT_FILE = module_product.AIRFLOW_RESULT_FILE + +# Initialization parameters +GLOBALINITPARAM = module_product.INIT_PARAM +GLOBALINITCOMMAND = module_product.INIT_COMMAND +GLOBALINITPARAM_PRE = module_product.INIT_PARAM_PRE +GLOBALINITCOMMAND_PRE = module_product.INIT_COMMAND_PRE + +################################ fancontrol parameter################################### + + +class MONITOR_CONST: + TEMP_MIN = module_product.MONITOR_TEMP_MIN + K = module_product.MONITOR_K + MAC_IN = module_product.MONITOR_MAC_IN + DEFAULT_SPEED = module_product.MONITOR_DEFAULT_SPEED + MAX_SPEED = module_product.MONITOR_MAX_SPEED + MIN_SPEED = module_product.MONITOR_MIN_SPEED + MAC_ERROR_SPEED = module_product.MONITOR_MAC_ERROR_SPEED + FAN_TOTAL_NUM = module_product.MONITOR_FAN_TOTAL_NUM + MAC_UP_TEMP = module_product.MONITOR_MAC_UP_TEMP + MAC_LOWER_TEMP = module_product.MONITOR_MAC_LOWER_TEMP + MAC_MAX_TEMP = module_product.MONITOR_MAC_MAX_TEMP + + MAC_WARNING_THRESHOLD = module_product.MONITOR_MAC_WARNING_THRESHOLD + OUTTEMP_WARNING_THRESHOLD = module_product.MONITOR_OUTTEMP_WARNING_THRESHOLD + BOARDTEMP_WARNING_THRESHOLD = module_product.MONITOR_BOARDTEMP_WARNING_THRESHOLD + CPUTEMP_WARNING_THRESHOLD = module_product.MONITOR_CPUTEMP_WARNING_THRESHOLD + INTEMP_WARNING_THRESHOLD = module_product.MONITOR_INTEMP_WARNING_THRESHOLD + + MAC_CRITICAL_THRESHOLD = module_product.MONITOR_MAC_CRITICAL_THRESHOLD + OUTTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_OUTTEMP_CRITICAL_THRESHOLD + BOARDTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_BOARDTEMP_CRITICAL_THRESHOLD + CPUTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_CPUTEMP_CRITICAL_THRESHOLD + INTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_INTEMP_CRITICAL_THRESHOLD + CRITICAL_NUM = module_product.MONITOR_CRITICAL_NUM + SHAKE_TIME = module_product.MONITOR_SHAKE_TIME + MONITOR_INTERVAL = module_product.MONITOR_INTERVAL + MONITOR_LED_INTERVAL = module_product.MONITOR_LED_INTERVAL + MONITOR_FALL_TEMP = module_product.MONITOR_FALL_TEMP + MONITOR_PID_FLAG = module_product.MONITOR_PID_FLAG + MONITOR_PID_MODULE = module_product.MONITOR_PID_MODULE + + MONITOR_MAC_SOURCE_SYSFS = module_product.MONITOR_MAC_SOURCE_SYSFS + MONITOR_MAC_SOURCE_PATH = module_product.MONITOR_MAC_SOURCE_PATH + + +PSU_FAN_FOLLOW = module_product.PSU_FAN_FOLLOW +MONITOR_SYS_LED = module_product.MONITOR_SYS_LED +MONITOR_FANS_LED = module_product.MONITOR_FANS_LED +MONITOR_SYS_FAN_LED = module_product.MONITOR_SYS_FAN_LED +MONITOR_SYS_PSU_LED = module_product.MONITOR_SYS_PSU_LED +MONITOR_FAN_STATUS = module_product.MONITOR_FAN_STATUS +MONITOR_PSU_STATUS = module_product.MONITOR_PSU_STATUS +MONITOR_DEV_STATUS = module_product.MONITOR_DEV_STATUS +MONITOR_DEV_STATUS_DECODE = module_product.MONITOR_DEV_STATUS_DECODE +DEV_LEDS = module_product.DEV_LEDS +fanloc = module_product.fanloc diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_driver.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_driver.py new file mode 100755 index 000000000000..6d2c6de653d9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_driver.py @@ -0,0 +1,258 @@ +#!/usr/bin/env python3 +import os +import subprocess +import time +import click +from platform_config import GLOBALCONFIG, WARM_UPGRADE_STARTED_FLAG, WARM_UPG_FLAG + + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def log_os_system(cmd): + status, output = subprocess.getstatusoutput(cmd) + if status: + print(output) + return status, output + + +def platform_process_file_check(): + # WARM_UPGRADE_STARTED_FLAG is used as warm_upgrade.py process start flag + if os.path.exists(WARM_UPGRADE_STARTED_FLAG): + os.remove(WARM_UPGRADE_STARTED_FLAG) + + # WARM_UPG_FLAG is used as port related service judgment flag + if os.path.exists(WARM_UPG_FLAG): + os.remove(WARM_UPG_FLAG) + + +def startCommon_operation(): + platform_process_file_check() + + +def check_driver(): + status, output = log_os_system("lsmod | grep wb | wc -l") + if status: + return False + if output.isdigit() and int(output) > 0: + return True + return False + + +def removeDev(bus, loc): + cmd = "echo 0x%02x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (loc, bus) + devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc) + if os.path.exists(devpath): + log_os_system(cmd) + + +def addDev(name, bus, loc): + if name == "lm75": + time.sleep(0.1) + pdevpath = "/sys/bus/i2c/devices/i2c-%d/" % (bus) + for i in range(1, 100): + if os.path.exists(pdevpath) is True: + break + time.sleep(0.1) + if i % 10 == 0: + click.echo("%%WB_PLATFORM_DRIVER-INIT: %s not found, wait 0.1 second ! i %d " % (pdevpath, i)) + + cmd = "echo %s 0x%02x > /sys/bus/i2c/devices/i2c-%d/new_device" % (name, loc, bus) + devpath = "/sys/bus/i2c/devices/%d-%04x" % (bus, loc) + if os.path.exists(devpath) is False: + os.system(cmd) + + +def removeOPTOE(startbus, endbus): + for bus in range(endbus, startbus - 1, -1): + removeDev(bus, 0x50) + + +def addOPTOE(name, startbus, endbus): + for bus in range(startbus, endbus + 1): + addDev(name, bus, 0x50) + + +def removeoptoes(): + optoes = GLOBALCONFIG["OPTOE"] + for index in range(len(optoes) - 1, -1, -1): + removeOPTOE(optoes[index]["startbus"], optoes[index]["endbus"]) + + +def addoptoes(): + optoes = GLOBALCONFIG["OPTOE"] + for optoe in optoes: + addOPTOE(optoe["name"], optoe["startbus"], optoe["endbus"]) + + +def removedevs(): + devs = GLOBALCONFIG["DEVS"] + for index in range(len(devs) - 1, -1, -1): + removeDev(devs[index]["bus"], devs[index]["loc"]) + + +def adddevs(): + devs = GLOBALCONFIG["DEVS"] + for dev in devs: + addDev(dev["name"], dev["bus"], dev["loc"]) + + +def checksignaldriver(name): + modisexistcmd = "lsmod | grep -w %s | wc -l" % name + status, output = log_os_system(modisexistcmd) + if status: + return False + if output.isdigit() and int(output) > 0: + return True + return False + + +def adddriver(name, delay): + cmd = "modprobe %s" % name + if delay != 0: + time.sleep(delay) + if checksignaldriver(name) is not True: + log_os_system(cmd) + + +def removedriver(name, delay, removeable=1): + realname = name.lstrip().split(" ")[0] + cmd = "rmmod -f %s" % realname + if checksignaldriver(realname) and removeable: + log_os_system(cmd) + if delay > 0: + time.sleep(delay) + + +def removedrivers(): + if GLOBALCONFIG is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load global config failed.") + return + drivers = GLOBALCONFIG.get("DRIVERLISTS", None) + if drivers is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load driver list failed.") + return + for index in range(len(drivers) - 1, -1, -1): + delay = 0 + name = "" + removeable = drivers[index].get("removable", 1) + if isinstance(drivers[index], dict) and "delay" in drivers[index]: + name = drivers[index].get("name") + delay = drivers[index]["delay"] + else: + name = drivers[index] + removedriver(name, delay, removeable) + + +def adddrivers(): + if GLOBALCONFIG is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load global config failed.") + return + drivers = GLOBALCONFIG.get("DRIVERLISTS", None) + if drivers is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load driver list failed.") + return + for driver in drivers: + delay = 0 + name = "" + if isinstance(driver, dict) and "delay" in driver: + name = driver.get("name") + delay = driver["delay"] + else: + name = driver + adddriver(name, delay) + + +def blacklist_driver_remove(): + if GLOBALCONFIG is None: + click.echo("%%WB_PLATFORM_DRIVER-INIT: load global config failed.") + return + blacklist_drivers = GLOBALCONFIG.get("BLACKLIST_DRIVERS", []) + for driver in blacklist_drivers: + delay = 0 + name = "" + if isinstance(driver, dict) and "delay" in driver: + name = driver.get("name") + delay = driver["delay"] + else: + name = driver + removedriver(name, delay) + + +def unload_driver(): + removeoptoes() + removedevs() + removedrivers() + + +def reload_driver(): + removedevs() + removedrivers() + time.sleep(1) + adddrivers() + adddevs() + + +def i2c_check(bus, retrytime=6): + try: + i2cpath = "/sys/bus/i2c/devices/" + bus + while retrytime and not os.path.exists(i2cpath): + click.echo("%%WB_PLATFORM_DRIVER-HA: i2c bus abnormal, last bus %s is not exist." % i2cpath) + reload_driver() + retrytime -= 1 + time.sleep(1) + except Exception as e: + click.echo("%%WB_PLATFORM_DRIVER-HA: %s" % str(e)) + + +def load_driver(): + startCommon_operation() + adddrivers() + adddevs() + addoptoes() + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''device operator''' + + +@main.command() +def start(): + '''load drivers and device ''' + blacklist_driver_remove() + if check_driver(): + unload_driver() + load_driver() + + +@main.command() +def stop(): + '''stop drivers device ''' + unload_driver() + + +@main.command() +def restart(): + '''restart drivers and device''' + unload_driver() + load_driver() + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_e2.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_e2.py new file mode 100755 index 000000000000..808d93216210 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_e2.py @@ -0,0 +1,434 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import click + +from eepromutil.fru import ipmifru +from eepromutil.fantlv import fan_tlv +import eepromutil.onietlv as ot +from platform_config import PLATFORM_E2_CONF +from platform_util import byteTostr, dev_file_read + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +class ExtraFunc(object): + @staticmethod + def decode_mac(encodedata): + if encodedata is None: + return None + ret = ":".join("%02x" % ord(data) for data in encodedata) + return ret.upper() + + @staticmethod + def decode_mac_number(encodedata): + if encodedata is None: + return None + return (ord(encodedata[0]) << 8) | (ord(encodedata[1]) & 0x00ff) + + @staticmethod + @staticmethod + def fru_decode_mac_number(params): + ipmi_fru = params.get("fru") + area = params.get("area") + field = params.get("field") + area_info = getattr(ipmi_fru, area, None) + if area_info is not None: + raw_mac_number = getattr(area_info, field, None) + mac_number = decode_mac_number(raw_mac_number) + ipmi_fru.setValue(area, field, mac_number) + + @staticmethod + def fru_decode_mac(params): + ipmi_fru = params.get("fru") + area = params.get("area") + field = params.get("field") + area_info = getattr(ipmi_fru, area, None) + if area_info is not None: + raw_mac = getattr(area_info, field, None) + decoded_mac = decode_mac(raw_mac) + ipmi_fru.setValue(area, field, decoded_mac) + + @staticmethod + def fru_decode_hw(params): + ipmi_fru = params.get("fru") + area = params.get("area") + field = params.get("field") + area_info = getattr(ipmi_fru, area, None) + if area_info is not None: + raw_hw = getattr(area_info, field, None) + decode_hw = str(int(raw_hw, 16)) + ipmi_fru.setValue(area, field, decode_hw) + + +def set_onie_value(params): + onie = params.get("onie") + field = params.get("field") + config_value = params.get("config_value") + for index, onie_item in enumerate(onie): + if onie_item.get("name") == field: + if "value" in onie_item.keys(): + onie[index]["value"] = config_value + + +def onie_eeprom_decode(onie, e2_decode): + for e2_decode_item in e2_decode: + field = e2_decode_item.get("field") + decode_type = e2_decode_item.get("decode_type") + if decode_type == 'func': + params = { + "onie": onie, + "field": field + } + func_name = e2_decode_item.get("func_name") + if func_name is not None: + run_func(func_name, params) + elif decode_type == 'config': + config_value = e2_decode_item.get("config_value") + if config_value is not None: + params = { + "onie": onie, + "field": field, + "config_value": config_value + } + set_onie_value(params) + else: + print("unsupport decode type") + continue + + +def onie_eeprom_show(eeprom, e2_decode=None): + try: + onietlv = ot.onie_tlv() + rets = onietlv.decode(eeprom) + if e2_decode is not None: + onie_eeprom_decode(rets, e2_decode) + print("%-20s %-5s %-5s %-20s" % ("TLV name", "Code", "lens", "Value")) + for item in rets: + if item["code"] == 0xfd: + print("%-20s 0x%-02X %-5s" % (item["name"], item["code"], item["lens"])) + else: + print("%-20s 0x%-02X %-5s %-20s" % (item["name"], item["code"], item["lens"], item["value"])) + except Exception as e: + print(str(e)) + + +def set_fantlv_value(params): + fantlv_dict = params.get("fantlv") + field = params.get("field") + config_value = params.get("config_value") + for index, fantlv_item in enumerate(fantlv_dict): + if fantlv_item.get("name") == field: + if "value" in fantlv_item.keys(): + fantlv_dict[index]["value"] = config_value + + +def fantlv_eeprom_decode(fantlv_dict, e2_decode): + for e2_decode_item in e2_decode: + field = e2_decode_item.get("field") + decode_type = e2_decode_item.get("decode_type") + if decode_type == 'func': + params = { + "fantlv": fantlv_dict, + "field": field + } + func_name = e2_decode_item.get("func_name") + if func_name is not None: + run_func(func_name, params) + elif decode_type == 'config': + config_value = e2_decode_item.get("config_value") + if config_value is not None: + params = { + "fantlv": fantlv_dict, + "field": field, + "config_value": config_value + } + set_fantlv_value(params) + else: + print("unsupport decode type") + continue + + +def fantlv_eeprom_show(eeprom, e2_decode=None): + try: + tlv = fan_tlv() + rets = tlv.decode(eeprom) + if len(rets) == 0: + print("fan tlv eeprom info error.!") + return + if e2_decode is not None: + fantlv_eeprom_decode(rets, e2_decode) + print("%-15s %-5s %-5s %-20s" % ("TLV name", "Code", "lens", "Value")) + for item in rets: + print("%-15s 0x%-02X %-5s %-20s" % (item["name"], item["code"], item["lens"], item["value"])) + except Exception as e: + print(str(e)) + return + + +def run_func(funcname, params): + try: + func = getattr(ExtraFunc, funcname) + func(params) + except Exception as e: + print(str(e)) + +def set_fru_value(params): + ipmi_fru = params.get("fru") + area = params.get("area") + field = params.get("field") + config_value = params.get("config_value") + ipmi_fru.setValue(area, field, config_value) + + +def fru_eeprom_decode(ipmi_fru, e2_decode): + for e2_decode_item in e2_decode: + area = e2_decode_item.get("area") + field = e2_decode_item.get("field") + decode_type = e2_decode_item.get("decode_type") + if decode_type == 'func': + params = { + "fru": ipmi_fru, + "area": area, + "field": field + } + func_name = e2_decode_item.get("func_name") + if func_name is not None: + run_func(func_name, params) + elif decode_type == 'config': + config_value = e2_decode_item.get("config_value") + if config_value is not None: + params = { + "fru": ipmi_fru, + "area": area, + "field": field, + "config_value": config_value + } + set_fru_value(params) + else: + print("unsupport decode type") + continue + + +def fru_eeprom_show(eeprom, e2_decode=None): + try: + ipmi_fru = ipmifru() + ipmi_fru.decodeBin(eeprom) + if e2_decode is not None: + fru_eeprom_decode(ipmi_fru, e2_decode) + print("=================board=================") + print(ipmi_fru.boardInfoArea) + print("=================product=================") + print(ipmi_fru.productInfoArea) + except Exception as e: + print(str(e)) + + +def eeprom_parase(eeprom_conf): + name = eeprom_conf.get("name") + e2_type = eeprom_conf.get("e2_type") + e2_path = eeprom_conf.get("e2_path") + e2_size = eeprom_conf.get("e2_size", 256) + e2_decode = eeprom_conf.get("e2_decode") + print("===================%s===================" % name) + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + print("eeprom read error, eeprom path: %s, msg: %s" % (e2_path, binval_bytes)) + return + binval = byteTostr(binval_bytes) + if e2_type == "onie_tlv": + onie_eeprom_show(binval, e2_decode) + elif e2_type == "fru": + fru_eeprom_show(binval, e2_decode) + elif e2_type == "fantlv": + fantlv_eeprom_show(binval, e2_decode) + else: + print("Unknow eeprom type: %s" % e2_type) + return + + +def get_fans_eeprom_info(param): + fan_eeprom_conf = PLATFORM_E2_CONF.get("fan", []) + fan_num = len(fan_eeprom_conf) + if fan_num == 0: + print("fan number is 0, can't get fan eeprom info") + return + if param == 'all': + for conf in fan_eeprom_conf: + eeprom_parase(conf) + return + if not param.isdigit(): + print("param error, %s is not digital or 'all'" % param) + return + fan_index = int(param, 10) - 1 + if fan_index < 0 or fan_index >= fan_num: + print("param error, total fan number: %d, fan index: %d" % (fan_num, fan_index + 1)) + return + eeprom_parase(fan_eeprom_conf[fan_index]) + return + + +def get_psus_eeprom_info(param): + psu_eeprom_conf = PLATFORM_E2_CONF.get("psu", []) + psu_num = len(psu_eeprom_conf) + if psu_num == 0: + print("psu number is 0, can't get psu eeprom info") + return + if param == 'all': + for conf in psu_eeprom_conf: + eeprom_parase(conf) + return + if not param.isdigit(): + print("param error, %s is not digital or 'all'" % param) + return + psu_index = int(param, 10) - 1 + if psu_index < 0 or psu_index >= psu_num: + print("param error, total psu number: %d, psu index: %d" % (psu_num, psu_index + 1)) + return + eeprom_parase(psu_eeprom_conf[psu_index]) + return + + +def get_slots_eeprom_info(param): + slot_eeprom_conf = PLATFORM_E2_CONF.get("slot", []) + slot_num = len(slot_eeprom_conf) + if slot_num == 0: + print("slot number is 0, can't get slot eeprom info") + return + if param == 'all': + for conf in slot_eeprom_conf: + eeprom_parase(conf) + return + if not param.isdigit(): + print("param error, %s is not digital or 'all'" % param) + return + slot_index = int(param, 10) - 1 + if slot_index < 0 or slot_index >= slot_num: + print("param error, total slot number: %d, slot index: %d" % (slot_num, slot_index + 1)) + return + eeprom_parase(slot_eeprom_conf[slot_index]) + return + + +def get_syseeprom_info(param): + syseeprom_conf = PLATFORM_E2_CONF.get("syseeprom", []) + syseeprom_num = len(syseeprom_conf) + if syseeprom_num == 0: + print("syseeprom number is 0, can't get syseeprom info") + return + if param == 'all': + for conf in syseeprom_conf: + eeprom_parase(conf) + return + if not param.isdigit(): + print("param error, %s is not digital or 'all'" % param) + return + syseeprom_index = int(param, 10) - 1 + if syseeprom_index < 0 or syseeprom_index >= syseeprom_num: + print("param error, total syseeprom number: %d, syseeprom index: %d" % (syseeprom_num, syseeprom_index + 1)) + return + eeprom_parase(syseeprom_conf[syseeprom_index]) + return + + +def decode_eeprom_info(e2_type, e2_path, e2_size): + if not e2_size.isdigit(): + print("param error, e2_size %s is not digital" % e2_size) + return + e2_size = int(e2_size, 10) + eeprom_conf = {} + eeprom_conf["name"] = e2_type + eeprom_conf["e2_type"] = e2_type + eeprom_conf["e2_path"] = e2_path + eeprom_conf["e2_size"] = e2_size + eeprom_parase(eeprom_conf) + return + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''platform eeprom display script''' + +# fan eeprom info display + + +@main.command() +@click.argument('fan_index', required=True) +def fan(fan_index): + '''fan_index(1, 2, 3...)/all''' + get_fans_eeprom_info(fan_index) + +# psu eeprom info display + + +@main.command() +@click.argument('psu_index', required=True) +def psu(psu_index): + '''psu_index(1, 2, 3...)/all''' + get_psus_eeprom_info(psu_index) + +# slot eeprom info display + + +@main.command() +@click.argument('slot_index', required=True) +def slot(slot_index): + '''slot_index(1, 2, 3...)/all''' + get_slots_eeprom_info(slot_index) + +# syseeprom info display + + +@main.command() +@click.argument('syseeprom_index', required=True) +def syseeprom(syseeprom_index): + '''syseeprom_index(1, 2, 3...)/all''' + get_syseeprom_info(syseeprom_index) + +# fru eeprom info decode + + +@main.command() +@click.argument('e2_path', required=True) +@click.argument('e2_size', required=False, default="256") +def fru(e2_path, e2_size): + '''e2_path''' + decode_eeprom_info("fru", e2_path, e2_size) + +# fantlv eeprom info decode + + +@main.command() +@click.argument('e2_path', required=True) +@click.argument('e2_size', required=False, default="256") +def fantlv(e2_path, e2_size): + '''e2_path''' + decode_eeprom_info("fantlv", e2_path, e2_size) + +# onie_tlv eeprom info decode + + +@main.command() +@click.argument('e2_path', required=True) +@click.argument('e2_size', required=False, default="256") +def onie_tlv(e2_path, e2_size): + '''e2_path''' + decode_eeprom_info("onie_tlv", e2_path, e2_size) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_intf.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_intf.py new file mode 100755 index 000000000000..2143b9420cd3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_intf.py @@ -0,0 +1,367 @@ +#!/usr/bin/env python3 +import os +import syslog +import importlib.machinery +from platform_util import getplatform_name, dev_file_read, dev_file_write, write_sysfs, read_sysfs + +__all__ = [ + "platform_reg_read", + "platform_reg_write", + "platform_set_optoe_type", + "platform_get_optoe_type", + "platform_sfp_read", + "platform_sfp_write", +] + +CPLD = 0 +FPGA = 1 +CPLD_PATH = "/dev/cpld%d" +FPGA_PATH = "/dev/fpga%d" + + +OPTOE_PATH = "/sys/bus/i2c/devices/%d-0050/" +OPTOE_DEV_CLASS = "dev_class" +OPTOE_EEPROM = "eeprom" + + +PLATFORM_INTF_DEBUG_FILE = "/etc/.platform_intf_debug_flag" + + +CONFIG_FILE_LIST = [ + "/usr/local/bin/", + "/usr/local/lib/python3/dist-packages/config/", + "/usr/local/lib/python3.7/dist-packages/config/", + "/usr/local/lib/python3.9/dist-packages/config/"] + + +def platform_intf_debug(s): + if os.path.exists(PLATFORM_INTF_DEBUG_FILE): + syslog.openlog("PLATFORM_INTF_DEBUG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def platform_intf_error(s): + if os.path.exists(PLATFORM_INTF_DEBUG_FILE): + syslog.openlog("PLATFORM_INTF_ERROR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +class IntfPlatform: + CONFIG_NAME = 'PLATFORM_INTF_OPTOE' + __port_optoe_dict = {} + + def __init__(self): + real_path = None + platform_name = (getplatform_name()).replace("-", "_") + for configfile_path in CONFIG_FILE_LIST: + configfile = configfile_path + platform_name + "_port_config.py" + if os.path.exists(configfile): + real_path = configfile + break + if real_path is None: + raise Exception("get port config error") + config = importlib.machinery.SourceFileLoader(self.CONFIG_NAME, real_path).load_module() + self.__port_optoe_dict = config.PLATFORM_INTF_OPTOE + + def get_dev_path(self, dev_type, dev_id): + if dev_type == CPLD: + path = CPLD_PATH % dev_id + elif dev_type == FPGA: + path = FPGA_PATH % dev_id + else: + msg = "dev_type error!" + return False, msg + platform_intf_debug("path:%s" % path) + return True, path + + def get_port_path(self, port): + port_num = self.__port_optoe_dict.get("port_num", 0) + optoe_start_bus = self.__port_optoe_dict.get("optoe_start_bus", 0) + if port_num <= 0 or optoe_start_bus <= 0: + msg = "PLATFORM_INTF_OPTOE config error!" + return False, msg + if port <= 0 or port > port_num: + msg = "port out of range !" + return False, msg + path = OPTOE_PATH % (port + optoe_start_bus - 1) + platform_intf_debug("path:%s" % path) + return True, path + + ########################################### + # reg_read - read logic device register + # @dev_type: 0: CPLD, 1: FPGA + # @dev_id: device ID, start from 0 + # @offset: register offset + # @size: read length + # return: + # @ret: True if read success, False if not + # @info: The read value list if read success, otherwise the detail error message + ########################################### + def reg_read(self, dev_type, dev_id, offset, size): + ret, path = self.get_dev_path(dev_type, dev_id) + if ret is False: + return False, path + ret, info = dev_file_read(path, offset, size) + return ret, info + + ########################################### + # platform_reg_write - write logic device register + # @dev_type: 0: CPLD, 1: FPGA + # @dev_id: device ID, start from 0 + # @offset: register offset + # @val_list: The write value list + # return: + # @ret: True if write success, False if not + # @info: The write value length if write success, otherwise the detail error message + ########################################### + def reg_write(self, dev_type, dev_id, offset, val_list): + ret, path = self.get_dev_path(dev_type, dev_id) + if ret is False: + return False, path + ret, info = dev_file_write(path, offset, val_list) + return ret, info + + ########################################### + # set_optoe_type - set port optoe type + # @port: port index start from 1 + # @optoe_type: optoe type, including the following values + # 1: OPTOE1 + # 2: OPTOE2 + # 3: OPTOE3 + # return: + # @ret: True if set optoe type success, False if not + # @info: None if set optoe type success, otherwise the detail error message + ########################################### + def set_optoe_type(self, port, optoe_type): + ret, path = self.get_port_path(port) + if ret is False: + return False, path + optoe_type_path = path + OPTOE_DEV_CLASS + ret, info = write_sysfs(optoe_type_path, "%d" % optoe_type) + if ret is False: + return False, info + return True, None + + ########################################### + # get_optoe_type - get port optoe type + # @port: port index start from 1 + # return: + # @ret: True if set optoe type success, False if not + # @info: Optoe type value if get optoe type success, otherwise the detail error message + # optoe type including the following values + # 1: OPTOE1 + # 2: OPTOE2 + # 3: OPTOE3 + ########################################### + def get_optoe_type(self, port): + ret, path = self.get_port_path(port) + if ret is False: + return False, path + optoe_type_path = path + OPTOE_DEV_CLASS + ret, info = read_sysfs(optoe_type_path) + if ret is False: + return False, info + return True, int(info) + + ########################################### + # sfp_read -read sfp eeprom + # @port_id: port index start from 1 + # @offset: sfp eeprom offset + # @size: read sfp eeprom length + # return: + # @ret: True if read success, False if not + # @info: The read value list if read success, otherwise the detail error message + ########################################### + def sfp_read(self, port_id, offset, size): + ret, path = self.get_port_path(port_id) + if ret is False: + return False, path + optoe_eeprom_path = path + OPTOE_EEPROM + ret, info = dev_file_read(optoe_eeprom_path, offset, size) + return ret, info + + ########################################### + # sfp_write -write sfp eeprom + # @port_id: port index start from 1 + # @offset: sfp eeprom offset + # @val_list: The write value list + # return: + # @ret: True if read success, False if not + # @info: The write value length if write success, otherwise the detail error message + ########################################### + def sfp_write(self, port_id, offset, val_list): + ret, path = self.get_port_path(port_id) + if ret is False: + return False, path + optoe_eeprom_path = path + OPTOE_EEPROM + ret, info = dev_file_write(optoe_eeprom_path, offset, val_list) + return ret, info + + +platform = IntfPlatform() + + +########################################### +# platform_reg_read - read logic device register +# @dev_type: 0: CPLD, 1: FPGA +# @dev_id: device ID, start from 0 +# @offset: register offset +# @size: read length +# return: +# @ret: True if read success, False if not +# @info: The read value list if read success, otherwise the detail error message +########################################### +def platform_reg_read(dev_type, dev_id, offset, size): + ret = False + info = None + + # params check + if (isinstance(dev_type, int) is False or isinstance(dev_id, int) is False or + isinstance(offset, int) is False or isinstance(size, int) is False): + info = "params type check fail in platform_reg_read" + return ret, info + if dev_id < 0 or offset < 0 or size <= 0: + info = "params value check fail in platform_reg_read" + return ret, info + support_dev_type = (CPLD, FPGA) + if dev_type not in support_dev_type: + info = "dev_type match erro, fail in platform_reg_read" + return ret, info + + # call the solve func + return platform.reg_read(dev_type, dev_id, offset, size) + + +########################################### +# platform_reg_write - write logic device register +# @dev_type: 0: CPLD, 1: FPGA +# @dev_id: device ID, start from 0 +# @offset: register offset +# @val_list: The write value list +# return: +# @ret: True if write success, False if not +# @info: The write value length if write success, otherwise the detail error message +########################################### +def platform_reg_write(dev_type, dev_id, offset, val_list): + ret = False + info = None + + # params check + if (isinstance(dev_type, int) is False or isinstance(dev_id, int) is False or + isinstance(offset, int) is False or isinstance(val_list, list) is False): + info = "params type check fail in platform_reg_write" + return ret, info + if dev_id < 0 or offset < 0 or len(val_list) <= 0: + info = "params value check fail in platform_reg_write" + return ret, info + support_dev_type = (CPLD, FPGA) + if dev_type not in support_dev_type: + info = "dev_type match erro, fail in platform_reg_write" + return ret, info + + # call the solve func + return platform.reg_write(dev_type, dev_id, offset, val_list) + + +########################################### +# platform_set_optoe_type - set port optoe type +# @port: port index start from 1 +# @optoe_type: optoe type, including the following values +# 1: OPTOE1 +# 2: OPTOE2 +# 3: OPTOE3 +# return: +# @ret: True if set optoe type success, False if not +# @info: None if set optoe type success, otherwise the detail error message +########################################### +def platform_set_optoe_type(port, optoe_type): + ret = False + info = None + + # params check + if isinstance(port, int) is False or isinstance(optoe_type, int) is False: + info = "params type check fail in platform_set_optoe_type" + return ret, info + if port < 0 or optoe_type < 1 or optoe_type > 3: + info = "params value check fail in platform_set_optoe_type" + return ret, info + + # call the solve func + return platform.set_optoe_type(port, optoe_type) + + +########################################### +# platform_get_optoe_type - get port optoe type +# @port: port index start from 1 +# return: +# @ret: True if set optoe type success, False if not +# @info: Optoe type value if get optoe type success, otherwise the detail error message +# optoe type including the following values +# 1: OPTOE1 +# 2: OPTOE2 +# 3: OPTOE3 +########################################### +def platform_get_optoe_type(port): + ret = False + info = None + + # params check + if isinstance(port, int) is False: + info = "params type check fail in platform_get_optoe_type" + return ret, info + if port < 0: + info = "params value check fail in platform_get_optoe_type" + return ret, info + + # call the solve func + return platform.get_optoe_type(port) + + +########################################### +# platform_sfp_read -read sfp eeprom +# @port_id: port index start from 1 +# @offset: sfp eeprom offset +# @size: read sfp eeprom length +# return: +# @ret: True if read success, False if not +# @info: The read value list if read success, otherwise the detail error message +########################################### +def platform_sfp_read(port_id, offset, size): + ret = False + info = None + + # params check + if isinstance(port_id, int) is False or isinstance(offset, int) is False or isinstance(size, int) is False: + info = "params type check fail in platform_sfp_read" + return ret, info + if port_id < 0 or offset < 0 or size <= 0: + info = "params value check fail in platform_sfp_read" + return ret, info + + # call the solve func + return platform.sfp_read(port_id, offset, size) + + +########################################### +# platform_sfp_write -write sfp eeprom +# @port_id: port index start from 1 +# @offset: sfp eeprom offset +# @val_list: The write value list +# return: +# @ret: True if read success, False if not +# @info: The write value length if write success, otherwise the detail error message +########################################### +def platform_sfp_write(port_id, offset, val_list): + ret = False + info = None + + # params check + if isinstance(port_id, int) is False or isinstance(offset, int) is False or isinstance(val_list, list) is False: + info = "params type check fail in platform_sfp_write" + return ret, info + if port_id < 0 or offset < 0 or len(val_list) <= 0: + info = "params value check fail in platform_sfp_write" + return ret, info + + # call the solve func + return platform.sfp_write(port_id, offset, val_list) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_ipmi.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_ipmi.py new file mode 100755 index 000000000000..c9b72c99cca9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_ipmi.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import sys +import os +import syslog +import click +from platform_util import exec_os_cmd + + +IPMITOOL_CMD = "ipmitool raw 0x32 0x04" # All products are the same command + +PLATFORM_IPMI_DEBUG_FILE = "/etc/.platform_ipmi_debug_flag" +UPGRADEDEBUG = 1 +debuglevel = 0 + + +def debug_init(): + global debuglevel + if os.path.exists(PLATFORM_IPMI_DEBUG_FILE): + debuglevel = debuglevel | UPGRADEDEBUG + else: + debuglevel = debuglevel & ~(UPGRADEDEBUG) + + +def ipmidebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if UPGRADEDEBUG & debuglevel: + syslog.openlog("PLATFORM_IPMI", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def ipmierror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("PLATFORM_IPMI", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +@click.command() +@click.argument('cmd', required=True) +def platform_ipmi_main(cmd): + '''Send command to BMC through ipmi''' + try: + # Convert string command to ASCII + user_cmd = "" + for ch in cmd: + user_cmd += " " + str(ord(ch)) + + final_cmd = IPMITOOL_CMD + user_cmd + ipmidebuglog("final cmd:%s" % final_cmd) + + # exec ipmitool cmd + status, output = exec_os_cmd(final_cmd) + if status: + ipmierror("exec ipmitool_cmd:%s user_cmd:%s failed" % (IPMITOOL_CMD, cmd)) + ipmierror("failed log: %s" % output) + return False, "exec final_cmd failed" + + # the data read by ipmitool is hex value, needs transformation + data_list = output.replace("\n", "").strip(' ').split(' ') + ipmidebuglog("data_list: %s" % data_list) + result = "" + for data in data_list: + result += chr(int(data, 16)) + + # 'result' string include ret and log, separated by , + result_list = result.split(',', 2) + if len(result_list) != 2: + log = "split failed. len(result) != 2. result:%s" % result + ipmierror(log) + return False, log + if int(result_list[0]) != 0: + ipmierror("finally analy ipmitool_cmd:%s user_cmd:%s exec failed" % (IPMITOOL_CMD, cmd)) + ipmierror("failed return log: %s" % result_list[1]) + print(result_list[1]) + return False, result_list[1] + + ipmidebuglog("finally exec ipmitool_cmd:%s user_cmd:%s success" % (IPMITOOL_CMD, cmd)) + print(result_list[1]) + return True, result_list[1] + + except Exception as e: + log = "An exception occurred, exception log:%s" % str(e) + ipmierror(log) + return False, log + + +if __name__ == '__main__': + debug_init() + ret, msg = platform_ipmi_main() + if ret is False: + sys.exit(1) + sys.exit(0) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_manufacturer.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_manufacturer.py new file mode 100755 index 000000000000..1404692bc93b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_manufacturer.py @@ -0,0 +1,591 @@ +#!/usr/bin/env python3 + +import re +import mmap +import fcntl +import subprocess +import shlex +import signal +import os +import time +import sys +from platform_config import MANUINFO_CONF +from monitor import status + + +INDENT = 4 + + +def printerr(vchar): + sys.stderr.write(vchar + '\n') + + +g_extra_cache = {} +g_meminfo_cache = {} +g_exphy_cache = {} + + +def exec_os_cmd(cmd, timeout = None): + status, output = subprocess.getstatusoutput(cmd) + return status, output + + +def exphyfwsplit(): + # improve performance + global g_exphy_cache + if g_exphy_cache: + return + cmd = "bcmcmd -t 1 \"phy control xe,ce fw_get\" |grep fw_version" + ret, output = exec_os_cmd(cmd) + if ret or len(output) == 0: + raise Exception("run cmd: {} error, status: {}, msg: {}".format(cmd, ret, output)) + exphyfwstr = output.strip() + portlist = exphyfwstr.split("\n") + for port in portlist: + phy_addr_str = get_regular_val(port, r"phy_addr\s*=\s*\w+", 0) + if phy_addr_str.startswith("ERR"): + continue + phy_addr_key = phy_addr_str.replace(" ", "") + if phy_addr_key in g_exphy_cache: + continue + + g_exphy_cache[phy_addr_key] = {} + + fw_version_str = get_regular_val(port, r"fw_version\s*=\s*\w+", 0) + if fw_version_str.startswith("ERR"): + del g_exphy_cache[phy_addr_key] + continue + + fw_version = fw_version_str.split("=")[1].strip() + g_exphy_cache[phy_addr_key]["fw_version"] = fw_version + + if "success" in port: + ret = "OK" + else: + ret = "Unexpected" + g_exphy_cache[phy_addr_key]["status"] = ret + return + + +def lshwmemorysplit(): + # improve performance + global g_meminfo_cache + if g_meminfo_cache: + return + cmd = "lshw -c memory" + ret, output = exec_os_cmd(cmd) + if ret or len(output) == 0: + raise Exception("run cmd: {} error, status: {}, msg: {}".format(cmd, ret, output)) + memstr = output.strip() + memlist = memstr.split("*-") + for item in memlist: + if item.strip().startswith("memory") and "System Memory" not in item: + continue + line_index = 0 + for line in item.splitlines(): + line_index += 1 + if line_index == 1: + memdict_key = line + g_meminfo_cache[memdict_key] = {} + else: + if ":" not in line: + continue + key = line.split(":", 1)[0].strip() + value = line.split(":", 1)[1].strip() + g_meminfo_cache[memdict_key][key] = value + if "empty" in item: + break + return + + +def run_extra_func(funcname): + # improve performance + if funcname in g_extra_cache: + return g_extra_cache.get(funcname) + func = getattr(status, funcname) + ret = [] + func(ret) + if ret: + g_extra_cache[funcname] = ret + return ret + + +def get_extra_value(funcname, itemid, key): + for item in run_extra_func(funcname): + if item.get("id") == itemid: + return item.get(key, "NA") + return "NA" + + +def io_wr(reg_addr, reg_data): + try: + regdata = 0 + regaddr = 0 + if isinstance(reg_addr, int): + regaddr = reg_addr + else: + regaddr = int(reg_addr, 16) + if isinstance(reg_data, int): + regdata = reg_data + else: + regdata = int(reg_data, 16) + devfile = "/dev/port" + fd = os.open(devfile, os.O_RDWR | os.O_CREAT) + os.lseek(fd, regaddr, os.SEEK_SET) + os.write(fd, regdata.to_bytes(1, 'little')) + return True + except ValueError as e: + print(e) + return False + except Exception as e: + print(e) + return False + finally: + os.close(fd) + + +def checksignaldriver(name): + modisexistcmd = "lsmod | grep -w %s | wc -l" % name + ret, output = exec_os_cmd(modisexistcmd) + if ret: + return False + if output.isdigit() and int(output) > 0: + return True + return False + + +def adddriver(name): + cmd = "modprobe %s" % name + if checksignaldriver(name) is not True: + ret, log = exec_os_cmd(cmd) + if ret != 0 or len(log) > 0: + return False + return True + return True + + +def removedriver(name): + cmd = "rmmod %s" % name + if checksignaldriver(name): + exec_os_cmd(cmd) + + +def add_5387_driver(): + errmsg = "" + spi_gpio = "wb_spi_gpio" + ret = adddriver(spi_gpio) + if ret is False: + errmsg = "modprobe wb_spi_gpio driver failed." + return False, errmsg + spi_5387_device = "wb_spi_93xx46 spi_bus_num=0" + ret = adddriver(spi_5387_device) + if ret is False: + errmsg = "modprobe wb_spi_93xx46 driver failed." + return ret, errmsg + return True, "" + + +def remove_5387_driver(): + spi_5387_device = "wb_spi_93xx46" + removedriver(spi_5387_device) + spi_gpio = "wb_spi_gpio" + removedriver(spi_gpio) + + +def deal_itmes(item_list): + for item in item_list: + dealtype = item.get("dealtype") + if dealtype == "shell": + cmd = item.get("cmd") + timeout = item.get("timeout", 10) + exec_os_cmd(cmd, timeout) + elif dealtype == "io_wr": + io_addr = item.get("io_addr") + wr_value = item.get("value") + io_wr(io_addr, wr_value) + + +def get_func_value(funcname, params): + func = getattr(ExtraFunc, funcname) + ret = func(params) + return ret + + +def read_pci_reg(pcibus, slot, fn, resource, offset): + '''read pci register''' + if offset % 4 != 0: + return "ERR offset: %d not 4 bytes align" + filename = "/sys/bus/pci/devices/0000:%02x:%02x.%x/resource%d" % (int(pcibus), int(slot), int(fn), int(resource)) + size = os.path.getsize(filename) + with open(filename, "r+") as file: + data = mmap.mmap(file.fileno(), size) + result = data[offset: offset + 4] + s = result[::-1] + val = 0 + for value in s: + val = val << 8 | value + data.close() + return "%08x" % val + + +def devfileread(path, offset, length, bit_width): + ret = "" + val_str = '' + val_list = [] + fd = -1 + if not os.path.exists(path): + return "%s not found !" % path + if length % bit_width != 0: + return "only support read by bit_width" + if length < bit_width: + return "len needs to greater than or equal to bit_width" + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, length) + for item in ret: + val_list.append(item) + + for i in range(0, length, bit_width): + val_str += " 0x" + for j in range(0, bit_width): + val_str += "%02x" % val_list[i + bit_width - j - 1] + except Exception as e: + return str(e) + finally: + if fd > 0: + os.close(fd) + return val_str + + +def read_reg(loc, offset, size): + with open(loc, 'rb') as file: + file.seek(offset) + return ' '.join(["%02x" % item for item in file.read(size)]) + + +def std_match(stdout, pattern): + if pattern is None: + return stdout.strip() + for line in stdout.splitlines(): + if re.match(pattern, line): + return line.strip() + raise EOFError("pattern: {} does not match anything in stdout {}".format( + pattern, stdout)) + + +def i2c_rd(bus, loc, offset): + ''' + read i2c with i2cget command + ''' + cmd = "i2cget -f -y {} {} {}".format(bus, loc, offset) + retrytime = 6 + for i in range(retrytime): + ret, stdout = subprocess.getstatusoutput(cmd) + if ret == 0: + return stdout + time.sleep(0.1) + raise RuntimeError("run cmd: {} error, status {}".format(cmd, ret)) + + +def i2c_rd_bytes(bus, loc, offset, size): + blist = [] + for i in range(size): + ret = i2c_rd(bus, loc, offset + i) + blist.append(ret) + + return blist + + +def get_pair_val(source, separator): + try: + value = source.split(separator, 1)[1] + except (ValueError, IndexError): + return "ERR separator: {} does not match in source: {}".format(separator, source) + return value.strip() + + +def get_regular_val(source, pattern, group): + try: + value = re.findall(pattern, source)[group] + except Exception: + return "ERR pattern: {} does not match in source: {} with group: {}".format(pattern, source, group) + return value.strip() + + +def find_match(file2read, pattern): + with open(file2read, 'r') as file: + for line in file: + if not re.match(pattern, line): + continue + return line.strip() + return "ERR pattern %s not match in %s" % (pattern, file2read) + + +def readaline(file2read): + with open(file2read, 'r') as file: + return file.readline() + + +def sort_key(e): + return e.arrt_index + + +class ExtraFunc(object): + @staticmethod + def get_bcm5387_version(params): + version = "" + try: + ret, msg = add_5387_driver() + if ret is False: + raise Exception(msg) + + before_deal_list = params.get("before", []) + deal_itmes(before_deal_list) + + ret, version = exec_os_cmd(params["get_version"]) + if ret != 0: + version = "ERR " + version + + after_deal_list = params.get("after", []) + deal_itmes(after_deal_list) + + except Exception as e: + version = "ERR %s" % (str(e)) + finally: + finally_deal_list = params.get("finally", []) + deal_itmes(finally_deal_list) + remove_5387_driver() + return version + + @staticmethod + def get_memory_value(params): + root_key = params.get("root_key") + sub_key = params.get("sub_key") + lshwmemorysplit() + return g_meminfo_cache.get(root_key, {}).get(sub_key, "NA") + + @staticmethod + def get_memory_bank_value(params): + lshwmemorysplit() + bank = params.get("bankid") + if g_meminfo_cache.get(bank, {}): + return True + return False + + @staticmethod + def get_exphy_fw(phyid): + exphyfwsplit() + if phyid not in g_exphy_cache: + return "ERR %s not found." % phyid + fw_version = g_exphy_cache.get(phyid).get("fw_version") + ret = g_exphy_cache.get(phyid).get("status") + msg = "%s %s" % (fw_version, ret) + return msg + +class CallbackSet: + def cpld_format(self, blist): + if isinstance(blist, str): + blist = blist.split() + elif not isinstance(blist, list) or len(blist) != 4: + raise ValueError("cpld format: wrong parameter: {}".format(blist)) + + return "{}{}{}{}".format(*blist).replace("0x", "") + + +class VersionHunter: + call = CallbackSet() + + def __init__(self, entires): + self.head = None + self.next = None + self.key = None + self.cmd = None + self.file = None + self.reg = None + self.i2c = None + self.extra = None + self.pattern = None + self.separator = None + self.parent = None + self.ignore = False + self.children = [] + self.level = 0 + self.callback = None + self.delspace = None + self.arrt_index = None + self.config = None + self.precheck = None + self.func = None + self.regular = None + self.group = 0 + self.pci = None + self.devfile = None + self.decode = None + self.timeout = 10 + self.__dict__.update(entires) + + def check_para(self): + if self.pattern is None: + return False + if self.cmd is None or self.file is None: + return False + return True + + def get_version(self): + ret = "NA" + try: + if self.cmd is not None: + ret, output = exec_os_cmd(self.cmd, self.timeout) + if ret or len(output) == 0: + raise RuntimeError("run cmd: {} error, status: {}, msg: {}".format(self.cmd, ret, output)) + ret = std_match(output, self.pattern) + elif self.file is not None: + ret = self.read_file() + elif self.reg is not None: + ret = read_reg(self.reg.get("loc"), self.reg.get("offset"), + self.reg.get("size")) + elif self.extra: + ret = get_extra_value(self.extra.get("funcname"), + self.extra.get("id"), + self.extra.get("key")) + elif self.i2c: + ret = i2c_rd_bytes(self.i2c.get("bus"), self.i2c.get("loc"), + self.i2c.get("offset"), + self.i2c.get("size")) + elif self.config: + ret = self.config + elif self.func: + ret = get_func_value(self.func.get("funcname"), + self.func.get("params")) + elif self.pci: + ret = read_pci_reg(self.pci.get("bus"), self.pci.get("slot"), + self.pci.get("fn"), self.pci.get("bar"), self.pci.get("offset")) + elif self.devfile: + ret = devfileread(self.devfile.get("loc"), self.devfile.get("offset"), + self.devfile.get("len"), self.devfile.get("bit_width")) + + except Exception as e: + # printerr(e.message) + return "ERR %s" % str(e) + return self.exe_callback(ret) + + def exe_callback(self, data): + try: + if self.callback: + method = getattr(self.call, self.callback) + return method(data) + except Exception: + return "ERR run callback method: {} error, data: {}".format(self.callback, data) + return data + + def read_file(self): + if self.pattern is not None: + return find_match(self.file, self.pattern) + return readaline(self.file) + + def hunt(self): + if self.ignore: + return + indent = self.level * INDENT * " " + + if self.precheck: + try: + ret = get_func_value(self.precheck.get("funcname"), self.precheck.get("params")) + if ret is not True: + return + except Exception as e: + err_msg = "ERR %s" % str(e) + format_str = "{}{:<{}}{}".format(indent, self.key + ':', + (30 - len(indent)), err_msg) + print(format_str) + return + # has children + if self.children: + self.children.sort(key=sort_key) + format_str = "{}{}:".format(indent, self.key) + print(format_str) + for child in self.children: + if not isinstance(child, VersionHunter): + continue + child.level = self.level + 1 + child.hunt() + else: + version = self.get_version() or "" + if not version.startswith("ERR"): + version = version.replace("\x00", "").strip() + if self.separator is not None: + version = get_pair_val(version, self.separator) + if self.delspace is not None: + version = version.replace(" ", "") + if self.regular is not None: + version = get_regular_val(version, self.regular, self.group) + if self.decode is not None: + tmp_version = self.decode.get(version) + if tmp_version is None: + version = "ERR decode %s failed" % version + else: + version = tmp_version + format_str = "{}{:<{}}{}".format(indent, self.key + ':', + (30 - len(indent)), version) + print(format_str) + + if self.next: + print("") + self.next.hunt() + + +pidfile = 0 + + +def ApplicationInstance(): + global pidfile + pidfile = open(os.path.realpath(__file__), "r") + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + return True + except Exception: + return False + + +def run(): + if os.geteuid() != 0: + print("Root privileges are required for this operation") + sys.exit(1) + + start_time = time.time() + while True: + ret = ApplicationInstance() + if ret is True: + break + if time.time() - start_time > 10: + printerr("manufacturer is running.") + sys.exit(1) + time.sleep(0.5) + + objmap = {} + + try: + target = {} + target.update(MANUINFO_CONF) + for objname, value in target.items(): + objmap[objname] = VersionHunter(value) + except Exception as e: + printerr(str(e)) + sys.exit(1) + + head = None + for objname, obj in objmap.items(): + if head is None and obj.head: + head = obj + if obj.parent: + objmap.get(obj.parent).children.append(obj) + if obj.next: + obj.next = objmap.get(obj.next) + + head.hunt() + + +if __name__ == "__main__": + run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_process.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_process.py new file mode 100755 index 000000000000..75bc95975520 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_process.py @@ -0,0 +1,396 @@ +#!/usr/bin/env python3 +import os +import subprocess +import glob +import time +import click +from platform_config import STARTMODULE, MAC_LED_RESET, AIRFLOW_RESULT_FILE +from platform_config import GLOBALINITPARAM, GLOBALINITCOMMAND, GLOBALINITPARAM_PRE, GLOBALINITCOMMAND_PRE +from platform_util import wbpciwr + + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def log_os_system(cmd): + status, output = subprocess.getstatusoutput(cmd) + if status: + print(output) + return status, output + + +def write_sysfs_value(reg_name, value): + mb_reg_file = "/sys/bus/i2c/devices/" + reg_name + locations = glob.glob(mb_reg_file) + if len(locations) == 0: + print("%s not found" % mb_reg_file) + return False + sysfs_loc = locations[0] + try: + with open(sysfs_loc, 'w') as fd: + fd.write(value) + except Exception: + return False + return True + + +def getPid(name): + ret = [] + for dirname in os.listdir('/proc'): + if dirname == 'curproc': + continue + try: + with open('/proc/{}/cmdline'.format(dirname), mode='r') as fd: + content = fd.read() + except Exception: + continue + if name in content: + ret.append(dirname) + return ret + + +def startAvscontrol(): + if STARTMODULE.get('avscontrol', 0) == 1: + cmd = "nohup avscontrol.py start >/dev/null 2>&1 &" + rets = getPid("avscontrol.py") + if len(rets) == 0: + os.system(cmd) + + +def startFanctrol(): + if STARTMODULE.get('fancontrol', 0) == 1: + cmd = "nohup fancontrol.py start >/dev/null 2>&1 &" + rets = getPid("fancontrol.py") + if len(rets) == 0: + os.system(cmd) + + +def starthal_fanctrl(): + if STARTMODULE.get('hal_fanctrl', 0) == 1: + cmd = "nohup hal_fanctrl.py start >/dev/null 2>&1 &" + rets = getPid("hal_fanctrl.py") + if len(rets) == 0: + os.system(cmd) + + +def starthal_ledctrl(): + if STARTMODULE.get('hal_ledctrl', 0) == 1: + cmd = "nohup hal_ledctrl.py start >/dev/null 2>&1 &" + rets = getPid("hal_ledctrl.py") + if len(rets) == 0: + os.system(cmd) + + +def startDevmonitor(): + if STARTMODULE.get('dev_monitor', 0) == 1: + cmd = "nohup dev_monitor.py start >/dev/null 2>&1 &" + rets = getPid("dev_monitor.py") + if len(rets) == 0: + os.system(cmd) + + +def startSlotmonitor(): + if STARTMODULE.get('slot_monitor', 0) == 1: + cmd = "nohup slot_monitor.py start >/dev/null 2>&1 &" + rets = getPid("slot_monitor.py") + if len(rets) == 0: + os.system(cmd) + + +def startIntelligentmonitor(): + if STARTMODULE.get('intelligent_monitor', 0) == 1: + cmd = "nohup intelligent_monitor.py >/dev/null 2>&1 &" + rets = getPid("intelligent_monitor.py") + if len(rets) == 0: + os.system(cmd) + + +def startSignalmonitor(): + if STARTMODULE.get('signal_monitor', 0) == 1: + cmd = "nohup signal_monitor.py start >/dev/null 2>&1 &" + rets = getPid("signal_monitor.py") + if len(rets) == 0: + os.system(cmd) + + +def startSff_temp_polling(): + if STARTMODULE.get('sff_temp_polling', 0) == 1: + cmd = "nohup sfp_highest_temperatue.py >/dev/null 2>&1 &" + rets = getPid("sfp_highest_temperatue.py") + if len(rets) == 0: + os.system(cmd) + + +def startRebootCause(): + if STARTMODULE.get('reboot_cause', 0) == 1: + cmd = "nohup reboot_cause.py >/dev/null 2>&1 &" + rets = getPid("reboot_cause.py") + if len(rets) == 0: + os.system(cmd) + + +def startPMON_sys(): + if STARTMODULE.get('pmon_syslog', 0) == 1: + cmd = "nohup pmon_syslog.py >/dev/null 2>&1 &" + rets = getPid("pmon_syslog.py") + if len(rets) == 0: + os.system(cmd) + + +def startSff_polling(): + if STARTMODULE.get('sff_polling', 0) == 1: + cmd = "nohup sff_polling.py start > /dev/null 2>&1 &" + rets = getPid("sff_polling.py") + if len(rets) == 0: + os.system(cmd) + + +def generate_air_flow(): + cmd = "nohup generate_airflow.py > /dev/null 2>&1 &" + rets = getPid("generate_airflow.py") + if len(rets) == 0: + os.system(cmd) + time.sleep(1) + + +def startGenerate_air_flow(): + if STARTMODULE.get('generate_airflow', 0) == 1: + for i in range(10): + generate_air_flow() + if os.path.exists(AIRFLOW_RESULT_FILE): + click.echo("%%WB_PLATFORM_PROCESS: generate air flow success") + return + time.sleep(1) + click.echo("%%WB_PLATFORM_PROCESS: generate air flow,failed, %s not exits" % AIRFLOW_RESULT_FILE) + return + + +def start_tty_console(): + if STARTMODULE.get('tty_console', 0) == 1: + cmd = "nohup tty_console.py > /dev/null 2>&1 &" + rets = getPid("tty_console.py") + if len(rets) == 0: + os.system(cmd) + + +def stopAvscontrol(): + if STARTMODULE.get('avscontrol', 0) == 1: + rets = getPid("avscontrol.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopFanctrol(): + if STARTMODULE.get('fancontrol', 0) == 1: + rets = getPid("fancontrol.py") # + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stophal_fanctrl(): + if STARTMODULE.get('hal_fanctrl', 0) == 1: + rets = getPid("hal_fanctrl.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stophal_ledctrl(): + if STARTMODULE.get('hal_ledctrl', 0) == 1: + rets = getPid("hal_ledctrl.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopDevmonitor(): + if STARTMODULE.get('dev_monitor', 0) == 1: + rets = getPid("dev_monitor.py") # + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopSlotmonitor(): + if STARTMODULE.get('slot_monitor', 0) == 1: + rets = getPid("slot_monitor.py") # + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopIntelligentmonitor(): + if STARTMODULE.get('intelligent_monitor', 0) == 1: + rets = getPid("intelligent_monitor.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopSignalmonitor(): + if STARTMODULE.get('signal_monitor', 0) == 1: + rets = getPid("signal_monitor.py") # + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopSff_temp_polling(): + if STARTMODULE.get('sff_temp_polling', 0) == 1: + rets = getPid("sfp_highest_temperatue.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopPMON_sys(): + if STARTMODULE.get('pmon_syslog', 0) == 1: + rets = getPid("pmon_syslog.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopRebootCause(): + if STARTMODULE.get('reboot_cause', 0) == 1: + rets = getPid("reboot_cause.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopSff_polling(): + if STARTMODULE.get('sff_polling', 0) == 1: + rets = getPid("sff_polling.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stopGenerate_air_flow(): + if STARTMODULE.get('generate_airflow', 0) == 1: + rets = getPid("generate_airflow.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def stop_tty_console(): + if STARTMODULE.get('tty_console', 0) == 1: + rets = getPid("tty_console.py") + for ret in rets: + cmd = "kill " + ret + os.system(cmd) + + +def otherinit(): + for index in GLOBALINITPARAM: + write_sysfs_value(index["loc"], index["value"]) + + for index in GLOBALINITCOMMAND: + log_os_system(index) + + +def otherinit_pre(): + for index in GLOBALINITPARAM_PRE: + write_sysfs_value(index["loc"], index["value"]) + + for index in GLOBALINITCOMMAND_PRE: + log_os_system(index) + + +def unload_apps(): + stopSff_polling() + stopPMON_sys() + stopSignalmonitor() + stopIntelligentmonitor() + stopSlotmonitor() + stopDevmonitor() + stopAvscontrol() + stophal_ledctrl() + stophal_fanctrl() + stopFanctrol() + stopSff_temp_polling() + stopRebootCause() + stop_tty_console() + stopGenerate_air_flow() + + +def MacLedSet(data): + '''write pci register''' + pcibus = MAC_LED_RESET.get("pcibus") + slot = MAC_LED_RESET.get("slot") + fn = MAC_LED_RESET.get("fn") + resource = MAC_LED_RESET.get("bar") + offset = MAC_LED_RESET.get("offset") + val = MAC_LED_RESET.get(data, None) + if val is None: + click.echo("%%WB_PLATFORM_PROCESS-INIT: MacLedSet wrong input") + return + wbpciwr(pcibus, slot, fn, resource, offset, val) + + +def load_apps(): + otherinit_pre() + startGenerate_air_flow() + start_tty_console() + startRebootCause() + startSff_temp_polling() + startFanctrol() + starthal_fanctrl() + starthal_ledctrl() + startAvscontrol() + startDevmonitor() + startSlotmonitor() + startIntelligentmonitor() + startSignalmonitor() + startPMON_sys() + startSff_polling() + otherinit() + if STARTMODULE.get("macledreset", 0) == 1: + MacLedSet("reset") + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''device operator''' + + +@main.command() +def start(): + '''load process ''' + load_apps() + + +@main.command() +def stop(): + '''stop process ''' + unload_apps() + + +@main.command() +def restart(): + '''restart process''' + unload_apps() + load_apps() + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_sensors.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_sensors.py new file mode 100755 index 000000000000..1727242b74b9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_sensors.py @@ -0,0 +1,253 @@ +#!/usr/bin/python3 + +import os +import sys +import importlib.machinery + + +def get_machine_info(): + if not os.path.isfile('/host/machine.conf'): + return None + machine_vars = {} + with open('/host/machine.conf') as machine_file: + for line in machine_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + machine_vars[tokens[0]] = tokens[1].strip() + return machine_vars + + +def get_platform_info(machine_info): + if machine_info is not None: + if 'onie_platform' in machine_info: + return machine_info['onie_platform'] + if 'aboot_platform' in machine_info: + return machine_info['aboot_platform'] + return None + + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +PLATFORM_SPECIFIC_MODULE_NAME = 'monitor' +PLATFORM_SPECIFIC_CLASS_NAME = 'status' +platform_status_class = None +platform = None + + +def get_platform_name(): + global platform + platform = get_platform_info(get_machine_info()) + return platform + + +val = get_platform_name() +sys.path.append("/".join([PLATFORM_ROOT_PATH, platform])) + +# Loads platform specific sfputil module from source + + +def load_platform_monitor(): + global platform_status_class + platform_name = get_platform_info(get_machine_info()) + platform_path = "/".join([PLATFORM_ROOT_PATH, platform_name]) + try: + module_file = "/".join([platform_path, PLATFORM_SPECIFIC_MODULE_NAME + ".py"]) + module = importlib.machinery.SourceFileLoader(PLATFORM_SPECIFIC_MODULE_NAME, module_file).load_module() + except IOError: + return -1 + try: + platform_status_class = getattr(module, PLATFORM_SPECIFIC_CLASS_NAME) + except AttributeError: + return -2 + return 0 + + +def printerr(msg): + print("\033[0;31m%s\033[0m" % msg) + + +def print_console(msg): + print(msg) + + +val_t = load_platform_monitor() +if val_t != 0: + raise Exception("load monitor.py error") + + +def print_platform(): + platform_info = get_platform_name() + print_console(platform_info) + print_console("") + + +def print_cputemp_sensors(): + val_ret = get_call_value_by_function("getcputemp") + print_info_str = "" + toptile = "Onboard coretemp Sensors:" + formatstr = " {name:<20} : {temp} C (high = {max} C , crit = {crit} C )" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + print_info_str += formatstr.format(**item) + '\n' + print_console(print_info_str) + + +def print_boardtemp(): + val_ret = get_call_value_by_function("getTemp") + print_info_str = "" + toptile = "Onboard Temperature Sensors:" + errformat = " {id:<20} : {errmsg}" + formatstr = " {id:<20} : {temp1_input} C (high = {temp1_max} C, hyst = {temp1_max_hyst} C)" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + realformat = formatstr if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + '\n' + print_console(print_info_str) + + +def print_mactemp_sensors(): + val_ret = get_call_value_by_function("getmactemp") + print_info_str = "" + toptile = "Onboard MAC Temperature Sensors:" + errformat = " {id:<20} : {errmsg}" + formatstr = " {id:<20} : {temp_input} C" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + realformat = formatstr if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + '\n' + print_console(print_info_str) + + +def print_macpower_sensors(): + val_ret = get_call_value_by_function("getmacpower") + print_info_str = "" + toptile = "Onboard MAC Power Sensors:" + errformat = " {id:<20} : {errmsg}" + formatstr = " {id:<20} : {power_input} W" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + realformat = formatstr if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + '\n' + print_console(print_info_str) + + +def print_fan_sensor(): + val_ret = get_call_value_by_function("checkFan") + print_info_str = "" + toptile = "Onboard fan Sensors:" + errformat = " {id} : {errmsg}\n" # " {id:<20} : {errmsg}" + fan_signle_rotor_format = " {id} : \n" \ + " fan_type :{fan_type}\n" \ + " sn :{sn}\n" \ + " hw_version:{hw_version}\n" \ + " Speed :{Speed} RPM\n" \ + " status :{errmsg} \n" + fan_double_rotor_format = " {id} : \n" \ + " fan_type :{fan_type}\n" \ + " sn :{sn}\n" \ + " hw_version:{hw_version}\n" \ + " Speed :\n" \ + " speed_front :{rotor1_speed:<5} RPM\n" \ + " speed_rear :{rotor2_speed:<5} RPM\n" \ + " status :{errmsg} \n" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + if item.get('Speed', None) is None: + realformat = fan_double_rotor_format if item.get('errcode', 0) == 0 else errformat + else: + realformat = fan_signle_rotor_format if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + print_console(print_info_str) + + +def print_psu_sensor(): + val_ret = get_call_value_by_function("getPsu") + print_info_str = "" + toptile = "Onboard Power Supply Unit Sensors:" + errformat = " {id} : {errmsg}\n" # " {id:<20} : {errmsg}" + psuformat = " {id} : \n" \ + " type :{type1}\n" \ + " sn :{sn}\n" \ + " in_current :{in_current} A\n" \ + " in_voltage :{in_voltage} V\n" \ + " out_current:{out_current} A\n" \ + " out_voltage:{out_voltage} V\n" \ + " temp :{temp} C \n" \ + " fan_speed :{fan_speed} RPM\n" \ + " in_power :{in_power} W\n" \ + " out_power :{out_power} W\n" + + if len(val_ret) != 0: + print_info_str += toptile + '\r\n' + for item in val_ret: + realformat = psuformat if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + print_console(print_info_str) + + +def print_slot_sensor(): + val_ret = get_call_value_by_function("checkSlot") + print_info_str = "" + toptile = "Onboard slot Sensors:" + errformat = " {id} : {errmsg}\n" # " {id:<20} : {errmsg}" + psuformat = " {id} : \n" \ + " slot_type :{slot_type}\n" \ + " sn :{sn}\n" \ + " hw_version :{hw_version} \n" \ + " status :{errmsg}\n" + + if len(val_ret) != 0: + print_info_str += toptile + '\r\n' + for item in val_ret: + realformat = psuformat if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + print_console(print_info_str) + + +def print_boarddcdc(): + val_ret = get_call_value_by_function("getDcdc") + print_info_str = "" + toptile = "Onboard DCDC Sensors:" + errformat = " {id:<26} : {errmsg}" + formatstr = " {id:<26} : {dcdc_input:<6} {dcdc_unit:<1} (Min = {dcdc_min:<6} {dcdc_unit:<1}, Max = {dcdc_max:<6} {dcdc_unit:<1})" + + if len(val_ret) != 0: + print_info_str += toptile + '\n' + for item in val_ret: + realformat = formatstr if item.get('errcode', 0) == 0 else errformat + print_info_str += realformat.format(**item) + '\n' + print_console(print_info_str) + + +def get_call_value_by_function(function_name): + valtemp = [] + if hasattr(platform_status_class, function_name): + test2_func = getattr(platform_status_class, function_name) + test2_func(valtemp) + return valtemp + + +def getsensors(): + print_platform() + print_cputemp_sensors() + print_boardtemp() + print_mactemp_sensors() + print_macpower_sensors() + print_fan_sensor() + print_psu_sensor() + print_slot_sensor() + print_boarddcdc() + + +if __name__ == "__main__": + getsensors() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_test.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_test.py new file mode 100755 index 000000000000..da7119a9ce49 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_test.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- + +try: + import click + from platform_intf import platform_reg_read, platform_reg_write, platform_get_optoe_type + from platform_intf import platform_set_optoe_type, platform_sfp_read, platform_sfp_write +except ImportError as error: + raise ImportError('%s - required module not found' % str(error)) from error + + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def print_reg(info, offset): + try: + size = len(info) + j = offset % 16 + tmp = j + offset -= j + print_buf = "\n " + + for i in range(16): + print_buf = print_buf + "%2x " % i + print(print_buf) + + print_buf = None + for i in range(size + j): + if i % 16 == 0: + print_buf = "" + print_buf = "0x%08x " % offset + offset = offset + 16 + if tmp: + print_buf = print_buf + " " + tmp = tmp - 1 + else: + print_buf = print_buf + "%02x " % info[i - j] + if (i + 1) % 16 == 0 or i == size + j - 1: + print(print_buf) + except Exception as e: + msg = str(e) + print("i = %d, j = %d," % (i, j)) + print(msg) + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''platform_test main''' + + +@main.command() +@click.argument('dev_type', required=True) +@click.argument('dev_id', required=True) +@click.argument('offset', required=True) +@click.argument('size', required=True) +def reg_rd(dev_type, dev_id, offset, size): + '''read cpld/fpga reg''' + ret, info = platform_reg_read(int(dev_type), int(dev_id), int(offset), int(size)) + print(ret) + if ret is True: + print_reg(info, int(offset)) + else: + print(info) + + +@main.command() +@click.argument('dev_type', required=True) +@click.argument('dev_id', required=True) +@click.argument('offset', required=True) +@click.argument('value', required=True) +def reg_wr(dev_type, dev_id, offset, value): + '''write cpld/fpga reg''' + value_list = [] + value_list.append(int(value)) + ret, info = platform_reg_write(int(dev_type), int(dev_id), int(offset), value_list) + print(ret) + print(info) + + +@main.command() +@click.argument('port', required=True) +def get_optoe_type(port): + '''get optoe type''' + ret, info = platform_get_optoe_type(int(port)) + print(ret) + print(info) + + +@main.command() +@click.argument('port', required=True) +@click.argument('optoe_type', required=True) +def set_optoe_type(port, optoe_type): + '''set optoe type''' + ret, info = platform_set_optoe_type(int(port), int(optoe_type)) + print(ret) + print(info) + + +@main.command() +@click.argument('port_id', required=True) +@click.argument('offset', required=True) +@click.argument('size', required=True) +def sfp_rd(port_id, offset, size): + '''read sfp''' + ret, info = platform_sfp_read(int(port_id), int(offset), int(size)) + print(ret) + if ret is True: + print_reg(info, int(offset)) + else: + print(info) + + +@main.command() +@click.argument('port_id', required=True) +@click.argument('offset', required=True) +@click.argument('value', required=True) +def sfp_wr(port_id, offset, value): + '''write sfp''' + value_list = [] + value_list.append(int(value)) + ret, info = platform_sfp_write(int(port_id), int(offset), value_list) + print(ret) + print(info) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_util.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_util.py new file mode 100755 index 000000000000..e7e6c8b1d6eb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/platform_util.py @@ -0,0 +1,845 @@ +#!/usr/bin/python3 + +import sys +import os +import re +import subprocess +import shlex +import time +import mmap +import glob +import logging.handlers +import shutil +import gzip +import ast + + +CONFIG_DB_PATH = "/etc/sonic/config_db.json" +MAILBOX_DIR = "/sys/bus/i2c/devices/" + + +__all__ = [ + "strtoint", + "byteTostr", + "getplatform_name", + "wbi2cget", + "wbi2cset", + "wbpcird", + "wbpciwr", + "wbi2cgetWord", + "wbi2csetWord", + "wbi2cset_pec", + "wbi2cset_wordpec", + "wbsysset", + "dev_file_read", + "dev_file_write", + "wb_os_system", + "io_rd", + "io_wr", + "exec_os_cmd", + "exec_os_cmd_log", + "write_sysfs", + "read_sysfs", + "get_sysfs_value", + "write_sysfs_value", + "get_value", + "set_value", + "getSdkReg", + "getMacTemp", + "getMacTemp_sysfs", + "get_format_value" +] + +class CodeVisitor(ast.NodeVisitor): + + def __init__(self): + self.value = None + + def get_value(self): + return self.value + + def get_op_value(self, node): + if isinstance(node, ast.Call): # node is func call + value = self.visit_Call(node) + elif isinstance(node, ast.BinOp): # node is BinOp + value = self.visit_BinOp(node) + elif isinstance(node, ast.UnaryOp): # node is UnaryOp + value = self.visit_UnaryOp(node) + elif isinstance(node, ast.Num): # node is Num Constant + value = node.n + elif isinstance(node, ast.Str): # node is Str Constant + value = node.s + else: + raise NotImplementedError("Unsupport operand type: %s" % type(node)) + return value + + def visit_UnaryOp(self, node): + ''' + node.op: operand type, only support ast.UAdd/ast.USub + node.operand: only support ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp/ast.UnaryOp + ''' + + operand_value = self.get_op_value(node.operand) + if isinstance(node.op, ast.UAdd): + self.value = operand_value + elif isinstance(node.op, ast.USub): + self.value = 0 - operand_value + else: + raise NotImplementedError("Unsupport arithmetic methods %s" % type(node.op)) + return self.value + + def visit_BinOp(self, node): + ''' + node.left: left operand, only support ast.Call/ast.Constant(ast.Num)/ast.BinOp + node.op: operand type, only support ast.Add/ast.Sub/ast.Mult/ast.Div + node.right: right operan, only support ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp + ''' + left_value = self.get_op_value(node.left) + right_value = self.get_op_value(node.right) + + if isinstance(node.op, ast.Add): + self.value = left_value + right_value + elif isinstance(node.op, ast.Sub): + self.value = left_value - right_value + elif isinstance(node.op, ast.Mult): + self.value = left_value * right_value + elif isinstance(node.op, ast.Div): + self.value = left_value / right_value + else: + raise NotImplementedError("Unsupport arithmetic methods %s" % type(node.op)) + return self.value + + def visit_Call(self, node): + ''' + node.func.id: func name, only support 'float', 'int', 'str' + node.args: func args list,only support ast.Constant(ast.Num/ast.Str)/ast.BinOp/ast.Call + str/float only support one parameter, eg: float(XXX), str(xxx) + int support one or two parameters, eg: int(xxx) or int(xxx, 16) + xxx can be ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp + ''' + calc_tuple = ("float", "int", "str") + + if node.func.id not in calc_tuple: + raise NotImplementedError("Unsupport function call type: %s" % node.func.id) + + args_val_list = [] + for item in node.args: + ret = self.get_op_value(item) + args_val_list.append(ret) + + if node.func.id == "str": + if len(args_val_list) != 1: + raise TypeError("str() takes 1 positional argument but %s were given" % len(args_val_list)) + value = str(args_val_list[0]) + self.value = value + return value + + if node.func.id == "float": + if len(args_val_list) != 1: + raise TypeError("float() takes 1 positional argument but %s were given" % len(args_val_list)) + value = float(args_val_list[0]) + self.value = value + return value + # int + if len(args_val_list) == 1: + value = int(args_val_list[0]) + self.value = value + return value + if len(args_val_list) == 2: + value = int(args_val_list[0], args_val_list[1]) + self.value = value + return value + raise TypeError("int() takes 1 or 2 arguments (%s given)" % len(args_val_list)) + +def inttostr(vl, length): + if not isinstance(vl, int): + raise Exception(" type error") + index = 0 + ret_t = "" + while index < length: + ret = 0xff & (vl >> index * 8) + ret_t += chr(ret) + index += 1 + return ret_t + + +def strtoint(str_tmp): + value = 0 + rest_v = str_tmp.replace("0X", "").replace("0x", "") + str_len = len(rest_v) + for index, val in enumerate(rest_v): + value |= int(val, 16) << ((str_len - index - 1) * 4) + return value + + +def inttobytes(val, length): + if not isinstance(val, int): + raise Exception("type error") + data_array = bytearray() + index = 0 + while index < length: + ret = 0xff & (val >> index * 8) + data_array.append(ret) + index += 1 + return data_array + + +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + strtmp = '' + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + + +def getonieplatform(path): + if not os.path.isfile(path): + return "" + machine_vars = {} + with open(path) as machine_file: + for line in machine_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + machine_vars[tokens[0]] = tokens[1].strip() + return machine_vars.get("onie_platform") + + +def getplatform_config_db(): + if not os.path.isfile(CONFIG_DB_PATH): + return "" + val = os.popen("sonic-cfggen -j %s -v DEVICE_METADATA.localhost.platform" % CONFIG_DB_PATH).read().strip() + if len(val) <= 0: + return "" + return val + + +def getplatform_name(): + if os.path.isfile('/host/machine.conf'): + return getonieplatform('/host/machine.conf') + if os.path.isfile('/usr/share/sonic/hwsku/machine.conf'): + return getonieplatform('/usr/share/sonic/hwsku/machine.conf') + return getplatform_config_db() + + +def wbi2cget(bus, devno, address, word=None): + if word is None: + command_line = "i2cget -f -y %d 0x%02x 0x%02x " % (bus, devno, address) + else: + command_line = "i2cget -f -y %d 0x%02x 0x%02x %s" % (bus, devno, address, word) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + time.sleep(0.1) + return False, ret_t + + +def wbi2cset(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbpcird(pcibus, slot, fn, resource, offset): + '''read pci register''' + if offset % 4 != 0: + return "ERR offset: %d not 4 bytes align" + filename = "/sys/bus/pci/devices/0000:%02x:%02x.%x/resource%d" % (int(pcibus), int(slot), int(fn), int(resource)) + with open(filename, "r+") as file: + size = os.path.getsize(filename) + data = mmap.mmap(file.fileno(), size) + result = data[offset: offset + 4] + s = result[::-1] + val = 0 + for value in s: + val = val << 8 | value + data.close() + return "0x%08x" % val + + +def wbpciwr(pcibus, slot, fn, resource, offset, data): + '''write pci register''' + ret = inttobytes(data, 4) + filename = "/sys/bus/pci/devices/0000:%02x:%02x.%x/resource%d" % (int(pcibus), int(slot), int(fn), int(resource)) + with open(filename, "r+") as file: + size = os.path.getsize(filename) + data = mmap.mmap(file.fileno(), size) + data[offset: offset + 4] = ret + result = data[offset: offset + 4] + s = result[::-1] + val = 0 + for value in s: + val = val << 8 | value + data.close() + + +def wbi2cgetWord(bus, devno, address): + command_line = "i2cget -f -y %d 0x%02x 0x%02x w" % (bus, devno, address) + retrytime = 3 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbi2csetWord(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%x w" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbi2cset_pec(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x bp" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbi2cset_wordpec(bus, devno, address, byte): + command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x wp" % ( + bus, devno, address, byte) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def wbsysset(location, value): + command_line = "echo 0x%02x > %s" % (value, location) + retrytime = 6 + ret_t = "" + for i in range(retrytime): + ret, ret_t = wb_os_system(command_line) + if ret == 0: + return True, ret_t + return False, ret_t + + +def dev_file_read(path, offset, read_len): + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + return True, val_list + + +def dev_file_write(path, offset, buf_list): + msg = "" + fd = -1 + + if not isinstance(buf_list, list) or len(buf_list) == 0: + msg = "buf:%s is not list type or is NONE !" % buf_list + return False, msg + + if not os.path.exists(path): + msg = path + " not found !" + return False, msg + + try: + fd = os.open(path, os.O_WRONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.write(fd, bytes(buf_list)) + except Exception as e: + msg = str(e) + return False, msg + finally: + if fd > 0: + os.close(fd) + + return True, ret + + +def wb_os_system(cmd): + status, output = subprocess.getstatusoutput(cmd) + return status, output + + +def io_rd(reg_addr, read_len=1): + try: + regaddr = 0 + if isinstance(reg_addr, int): + regaddr = reg_addr + else: + regaddr = int(reg_addr, 16) + devfile = "/dev/port" + fd = os.open(devfile, os.O_RDWR | os.O_CREAT) + os.lseek(fd, regaddr, os.SEEK_SET) + val = os.read(fd, read_len) + return "".join(["%02x" % item for item in val]) + except ValueError: + return None + except Exception as e: + print(e) + return None + finally: + os.close(fd) + + +def io_wr(reg_addr, reg_data): + try: + regdata = 0 + regaddr = 0 + if isinstance(reg_addr, int): + regaddr = reg_addr + else: + regaddr = int(reg_addr, 16) + if isinstance(reg_data, int): + regdata = reg_data + else: + regdata = int(reg_data, 16) + devfile = "/dev/port" + fd = os.open(devfile, os.O_RDWR | os.O_CREAT) + os.lseek(fd, regaddr, os.SEEK_SET) + os.write(fd, regdata.to_bytes(1, 'little')) + return True + except ValueError as e: + print(e) + return False + except Exception as e: + print(e) + return False + finally: + os.close(fd) + + +def exec_os_cmd(cmd): + cmds = cmd.split('|') + procs = [] + for i, c in enumerate(cmds): + stdin = None if i == 0 else procs[i-1].stdout + p = subprocess.Popen(shlex.split(c), stdin=stdin, stdout=subprocess.PIPE, shell=False, stderr=subprocess.STDOUT) + procs.append(p) + for proc in procs: + proc.wait() + return procs[-1].returncode, typeTostr(procs[-1].communicate()[0]) + + +def exec_os_cmd_log(cmd): + proc = subprocess.Popen(shlex.split(cmd), stdin=subprocess.PIPE, shell=False, stderr=sys.stderr, close_fds=True, + stdout=sys.stdout, universal_newlines=True, bufsize=1) + proc.wait() + stdout = proc.communicate()[0] + stdout = typeTostr(stdout) + return proc.returncode, stdout + + +def write_sysfs(location, value): + try: + if not os.path.isfile(location): + return False, ("location[%s] not found !" % location) + with open(location, 'w') as fd1: + fd1.write(value) + except Exception as e: + return False, (str(e) + " location[%s]" % location) + return True, ("set location[%s] %s success !" % (location, value)) + + +def read_sysfs(location): + try: + locations = glob.glob(location) + with open(locations[0], 'rb') as fd1: + retval = fd1.read() + retval = typeTostr(retval) + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + except Exception as e: + return False, (str(e) + "location[%s]" % location) + return True, retval + + +def get_pmc_register(reg_name): + retval = 'ERR' + mb_reg_file = MAILBOX_DIR + reg_name + filepath = glob.glob(mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) + mb_reg_file = filepath[0] + if not os.path.isfile(mb_reg_file): + return "%s %s notfound" % (retval, mb_reg_file) + try: + with open(mb_reg_file, 'r') as fd: + retval = fd.read() + except Exception as error: + retval = retval + str(error) + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +def get_sysfs_value(location): + pos_t = str(location) + name = get_pmc_register(pos_t) + return name + + +def write_sysfs_value(reg_name, value): + fileLoc = MAILBOX_DIR + reg_name + try: + if not os.path.isfile(fileLoc): + print(fileLoc, 'not found !') + return False + with open(fileLoc, 'w') as fd: + fd.write(value) + except Exception: + print("Unable to open " + fileLoc + "file !") + return False + return True + + +def get_value_once(config): + try: + way = config.get("gettype") + int_decode = config.get("int_decode", 16) + if way == 'sysfs': + loc = config.get("loc") + ret, val = read_sysfs(loc) + if ret is True: + return True, int(val, int_decode) + return False, ("sysfs read %s failed. log:%s" % (loc, val)) + if way == "i2c": + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset", 0) + ret, val = wbi2cget(bus, addr, offset) + if ret is True: + return True, int(val, int_decode) + return False, ("i2c read failed. bus:%d , addr:0x%x, offset:0x%x" % (bus, addr, offset)) + if way == "io": + io_addr = config.get('io_addr') + val = io_rd(io_addr) + if len(val) != 0: + return True, int(val, int_decode) + return False, ("io_addr read 0x%x failed" % io_addr) + if way == "i2cword": + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + ret, val = wbi2cgetWord(bus, addr, offset) + if ret is True: + return True, int(val, int_decode) + return False, ("i2cword read failed. bus:%d, addr:0x%x, offset:0x%x" % (bus, addr, offset)) + if way == "devfile": + path = config.get("path") + offset = config.get("offset") + read_len = config.get("read_len") + ret, val_list = dev_file_read(path, offset, read_len) + if ret is True: + return True, val_list + return False, ("devfile read failed. path:%s, offset:0x%x, read_len:%d" % (path, offset, read_len)) + if way == 'cmd': + cmd = config.get("cmd") + ret, val = exec_os_cmd(cmd) + if ret: + return False, ("cmd read exec %s failed, log: %s" % (cmd, val)) + return True, int(val, int_decode) + if way == 'file_exist': + judge_file = config.get('judge_file', None) + if os.path.exists(judge_file): + return True, True + return True, False + return False, "not support read type" + except Exception as e: + return False, ("get_value_once exception:%s happen" % str(e)) + + +def set_value_once(config): + try: + delay_time = config.get("delay", None) + if delay_time is not None: + time.sleep(delay_time) + + way = config.get("gettype") + if way == 'sysfs': + loc = config.get("loc") + value = config.get("value") + mask = config.get("mask", 0xff) + mask_tuple = (0xff, 0) + if mask not in mask_tuple: + ret, read_value = read_sysfs(loc) + if ret is True: + read_value = int(read_value, base=16) + value = (read_value & mask) | value + else: + return False, ("sysfs read %s failed. log:%s" % (loc, read_value)) + ret, log = write_sysfs(loc, "0x%02x" % value) + if ret is not True: + return False, ("sysfs %s write 0x%x failed" % (loc, value)) + return True, ("sysfs write 0x%x success" % value) + if way == "i2c": + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + value = config.get("value") + mask = config.get("mask", 0xff) + mask_tuple = (0xff, 0) + if mask not in mask_tuple: + ret, read_value = wbi2cget(bus, addr, offset) + if ret is True: + read_value = int(read_value, base=16) + value = (read_value & mask) | value + else: + return False, ("i2c read failed. bus:%d , addr:0x%x, offset:0x%x" % (bus, addr, offset)) + ret, log = wbi2cset(bus, addr, offset, value) + if ret is not True: + return False, ("i2c write bus:%d, addr:0x%x, offset:0x%x, value:0x%x failed" % + (bus, addr, offset, value)) + return True, ("i2c write bus:%d, addr:0x%x, offset:0x%x, value:0x%x success" % + (bus, addr, offset, value)) + if way == "io": + io_addr = config.get('io_addr') + value = config.get('value') + mask = config.get("mask", 0xff) + mask_tuple = (0xff, 0) + if mask not in mask_tuple: + read_value = io_rd(io_addr) + if read_value is None: + return False, ("io_addr 0x%x read failed" % (io_addr)) + read_value = int(read_value, base=16) + value = (read_value & mask) | value + ret = io_wr(io_addr, value) + if ret is not True: + return False, ("io_addr 0x%x write 0x%x failed" % (io_addr, value)) + return True, ("io_addr 0x%x write 0x%x success" % (io_addr, value)) + if way == 'i2cword': + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + value = config.get("value") + mask = config.get("mask", 0xff) + mask_tuple = (0xff, 0) + if mask not in mask_tuple: + ret, read_value = wbi2cgetWord(bus, addr, offset) + if ret is True: + read_value = int(read_value, base=16) + value = (read_value & mask) | value + else: + return False, ("i2c read word failed. bus:%d , addr:0x%x, offset:0x%x" % (bus, addr, offset)) + ret, log = wbi2csetWord(bus, addr, offset, value) + if ret is not True: + return False, ("i2cword write bus:%d, addr:0x%x, offset:0x%x, value:0x%x failed" % + (bus, addr, offset, value)) + return True, ("i2cword write bus:%d, addr:0x%x, offset:0x%x, value:0x%x success" % + (bus, addr, offset, value)) + if way == "devfile": + path = config.get("path") + offset = config.get("offset") + buf_list = config.get("value") + ret, log = dev_file_write(path, offset, buf_list) + if ret is True: + return True, ("devfile write path:%s, offset:0x%x, buf_list:%s success." % (path, offset, buf_list)) + return False, ("devfile read path:%s, offset:0x%x, buf_list:%s failed.log:%s" % + (path, offset, buf_list, log)) + if way == 'cmd': + cmd = config.get("cmd") + ret, log = exec_os_cmd(cmd) + if ret: + return False, ("cmd write exec %s failed, log: %s" % (cmd, log)) + return True, ("cmd write exec %s success" % cmd) + if way == 'bit_wr': + mask = config.get("mask") + bit_val = config.get("value") + val_config = config.get("val_config") + ret, rd_value = get_value_once(val_config) + if ret is False: + return False, ("bit_wr read failed, log: %s" % rd_value) + wr_val = (rd_value & mask) | bit_val + val_config["value"] = wr_val + ret, log = set_value_once(val_config) + if ret is False: + return False, ("bit_wr failed, log: %s" % log) + return True, ("bit_wr success, log: %s" % log) + if way == 'creat_file': + file_name = config.get("file") + ret, log = exec_os_cmd("touch %s" % file_name) + if ret: + return False, ("creat file %s failed, log: %s" % (file_name, log)) + exec_os_cmd("sync") + return True, ("creat file %s success" % file_name) + if way == 'remove_file': + file_name = config.get("file") + ret, log = exec_os_cmd("rm -rf %s" % file_name) + if ret: + return False, ("remove file %s failed, log: %s" % (file_name, log)) + exec_os_cmd("sync") + return True, ("remove file %s success" % file_name) + return False, "not support write type" + except Exception as e: + return False, ("set_value_once exception:%s happen" % str(e)) + + +def get_value(config): + retrytime = 6 + for i in range(retrytime): + ret, val = get_value_once(config) + if ret is True: + return True, val + time.sleep(0.1) + return False, val + + +def set_value(config): + retrytime = 6 + ignore_result_flag = config.get("ignore_result", 0) + for i in range(retrytime): + ret, log = set_value_once(config) + if ret is True: + return True, log + if ignore_result_flag == 1: + return True, log + time.sleep(0.1) + return False, log + + +class CompressedRotatingFileHandler(logging.handlers.RotatingFileHandler): + def doRollover(self): + """ + Do a rollover, as described in __init__(). + """ + if self.stream: + self.stream.close() + self.stream = None + if self.backupCount > 0: + for i in range(self.backupCount - 1, 0, -1): + sfn = "%s.%d.gz" % (self.baseFilename, i) + dfn = "%s.%d.gz" % (self.baseFilename, i + 1) + if os.path.exists(sfn): + if os.path.exists(dfn): + os.remove(dfn) + os.rename(sfn, dfn) + dfn = self.baseFilename + ".1.gz" + if os.path.exists(dfn): + os.remove(dfn) + # These two lines below are the only new lines. I commented out the os.rename(self.baseFilename, dfn) and + # replaced it with these two lines. + with open(self.baseFilename, 'rb') as f_in, gzip.open(dfn, 'wb') as f_out: + shutil.copyfileobj(f_in, f_out) + self.mode = 'w' + self.stream = self._open() + + +def getSdkReg(reg): + try: + cmd = "bcmcmd -t 1 'getr %s ' < /dev/null" % reg + ret, result = wb_os_system(cmd) + result_t = result.strip().replace("\r", "").replace("\n", "") + if ret != 0 or "Error:" in result_t: + return False, result + patt = r"%s.(.*):(.*)>drivshell" % reg + rt = re.findall(patt, result_t, re.S) + test = re.findall("=(.*)", rt[0][0])[0] + except Exception: + return False, 'getsdk register error' + return True, test + + +def getMacTemp(): + result = {} + wb_os_system("bcmcmd -t 1 \"show temp\" < /dev/null") + ret, log = wb_os_system("bcmcmd -t 1 \"show temp\" < /dev/null") + if ret: + return False, result + logs = log.splitlines() + for line in logs: + if "average" in line: + b = re.findall(r'\d+.\d+', line) + result["average"] = b[0] + elif "maximum" in line: + b = re.findall(r'\d+.\d+', line) + result["maximum"] = b[0] + return True, result + + +def getMacTemp_sysfs(mactempconf): + temp = -1000000 + try: + temp_list = [] + mac_temp_loc = mactempconf.get("loc", []) + mac_temp_flag = mactempconf.get("flag", None) + if mac_temp_flag is not None: + gettype = mac_temp_flag.get('gettype') + okbit = mac_temp_flag.get('okbit') + okval = mac_temp_flag.get('okval') + if gettype == "io": + io_addr = mac_temp_flag.get('io_addr') + val = io_rd(io_addr) + if val is None: + raise Exception("get mac_flag by io failed.") + else: + bus = mac_temp_flag.get('bus') + loc = mac_temp_flag.get('loc') + offset = mac_temp_flag.get('offset') + ind, val = wbi2cget(bus, loc, offset) + if ind is not True: + raise Exception("get mac_flag by i2c failed.") + val_t = (int(val, 16) & (1 << okbit)) >> okbit + if val_t != okval: + raise Exception("mac_flag invalid, val_t:%d." % val_t) + for loc in mac_temp_loc: + temp_s = get_sysfs_value(loc) + if isinstance(temp_s, str) and temp_s.startswith("ERR"): + raise Exception("get mac temp error. loc:%s" % loc) + temp_t = int(temp_s) + if temp_t == -1000000: + raise Exception("mac temp invalid.loc:%s" % loc) + temp_list.append(temp_t) + temp_list.sort(reverse=True) + temp = temp_list[0] + except Exception: + return False, temp + return True, temp + +def get_format_value(format_str): + ast_obj = ast.parse(format_str, mode='eval') + visitor = CodeVisitor() + visitor.visit(ast_obj) + ret = visitor.get_value() + return ret + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/pmon_syslog.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/pmon_syslog.py new file mode 100755 index 000000000000..8bdceef8c1b5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/pmon_syslog.py @@ -0,0 +1,519 @@ +#!/usr/bin/python3 +# * onboard interval check +# * FAN trays +# * PSU +# * SFF +import time +import syslog +import traceback +import glob +from platform_config import PMON_SYSLOG_STATUS + +PMON_DEBUG_FILE = "/etc/.pmon_syslog_debug_flag" +debuglevel = 0 +PMONERROR = 1 +PMONDEBUG = 2 + + +def pmon_debug(s): + if PMONDEBUG & debuglevel: + syslog.openlog("PMON_SYSLOG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def pmon_error(s): + if PMONERROR & debuglevel: + syslog.openlog("PMON_SYSLOG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def dev_syslog(s): + syslog.openlog("PMON_SYSLOG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_LOCAL1 | syslog.LOG_NOTICE, s) + + +# status +STATUS_PRESENT = 'PRESENT' +STATUS_ABSENT = 'ABSENT' +STATUS_OK = 'OK' +STATUS_NOT_OK = 'NOT OK' +STATUS_FAILED = 'FAILED' + + +class checkBase(object): + def __init__(self, path, dev_name, display_name, obj_type, config): + self._peroid_syslog = None + self._peroid_failed_syslog = None # exception + self._preDevStatus = None + self._path = path + self._name = dev_name + self._display_name = display_name + self._type = obj_type + self._config = config + + def getCurstatus(self): + # get ok/not ok/absent status + status, log = self.getPresent() + if status == STATUS_PRESENT: + # check status + property_status, log = self.getStatus() + if property_status is not None: + status = property_status + return status, log + + def getPresent(self): + presentFilepath = self.getPath() + try: + # get ok/not ok/absent status + presentConfig = self._config["present"] + mask = presentConfig.get("mask", 0xff) + absent_val = presentConfig.get("ABSENT", None) + absent_val = absent_val & mask + with open(presentFilepath, "r") as fd: + retval = fd.read() + if int(retval) == absent_val: + return STATUS_ABSENT, None + return STATUS_PRESENT, None + except Exception as e: + return STATUS_FAILED, (str(e) + " location[%s]" % presentFilepath) + + def getStatus(self): + if "status" in self._config: + statusConfig = self._config["status"] + for itemConfig in statusConfig: + mask = itemConfig.get("mask", 0xff) + ok_val = itemConfig.get("okval", None) + ok_val = ok_val & mask + Filepath = itemConfig["path"] % self._name + try: + with open(Filepath, "r") as fd1: + retval = fd1.read() + if int(retval) != ok_val: + return STATUS_NOT_OK, None + except Exception as e: + return STATUS_FAILED, (str(e) + " location[%s]" % Filepath) + return STATUS_OK, None + return None, None + + def getPath(self): + return self._path + + def getName(self): + return self._name + + def getType(self): + return self._type + + def getDisplayName(self): + return self._display_name + + def getnochangedMsgFlag(self): + return self._config["nochangedmsgflag"] + + def getnochangedMsgTime(self): + return self._config["nochangedmsgtime"] + + def getnoprintFirstTimeFlag(self): + return self._config["noprintfirsttimeflag"] + + def checkStatus(self): + # syslog msg + dev_type = self.getType() + display_name = self.getDisplayName() + nochangedMsgTime = self.getnochangedMsgTime() + getnochangedMsgFlag = self.getnochangedMsgFlag() + noprintFirstTimeFlag = self.getnoprintFirstTimeFlag() + MSG_IN = '%%PMON-5-' + dev_type + '_PLUG_IN: %s is PRESENT.' + MSG_OUT = '%%PMON-5-' + dev_type + '_PLUG_OUT: %s is ABSENT.' + MSG_OK = '%%PMON-5-' + dev_type + '_OK: %s is OK.' + MSG_NOT_OK = '%%PMON-5-' + dev_type + '_FAILED: %s is NOT OK.' + MSG_ABSENT = '%%PMON-5-' + dev_type + '_ABSENT: %s is ABSENT.' + MSG_UNKNOWN = '%%PMON-5-' + dev_type + '_UNKNOWN: %s is UNKNOWN.%s' + MSG_RECOVER = '%%PMON-5-' + dev_type + '_OK: %s is OK. Recover from ' + dev_type + ' FAILED.' + + curStatus, log = self.getCurstatus() + pmon_debug("%s: current status %s" % (display_name, curStatus)) + pmon_debug("%s: pre status %s" % (display_name, self._preDevStatus)) + pmon_debug("%s: peroid_syslog %s" % (display_name, self._peroid_syslog)) + + if curStatus == STATUS_FAILED: + # get status failed + if self._peroid_failed_syslog is not None: + if getnochangedMsgFlag and time.time() - self._peroid_failed_syslog >= nochangedMsgTime: + # absent as before for some time, notice + dev_syslog(MSG_UNKNOWN % (display_name, log)) + self._peroid_failed_syslog = time.time() + else: # first time failed + dev_syslog(MSG_UNKNOWN % (display_name, log)) + self._peroid_failed_syslog = time.time() + return + self._peroid_failed_syslog = time.time() + + if self._preDevStatus is None: + # 1st time + if noprintFirstTimeFlag == 1: + self._peroid_syslog = time.time() + else: + if curStatus == STATUS_PRESENT: + # present + dev_syslog(MSG_IN % display_name) + elif curStatus == STATUS_OK: + # ok + dev_syslog(MSG_OK % display_name) + elif curStatus == STATUS_NOT_OK: + # not ok + dev_syslog(MSG_NOT_OK % display_name) + self._peroid_syslog = time.time() + else: + # absent + dev_syslog(MSG_ABSENT % display_name) + self._peroid_syslog = time.time() + else: + # from 2nd time... + if self._preDevStatus == curStatus: + # status not changed + if self._preDevStatus == STATUS_ABSENT: + if self._peroid_syslog is not None: + if getnochangedMsgFlag and time.time() - self._peroid_syslog >= nochangedMsgTime: + # absent as before for some time, notice + dev_syslog(MSG_ABSENT % display_name) + self._peroid_syslog = time.time() + elif self._preDevStatus == STATUS_NOT_OK: + if self._peroid_syslog is not None: + if getnochangedMsgFlag and time.time() - self._peroid_syslog >= nochangedMsgTime: + # not ok as before for some time, notice + dev_syslog(MSG_NOT_OK % display_name) + self._peroid_syslog = time.time() + else: + # status changed + if self._preDevStatus == STATUS_ABSENT: + if curStatus == STATUS_NOT_OK: + # absent -> not ok + dev_syslog(MSG_IN % display_name) + dev_syslog(MSG_NOT_OK % display_name) + self._peroid_syslog = time.time() + elif curStatus == STATUS_OK: + # absent -> ok + dev_syslog(MSG_IN % display_name) + dev_syslog(MSG_OK % display_name) + else: + # absent -> prsent + dev_syslog(MSG_IN % display_name) + + elif self._preDevStatus == STATUS_OK: + if curStatus == STATUS_NOT_OK: + # ok -> not ok + dev_syslog(MSG_NOT_OK % display_name) + self._peroid_syslog = time.time() + elif curStatus == STATUS_ABSENT: + # ok -> absent + dev_syslog(MSG_OUT % display_name) + self._peroid_syslog = time.time() + elif self._preDevStatus == STATUS_PRESENT: + # present -> absent + dev_syslog(MSG_OUT % display_name) + self._peroid_syslog = time.time() + else: # not ok + if curStatus == STATUS_OK: + # not ok -> ok + dev_syslog(MSG_RECOVER % display_name) + dev_syslog(MSG_OK % display_name) + else: + # not ok -> absent + dev_syslog(MSG_OUT % display_name) + self._peroid_syslog = time.time() + self._preDevStatus = curStatus + + +class checkSfp(checkBase): + def __init__(self, path, dev_name, display_name, config): + super(checkSfp, self).__init__(path, dev_name, display_name, 'XCVR', config) + + def getPath(self): + super(checkSfp, self).getPath() + return self._path + + def getName(self): + super(checkSfp, self).getName() + return self._name + + def getType(self): + super(checkSfp, self).getType() + return self._type + + +class checkSlot(checkBase): + def __init__(self, path, dev_name, display_name, config): + super(checkSlot, self).__init__(path, dev_name, display_name, 'SLOT', config) + + def getPath(self): + super(checkSlot, self).getPath() + return self._path + + def getName(self): + super(checkSlot, self).getName() + return self._name + + def getType(self): + super(checkSlot, self).getType() + return self._type + + +class checkPSU(checkBase): + def __init__(self, path, dev_name, display_name, config): + super(checkPSU, self).__init__(path, dev_name, display_name, 'PSU', config) + + def getPath(self): + super(checkPSU, self).getPath() + return self._path + + def getName(self): + super(checkPSU, self).getName() + return self._name + + def getType(self): + super(checkPSU, self).getType() + return self._type + + +class checkFAN(checkBase): + def __init__(self, path, dev_name, display_name, config): + super(checkFAN, self).__init__(path, dev_name, display_name, 'FAN', config) + + def getPath(self): + super(checkFAN, self).getPath() + return self._path + + def getName(self): + super(checkFAN, self).getName() + return self._name + + def getType(self): + super(checkFAN, self).getType() + return self._type + + +class platformSyslog(): + def __init__(self): + self.__sfp_checklist = [] + self.__fan_checklist = [] + self.__psu_checklist = [] + self.__slot_checklist = [] + self.__temp_checklist = [] + self.temps_peroid_syslog = {} + self.normal_status = 0 + self.warning_status = 1 + self.critical_status = 2 + self.poweron_flag = 0 + + self.pmon_syslog_config = PMON_SYSLOG_STATUS.copy() + self.__pollingtime = self.pmon_syslog_config.get('polling_time', 3) + + tmpconfig = self.pmon_syslog_config.get('sffs', None) + if tmpconfig is not None: + preset_item = tmpconfig.get("present", {}) + path = preset_item.get("path", []) + for location in path: + if '*' not in location: + pmon_error("sff location config error: %s" % location) + continue + dev_name_index = 0 + loc_split_list = location.split('/') + for i, item in enumerate(loc_split_list): + if '*' in item: + dev_name_index = i + break + locations = glob.glob(location) + for dev_path in locations: + dev_name_list = dev_path.split('/') + # explame:get eth1 from /sys_switch/transceiver/eth1/present + dev_name = dev_name_list[dev_name_index] + dev_name_alias = tmpconfig.get("alias", {}) + display_name = dev_name_alias.get(dev_name, dev_name) + dev = checkSfp(dev_path, dev_name, display_name, tmpconfig) + self.__sfp_checklist.append(dev) + + tmpconfig = self.pmon_syslog_config.get('fans', None) + if tmpconfig is not None: + preset_item = tmpconfig.get("present", {}) + path = preset_item.get("path", []) + for location in path: + if '*' not in location: + pmon_error("fan location config error: %s" % location) + continue + dev_name_index = 0 + loc_split_list = location.split('/') + for i, item in enumerate(loc_split_list): + if '*' in item: + dev_name_index = i + break + locations = glob.glob(location) + for dev_path in locations: + dev_name_list = dev_path.split('/') + dev_name = dev_name_list[dev_name_index] + dev_name_alias = tmpconfig.get("alias", {}) + display_name = dev_name_alias.get(dev_name, dev_name) + dev = checkFAN(dev_path, dev_name, display_name, tmpconfig) + self.__fan_checklist.append(dev) + + tmpconfig = self.pmon_syslog_config.get('psus', None) + if tmpconfig is not None: + preset_item = tmpconfig.get("present", {}) + path = preset_item.get("path", []) + for location in path: + if '*' not in location: + pmon_error("psu location config error: %s" % location) + continue + dev_name_index = 0 + loc_split_list = location.split('/') + for i, item in enumerate(loc_split_list): + if '*' in item: + dev_name_index = i + break + locations = glob.glob(location) + for dev_path in locations: + dev_name_list = dev_path.split('/') + dev_name = dev_name_list[dev_name_index] + dev_name_alias = tmpconfig.get("alias", {}) + display_name = dev_name_alias.get(dev_name, dev_name) + dev = checkPSU(dev_path, dev_name, display_name, tmpconfig) + self.__psu_checklist.append(dev) + + tmpconfig = self.pmon_syslog_config.get('slots', None) + if tmpconfig is not None: + preset_item = tmpconfig.get("present", {}) + path = preset_item.get("path", []) + for location in path: + if '*' not in location: + pmon_error("slot location config error: %s" % location) + continue + dev_name_index = 0 + loc_split_list = location.split('/') + for i, item in enumerate(loc_split_list): + if '*' in item: + dev_name_index = i + break + locations = glob.glob(location) + for dev_path in locations: + dev_name_list = dev_path.split('/') + dev_name = dev_name_list[dev_name_index] + dev_name_alias = tmpconfig.get("alias", {}) + display_name = dev_name_alias.get(dev_name, dev_name) + dev = checkSlot(dev_path, dev_name, display_name, tmpconfig) + self.__slot_checklist.append(dev) + + tmpconfig = self.pmon_syslog_config.get('temps', None) + if tmpconfig is not None: + self.__temp_checklist = tmpconfig.get('temps_list', []) + self.__temps_pollingseconds = tmpconfig.get('over_temps_polling_seconds', None) + + def checkTempStaus(self, temp_item): + temp_name = temp_item.get('name', None) + input_path = temp_item.get('input_path', None) + warning_temp = temp_item.get('warning', None) + critical_temp = temp_item.get('critical', None) + input_accuracy = temp_item.get('input_accuracy', None) + if temp_name is None or input_path is None or warning_temp is None or critical_temp is None: + dev_syslog('%%PMON-5-TEMP_NOTICE: get temperature config parament failed.') + return + try: + locations = glob.glob(input_path) + with open(locations[0], "r") as fd: + input_temp = fd.read() + input_temp = float(input_temp) / float(input_accuracy) + + if 'time' not in temp_item: + temp_item['time'] = time.time() + temp_item['status'] = self.normal_status + if float(input_temp) >= float(warning_temp): + if float(input_temp) >= float(critical_temp): + if time.time() - \ + temp_item['time'] >= self.__temps_pollingseconds or temp_item['status'] != self.critical_status: + dev_syslog('%%PMON-5-TEMP_HIGH: %s temperature %sC is larger than max critical threshold %sC.' + % (temp_name, input_temp, critical_temp)) + temp_item['status'] = self.critical_status + temp_item['time'] = time.time() + else: + if time.time() - \ + temp_item['time'] >= self.__temps_pollingseconds or temp_item['status'] != self.warning_status: + dev_syslog('%%PMON-5-TEMP_HIGH: %s temperature %sC is larger than max warning threshold %sC.' + % (temp_name, input_temp, warning_temp)) + temp_item['status'] = self.warning_status + temp_item['time'] = time.time() + else: + pmon_debug( + "%s temperature %sC is in range [%s, %s]" % + (temp_name, input_temp, warning_temp, critical_temp)) + temp_item['status'] = self.normal_status + temp_item['time'] = time.time() + except Exception as e: + dev_syslog('%%PMON-5-TEMP_NOTICE: Cannot get %s temperature. Exception log: %s' % (temp_name, str(e))) + return + + def sysfs_precondition_check(self, check_module, check_project): + try: + tmpconfig = self.pmon_syslog_config.get(check_module, None) + if tmpconfig is not None: + check_list = tmpconfig.get(check_project, []) + for check_item in check_list: + location = check_item.get("path", None) + ok_val = check_item.get("ok_val", None) + mask = check_item.get("mask", 0xff) + ok_val = ok_val & mask + locations = glob.glob(location) + for power_path in locations: + with open(power_path, "r") as fd: + retval = fd.read() + if int(retval) != ok_val: + return + self.poweron_flag = 1 + except Exception as e: + dev_syslog('%%PMON-5-TEMP_NOTICE: Cannot check power status. Exception log: %s' % str(e)) + return + + def updateSysDeviceStatus(self): + if self.poweron_flag == 1: + for dev in self.__sfp_checklist: + dev.checkStatus() + else: + self.sysfs_precondition_check('sffs', 'power') + + for dev in self.__fan_checklist: + dev.checkStatus() + for dev in self.__psu_checklist: + dev.checkStatus() + for dev in self.__slot_checklist: + dev.checkStatus() + for temp_item in self.__temp_checklist: + self.checkTempStaus(temp_item) + + def getPollingtime(self): + return self.__pollingtime + + def debug_init(self): + global debuglevel + try: + with open(PMON_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + def doWork(self): + try: + self.debug_init() + self.updateSysDeviceStatus() + except Exception as e: + MSG_EXCEPTION = '%%PMON-5-NOTICE: Exception happened! info:%s' % str(e) + pmon_error(MSG_EXCEPTION % traceback.format_exc()) + + +def run(): + platform = platformSyslog() + while True: + platform.doWork() + time.sleep(platform.getPollingtime()) + + +if __name__ == '__main__': + run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/ragilecommon.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/ragilecommon.py deleted file mode 100755 index 0adad9d74659..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/script/ragilecommon.py +++ /dev/null @@ -1,1365 +0,0 @@ -# -*- coding: UTF-8 -*- -# ------------------------------------------------------------------------------- -# Name: Ragile python common module -# Purpose: called by other modules -# -# Author: support -# -# Created: 02/07/2018 -# Copyright: (c) rd 2018 -# ------------------------------------------------------------------------------- - -################################driver-load-adaption####################################################### -# need to export interface -################################################################################################### - -__all__ = [ - "fancontrol_loc", - "fancontrol_config_loc", - "GLOBALCONFIG", - "MONITOR_CONST", - "RAGILE_PART_NUMBER", - "RAGILE_LABEL_REVISION", - "RAGILE_ONIE_VERSION", - "RAGILE_MAC_SIZE", - "RAGILE_MANUF_NAME", - "RAGILE_MANUF_COUNTRY", - "RAGILE_VENDOR_NAME", - "RAGILE_DIAG_VERSION", - "RAGILE_SERVICE_TAG", - "DEV_LEDS", - "MEM_SLOTS", - "LOCAL_LED_CONTROL", - "FIRMWARE_TOOLS", - "STARTMODULE", - "i2ccheck_params", - "FANS_DEF", - "factest_module", - "MONITOR_TEMP_MIN", - "MONITOR_K", - "MONITOR_MAC_IN", - "MONITOR_DEFAULT_SPEED", - "MONITOR_MAX_SPEED", - "MONITOR_MIN_SPEED", - "MONITOR_MAC_ERROR_SPEED", - "MONITOR_FAN_TOTAL_NUM", - "MONITOR_MAC_UP_TEMP", - "MONITOR_MAC_LOWER_TEMP", - "MONITOR_MAC_MAX_TEMP", - "MONITOR_FALL_TEMP", - "MONITOR_MAC_WARNING_THRESHOLD", - "MONITOR_OUTTEMP_WARNING_THRESHOLD", - "MONITOR_BOARDTEMP_WARNING_THRESHOLD", - "MONITOR_CPUTEMP_WARNING_THRESHOLD", - "MONITOR_INTEMP_WARNING_THRESHOLD", - "MONITOR_MAC_CRITICAL_THRESHOLD", - "MONITOR_OUTTEMP_CRITICAL_THRESHOLD", - "MONITOR_BOARDTEMP_CRITICAL_THRESHOLD", - "MONITOR_CPUTEMP_CRITICAL_THRESHOLD", - "MONITOR_INTEMP_CRITICAL_THRESHOLD", - "MONITOR_CRITICAL_NUM", - "MONITOR_SHAKE_TIME", - "MONITOR_INTERVAL", - "MONITOR_MAC_SOURCE_SYSFS", - "MONITOR_MAC_SOURCE_PATH", - "MAC_AVS_PARAM", - "MAC_DEFAULT_PARAM", - "MONITOR_SYS_LED", - "MONITOR_SYS_FAN_LED", - "MONITOR_FANS_LED", - "MONITOR_SYS_PSU_LED", - "MONITOR_FAN_STATUS", - "MONITOR_PSU_STATUS", - "MONITOR_DEV_STATUS", - "MONITOR_DEV_STATUS_DECODE", - "DEV_MONITOR_PARAM", - "SLOT_MONITOR_PARAM", - "fanloc", - "PCA9548START", - "PCA9548BUSEND", - "RAGILE_CARDID", - "RAGILE_PRODUCTNAME", - "FAN_PROTECT", - "rg_eeprom", - "E2_LOC", - "E2_PROTECT", - "MAC_LED_RESET", - "INIT_PARAM", - "INIT_COMMAND", - "CPLDVERSIONS", - "DRIVERLISTS", - "DEVICE", - "E2TYPE", - "FRULISTS", - "fanlevel_6510", - "fanlevel_6520", - "fanlevel", - "TEMPIDCHANGE", - "FACTESTMODULE", - "item1", - "test_sys_reload_item", - "test_sys_item", - "test_temp_item", - "test_mem_item", - "test_hd_item", - "test_rtc_item", - "test_i2c_item", - "test_cpld_item", - "test_portframe_item", - "test_sysled_item", - "test_fan_item", - "test_power_item", - "test_usb_item", - "test_prbs_item", - "test_portbroadcast_item", - "test_debug_level", - "test_log_level", - "test_setmac", - "test_setrtc", - "log_level_critical", - "log_level_debug", - "log_level_error", - "log_level_info", - "log_level_notset", - "log_level_warning", - "test_e2_setmac_item", - "test_bmc_setmac_item", - "test_fan_setmac_item", - "alltest", - "looptest", - "diagtestall", - "menuList", - "TESTCASE", - "PCIe_DEV_LIST", - "PCIe_SPEED_ITEM", -] - -fancontrol_loc = "/usr/local/bin" -fancontrol_config_loc = "/usr/local/bin" - -GLOBALCONFIG = "GLOBALCONFIG" -MONITOR_CONST = "MONITOR_CONST" - -RAGILE_PART_NUMBER = "RJ000001" -RAGILE_LABEL_REVISION = "R01" -RAGILE_ONIE_VERSION = "2018.02" -RAGILE_MAC_SIZE = 3 -RAGILE_MANUF_NAME = "Ragile" -RAGILE_MANUF_COUNTRY = "CHN" -RAGILE_VENDOR_NAME = "Ragile" -RAGILE_DIAG_VERSION = "0.1.0.15" -RAGILE_SERVICE_TAG = "www.ragile.com" - -DEV_LEDS = {} -MEM_SLOTS = [] - -LOCAL_LED_CONTROL = {"CLOSE": {}, "OPEN": {}} - -FIRMWARE_TOOLS = {} -# start-up module -STARTMODULE = {"fancontrol": 1, "avscontrol": 1} - -i2ccheck_params = {"busend": "i2c-66", "retrytime": 6} - -################################################################################################### -##### fan board ID reference -################################################################################################### -FANS_DEF = { - 0x8100: "M6500-FAN-F", - 0x8101: "M6510-FAN-F", - 0x8102: "M6520-FAN-F", - 0x8103: "M6510-FAN-R", -} - -factest_module = { - "sysinfo_showfanmsg": 1, - "sysinfo_showPsumsg": 1, - "sysinfo_showrestfanmsg": 0, - "sysinfo_showrestpsumsg": 0, -} - -#################fan adjustment parameters ############################## -MONITOR_TEMP_MIN = 38 # temperature before speed-adjustment -MONITOR_K = 11 # adjustment algorithm -MONITOR_MAC_IN = 35 # temperature difference between mac and chip(backup) -MONITOR_DEFAULT_SPEED = 0x60 # default speed -MONITOR_MAX_SPEED = 0xFF # maximum speed -MONITOR_MIN_SPEED = 0x33 # minimum speed -MONITOR_MAC_ERROR_SPEED = 0xBB # MAC abnormal speed -MONITOR_FAN_TOTAL_NUM = 4 # 3+1 redundancy design, report to syslog if there is a error -MONITOR_MAC_UP_TEMP = 50 # MAC compared with inlet up -MONITOR_MAC_LOWER_TEMP = -50 # MAC compared with outlet down -MONITOR_MAC_MAX_TEMP = 100 # - -MONITOR_FALL_TEMP = 4 # adjustment reduced temperature -MONITOR_MAC_WARNING_THRESHOLD = 100 # 100 -MONITOR_OUTTEMP_WARNING_THRESHOLD = 85 -MONITOR_BOARDTEMP_WARNING_THRESHOLD = 85 -MONITOR_CPUTEMP_WARNING_THRESHOLD = 85 -MONITOR_INTEMP_WARNING_THRESHOLD = 70 # 70 - -MONITOR_MAC_CRITICAL_THRESHOLD = 105 # 105 -MONITOR_OUTTEMP_CRITICAL_THRESHOLD = 90 # 90 -MONITOR_BOARDTEMP_CRITICAL_THRESHOLD = 90 # 90 -MONITOR_CPUTEMP_CRITICAL_THRESHOLD = 100 # 100 -MONITOR_INTEMP_CRITICAL_THRESHOLD = 80 # 80 -MONITOR_CRITICAL_NUM = 3 # retry times -MONITOR_SHAKE_TIME = 20 # anti-shake times -MONITOR_INTERVAL = 60 - -# 1 get mac temperature from sysfs ,0 get mac temperature from bcmcmd -MONITOR_MAC_SOURCE_SYSFS = (0) -MONITOR_MAC_SOURCE_PATH = None # sysfs path - - -# default MAC AVS parameters -MAC_AVS_PARAM = { - 0x72: 0x0384, - 0x73: 0x037E, - 0x74: 0x0378, - 0x75: 0x0372, - 0x76: 0x036B, - 0x77: 0x0365, - 0x78: 0x035F, - 0x79: 0x0359, - 0x7A: 0x0352, - 0x7B: 0x034C, - 0x7C: 0x0346, - 0x7D: 0x0340, - 0x7E: 0x0339, - 0x7F: 0x0333, - 0x80: 0x032D, - 0x81: 0x0327, - 0x82: 0x0320, - 0x83: 0x031A, - 0x84: 0x0314, - 0x85: 0x030E, - 0x86: 0x0307, - 0x87: 0x0301, - 0x88: 0x02FB, - 0x89: 0x02F5, - 0x8A: 0x02EE, -} - -# default 6520 configuration -MAC_DEFAULT_PARAM = { - "type": 1, # type 1 represents default if out of range / 0 represents no voltage-adjustment if out of range - "default": 0x74, # should be used with type - "loopaddr": 0x00, # AVS loop address - "loop": 0x00, # AVS loop value - "open": 0x00, # diasble write-protection value - "close": 0x40, # enable write-protection value - "bus": 2, # AVSI2C bus address - "devno": 0x60, # AVS address - "addr": 0x21, # AVS voltage-adjustment address - "protectaddr": 0x10, # AVS write-protection address - "sdkreg": "DMU_PCU_OTP_CONFIG_8", # SDK register name - "sdktype": 1, # type 0 represents no shift operation / 1 represents shift operation - "macregloc": 24, # shift operation - "mask": 0xFF, # mask after shift -} - -MONITOR_SYS_LED = [ - {"bus": 2, "devno": 0x33, "addr": 0xB2, "yellow": 0x06, "red": 0x02, "green": 0x04}, - {"bus": 2, "devno": 0x32, "addr": 0x72, "yellow": 0x06, "red": 0x02, "green": 0x04}, -] - -MONITOR_SYS_FAN_LED = [ - {"bus": 2, "devno": 0x33, "addr": 0xB4, "yellow": 0x06, "red": 0x02, "green": 0x04}, -] - -MONITOR_FANS_LED = [ - {"bus": 2, "devno": 0x32, "addr": 0x23, "green": 0x09, "red": 0x0A}, - {"bus": 2, "devno": 0x32, "addr": 0x24, "green": 0x09, "red": 0x0A}, - {"bus": 2, "devno": 0x32, "addr": 0x25, "green": 0x09, "red": 0x0A}, - {"bus": 2, "devno": 0x32, "addr": 0x26, "green": 0x09, "red": 0x0A}, -] - - -MONITOR_SYS_PSU_LED = [ - {"bus": 2, "devno": 0x33, "addr": 0xB3, "yellow": 0x06, "red": 0x02, "green": 0x04}, -] - -MONITOR_FAN_STATUS = [ - {"status": "green", "minOkNum": 4, "maxOkNum": 4}, - {"status": "yellow", "minOkNum": 3, "maxOkNum": 3}, - {"status": "red", "minOkNum": 0, "maxOkNum": 2}, -] - -MONITOR_PSU_STATUS = [ - {"status": "green", "minOkNum": 2, "maxOkNum": 2}, - {"status": "yellow", "minOkNum": 1, "maxOkNum": 1}, - {"status": "red", "minOkNum": 0, "maxOkNum": 0}, -] - -MONITOR_DEV_STATUS = {} -MONITOR_DEV_STATUS_DECODE = {} -DEV_MONITOR_PARAM = {} -SLOT_MONITOR_PARAM = {} - - -fanloc = {"name": "fanset", "location": "0-0032/fan_speed_set"} -#####################MAC-Voltage-Adjustment-Parameters#################################### - - -####================================Adaption-Area================================ -#### RAGILE_COMMON common configuration head -#### “platform” specific configuration head -#### -PCA9548START = 11 -PCA9548BUSEND = 74 - -RAGILE_CARDID = 0x00004040 -RAGILE_PRODUCTNAME = "ragile_ra-b6510" - -FAN_PROTECT = {"bus": 0, "devno": 0x32, "addr": 0x19, "open": 0x00, "close": 0x0F} -rg_eeprom = "2-0057/eeprom" -E2_LOC = {"bus": 2, "devno": 0x57} -E2_PROTECT = {"bus": 2, "devno": 0x33, "addr": 0xB0, "open": 0, "close": 1} -MAC_LED_RESET = {"pcibus": 8, "slot": 0, "fn": 0, "bar": 0, "offset": 64, "reset": 0x98} - -INIT_PARAM = [ - {"loc": "1-0034/sfp_enable", "value": "01"}, - {"loc": "2-0035/sfp_enable2", "value": "ff"}, - {"loc": "2-0033/mac_led", "value": "ff"}, - {"loc": "1-0034/sfp_txdis1", "value": "00"}, - {"loc": "1-0034/sfp_txdis2", "value": "00"}, - {"loc": "1-0034/sfp_txdis3", "value": "00"}, - {"loc": "1-0036/sfp_txdis4", "value": "00"}, - {"loc": "1-0036/sfp_txdis5", "value": "00"}, - {"loc": "1-0036/sfp_txdis6", "value": "00"}, - {"loc": fanloc["location"], "value": "80"}, -] - -INIT_COMMAND = [] - -CPLDVERSIONS = [ - {"loc": "2-0033/cpld_version", "des": "MAC Board CPLDA"}, - {"loc": "2-0035/cpld_version", "des": "MAC Board CPLDB"}, - {"loc": "2-0037/cpld_version", "des": "CPU Board CPLD"}, -] - -## Driver List -## - -DRIVERLISTS = [] -DEVICE = [] -""" -DRIVERLISTS = [ - "i2c_dev", - "i2c_algo_bit", - "i2c_gpio", - "i2c_mux", - "i2c_mux_pca9641", - "i2c_mux_pca954x", # force_deselect_on_exit=1 - "eeprom", - "at24", - "ragile_platform", - "rg_cpld", - "rg_fan", - "rg_psu", - "csu550", - "rg_gpio_xeon", - #IPMIdriver - "ipmi_msghandler", - "ipmi_devintf", - "ipmi_si", -] - -DEVICE = [ - {"name":"pca9641","bus":0 ,"loc":0x10 }, - {"name":"pca9548","bus":2 ,"loc":0x70 }, - {"name":"lm75","bus": 2, "loc":0x48 }, - {"name":"lm75","bus": 2, "loc":0x49 }, - {"name":"lm75","bus": 2, "loc":0x4a }, - {"name":"24c02","bus":2 , "loc":0x57 }, - {"name":"rg_cpld","bus":2 ,"loc":0x33 }, - {"name":"rg_cpld","bus":2 ,"loc":0x35 }, - {"name":"rg_cpld","bus":2 ,"loc":0x37 }, - {"name":"pca9548","bus":1,"loc":0x70 }, - {"name":"pca9548","bus":1,"loc":0x71 }, - {"name":"pca9548","bus":1,"loc":0x72 }, - {"name":"pca9548","bus":1,"loc":0x73 }, - {"name":"pca9548","bus":1,"loc":0x74 }, - {"name":"pca9548","bus":1,"loc":0x75 }, - {"name":"pca9548","bus":1,"loc":0x76 }, - {"name":"pca9548","bus":1,"loc":0x77 }, - {"name":"rg_fan","bus":3,"loc":0x53 }, - {"name":"rg_fan","bus":4,"loc":0x53 }, - {"name":"rg_fan","bus":5,"loc":0x53 }, - #{"name":"rg_fan","bus":6,"loc":0x53 }, #specific fan - {"name":"rg_psu","bus":7 ,"loc":0x50 }, - {"name":"csu550","bus":7 ,"loc":0x58 }, - {"name":"rg_psu","bus":8 ,"loc":0x53 }, - {"name":"csu550","bus":8 ,"loc":0x5b }, -] -""" - -#####################FRU-Info-Adaption################################# -E2TYPE = { - "1": "tlveeprom", - "2": "x86cpueeprom", - "3": "bmceeprom", - "4": "cpueeprom", - "5": "maceeprom", - "6": "sloteeprom", - "7": "fanconnecteeprom", - "8": "M1HFANI-F", - "9": "M1HFANI-R", - "A": "M2HFANI-F", - "B": "M2HFANI-R", - "C": "psu", -} -FRULISTS = [] -################################Manufacturing-Test-Adaption-Area####################################################### -# need to export interface -fanlevel_6510 = { - "level": [51, 150, 255], - "low_speed": [500, 7500, 17000], - "high_speed": [11000, 22500, 28500], -} - -fanlevel_6520 = { - "level": [75, 150, 255], - "low_speed": [750, 4250, 6750], - "high_speed": [4500, 7500, 10000], -} - -fanlevel = fanlevel_6520 - -TEMPIDCHANGE = { - "lm75in": "inlet", - "lm75out": "outlet", - "lm75hot": "hot-point", - "inlet": "lm75in", - "outlet": "lm75out", - "hot-point": "lm75hot", -} - -# Manufacturing-Test module -FACTESTMODULE = {} - -##################################Manufacturing-Test-Menu -item1 = {"name": "Single Test", "deal": "test_signal", "childid": 1} -test_sys_reload_item = {"name": "reset-system", "deal": "test_sys_reload"} - -test_sys_item = {"name": "Product information test", "deal": "test_sysinfo"} -test_temp_item = {"name": "temperature test", "deal": "test_tempinfo"} -test_mem_item = {"name": "Memory test", "deal": "test_cpumemoryinfo"} -test_hd_item = {"name": "Hard disk test", "deal": "test_hard"} -test_rtc_item = {"name": "RTC test ", "deal": "test_rtc"} -test_i2c_item = {"name": "I2c test ", "deal": "test_i2c"} -test_cpld_item = {"name": "CPLD test", "deal": "test_cpld"} -test_portframe_item = { - "name": "Port transmit-receive frame test", - "deal": "test_portframe", -} -test_sysled_item = {"name": "System led test", "deal": "test_led"} -test_fan_item = {"name": "Fan status test", "deal": "test_fan"} -test_power_item = {"name": "PSU status test", "deal": "test_power"} -test_usb_item = {"name": "USB test", "deal": "test_usb"} -test_prbs_item = {"name": "PRBS test", "deal": "test_prbs"} -test_portbroadcast_item = {"name": "Port broadcast", "deal": "test_portbroadcast"} - -test_debug_level = {"name": "Change debug level", "deal": "test_setdebug"} -test_log_level = {"name": "Log output level", "deal": "test_loginfolevel"} -test_setmac = {"name": "setmac", "deal": "test_setmac"} -test_setrtc = {"name": "Set RTC", "deal": "test_set_rtc"} - -log_level_critical = {"name": "CRITICAL", "deal": "test_log_critical"} -log_level_debug = {"name": "DEBUG", "deal": "test_log_debug"} -log_level_error = {"name": "ERROR", "deal": "test_log_error"} -log_level_info = {"name": "INFO", "deal": "test_log_info"} -log_level_notset = {"name": "NOTSET", "deal": "test_log_notset"} -log_level_warning = {"name": "WARNING", "deal": "test_log_warning"} - - -test_e2_setmac_item = {"name": "E2SETMAC", "deal": "test_e2_setmac"} -test_bmc_setmac_item = {"name": "BMCSETMAC", "deal": "test_bmc_setmac"} -test_fan_setmac_item = {"name": "fan SETMAC", "deal": "test_fan_setmac"} - -alltest = [ - test_sys_item, - test_temp_item, - test_mem_item, - test_hd_item, - test_rtc_item, - test_i2c_item, - test_cpld_item, - test_portframe_item, - test_sysled_item, - test_fan_item, - test_power_item, - test_usb_item, - test_prbs_item, - test_portbroadcast_item, -] - -looptest = [ - test_sys_item, - test_temp_item, - test_mem_item, - test_hd_item, - test_rtc_item, - test_i2c_item, - test_cpld_item, - test_portframe_item, - test_fan_item, - test_power_item, - test_usb_item, - test_prbs_item, - test_portbroadcast_item, -] - -diagtestall = [] - -menuList = [ - { - "menuid": 0, - "value": [ - {"name": "Single test", "deal": "test_signal", "childid": 1}, - {"name": "All test", "deal": "test_all"}, - {"name": "Loop test", "deal": "test_loop"}, - # {"name":"Check loop-test result", "deal" :"test_loop_read"}, - # {"name":"Delete loop-test result", "deal" :"test_loop_delete"}, - # {"name":"Load configuration", "deal" :"test_config"}, - test_sys_reload_item, - {"name": "System Configuration", "deal": "test_sysconfig", "childid": 2}, - ], - }, - { - "menuid": 1, - "parentid": 0, - "value": [ - test_sys_item, - test_temp_item, - test_mem_item, - test_hd_item, - test_rtc_item, - test_i2c_item, - test_cpld_item, - test_portframe_item, - test_sysled_item, - test_fan_item, - test_power_item, - test_usb_item, - test_prbs_item, - test_portbroadcast_item, - ], - }, - { - "menuid": 2, - "parentid": 0, - "value": [test_debug_level, test_log_level, test_setmac, test_setrtc,], - }, - { - "menuid": 3, - "parentid": 2, - "value": [ - log_level_critical, - log_level_debug, - log_level_error, - log_level_info, - log_level_notset, - log_level_warning, - ], - }, - { - "menuid": 4, - "parentid": 2, - "value": [test_e2_setmac_item, test_bmc_setmac_item, test_fan_setmac_item,], - }, -] - - -TESTCASE = { - "CPLD": [ - { - "name": "CONNECT BOARD CPLD-A", - "cases": [ - {"name": "cpld32", "cmd": "grtd_test.py cpld_check 0 0x32 0xAA"}, - {"name": "cpld37", "cmd": "grtd_test.py cpld_check 2 0x37 0xAC"}, - ], - }, - { - "name": "MAC BOARD CPLD-A", - "cases": [ - {"name": "cpld33", "cmd": "grtd_test.py cpld_check 2 0x33 0xAB"}, - {"name": "cpld34", "cmd": "grtd_test.py cpld_check 1 0x34 0xAA"}, - ], - }, - { - "name": "MAC BOARD CPLD-B", - "cases": [ - {"name": "cpld36", "cmd": "grtd_test.py cpld_check 1 0x36 0xAA"}, - {"name": "cpld35", "cmd": "grtd_test.py cpld_check 2 0x35 0xAB"}, - ], - }, - ], - "TEMPERATURE": [ - { - "name": "-->temperature test", - "cases": [ - { - "name": "inlet", - "cmd": "grtd_test.py temp 2-0048/hwmon/hwmon1/temp1_input", - }, - { - "name": "outlet", - "cmd": "grtd_test.py temp 2-0049/hwmon/hwmon2/temp1_input", - }, - { - "name": "hot-point", - "cmd": "grtd_test.py temp 2-004a/hwmon/hwmon3/temp1_input", - }, - ], - } - ], - "MEMTORY": { - "cases": [ - {"name": "->memory test 1M", "cmd": "memtester 1M 1"}, - {"name": "->memory test 2M", "cmd": "memtester 2M 1"}, - {"name": "->memory test 8M", "cmd": "memtester 8M 1"}, - # {"name":"->memory test 16M","cmd":"memtester 16M 1"}, - # {"name":"->memory test 256M","cmd":"memtester 256M 1"}, - ] - }, - "SMARTCTLCMDS": { - "cases": [ - {"name": "->Check Hard Disk Info", "cmd": "smartctl -i /dev/sda"}, - {"name": "->Check Hard Disk Monitor Status", "cmd": "smartctl -H /dev/sda"}, - ] - }, - "LED": [ - { - "name": "Light Port Led test", - "cases": [ - { - "name": "-> Red Led Off", - "cmd": "grtd_test.py led loc 1-0034/sfp_led1_red,1-0034/sfp_led2_red,1-0034/sfp_led3_red,1-0034/sfp_led8_red,1-0036/sfp_led4_red,1-0036/sfp_led5_red,1-0036/sfp_led6_red,1-0036/sfp_led7_red 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00", - }, - { - "name": "-> Red Led On", - "cmd": "grtd_test.py led loc 1-0034/sfp_led1_red,1-0034/sfp_led2_red,1-0034/sfp_led3_red,1-0034/sfp_led8_red,1-0036/sfp_led4_red,1-0036/sfp_led5_red,1-0036/sfp_led6_red,1-0036/sfp_led7_red 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff", - }, - { - "name": "-> Recovery Red Led Off", - "cmd": "grtd_test.py led loc 1-0034/sfp_led1_red,1-0034/sfp_led2_red,1-0034/sfp_led3_red,1-0034/sfp_led8_red,1-0036/sfp_led4_red,1-0036/sfp_led5_red,1-0036/sfp_led6_red,1-0036/sfp_led7_red 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00", - }, - { - "name": "-> Yellow Led Off", - "cmd": "grtd_test.py led loc 1-0034/sfp_led1_yellow,1-0034/sfp_led2_yellow,1-0034/sfp_led3_yellow,1-0034/sfp_led8_yellow,1-0036/sfp_led4_yellow,1-0036/sfp_led5_yellow,1-0036/sfp_led6_yellow,1-0036/sfp_led7_yellow 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00", - }, - { - "name": "-> Yellow Led On", - "cmd": "grtd_test.py led loc 1-0034/sfp_led1_yellow,1-0034/sfp_led2_yellow,1-0034/sfp_led3_yellow,1-0034/sfp_led8_yellow,1-0036/sfp_led4_yellow,1-0036/sfp_led5_yellow,1-0036/sfp_led6_yellow,1-0036/sfp_led7_yellow 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff", - }, - { - "name": "-> Recovery Yellow Led Off", - "cmd": "grtd_test.py led loc 1-0034/sfp_led1_yellow,1-0034/sfp_led2_yellow,1-0034/sfp_led3_yellow,1-0034/sfp_led8_yellow,1-0036/sfp_led4_yellow,1-0036/sfp_led5_yellow,1-0036/sfp_led6_yellow,1-0036/sfp_led7_yellow 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00", - }, - ], - }, - { - "name": "fan 1 Led", - "cases": [ - { - "name": "-> LedOff", - "cmd": "grtd_test.py led loc 0-0032/fan0_led 0x0b", - }, - { - "name": "-> Red Led ", - "cmd": "grtd_test.py led loc 0-0032/fan0_led 0x0a", - }, - { - "name": "-> Green Led ", - "cmd": "grtd_test.py led loc 0-0032/fan0_led 0x09", - }, - { - "name": "-> Yellow Led ", - "cmd": "grtd_test.py led loc 0-0032/fan0_led 0x08", - }, - { - "name": "-> Red Led Flashing", - "cmd": "grtd_test.py led loc 0-0032/fan0_led 0x0e", - }, - { - "name": "-> Green Led Flashing", - "cmd": "grtd_test.py led loc 0-0032/fan0_led 0x0d", - }, - { - "name": "-> Yellow Led Flashing", - "cmd": "grtd_test.py led loc 0-0032/fan0_led 0x0c", - }, - { - "name": "-> Recovery Green Led ", - "cmd": "grtd_test.py led loc 0-0032/fan0_led 0x09", - }, - ], - }, - { - "name": "fan 2 Led", - "cases": [ - { - "name": "-> LedOff", - "cmd": "grtd_test.py led loc 0-0032/fan1_led 0x0b", - }, - { - "name": "-> Red Led ", - "cmd": "grtd_test.py led loc 0-0032/fan1_led 0x0a", - }, - { - "name": "-> Green Led ", - "cmd": "grtd_test.py led loc 0-0032/fan1_led 0x09", - }, - { - "name": "-> Yellow Led ", - "cmd": "grtd_test.py led loc 0-0032/fan1_led 0x08", - }, - { - "name": "-> Red Led Flashing", - "cmd": "grtd_test.py led loc 0-0032/fan1_led 0x0e", - }, - { - "name": "-> Green Led Flashing", - "cmd": "grtd_test.py led loc 0-0032/fan1_led 0x0d", - }, - { - "name": "-> Yellow Led Flashing", - "cmd": "grtd_test.py led loc 0-0032/fan1_led 0x0c", - }, - { - "name": "-> Recovery Green Led ", - "cmd": "grtd_test.py led loc 0-0032/fan1_led 0x09", - }, - ], - }, - { - "name": "fan 3 Led", - "cases": [ - { - "name": "-> LedOff", - "cmd": "grtd_test.py led loc 0-0032/fan2_led 0x0b", - }, - { - "name": "-> Red Led ", - "cmd": "grtd_test.py led loc 0-0032/fan2_led 0x0a", - }, - { - "name": "-> Green Led ", - "cmd": "grtd_test.py led loc 0-0032/fan2_led 0x09", - }, - { - "name": "-> Yellow Led ", - "cmd": "grtd_test.py led loc 0-0032/fan2_led 0x08", - }, - { - "name": "-> Red Led Flashing", - "cmd": "grtd_test.py led loc 0-0032/fan2_led 0x0e", - }, - { - "name": "-> Green Led Flashing", - "cmd": "grtd_test.py led loc 0-0032/fan2_led 0x0d", - }, - { - "name": "-> Yellow Led Flashing", - "cmd": "grtd_test.py led loc 0-0032/fan2_led 0x0c", - }, - { - "name": "-> Recovery Green Led ", - "cmd": "grtd_test.py led loc 0-0032/fan2_led 0x09", - }, - ], - }, - { - "name": "Front panel CPU Led", - "cases": [ - { - "name": "-> LedOff", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x00", - }, - { - "name": "-> Green Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x01", - }, - { - "name": "-> Red Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x02", - }, - { - "name": "-> Yellow Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x03", - }, - { - "name": "-> Green Led 1/4sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x11", - }, - { - "name": "-> Green Led 1/2sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x21", - }, - { - "name": "-> Green Led 1sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x41", - }, - { - "name": "-> Green Led 2sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x81", - }, - { - "name": "-> Red Led 1/4sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x12", - }, - { - "name": "-> Red Led 1/2sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x22", - }, - { - "name": "-> Red Led 1sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x42", - }, - { - "name": "-> Red Led 2sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x82", - }, - { - "name": "-> Yellow Led 1/4sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x13", - }, - { - "name": "-> Yellow Led 1/2sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x23", - }, - { - "name": "-> Yellow Led 1sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x43", - }, - { - "name": "-> Yellow Led 2sFlashing ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x83", - }, - { - "name": "-> Recovery Green Led ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_cpu 0x01", - }, - ], - }, - { - "name": "Front panel BMC Led", - "cases": [ - { - "name": "-> LedOff", - "cmd": "grtd_test.py led loc 2-0035/broad_front_bmc 0x00", - }, - { - "name": "-> Red Led Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_bmc 0x01", - }, - { - "name": "-> Red Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_bmc 0x02", - }, - { - "name": "-> Green Led Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_bmc 0x03", - }, - { - "name": "-> Green Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_bmc 0x04", - }, - { - "name": "-> Yellow Led Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_bmc 0x05", - }, - { - "name": "-> Yellow Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_bmc 0x06", - }, - { - "name": "-> Recovery Green Led ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_bmc 0x04", - }, - ], - }, - { - "name": "Front panel location Led", - "cases": [ - { - "name": "-> LedOff", - "cmd": "grtd_test.py led loc 2-0035/broad_front_lct 0xff", - }, - { - "name": "-> LedOn", - "cmd": "grtd_test.py led loc 2-0035/broad_front_lct 0xfe", - }, - { - "name": "->Recovery LedOff", - "cmd": "grtd_test.py led loc 2-0035/broad_front_lct 0xff", - }, - ], - }, - { - "name": "Front panel pwr Led", - "cases": [ - { - "name": "-> LedOff", - "cmd": "grtd_test.py led loc 2-0035/broad_front_pwr 0x00", - }, - { - "name": "-> Red Led Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_pwr 0x01", - }, - { - "name": "-> Red Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_pwr 0x02", - }, - { - "name": "-> Green Led Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_pwr 0x03", - }, - { - "name": "-> Green Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_pwr 0x04", - }, - { - "name": "-> Yellow Led Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_pwr 0x05", - }, - { - "name": "-> Yellow Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_pwr 0x06", - }, - { - "name": "-> Recovery Green Led ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_pwr 0x04", - }, - ], - }, - { - "name": "Front panel fan Led", - "cases": [ - { - "name": "-> LedOff", - "cmd": "grtd_test.py led loc 2-0035/broad_front_fan 0x00", - }, - { - "name": "-> Red Led Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_fan 0x01", - }, - { - "name": "-> Red Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_fan 0x02", - }, - { - "name": "-> Green Led Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_fan 0x03", - }, - { - "name": "-> Green Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_fan 0x04", - }, - { - "name": "-> Yellow Led Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_fan 0x05", - }, - { - "name": "-> Yellow Led not Flashing", - "cmd": "grtd_test.py led loc 2-0035/broad_front_fan 0x06", - }, - { - "name": "-> Recovery Green Led ", - "cmd": "grtd_test.py led loc 2-0035/broad_front_fan 0x04", - }, - ], - }, - ], - "I2C": [ - ####type 1 represents value obtained compated with value - ####type 2 represents return True or False - { - "name": "I2C device test", - "cases": [ - { - "name": " PCA9641 test", - "cmd": "grtd_test.py dev_rd 0 10 0", - "deal_type": 2, - }, - { - "name": " cpld32 test", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " cpld33 test", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " cpld34 test", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " cpld35 test", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " cpld36 test", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " cpld37 test", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " inlet LM75", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " outlet LM75", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " hot-point LM75", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " EEPROM", - "cmd": "grtd_test.py dev_rd 0 32 0", - "deal_type": 2, - }, - { - "name": " Port 1", - "cmd": "grtd_test.py dev_rd 11 0050 0", - "deal_type": 2, - }, - { - "name": " Port 2", - "cmd": "grtd_test.py dev_rd 12 0050 0", - "deal_type": 2, - }, - { - "name": " Port 3", - "cmd": "grtd_test.py dev_rd 13 0050 0", - "deal_type": 2, - }, - { - "name": " Port 4", - "cmd": "grtd_test.py dev_rd 14 0050 0", - "deal_type": 2, - }, - { - "name": " Port 5", - "cmd": "grtd_test.py dev_rd 15 0050 0", - "deal_type": 2, - }, - { - "name": " Port 6", - "cmd": "grtd_test.py dev_rd 16 0050 0", - "deal_type": 2, - }, - { - "name": " Port 7", - "cmd": "grtd_test.py dev_rd 17 0050 0", - "deal_type": 2, - }, - { - "name": " Port 8", - "cmd": "grtd_test.py dev_rd 18 0050 0", - "deal_type": 2, - }, - { - "name": " Port 9", - "cmd": "grtd_test.py dev_rd 19 0050 0", - "deal_type": 2, - }, - { - "name": " Port 10", - "cmd": "grtd_test.py dev_rd 20 0050 0", - "deal_type": 2, - }, - { - "name": " Port 11", - "cmd": "grtd_test.py dev_rd 21 0050 0", - "deal_type": 2, - }, - { - "name": " Port 12", - "cmd": "grtd_test.py dev_rd 22 0050 0", - "deal_type": 2, - }, - { - "name": " Port 13", - "cmd": "grtd_test.py dev_rd 23 0050 0", - "deal_type": 2, - }, - { - "name": " Port 14", - "cmd": "grtd_test.py dev_rd 24 0050 0", - "deal_type": 2, - }, - { - "name": " Port 15", - "cmd": "grtd_test.py dev_rd 25 0050 0", - "deal_type": 2, - }, - { - "name": " Port 16", - "cmd": "grtd_test.py dev_rd 26 0050 0", - "deal_type": 2, - }, - { - "name": " Port 17", - "cmd": "grtd_test.py dev_rd 27 0050 0", - "deal_type": 2, - }, - { - "name": " Port 18", - "cmd": "grtd_test.py dev_rd 28 0050 0", - "deal_type": 2, - }, - { - "name": " Port 19", - "cmd": "grtd_test.py dev_rd 29 0050 0", - "deal_type": 2, - }, - { - "name": " Port 20", - "cmd": "grtd_test.py dev_rd 30 0050 0", - "deal_type": 2, - }, - { - "name": " Port 21", - "cmd": "grtd_test.py dev_rd 31 0050 0", - "deal_type": 2, - }, - { - "name": " Port 22", - "cmd": "grtd_test.py dev_rd 32 0050 0", - "deal_type": 2, - }, - { - "name": " Port 23", - "cmd": "grtd_test.py dev_rd 33 0050 0", - "deal_type": 2, - }, - { - "name": " Port 24", - "cmd": "grtd_test.py dev_rd 34 0050 0", - "deal_type": 2, - }, - { - "name": " Port 25", - "cmd": "grtd_test.py dev_rd 35 0050 0", - "deal_type": 2, - }, - { - "name": " Port 26", - "cmd": "grtd_test.py dev_rd 36 0050 0", - "deal_type": 2, - }, - { - "name": " Port 27", - "cmd": "grtd_test.py dev_rd 37 0050 0", - "deal_type": 2, - }, - { - "name": " Port 28", - "cmd": "grtd_test.py dev_rd 38 0050 0", - "deal_type": 2, - }, - { - "name": " Port 29", - "cmd": "grtd_test.py dev_rd 39 0050 0", - "deal_type": 2, - }, - { - "name": " Port 30", - "cmd": "grtd_test.py dev_rd 40 0050 0", - "deal_type": 2, - }, - { - "name": " Port 31", - "cmd": "grtd_test.py dev_rd 41 0050 0", - "deal_type": 2, - }, - { - "name": " Port 32", - "cmd": "grtd_test.py dev_rd 42 0050 0", - "deal_type": 2, - }, - { - "name": " Port 33", - "cmd": "grtd_test.py dev_rd 43 0050 0", - "deal_type": 2, - }, - { - "name": " Port 34", - "cmd": "grtd_test.py dev_rd 44 0050 0", - "deal_type": 2, - }, - { - "name": " Port 35", - "cmd": "grtd_test.py dev_rd 45 0050 0", - "deal_type": 2, - }, - { - "name": " Port 36", - "cmd": "grtd_test.py dev_rd 46 0050 0", - "deal_type": 2, - }, - { - "name": " Port 37", - "cmd": "grtd_test.py dev_rd 47 0050 0", - "deal_type": 2, - }, - { - "name": " Port 38", - "cmd": "grtd_test.py dev_rd 48 0050 0", - "deal_type": 2, - }, - { - "name": " Port 39", - "cmd": "grtd_test.py dev_rd 49 0050 0", - "deal_type": 2, - }, - { - "name": " Port 40", - "cmd": "grtd_test.py dev_rd 50 0050 0", - "deal_type": 2, - }, - { - "name": " Port 41", - "cmd": "grtd_test.py dev_rd 51 0050 0", - "deal_type": 2, - }, - { - "name": " Port 42", - "cmd": "grtd_test.py dev_rd 52 0050 0", - "deal_type": 2, - }, - { - "name": " Port 43", - "cmd": "grtd_test.py dev_rd 53 0050 0", - "deal_type": 2, - }, - { - "name": " Port 44", - "cmd": "grtd_test.py dev_rd 54 0050 0", - "deal_type": 2, - }, - { - "name": " Port 45", - "cmd": "grtd_test.py dev_rd 55 0050 0", - "deal_type": 2, - }, - { - "name": " Port 46", - "cmd": "grtd_test.py dev_rd 56 0050 0", - "deal_type": 2, - }, - { - "name": " Port 47", - "cmd": "grtd_test.py dev_rd 57 0050 0", - "deal_type": 2, - }, - { - "name": " Port 48", - "cmd": "grtd_test.py dev_rd 58 0050 0", - "deal_type": 2, - }, - { - "name": " Port 49", - "cmd": "grtd_test.py dev_rd 59 0050 0", - "deal_type": 2, - }, - { - "name": " Port 50", - "cmd": "grtd_test.py dev_rd 60 0050 0", - "deal_type": 2, - }, - { - "name": " Port 51", - "cmd": "grtd_test.py dev_rd 61 0050 0", - "deal_type": 2, - }, - { - "name": " Port 52", - "cmd": "grtd_test.py dev_rd 62 0050 0", - "deal_type": 2, - }, - { - "name": " Port 53", - "cmd": "grtd_test.py dev_rd 63 0050 0", - "deal_type": 2, - }, - { - "name": " Port 54", - "cmd": "grtd_test.py dev_rd 64 0050 0", - "deal_type": 2, - }, - { - "name": " Port 55", - "cmd": "grtd_test.py dev_rd 65 0050 0", - "deal_type": 2, - }, - { - "name": " Port 56", - "cmd": "grtd_test.py dev_rd 66 0050 0", - "deal_type": 2, - }, - { - "name": " Port 57", - "cmd": "grtd_test.py dev_rd 67 0050 0", - "deal_type": 2, - }, - { - "name": " Port 58", - "cmd": "grtd_test.py dev_rd 68 0050 0", - "deal_type": 2, - }, - { - "name": " Port 59", - "cmd": "grtd_test.py dev_rd 69 0050 0", - "deal_type": 2, - }, - { - "name": " Port 60", - "cmd": "grtd_test.py dev_rd 70 0050 0", - "deal_type": 2, - }, - { - "name": " Port 61", - "cmd": "grtd_test.py dev_rd 71 0050 0", - "deal_type": 2, - }, - { - "name": " Port 62", - "cmd": "grtd_test.py dev_rd 72 0050 0", - "deal_type": 2, - }, - { - "name": " Port 63", - "cmd": "grtd_test.py dev_rd 73 0050 0", - "deal_type": 2, - }, - { - "name": " Port 64", - "cmd": "grtd_test.py dev_rd 74 0050 0", - "deal_type": 2, - }, - ], - }, - ], -} - -PCIe_DEV_LIST = [] -PCIe_SPEED_ITEM = [] - -################################Manufacturing-Test-Adaption-Area####################################################### diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/ragileconfig.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/ragileconfig.py deleted file mode 100755 index 4a3a321d6e42..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/script/ragileconfig.py +++ /dev/null @@ -1,225 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: UTF-8 -*- -# ------------------------------------------------------------------------------- -# Name: ragileconfig.py -# Purpose: block the difference between various product/onie version for other module -# -# Author: rd -# -# Created: 02/07/2018 -# Copyright: (c) rd 2018 -# ------------------------------------------------------------------------------- -import sys -import os -from rgutil.baseutil import get_machine_info -from rgutil.baseutil import get_platform_info - -__all__ = [ - "getdeviceplatform", - "get_rjconfig_info", - "MONITOR_CONST", - "MAILBOX_DIR", - "DEVICE", - "GLOBALCONFIG", - "GLOBALINITPARAM", - "GLOBALINITCOMMAND", - "MAC_LED_RESET", - "STARTMODULE", - "fanloc", - "RAGILE_CARDID", - "RAGILE_PRODUCTNAME", - "RAGILE_PART_NUMBER", - "RAGILE_LABEL_REVISION", - "RAGILE_MAC_SIZE", - "RAGILE_MANUF_NAME", - "RAGILE_MANUF_COUNTRY", - "RAGILE_VENDOR_NAME", - "RAGILE_DIAG_VERSION", - "RAGILE_SERVICE_TAG", - "E2_PROTECT", - "E2_LOC", - "FAN_PROTECT", - "FANS_DEF", - "MONITOR_FANS_LED", - "MONITOR_SYS_FAN_LED", - "MONITOR_SYS_PSU_LED", - "MONITOR_FAN_STATUS", - "MONITOR_PSU_STATUS", - "MONITOR_DEV_STATUS", - "MONITOR_DEV_STATUS_DECODE", - "DEV_LEDS", - "MAC_AVS_PARAM", - "MAC_DEFAULT_PARAM", - "FRULISTS", - "rg_eeprom", - "i2ccheck_params", - "FANCTROLDEBUG", - "DEVMONITORDEBUG", -] - - -def getdeviceplatform(): - x = get_platform_info(get_machine_info()) - if x != None: - filepath = "/usr/share/sonic/device/" + x - return filepath - - -platform = get_platform_info(get_machine_info()) -platformpath = getdeviceplatform() -MAILBOX_DIR = "/sys/bus/i2c/devices/" -grtd_productfile = (platform + "_config").replace("-", "_") -common_productfile = "ragilecommon" -configfile_pre = "/usr/local/bin/" - -sys.path.append(platformpath) -sys.path.append(configfile_pre) - - -def get_rjconfig_info(attr_key): - rjconf_filename = platformpath + "/plugins" + "/rj.conf" - if not os.path.isfile(rjconf_filename): - return None - with open(rjconf_filename) as rjconf_file: - for line in rjconf_file: - tokens = line.split("=") - if len(tokens) < 2: - continue - if tokens[0] == attr_key: - return tokens[1].strip() - return None - - -#####BMC-Password### -OPENBMC_PASSWORD = get_rjconfig_info("OPENBMC_PASSWORD") -OPENBMC_PASSWORD = OPENBMC_PASSWORD if (OPENBMC_PASSWORD != None) else "0penBmc" - -############################################################################################ -## if there is no specific file, use common file -module_product = None -if os.path.exists(configfile_pre + grtd_productfile + ".py"): - module_product = __import__(grtd_productfile, globals(), locals(), [], 0) -elif os.path.exists(configfile_pre + common_productfile + ".py"): - module_product = __import__(common_productfile, globals(), locals(), [], 0) -else: - print("No Configuration existed, quit") - exit(-1) -############################################################################################ - -DEVICE = module_product.DEVICE - -##########Driver loading needs parameters -# get different product configuration -RAGILE_GLOBALCONFIG = { - "DRIVERLISTS": module_product.DRIVERLISTS, - "QSFP": { - "startbus": module_product.PCA9548START, - "endbus": module_product.PCA9548BUSEND, - }, - "DEVS": DEVICE, -} -GLOBALCONFIG = RAGILE_GLOBALCONFIG -GLOBALINITPARAM = module_product.INIT_PARAM -GLOBALINITCOMMAND = module_product.INIT_COMMAND - -fancontrol_loc = module_product.fancontrol_loc -fancontrol_config_loc = module_product.fancontrol_config_loc -MAC_LED_RESET = module_product.MAC_LED_RESET -###########Stat-up module parameters -STARTMODULE = module_product.STARTMODULE -FIRMWARE_TOOLS = module_product.FIRMWARE_TOOLS - - -##########Manufacturing-Test need parameters -FACTESTMODULE = module_product.FACTESTMODULE -TESTCASE = module_product.TESTCASE -menuList = module_product.menuList -alltest = module_product.alltest -diagtestall = module_product.diagtestall -looptest = module_product.looptest -fanloc = module_product.fanloc -fanlevel = module_product.fanlevel # fan adjustment level -TEMPIDCHANGE = module_product.TEMPIDCHANGE -CPLDVERSIONS = module_product.CPLDVERSIONS -RAGILE_CARDID = module_product.RAGILE_CARDID -RAGILE_PRODUCTNAME = module_product.RAGILE_PRODUCTNAME - -RAGILE_PART_NUMBER = module_product.RAGILE_PART_NUMBER -RAGILE_LABEL_REVISION = module_product.RAGILE_LABEL_REVISION -RAGILE_ONIE_VERSION = module_product.RAGILE_ONIE_VERSION -RAGILE_MAC_SIZE = module_product.RAGILE_MAC_SIZE -RAGILE_MANUF_NAME = module_product.RAGILE_MANUF_NAME -RAGILE_MANUF_COUNTRY = module_product.RAGILE_MANUF_COUNTRY -RAGILE_VENDOR_NAME = module_product.RAGILE_VENDOR_NAME -RAGILE_DIAG_VERSION = module_product.RAGILE_DIAG_VERSION -RAGILE_SERVICE_TAG = module_product.RAGILE_SERVICE_TAG - -E2_PROTECT = module_product.E2_PROTECT -E2_LOC = module_product.E2_LOC -FAN_PROTECT = module_product.FAN_PROTECT - -FANS_DEF = module_product.FANS_DEF -MONITOR_SYS_LED = module_product.MONITOR_SYS_LED -MONITOR_FANS_LED = module_product.MONITOR_FANS_LED -MONITOR_SYS_FAN_LED = module_product.MONITOR_SYS_FAN_LED -MONITOR_SYS_PSU_LED = module_product.MONITOR_SYS_PSU_LED -MONITOR_FAN_STATUS = module_product.MONITOR_FAN_STATUS -MONITOR_PSU_STATUS = module_product.MONITOR_PSU_STATUS -MONITOR_DEV_STATUS = module_product.MONITOR_DEV_STATUS -MONITOR_DEV_STATUS_DECODE = module_product.MONITOR_DEV_STATUS_DECODE -DEV_MONITOR_PARAM = module_product.DEV_MONITOR_PARAM -SLOT_MONITOR_PARAM = module_product.SLOT_MONITOR_PARAM - - -DEV_LEDS = module_product.DEV_LEDS -MEM_SLOTS = module_product.MEM_SLOTS - -MAC_AVS_PARAM = module_product.MAC_AVS_PARAM -MAC_DEFAULT_PARAM = module_product.MAC_DEFAULT_PARAM -E2TYPE = module_product.E2TYPE -FRULISTS = module_product.FRULISTS -rg_eeprom = "%d-%04x/eeprom" % (E2_LOC["bus"], E2_LOC["devno"]) -factest_module = module_product.factest_module - -LOCAL_LED_CONTROL = module_product.LOCAL_LED_CONTROL - -PCIe_DEV_LIST = module_product.PCIe_DEV_LIST -PCIe_SPEED_ITEM = module_product.PCIe_SPEED_ITEM -i2ccheck_params = module_product.i2ccheck_params - - -class MONITOR_CONST: - TEMP_MIN = module_product.MONITOR_TEMP_MIN - K = module_product.MONITOR_K - MAC_IN = module_product.MONITOR_MAC_IN - DEFAULT_SPEED = module_product.MONITOR_DEFAULT_SPEED - MAX_SPEED = module_product.MONITOR_MAX_SPEED - MIN_SPEED = module_product.MONITOR_MIN_SPEED - MAC_ERROR_SPEED = module_product.MONITOR_MAC_ERROR_SPEED - FAN_TOTAL_NUM = module_product.MONITOR_FAN_TOTAL_NUM - MAC_UP_TEMP = module_product.MONITOR_MAC_UP_TEMP - MAC_LOWER_TEMP = module_product.MONITOR_MAC_LOWER_TEMP - MAC_MAX_TEMP = module_product.MONITOR_MAC_MAX_TEMP - - MAC_WARNING_THRESHOLD = module_product.MONITOR_MAC_WARNING_THRESHOLD - OUTTEMP_WARNING_THRESHOLD = module_product.MONITOR_OUTTEMP_WARNING_THRESHOLD - BOARDTEMP_WARNING_THRESHOLD = module_product.MONITOR_BOARDTEMP_WARNING_THRESHOLD - CPUTEMP_WARNING_THRESHOLD = module_product.MONITOR_CPUTEMP_WARNING_THRESHOLD - INTEMP_WARNING_THRESHOLD = module_product.MONITOR_INTEMP_WARNING_THRESHOLD - - MAC_CRITICAL_THRESHOLD = module_product.MONITOR_MAC_CRITICAL_THRESHOLD - OUTTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_OUTTEMP_CRITICAL_THRESHOLD - BOARDTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_BOARDTEMP_CRITICAL_THRESHOLD - CPUTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_CPUTEMP_CRITICAL_THRESHOLD - INTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_INTEMP_CRITICAL_THRESHOLD - CRITICAL_NUM = module_product.MONITOR_CRITICAL_NUM - SHAKE_TIME = module_product.MONITOR_SHAKE_TIME - MONITOR_INTERVAL = module_product.MONITOR_INTERVAL - MONITOR_FALL_TEMP = module_product.MONITOR_FALL_TEMP - - MONITOR_MAC_SOURCE_SYSFS = module_product.MONITOR_MAC_SOURCE_SYSFS - MONITOR_MAC_SOURCE_PATH = module_product.MONITOR_MAC_SOURCE_PATH - - -FANCTROLDEBUG = 0 # 1 means enable -DEVMONITORDEBUG = 0 # 1 means enable diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/ragileutil.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/ragileutil.py deleted file mode 100755 index debfcad5bc6d..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/script/ragileutil.py +++ /dev/null @@ -1,2101 +0,0 @@ -# -*- coding: UTF-8 -*- -# ------------------------------------------------------------------------- -# Name: ragileutil -# Purpose: common configuration and api -# -# Author: rd -# -# Created: 02/07/2018 -# Copyright: (c) rd 2018 -# ------------------------------------------------------------------------- -import sys - -if sys.version_info >= (3, 0): - import subprocess as commands -else: - import commands -import os -import re -import syslog -import time -import binascii -import tty -import termios -import threading -import click -import mmap -from ragileconfig import ( - rg_eeprom, - FRULISTS, - MAC_DEFAULT_PARAM, - MAC_AVS_PARAM, - FANS_DEF, - FAN_PROTECT, - E2_LOC, - E2_PROTECT, - RAGILE_SERVICE_TAG, - RAGILE_DIAG_VERSION, - STARTMODULE, - RAGILE_CARDID, - RAGILE_PRODUCTNAME, - RAGILE_PART_NUMBER, - RAGILE_LABEL_REVISION, - RAGILE_MAC_SIZE, - RAGILE_MANUF_NAME, - RAGILE_MANUF_COUNTRY, - RAGILE_VENDOR_NAME, - MAILBOX_DIR, -) - -try: - from eepromutil.fru import ipmifru - -except Exception or SystemExit: - pass - -import logging.handlers -import shutil -import gzip -import glob - -__all__ = [ - "MENUID", - "MENUPARENT", - "MENUVALUE", - "CHILDID", - "MENUITEMNAME", - "MENUITEMDEAL", - "GOBACK", - "GOQUIT", - "file_name", - "CRITICAL", - "FATAL", - "ERROR", - "WARNING", - "WARN", - "INFO", - "DEBUG", - "NOTSET", - "levelNames", - "TLV_INFO_ID_STRING", - "TLV_INFO_VERSION", - "TLV_INFO_LENGTH", - "TLV_INFO_LENGTH_VALUE", - "TLV_CODE_PRODUCT_NAME", - "TLV_CODE_PART_NUMBER", - "TLV_CODE_SERIAL_NUMBER", - "TLV_CODE_MAC_BASE", - "TLV_CODE_MANUF_DATE", - "TLV_CODE_DEVICE_VERSION", - "TLV_CODE_LABEL_REVISION", - "TLV_CODE_PLATFORM_NAME", - "TLV_CODE_ONIE_VERSION", - "TLV_CODE_MAC_SIZE", - "TLV_CODE_MANUF_NAME", - "TLV_CODE_MANUF_COUNTRY", - "TLV_CODE_VENDOR_NAME", - "TLV_CODE_DIAG_VERSION", - "TLV_CODE_SERVICE_TAG", - "TLV_CODE_VENDOR_EXT", - "TLV_CODE_CRC_32", - "_TLV_DISPLAY_VENDOR_EXT", - "TLV_CODE_RJ_CARID", - "_TLV_INFO_HDR_LEN", - "SYSLOG_IDENTIFIER", - "log_info", - "log_debug", - "log_warning", - "log_error", - "CompressedRotatingFileHandler", - "SETMACException", - "checkinput", - "checkinputproduct", - "getInputSetmac", - "fan_tlv", - "AVSUTIL", - "I2CUTIL", - "BMC", - "getSdkReg", - "getfilevalue", - "get_sysfs_value", - "write_sysfs_value", - "RJPRINTERR", - "strtoint", - "inttostr", - "str_to_hex", - "hex_to_str", - "str_to_bin", - "bin_to_str", - "get_mac_temp", - "get_mac_temp_sysfs", - "restartDockerService", - "wait_dhcp", - "wait_sdk", - "wait_docker", - "getTLV_BODY", - "_crc32", - "printvalue", - "generate_value", - "getsyseeprombyId", - "fac_init_cardidcheck", - "isValidMac", - "util_setmac", - "getInputCheck", - "getrawch", - "upper_input", - "changeTypeValue", - "astrcmp", - "generate_ext", - "rgi2cget", - "rgi2cset", - "rgpcird", - "rgpciwr", - "rgsysset", - "rgi2cget_word", - "rgi2cset_word", - "fan_setmac", - "checkfansninput", - "checkfanhwinput", - "util_show_fanse2", - "get_fane2_sysfs", - "util_show_fane2", - "getPid", - "fac_fans_setmac_tlv", - "fac_fan_setmac_fru", - "fac_fans_setmac", - "fac_fan_setmac", - "writeToEEprom", - "get_local_eth0_mac", - "getonieversion", - "createbmcMac", - "fac_board_setmac", - "ipmi_set_mac", - "getInputValue", - "bmc_setmac", - "closeProtocol", - "checkSdkMem", - "getch", - "get_raw_input", - "getsysvalue", - "get_pmc_register", - "decoder", - "decode_eeprom", - "get_sys_eeprom", - "getCardId", - "getsysmeminfo", - "getsysmeminfo_detail", - "getDmiSysByType", - "gethwsys", - "getsysbios", - "searchDirByName", - "getUsbLocation", - "getusbinfo", - "get_cpu_info", - "get_version_config_info", - "io_rd", - "io_wr", -] - -MENUID = "menuid" -MENUPARENT = "parentid" -MENUVALUE = "value" -CHILDID = "childid" -MENUITEMNAME = "name" -MENUITEMDEAL = "deal" -GOBACK = "goBack" -GOQUIT = "quit" - -file_name = "/etc/init.d/opennsl-modules-3.16.0-5-amd64" -########################################################################## -# ERROR LOG LEVEL -########################################################################## -CRITICAL = 50 -FATAL = CRITICAL -ERROR = 40 -WARNING = 30 -WARN = WARNING -INFO = 20 -DEBUG = 10 -NOTSET = 0 - -levelNames = { - CRITICAL: "CRITICAL", - ERROR: "ERROR", - WARNING: "WARNING", - INFO: "INFO", - DEBUG: "DEBUG", - NOTSET: "NOTSET", - "CRITICAL": CRITICAL, - "ERROR": ERROR, - "WARN": WARNING, - "WARNING": WARNING, - "INFO": INFO, - "DEBUG": DEBUG, - "NOTSET": NOTSET, -} - -TLV_INFO_ID_STRING = "TlvInfo\x00" -TLV_INFO_VERSION = 0x01 -TLV_INFO_LENGTH = 0x00 -TLV_INFO_LENGTH_VALUE = 0xBA - -########################################################################## -# eeprom info -########################################################################## -TLV_CODE_PRODUCT_NAME = 0x21 -TLV_CODE_PART_NUMBER = 0x22 -TLV_CODE_SERIAL_NUMBER = 0x23 -TLV_CODE_MAC_BASE = 0x24 -TLV_CODE_MANUF_DATE = 0x25 -TLV_CODE_DEVICE_VERSION = 0x26 -TLV_CODE_LABEL_REVISION = 0x27 -TLV_CODE_PLATFORM_NAME = 0x28 -TLV_CODE_ONIE_VERSION = 0x29 -TLV_CODE_MAC_SIZE = 0x2A -TLV_CODE_MANUF_NAME = 0x2B -TLV_CODE_MANUF_COUNTRY = 0x2C -TLV_CODE_VENDOR_NAME = 0x2D -TLV_CODE_DIAG_VERSION = 0x2E -TLV_CODE_SERVICE_TAG = 0x2F -TLV_CODE_VENDOR_EXT = 0xFD -TLV_CODE_CRC_32 = 0xFE -_TLV_DISPLAY_VENDOR_EXT = 1 -TLV_CODE_RJ_CARID = 0x01 -_TLV_INFO_HDR_LEN = 11 - - -SYSLOG_IDENTIFIER = "UTILTOOL" - -# ========================== Syslog wrappers ========================== - - -def log_info(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - - if also_print_to_console: - click.echo(msg) - - -def log_debug(msg, also_print_to_console=False): - try: - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_DEBUG, msg) - syslog.closelog() - - if also_print_to_console: - click.echo(msg) - except Exception as e: - pass - - -def log_warning(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - - if also_print_to_console: - click.echo(msg) - - -def log_error(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - - if also_print_to_console: - click.echo(msg) - - -class CompressedRotatingFileHandler(logging.handlers.RotatingFileHandler): - def doRollover(self): - """ - Do a rollover, as described in __init__(). - """ - if self.stream: - self.stream.close() - self.stream = None - if self.backupCount > 0: - for i in range(self.backupCount - 1, 0, -1): - sfn = "%s.%d.gz" % (self.baseFilename, i) - dfn = "%s.%d.gz" % (self.baseFilename, i + 1) - if os.path.exists(sfn): - if os.path.exists(dfn): - os.remove(dfn) - os.rename(sfn, dfn) - dfn = self.baseFilename + ".1.gz" - if os.path.exists(dfn): - os.remove(dfn) - # These two lines below are the only new lines. I commented out the os.rename(self.baseFilename, dfn) and - # replaced it with these two lines. - with open(self.baseFilename, "rb") as f_in, gzip.open(dfn, "wb") as f_out: - shutil.copyfileobj(f_in, f_out) - self.mode = "w" - self.stream = self._open() - - -class SETMACException(Exception): - def __init__(self, param="ERROR", errno="-1"): - err = "Setmac fail[%s]: %s" % (errno, param) - Exception.__init__(self, err) - self.param = param - self.errno = errno - - -def checkinput(b): - if b.isdigit() == False: - raise Exception("Ivalid Number") - if int(b) > 0xFF or int(b) < 0: - raise Exception("Out of area") - - -def checkinputproduct(b): - if b.isalnum() == False: - raise Exception("Invalid string") - - -def getInputSetmac(val): - bia = val.boardInfoArea - pia = val.productInfoArea - if bia != None: - a = raw_input("[Board Card]Product Serial Number:") - if len(a) != 13: - raise Exception("Invalid Serial Number length") - checkinputproduct(a) - bia.boardSerialNumber = a - b = raw_input("[Board Card]Product Version:(from 1-255)") - checkinput(b) - b = "%0x" % int(b) - bia.boardextra1 = b.upper() - if pia != None: - a = raw_input("[Product Area]Product Serial Number:") - if len(a) != 13: - raise Exception("Invalid Serial Number") - checkinputproduct(a) - pia.productSerialNumber = a - b = raw_input("[Product Area]Product Version:(from 1-255)") - checkinput(b) - b = "%0x" % int(b) - pia.productVersion = b.upper() - return val - - -class fan_tlv(object): - VERSION = 0x01 # E2PROM Version,start from 0x01 - FLAG = 0x7E # New E2PROM version flag is 0x7E - HW_VER = 0x01 # compose by master version and fixed version - TYPE = 0xF1 # hw type defination - TLV_LEN = 00 # data length (16bit) - _FAN_TLV_HDR_LEN = 6 - _FAN_TLV_CRC_LEN = 2 - - _FAN_TLV_TYPE_NAME = 0x02 - _FAN_TLV_TYPE_SN = 0x03 - _FAN_TLV_TYPE_HW_INFO = 0x05 - _FAN_TLV_TYPE_DEV_TYPE = 0x06 - - _fandecodetime = 0 - - @property - def dstatus(self): - return self._dstatus - - @property - def typename(self): - return self._typename - - @property - def typesn(self): - return self._typesn - - @property - def typehwinfo(self): - return self._typehwinfo - - @property - def typedevtype(self): - return self._typedevtype - - @property - def fanbus(self): - return self._fanbus - - @property - def fanloc(self): - return self._fanloc - - @property - def fandecodetime(self): - return self._fandecodetime - - def __init__(self): - self._typename = "" - self._typesn = "" - self._typehwinfo = "" - self._typedevtype = "" - self._dstatus = 0 - - def strtoarr(self, str): - s = [] - if str is not None: - for index in range(len(str)): - s.append(str[index]) - return s - - def generate_fan_value(self): - bin_buffer = [chr(0xFF)] * 256 - bin_buffer[0] = chr(self.VERSION) - bin_buffer[1] = chr(self.FLAG) - bin_buffer[2] = chr(self.HW_VER) - bin_buffer[3] = chr(self.TYPE) - - temp_t = "%08x" % self.typedevtype # handle devtype first - typedevtype_t = hex_to_str(temp_t) - total_len = ( - len(self.typename) - + len(self.typesn) - + len(self.typehwinfo) - + len(typedevtype_t) - + 8 - ) - - bin_buffer[4] = chr(total_len >> 8) - bin_buffer[5] = chr(total_len & 0x00FF) - - index_start = 6 - bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_NAME) - bin_buffer[index_start + 1] = chr(len(self.typename)) - bin_buffer[ - index_start + 2 : index_start + 2 + len(self.typename) - ] = self.strtoarr(self.typename) - index_start = index_start + 2 + len(self.typename) - - bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_SN) - bin_buffer[index_start + 1] = chr(len(self.typesn)) - bin_buffer[ - index_start + 2 : index_start + 2 + len(self.typesn) - ] = self.strtoarr(self.typesn) - index_start = index_start + 2 + len(self.typesn) - - bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_HW_INFO) - bin_buffer[index_start + 1] = chr(len(self.typehwinfo)) - bin_buffer[ - index_start + 2 : index_start + 2 + len(self.typehwinfo) - ] = self.strtoarr(self.typehwinfo) - index_start = index_start + 2 + len(self.typehwinfo) - - bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_DEV_TYPE) - bin_buffer[index_start + 1] = chr(len(typedevtype_t)) - bin_buffer[ - index_start + 2 : index_start + 2 + len(typedevtype_t) - ] = self.strtoarr(typedevtype_t) - index_start = index_start + 2 + len(typedevtype_t) - - crcs = fan_tlv.fancrc("".join(bin_buffer[0:index_start])) # check 2bytes - bin_buffer[index_start] = chr(crcs >> 8) - bin_buffer[index_start + 1] = chr(crcs & 0x00FF) - return bin_buffer - - def decode(self, e2): - ret = [] - self.VERSION = ord(e2[0]) - self.FLAG = ord(e2[1]) - self.HW_VER = ord(e2[2]) - self.TYPE = ord(e2[3]) - self.TLV_LEN = (ord(e2[4]) << 8) | ord(e2[5]) - - tlv_index = self._FAN_TLV_HDR_LEN - tlv_end = self._FAN_TLV_HDR_LEN + self.TLV_LEN - - # check checksum - if len(e2) < self._FAN_TLV_HDR_LEN + self.TLV_LEN + 2: - self._dstatus = -2 - return ret - sumcrc = fan_tlv.fancrc(e2[0 : self._FAN_TLV_HDR_LEN + self.TLV_LEN]) - readcrc = ord(e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN]) << 8 | ord( - e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN + 1] - ) - if sumcrc != readcrc: - self._dstatus = -1 - return ret - else: - self._dstatus = 0 - while (tlv_index + 2) < len(e2) and tlv_index < tlv_end: - s = self.decoder(e2[tlv_index : tlv_index + 2 + ord(e2[tlv_index + 1])]) - tlv_index += ord(e2[tlv_index + 1]) + 2 - ret.append(s) - - return ret - - @staticmethod - def fancrc(t): - sum = 0 - for index in range(len(t)): - sum += ord(t[index]) - return sum - - def decoder(self, t): - try: - name = "" - value = "" - if ord(t[0]) == self._FAN_TLV_TYPE_NAME: - name = "Product Name" - value = str(t[2 : 2 + ord(t[1])]) - self._typename = value - elif ord(t[0]) == self._FAN_TLV_TYPE_SN: - name = "serial Number" - value = str(t[2 : 2 + ord(t[1])]) - self._typesn = value - elif ord(t[0]) == self._FAN_TLV_TYPE_HW_INFO: - name = "hardware info" - value = str(t[2 : 2 + ord(t[1])]) - self._typehwinfo = value - elif ord(t[0]) == self._FAN_TLV_TYPE_DEV_TYPE: - name = "dev type" - value = str(t[2 : 2 + ord(t[1])]) - value = str_to_hex(value) - self._typedevtype = value - value = "0x08%x" % value - except Exception as e: - print(e) - return {"name": name, "code": ord(t[0]), "value": value} - - def __str__(self): - formatstr = ( - "VERSION : 0x%02x \n" - " FLAG : 0x%02x \n" - " HW_VER : 0x%02x \n" - " TYPE : 0x%02x \n" - "typename : %s \n" - "typesn : %s \n" - "typehwinfo : %s \n" - ) - return formatstr % ( - self.VERSION, - self.FLAG, - self.HW_VER, - self.TYPE, - self.typename, - self.typesn, - self.typehwinfo, - ) - - -class AVSUTIL: - @staticmethod - def mac_avs_chip(bus, devno, loc, open, close, loop, protectaddr, level, loopaddr): - # disable protection - rgi2cset(bus, devno, protectaddr, open) - rgi2cset(bus, devno, loopaddr, loop) - rgi2cset_word(bus, devno, loc, level) - ret, value = rgi2cget_word(bus, devno, loc) - if strtoint(value) == level: - ret = 0 - # enable protection - rgi2cset(bus, devno, protectaddr, close) - if ret == 0: - return True - return False - - @staticmethod - def macPressure_adj(macavs, avs_param, mac_def_param): - # check whether it within range - max_adj = max(avs_param.keys()) - min_adj = min(avs_param.keys()) - type = mac_def_param["type"] - level = 0 - if type == 0: - if macavs not in range(min_adj, max_adj + 1): - return False - else: - level = macavs - else: - if macavs not in range(min_adj, max_adj + 1): - level = mac_def_param["default"] - else: - level = macavs - ret = AVSUTIL.mac_avs_chip( - mac_def_param["bus"], - mac_def_param["devno"], - mac_def_param["addr"], - mac_def_param["open"], - mac_def_param["close"], - mac_def_param["loop"], - mac_def_param["protectaddr"], - avs_param[level], - mac_def_param["loopaddr"], - ) - return ret - - @staticmethod - def mac_adj(): - macavs = 0 - name = MAC_DEFAULT_PARAM["sdkreg"] - ret, status = getSdkReg(name) - if ret == False: - return False - status = strtoint(status) - # shift operation - if MAC_DEFAULT_PARAM["sdktype"] != 0: - status = (status >> MAC_DEFAULT_PARAM["macregloc"]) & MAC_DEFAULT_PARAM[ - "mask" - ] - macavs = status - ret = AVSUTIL.macPressure_adj(macavs, MAC_AVS_PARAM, MAC_DEFAULT_PARAM) - return ret - - -class I2CUTIL: - @staticmethod - def getvaluefromdevice(name): - ret = [] - for item in DEVICE: - if item["name"] == name: - ret.append(item) - return ret - - @staticmethod - def openFanE2Protect(): - rgi2cset( - FAN_PROTECT["bus"], - FAN_PROTECT["devno"], - FAN_PROTECT["addr"], - FAN_PROTECT["open"], - ) - - @staticmethod - def closeFanE2Protect(): - rgi2cset( - FAN_PROTECT["bus"], - FAN_PROTECT["devno"], - FAN_PROTECT["addr"], - FAN_PROTECT["close"], - ) - - @staticmethod - def writeToFanE2(bus, loc, rst_arr): - index = 0 - for item in rst_arr: - rgi2cset(bus, loc, index, ord(item)) - index += 1 - - @staticmethod - def writeToE2(bus, loc, rst_arr): - index = 0 - for item in rst_arr: - rgi2cset(bus, loc, index, ord(item)) - index += 1 - - @staticmethod - def getE2File(bus, loc): - return "/sys/bus/i2c/devices/%d-00%02x/eeprom" % (bus, loc) - - -class BMC: - _instance_lock = threading.Lock() - - def __init__(self): - pass - - def __new__(cls, *args, **kwargs): - if not hasattr(Singleton, "_instance"): - with Singleton._instance_lock: - if not hasattr(Singleton, "_instance"): - Singleton._instance = object.__new__(cls) - return Singleton._instance - - -# Internal interface - - -def getSdkReg(reg): - try: - cmd = "bcmcmd -t 1 'getr %s ' < /dev/null" % reg - ret, result = os_system(cmd) - result_t = result.strip().replace("\r", "").replace("\n", "") - if ret != 0 or "Error:" in result_t: - return False, result - patt = r"%s.(.*):(.*)>drivshell" % reg - rt = re.findall(patt, result_t, re.S) - test = re.findall("=(.*)", rt[0][0])[0] - except Exception as e: - return False, "getsdk register error" - return True, test - - -def getfilevalue(location): - try: - with open(location, "r") as fd: - value = fd.read() - return True, value.strip() - except Exception as e: - return False, "error" - - -def get_sysfs_value(location): - pos_t = str(location) - name = get_pmc_register(pos_t) - return name - - -def write_sysfs_value(reg_name, value): - fileLoc = MAILBOX_DIR + reg_name - try: - if not os.path.isfile(fileLoc): - print(fileLoc, "not found !") - return False - with open(fileLoc, "w") as fd: - fd.write(value) - except Exception as error: - log_error("Unable to open " + fileLoc + "file !") - return False - return True - - -def RJPRINTERR(str): - print("\033[0;31m%s\033[0m" % str) - - -def strtoint(str): # convert Hex string to int such as "4040"/"0x4040"/"0X4040" = 16448 - value = 0 - rest_v = str.replace("0X", "").replace("0x", "") - for index in range(len(rest_v)): - print(rest_v[index]) - value |= int(rest_v[index], 16) << ((len(rest_v) - index - 1) * 4) - return value - - -def inttostr(vl, len): # convert int to string such as 0x3030 = 00 - if type(vl) != int: - raise Exception(" type error") - index = 0 - ret_t = "" - while index < len: - ret = 0xFF & (vl >> index * 8) - ret_t += chr(ret) - index += 1 - return ret_t - - -def str_to_hex(rest_v): - value = 0 - for index in range(len(rest_v)): - value |= ord(rest_v[index]) << ((len(rest_v) - index - 1) * 8) - return value - - -def hex_to_str(s): - len_t = len(s) - if len_t % 2 != 0: - return 0 - ret = "" - for t in range(0, int(len_t / 2)): - ret += chr(int(s[2 * t : 2 * t + 2], 16)) - return ret - - -def str_to_bin(s): - return " ".join([bin(ord(c)).replace("0b", "") for c in s]) - - -def bin_to_str(s): - return "".join([chr(i) for i in [int(b, 2) for b in s.split(" ")]]) - - -def get_mac_temp(): - result = {} - # wait_docker() - # exec twice, get the second result - os_system('bcmcmd -t 1 "show temp" < /dev/null') - ret, log = os_system('bcmcmd -t 1 "show temp" < /dev/null') - if ret: - return False, result - else: - # decode obtained info - logs = log.splitlines() - for line in logs: - if "average" in line: - b = re.findall(r"\d+.\d+", line) - result["average"] = b[0] - elif "maximum" in line: - b = re.findall(r"\d+.\d+", line) - result["maximum"] = b[0] - return True, result - - -def get_mac_temp_sysfs(mactempconf): - try: - temp = -1000000 - temp_list = [] - mac_temp_loc = mactempconf.get("loc", []) - mac_temp_flag = mactempconf.get("flag", None) - if mac_temp_flag is not None: # check mac temperature vaild flag - gettype = mac_temp_flag.get("gettype") - okbit = mac_temp_flag.get("okbit") - okval = mac_temp_flag.get("okval") - if gettype == "io": - io_addr = mac_temp_flag.get("io_addr") - val = io_rd(io_addr) - if val is None: - raise Exception("get mac_flag by io failed.") - else: - bus = mac_temp_flag.get("bus") - loc = mac_temp_flag.get("loc") - offset = mac_temp_flag.get("offset") - ind, val = rgi2cget(bus, loc, offset) - if ind is not True: - raise Exception("get mac_flag by i2c failed.") - val_t = (int(val, 16) & (1 << okbit)) >> okbit - if val_t != okval: - raise Exception("mac_flag invalid, val_t:%d." % val_t) - for loc in mac_temp_loc: - temp_s = get_sysfs_value(loc) - if isinstance(temp_s, str) and temp_s.startswith("ERR"): - raise Exception("get mac temp error. loc:%s" % loc) - temp_t = int(temp_s) - if temp_t == -1000000: - raise Exception("mac temp invalid.loc:%s" % loc) - temp_list.append(temp_t) - temp_list.sort(reverse=True) - temp = temp_list[0] - except Exception as e: - return False, temp - return True, temp - - -def restartDockerService(force=False): - container_name = [ - "database", - "snmp", - "syncd", - "swss", - "dhcp_relay", - "radv", - "teamd", - "pmon", - ] - ret, status = os_system("docker ps") - if ret == 0: - for tmpname in container_name: - if tmpname not in status: - if force == True: - os_system("docker restart %s" % tmpname) - else: - os_system("systemctl restart %s" % tmpname) - - -def wait_dhcp(timeout): - time_cnt = 0 - while True: - try: - ret, status = os_system("systemctl status dhcp_relay.service") - if (ret == 0 and "running" in status) or "SUCCESS" in status: - break - else: - sys.stdout.write(".") - sys.stdout.flush() - time_cnt = time_cnt + 1 - if time_cnt > timeout: - raise Exception("wait_dhcp timeout") - time.sleep(1) - except Exception as e: - return False - return True - - -def wait_sdk(sdk_fpath, timeout): - time_cnt = 0 - while True: - try: - if os.path.exists(sdk_fpath): - break - else: - sys.stdout.write(".") - sys.stdout.flush() - time_cnt = time_cnt + 1 - if time_cnt > timeout: - raise Exception("wait_sdk timeout") - time.sleep(1) - except Exception as e: - return False - return True - - -def wait_docker(need_restart=False, timeout=180): - sdkcheck_params = STARTMODULE.get("sdkcheck", {}) - if sdkcheck_params.get("checktype") == "file": # pass file check - sdk_fpath = sdkcheck_params.get("sdk_fpath") - return wait_sdk(sdk_fpath, timeout) - return wait_dhcp(timeout) - - -def getTLV_BODY(type, productname): - x = [] - temp_t = "" - if type == TLV_CODE_MAC_BASE: - arr = productname.split(":") - for tt in arr: - temp_t += chr(int(tt, 16)) - elif type == TLV_CODE_DEVICE_VERSION: - temp_t = chr(productname) - elif type == TLV_CODE_MAC_SIZE: - temp_t = chr(productname >> 8) + chr(productname & 0x00FF) - else: - temp_t = productname - x.append(chr(type)) - x.append(chr(len(temp_t))) - for i in temp_t: - x.append(i) - return x - - -def _crc32(v): - return "0x%08x" % ( - binascii.crc32(v) & 0xFFFFFFFF - ) # get 8 bytes of crc32 %x return hex - - -def printvalue(b): - index = 0 - for i in range(0, len(b)): - if index % 16 == 0: - print(" ") - print("%02x " % ord(b[i])) - index += 1 - print("\n") - - -def generate_value(_t): - ret = [] - for i in TLV_INFO_ID_STRING: - ret.append(i) - ret.append(chr(TLV_INFO_VERSION)) - ret.append(chr(TLV_INFO_LENGTH)) - ret.append(chr(TLV_INFO_LENGTH_VALUE)) - - total_len = 0 - for key in _t: - x = getTLV_BODY(key, _t[key]) - ret += x - total_len += len(x) - ret[10] = chr(total_len + 6) - - ret.append(chr(0xFE)) - ret.append(chr(0x04)) - s = _crc32("".join(ret)) - for t in range(0, 4): - ret.append(chr(int(s[2 * t + 2 : 2 * t + 4], 16))) - totallen = len(ret) - if totallen < 256: - for left_t in range(0, 256 - totallen): - ret.append(chr(0x00)) - return (ret, True) - - -def getsyseeprombyId(id): - ret = get_sys_eeprom() - for item in ret: - if item["code"] == id: - return item - return None - - -def fac_init_cardidcheck(): - rest = getsyseeprombyId(TLV_CODE_RJ_CARID) # check cardId same or not - if rest is None: - print("need to program write bin file") - return False - else: - rest_v = rest["value"] - value = strtoint(rest_v) - if value == RAGILE_CARDID: - log_debug("check card ID pass") - else: - log_debug("check card ID error") - return False - return True - - -def isValidMac(mac): - if re.match(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}\s*$", mac): - return True - return False - - -# Internet cardsetmac - - -def util_setmac(eth, mac): - rulefile = "/etc/udev/rules.d/70-persistent-net.rules" - if isValidMac(mac) == False: - return False, "MAC invaild" - cmd = "ethtool -e %s | grep 0x0010 | awk '{print \"0x\"$13$12$15$14}'" % eth - ret, log = os_system(cmd) - log_debug(log) - magic = "" - if ret == 0 and len(log): - magic = log - macs = mac.upper().split(":") - - # chage ETH0 to value after setmac - ifconfigcmd = "ifconfig eth0 hw ether %s" % mac - log_debug(ifconfigcmd) - ret, status = os_system(ifconfigcmd) - if ret: - raise SETMACException("software set Internet card MAC error") - index = 0 - for item in macs: - cmd = "ethtool -E %s magic %s offset %d value 0x%s" % (eth, magic, index, item) - log_debug(cmd) - index += 1 - ret, log = os_system(cmd) - if ret != 0: - raise SETMACException("set hardware Internet card MAC error") - # get value after setting - cmd_t = "ethtool -e eth0 offset 0 length 6" - ret, log = os_system(cmd_t) - m = re.split(":", log)[-1].strip().upper() - mac_result = m.upper().split(" ") - - for ind, s in enumerate(macs): - if s != mac_result[ind]: - RJPRINTERR("MAC comparison error") - if os.path.exists(rulefile): - os.remove(rulefile) - print("MGMT MAC[%s]" % mac) - return True - - -def getInputCheck(tips): - str = raw_input(tips) - if ( - astrcmp(str, "y") - or astrcmp(str, "ye") - or astrcmp(str, "yes") - or astrcmp(str, "") - ): - return True - else: - return False - - -def getrawch(): - fd = sys.stdin.fileno() - old_settings = termios.tcgetattr(fd) - try: - tty.setraw(sys.stdin.fileno()) - ch = sys.stdin.read(1) - finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) - return ch - - -def upper_input(tips): - sys.stdout.write(tips) - sys.stdout.flush() - passwd = [] - while True: - ch = getrawch().upper() - if ch == "\r" or ch == "\n": - return "".join(passwd) - elif ch == "\b" or ord(ch) == 127: - if passwd: - del passwd[-1] - sys.stdout.write("\b \b") - else: - sys.stdout.write(ch) - passwd.append(ch) - - -def changeTypeValue(_value, type1, tips, example): - if type1 == TLV_CODE_PRODUCT_NAME: - while True: - print( - "please check (1)air from forward to backward/(2)air from backward to forward:" - ) - option = raw_input() - if option == "1": - _value[type1] = example + "-F-RJ" - print( - "check Product is air from forward to backward device,Product Name:%s" - % _value[type1] - ) - break - elif option == "2": - _value[type1] = example + "-R-RJ" - print( - "check Product is air from backward to forward device,Product Name:%s" - % _value[type1] - ) - break - else: - print("input incorrect, check please") - return True - print("Please input[%s]such as(%s):" % (tips, example)) - name = upper_input("") - if type1 == TLV_CODE_MAC_BASE: - if len(name) != 12: - raise SETMACException("MAC address length incorrect, check please") - release_mac = "" - for i in range(int(len(name) / 2)): - if i == 0: - release_mac += name[i * 2 : i * 2 + 2] - else: - release_mac += ":" + name[i * 2 : i * 2 + 2] - if isValidMac(release_mac) == True: - _value[type1] = release_mac - else: - raise SETMACException("MAC address invaild, check please") - elif type1 == TLV_CODE_DEVICE_VERSION: - if name.isdigit(): - _value[type1] = int(name) - else: - raise SETMACException("Version is not number, check please") - elif type1 == TLV_CODE_MAC_SIZE: - if name.isdigit(): - _value[type1] = int(name, 16) - else: - raise SETMACException("Version is not number, check please") - elif type1 == TLV_CODE_SERIAL_NUMBER: - if name.isalnum() == False: - raise SETMACException("Serial Number invaild string, check please") - elif len(name) != 13: - raise SETMACException("Serial Number length incorrect, check please") - else: - _value[type1] = name - elif type1 == TLV_CODE_VENDOR_EXT: - _value[type1] = name - else: - _value[type1] = name - return True - - -def astrcmp(str1, str2): - return str1.lower() == str2.lower() - - -def generate_ext(cardid): - s = "%08x" % cardid - ret = "" - for t in range(0, 4): - ret += chr(int(s[2 * t : 2 * t + 2], 16)) - ret = chr(0x01) + chr(len(ret)) + ret - return ret - - -def rgi2cget(bus, devno, address): - command_line = "i2cget -f -y %d 0x%02x 0x%02x " % (bus, devno, address) - retrytime = 6 - ret_t = "" - for i in range(retrytime): - ret, ret_t = os_system(command_line) - if ret == 0: - return True, ret_t - time.sleep(0.1) - return False, ret_t - - -def rgi2cset(bus, devno, address, byte): - command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x" % (bus, devno, address, byte) - retrytime = 6 - ret_t = "" - for i in range(retrytime): - ret, ret_t = os_system(command_line) - if ret == 0: - return True, ret_t - return False, ret_t - - -def rgpcird(pcibus, slot, fn, bar, offset): - """read pci register""" - if offset % 4 != 0: - return - filename = "/sys/bus/pci/devices/0000:%02x:%02x.%x/resource%d" % ( - int(pcibus), - int(slot), - int(fn), - int(bar), - ) - file = open(filename, "r+") - size = os.path.getsize(filename) - data = mmap.mmap(file.fileno(), size) - result = data[offset : offset + 4] - s = result[::-1] - val = 0 - for i in range(0, len(s)): - val = val << 8 | s[i] - return "0x%08x" % val - - -def rgpciwr(pcibus, slot, fn, bar, offset, data): - """write pci register""" - ret = inttostr(data, 4) - ret = str.encode(ret) - ret = ret.strip(b'\xc2') - filename = "/sys/bus/pci/devices/0000:%02x:%02x.%x/resource%d" % ( - int(pcibus), - int(slot), - int(fn), - int(bar), - ) - file = open(filename, "r+") - size = os.path.getsize(filename) - data = mmap.mmap(file.fileno(), size) - data[offset : offset + 4] = ret - result = data[offset : offset + 4] - s = result[::-1] - val = 0 - for i in range(0, len(s)): - val = val << 8 | s[i] - data.close() - - -def rgsysset(location, value): - command_line = "echo 0x%02x > %s" % (value, location) - retrytime = 6 - ret_t = "" - for i in range(retrytime): - ret, ret_t = os_system(command_line) - if ret == 0: - return True, ret_t - return False, ret_t - - -def rgi2cget_word(bus, devno, address): - command_line = "i2cget -f -y %d 0x%02x 0x%02x w" % (bus, devno, address) - retrytime = 3 - ret_t = "" - for i in range(retrytime): - ret, ret_t = os_system(command_line) - if ret == 0: - return True, ret_t - return False, ret_t - - -def rgi2cset_word(bus, devno, address, byte): - command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%x w" % (bus, devno, address, byte) - os_system(command_line) - - -def fan_setmac(): - rgi2cset( - FAN_PROTECT["bus"], - FAN_PROTECT["devno"], - FAN_PROTECT["addr"], - FAN_PROTECT["open"], - ) - rgi2cset( - FAN_PROTECT["bus"], - FAN_PROTECT["devno"], - FAN_PROTECT["addr"], - FAN_PROTECT["close"], - ) - - -def checkfansninput(fan_sn, fansntemp): - if fan_sn in fansntemp: - RJPRINTERR("exist same Serial Number,please input again") - return False - if len(fan_sn) != 13: - RJPRINTERR("Serial Number length incorrect,please input again") - return False - return True - - -# check hw version -def checkfanhwinput(hw): - if len(hw) != 4: - RJPRINTERR("hardware version length incorrect, please input again") - return False - if hw.find(".") != 1: - RJPRINTERR("hardware version incorrect, please input again") - return False - return True - - -def util_show_fanse2(fans): - formatstr = "%-8s %-20s %-20s %-20s %-20s" - print(formatstr % ("id", "Name", "hardware version", "Serial Number", "Time")) - print( - formatstr - % ("------", "---------------", "---------------", "---------------", "----") - ) - for fan in fans: - # print fan.dstatus - if fan.dstatus < 0: - print("%-8s" % ("FAN%d" % (fans.index(fan) + 1))) - RJPRINTERR(" decode e2 error") - else: - print( - formatstr - % ( - "FAN%d" % (fans.index(fan) + 1), - fan.typename.replace(chr(0x00), ""), - fan.typehwinfo.replace(chr(0x00), ""), - fan.typesn.replace(chr(0x00), ""), - fan.fandecodetime, - ) - ) - - -def get_fane2_sysfs(bus, loc): - rg_fan_e2 = "%d-%04x/fan" % (bus, loc) - eeprom = get_sysfs_value(rg_fan_e2) - return eeprom - - -def util_show_fane2(): - ret = sorted(I2CUTIL.getvaluefromdevice("rg_fan")) - if len(ret) <= 0: - return None - fans = [] - for index in range(len(ret)): - t1 = int(round(time.time() * 1000)) - eeprom = get_fane2_sysfs(ret[index]["bus"], ret[index]["loc"]) - t2 = int(round(time.time() * 1000)) - fane2 = fan_tlv() - fane2.fandecodetime = t2 - t1 - fane2.decode(eeprom) - fans.append(fane2) - util_show_fanse2(fans) - - -def getPid(name): - ret = [] - for dirname in os.listdir("/proc"): - if dirname == "curproc": - continue - try: - with open("/proc/{}/cmdline".format(dirname), mode="rb") as fd: - content = fd.read() - except Exception: - continue - if name in content: - ret.append(dirname) - return ret - - -def fac_fans_setmac_tlv(ret): - if len(ret) <= 0: - return None - fans = [] - fansntemp = [] - for index in range(len(ret)): - item = ret[index] - log_debug(item) - eeprom = get_fane2_sysfs(item["bus"], item["loc"]) - fane2 = fan_tlv() - fane2.decode(eeprom) - fane2.fanbus = item["bus"] - fane2.fanloc = item["loc"] - log_debug("decode eeprom success") - - print("Fan[%d]-[%s]setmac" % ((index + 1), FANS_DEF[fane2.typedevtype])) - while True: - print("Please input[%s]:" % "Serial Number") - fan_sn = raw_input() - if checkfansninput(fan_sn, fansntemp) == False: - continue - fansntemp.append(fan_sn) - fan_sn = fan_sn + chr(0x00) - fane2.typesn = fan_sn + chr(0x00) - break - while True: - print("Please input[%s]:" % "hardware version") - hwinfo = raw_input() - if checkfanhwinput(hwinfo) == False: - continue - fan_hwinfo = hwinfo + chr(0x00) - fane2.typehwinfo = fan_hwinfo + chr(0x00) - break - log_debug(fane2.typedevtype) - fane2.typename = FANS_DEF[fane2.typedevtype] + chr(0x00) - fans.append(fane2) - print("\n") - print("\n*******************************\n") - - util_show_fanse2(fans) - if getInputCheck("check input correctly or not(Yes/No):") == True: - for fan in fans: - log_debug("ouput fan") - fac_fan_setmac(fan) - else: - print("setmac quit") - return False - - -def fac_fan_setmac_fru(ret): - fans = FRULISTS.get("fans") - - fanfrus = {} - newfrus = {} - - # getmsg - try: - for fan in fans: - print("===============%s ================getmessage" % fan.get("name")) - eeprom = getsysvalue(I2CUTIL.getE2File(fan.get("bus"), fan.get("loc"))) - fru = ipmifru() - fru.decodeBin(eeprom) - fanfrus[fan.get("name")] = fru - except Exception as e: - print(str(e)) - return False - - # setmsg - for fan in fans: - print("===============%s ================setmac" % fan.get("name")) - fruold = fanfrus.get(fan.get("name")) - newfru = getInputSetmac(fruold) - newfru.recalcute() - newfrus[fan.get("name")] = newfru - # writemsg - for fan in fans: - print("===============%s ================writeToE2" % fan.get("name")) - ret_t = newfrus.get(fan.get("name")) - I2CUTIL.openFanE2Protect() - I2CUTIL.writeToFanE2(fan.get("bus"), fan.get("loc"), ret_t.bindata) - I2CUTIL.closeFanE2Protect() - # check - try: - for fan in fans: - print("===============%s ================getmessage" % fan.get("name")) - eeprom = getsysvalue(I2CUTIL.getE2File(fan.get("bus"), fan.get("loc"))) - fru = ipmifru() - fru.decodeBin(eeprom) - except Exception as e: - print(str(e)) - return False - return True - - -def fac_fans_setmac(): - ret = I2CUTIL.getvaluefromdevice("rg_fan") - if ret is not None and len(ret) > 0: - return fac_fans_setmac_tlv(ret) - fans = FRULISTS.get("fans", None) - if fans is not None and len(fans) > 0: - return fac_fan_setmac_fru(ret) - return False - - -def fac_fan_setmac(item): - I2CUTIL.openFanE2Protect() - I2CUTIL.writeToFanE2(item.fanbus, item.fanloc, item.generate_fan_value()) - I2CUTIL.closeFanE2Protect() - - -def writeToEEprom(rst_arr): - dealtype = E2_PROTECT.get("gettype", None) - if dealtype is None: - rgi2cset( - E2_PROTECT["bus"], - E2_PROTECT["devno"], - E2_PROTECT["addr"], - E2_PROTECT["open"], - ) - elif dealtype == "io": - io_wr(E2_PROTECT["io_addr"], E2_PROTECT["open"]) - index = 0 - for item in rst_arr: - rgi2cset(E2_LOC["bus"], E2_LOC["devno"], index, ord(item)) - index += 1 - - if dealtype is None: - rgi2cset( - E2_PROTECT["bus"], - E2_PROTECT["devno"], - E2_PROTECT["addr"], - E2_PROTECT["close"], - ) - elif dealtype == "io": - io_wr(E2_PROTECT["io_addr"], E2_PROTECT["close"]) - # deal last drivers - os.system("rmmod at24 ") - os.system("modprobe at24 ") - os.system("rm -f /var/cache/sonic/decode-syseeprom/syseeprom_cache") - - -def get_local_eth0_mac(): - cmd = "ifconfig eth0 |grep HWaddr" - print(os_system(cmd)) - - -def getonieversion(): - if not os.path.isfile("/host/machine.conf"): - return "" - machine_vars = {} - with open("/host/machine.conf") as machine_file: - for line in machine_file: - tokens = line.split("=") - if len(tokens) < 2: - continue - machine_vars[tokens[0]] = tokens[1].strip() - return machine_vars.get("onie_version") - - -def createbmcMac(cpumac, num=2): - bcmvalue = strtoint(cpumac[cpumac.rindex(":") + 1 : len(cpumac)]) + num - # bmcmac = - t = cpumac.split(":") - t[5] = "%02x" % bcmvalue - bmcmac = ":".join(t) - return bmcmac.upper() - - -def fac_board_setmac(): - _value = {} - # default value - _value[TLV_CODE_VENDOR_EXT] = generate_ext(RAGILE_CARDID) # generate id - _value[TLV_CODE_PRODUCT_NAME] = RAGILE_PRODUCTNAME - _value[TLV_CODE_PART_NUMBER] = RAGILE_PART_NUMBER - _value[TLV_CODE_LABEL_REVISION] = RAGILE_LABEL_REVISION - _value[TLV_CODE_PLATFORM_NAME] = platform - _value[TLV_CODE_ONIE_VERSION] = getonieversion() - _value[TLV_CODE_MAC_SIZE] = RAGILE_MAC_SIZE - _value[TLV_CODE_MANUF_NAME] = RAGILE_MANUF_NAME - _value[TLV_CODE_MANUF_COUNTRY] = RAGILE_MANUF_COUNTRY - _value[TLV_CODE_VENDOR_NAME] = RAGILE_VENDOR_NAME - _value[TLV_CODE_DIAG_VERSION] = RAGILE_DIAG_VERSION - _value[TLV_CODE_SERVICE_TAG] = RAGILE_SERVICE_TAG - try: - if 0x00004052 == RAGILE_CARDID: - _value[TLV_CODE_PRODUCT_NAME] = RAGILE_PRODUCTNAME + "-RJ" - elif 0x00004051 == RAGILE_CARDID or 0x00004050 == RAGILE_CARDID: - changeTypeValue( - _value, TLV_CODE_PRODUCT_NAME, "Product name", RAGILE_PRODUCTNAME - ) - - changeTypeValue( - _value, TLV_CODE_SERIAL_NUMBER, "SN", "0000000000000" - ) # add serial number - changeTypeValue( - _value, TLV_CODE_DEVICE_VERSION, "hardware version", "101" - ) # hardware version - changeTypeValue( - _value, TLV_CODE_MAC_BASE, "MAC address", "58696cfb2108" - ) # MAC address - _value[TLV_CODE_MANUF_DATE] = time.strftime( - "%m/%d/%Y %H:%M:%S", time.localtime() - ) # add setmac time - rst, ret = generate_value(_value) - if ( - util_setmac("eth0", _value[TLV_CODE_MAC_BASE]) == True - ): # set Internet cardIP - writeToEEprom(rst) # write to e2 - # set BMC MAC - if "bmcsetmac" in FACTESTMODULE and FACTESTMODULE["bmcsetmac"] == 1: - bmcmac = createbmcMac(_value[TLV_CODE_MAC_BASE]) - if ipmi_set_mac(bmcmac) == True: - print("BMC MAC[%s]" % bmcmac) - else: - print("SET BMC MAC FAILED") - return False - else: - return False - except SETMACException as e: - # print(e) - RJPRINTERR("\n\n%s\n\n" % e) - return False - except ValueError as e: - return False - return True - - -def ipmi_set_mac(mac): - macs = mac.split(":") - cmdinit = "ipmitool raw 0x0c 0x01 0x01 0xc2 0x00" - cmdset = "ipmitool raw 0x0c 0x01 0x01 0x05" - for ind in range(len(macs)): - cmdset += " 0x%02x" % int(macs[ind], 16) - os_system(cmdinit) - ret, status = os_system(cmdset) - if ret: - RJPRINTERR("\n\n%s\n\n" % status) - return False - return True - - -def getInputValue(title, tips): - print("Please input[%s]such as(%s):" % (title, tips)) - name = raw_input() - - return name - - -def bmc_setmac(): - tips = "BMC MAC" - print("Please input value you want to change[%s]:" % tips) - name = raw_input() - if len(name) != 12: - RJPRINTERR("\nMAC address invaild, try again\n") - return False - release_mac = "" - for i in range(int(len(name) / 2)): - if i == 0: - release_mac += name[i * 2 : i * 2 + 2] - else: - release_mac += ":" + name[i * 2 : i * 2 + 2] - if isValidMac(release_mac) == True: - if ipmi_set_mac(release_mac) == True: - return True - else: - RJPRINTERR("\nMAC address invaild, try again\n") - return False - - -def closeProtocol(): - # disable LLDP - log_info("disable LLDP") - sys.stdout.write(".") - sys.stdout.flush() - os_system("systemctl stop lldp.service") - log_info("disable lldp service") - sys.stdout.write(".") - sys.stdout.flush() - os_system("systemctl stop bgp.service") - log_info("disable bgp service") - sys.stdout.write(".") - sys.stdout.flush() - # ret, status = os_system('bcmcmd "port ce,xe stp=disable"') - - -# check SDK memory must be 256M - - -def checkSdkMem(): - ind = 0 - file_data = "" - with open(file_name, "r") as f: - for line in f: - if "dmasize=16M" in line: - line = line.replace("dmasize=16M", "dmasize=256M") - ind = -1 - file_data += line - if ind == 0: - return - with open(file_name, "w") as f: - f.write(file_data) - print("change SDK memory to 256, reboot required") - os_system("sync") - os_system("reboot") - - -########################################################################## -# receives a character setting -########################################################################## - - -def getch(msg): - ret = "" - fd = sys.stdin.fileno() - old_ttyinfo = termios.tcgetattr(fd) - new_ttyinfo = old_ttyinfo[:] - new_ttyinfo[3] &= ~termios.ICANON - new_ttyinfo[3] &= ~termios.ECHO - sys.stdout.write(msg) - sys.stdout.flush() - try: - termios.tcsetattr(fd, termios.TCSANOW, new_ttyinfo) - ret = os.read(fd, 1) - finally: - # print "try to setting" - termios.tcsetattr(fd, termios.TCSANOW, old_ttyinfo) - return ret - - -def get_raw_input(): - ret = "" - fd = sys.stdin.fileno() - old_ttyinfo = termios.tcgetattr(fd) - new_ttyinfo = old_ttyinfo[:] - new_ttyinfo[3] &= ~termios.ICANON - new_ttyinfo[3] &= ~termios.ECHO - try: - termios.tcsetattr(fd, termios.TCSANOW, new_ttyinfo) - ret = raw_input("") - except Exception as e: - print(e) - finally: - termios.tcsetattr(fd, termios.TCSANOW, old_ttyinfo) - return ret - - -def getsysvalue(location): - retval = None - mb_reg_file = location - if not os.path.isfile(mb_reg_file): - print(mb_reg_file, "not found !") - return retval - try: - if not os.path.isfile(mb_reg_file): - print(mb_reg_file, "not found !") - return retval - with open(mb_reg_file, "r") as fd: - retval = fd.read() - except Exception as error: - log_error("Unable to open " + mb_reg_file + "file !") - retval = retval.rstrip("\r\n") - retval = retval.lstrip(" ") - # log_debug(retval) - return retval - - -# get file value - - -def get_pmc_register(reg_name): - retval = "ERR" - mb_reg_file = MAILBOX_DIR + reg_name - filepath = glob.glob(mb_reg_file) - if len(filepath) == 0: - return "%s %s notfound" % (retval, mb_reg_file) - mb_reg_file = filepath[0] - if not os.path.isfile(mb_reg_file): - return "%s %s notfound" % (retval, mb_reg_file) - try: - with open(mb_reg_file, "r") as fd: - retval = fd.read() - except Exception as error: - pass - retval = retval.rstrip("\r\n") - retval = retval.lstrip(" ") - return retval - - -# decode EEPROM - - -def decoder(s, t): - if ord(t[0]) == TLV_CODE_PRODUCT_NAME: - name = "Product Name" - value = str(t[2 : 2 + ord(t[1])]) - elif ord(t[0]) == TLV_CODE_PART_NUMBER: - name = "Part Number" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_SERIAL_NUMBER: - name = "Serial Number" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_MAC_BASE: - name = "Base MAC Address" - value = ":".join([binascii.b2a_hex(T) for T in t[2:8]]).upper() - elif ord(t[0]) == TLV_CODE_MANUF_DATE: - name = "Manufacture Date" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_DEVICE_VERSION: - name = "Device Version" - value = str(ord(t[2])) - elif ord(t[0]) == TLV_CODE_LABEL_REVISION: - name = "Label Revision" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_PLATFORM_NAME: - name = "Platform Name" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_ONIE_VERSION: - name = "ONIE Version" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_MAC_SIZE: - name = "MAC Addresses" - value = str((ord(t[2]) << 8) | ord(t[3])) - elif ord(t[0]) == TLV_CODE_MANUF_NAME: - name = "Manufacturer" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_MANUF_COUNTRY: - name = "Manufacture Country" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_VENDOR_NAME: - name = "Vendor Name" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_DIAG_VERSION: - name = "Diag Version" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_SERVICE_TAG: - name = "Service Tag" - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_VENDOR_EXT: - name = "Vendor Extension" - value = "" - if _TLV_DISPLAY_VENDOR_EXT: - value = t[2 : 2 + ord(t[1])] - elif ord(t[0]) == TLV_CODE_CRC_32 and len(t) == 6: - name = "CRC-32" - value = "0x%08X" % ( - ((ord(t[2]) << 24) | (ord(t[3]) << 16) | (ord(t[4]) << 8) | ord(t[5])), - ) - elif ord(t[0]) == TLV_CODE_RJ_CARID: - name = "rj_cardid" - value = "" - for c in t[2 : 2 + ord(t[1])]: - value += "%02X" % (ord(c),) - else: - name = "Unknown" - value = "" - for c in t[2 : 2 + ord(t[1])]: - value += "0x%02X " % (ord(c),) - return {"name": name, "code": ord(t[0]), "value": value} - - -def decode_eeprom(e): - total_len = (ord(e[9]) << 8) | ord(e[10]) - tlv_index = _TLV_INFO_HDR_LEN - tlv_end = _TLV_INFO_HDR_LEN + total_len - ret = [] - while (tlv_index + 2) < len(e) and tlv_index < tlv_end: - rt = decoder(None, e[tlv_index : tlv_index + 2 + ord(e[tlv_index + 1])]) - ret.append(rt) - if ord(e[tlv_index]) == TLV_CODE_CRC_32: - break - tlv_index += ord(e[tlv_index + 1]) + 2 - for item in ret: - if item["code"] == TLV_CODE_VENDOR_EXT: - rt = decoder(None, item["value"][0 : 0 + 2 + ord(item["value"][0 + 1])]) - ret.append(rt) - return ret - - -def get_sys_eeprom(): - eeprom = get_sysfs_value(rg_eeprom) - return decode_eeprom(eeprom) - - -# get card ID -def getCardId(): - ret = get_sys_eeprom() - for item in ret: - if item["code"] == TLV_CODE_RJ_CARID: - return item.get("value", None) - return None - - -# ==================================== -# execute shell command -# ==================================== -def os_system(cmd): - status, output = commands.getstatusoutput(cmd) - return status, output - - -########################################### -# get memory slot and number via DMI command -########################################### -def getsysmeminfo(): - ret, log = os_system("which dmidecode ") - if ret != 0 or len(log) <= 0: - error = "cmd find dmidecode" - return False, error - cmd = log + '|grep -P -A5 "Memory\s+Device"|grep Size|grep -v Range' - # get total number first - result = [] - ret1, log1 = os_system(cmd) - if ret1 == 0 and len(log1): - log1 = log1.lstrip() - arr = log1.split("\n") - # total = len(arr) # total slot number - for i in range(len(arr)): - val = re.sub("\D", "", arr[i]) - if val == "": - val = arr[i].lstrip() - val = re.sub("Size:", "", val).lstrip() - # print val - result.append({"slot": i + 1, "size": val}) - return True, result - return False, "error" - - -########################################### -# get memory slot and number via DMI command -# return various arrays -########################################### -def getsysmeminfo_detail(): - ret, log = os_system("which dmidecode ") - if ret != 0 or len(log) <= 0: - error = "cmd find dmidecode" - return False, error - cmd = log + ' -t 17 | grep -A21 "Memory Device"' # 17 - # get total number - ret1, log1 = os_system(cmd) - if ret1 != 0 or len(log1) <= 0: - return False, "command execution error[%s]" % cmd - result_t = log1.split("--") - mem_rets = [] - for item in result_t: - its = item.replace("\t", "").strip().split("\n") - ret = {} - for it in its: - if ":" in it: - key = it.split(":")[0].lstrip() - value = it.split(":")[1].lstrip() - ret[key] = value - mem_rets.append(ret) - return True, mem_rets - - -########################################### -# get BIOS info via DMI command -########################################### -def getDmiSysByType(type_t): - ret, log = os_system("which dmidecode ") - if ret != 0 or len(log) <= 0: - error = "cmd find dmidecode" - return False, error - cmd = log + " -t %s" % type_t - # get total number - ret1, log1 = os_system(cmd) - if ret1 != 0 or len(log1) <= 0: - return False, "command execution error[%s]" % cmd - its = log1.replace("\t", "").strip().split("\n") - ret = {} - for it in its: - if ":" in it: - key = it.split(":")[0].lstrip() - value = it.split(":")[1].lstrip() - ret[key] = value - return True, ret - - -def gethwsys(): - return getDmiSysByType(1) - - -########################################### -# get BIOS info via DMI command - - -def getsysbios(): - return getDmiSysByType(0) - - -def searchDirByName(name, dir): - result = [] - try: - files = os.listdir(dir) - for file in files: - if name in file: - result.append(os.path.join(dir, file)) - except Exception as e: - pass - return result - - -def getUsbLocation(): - dir = "/sys/block/" - spect = "sd" - usbpath = "" - result = searchDirByName(spect, dir) - if len(result) <= 0: - return False - for item in result: - with open(os.path.join(item, "removable"), "r") as fd: - value = fd.read() - if value.strip() == "1": # U-Disk found - usbpath = item - break - if usbpath == "": # no U-Disk found - log_debug("no usb found") - return False, usbpath - return True, usbpath - - -# judge USB file -def getusbinfo(): - ret, path = getUsbLocation() - if ret == False: - return False, "not usb exists" - str = os.path.join(path, "size") - ret, value = getfilevalue(str) - if ret == True: - return ( - True, - { - "id": os.path.basename(path), - "size": float(value) * 512 / 1024 / 1024 / 1024, - }, - ) - else: - return False, "Err" - - -def get_cpu_info(): - cmd = "cat /proc/cpuinfo |grep processor -A18" # 17 - - ret, log1 = os_system(cmd) - if ret != 0 or len(log1) <= 0: - return False, "command execution error[%s]" % cmd - result_t = log1.split("--") - mem_rets = [] - for item in result_t: - its = item.replace("\t", "").strip().split("\n") - ret = {} - for it in its: - if ":" in it: - key = it.split(":")[0].lstrip() - value = it.split(":")[1].lstrip() - ret[key] = value - mem_rets.append(ret) - return True, mem_rets - - -# read file -def get_version_config_info(attr_key, file_name=None): - if file_name is None: - version_conf_filename = "/root/version.json" - else: - version_conf_filename = file_name - if not os.path.isfile(version_conf_filename): - return None - with open(version_conf_filename) as rjconf_file: - for line in rjconf_file: - tokens = line.split("=") - if len(tokens) < 2: - continue - if tokens[0] == attr_key: - return tokens[1].strip() - return None - - -def io_rd(reg_addr, size=1): - path = "/dev/port" - ret = "" - fd = None - try: - reg_addr = int(reg_addr) - fd = os.open(path, os.O_RDWR|os.O_CREAT) - for i in range(size): - os.lseek(fd, reg_addr+i, os.SEEK_SET) - ret+="{:02x}".format(ord(os.read(fd, 1).decode('latin-1'))) - return ret - except Exception as e: - print(str(e)) - return None - finally: - if fd: os.close(fd) - - -def io_wr(reg_addr, reg_data): - u"""io write""" - fd = None - try: - regdata = 0 - regaddr = 0 - if type(reg_addr) == int: - regaddr = reg_addr - else: - regaddr = int(reg_addr, 16) - if type(reg_data) == int: - regdata = reg_data - else: - regdata = int(reg_data, 16) - devfile = "/dev/port" - fd = os.open(devfile, os.O_RDWR | os.O_CREAT) - os.lseek(fd, regaddr, os.SEEK_SET) - os.write(fd, regdata.to_bytes(2, 'little')) - return True - except ValueError as e: - print(e) - return False - except Exception as e: - print(e) - return False - finally: - if fd: os.close(fd) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_cause.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_cause.py new file mode 100755 index 000000000000..2f125c5084c2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_cause.py @@ -0,0 +1,183 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- +import sys +import os +import time +import syslog +from platform_util import get_value, set_value, exec_os_cmd, wb_os_system +from platform_config import REBOOT_CAUSE_PARA + +REBOOT_CAUSE_DEBUG_FILE = "/etc/.reboot_cause_debug" +REBOOT_CAUSE_STARTED_FLAG = "/tmp/.reboot_cause_started_flag" + +debuglevel = 0 + + +def record_syslog_debug(s): + if debuglevel: + syslog.openlog("REBOOT_CAUSE_DEBUG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def record_syslog(s): + syslog.openlog("REBOOT_CAUSE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +class RebootCause(): + def __init__(self): + self.reboot_cause_para = REBOOT_CAUSE_PARA.copy() + self.reboot_cause_list = self.reboot_cause_para.get('reboot_cause_list', None) + self.other_reboot_cause_record = self.reboot_cause_para.get('other_reboot_cause_record', None) + + def debug_init(self): + global debuglevel + if os.path.exists(REBOOT_CAUSE_DEBUG_FILE): + debuglevel = 1 + else: + debuglevel = 0 + + def monitor_point_check(self, item): + try: + gettype = item.get('gettype', None) + okval = item.get('okval', None) + compare_mode = item.get('compare_mode', "equal") + ret, value = get_value(item) + if ret is True: + if compare_mode == "equal": + if value == okval: + return True + elif compare_mode == "great": + if value > okval: + return True + elif compare_mode == "ignore": + return True + else: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: compare_mode %s not match error.' % (compare_mode)) + else: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: base point check type:%s not support.' % gettype) + except Exception as e: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: base point check error. msg: %s.' % (str(e))) + return False + + def reboot_cause_record(self, item_list): + RET = {"RETURN_KEY1": 0} + try: + for item in item_list: + record_type = item.get('record_type', None) + if record_type == 'file': + file_mode = item.get('mode', None) + file_log = item.get('log', None) + file_path = item.get('path', None) + file_max_size = item.get('file_max_size', 0) + + if file_path is None: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: record type is file, but path is none.') + continue + + if file_max_size > 0: + file_size = 0 + if os.path.exists(file_path): + file_size = os.path.getsize(file_path) // file_max_size + if file_size >= 1: + reocrd_cmd = "mv %s %s_bak" % (file_path, file_path) + status, output = exec_os_cmd(reocrd_cmd) + if status: + record_syslog( + '%%REBOOT_CAUSE-3-EXCEPTION: exec cmd %s failed, %s' % + (reocrd_cmd, output)) + + if file_mode == 'cover': + operate_cmd = ">" + elif file_mode == 'add': + operate_cmd = ">>" + else: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: file record mode:%s not support.' % file_mode) + continue + + create_dir = "mkdir -p %s" % os.path.dirname(file_path) + status, ret_t = wb_os_system(create_dir) + if status != 0: + RET["RETURN_KEY1"] = -1 + record_syslog( + '%%REBOOT_CAUSE-3-EXCEPTION: create %s failed, msg: %s' % + (os.path.dirname(file_path), ret_t)) + continue + + status, date = wb_os_system("date") + if status != 0 or len(date) == 0: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: get date failed.') + continue + + reocrd_cmd = "echo %s %s %s %s" % (file_log, date, operate_cmd, file_path) + status, ret_t = wb_os_system(reocrd_cmd) + if status != 0: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: get date failed, msg: %s' % ret_t) + continue + wb_os_system('sync') + else: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: record_type:%s not support.' % record_type) + continue + except Exception as e: + RET["RETURN_KEY1"] = -1 + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: reboot cause record error. msg: %s.' % (str(e))) + if RET["RETURN_KEY1"] == 0: + return True + return False + + def reboot_cause_check(self): + try: + reboot_cause_flag = False + if self.reboot_cause_list is None: + record_syslog_debug('%%REBOOT_CAUSE-6-DEBUG: reboot cause check config not found') + return + for item in self.reboot_cause_list: + name = item.get('name', None) + monitor_point = item.get('monitor_point', None) + record = item.get('record', None) + finish_operation_list = item.get('finish_operation', []) + if name is None or monitor_point is None or record is None: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: reboot cause check get config failed.name:%s, monitor_point:%s, record:%s' % + (name, monitor_point, record)) + return + ret = self.monitor_point_check(monitor_point) + if ret is True: + record_syslog_debug('%%REBOOT_CAUSE-6-DEBUG: %s reboot cause is happen' % name) + self.reboot_cause_record(record) + reboot_cause_flag = True + for finish_operation_item in finish_operation_list: + ret, log = set_value(finish_operation_item) + if ret is False: + log = "%%REBOOT_CAUSE-3-EXCEPTION: " + log + record_syslog(log) + + if reboot_cause_flag is False and self.other_reboot_cause_record is not None: + record_syslog_debug('%%REBOOT_CAUSE-6-DEBUG: other reboot cause is happen') + self.reboot_cause_record(self.other_reboot_cause_record) + except Exception as e: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: reboot cause check error. msg: %s.' % (str(e))) + return + + def run(self): + try: + self.debug_init() + if os.path.exists(REBOOT_CAUSE_STARTED_FLAG): + record_syslog_debug( + '%%REBOOT_CAUSE-6-DEBUG: Reboot cause has been started and will not be started again') + sys.exit(0) + self.reboot_cause_check() + wb_os_system("touch %s" % REBOOT_CAUSE_STARTED_FLAG) + wb_os_system("sync") + time.sleep(5) + sys.exit(0) + except Exception as e: + record_syslog('%%REBOOT_CAUSE-3-EXCEPTION: %s.' % (str(e))) + + +if __name__ == '__main__': + reboot_cause = RebootCause() + reboot_cause.run() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_ctrl.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_ctrl.py new file mode 100755 index 000000000000..17d3f5902b9d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/reboot_ctrl.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import time +import syslog +import click +from platform_util import write_sysfs, wbi2cset, io_wr, wbi2csetWord +from platform_config import REBOOT_CTRL_PARAM + + +REBOOTCTLDEBUG = 0 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def rebootctrlwarning(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("REBOOTCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def rebootctrlcritical(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("REBOOTCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def rebootctrlerror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("REBOOTCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def rebootctrldebug(s): + # s = s.decode('utf-8').encode('gb2312') + if REBOOTCTLDEBUG == 1: + syslog.openlog("REBOOTCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +class RebootCtrl(): + def __init__(self): + self.config = REBOOT_CTRL_PARAM.copy() + + def set_value(self, config, val): + way = config.get("gettype") + if way == 'sysfs': + loc = config.get("loc") + value = config.get(val) + rebootctrldebug("sysfs type.loc:0x%x, value:0x%x" % (loc, value)) + return write_sysfs(loc, "0x%02x" % value) + if way == "i2c": + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + value = config.get(val) + rebootctrldebug("i2c type.bus:0x%x, addr:0x%x, offset:0x%x, value:0x%x" % (bus, addr, offset, value)) + return wbi2cset(bus, addr, offset, value) + if way == "io": + io_addr = config.get('io_addr') + value = config.get(val) + rebootctrldebug("io type.io_addr:0x%x, value:0x%x" % (io_addr, value)) + ret = io_wr(io_addr, value) + if ret is not True: + return False, ("write 0x%x failed" % io_addr) + return True, ("write 0x%x success" % io_addr) + if way == 'i2cword': + bus = config.get("bus") + addr = config.get("loc") + offset = config.get("offset") + value = config.get(val) + rebootctrldebug("i2cword type.bus:0x%x, addr:0x%x, offset:0x%x, value:0x%x" % (bus, addr, offset, value)) + return wbi2csetWord(bus, addr, offset, value) + return False, "unsupport way: %s" % way + + def reset_operate(self, config): + ret, log = self.set_value(config, "rst_val") + rst_delay = config.get("rst_delay", 0) + time.sleep(rst_delay) + return ret, log + + def unlock_reset_operate(self, config): + ret, log = self.set_value(config, "unlock_rst_val") + unlock_rst_delay = config.get("unlock_rst_delay", 0) + time.sleep(unlock_rst_delay) + return ret, log + + def do_rebootctrl(self, option): + if self.config is None: + rebootctrlerror("Reset failed, REBOOT_CTRL_PARAM cfg get failed.") + return + try: + name_conf = self.config.get(option, None) + if name_conf is None: + print("Reset %s not support" % option) + return + try: + click.confirm("Are you sure you want to reset " + option + "?", + default=False, abort=True, show_default=True) + except Exception as e: + print("Aborted, msg: %s" % str(e)) + return + print("Reset %s start" % option) + ret, log = self.reset_operate(name_conf) + if ret is False: + rebootctrlerror(log) + print("Reset %s failed" % option) + return + if "unlock_rst_val" in name_conf: + ret, log = self.unlock_reset_operate(name_conf) + if ret is False: + rebootctrlerror(log) + print("%s unlock reset failed" % option) + return + print("Reset %s success" % option) + except Exception: + rebootctrlerror("do_rebootctrl Exception error") + return + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''reboot_ctrl reset [option]''' + + +@main.command() +@click.argument('option', required=True) +def reset(option): + '''reset device''' + rebootctrldebug("reboot ctrl option %s" % option) + rebootctrl = RebootCtrl() + rebootctrl.do_rebootctrl(option) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/sensors b/platform/broadcom/sonic-platform-modules-ragile/common/script/sensors new file mode 100755 index 000000000000..a2c72b123a43 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +#docker exec -i pmon sensors "$@" + + +#To probe sensors not part of lm-sensors +if [ -r /usr/local/bin/platform_sensors.py ]; then + python /usr/local/bin/platform_sensors.py +fi diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/sfp_highest_temperatue.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/sfp_highest_temperatue.py new file mode 100755 index 000000000000..4dd98f3a36b3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/sfp_highest_temperatue.py @@ -0,0 +1,148 @@ +#!/usr/bin/python3 +import os +import importlib.machinery +import time +import syslog +import subprocess +import fcntl + +sfp_temperature_file = "/tmp/highest_sff_temp" + +SFP_TEMP_DEBUG_FILE = "/etc/.sfp_temp_debug_flag" +SFP_TEMP_RECORD_DEBUG = 1 +SFP_TEMP_RECORD_ERROR = 2 +debuglevel = 0 + + +def sfp_temp_debug(s): + if SFP_TEMP_RECORD_DEBUG & debuglevel: + syslog.openlog("SFP_TEMP_DEBUG", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def sfp_temp_error(s): + if SFP_TEMP_RECORD_ERROR & debuglevel: + syslog.openlog("SFP_TEMP_ERROR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +pidfile = None + + +def file_rw_lock(): + global pidfile + pidfile = open(sfp_temperature_file, "r") + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + sfp_temp_debug("file lock success") + return True + except Exception: + if pidfile is not None: + pidfile.close() + pidfile = None + return False + + +def file_rw_unlock(): + try: + global pidfile + + if pidfile is not None: + fcntl.flock(pidfile, fcntl.LOCK_UN) + pidfile.close() + pidfile = None + sfp_temp_debug("file unlock success") + else: + sfp_temp_debug("pidfile is invalid, do nothing") + return True + except Exception as e: + sfp_temp_error("file unlock err, msg:%s" % (str(e))) + return False + + +def get_sfp_highest_temperature(): + highest_temperature = 0 + platform_sfputil = None + + sfputil_dir = "/usr/share/sonic/device/" + try: + if not os.path.exists(sfputil_dir): + sfputil_dir = "/usr/share/sonic/platform/" + sfputil_path = sfputil_dir + "/plugins/sfputil.py" + else: + cmd = "cat /host/machine.conf | grep onie_build_platform" + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) + + onie_platform = output.split("=")[1] + sfputil_path = sfputil_dir + onie_platform + "/plugins/sfputil.py" + + module = importlib.machinery.SourceFileLoader("sfputil", sfputil_path).load_module() + platform_sfputil_class = getattr(module, "SfpUtil") + platform_sfputil = platform_sfputil_class() + + temperature = platform_sfputil.get_highest_temperature() + highest_temperature = int(temperature) * 1000 + except Exception as e: + sfp_temp_error("get sfp temperature error, msg:%s" % str(e)) + highest_temperature = -9999000 + + return highest_temperature + + +def write_sfp_highest_temperature(temperature): + + loop = 1000 + ret = False + try: + if os.path.exists(sfp_temperature_file) is False: + with open(sfp_temperature_file, 'w') as sfp_f: + pass + for i in range(0, loop): + ret = file_rw_lock() + if ret is True: + break + time.sleep(0.001) + + if ret is False: + sfp_temp_error("take file lock timeout") + return + + with open(sfp_temperature_file, 'w') as sfp_f: + sfp_f.write("%s\n" % str(temperature)) + + file_rw_unlock() + return + except Exception as e: + sfp_temp_error("write sfp temperature error, msg:%s" % str(e)) + file_rw_unlock() + return + + +def debug_init(): + global debuglevel + + try: + with open(SFP_TEMP_DEBUG_FILE, "r") as fd: + value = fd.read() + debuglevel = int(value) + except Exception: + debuglevel = 0 + + +def main(): + while True: + debug_init() + temperature = 0 + try: + temperature = get_sfp_highest_temperature() + write_sfp_highest_temperature(temperature) + except Exception as e: + sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) + write_sfp_highest_temperature(-9999000) + time.sleep(5) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/slot_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/slot_monitor.py new file mode 100755 index 000000000000..b8b774c8b726 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/slot_monitor.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import time +import syslog +import traceback +import operator +import click +from platform_config import SLOT_MONITOR_PARAM, MONITOR_DEV_STATUS_DECODE +from platform_util import io_rd, io_wr, wbi2cget, wbi2cset + + +SLOTMONITORDEBUG = 0 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def slotwarninglog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def slotcriticallog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def sloterror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def slotinfo(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_INFO, s) + + +def slotdebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if SLOTMONITORDEBUG == 1: + syslog.openlog("SLOTMONITOR", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +class SlotMonitor(): + def __init__(self): + self.preSlotStatus = [] + + def checkslot(self, ret): + slots_conf = SLOT_MONITOR_PARAM.get('slots', None) + slotpresent = MONITOR_DEV_STATUS_DECODE.get('slotpresent', None) + + if slots_conf is None or slotpresent is None: + return False + for item_slot in slots_conf: + totalerr = 0 + try: + ret_t = {} + ret_t["id"] = item_slot.get('name') + ret_t["status"] = "" + presentattr = item_slot.get('present') + gettype = presentattr.get('gettype') + presentbit = presentattr.get('presentbit') + if gettype == "io": + io_addr = presentattr.get('io_addr') + val = io_rd(io_addr) + if val is not None: + retval = val + else: + totalerr -= 1 + sloterror(" %s %s" % (item_slot.get('name'), "lpc read failed")) + else: + bus = presentattr.get('bus') + loc = presentattr.get('loc') + offset = presentattr.get('offset') + ind, val = wbi2cget(bus, loc, offset) + if ind is True: + retval = val + else: + totalerr -= 1 + sloterror(" %s %s" % (item_slot.get('name'), "i2c read failed")) + if totalerr < 0: + ret_t["status"] = "NOT OK" + ret.append(ret_t) + continue + val_t = (int(retval, 16) & (1 << presentbit)) >> presentbit + slotdebuglog("%s present:%s" % (item_slot.get('name'), slotpresent.get(val_t))) + if val_t != slotpresent.get('okval'): + ret_t["status"] = "ABSENT" + else: + ret_t["status"] = "PRESENT" + except Exception as e: + ret_t["status"] = "NOT OK" + totalerr -= 1 + sloterror("checkslot error") + sloterror(str(e)) + ret.append(ret_t) + return True + + def dealslotplugin(self, name): + slotdebuglog("enter dealslotplugin %s" % name) + # wait for slot stable + time.sleep(5) + slots_conf = SLOT_MONITOR_PARAM.get('slots', None) + if slots_conf is None: + return False + for item_slot in slots_conf: + try: + slotdebuglog("name %s, item_slot.get('name') %s" % (name, item_slot.get('name'))) + if name == item_slot.get('name'): + actattr = item_slot.get('act') + for item_act in actattr: + gettype = item_act.get('gettype') + if gettype == "io": + io_addr = item_act.get('io_addr') + value = item_act.get('value') + mask = item_act.get('mask') + val = io_rd(io_addr) + if val is None: + sloterror(" %s %s" % (name, "lpc read failed")) + continue + set_val = (int(val, 16) & mask) | value + ret = io_wr(io_addr, set_val) + if ret is not True: + sloterror(" %s %s" % (name, "lpc write failed")) + continue + slotdebuglog("io set io_addr:0x%x value:0x%x success" % (io_addr, set_val)) + elif gettype == "i2c": + bus = item_act.get('bus') + loc = item_act.get('loc') + offset = item_act.get('offset') + value = item_act.get('value') + ret, log = wbi2cset(bus, loc, offset, value) + if ret is not True: + sloterror(" %s %s %s" % (name, "i2c write failed", log)) + continue + slotdebuglog( + "i2c set bus:%d loc:0x%x offset:0x%x value:0x%x success" % + (bus, loc, offset, value)) + else: + sloterror("gettype error") + break + except Exception as e: + sloterror("dealslotplugin failed") + sloterror(str(e)) + return False + return True + + def updateSlotStatus(self): + ''' + Only two status: PRESENT and ABSENT + ''' + curSlotStatus = [] + self.checkslot(curSlotStatus) + slotdebuglog('curSlotStatus: {}\n preSlotStatus: {}'.format(curSlotStatus, self.preSlotStatus)) + if operator.eq(self.preSlotStatus, curSlotStatus) is False: + if len(self.preSlotStatus) == 0: + # first time + for i, item in enumerate(curSlotStatus): + if item['status'] == 'PRESENT': + slotdebuglog('SLOT_PLUG_IN: %s' % (item['id'])) + elif item['status'] == 'ABSENT': + slotdebuglog('SLOT_ABSENT: %s' % (item['id'])) + else: + slotdebuglog('SLOT_FAILED: %s status %s not support yet' % (item['id'], item['status'])) + self.preSlotStatus.append(item) + else: + for i, item in enumerate(curSlotStatus): + if item['status'] == self.preSlotStatus[i]['status']: + continue + if item['status'] == 'PRESENT' and self.preSlotStatus[i]['status'] == 'ABSENT': + self.dealslotplugin(item['id']) + slotinfo('SLOT_PLUG_IN: %s' % (item['id'])) + elif item['status'] == 'ABSENT' and self.preSlotStatus[i]['status'] == 'PRESENT': + slotwarninglog('SLOT_PLUG_OUT: %s' % (item['id'])) + else: + slotwarninglog('SLOT_PLUG_OUT: %s status change from %s to %s not support' % + (item['id'], self.preSlotStatus[i]['status'], item['status'])) + self.preSlotStatus.remove(self.preSlotStatus[i]) + self.preSlotStatus.insert(i, item) + + def slotmonitor(self): + self.updateSlotStatus() + return 0 + + +def doSlotMonitor(slotMonitor): + slotMonitor.slotmonitor() + + +def run(interval, slotMonitor): + # slotMonitor.devattrinit() + while True: + try: + doSlotMonitor(slotMonitor) + except Exception as e: + traceback.print_exc() + sloterror(str(e)) + time.sleep(interval) + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''slot monitor operator''' + + +@main.command() +def start(): + '''start slot monitor''' + slotinfo("slot_monitor start") + slotMonitor = SlotMonitor() + interval = SLOT_MONITOR_PARAM.get('polling_time', 1) + run(interval, slotMonitor) + + +@main.command() +def stop(): + '''stop slot monitor ''' + slotinfo("stop") + + +# device_i2c operation +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/ssdmon b/platform/broadcom/sonic-platform-modules-ragile/common/script/ssdmon new file mode 100755 index 000000000000..4290b0a68725 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/ssdmon @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +# +# ssdmon +# +# Command-line utility to check SSD health and parameters +# + +try: + import argparse + import os + import sys + + from sonic_py_common import device_info, logger +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +DEFAULT_DEVICE = "/dev/sda" +SYSLOG_IDENTIFIER = "ssdmon" + +# Global logger instance +log = logger.Logger(SYSLOG_IDENTIFIER) + +def import_ssd_api(diskdev): + """ + Loads platform specific or generic ssd_mon module from source + Raises an ImportError exception if none of above available + + Returns: + Instance of the class with SSD API implementation (vendor or generic) + """ + + # try to load platform specific module + try: + platform_path, _ = device_info.get_paths_to_platform_and_hwsku_dirs() + platform_plugins_path = os.path.join(platform_path, "plugins") + sys.path.append(os.path.abspath(platform_plugins_path)) + from ssd_util import SsdUtil + except ImportError as e: + log.log_warning("Platform specific SsdMon module not found.") + + return SsdUtil(diskdev) + +def is_number(s): + try: + float(s) + return True + except ValueError: + return False + +# ==================== Entry point ==================== +def ssdmon(): + if os.geteuid() != 0: + print("Root privileges are required for this operation") + sys.exit(1) + + parser = argparse.ArgumentParser() + parser.add_argument("-d", "--device", help="Device name to show health info", default=DEFAULT_DEVICE) + parser.add_argument("-t", "--temperature", action="store_true", default=False, help="Show only temperature") + parser.add_argument("-j", "--health", action="store_true", default=False, help="Show only health") + + args = parser.parse_args() + + ssd = import_ssd_api(args.device) + + if args.temperature: + print(ssd.get_temperature()) + return + + if args.health: + print(ssd.get_health()) + return + + print("Device Model : {}".format(ssd.get_model())) + print("Firmware : {}".format(ssd.get_firmware())) + print("Serial : {}".format(ssd.get_serial())) + print("Health : {}{}".format(ssd.get_health(), "%" if is_number(ssd.get_health()) else "")) + print("Remain Life : {}{}".format(ssd.get_remaining_life(), "%" if is_number(ssd.get_remaining_life()) else "")) + print("Temperature : {}{}".format(ssd.get_temperature(), "C" if is_number(ssd.get_temperature()) else "")) + print("SATA Rate : {}".format(ssd.get_sata_rate())) + +if __name__ == '__main__': + ssdmon() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/tty_console.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/tty_console.py new file mode 100755 index 000000000000..4fae02f5128e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/tty_console.py @@ -0,0 +1,91 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +import logging.handlers +import subprocess +import shlex +import time +import sys +import os +from platform_util import CompressedRotatingFileHandler, exec_os_cmd + +console_file = "/dev/ttyS1" +console_logfile = "/var/log/bmc-console.log" +MAX_LOG_BYTES = 20 * 1024 * 1024 +BACKUP_COUNT = 9 + +READ_SIZE = 1024 + +logger = logging.getLogger("cpu_monitor_bmc") +logger.setLevel(logging.DEBUG) +fh = CompressedRotatingFileHandler( + console_logfile, + mode='a', + maxBytes=MAX_LOG_BYTES, + backupCount=BACKUP_COUNT, + encoding=None, + delay=0) +fh.setLevel(logging.DEBUG) + +formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") +fh.setFormatter(formatter) +logger.addHandler(fh) + + +def tty_system_cmd(cmd, print_log=True): + if print_log: + logger.debug("command: %s", cmd) + status, output = exec_os_cmd(cmd) + logger.debug("command status %s", status) + logger.debug("command output:\n%s", output) + else: + status, output = exec_os_cmd(cmd) + return status, output + + +if __name__ == '__main__': + try_times = 0 + while try_times < 3: + try_times = try_times + 1 + ret, log = tty_system_cmd("stty -F /dev/ttyS1 | grep 115200", True) + if len(log) != 0 and "115200" in log: + break + tty_system_cmd("stty -F /dev/ttyS1 115200", True) + if try_times > 1: + logger.error("The %d time try to set SONiC /dev/ttyS1 115200", try_times) + + if not os.path.exists(console_file): + logger.error("device %s not exist", console_file) + sys.exit(1) + + nopen = 3 + while nopen > 0: + try: + console_fd = os.open(console_file, os.O_RDONLY) + break + except Exception as e: + logger.error(e) + logger.error("open %s failed", console_file) + nopen = nopen - 1 + time.sleep(1) + if nopen == 0: + sys.exit(1) + + try: + tmp_read = "" + while True: + dev_read = os.read(console_fd, READ_SIZE) + dev_read = str(dev_read, encoding='utf-8') + if len(dev_read) == 1 and dev_read == "\n": + continue + if dev_read[len(dev_read) - 1] == '\n': + tmp_read = tmp_read + dev_read[0:(len(dev_read) - 1)] + logger.info(tmp_read) + tmp_read = "" + else: + tmp_read = tmp_read + dev_read + + except Exception as e: + if console_fd is not None: + os.close(console_fd) + logger.error(e) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/upgrade.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/upgrade.py new file mode 100755 index 000000000000..f56712e471b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/upgrade.py @@ -0,0 +1,991 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import sys +import os +import time +import syslog +import signal +import click +from platform_util import get_value, set_value, exec_os_cmd, exec_os_cmd_log +from platform_config import UPGRADE_SUMMARY, WARM_UPGRADE_STARTED_FLAG +from warm_upgrade import WarmBasePlatform + + +############################# Error code defined ############################# +ERR_FW_CHECK_CPLD_UPGRADE = -601 # "Failed to check the device CPLD information" +ERR_FW_CHECK_FPGA_UPGRADE = -602 # "Failed to check the device FPGA information" +ERR_FW_MATCH_CPLD_UPGRADE = -603 # "Not found upgrade CPLD file." +ERR_FW_MATCH_FPGA_UPGRADE = -604 # "Not found upgrade FPGA file." +ERR_FW_SAMEVER_CPLD_UPGRADE = -605 # "The CPLD version in device is same" +ERR_FW_SAMEVER_FPGA_UPGRADE = -606 # "The FPGA version in device is same" +ERR_FW_DO_CPLD_UPGRADE = -607 # "Doing upgrade CPLD is failed." +ERR_FW_DO_FPGA_UPGRADE = -608 # "Doing upgrade FPGA is failed." +ERR_FW_UPGRADE = -609 # "Failed to upgrade firmware" +FIRMWARE_PROGRAM_EXEC_ERR = -610 # "Firmware program run error!" +ERR_FW_FILE_FOUND = -701 # "Failed to find upgrade file" +ERR_FW_HEAD_PARSE = -702 # "Failed to parse upgrade firmware head info" +ERR_FW_CONFIG_FOUND = -703 # "Failed to find config item" +ERR_FW_NOSUPPORT_HOT = -704 # "No support hot upgrade" +ERR_FW_CHECK_SIZE = -705 # "Failed to check file size" +ERR_FW_DEVICE_ACCESS = -706 # "Failed to access device" +ERR_FW_NO_FILE_SUCCESS = -707 # "No files were successfully upgraded" +ERR_FW_CARD_ABSENT = -708 # "The subcard not present" +ERR_FW_HEAD_CHECK = -709 # "Failed to check head info" +ERR_FW_FOOL_PROOF = -710 # "Failed to fool proof verification" +ERR_FW_RAISE_EXCEPTION = -711 # Code raise exception +ERR_FW_INVALID_PARAM = -712 # Invalid parameter +ERR_FW_UNZIP_FAILED = -713 # Unzip firmware failed + +FIRMWARE_SUCCESS = 0 +CHECK_OK = 0 + + +UPGRADE_DEBUG_FILE = "/etc/.upgrade_debug_flag" +UPGRADE_FILE_DIR = "/tmp/firmware/" + +UPGRADEDEBUG = 1 + +debuglevel = 0 + +COLD_UPGRADE = 1 +WARM_UPGRADE = 2 +TEST_UPGRADE = 3 +BMC_UPGRADE = 4 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def debug_init(): + global debuglevel + if os.path.exists(UPGRADE_DEBUG_FILE): + debuglevel = debuglevel | UPGRADEDEBUG + else: + debuglevel = debuglevel & ~(UPGRADEDEBUG) + + +def upgradewarninglog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("UPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def upgradecriticallog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("UPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def upgradeerror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("UPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def upgradedebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if UPGRADEDEBUG & debuglevel: + syslog.openlog("UPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def signal_init(): + signal.signal(signal.SIGINT, signal.SIG_IGN) # ignore ctrl+c signal + signal.signal(signal.SIGTERM, signal.SIG_IGN) # ignore kill signal + signal.signal(signal.SIGTSTP, signal.SIG_IGN) # ignore ctrl+z signal + + +class BasePlatform(): + + def __init__(self): + self.upgrade_param = UPGRADE_SUMMARY.copy() + self.devtype = self.upgrade_param.get('devtype', None) + self.max_slot_num = self.upgrade_param.get("max_slot_num", 0) + self.head_info_config = {} + self.slot_config = {} + self.cold_chain_config = {} + self.subtype = None + self.chain = None + self.filetype = None + self.DEVTYPE = None + self.SUBTYPE = '0' + self.TYPE = None + self.CHAIN = None + self.CHIPNAME = None + self.VERSION = None + self.FILETYPE = None + self.CRC = None + self.SUBTYPE_LIST = None + + def save_and_set_value(self, cfg_list): + for config in cfg_list: + ret, val = get_value(config) + if ret: + config["save_value"] = val + else: + upgradeerror(val) + return False, "get save value fail" + + set_val = config.get("set_value", None) + if set_val is None: + log = "save_and_set_value lack of set_val config" + upgradeerror(log) + return log + + gettype = config.get("gettype", None) + set_cmd = config.get("set_cmd", None) + if gettype == "cmd": + if set_cmd is None: + log = "save_and_set_value lack of set_cmd config" + upgradeerror(log) + return False, log + config["cmd"] = set_cmd % set_val + upgradedebuglog("save_and_set_value modify set cmd to %s" % config["cmd"]) + else: + config["value"] = set_val + upgradedebuglog("save_and_set_value modify set val to %s" % config["value"]) + + ret, log = set_value(config) + if ret is False: + upgradeerror(log) + return False, log + return True, "save and set value success" + + def recover_save_value(self, cfg_list): + total_err = 0 + for config in cfg_list: + upgradedebuglog("config: %s, recover save value" % config) + val = config.get("save_value", None) + if val is None: + upgradeerror("recover_save_value lack of save_value config") + total_err -= 1 + continue + gettype = config.get("gettype", None) + set_cmd = config.get("set_cmd", None) + if gettype == "cmd": + config["cmd"] = set_cmd % val + upgradedebuglog("recover_save_value modify set cmd to %s" % config["cmd"]) + else: + config["value"] = val + upgradedebuglog("recover_save_value modify set val to %s" % config["value"]) + + ret, log = set_value(config) + if ret is False: + upgradeerror("recover save value write failed, log: %s" % log) + total_err -= 1 + else: + upgradedebuglog("recover save value success") + if total_err < 0: + return False, "recover save value failed" + return True, "recover save value success" + + def check_slot_present(self, slot_present_config): + presentbit = slot_present_config.get('presentbit') + ret, value = get_value(slot_present_config) + if ret is False: + return "NOT OK" + if isinstance(value, str): + val_t = int(value, 16) + else: + val_t = value + val_t = (val_t & (1 << presentbit)) >> presentbit + if val_t != slot_present_config.get('okval'): + status = "ABSENT" + else: + status = "PRESENT" + return status + + def linecard_present_check(self, slot_present_config): + present_status = self.check_slot_present(slot_present_config) + if present_status == "NOT OK": + return ERR_FW_DEVICE_ACCESS, "get slot present status failed." + if present_status == "ABSENT": + return ERR_FW_CARD_ABSENT, "slot absent" + return CHECK_OK, "slot present" + + def subprocess_warm_upgrade(self, config, file, main_type, sub_type, slot): + dev_name = config.get("name", None) + status, output = self.subprocess_firmware_upgrade(config, file, main_type, sub_type, slot) + if status is False: + upgradeerror("%s warm upgrade failed" % dev_name) + return False, output + command = "warm_upgrade.py %s 0x%x 0x%x %s %s %s" % (file, main_type, sub_type, slot, self.filetype, self.chain) + upgradedebuglog("warm upgrade cmd: %s" % command) + if os.path.exists(UPGRADE_DEBUG_FILE): + status, output = exec_os_cmd_log(command) + else: + status, output = exec_os_cmd(command) + if status: + upgradeerror("%s warm upgrade failed" % dev_name) + return False, output + upgradedebuglog("%s warm upgrade success" % dev_name) + return True, "upgrade success" + + def do_fw_upg_init_cmd(self, dev_name, init_cmd_list): + # pre operation + try: + for init_cmd_config in init_cmd_list: + ret, log = set_value(init_cmd_config) + if ret is False: + upgradeerror("%s do init cmd: %s failed, msg: %s" % (dev_name, init_cmd_config, log)) + return False, log + msg = "%s firmware init cmd all set success" % dev_name + upgradedebuglog(msg) + return True, msg + except Exception as e: + return False, str(e) + + def do_fw_upg_finish_cmd(self, dev_name, finish_cmd_list): + # end operation + ret = 0 + for finish_cmd_config in finish_cmd_list: + ret_t, log = set_value(finish_cmd_config) + if ret_t is False: + upgradeerror("%s do finish cmd: %s failed, msg: %s" % (dev_name, finish_cmd_config, log)) + ret = -1 + if ret != 0: + msg = "%s firmware finish cmd exec failed" % dev_name + upgradeerror(msg) + return False, msg + msg = "%s firmware finish cmd all set success" % dev_name + upgradedebuglog(msg) + return True, msg + + def subprocess_firmware_upgrade(self, config, file, main_type, sub_type, slot): + dev_name = config.get("name", None) + init_cmd_list = config.get("init_cmd", []) + finish_cmd_list = config.get("finish_cmd", []) + try: + ret, log = self.do_fw_upg_init_cmd(dev_name, init_cmd_list) + if ret is False: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, log + time.sleep(0.5) # delay 0.5s after execute init_cmd + command = "firmware_upgrade %s 0x%x 0x%x %s" % (file, main_type, sub_type, slot) + upgradedebuglog("firmware upgrade cmd: %s" % command) + if os.path.exists(UPGRADE_DEBUG_FILE): + status, output = exec_os_cmd_log(command) + else: + status, output = exec_os_cmd(command) + if status: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + upgradeerror("%s firmware upgrade failed, msg: %s" % (dev_name, output)) + return False, output + upgradedebuglog("%s firmware upgrade success" % dev_name) + ret, log = self.do_fw_upg_finish_cmd(dev_name, init_cmd_list) + if ret is False: + return False, log + return True, "upgrade success" + except Exception as e: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, str(e) + + def subprocess_test_upgrade(self, config, file, main_type, sub_type, slot): + dev_name = config.get("name", None) + init_cmd_list = config.get("init_cmd", []) + finish_cmd_list = config.get("finish_cmd", []) + try: + ret, log = self.do_fw_upg_init_cmd(dev_name, init_cmd_list) + if ret is False: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, log + time.sleep(0.5) # delay 0.5s after execute init_cmd + command = "firmware_upgrade test %s 0x%x 0x%x %s" % (file, main_type, sub_type, slot) + upgradedebuglog("firmware upgrade cmd: %s" % command) + if os.path.exists(UPGRADE_DEBUG_FILE): + status, output = exec_os_cmd_log(command) + else: + status, output = exec_os_cmd(command) + if status: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + upgradeerror("%s test upgrade failed, msg: %s" % (dev_name, output)) + return False, output + upgradedebuglog("%s test upgrade success" % dev_name) + ret, log = self.do_fw_upg_finish_cmd(dev_name, init_cmd_list) + if ret is False: + return False, log + return True, "upgrade success" + except Exception as e: + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, str(e) + + def subprocess_bmc_upgrade(self, config, file, chip_select, erase_type): + dev_name = config.get("name", None) + init_cmd_list = config.get("init_cmd", []) + finish_cmd_list = config.get("finish_cmd", []) + save_set_reg_list = config.get("save_set_reg", []) + try: + # save and set reg + ret, log = self.save_and_set_value(save_set_reg_list) + if ret is False: + upgradeerror(log) + self.recover_save_value(save_set_reg_list) + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, log + upgradedebuglog("%s save and set cmd all set success" % dev_name) + time.sleep(0.5) # delay 0.5s after execute save and set reg + + # pre operation + ret, log = self.do_fw_upg_init_cmd(dev_name, init_cmd_list) + if ret is False: + self.recover_save_value(save_set_reg_list) + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, log + + upgradedebuglog("%s bmc init cmd all set success" % dev_name) + time.sleep(0.5) # delay 0.5s after execute init_cmd + + command = "fw_upgrade upgrade %s %s %s" % (file, chip_select, erase_type) + upgradedebuglog("fw_upgrade upgrade cmd: %s" % command) + status, output = exec_os_cmd_log(command) + if status: + upgradeerror("%s bmc upgrade failed" % dev_name) + self.recover_save_value(save_set_reg_list) + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, output + upgradedebuglog("%s bmc upgrade success" % dev_name) + + ret1, log1 = self.recover_save_value(save_set_reg_list) + if ret1 is False: + upgradeerror("bmc upgrade recover save value failed, msg: %s" % log1) + ret2, log2 = self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + if ret2 is False: + upgradeerror("bmc upgrade do finish command failed, msg: %s" % log2) + if ret1 is False or ret2 is False: + return False, "bmc upgrade do recover save value or finish command failed" + return True, "upgrade success" + + except Exception as e: + self.recover_save_value(save_set_reg_list) + self.do_fw_upg_finish_cmd(dev_name, finish_cmd_list) + return False, str(e) + + def file_head_param_check(self, head_info_config): + try: + self.DEVTYPE = head_info_config.get('DEVTYPE', None) + self.SUBTYPE = head_info_config.get('SUBTYPE', '0') + self.TYPE = head_info_config.get('TYPE', None) + self.CHAIN = head_info_config.get('CHAIN', None) + self.CHIPNAME = head_info_config.get('CHIPNAME', None) + self.VERSION = head_info_config.get('VERSION', None) + self.FILETYPE = head_info_config.get('FILETYPE', None) + self.CRC = head_info_config.get('CRC', None) + + if self.devtype != int(self.DEVTYPE, 16): + return ERR_FW_HEAD_CHECK, ("no support %s devtype" % self.DEVTYPE) + + if self.SUBTYPE is not None: + self.SUBTYPE_LIST = self.SUBTYPE.split(',') + self.SUBTYPE_LIST = [int(tmp_subtype, base=16) for tmp_subtype in self.SUBTYPE_LIST] + if len(self.SUBTYPE) != 0 and self.subtype not in self.SUBTYPE_LIST: + return ERR_FW_HEAD_CHECK, ("no support %s SUBTYPE" % self.SUBTYPE) + + if len(self.CHAIN) == 0 or len(self.FILETYPE) == 0: + return ERR_FW_HEAD_CHECK, ("CHAIN:%s, FILETYPE:%s get failed" % (self.CHAIN, self.FILETYPE)) + self.chain = int(self.CHAIN) + self.filetype = self.FILETYPE + upgradedebuglog("file head param: devtype:0x%x, subtype:0x%x, chain:%s, filetype:%s" + % (self.devtype, self.subtype, self.chain, self.filetype)) + return CHECK_OK, "SUCCESS" + except Exception as e: + return ERR_FW_RAISE_EXCEPTION, str(e) + + def parse_file_head(self, file): + try: + self.head_info_config = {} + with open(file, 'r', errors='ignore') as fd: + rdbuf = fd.read() + upgradedebuglog("start parse upgrade file head") + file_head_start = rdbuf.index('FILEHEADER(\n') # ponit to F + file_head_start += rdbuf[file_head_start:].index('\n') # ponit to \n + file_head_end = rdbuf.index(')\n') + header_buf = rdbuf[file_head_start + 1: file_head_end - 1] + upgradedebuglog("upgrade file head find FILEHEADER") + for line in header_buf.split('\n'): + head_list = line.split('=', 1) + head_key = head_list[0] + head_val = head_list[1] + self.head_info_config[head_key] = head_val + upgradedebuglog("file: %s head_info_config: %s" % (file, self.head_info_config)) + return CHECK_OK, "SUCCESS" + except Exception as e: + msg = "parse %s head failed, msg: %s" % (file, str(e)) + upgradeerror(msg) + return ERR_FW_RAISE_EXCEPTION, msg + + def get_file_size_k(self, file): + fsize = os.path.getsize(file) + fsize = fsize / float(1024) + return round(fsize, 2) + + def get_device_model(self, conf): + ret, val = get_value(conf) + if ret is False: + msg = "get device model failed, msg: %s" % val + return False, msg + decode_val = conf.get("decode") + if decode_val is None: + return True, val + for k, v in decode_val.items(): + if val == v: + return True, k + msg = "device model decode error, val: %s" % val + return False, msg + + def upgrade_fool_proofing(self, conf): + try: + status, dev_model = self.get_device_model(conf) + if status is False: + msg = "upgrade fool proofing get device model failed, msg: %s" % dev_model + upgradeerror(msg) + return False, msg + upgradedebuglog("get device model success, device model: %s" % dev_model) + if dev_model != self.VERSION: + msg = "upgrade fool proofing failed, device model: %s, upgrade file version: %s" % ( + dev_model, self.VERSION) + upgradedebuglog(msg) + return False, msg + msg = "upgrade fool proofing pass, device model: %s, upgrade file version: %s" % (dev_model, self.VERSION) + upgradedebuglog(msg) + return True, msg + except Exception as e: + upgradeerror(str(e)) + return False, str(e) + + def upgrading(self, config, file, devtype, subtype, slot, option_flag, erase_type=None): + dev_name = config.get("name", None) + if option_flag == COLD_UPGRADE: + status, output = self.subprocess_firmware_upgrade(config, file, devtype, subtype, slot) + elif option_flag == WARM_UPGRADE: + status, output = self.subprocess_warm_upgrade(config, file, devtype, subtype, slot) + elif option_flag == TEST_UPGRADE: + status, output = self.subprocess_test_upgrade(config, file, devtype, subtype, slot) + elif option_flag == BMC_UPGRADE: + status, output = self.subprocess_bmc_upgrade(config, file, slot, erase_type) + else: + log = "%s set error option flag" % dev_name + upgradeerror(log) + return False, log + + if status is False: + upgradeerror("%s upgrade failed" % dev_name) + return False, output + upgradedebuglog("%s upgrade success" % dev_name) + return True, "upgrade success" + + def initial_check(self, file, slot, upg_type): + try: + upgradedebuglog("BasePlatform initial_check, file: %s, slot: %s, upg_type: %s" % + (file, slot, upg_type)) + + upgradedebuglog("do file exist check...") + if not os.path.isfile(file): + msg = "%s not found" % file + upgradedebuglog(msg) + return ERR_FW_FILE_FOUND, msg + upgradedebuglog("file exist check ok") + + slot_name = "slot%d" % slot + slot_config = self.upgrade_param.get(slot_name, {}) + slot_present_config = slot_config.get("present", {}) + if len(slot_present_config) != 0: + upgradedebuglog("do %s present check..." % slot_name) + ret, log = self.linecard_present_check(slot_present_config) + if ret != CHECK_OK: + msg = "check %s present error, msg: %s" % (slot_name, log) + upgradedebuglog(msg) + return ret, msg + upgradedebuglog("%s present check ok" % slot_name) + + upgradedebuglog("do file head parse...") + self.subtype = slot_config.get("subtype", 0) + ret, log = self.parse_file_head(file) + if ret != CHECK_OK: + return ret, log + upgradedebuglog("file head parse success") + + upgradedebuglog("do file head check...") + ret, log = self.file_head_param_check(self.head_info_config) + if ret != CHECK_OK: + msg = "file: %s, head check failed, msg: %s" % (file, log) + upgradedebuglog(msg) + return ret, msg + upgradedebuglog("file head check ok") + + upgradedebuglog("get upgrade chain config...") + filetype_config = slot_config.get(self.filetype, {}) + if len(filetype_config) == 0: + msg = "file: %s filetype: %s no support" % (file, self.filetype) + upgradedebuglog(msg) + return ERR_FW_CONFIG_FOUND, msg + chain_num = "chain%s" % self.chain + chain_config = filetype_config.get(chain_num, {}) + if len(chain_config) == 0: + msg = "file: %s get %s config failed" % (file, chain_num) + upgradedebuglog(msg) + return ERR_FW_CONFIG_FOUND, msg + self.cold_chain_config = chain_config + upgradedebuglog("get %s filetype: %s %s config success" % (slot_name, self.filetype, chain_num)) + + fool_proofing = chain_config.get("fool_proofing") + if fool_proofing is not None: + upgradedebuglog("do fool proofing check...") + status, log = self.upgrade_fool_proofing(fool_proofing) + if status is False: + msg = "upgrade fool proofing check failed, msg: %s" % log + upgradedebuglog(msg) + return ERR_FW_FOOL_PROOF, msg + upgradedebuglog("do fool proofing check ok") + + if upg_type == WARM_UPGRADE: + upgradedebuglog("do support warm upgrade check...") + if chain_config.get("is_support_warm_upg", 0) != 1: + msg = "file: %s %s chain config not support warm upgrade" % (file, slot_name) + upgradedebuglog(msg) + return ERR_FW_NOSUPPORT_HOT, msg + upgradedebuglog("file: %s %s chain config support warm upgrade" % (file, slot_name)) + + filesizecheck = chain_config.get("filesizecheck", 0) + if filesizecheck != 0: + upgradedebuglog("do file size check...") + file_size = self.get_file_size_k(file) + if file_size > filesizecheck: + msg = "file: %s size: %s exceed %s" % (file, file_size, filesizecheck) + upgradedebuglog(msg) + return ERR_FW_CHECK_SIZE, msg + msg = "file: %s size: %s check ok" % (file, file_size) + upgradedebuglog(msg) + + msg = "file: %s slot: %s upgrade type: %s check ok" % (file, slot, upg_type) + upgradedebuglog(msg) + return CHECK_OK, msg + except Exception as e: + return ERR_FW_RAISE_EXCEPTION, str(e) + + def do_upgrade(self, file, slot, upg_type): + try: + ret, log = self.initial_check(file, slot, upg_type) + if ret != CHECK_OK: + return ret, log + + # start upgrading + upgradedebuglog("start upgrading") + ret, log = self.upgrading(self.cold_chain_config, file, self.devtype, self.subtype, slot, upg_type) + if ret is False: + upgradeerror("upgrade failed") + return ERR_FW_UPGRADE, log + upgradedebuglog("upgrade success") + return FIRMWARE_SUCCESS, "SUCCESS" + except Exception as e: + return ERR_FW_RAISE_EXCEPTION, str(e) + + def do_pre_check(self, conf): + ret, val = get_value(conf) + if ret is False: + msg = "pre check get value failed, msg: %s" % val + return False, msg + ok_val = conf.get("ok_val") + if val == ok_val: + msg = "pre check success, ok_val: %s, get value: %s" % (ok_val, val) + return True, msg + msg = "pre check failed, ok_val: %s, get value: %s" % (ok_val, val) + return False, msg + + def do_test(self, device, slot): + try: + # slot present check + slot_name = "slot%d" % slot + slot_config = self.upgrade_param.get(slot_name, {}) + slot_present_config = slot_config.get("present", {}) + if len(slot_present_config) != 0: + ret, log = self.linecard_present_check(slot_present_config) + if ret != CHECK_OK: + msg = "check %s present error, msg: %s" % (slot_name, log) + upgradedebuglog(msg) + return ret, msg + upgradedebuglog("%s present" % slot_name) + + # get list of devices to be tested + test_config = slot_config.get("TEST", {}) + if len(test_config) == 0: + return ERR_FW_CONFIG_FOUND, "test config no found" + device_list = test_config.get(device, []) + if len(device_list) == 0: + return ERR_FW_CONFIG_FOUND, ("logic device %s test config list not found" % device) + + # test_file existence check + for test_config in device_list: + chain_num = test_config.get("chain", None) + test_file = test_config.get("file", None) + display_name = test_config.get("display_name", None) + if chain_num is None or test_file is None or display_name is None: + log = "test_config:%s lack of config" % test_config + upgradeerror(log) + return ERR_FW_CONFIG_FOUND, log + if not os.path.isfile(test_file): + return ERR_FW_FILE_FOUND, ("%s not found" % test_file) + + # start testing + RET = 0 + pre_check_failed = 0 + pre_check_failed_summary = "" + failed_summary = "chain test failed.\ntest fail chain:" + success_summary = "test success chain:" + for test_config in device_list: + chain_num = test_config.get("chain", None) + test_file = test_config.get("file", None) + display_name = test_config.get("display_name", None) + pre_check_conf = test_config.get("pre_check", None) + if pre_check_conf is not None: + status, msg = self.do_pre_check(pre_check_conf) + if status is False: + pre_check_failed += 1 + log = "\nchain:%d, name:%s, pre check failed, msg: %s" % (chain_num, display_name, msg) + upgradedebuglog(log) + pre_check_failed_summary += log + continue + upgradedebuglog("chain:%d, name:%s, pre check ok, msg: %s" % (chain_num, display_name, msg)) + ret, log = self.do_upgrade(test_file, slot, TEST_UPGRADE) + if ret != FIRMWARE_SUCCESS: + RET = -1 + upgradeerror("chain:%d, name:%s test failed" % (chain_num, display_name)) + failed_summary += "\n chain:%d, name:%s;" % (chain_num, display_name) + else: + upgradedebuglog("chain:%d, name:%s test success" % (chain_num, display_name)) + success_summary += "\n chain:%d, name:%s;" % (chain_num, display_name) + if RET != 0: + return ERR_FW_UPGRADE, failed_summary + if pre_check_failed == len(device_list): + return ERR_FW_NO_FILE_SUCCESS, failed_summary + pre_check_failed_summary + return FIRMWARE_SUCCESS, success_summary + except Exception as e: + return ERR_FW_RAISE_EXCEPTION, str(e) + + def do_test_main(self, device, slot): + print("+================================+") + print("|Doing upgrade test, please wait.|") + ret, log = self.do_test(device, slot) + if ret == FIRMWARE_SUCCESS: + print("| test succeeded! |") + print("+================================+") + print(log) + sys.exit(0) + else: + print("| test failed! |") + print("+================================+") + print("FAILED REASON:") + print(log) + sys.exit(1) + + def do_bmc_upgrade_main(self, file, chip_select, erase_type): + bmc_upgrade_config = self.upgrade_param.get("BMC", {}) + ret, log = self.upgrading(bmc_upgrade_config, file, self.devtype, + self.subtype, chip_select, BMC_UPGRADE, erase_type) + if ret is True: + print("===========upgrade succeeded!============") + sys.exit(0) + else: + print("============upgrade failed!==============") + print("FAILED REASON:") + print("%s" % log) + sys.exit(1) + + +class FileUpg(object): + def __init__(self, config, file, devtype, subtype, slot, filetype, chain, upg_type): + self.config = config + self.file = file + self.devtype = devtype + self.subtype = subtype + self.slot = slot + self.filetype = filetype + self.chain = chain + self.upg_type = upg_type + + def __repr__(self): + return "file:%s slot:%d" % (self.file, self.slot) + + +class FwUpg(object): + def __init__(self): + self.upg_platform = BasePlatform() + self.warm_upg_platform = WarmBasePlatform() + self.max_slot_num = self.upg_platform.max_slot_num + self.file_list = [] + + def do_file_refresh(self, fw_upg_instance): + fw_upg_config = fw_upg_instance.config + fw_upg_file = fw_upg_instance.file + fw_upg_devtype = fw_upg_instance.devtype + fw_upg_subype = fw_upg_instance.subtype + fw_upg_slot = fw_upg_instance.slot + fw_upg_filetype = fw_upg_instance.filetype + fw_upg_chain = fw_upg_instance.chain + dev_name = fw_upg_config.get("name", None) + upgradedebuglog("%s start warm upgrade, file: %s, devtype:0x%x, subype: 0x%x, slot: %d, filetype: %s, chain: %d" % + (dev_name, fw_upg_file, fw_upg_devtype, fw_upg_subype, fw_upg_slot, fw_upg_filetype, fw_upg_chain)) + status, output = self.warm_upg_platform.do_warmupgrade(fw_upg_file, fw_upg_devtype, fw_upg_subype, fw_upg_slot, + fw_upg_filetype, fw_upg_chain) + if status is False: + upgradeerror("%s warm upgrade failed, msg: %s" % (dev_name, output)) + return False, output + upgradedebuglog("%s warm upgrade success" % dev_name) + return True, "upgrade success" + + def do_refresh(self): + try: + exec_os_cmd("touch %s" % WARM_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") + + # stop upper layer services access + ret, log = self.warm_upg_platform.stop_services_access() + if ret is False: + upgradeerror("stop upper layer services access failed") + upgradeerror(log) + return ERR_FW_UPGRADE, log + upgradedebuglog("stop upper layer services access success") + + for file_instance in self.file_list: + file_info = repr(file_instance) + ret, log = self.do_file_refresh(file_instance) + if ret is False: + msg = "%s refresh failed, ret:%s, \n log:%s." % (file_info, ret, log) + upgradeerror(msg) + return ERR_FW_UPGRADE, msg + upgradedebuglog("%s refresh success." % file_info) + msg = "all files refresh success." + return FIRMWARE_SUCCESS, msg + except Exception as e: + msg = "do warm upg exception happend. log:%s" % str(e) + upgradeerror(msg) + return ERR_FW_UPGRADE, msg + finally: + self.warm_upg_platform.start_services_access() + if os.path.isfile(WARM_UPGRADE_STARTED_FLAG): + exec_os_cmd("rm -rf %s" % WARM_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") + + def do_file_cold_upg(self, fw_upg_instance): + try: + upgradedebuglog("start cold upgrade") + fw_upg_config = fw_upg_instance.config + fw_upg_file = fw_upg_instance.file + fw_upg_devtype = fw_upg_instance.devtype + fw_upg_subype = fw_upg_instance.subtype + fw_upg_slot = fw_upg_instance.slot + ret, log = self.upg_platform.upgrading( + fw_upg_config, fw_upg_file, fw_upg_devtype, fw_upg_subype, fw_upg_slot, COLD_UPGRADE) + if ret is False: + upgradeerror("cold upgrade %s slot%d failed, log:%s" % (fw_upg_file, fw_upg_slot, log)) + return ERR_FW_UPGRADE, log + log = "cold upgrade %s slot%d success" % (fw_upg_file, fw_upg_slot) + upgradedebuglog(log) + return FIRMWARE_SUCCESS, log + except Exception as e: + msg = "do cold upg exception happend. log:%s" % str(e) + upgradeerror(msg) + return ERR_FW_UPGRADE, msg + + def do_file_init_check(self, file_path, slot, upg_type): + upgradedebuglog("do_file_init_check, file_path: %s, slot: %s, upg_type: %s" % (file_path, slot, upg_type)) + + if slot is None: # traverse all slots + for i in range(0, self.max_slot_num + 1): + ret, log = self.upg_platform.initial_check(file_path, i, upg_type) + if ret != CHECK_OK: + upgradedebuglog( + "file: %s, slot%d initial check not ok, ret: %d, msg: %s" % + (file_path, i, ret, log)) + accept_error = (ERR_FW_CARD_ABSENT, ERR_FW_HEAD_CHECK, ERR_FW_FOOL_PROOF) + if ret in accept_error: + msg = "file: %s, slot%d initial check ret: %d, acceptable error." % (file_path, i, ret) + upgradedebuglog(msg) + continue + return ret, log + file_instance = FileUpg(self.upg_platform.cold_chain_config, file_path, self.upg_platform.devtype, + self.upg_platform.subtype, i, self.upg_platform.filetype, self.upg_platform.chain, upg_type) + self.file_list.append(file_instance) + else: + slot = int(slot, 10) + ret, log = self.upg_platform.initial_check(file_path, slot, upg_type) + if ret != CHECK_OK: + msg = "file: %s, slot%d initial check not ok, ret: %d, msg: %s" % (file_path, slot, ret, log) + return ret, msg + file_instance = FileUpg(self.upg_platform.cold_chain_config, file_path, self.upg_platform.devtype, + self.upg_platform.subtype, slot, self.upg_platform.filetype, self.upg_platform.chain, upg_type) + self.file_list.append(file_instance) + msg = "file: %s all slots init check ok" % file_path + return CHECK_OK, msg + + def do_dir_init_check(self, path, slot, upg_type): + for root, dirs, names in os.walk(path): + # root: directory absolute path + # dirs: folder path collection under directory + # names: file path collection under directory + for filename in names: + # file_path is file absolute path + file_path = os.path.join(root, filename) + ret, log = self.do_file_init_check(file_path, slot, upg_type) + if ret != CHECK_OK: + return ret, log + msg = "all files in dir have been check ok" + upgradedebuglog(msg) + return CHECK_OK, msg + + def do_fw_upg(self, path, slot, upg_type): + match_zip_file_flag = False + try: + upgradedebuglog("do_fw_upg, path: %s, slot: %s, upg_type: %s" % (path, slot, upg_type)) + if slot is not None and not slot.isdigit(): + msg = "invalid slot param: %s" % slot + upgradeerror(msg) + return ERR_FW_INVALID_PARAM, msg + + upgradedebuglog("start init check") + if os.path.isfile(path) and path.endswith(".zip"): + upgradedebuglog("firmware upgrade via compressed package: %s" % path) + # remove origin firmware upgrade file + exec_os_cmd("rm -rf %s" % UPGRADE_FILE_DIR) + cmd = "unzip -o %s -d /tmp/" % path + if os.path.exists(UPGRADE_DEBUG_FILE): + status, output = exec_os_cmd_log(cmd) + else: + status, output = exec_os_cmd(cmd) + if status: + msg = "unzip %s failed, log: %s" % (path, output) + upgradeerror(msg) + return ERR_FW_UNZIP_FAILED, msg + match_zip_file_flag = True + path = UPGRADE_FILE_DIR + + if os.path.isdir(path): + ret, msg = self.do_dir_init_check(path, slot, upg_type) + elif os.path.isfile(path): + ret, msg = self.do_file_init_check(path, slot, upg_type) + else: + ret = ERR_FW_FILE_FOUND + msg = "path: %s not found" % path + upgradeerror(msg) + + if ret != CHECK_OK: + return ret, msg + + # self.file_list is a collection of all check ok files + if len(self.file_list) == 0: + msg = "all file upgrade check not be satisfied." + upgradeerror(msg) + return ERR_FW_NO_FILE_SUCCESS, msg + + SUCCUSS_FILE_SUMMARY = "SUCCESS FILE: \n" + # file cold upgrade + upgradedebuglog("start all files cold upgrade") + for file_instance in self.file_list: + file_info = repr(file_instance) + ret, log = self.do_file_cold_upg(file_instance) + if ret != FIRMWARE_SUCCESS: + msg = "%s cold upgrade failed, ret:%d, \n log:\n%s." % (file_info, ret, log) + upgradeerror(msg) + return ret, msg + SUCCUSS_FILE_SUMMARY += "%s \n" % file_info + upgradedebuglog("%s cold upgrade success." % file_info) + + # file refresh upgrade + if upg_type == WARM_UPGRADE: + upgradedebuglog("start all files refresh upgrade") + ret, log = self.do_refresh() + if ret != FIRMWARE_SUCCESS: + return ret, log + + msg = "all file upgrade success" + upgradedebuglog(msg) + return FIRMWARE_SUCCESS, SUCCUSS_FILE_SUMMARY + except Exception as e: + msg = "do dir upgrade exception happend. log: %s" % str(e) + upgradeerror(msg) + return ERR_FW_UPGRADE, msg + finally: + if match_zip_file_flag is True: + exec_os_cmd("rm -rf %s" % UPGRADE_FILE_DIR) + + def fw_upg(self, path, slot, upg_type): + print("+================================+") + print("| Doing upgrade, please wait... |") + ret, log = self.do_fw_upg(path, slot, upg_type) + if ret == FIRMWARE_SUCCESS: + print("| upgrade succeeded! |") + print("+================================+") + print(log) + sys.exit(0) + else: + print("| upgrade failed! |") + print("+================================+") + print("FAILED REASON:") + print("%s" % log) + sys.exit(1) + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +def main(): + '''upgrade script''' + + +# cold upgrade +@main.command() +@click.argument('file_name', required=True) +@click.argument('slot_num', required=False, default=None) +def cold(file_name, slot_num): + '''cold upgrade''' + fwupg = FwUpg() + fwupg.fw_upg(file_name, slot_num, COLD_UPGRADE) + + +# warm upgrade +@main.command() +@click.argument('file_name', required=True) +@click.argument('slot_num', required=False, default=None) +def warm(file_name, slot_num): + '''warm upgrade''' + fwupg = FwUpg() + fwupg.fw_upg(file_name, slot_num, WARM_UPGRADE) + + +# test upgrade +@main.command() +@click.argument('device', required=True) +@click.argument('slot_num', required=True) +def test(device, slot_num): + '''upgrade test''' + platform = BasePlatform() + platform.do_test_main(device, int(slot_num)) + + +# BMC upgrade +@main.command() +@click.argument('file_name', required=True) +@click.argument('chip_select', required=False, default="2") +@click.argument('erase_type', required=False, default="full") +def bmc(file_name, chip_select, erase_type): + '''BMC upgrade''' + platform = BasePlatform() + platform.do_bmc_upgrade_main(file_name, chip_select, erase_type) + + +if __name__ == '__main__': + signal_init() + debug_init() + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/script/warm_upgrade.py b/platform/broadcom/sonic-platform-modules-ragile/common/script/warm_upgrade.py new file mode 100755 index 000000000000..69a310faa606 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/script/warm_upgrade.py @@ -0,0 +1,514 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +import sys +import os +import time +import syslog +import signal +import click +from platform_util import get_value, set_value, exec_os_cmd, exec_os_cmd_log +from platform_config import WARM_UPGRADE_PARAM + + +WARM_UPGRADE_DEBUG_FILE = "/etc/.warm_upgrade_debug_flag" + +WARMUPGRADEDEBUG = 1 + +debuglevel = 0 + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def debug_init(): + global debuglevel + if os.path.exists(WARM_UPGRADE_DEBUG_FILE): + debuglevel = debuglevel | WARMUPGRADEDEBUG + else: + debuglevel = debuglevel & ~(WARMUPGRADEDEBUG) + + +def warmupgradewarninglog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("WARMUPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_WARNING, s) + + +def warmupgradecriticallog(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("WARMUPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_CRIT, s) + + +def warmupgradeerror(s): + # s = s.decode('utf-8').encode('gb2312') + syslog.openlog("WARMUPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_ERR, s) + + +def warmupgradedebuglog(s): + # s = s.decode('utf-8').encode('gb2312') + if WARMUPGRADEDEBUG & debuglevel: + syslog.openlog("WARMUPGRADE", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def subprocess_warm_upgrade(file, main_type, sub_type, slot): + command = "firmware_upgrade %s 0x%x 0x%x %s" % (file, main_type, sub_type, slot) + warmupgradedebuglog("warm upgrade firmware cmd:%s" % command) + if os.path.exists(WARM_UPGRADE_DEBUG_FILE): + return exec_os_cmd_log(command) + return exec_os_cmd(command) + + +def signal_init(): + signal.signal(signal.SIGINT, signal.SIG_IGN) # ignore ctrl+c signal + signal.signal(signal.SIGTERM, signal.SIG_IGN) # ignore kill signal + signal.signal(signal.SIGTSTP, signal.SIG_IGN) # ignore ctrl+z signal + + +class RefreshUpgradeBase(object): + + def __init__(self, config, slot_num, devtype, subtype): + self._config = config + self._slot_num = slot_num + self._devtype = devtype + self._subtype = subtype + self.device_name = self._config.get("name", None) + self.refresh_file = self._config.get("refresh_file", None) + self.init_cmd_list = self._config.get("init_cmd", []) + self.save_set_reg_list = self._config.get("save_set_reg", []) + self.rw_recover_reg_list = self._config.get("rw_recover_reg", []) + self.after_upgrade_delay = self._config.get("after_upgrade_delay", None) + self.after_upgrade_delay_timeout = self._config.get("after_upgrade_delay_timeout", None) + self.refresh_finish_flag_check_config = self._config.get("refresh_finish_flag_check", None) + self.access_check_reg_config = self._config.get("access_check_reg", {}) + self.time_delay = 0 + self.finish_cmd_list = self._config.get("finish_cmd", []) + + def get_config(self): + pass + + def get_slot_num(self): + pass + + def save_value(self, cfg_list): + for config in cfg_list: + ret, val = get_value(config) + if ret: + config["value"] = val + else: + warmupgradeerror(val) + return False, val + return True, "save value success" + + def save_and_set_value(self, cfg_list): + for config in cfg_list: + ret, val = get_value(config) + if ret: + config["save_value"] = val + else: + warmupgradeerror(val) + return False, "get save value fail" + set_val = config.get("set_value", None) + if set_val is not None: + config["value"] = set_val + else: + warmupgradeerror("save_and_set_value lack of set_val config") + return False, "set value is not config" + ret, log = set_value(config) + if ret is False: + warmupgradeerror(log) + return False, log + return True, "save value success" + + def recover_value(self, cfg_list): + fail_flag = 0 + for config in cfg_list: + ret, log = set_value(config) + if ret is False: + fail_flag = -1 + warmupgradeerror("recover_value set_value failed, log: %s" % log) + if fail_flag != 0: + warmupgradeerror("recover_value write failed") + return False, "recover write failed" + return True, "recover write success" + + def recover_save_value(self, cfg_list): + total_err = 0 + for config in cfg_list: + val = config.get("save_value", None) + if val is None: + warmupgradeerror("recover_save_value lack of save_value config") + total_err -= 1 + continue + config["value"] = val + ret, log = set_value(config) + if ret is False: + total_err -= 1 + warmupgradeerror("recover save value write failed, log: %s" % log) + else: + warmupgradedebuglog("recover save value success") + if total_err < 0: + return False, "recover save value failed" + return True, "recover save value success" + + def do_fw_upg_init_cmd(self, init_cmd_list): + # pre operation + try: + for init_cmd_config in init_cmd_list: + ret, log = set_value(init_cmd_config) + if ret is False: + warmupgradeerror("%s do init cmd: %s failed, msg: %s" % (self.device_name, init_cmd_config, log)) + return False, log + msg = "%s warm upgrade init cmd all set success" % self.device_name + warmupgradedebuglog(msg) + return True, msg + except Exception as e: + return False, str(e) + + def do_fw_upg_finish_cmd(self, finish_cmd_list): + # end operation + total_err = 0 + for finish_cmd_config in finish_cmd_list: + ret_t, log = set_value(finish_cmd_config) + if ret_t is False: + warmupgradeerror("%s do finish cmd: %s failed, msg: %s" % (self.device_name, finish_cmd_config, log)) + total_err -= 1 + if total_err < 0: + msg = "%s warm upgrade finish cmd exec failed" % self.device_name + warmupgradeerror(msg) + return False, msg + msg = "%s warm upgrade finish cmd all set success" % self.device_name + warmupgradedebuglog(msg) + return True, msg + + def access_test(self, config): + # polling execute command + polling_cmd_list = config.get("polling_cmd", []) + for polling_cmd_config in polling_cmd_list: + ret, log = set_value(polling_cmd_config) + if ret is False: + warmupgradeerror(log) + return False + polling_delay = config.get("polling_delay", None) + if polling_delay is not None: + time.sleep(polling_delay) + + # record check val + check_val = config.get("value", None) + # write value + ret, log = set_value(config) + if ret is False: + warmupgradeerror(log) + return False + # read value + ret, val = get_value(config) + if ret is False: + warmupgradeerror(val) + return False + + # compare write and read val + warmupgradedebuglog("check_val:%s" % check_val) + warmupgradedebuglog("get_value:%s" % val) + if val != check_val: + warmupgradeerror("check_val:%s != get_value:%s" % (check_val, val)) + return False + return True + + def check_value(self, config): + # record check val + check_val = config.get("value", None) + ret, val = get_value(config) + if ret is False: + warmupgradeerror(val) + return False + # compare write and read val + warmupgradedebuglog("check_val:%s" % check_val) + warmupgradedebuglog("get_value:%s" % val) + if val != check_val: + warmupgradeerror("check_val:%s != get_value:%s" % (check_val, val)) + return False + return True + + def refresh_file_upgrade(self): + try: + warmupgradedebuglog("start %s warm upgrading" % self.device_name) + + # save and set reg + ret, log = self.save_and_set_value(self.save_set_reg_list) + if ret is False: + warmupgradeerror(log) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("%s save and set reg cmd all set success" % self.device_name) + time.sleep(0.5) # delay 0.5s after execute save and set reg + + # pre operation + ret, log = self.do_fw_upg_init_cmd(self.init_cmd_list) + if ret is False: + warmupgradeerror(log) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + time.sleep(0.5) # delay 0.5s after execute init_cmd + + # save reg + ret, log = self.save_value(self.rw_recover_reg_list) + if ret is False: + warmupgradeerror("%s save reg failed" % self.device_name) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("%s all reg save success" % self.device_name) + + # upgrade refresh file + if self.refresh_file is not None: + status, output = subprocess_warm_upgrade( + self.refresh_file, self._devtype, self._subtype, self._slot_num) + if status: + log = "%s refresh file upg failed, msg: %s" % (self.device_name, output) + warmupgradeerror(log) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("%s refresh file upg success" % self.device_name) + + # delay the preset time after the upgrade is complete + if self.after_upgrade_delay is not None: + time.sleep(self.after_upgrade_delay) + + # check something in the timeout period + if self.after_upgrade_delay_timeout is not None: + while self.time_delay < self.after_upgrade_delay_timeout: + + # check refresh finish flag + if self.refresh_finish_flag_check_config is not None: + ret = self.check_value(self.refresh_finish_flag_check_config) + if ret is False: + time.sleep(1) + self.time_delay = self.time_delay + 1 + warmupgradedebuglog("doing refresh_finish_flag_check, time_delay:%s" % self.time_delay) + continue + warmupgradedebuglog("%s upgrade_finish_flag_check success. self.time_delay:%d" + % (self.device_name, self.time_delay)) + + # doing logic device rw access test + ret = self.access_test(self.access_check_reg_config) + if ret: + warmupgradedebuglog( + "%s rw test success. self.time_delay:%d" % + (self.device_name, self.time_delay)) + break + time.sleep(1) + self.time_delay = self.time_delay + 1 + warmupgradedebuglog("doing access_test, self.time_delay:%s" % self.time_delay) + + if self.time_delay >= self.after_upgrade_delay_timeout: + log = "wait %s access test timeout" % self.device_name + warmupgradeerror(log) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("%s access test success" % self.device_name) + + # recover reg + ret, log = self.recover_value(self.rw_recover_reg_list) + if ret is False: + warmupgradeerror("recover %s reg failed" % self.device_name) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + warmupgradedebuglog("recover %s reg success" % self.device_name) + # finally + ret1, log1 = self.recover_save_value(self.save_set_reg_list) + if ret1 is False: + warmupgradeerror("bmc upgrade recover save value failed, msg: %s" % log1) + ret2, log2 = self.do_fw_upg_finish_cmd(self.finish_cmd_list) + if ret2 is False: + warmupgradeerror("bmc upgrade do finish command failed, msg: %s" % log2) + if ret1 is False or ret2 is False: + return False, "upgrading %s recover save value or finish command failed" % self.device_name + return True, "upgrading %s success" % self.device_name + + except Exception as e: + log = "refresh file upgrade Exception happend, error log : %s" % str(e) + self.recover_save_value(self.save_set_reg_list) + self.do_fw_upg_finish_cmd(self.finish_cmd_list) + return False, log + + +class RefreshUpgrade(RefreshUpgradeBase): + + def __init__(self, config, slot_num, devtype, subtype): + super(RefreshUpgrade, self).__init__(config, slot_num, devtype, subtype) + + def get_config(self): + super(RefreshUpgrade, self).get_config() + return self._config + + def get_slot_num(self): + super(RefreshUpgrade, self).get_slot_num() + return self._slot_num + + +class WarmBasePlatform(): + + def __init__(self): + signal_init() + debug_init() + self.warm_upgrade_param = WARM_UPGRADE_PARAM.copy() + self.stop_services_cmd_list = self.warm_upgrade_param.get("stop_services_cmd", []) + self.start_services_cmd_list = self.warm_upgrade_param.get("start_services_cmd", []) + self.__warm_upgrade_config_list = [] + + def execute_command_list(self, cmd_list): + for cmd_item in cmd_list: + warmupgradedebuglog("execute cmd: %s" % cmd_item) + status, output = exec_os_cmd(cmd_item) + if status: + log = "execute %s failed, msg: %s" % (cmd_item, output) + warmupgradeerror(log) + return False, log + return True, "execute success" + + def stop_services_access(self): + return self.execute_command_list(self.stop_services_cmd_list) + + def start_services_access(self): + return self.execute_command_list(self.start_services_cmd_list) + + def check_slot_present(self, slot_present_config): + totalerr = 0 + presentbit = slot_present_config.get('presentbit') + ret, value = get_value(slot_present_config) + if ret is False: + return "NOT OK" + if isinstance(value, str): + val_t = int(value, 16) + else: + val_t = value + val_t = (val_t & (1 << presentbit)) >> presentbit + if val_t != slot_present_config.get('okval'): + status = "ABSENT" + else: + status = "PRESENT" + return status + + def linecard_present_check(self, slot_name, slot_present_config): + present_status = self.check_slot_present(slot_present_config) + present_status_tuple = ("ABSENT", "NOT OK") + if present_status in present_status_tuple: + return False, ("%s not present, warm upgrade exit" % slot_name) + warmupgradedebuglog("%s present" % slot_name) + return True, ("%s present" % slot_name) + + def start_warmupgrade(self): + try: + # start refresh file upgrade process + for dev in self.__warm_upgrade_config_list: + ret, log = dev.refresh_file_upgrade() + if ret is False: + return ret, log + return True, "all success" + except Exception as e: + log = "Exception happend, error log : %s" % str(e) + return False, log + + def do_warmupgrade(self, file, main_type, sub_type, slot, file_type, chain): + try: + # upgrade file existence check + if not os.path.isfile(file): + return False, "%s not found" % file + + # get slot config + slot_name = "slot%d" % slot + slot_config = self.warm_upgrade_param.get(slot_name, {}) + if len(slot_config) == 0: + return False, ("%s config not found" % slot_name) + + # linecard present check + slot_present_config = slot_config.get("present", {}) + if len(slot_present_config) != 0: + ret, log = self.linecard_present_check(slot_name, slot_present_config) + if ret is False: + return False, log + + # match file_type and chain_num get chain_config + file_type_config = slot_config.get(file_type, {}) + chain_name = "chain%d" % chain + chain_list = file_type_config.get(chain_name, []) + self.__warm_upgrade_config_list = [] + for refresh_config in chain_list: + # refresh_file existence check + refresh_file_judge_flag = refresh_config.get("refresh_file_judge_flag", 0) + if refresh_file_judge_flag == 1: + refresh_file = refresh_config.get("refresh_file", None) + if not os.path.isfile(refresh_file): + log = "%s not found" % refresh_file + return False, log + # each refresh_config add as an instance of RefreshUpgrade Class + refresh_instance = RefreshUpgrade(refresh_config, slot, main_type, sub_type) + self.__warm_upgrade_config_list.append(refresh_instance) + + ret, log = self.start_warmupgrade() + if ret is False: + warmupgradeerror("doing warm upgrade failed") + warmupgradeerror(log) + return ret, log + + except Exception as e: + log = "Exception happend, error log : %s" % str(e) + return False, log + return True, "all success" + + def do_warm_upgrade(self, file, main_type, sub_type, slot, file_type, chain): + print("+================================+") + print("|Begin warm upgrade, please wait..|") + ret, log = self.do_warmupgrade(file, main_type, sub_type, slot, file_type, chain) + if ret: + print("| warm upgrade succeeded! |") + print("+================================+") + sys.exit(0) + else: + print("| warm upgrade failed! |") + print("+================================+") + print("FAILED REASON:") + print("%s" % log) + sys.exit(1) + + +@click.group(invoke_without_command=True, context_settings=CONTEXT_SETTINGS) +@click.argument('file', required=True) +@click.argument('main_type', required=True) +@click.argument('sub_type', required=True) +@click.argument('slot', required=True) +@click.argument('file_type', required=True) +@click.argument('chain', required=True) +def main(file, main_type, sub_type, slot, file_type, chain): + '''warm upgrade''' + signal_init() + debug_init() + platform = WarmBasePlatform() + platform.do_warm_upgrade(file, int(main_type, 16), int(sub_type, 16), int(slot), file_type, int(chain)) + + +# warm upgrade +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/service/device_i2c.service b/platform/broadcom/sonic-platform-modules-ragile/common/service/device_i2c.service deleted file mode 100755 index 136034900aaf..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/common/service/device_i2c.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description= ragile Global Initialize I2c drivers. -After=pddf-platform-init.service -Before=pmon.service -DefaultDependencies=no - -[Service] -Type=oneshot -ExecStart=/usr/local/bin/device_i2c.py start -ExecStop=/usr/local/bin/device_i2c.py stop -RemainAfterExit=yes - -[Install] -WantedBy=multi-user.target - diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_driver.service b/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_driver.service new file mode 100644 index 000000000000..08a49d695c92 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_driver.service @@ -0,0 +1,15 @@ +[Unit] +Description= Global Initialize platform drivers. +After=local-fs.target +Before=pmon.service platform_process.service +#DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/platform_driver.py start +ExecStop=/usr/local/bin/platform_driver.py stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_process.service b/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_process.service new file mode 100644 index 000000000000..7bd853152752 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/service/platform_process.service @@ -0,0 +1,15 @@ +[Unit] +Description= Global Load process. +After=platform_driver.service +Requires=platform_driver.service +#DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/platform_process.py start +ExecStop=/usr/local/bin/platform_process.py stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/__init__.py new file mode 100644 index 000000000000..b70995a582fc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "thermal", "psu", "fan", "fan_drawer", "watchdog"] +from . import platform diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/chassis.py new file mode 100644 index 000000000000..adbd4e746c36 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/chassis.py @@ -0,0 +1,520 @@ +#!/usr/bin/env python3 + +############################################################################# +# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import time + import sys + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.psu import Psu + # from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer + from sonic_platform.thermal import Thermal + # from sonic_platform.watchdog import Watchdog + from sonic_platform.component import Component + from sonic_platform.eeprom import Eeprom + from sonic_platform.dcdc import Dcdc + from plat_hal.baseutil import baseutil + + from plat_hal.interface import interface + +except ImportError as error: + raise ImportError(str(error) + "- required module not found")from error + + +class Chassis(ChassisBase): + """ + Platform-specific Chassis class + """ + # List of Dcdc objects representing all dcdc + # available on the chassis + _dcdc_list = None + + STATUS_INSERTED = "1" + STATUS_REMOVED = "0" + STATUS_NORMAL = "0" + STATUS_ABNORMAL = "1" + sfp_present_dict = {} + fan_present_dict = {} + voltage_status_dict = {} + + def __init__(self): + ChassisBase.__init__(self) + self._dcdc_list = [] + self.int_case = interface() + # Initialize SFP list + + # sfp.py will read eeprom contents and retrive the eeprom data. + # It will also provide support sfp controls like reset and setting + # low power mode. + # We pass the eeprom path and sfp control path from chassis.py + # So that sfp.py implementation can be generic to all platforms + try: + self._sfp_list = [] + self.port_num = baseutil.get_config().get("sfps", None).get("port_num", 0) + self.port_start_index = baseutil.get_config().get("sfps", None).get("port_index_start", 0) + # fix problem with first index is 1, we add a fake sfp node + if self.port_start_index == 1: + self._sfp_list.append(Sfp(1)) + + # sfp id always start at 1 + for index in range(1, self.port_num + 1): + self._sfp_list.append(Sfp(index)) + + for i in range(self.port_start_index, self.port_start_index + self.port_num): + self.sfp_present_dict[i] = self.STATUS_REMOVED + + except Exception as err: + print("SFP init error: %s" % str(err)) + + try: + self._eeprom = Eeprom(self.int_case) + except Exception as err: + print("EEPROM INIT ERROR %s" % str(err)) + + # Initialize watchdog + # self._watchdog = Watchdog() + fantray_num = self.int_case.get_fan_total_number() + for index in range(fantray_num): + fandrawer = FanDrawer(self.int_case, index + 1) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + + psu_num = self.int_case.get_psu_total_number() + for index in range(psu_num): + psuobj = Psu(self.int_case, index + 1) + self._psu_list.append(psuobj) + + thermal_num = self.int_case.get_temp_id_number() + for index in range(thermal_num): + thermalobj = Thermal(self.int_case, index + 1) + self._thermal_list.append(thermalobj) + + component_num = self.int_case.get_cpld_total_number() + for index in range(component_num): + componentobj = Component(self.int_case, index + 1) + self._component_list.append(componentobj) + + dcdc_num = self.int_case.get_dcdc_total_number() + for index in range(dcdc_num): + dcdcobj = Dcdc(self.int_case, index + 1) + self._dcdc_list.append(dcdcobj) + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + name = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + name = sys_eeprom.modelstr(e) + if name is None: + return '' + return name + + 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 chassis + Returns: + string: Model/part number of chassis + """ + model = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + model = sys_eeprom.modelnumber(e) + if model is None: + return '' + return model + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + serial_number = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + serial_number = sys_eeprom.serial_number_str(e) + if serial_number is None: + return '' + + return serial_number + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + device_version = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + device_version = sys_eeprom.deviceversion(e) + if device_version is None: + return '' + + return device_version + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self.get_serial_number() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis 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 initizalize_system_led(self): + return True + + def set_status_led(self, color): + return False + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + ret, color = self.int_case.get_led_color_by_type('SYS_LED') + if ret is True: + return color + return 'N/A' + + 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' + """ + base_mac = '' + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return '' + + e = sys_eeprom.read_eeprom() + base_mac = sys_eeprom.base_mac_addr(e) + if base_mac is None: + return '' + + return base_mac.upper() + + 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. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + sys_eeprom = self.get_eeprom() + if sys_eeprom is None: + return {} + return sys_eeprom.system_eeprom_info() + + def get_thermal_manager(self): + """ + Retrieves thermal manager class on this chassis + :return: A class derived from ThermalManagerBase representing the + specified thermal manager. ThermalManagerBase is returned as default + """ + return False + + 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. + """ + reset_num = self.int_case.get_cpu_reset_num() + # cold reboot + if reset_num == 0: + return (self.REBOOT_CAUSE_POWER_LOSS, None) + + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + def get_module(self, index): + """ + Retrieves module represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the module to + retrieve + + Returns: + An object dervied from ModuleBase representing the specified + module + """ + module = None + + try: + if self.get_num_modules(): + module = self._module_list[index] + except IndexError: + sys.stderr.write("Module index {} out of range (0-{})\n".format( + index, len(self._module_list) - 1)) + + return module + + def get_fan_drawer(self, index): + """ + Retrieves fan drawers represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the fan drawer to + retrieve + + Returns: + An object dervied from FanDrawerBase representing the specified fan + drawer + """ + fan_drawer = None + + try: + if self.get_num_fan_drawers(): + fan_drawer = self._fan_drawer_list[index] + except IndexError: + sys.stderr.write("Fan drawer index {} out of range (0-{})\n".format( + index, len(self._fan_drawer_list) - 1)) + + return fan_drawer + + 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. + """ + + change_event_dict = {"fan": {}, "sfp": {}, "voltage": {}} + + start_time = time.time() + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print("get_change_event:Invalid timeout value: %s" % timeout) + return False, change_event_dict + + end_time = start_time + timeout + if start_time > end_time: + print("get_change_event:time wrap / invalid timeout value: %s" % timeout) + return False, change_event_dict # Time wrap or possibly incorrect timeout + try: + while timeout >= 0: + # check for sfp + sfp_change_dict = self.get_transceiver_change_event() + # check for fan + fan_change_dict = self.get_fan_change_event() + # check for voltage + voltage_change_dict = self.get_voltage_change_event() + + if sfp_change_dict or fan_change_dict or voltage_change_dict: + change_event_dict["sfp"] = sfp_change_dict + change_event_dict["fan"] = fan_change_dict + change_event_dict["voltage"] = voltage_change_dict + return True, change_event_dict + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, change_event_dict + except Exception as e: + print(e) + print("get_change_event: Should not reach here.") + return False, change_event_dict + + def get_transceiver_change_event(self): + current_sfp_present_dict = {} + ret_dict = {} + + # Check for OIR events and return ret_dict + for i in range(self.port_start_index, self.port_start_index + self.port_num): + sfp = self._sfp_list[i] + if sfp.get_presence(): + current_sfp_present_dict[i] = self.STATUS_INSERTED + + else: + current_sfp_present_dict[i] = self.STATUS_REMOVED + + # Update reg value + if current_sfp_present_dict == self.sfp_present_dict: + return ret_dict + + for index, status in current_sfp_present_dict.items(): + if self.sfp_present_dict[index] != status: + ret_dict[index] = status + + self.sfp_present_dict = current_sfp_present_dict + + return ret_dict + + def get_fan_change_event(self): + current_fan_present_dict = {} + ret_dict = {} + + # Check for OIR events and return ret_dict + for index, fan in enumerate(self._fan_list): + if fan.get_presence() is True: + current_fan_present_dict[index] = self.STATUS_INSERTED + else: + current_fan_present_dict[index] = self.STATUS_REMOVED + + if len(self.fan_present_dict) == 0: # first time + self.fan_present_dict = current_fan_present_dict + return {} + + if current_fan_present_dict == self.fan_present_dict: + return {} + + # updated fan_present_dict + for index, status in current_fan_present_dict.items(): + if self.fan_present_dict[index] != status: + ret_dict[str(index)] = status + self.fan_present_dict = current_fan_present_dict + return ret_dict + + def get_voltage_change_event(self): + current_voltage_status_dict = {} + ret_dict = {} + + # Check for OIR events and return ret_dict + for index, dcdc in enumerate(self._dcdc_list): + name = dcdc.get_name() + value = dcdc.get_value() + high = dcdc.get_high_threshold() + low = dcdc.get_low_threshold() + if (value is None) or (value > high) or (value < low): + current_voltage_status_dict[name] = self.STATUS_ABNORMAL + else: + current_voltage_status_dict[name] = self.STATUS_NORMAL + + if len(self.voltage_status_dict) == 0: # first time + self.voltage_status_dict = current_voltage_status_dict + return {} + + if current_voltage_status_dict == self.voltage_status_dict: + return {} + + # updated voltage_status_dict + for name, status in current_voltage_status_dict.items(): + if self.voltage_status_dict[name] != status: + ret_dict[name] = status + self.voltage_status_dict = current_voltage_status_dict + return ret_dict + + diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/component.py new file mode 100644 index 000000000000..3181d0508d45 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/component.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python3 + +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import time + import subprocess + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Component(ComponentBase): + """Platform-specific Component class""" + + def __init__(self, interface_obj, index): + self.cpld_dict = {} + self.int_case = interface_obj + self.index = index + self.update_time = 0 + self.cpld_id = "CPLD" + str(index) + + def cpld_dict_update(self): + local_time = time.time() + if not self.cpld_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + self.cpld_dict = self.int_case.get_cpld_version_by_id(self.cpld_id) + + def get_slot(self): + self.cpld_dict_update() + return self.cpld_dict["Slot"] + + def get_warm_upgrade_flag(self): + self.cpld_dict_update() + return self.cpld_dict["Warm"] + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + self.cpld_dict_update() + return self.cpld_dict["Name"] + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + self.cpld_dict_update() + return self.cpld_dict["Desc"] + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Note: the firmware version will be read from HW + + Returns: + A string containing the firmware version of the component + """ + self.cpld_dict_update() + return self.cpld_dict["Version"] + + def get_available_firmware_version(self, image_path): + """ + Retrieves the available firmware version of the component + + Note: the firmware version will be read from image + + Args: + image_path: A string, path to firmware image + + Returns: + A string containing the available firmware version of the component + """ + raise NotImplementedError + + def get_firmware_update_notification(self, image_path): + """ + Retrieves a notification on what should be done in order to complete + the component firmware update + + Args: + image_path: A string, path to firmware image + + Returns: + A string containing the component firmware update notification if required. + By default 'None' value will be used, which indicates that no actions are required + """ + return None + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + This API performs firmware installation only: this may/may not be the same as firmware update. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this must be done manually by user + + Note: in case immediate actions are required to complete the component firmware update + (e.g., reboot, power cycle, etc.) - will be done automatically by API and no return value provided + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + cmdstr = "upgrade.py cold %s %d" % (image_path, self.get_slot()) + status, output = subprocess.getstatusoutput(cmdstr) + if status == 0: + print("INFO: %s firmware upgrade succeeded" % self.get_name()) + return True + print("%s upgrade failed. status:%d, output:\n%s" % (self.get_name(), status, output)) + return False + + def update_firmware(self, image_path): + """ + Updates firmware of the component + + This API performs firmware update: it assumes firmware installation and loading in a single call. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically by API + + Args: + image_path: A string, path to firmware image + + Raises: + RuntimeError: update failed + """ + if self.get_warm_upgrade_flag() == 1: # use warm upgrade + cmdstr = "upgrade.py warm %s %d" % (image_path, self.get_slot()) + else: + cmdstr = "upgrade.py cold %s %d" % (image_path, self.get_slot()) + status, output = subprocess.getstatusoutput(cmdstr) + if status == 0: + if self.get_warm_upgrade_flag() != 1: # not support warm upgrade, need to reboot + reboot_log = "update %s firmware %s, the system is going to reboot now." % (self.get_name(), image_path) + reboot_log_cmd = "echo '%s' > /dev/ttyS0" % reboot_log + print(reboot_log) + subprocess.call(reboot_log_cmd) + subprocess.call("sync") + time.sleep(3) + subprocess.call("reboot") + print("INFO: %s firmware version up-to-date" % self.get_name()) + return None + raise RuntimeError(output) + + def auto_update_firmware(self, image_path, boot_type): + """ + Updates firmware of the component + + This API performs firmware update automatically based on boot_type: it assumes firmware installation + and/or creating a loading task during the reboot, if needed, in a single call. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically during the reboot. + The loading task will be created by API. + + Args: + image_path: A string, path to firmware image + boot_type: A string, reboot type following the upgrade + - none/fast/warm/cold + + Returns: + Output: A return code + return_code: An integer number, status of component firmware auto-update + - return code of a positive number indicates successful auto-update + - status_installed = 1 + - status_updated = 2 + - status_scheduled = 3 + - return_code of a negative number indicates failed auto-update + - status_err_boot_type = -1 + - status_err_image = -2 + - status_err_unknown = -3 + + Raises: + RuntimeError: auto-update failure cause + """ + if self.get_warm_upgrade_flag() == 1: # use warm upgrade + cmdstr = "upgrade.py warm %s %d" % (image_path, self.get_slot()) + else: + cmdstr = "upgrade.py cold %s %d" % (image_path, self.get_slot()) + status, output = subprocess.getstatusoutput(cmdstr) + if status == 0: + reboot_log = "update %s firmware %s, the system is going to reboot now." % (self.get_name(), image_path) + reboot_log_cmd = "echo '%s' > /dev/ttyS0" % reboot_log + print(reboot_log) + subprocess.call(reboot_log_cmd) + subprocess.call("sync") + time.sleep(3) + if boot_type == "none": + subprocess.call("sync") + elif boot_type == "cold": + subprocess.call("reboot_ctrl.py reset power") + else: + subprocess.call("reboot") + print("INFO: %s firmware version up-to-date" % self.get_name()) + return 2 + print("%s upgrade failed. status:%d, output:\n%s" % (self.get_name(), status, output)) + return -3 diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/dcdc.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/dcdc.py new file mode 100644 index 000000000000..494d4aa610dc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/dcdc.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## +import time + + +class Dcdc(object): + + def __init__(self, interface_obj, index): + self.dcdc_dict = {} + self.int_case = interface_obj + self.index = index + self.update_time = 0 + self.dcdc_id = "DCDC" + str(index) + + def dcdc_dict_update(self): + local_time = time.time() + if not self.dcdc_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + self.dcdc_dict = self.int_case.get_dcdc_by_id(self.dcdc_id) + + def get_name(self): + """ + Retrieves the name of the sensor + + Returns: + string: The name of the sensor + """ + self.dcdc_dict_update() + return self.dcdc_dict["Name"] + + def get_value(self): + """ + Retrieves current value reading from sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["Value"] + if value is None: + value = 0 + return round(float(value), 3) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["High"] + if value is None: + value = 0 + return round(float(value), 3) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["Low"] + if value is None: + value = 0 + return round(float(value), 3) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["Max"] + if value is None: + value = 0 + return round(float(value), 3) + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of sensor + """ + self.dcdc_dict_update() + value = self.dcdc_dict["Min"] + if value is None: + value = 0 + return round(float(value), 3) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/eeprom.py new file mode 100644 index 000000000000..05fcc3c25678 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/eeprom.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +######################################################################## +# +# Module contains platform specific implementation of SONiC Platform +# Base API and provides the EEPROMs' information. +# +# The different EEPROMs available are as follows: +# - System EEPROM : Contains Serial number, Service tag, Base MA +# address, etc. in ONIE TlvInfo EEPROM format. +# - PSU EEPROM : Contains Serial number, Part number, Service Tag, +# PSU type, Revision. +# - Fan EEPROM : Contains Serial number, Part number, Service Tag, +# Fan type, Number of Fans in Fantray, Revision. +######################################################################## + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as error: + raise ImportError(str(error) + "- required module not found") from error + + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, interface_obj): + self.int_case = interface_obj + self.name = "ONIE_E2" + + eeprom_path = self.int_case.get_onie_e2_path(self.name) + if eeprom_path is None: + raise ValueError("get eeprom path failed") + + super().__init__(eeprom_path, 0, "", True) + + def modelnumber(self, e): + ''' + Returns the value field of the model(part) number TLV as a string + ''' + (is_valid, t) = self.get_tlv_field(e, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return super().part_number_str(e) + + return t[2].decode("ascii") + + def deviceversion(self, e): + ''' + Returns the value field of the Device Version as a string + ''' + (is_valid, t) = self.get_tlv_field(e, self._TLV_CODE_DEVICE_VERSION) + if not is_valid: + return "N/A" + + return str(ord(t[2])) + + def 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. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + ''' + sys_eeprom_dict = {} + e = self.read_eeprom() + if self._TLV_HDR_ENABLED: + if not self.is_valid_tlvinfo_header(e): + return {} + total_len = (e[9] << 8) | e[10] + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_len + else: + tlv_index = self.eeprom_start + tlv_end = self._TLV_INFO_MAX_LEN + + while (tlv_index + 2) < len(e) and tlv_index < tlv_end: + if not self.is_valid_tlv(e[tlv_index:]): + break + + tlv = e[tlv_index:tlv_index + 2 + e[tlv_index + 1]] + code = "0x%02X" % tlv[0] + name, value = self.decoder(None, tlv) + sys_eeprom_dict[code] = value + + if e[tlv_index] == self._TLV_CODE_QUANTA_CRC or \ + e[tlv_index] == self._TLV_CODE_CRC_32: + break + tlv_index += e[tlv_index + 1] + 2 + + return sys_eeprom_dict diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan.py new file mode 100644 index 000000000000..9499e721a0f9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python3 +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform. +# +######################################################################## + +try: + import time + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, interface_obj, fantray_index, fan_index, psu_fan=False, psu_index=0): + self.fan_dict = {} + self.int_case = interface_obj + self.fantray_index = fantray_index + self.fan_index = fan_index + self.psu_index = psu_index + self.is_psu_fan = psu_fan + self.update_time = 0 + if not self.is_psu_fan: + self.name = "FAN" + str(fantray_index) + else: + self.name = "PSU" + str(psu_index) + + def fan_dict_update(self): + local_time = time.time() + if not self.fan_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + if not self.is_psu_fan: + self.fan_dict = self.int_case.get_fan_info(self.name) + else: + self.fan_dict = self.int_case.get_psu_fru_info(self.name) + + def get_name(self): + """ + Retrieves the fan name + Returns: + string: The name of the device + """ + if not self.is_psu_fan: + return "Fantray{}_{}".format(self.fantray_index, self.fan_index) + return "PSU{}_FAN{}".format(self.psu_index, self.fan_index) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + string: Part number of FAN + """ + if not self.is_psu_fan: + self.fan_dict_update() + return self.fan_dict["NAME"] + return 'N/A' + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + string: Serial number of FAN + """ + if not self.is_psu_fan: + self.fan_dict_update() + return self.fan_dict["SN"] + return 'N/A' + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + if not self.is_psu_fan: + return self.int_case.get_fan_presence(self.name) + return self.int_case.get_psu_presence(self.name) + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + if not self.get_presence(): + return False + + if not self.is_psu_fan: + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor pwm + rotor_name = "Rotor" + str(self.fan_index) + value = fan_dir[rotor_name]["Speed"] + min_speed = fan_dir[rotor_name]["SpeedMin"] + max_speed = fan_dir[rotor_name]["SpeedMax"] + tolerance = fan_dir[rotor_name]["Tolerance"] + else: + psu_status_dict = self.int_case.get_psu_status(self.name) + value = psu_status_dict["FanSpeed"]["Value"] + min_speed = psu_status_dict["FanSpeed"]["Min"] + max_speed = psu_status_dict["FanSpeed"]["Max"] + tolerance = psu_status_dict["FanSpeed"]["Tolerance"] + + if isinstance(tolerance, str) or tolerance is None: + tolerance = 30 + + if isinstance(value, str) or value is None: + return False + + if value < min_speed: + return False + + speed = int(value * 100 / max_speed) + if speed > 100: + speed = 100 + elif speed < 0: + speed = 0 + target = self.get_target_speed() + + if (speed - target) > target * tolerance / 100: + return False + if (target - speed) > target * tolerance / 100: + return False + + 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 True + + def get_direction(self): + """ + Retrieves the fan airflow direction + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Notes: + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. + """ + self.fan_dict_update() + air_flow = self.fan_dict["AirFlow"] + if air_flow is not None: + return air_flow + return self.FAN_DIRECTION_NOT_APPLICABLE + + 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 not self.get_presence(): + return 0 + + if not self.is_psu_fan: + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor pwm + rotor_name = "Rotor" + str(self.fan_index) + value = fan_dir[rotor_name]["Speed"] + max_speed = fan_dir[rotor_name]["SpeedMax"] + else: + psu_status_dict = self.int_case.get_psu_status(self.name) + value = psu_status_dict["FanSpeed"]["Value"] + max_speed = psu_status_dict["FanSpeed"]["Max"] + + if isinstance(value, str) or value is None: + return 0 + pwm = value * 100 / max_speed + if pwm > 100: + pwm = 100 + elif pwm < 0: + pwm = 0 + return int(pwm) + + 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 + """ + # The default tolerance value is fixed as 30% + if not self.is_psu_fan: + fan_dir = {} + fan_dir = self.int_case.get_fan_info_rotor(self.name) + # get fan rotor tolerance + rotor_name = "Rotor" + str(self.fan_index) + tolerance = fan_dir[rotor_name]["Tolerance"] + else: + psu_status_dict = self.int_case.get_psu_status(self.name) + tolerance = psu_status_dict["FanSpeed"]["Tolerance"] + + if isinstance(tolerance, str) or tolerance is None: + return 30 + return tolerance + + def fan_set_speed_pwm(self, pwm): + status = self.int_case.set_fan_speed_pwm(self.name, self.fan_index, pwm) + if status == -1: + return False + return True + + def set_speed(self, speed): + """ + Set fan speed to expected value + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + bool: True if set success, False if fail. + """ + if not self.is_psu_fan: + return self.fan_set_speed_pwm(speed) + return self.int_case.set_psu_fan_speed_pwm(self.name, int(speed)) + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if set success, False if fail. + """ + # not supported + return False + + def get_status_led(self): + """ + Gets the state of the Fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.is_psu_fan: + # No LED available for PSU Fan + return 'N/A' + + if not self.get_presence(): + return 'N/A' + + ret, color = self.int_case.get_fan_led(self.name) + if ret is True: + return color + return 'N/A' + + 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) + """ + if not self.is_psu_fan: + # get fan rotor pwm + pwm = int(self.int_case.get_fan_speed_pwm(self.name, self.fan_index)) + else: + psu_status_dict = self.int_case.get_psu_status(self.name) + if psu_status_dict["InputStatus"] is False: + pwm = 0 + else: + pwm = self.get_speed() # target equal to real pwm, to avoid alarm + return int(pwm) + + def get_vendor(self): + """ + Retrieves the vendor name of the fan + + Returns: + string: Vendor name of fan + """ + if not self.is_psu_fan: + return "WB" + return 'N/A' + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + if not self.is_psu_fan: + self.fan_dict_update() + return self.fan_dict["HW"] + return 'N/A' diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..f0b039648158 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/fan_drawer.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +# +# fan_drawer_base.py +# +# Abstract base class for implementing a platform-specific class with which +# to interact with a fan drawer module in SONiC +# + +try: + import time + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class FanDrawer(FanDrawerBase): + """ + Abstract base class for interfacing with a fan drawer + """ + # Device type definition. Note, this is a constant. + DEVICE_TYPE = "fan_drawer" + + def __init__(self, interface_obj, fantray_index): + FanDrawerBase.__init__(self) + self.fantray_dict = {} + self.fantray_update_time = 0 + self.fantray_index = fantray_index + self.int_case = interface_obj + self.fantrayname = "FAN" + str(fantray_index) + self.num_fans_per_fantray = self.int_case.get_fan_rotor_number(self.fantrayname) + for i in range(self.num_fans_per_fantray): + self._fan_list.append(Fan(interface_obj, fantray_index, i + 1)) + + def fantray_dict_update(self): + local_time = time.time() + # update data every 1 seconds + if not self.fantray_dict or (local_time - self.fantray_update_time) >= 1: + self.fantray_update_time = local_time + self.fantray_dict = self.int_case.get_fan_info(self.fantrayname) + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return "Fantray{}".format(self.fantray_index) + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + return self.int_case.get_fan_presence(self.fantrayname) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + string: Part number of FAN + """ + self.fantray_dict_update() + return self.fantray_dict["NAME"] + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + string: Serial number of FAN + """ + self.fantray_dict_update() + return self.fantray_dict["SN"] + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + self.fantray_dict_update() + return self.fantray_dict["HW"] + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + for i in range(self.num_fans_per_fantray): + if self._fan_list[i].get_status() is False: + return False + 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 True + + def get_num_fans(self): + """ + Retrieves the number of fans available on this fan drawer + Returns: + An integer, the number of fan modules available on this fan drawer + """ + return len(self._fan_list) + + def get_all_fans(self): + """ + Retrieves all fan modules available on this fan drawer + Returns: + A list of objects derived from FanBase representing all fan + modules available on this fan drawer + """ + return self._fan_list + + 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 + """ + # not supported + return False + + def get_status_led(self): + """ + Gets the state of the Fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if not self.get_presence(): + return 'N/A' + + ret, color = self.int_case.get_fan_led(self.fantrayname) + if ret is True: + return color + return 'N/A' + + def get_maximum_consumed_power(self): + """ + Retrives the maximum power drawn by Fan Drawer + + Returns: + A float, with value of the maximum consumable power of the + component. + """ + self.fantray_dict_update() + return self.fantray_dict["PowerMax"] diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/pcie.py new file mode 100644 index 000000000000..8ea66f339e96 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/pcie.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +######################################################################## +# +# Module contains a platform specific implementation of SONiC Platform +# Base PCIe class +# +######################################################################## + +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Pcie(PcieUtil): + """Platform-specific Pcie class""" + + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/platform.py similarity index 50% rename from platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/platform.py rename to platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/platform.py index 8595e80692df..4d6fe03d93ac 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/platform.py +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/platform.py @@ -1,23 +1,24 @@ +#!/usr/bin/env python3 + ############################################################################# -# PDDF +# # Module contains an implementation of SONiC Platform Base API and # provides the platform information # ############################################################################# - try: - from sonic_platform_pddf_base.pddf_platform import PddfPlatform + 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") + raise ImportError(str(e) + "- required module not found") from e -class Platform(PddfPlatform): +class Platform(PlatformBase): """ - PDDF Platform-Specific Platform Class + Platform-specific class """ def __init__(self): - PddfPlatform.__init__(self) - - # Provide the functions/variables below for which implementation is to be overwritten + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/psu.py new file mode 100644 index 000000000000..a9f7e87d2027 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/psu.py @@ -0,0 +1,359 @@ +#!/usr/bin/env python3 +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + + +try: + import time + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Psu(PsuBase): + """Platform-specific PSU class""" + + def __init__(self, interface_obj, index): + self.psu_dict = {} + self.psu_status_dict = {} + self.psu_power_dict = {} + self._fan_list = [] + self._thermal_list = [] + self.int_case = interface_obj + self.index = index + self.name = "PSU" + str(index) + + self.psu_dict_update_time = 0 + self.psu_status_dict_update_time = 0 + self.psu_power_dict_update_time = 0 + + self._fan_list.append(Fan(self.int_case, 1, 1, psu_fan=True, psu_index=index)) + + def psu_dict_update(self): + local_time = time.time() + if not self.psu_dict or (local_time - self.psu_dict_update_time) >= 1: # update data every 1 seconds + self.psu_dict_update_time = local_time + self.psu_dict = self.int_case.get_psu_fru_info(self.name) + + def psu_status_dict_update(self): + local_time = time.time() + if not self.psu_status_dict or ( + local_time - self.psu_status_dict_update_time) >= 1: # update data every 1 seconds + self.psu_status_dict_update_time = local_time + self.psu_status_dict = self.int_case.get_psu_status(self.name) + + def psu_power_dict_update(self): + local_time = time.time() + if not self.psu_power_dict or ( + local_time - self.psu_power_dict_update_time) >= 1: # update data every 1 seconds + self.psu_power_dict_update_time = local_time + self.psu_power_dict = self.int_case.get_psu_power_status(self.name) + + 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 Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + return self.int_case.get_psu_presence(self.name) + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + self.psu_dict_update() + return self.psu_dict["DisplayName"] + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + self.psu_dict_update() + return self.psu_dict["SN"] + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + return self.int_case.get_psu_input_output_status(self.name) + + 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 True + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Voltage"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Current"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Power"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + 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.int_case.get_psu_input_output_status(self.name) + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if not self.get_presence(): + return "N/A" + if self.int_case.get_psu_input_output_status(self.name): + return self.STATUS_LED_COLOR_GREEN + return self.STATUS_LED_COLOR_RED + + 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 + Returns: + bool: True if status LED state is set successfully, False if + not + """ + # not supported + return False + + 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 + """ + self.psu_status_dict_update() + value = self.psu_status_dict["Temperature"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + 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 + """ + self.psu_status_dict_update() + value = self.psu_status_dict["Temperature"]["Max"] + if value is None: + value = 0 + return round(float(value), 1) + + 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 + """ + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Voltage"]["HighAlarm"] + if value is None: + value = 0 + return round(float(value), 1) + + 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 + """ + self.psu_power_dict_update() + value = self.psu_power_dict["Outputs"]["Voltage"]["LowAlarm"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_input_voltage(self): + """ + Get the input voltage of the PSU + + Returns: + A float number, the input voltage in volts, + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Inputs"]["Voltage"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_input_current(self): + """ + Get the input electric current of the PSU + + Returns: + A float number, the input current in amperes, e.g 220.3 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Inputs"]["Current"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_input_power(self): + """ + Get the input current energy of the PSU + + Returns: + A float number, the input power in watts, e.g. 302.6 + """ + self.psu_status_dict_update() + if self.psu_status_dict["InputStatus"] is False: + value = 0 + else: + self.psu_power_dict_update() + value = self.psu_power_dict["Inputs"]["Power"]["Value"] + if value is None: + value = 0 + return round(float(value), 1) + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + self.psu_dict_update() + return self.psu_dict["HW"] + + def get_vendor(self): + """ + Retrieves the vendor name of the psu + + Returns: + string: Vendor name of psu + """ + self.psu_dict_update() + return self.psu_dict["VENDOR"] + + 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 False + + def get_thermal(self, index): + """ + Retrieves thermal unit represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the thermal to + retrieve + + Returns: + An object dervied from ThermalBase representing the specified thermal + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/sfp.py new file mode 100644 index 000000000000..4667d3efcd7c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/sfp.py @@ -0,0 +1,480 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +# +# *_device.py config version instruction: +# ver 1.0 - platform api: +# "presence_cpld": { +# "dev_id": { +# [dev_id]: { +# "offset": { +# [offset]: [port_id] +# } +# } +# } +# } +# "reset_cpld": { +# "dev_id": { +# [dev_id]: { +# "offset": { +# [offset]: [port_id] +# } +# } +# } +# } +# ver 2.0 - wb_plat: +# "presence_path": "/xx/wb_plat/xx[port_id]/present" +# "eeprom_path": "/sys/bus/i2c/devices/i2c-[bus]/[bus]-0050/eeprom" +# "reset_path": "/xx/wb_plat/xx[port_id]/reset" +############################################################################# +import sys +import time +import syslog +import traceback +from abc import abstractmethod + +configfile_pre = "/usr/local/bin/" +sys.path.append(configfile_pre) + +try: + from platform_intf import * + from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase + from plat_hal.baseutil import baseutil + +except ImportError as error: + raise ImportError(str(error) + "- required module not found") from error + +LOG_DEBUG_LEVEL = 1 +LOG_WARNING_LEVEL = 2 +LOG_ERROR_LEVEL = 3 + + +class Sfp(SfpOptoeBase): + + OPTOE_DRV_TYPE1 = 1 + OPTOE_DRV_TYPE2 = 2 + OPTOE_DRV_TYPE3 = 3 + + # index must start at 1 + def __init__(self, index): + SfpOptoeBase.__init__(self) + self.sfp_type = None + sfp_config = baseutil.get_config().get("sfps", None) + self.log_level_config = sfp_config.get("log_level", LOG_WARNING_LEVEL) + # Init instance of SfpCust + ver = sfp_config.get("ver", None) + if ver is None: + self._sfplog(LOG_ERROR_LEVEL, "Get Ver Config Error!") + vers = int(float(ver)) + if vers == 1: + self._sfp_api = SfpV1(index) + elif vers == 2: + self._sfp_api = SfpV2(index) + else: + self._sfplog(LOG_ERROR_LEVEL, "Get SfpVer Error!") + + def get_eeprom_path(self): + return self._sfp_api._get_eeprom_path() + + def read_eeprom(self, offset, num_bytes): + return self._sfp_api.read_eeprom(offset, num_bytes) + + def write_eeprom(self, offset, num_bytes, write_buffer): + return self._sfp_api.write_eeprom(offset, num_bytes, write_buffer) + + def get_presence(self): + return self._sfp_api.get_presence() + + def get_transceiver_info(self): + # temporary solution for a sonic202111 bug + transceiver_info = super().get_transceiver_info() + try: + if transceiver_info["vendor_rev"] is not None: + transceiver_info["hardware_rev"] = transceiver_info["vendor_rev"] + except BaseException: + print(traceback.format_exc()) + return None + return transceiver_info + + def reset(self): + if self.get_presence() is False: + return False + + if self.sfp_type is None: + self.refresh_xcvr_api() + + if self.sfp_type == 'SFP': + self._sfplog(LOG_ERROR_LEVEL, 'SFP does not support reset') + return False + + self._sfplog(LOG_DEBUG_LEVEL, 'resetting...') + ret = self._sfp_api.set_reset(True) + if ret: + time.sleep(0.5) + ret = self._sfp_api.set_reset(False) + + return ret + + def get_lpmode(self): + if self.get_presence() is False: + return False + + if self.sfp_type is None: + self.refresh_xcvr_api() + + if self.sfp_type == 'SFP': + self._sfplog(LOG_WARNING_LEVEL, 'SFP does not support lpmode') + return False + + # implement in future + + return False + + def set_lpmode(self, lpmode): + if self.get_presence() is False: + return False + + if self.sfp_type is None or self._xcvr_api is None: + self.refresh_xcvr_api() + + if self.sfp_type == 'QSFP-DD': + return SfpOptoeBase.set_lpmode(self, lpmode) + if self.sfp_type == 'QSFP': + if lpmode: + return self._xcvr_api.set_power_override(True, lpmode) + return self._xcvr_api.set_power_override(False, lpmode) + self._sfplog(LOG_WARNING_LEVEL, 'SFP does not support lpmode') + return False + + def set_optoe_write_max(self, write_max): + """ + This func is declared and implemented by SONiC but we're not supported + so override it as NotImplemented + """ + self._sfplog(LOG_DEBUG_LEVEL, "set_optoe_write_max NotImplemented") + + def refresh_xcvr_api(self): + """ + Updates the XcvrApi associated with this SFP + """ + self._xcvr_api = self._xcvr_api_factory.create_xcvr_api() + class_name = self._xcvr_api.__class__.__name__ + optoe_type = None + # set sfp_type + if 'CmisApi' in class_name: + self.sfp_type = 'QSFP-DD' + optoe_type = self.OPTOE_DRV_TYPE3 + elif 'Sff8472Api' in class_name: + self.sfp_type = 'SFP' + optoe_type = self.OPTOE_DRV_TYPE2 + elif ('Sff8636Api' in class_name or 'Sff8436Api' in class_name): + self.sfp_type = 'QSFP' + optoe_type = self.OPTOE_DRV_TYPE1 + # set optoe driver + if optoe_type is not None: + self._sfp_api.set_optoe_type(optoe_type) + + def _sfplog(self, log_level, msg): + if log_level >= self.log_level_config: + try: + syslog.openlog("Sfp") + if log_level == LOG_DEBUG_LEVEL: + syslog.syslog(syslog.LOG_DEBUG, msg) + elif log_level == LOG_WARNING_LEVEL: + syslog.syslog(syslog.LOG_DEBUG, msg) + elif log_level == LOG_ERROR_LEVEL: + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + + except BaseException: + print(traceback.format_exc()) + + +class SfpCust(): + def __init__(self, index): + self.eeprom_path = None + self._init_config(index) + + def _init_config(self, index): + sfp_config = baseutil.get_config().get("sfps", None) + self.log_level_config = sfp_config.get("log_level", LOG_WARNING_LEVEL) + self._port_id = index + self.eeprom_retry_times = sfp_config.get("eeprom_retry_times", 0) + self.eeprom_retry_break_sec = sfp_config.get("eeprom_retry_break_sec", 0) + + def _get_eeprom_path(self): + return self.eeprom_path or None + + @abstractmethod + def get_presence(self): + pass + + def read_eeprom(self, offset, num_bytes): + try: + for i in range(self.eeprom_retry_times): + with open(self._get_eeprom_path(), mode='rb', buffering=0) as f: + f.seek(offset) + result = f.read(num_bytes) + # temporary solution for a sonic202111 bug + if len(result) < num_bytes: + result = result[::-1].zfill(num_bytes)[::-1] + if result is not None: + return bytearray(result) + time.sleep(self.eeprom_retry_break_sec) + continue + + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return None + + def write_eeprom(self, offset, num_bytes, write_buffer): + try: + for i in range(self.eeprom_retry_times): + ret = SfpOptoeBase.write_eeprom(self, offset, num_bytes, write_buffer) + if ret is False: + time.sleep(self.eeprom_retry_break_sec) + continue + break + + return ret + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + + @abstractmethod + def set_optoe_type(self, optoe_type): + pass + + @abstractmethod + def set_reset(self, reset): + pass + + def _convert_str_range_to_int_arr(self, range_str): + if not range_str: + return [] + + int_range_strs = range_str.split(',') + range_res = [] + for int_range_str in int_range_strs: + if '-' in int_range_str: + range_s = int(int_range_str.split('-')[0]) + range_e = int(int_range_str.split('-')[1]) + 1 + else: + range_s = int(int_range_str) + range_e = int(int_range_str) + 1 + + range_res = range_res + list(range(range_s, range_e)) + + return range_res + + def _sfplog(self, log_level, msg): + if log_level >= self.log_level_config: + try: + syslog.openlog("SfpCust") + if log_level == LOG_DEBUG_LEVEL: + syslog.syslog(syslog.LOG_DEBUG, msg) + elif log_level == LOG_WARNING_LEVEL: + syslog.syslog(syslog.LOG_DEBUG, msg) + elif log_level == LOG_ERROR_LEVEL: + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + + except BaseException: + print(traceback.format_exc()) + + +class SfpV1(SfpCust): + def _init_config(self, index): + super()._init_config(index) + # init presence path + sfp_config = baseutil.get_config().get("sfps", None) + self.presence_cpld = sfp_config.get("presence_cpld", None) + self.presence_val_is_present = sfp_config.get("presence_val_is_present", 0) + self._sfplog(LOG_DEBUG_LEVEL, "Done init presence path") + + # init reset path + self.reset_cpld = sfp_config.get("reset_cpld", None) + self.reset_val_is_reset = sfp_config.get("reset_val_is_reset", 0) + self._sfplog(LOG_DEBUG_LEVEL, "Done init cpld path") + + def get_presence(self): + if self.presence_cpld is None: + self._sfplog(LOG_ERROR_LEVEL, "presence_cpld is None!") + return False + try: + dev_id, offset, offset_bit = self._get_sfp_cpld_info(self.presence_cpld) + ret, info = platform_reg_read(0, dev_id, offset, 1) + if (ret is False + or info is None): + return False + return info[0] & (1 << offset_bit) == self.presence_val_is_present + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + + def read_eeprom(self, offset, num_bytes): + try: + for i in range(self.eeprom_retry_times): + ret, info = platform_sfp_read(self._port_id, offset, num_bytes) + if (ret is False + or info is None): + time.sleep(self.eeprom_retry_break_sec) + continue + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + for n in range(0, len(info)): + eeprom_raw[n] = info[n] + # temporary solution for a sonic202111 bug + if len(eeprom_raw) < num_bytes: + eeprom_raw = eeprom_raw[::-1].zfill(num_bytes)[::-1] + return bytearray(eeprom_raw) + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return None + + def write_eeprom(self, offset, num_bytes, write_buffer): + try: + for i in range(self.eeprom_retry_times): + # TODO: write_buffer is bytearray, need to convert to int array + val_list = [] + if isinstance(write_buffer, list): + val_list = write_buffer + else: + val_list.append(write_buffer) + ret, info = platform_sfp_write(self._port_id, offset, val_list) + if (ret is False + or info is None): + time.sleep(self.eeprom_retry_break_sec) + continue + return True + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + + return False + + def set_optoe_type(self, optoe_type): + ret, info = platform_get_optoe_type(self._port_id) + if ret is True and info != optoe_type: + try: + ret, _ = platform_set_optoe_type(self._port_id, optoe_type) + except Exception as err: + self._sfplog(LOG_ERROR_LEVEL, "Set optoe err %s" % err) + + def set_reset(self, reset): + if self.reset_cpld is None: + self._sfplog(LOG_ERROR_LEVEL, "reset_cpld is None!") + return False + try: + val = [] + dev_id, offset, offset_bit = self._get_sfp_cpld_info(self.reset_cpld) + ret, info = platform_reg_read(0, dev_id, offset, 1) + if self.reset_val_is_reset == 0: + if reset: + val.append(info[0] & (~(1 << offset_bit))) + else: + val.append(info[0] | (1 << offset_bit)) + else: + if reset: + val.append(info[0] | (1 << offset_bit)) + else: + val.append(info[0] & (~(1 << offset_bit))) + + ret, info = platform_reg_write(0, dev_id, offset, val) + if ret is False: + self._sfplog(LOG_ERROR_LEVEL, "platform_reg_write error!") + return False + + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + + return True + + def _get_sfp_cpld_info(self, cpld_config): + dev_id = 0 + offset = 0 + + for dev_id_temp in cpld_config["dev_id"]: + for offset_temp in cpld_config["dev_id"][dev_id_temp]["offset"]: + port_range_str = cpld_config["dev_id"][dev_id_temp]["offset"][offset_temp] + port_range_int = self._convert_str_range_to_int_arr(port_range_str) + if self._port_id in port_range_int: + dev_id = dev_id_temp + offset = offset_temp + offset_bit = port_range_int.index(self._port_id) + break + + return dev_id, offset, offset_bit + + +class SfpV2(SfpCust): + def _init_config(self, index): + super()._init_config(index) + # init eeprom path + sfp_config = baseutil.get_config().get("sfps", None) + eeprom_path_config = sfp_config.get("eeprom_path", None) + eeprom_path_key = sfp_config.get("eeprom_path_key")[self._port_id - 1] + self.eeprom_path = None if eeprom_path_config is None else eeprom_path_config % ( + eeprom_path_key, eeprom_path_key) + self._sfplog(LOG_DEBUG_LEVEL, "Done init eeprom path: %s" % self.eeprom_path) + + # init presence path + self.presence_path = None if sfp_config.get("presence_path", + None) is None else sfp_config.get("presence_path") % self._port_id + self.presence_val_is_present = sfp_config.get("presence_val_is_present", 0) + self._sfplog(LOG_DEBUG_LEVEL, "Done init presence path: %s" % self.presence_path) + + # init optoe driver path + optoe_driver_path = sfp_config.get("optoe_driver_path", None) + optoe_driver_key = sfp_config.get("optoe_driver_key")[self._port_id - 1] + self.dev_class_path = None if optoe_driver_path is None else optoe_driver_path % ( + optoe_driver_key, optoe_driver_key) + self._sfplog(LOG_DEBUG_LEVEL, "Done init optoe driver path: %s" % self.dev_class_path) + + # init reset path + self.reset_path = None if sfp_config.get( + "reset_path", + None) is None else sfp_config.get( + "reset_path", + None) % self._port_id + self.reset_val_is_reset = sfp_config.get("reset_val_is_reset", 0) + self._sfplog(LOG_DEBUG_LEVEL, "Done init reset path: %s" % self.reset_path) + + def get_presence(self): + if self.presence_path is None: + self._sfplog(LOG_ERROR_LEVEL, "presence_path is None!") + return False + try: + with open(self.presence_path, "rb") as data: + sysfs_data = data.read(1) + if sysfs_data != "": + result = int(sysfs_data, 16) + return result == self.presence_val_is_present + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + + def set_reset(self, reset): + return True + + def set_optoe_type(self, optoe_type): + if self.dev_class_path is None: + self._sfplog(LOG_ERROR_LEVEL, "dev_class_path is None!") + return False + try: + with open(self.dev_class_path, "r+") as dc_file: + dc_file_val = dc_file.read(1) + if int(dc_file_val) != optoe_type: + dc_str = "%s" % str(optoe_type) + dc_file.write(dc_str) + # dc_file.close() + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return False + return True diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/thermal.py new file mode 100644 index 000000000000..4632de3bc1e4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/thermal.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 + +######################################################################## +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + import time + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") from e + + +class Thermal(ThermalBase): + + def __init__(self, interface_obj, index): + self.temp_dict = {} + self.temperature_list = [] + self.int_case = interface_obj + self.index = index + self.update_time = 0 + self.temp_id = "TEMP" + str(index) + + def temp_dict_update(self): + local_time = time.time() + if not self.temp_dict or (local_time - self.update_time) >= 1: # update data every 1 seconds + self.update_time = local_time + self.temp_dict = self.int_case.get_monitor_temp_by_id(self.temp_id) + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + self.temp_dict_update() + return self.temp_dict["Api_name"] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + 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 Thermal + + Returns: + string: Model/part number of Thermal + """ + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return "N/A" + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + return "N/A" + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + self.temp_dict_update() + if (self.temp_dict["Value"] >= self.temp_dict["High"]) or (self.temp_dict["Value"] <= self.temp_dict["Low"]): + return False + + 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 get_temperature(self): + """ + 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 + """ + self.temp_dict_update() + value = self.temp_dict["Value"] + if value is None or value == self.int_case.error_ret: + return "N/A" + if len(self.temperature_list) >= 1000: + del self.temperature_list[0] + self.temperature_list.append(float(value)) + return round(float(value), 1) + + 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 + """ + self.temp_dict_update() + value = self.temp_dict["High"] + if value is None or value == self.int_case.error_ret: + return "N/A" + return round(float(value), 1) + + 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 + """ + self.temp_dict_update() + value = self.temp_dict["Low"] + if value is None or value == self.int_case.error_ret: + return "N/A" + return round(float(value), 1) + + 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 + """ + # not supported + return False + + 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 + """ + # not supported + 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 + """ + self.temp_dict_update() + value = self.temp_dict["Max"] + if value is None or value == self.int_case.error_ret: + return "N/A" + return round(float(value), 1) + + 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 + """ + self.temp_dict_update() + value = self.temp_dict["Min"] + if value is None or value == self.int_case.error_ret: + return "N/A" + return round(float(value), 1) + + 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 + """ + if len(self.temperature_list) == 0: + return "N/A" + return round(float(min(self.temperature_list)), 1) + + 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 + """ + if len(self.temperature_list) == 0: + return "N/A" + return round(float(max(self.temperature_list)), 1) diff --git a/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/watchdog.py new file mode 100644 index 000000000000..948337f47a9a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/common/sonic_platform/watchdog.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 + +######################################################################## +# +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +import fcntl +import os +import array + +try: + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as error: + raise ImportError(str(error) + "- required module not found") from error + + +# ioctl constants +IO_WRITE = 0x40000000 +IO_READ = 0x80000000 +IO_READ_WRITE = 0xC0000000 +IO_SIZE_INT = 0x00040000 +IO_SIZE_40 = 0x00280000 +IO_TYPE_WATCHDOG = ord('W') << 8 + +WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG +WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG +WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG + +# Watchdog ioctl command +WDIOC_GETSUPPORT = 0 | WDR_40 +WDIOC_GETSTATUS = 1 | WDR_INT +WDIOC_GETBOOTSTATUS = 2 | WDR_INT +WDIOC_GETTEMP = 3 | WDR_INT +WDIOC_SETOPTIONS = 4 | WDR_INT +WDIOC_KEEPALIVE = 5 | WDR_INT +WDIOC_SETTIMEOUT = 6 | WDWR_INT +WDIOC_GETTIMEOUT = 7 | WDR_INT +WDIOC_SETPRETIMEOUT = 8 | WDWR_INT +WDIOC_GETPRETIMEOUT = 9 | WDR_INT +WDIOC_GETTIMELEFT = 10 | WDR_INT + +# Watchdog status constants +WDIOS_DISABLECARD = 0x0001 +WDIOS_ENABLECARD = 0x0002 + +WDT_COMMON_ERROR = -1 +WDT_IDENTITY = "CPLD Watchdog" +WDT_SYSFS_PATH = "/sys/class/watchdog/" + +DEFAULT_TIMEOUT = 180 + + +class Watchdog(WatchdogBase): + """ + Abstract base class for interfacing with a hardware watchdog module + """ + + def __init__(self): + self.watchdog, self.wdt_main_dev_name = self._get_wdt() + self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name + self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name + self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name + # Set default value + self._disable() + self.armed = False + self.timeout = self._gettimeout() + + def _is_wd_main(self, dev): + """ + Checks watchdog identity + """ + identity = self._read_file( + "{}/{}/identity".format(WDT_SYSFS_PATH, dev)) + return identity == WDT_IDENTITY + + def _get_wdt(self): + """ + Retrieves watchdog device + """ + wdt_main_dev_list = [dev for dev in os.listdir( + "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] + if not wdt_main_dev_list: + return None + wdt_main_dev_name = wdt_main_dev_list[0] + watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) + watchdog = os.open(watchdog_device_path, os.O_RDWR) + return watchdog, wdt_main_dev_name + + def _read_file(self, file_path): + """ + Read text file + """ + try: + with open(file_path, "r") as fd: + txt = fd.read() + except IOError: + return WDT_COMMON_ERROR + return txt.strip() + + def _enable(self): + """ + Turn on the watchdog timer + """ + req = array.array('h', [WDIOS_ENABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _disable(self): + """ + Turn off the watchdog timer + """ + req = array.array('h', [WDIOS_DISABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE) + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + req = array.array('I', [seconds]) + fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True) + return int(req[0]) + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True) + + return int(req[0]) + + def _gettimeleft(self): + """ + Get time left before watchdog timer expires + @return time left in seconds + """ + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True) + + return int(req[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: + self._settimeout(seconds) + self._enable() + 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: + 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 + + def __del__(self): + """ + Close watchdog + """ + os.close(self.watchdog) diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/compat b/platform/broadcom/sonic-platform-modules-ragile/debian/compat index 45a4fb75db86..f599e28b8ab0 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/compat +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/compat @@ -1 +1 @@ -8 +10 diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/control b/platform/broadcom/sonic-platform-modules-ragile/debian/control index 795c8219a61e..ae30aee8c0b5 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/control +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/control @@ -1,18 +1,18 @@ Source: sonic-ragile-platform-modules Section: main Priority: extra -Maintainer: support +Maintainer: support Standards-Version: 3.9.3 Package: platform-modules-ragile-ra-b6510-48v8c Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp -Package: platform-modules-ragile-ra-b6910-64c +Package: platform-modules-ragile-ra-b6510-32c Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp -Package: platform-modules-ragile-ra-b6510-32c +Package: platform-modules-ragile-ra-b6910-64c Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/copyright b/platform/broadcom/sonic-platform-modules-ragile/debian/copyright index 1e4fc20a1672..676cdeec726b 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/copyright +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/copyright @@ -1,5 +1,4 @@ Copyright (C) 2016 Microsoft, Inc -Copyright (C) 2018 Ragile Network Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.install b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.install index 568190dca044..a63d409ace41 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.install +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.install @@ -1 +1 @@ -ra-b6510-48v8c/scripts/pddf_post_driver_install.sh /usr/local/bin +ra-b6510-48v8c/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-ragile_ra-b6510-48v8c-r0 diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.postinst b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.postinst index 0d9d6a34d2a5..a8132f4f65a9 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.postinst +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-48v8c.postinst @@ -7,11 +7,4 @@ if [ -e /boot/System.map-${kernel_version} ]; then depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true fi -# enable platform-service -depmod -a -# systemctl enable platform-modules-ra-b6510-48v8c.service -# systemctl start platform-modules-ra-b6510-48v8c.service -systemctl enable pddf-platform-init.service -systemctl start pddf-platform-init.service - #DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.install b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.install index 0034aa70603d..8de43ed4ed66 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.install +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.install @@ -1 +1 @@ -ra-b6920-4s/scripts/pddf_post_device_create.sh /usr/local/bin +ra-b6920-4s/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-ragile_ra-b6920-4s-r0 diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/rule-ragile.mk b/platform/broadcom/sonic-platform-modules-ragile/debian/rule-ragile.mk deleted file mode 100755 index 6620b8762f86..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/rule-ragile.mk +++ /dev/null @@ -1,8 +0,0 @@ -currentdir = $(shell pwd) - -MODULE_DIRS := ra-b6510-48v8c -MODULE_DIRS += ra-b6910-64c -MODULE_DIRS += ra-b6510-32c -MODULE_DIRS += ra-b6920-4s - -export MODULE_DIRS diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/rules b/platform/broadcom/sonic-platform-modules-ragile/debian/rules index e32da1faa711..0177d5072684 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/debian/rules +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/rules @@ -6,17 +6,12 @@ KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) KBUILD_OUTPUT=$(KERNEL_SRC)/build -LIB_DIR = usr/lib/python3.7/dist-packages +LIB_DIR = usr/lib/python3/dist-packages CUSTOM_RULES_DIR := $(shell pwd)/debian -PLATFORM_PREFIX = "x86_64-ragile" -PLATFORM_VER = "r0" -BDIST_DIR = "dist" -BDIST_TARGET = "bdist_t" +export INSTALL_MOD_DIR top_srcdir KVERSION KERNEL_SRC CC KBUILD_OUTPUT CUSTOM_RULES_DIR -export INSTALL_MOD_DIR top_srcdir KVERSION KERNEL_SRC CC KBUILD_OUTPUT - -include $(CUSTOM_RULES_DIR)/rule-ragile.mk +include $(CUSTOM_RULES_DIR)/rule.mk #all product need common COMPILE_DIRS = $(MODULE_DIRS) @@ -24,15 +19,14 @@ COMPILE_DIRS = $(MODULE_DIRS) clean_dirs = $(MODULE_DIRS) clean_dirs += common -custom_clean_dirs := $(addprefix _clean_,$(clean_dirs) ) - +complie_clean_dirs := $(addprefix _clean_,$(clean_dirs) ) %: dh $@ -build: $(COMPILE_DIRS) +build: COMPILE_WHL @echo "build success" -$(custom_clean_dirs): +$(complie_clean_dirs): $(MAKE) -C $(patsubst _clean_%,%,$@) clean common_build : @@ -42,26 +36,29 @@ $(COMPILE_DIRS): common_build $(MAKE) -C $(MOD_SRC_DIR)/$@ dh_testdir dh_installdirs - # - # wheel pcakage - @cp -r \ - $(MOD_SRC_DIR)/common/lib/rgutil \ - $(MOD_SRC_DIR)/common/lib/eepromutil \ - $(MOD_SRC_DIR)/$@/; \ - cd $(MOD_SRC_DIR)/$@; \ - python3 setup.py bdist_wheel --bdist-dir $(BDIST_DIR) -d $(BDIST_TARGET); \ - mkdir -p build/usr/share/sonic/device/$(PLATFORM_PREFIX)_$@-$(PLATFORM_VER); \ - mkdir -p build/usr/share/sonic/device/$(PLATFORM_PREFIX)_$@-$(PLATFORM_VER)/pddf; \ - cp $(BDIST_TARGET)/*.whl build/usr/share/sonic/device/$(PLATFORM_PREFIX)_$@-$(PLATFORM_VER); \ - cp $(BDIST_TARGET)/*.whl build/usr/share/sonic/device/$(PLATFORM_PREFIX)_$@-$(PLATFORM_VER)/pddf/; \ - cd $(MOD_SRC_DIR); \ - rm -rf \ - $(MOD_SRC_DIR)/$@/rgutil \ - $(MOD_SRC_DIR)/$@/eepromutil \ - $(MOD_SRC_DIR)/$@/$(BDIST_TARGET) - - cp -r $(MOD_SRC_DIR)/common/build/* debian/platform-modules-ragile-$@/ - cp -r $(MOD_SRC_DIR)/$@/build/* debian/platform-modules-ragile-$@/ + cp -r $(MOD_SRC_DIR)/common/build/* debian/platform-modules-ragile-$@/; \ + cp -r $(MOD_SRC_DIR)/$@/build/* debian/platform-modules-ragile-$@/; \ + +COMPILE_WHL: $(COMPILE_DIRS) + @(for mod in $(MODULE_DIRS); do \ + cd $(MOD_SRC_DIR)/$${mod}; \ + cp -r $(MOD_SRC_DIR)/common/lib/plat_hal $(MOD_SRC_DIR)/$${mod}/; \ + cp -r $(MOD_SRC_DIR)/common/lib/wbutil $(MOD_SRC_DIR)/$${mod}/; \ + cp -r $(MOD_SRC_DIR)/common/lib/eepromutil $(MOD_SRC_DIR)/$${mod}/; \ + cp -r $(MOD_SRC_DIR)/common/sonic_platform $(MOD_SRC_DIR)/$${mod}/; \ + cp $(MOD_SRC_DIR)/common/script/hal_pltfm.py $(MOD_SRC_DIR)/$${mod}/hal_pltfm.py; \ + cp $(MOD_SRC_DIR)/common/script/platform_util.py $(MOD_SRC_DIR)/$${mod}/platform_util.py; \ + cp $(MOD_SRC_DIR)/common/script/platform_intf.py $(MOD_SRC_DIR)/$${mod}/platform_intf.py; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/plat_hal; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/wbutil; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/eepromutil; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/sonic_platform; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/hal_pltfm.py; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/platform_intf.py; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/platform_util.py; \ + cd $(MOD_SRC_DIR); \ + done) binary: binary-indep @echo "=======================================================" @@ -87,7 +84,7 @@ override_dh_usrlocal: override_dh_pysupport: -clean: $(custom_clean_dirs) +clean: $(complie_clean_dirs) dh_testdir dh_testroot dh_clean diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/.upgrade_test/cpld_test_header.vme b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/.upgrade_test/cpld_test_header.vme new file mode 100644 index 0000000000000000000000000000000000000000..7b149c47b31018f8b5f6818f4336f8b3a17c6811 GIT binary patch literal 413 zcmaiu!A^rf5QZ0MSXg6HMH9VkJn4n7P_?PyK+0-KEH+3;JQ0L7Z9>aNvC)$^AIxX) zA-wtoxZndYmzhky@1MzeS)?_4snaFP3ifPn*9=_;w{%85pGK$1r%C*C6j4mxvxLLT^spZky2PKDZ0rt<|M;crvGG8co}Xr!2GV;u4)9c6E}9BDP6> z^BaGat*cFeea6e`ea$vCj;pG~j!DFYh?!2$T%{r)_Zn*rD4mLCe9>yj9u dW;DE4YDu*v^;U - -#define PSU "PDDF_PSU" -#define LED "PDDF_LED" -#define FAN "PDDF_FAN" -#define CLIENT "PDDF_CLIENT" -#define CPLD "PDDF_CPLD" -#define CPLDMUX "PDDF_CPLDMUX" -#define MUX "PDDF_MUX" -#define GPIO "PDDF_GPIO" -#define SYSSTATUS "PDDF_SYSSTATUS" -#define XCVR "PDDF_XCVR" - -#define PDDF_DEBUG -#ifdef PDDF_DEBUG -#define pddf_dbg(filter,...) printk("%s\t", filter); printk(KERN_CONT __VA_ARGS__) -#else -#define pddf_dbg(...) -#endif - - -#define GEN_NAME_SIZE 32 -#define ERR_STR_SIZE 128 - - -typedef struct pddf_data_attribute{ - struct device_attribute dev_attr; - int type; - int len; - char *addr; - char *data; -}PDDF_ATTR; - -#define PDDF_DATA_ATTR(_name, _mode, _show, _store, _type, _len, _addr, _data) \ - struct pddf_data_attribute attr_##_name = { .dev_attr = __ATTR(_name, _mode, _show, _store), \ - .type = _type , \ - .len = _len , \ - .addr = _addr, \ - .data = _data } - - -enum attribute_data_type { - PDDF_CHAR, - PDDF_UCHAR, - PDDF_INT_HEX, // integer represented in HEX - PDDF_INT_DEC, // integer represented in DECIMAL - PDDF_USHORT, // HEX - PDDF_UINT32 // HEX -}; - - - - - -// PSU Specific details - -typedef struct NEW_DEV_ATTR -{ - char i2c_type[GEN_NAME_SIZE]; - char i2c_name[GEN_NAME_SIZE]; - int parent_bus; - char dev_type[GEN_NAME_SIZE]; - int dev_id; - int dev_addr; - char *data; - int error; - char errstr[ERR_STR_SIZE]; - -}NEW_DEV_ATTR; -extern NEW_DEV_ATTR pddf_data; - -extern struct attribute_group pddf_clients_data_group; -extern ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); -extern ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf); -struct kobject* get_device_i2c_kobj(void); -void set_attr_data(void * ptr); -void set_error_code(int, char *); -ssize_t show_error_code(struct device *dev, struct device_attribute *da, char *buf); -ssize_t show_all_devices(struct device *dev, struct device_attribute *da, char *buf); -void traverse_device_table(void ); - - - -/*Various Ops hook which can be used by vendors to provide some deviation from usual pddf functionality*/ -struct pddf_ops_t -{ - /*Module init ops*/ - int (*pre_init)(void); - int (*post_init)(void); - /*probe ops*/ - int (*pre_probe)(struct i2c_client *, const struct i2c_device_id *); - int (*post_probe)(struct i2c_client *, const struct i2c_device_id *); - /*remove ops*/ - int (*pre_remove)(struct i2c_client *); - int (*post_remove)(struct i2c_client *); - /*Module exit ops*/ - void (*pre_exit)(void); - void (*post_exit)(void); -}; - - -typedef struct PDEVICE -{ - struct hlist_node node; - char name[GEN_NAME_SIZE]; - void *data; - -}PDEVICE; - -void add_device_table(char *name, void *ptr); - - -#endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_custom_led_module.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_custom_led_module.c deleted file mode 100644 index 5776735ef4fa..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_custom_led_module.c +++ /dev/null @@ -1,736 +0,0 @@ -/* - * Copyright 2019 Broadcom. - * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. - * - * 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. - * - * - * A pddf kernel module to manage various LEDs of a switch - */ - -#include -#include -#include -#include -#include -#include -#include "pddf_led_defs.h" -#include "pddf_client_defs.h" -#include -#include -#include -#include - -#define DEBUG 0 -LED_OPS_DATA sys_led_ops_data[1]={0}; -LED_OPS_DATA* psu_led_ops_data=NULL; -LED_OPS_DATA diag_led_ops_data[1]= {0}; -LED_OPS_DATA fan_led_ops_data[1]= {0}; -LED_OPS_DATA loc_led_ops_data[1]= {0}; -LED_OPS_DATA* fantray_led_ops_data=NULL; -LED_OPS_DATA temp_data={0}; -LED_OPS_DATA* dev_list[LED_TYPE_MAX] = { - sys_led_ops_data, - NULL, - fan_led_ops_data, - NULL, - diag_led_ops_data, - loc_led_ops_data, -}; -int num_psus = 0; -int num_fantrays = 0; - -extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); -extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); -extern ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf); -extern ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); -extern void *get_device_table(char *name); - -static LED_STATUS find_state_index(const char* state_str) { - int index; - char *ptr = (char *)state_str; - while (*ptr && *ptr!= '\n' && *ptr !='\0') ptr++; - *ptr='\0'; - for ( index = 0; index < MAX_LED_STATUS; index++) { - /*int rc = strcmp(state_str, LED_STATUS_STR[index]) ;*/ - if (strcmp(state_str, LED_STATUS_STR[index]) == 0 ) { - return index; - } - } - return MAX_LED_STATUS; -} - -static LED_TYPE get_dev_type(char* name) -{ - LED_TYPE ret = LED_TYPE_MAX; - if(strcasecmp(name, "SYS_LED")==0) { - ret = LED_SYS; - } else if(strcasecmp(name, "FAN_LED")==0) { - ret = LED_FAN; - } else if(strstr(name, "PSU_LED")) { - ret = LED_PSU; - } else if(strcasecmp(name, "DIAG_LED")==0) { - ret = LED_DIAG; - } else if(strcasecmp(name, "LOC_LED")==0) { - ret = LED_LOC; - } else if(strstr(name, "FANTRAY_LED")) { - ret = LED_FANTRAY; - } -#if DEBUG > 1 - pddf_dbg(LED, KERN_INFO "LED get_dev_type: %s; %d\n", name, ret); -#endif - return (ret); -} -static int dev_index_check(LED_TYPE type, int index) -{ -#if DEBUG - pddf_dbg(LED, "dev_index_check: type:%s index:%d num_psus:%d num_fantrays:%d\n", - LED_TYPE_STR[type], index, num_psus, num_fantrays); -#endif - switch(type) - { - case LED_PSU: - if(index >= num_psus) return (-1); - break; - case LED_FANTRAY: - if(index >= num_fantrays) return (-1); - break; - default: - if(index >= 1) return (-1); - break; - } - return (0); -} - -static LED_OPS_DATA* find_led_ops_data(struct device_attribute *da) -{ - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; - LED_TYPE led_type; - if(!ptr || strlen(ptr->device_name)==0 ) return(NULL); - - - if((led_type=get_dev_type(ptr->device_name))==LED_TYPE_MAX) { - printk(KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); - return(NULL); - } - if(dev_index_check(led_type, ptr->index)==-1) { - printk(KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%s\n", __func__, ptr->index, ptr->device_name); - return(NULL); - } -#if DEBUG > 1 - pddf_dbg(LED, "find_led_ops_data: name:%s; index=%d tempAddr:%p actualAddr:%p\n", - ptr->device_name, ptr->index, ptr, dev_list[led_type]+ptr->index); -#endif - return (dev_list[led_type]+ptr->index); -} - -static void print_led_data(LED_OPS_DATA *ptr, LED_STATUS state) -{ - int i = 0; - if(!ptr) return ; - pddf_dbg(LED, KERN_INFO "Print %s index:%d num_psus:%d num_fantrays:%d ADDR=%p\n", - ptr->device_name, ptr->index, num_psus, num_fantrays, ptr); - pddf_dbg(LED, KERN_INFO "\tindex: %d\n", ptr->index); - pddf_dbg(LED, KERN_INFO "\tcur_state: %d; %s \n", ptr->cur_state.state, ptr->cur_state.color); - for (i = 0; i< MAX_LED_STATUS; i++) { - if(ptr->data[i].swpld_addr && (i == state || state == -1)) { - pddf_dbg(LED, KERN_INFO "\t\t[%s]: addr/offset:0x%x;0x%x color:%s; value:%x; mask_bits: 0x%x; pos:%d\n", - LED_STATUS_STR[i], - ptr->data[i].swpld_addr, ptr->data[i].swpld_addr_offset, - LED_STATUS_STR[i], ptr->data[i].value, ptr->data[i].bits.mask_bits, ptr->data[i].bits.pos); - } - } -} - -int get_sys_val(LED_OPS_DATA *ops_ptr, uint32_t *sys_val) -{ - int ret; - struct i2c_client *client_ptr; - - ret = -1; - - if (ops_ptr == NULL) { - pddf_dbg(LED, KERN_ERR "ERROR %s: param is NULL\n", __func__); - return ret; - } - - if (strlen(ops_ptr->device_name) != 0 && strncmp(ops_ptr->device_name, "FANTRAY_LED", strlen("FANTRAY_LED")) == 0) { - client_ptr = (struct i2c_client *)get_device_table("FAN-CTRL"); - if (client_ptr == NULL) { - pddf_dbg(LED, KERN_ERR "ERROR %s: get led color by cpld fail\n", __func__); - return ret; - } - *sys_val = i2c_smbus_read_byte_data(client_ptr, ops_ptr->swpld_addr_offset); - ret = 0; - } - else { - ret = inb(ops_ptr->swpld_addr_offset); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: get led color by io fail\n", __func__); - return ret; - } - *sys_val = (uint32_t)ret; - ret = 0; - } - - return ret; -} - - -ssize_t get_status_led(struct device_attribute *da) -{ - int ret=0; - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; - LED_OPS_DATA* ops_ptr=find_led_ops_data(da); - uint32_t color_val=0, sys_val=0; - int state=0; - if (!ops_ptr) { - pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot find LED Ptr", __func__); - return (-1); - } - if (ops_ptr->swpld_addr == 0x0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: device: %s %d not configured\n", __func__, - temp_data_ptr->device_name, temp_data_ptr->index); - return (-1); - } - ret = get_sys_val(ops_ptr, &sys_val); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot get sys val\n", __func__); - return (-1); - } - /* keep ret as old value */ - ret = 0; - - strcpy(temp_data.cur_state.color, "None"); - for (state=0; statedata[state].bits.mask_bits); - if ((color_val ^ (ops_ptr->data[state].value<data[state].bits.pos))==0) { - strcpy(temp_data.cur_state.color, LED_STATUS_STR[state]); - } - } -#if DEBUG > 1 - pddf_dbg(LED, KERN_ERR "Get : %s:%d addr/offset:0x%x; 0x%x value=0x%x [%s]\n", - ops_ptr->device_name, ops_ptr->index, - ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, sys_val, - temp_data.cur_state.color); -#endif - - return(ret); -} - -int set_sys_val(LED_OPS_DATA *ops_ptr, uint32_t new_val) -{ - int ret; - struct i2c_client *client_ptr; - - ret = -1; - - if (ops_ptr == NULL) { - pddf_dbg(LED, KERN_ERR "ERROR %s: param is NULL\n", __func__); - return ret; - } - - if (strlen(ops_ptr->device_name) != 0 && strncmp(ops_ptr->device_name, "FANTRAY_LED", strlen("FANTRAY_LED")) == 0) { - client_ptr = (struct i2c_client *)get_device_table("FAN-CTRL"); - if (client_ptr == NULL) { - pddf_dbg(LED, KERN_ERR "ERROR %s: get i2c_client fail\n", __func__); - return ret; - } - ret = i2c_smbus_write_byte_data(client_ptr, ops_ptr->swpld_addr_offset, new_val); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: set led color by cpld fail\n", __func__); - } - } - else { - outb(new_val, ops_ptr->swpld_addr_offset); - } - - return ret; -} - -ssize_t set_status_led(struct device_attribute *da) -{ - int ret=0; - uint32_t sys_val=0, new_val=0; - LED_STATUS cur_state = MAX_LED_STATUS; - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; - LED_OPS_DATA* ops_ptr=find_led_ops_data(da); - char* _buf=temp_data_ptr->cur_state.color; - - if (!ops_ptr) { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: Cannot find LED Ptr", __func__); - return (-1); - } - if (ops_ptr->swpld_addr == 0x0) { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: device: %s %d not configured\n", - __func__, ops_ptr->device_name, ops_ptr->index); - return (-1); - } - pddf_dbg(LED, KERN_ERR "%s: Set [%s;%d] color[%s]\n", __func__, - temp_data_ptr->device_name, temp_data_ptr->index, - temp_data_ptr->cur_state.color); - cur_state = find_state_index(_buf); - - if (cur_state == MAX_LED_STATUS) { - pddf_dbg(LED, KERN_ERR "ERROR %s: not supported: %s\n", _buf, __func__); - return (-1); - } - - if(ops_ptr->data[cur_state].swpld_addr != 0x0) { - ret = get_sys_val(ops_ptr, &sys_val); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot get sys val\n", __func__); - return (-1); - } - - new_val = (sys_val & ops_ptr->data[cur_state].bits.mask_bits) | - (ops_ptr->data[cur_state].value << ops_ptr->data[cur_state].bits.pos); - - } else { - pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d state %d; %s not configured\n",__func__, - ops_ptr->device_name, ops_ptr->index, cur_state, _buf); - return (-1); - } - - ret = set_sys_val(ops_ptr, new_val); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot set sys val\n", __func__); - return (-1); - } - pddf_dbg(LED, KERN_INFO "Set color:%s; 0x%x:0x%x sys_val:0x%x new_val:0x%x read:0x%x\n", - LED_STATUS_STR[cur_state], - ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, - sys_val, new_val, - ret = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset)); - if (ret < 0) - { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: Error %d in reading from cpld(0x%x) offset 0x%x\n", __FUNCTION__, ret, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); - return ret; - } - return(ret); -} - - -ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, - char *buf) -{ - int ret = 0; - struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; - switch(ptr->type) - { - case PDDF_CHAR: - ret = sprintf(buf, "%s\n", ptr->addr); - break; - case PDDF_INT_DEC: - ret = sprintf(buf, "%d\n", *(int*)(ptr->addr)); - break; - case PDDF_INT_HEX: - ret = sprintf(buf, "0x%x\n", *(int*)(ptr->addr)); - break; - case PDDF_USHORT: - ret = sprintf(buf, "0x%x\n", *(unsigned short *)(ptr->addr)); - break; - case PDDF_UINT32: - ret = sprintf(buf, "0x%x\n", *(uint32_t *)(ptr->addr)); - break; - default: - break; - } -#if DEBUG > 1 - pddf_dbg(LED, "[ READ ] DATA ATTR PTR [%s] TYPE:%d, Value:[%s]\n", - ptr->dev_attr.attr.name, ptr->type, buf); -#endif - return ret; -} - -ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) -{ - int ret = 0, num = 0; - struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; - switch(ptr->type) - { - case PDDF_CHAR: - strncpy(ptr->addr, buf, strlen(buf)-1); // to discard newline char form buf - ptr->addr[strlen(buf)-1] = '\0'; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_CHAR VALUE:%s\n", - ptr->dev_attr.attr.name, ptr->addr); -#endif - break; - case PDDF_INT_DEC: - ret = kstrtoint(buf,10,&num); - if (ret==0) - *(int *)(ptr->addr) = num; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_DEC VALUE:%d\n", - ptr->dev_attr.attr.name, *(int *)(ptr->addr)); -#endif - break; - case PDDF_INT_HEX: - ret = kstrtoint(buf,16,&num); - if (ret==0) - *(int *)(ptr->addr) = num; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_HEX VALUE:0x%x\n", - ptr->dev_attr.attr.name, *(int *)(ptr->addr)); -#endif - break; - case PDDF_USHORT: - ret = kstrtoint(buf,16,&num); - if (ret==0) - *(unsigned short *)(ptr->addr) = (unsigned short)num; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_USHORT VALUE:%x\n", - ptr->dev_attr.attr.name, *(unsigned short *)(ptr->addr)); -#endif - break; - case PDDF_UINT32: - ret = kstrtoint(buf,16,&num); - if (ret==0) - *(uint32_t *)(ptr->addr) = (uint32_t)num; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_UINT32 VALUE:%d\n", - ptr->dev_attr.attr.name, *(uint32_t *)(ptr->addr)); -#endif - break; - default: - break; - } - return count; -} - -static int load_led_ops_data(struct device_attribute *da, LED_STATUS state) -{ - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; - LED_TYPE led_type; - LED_OPS_DATA* ops_ptr=NULL; - if(!ptr || strlen(ptr->device_name)==0 ) { - pddf_dbg(LED, KERN_INFO "SYSTEM_LED: load_led_ops_data return -1 device_name:%s\n", ptr? ptr->device_name:"NULL"); - return(-1); - } - if(ptr->device_name) - { - pddf_dbg(LED, KERN_INFO "[%s]: load_led_ops_data: index=%d addr=0x%x;0x%x valu=0x%x\n", - ptr->device_name, ptr->index, ptr->swpld_addr, ptr->swpld_addr_offset, ptr->data[0].value); - } - if((led_type=get_dev_type(ptr->device_name))==LED_TYPE_MAX) { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); - return(-1); - } - if(dev_index_check(led_type, ptr->index)==-1) { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%d\n", __func__, ptr->index, led_type); - return(-1); - } - ops_ptr = dev_list[led_type]+ptr->index; - - memcpy(ops_ptr->device_name, ptr->device_name, sizeof(ops_ptr->device_name)); - ops_ptr->index = ptr->index; - memcpy(&ops_ptr->data[state], &ptr->data[0], sizeof(LED_DATA)); - ops_ptr->data[state].swpld_addr = ptr->swpld_addr; - ops_ptr->data[state].swpld_addr_offset = ptr->swpld_addr_offset; - ops_ptr->swpld_addr = ptr->swpld_addr; - ops_ptr->swpld_addr_offset = ptr->swpld_addr_offset; - - print_led_data(dev_list[led_type]+ptr->index, state); - - memset(ptr, 0, sizeof(LED_OPS_DATA)); - return (0); -} - -static int show_led_ops_data(struct device_attribute *da) -{ - LED_OPS_DATA* ops_ptr=find_led_ops_data(da); - print_led_data(ops_ptr, -1); - return(0); -} - -static int verify_led_ops_data(struct device_attribute *da) -{ - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; - LED_OPS_DATA* ops_ptr=find_led_ops_data(da); - - if(ops_ptr) - memcpy(ptr, ops_ptr, sizeof(LED_OPS_DATA)); - else - { - pddf_dbg(LED, "SYSTEM_LED: verify_led_ops_data: Failed to find ops_ptr name:%s; index=%d\n", ptr->device_name, ptr->index); - } - return (0); -} - - -ssize_t dev_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) -{ -#if DEBUG - pddf_dbg(LED, KERN_INFO "dev_operation [%s]\n", buf); -#endif - if(strstr(buf, "STATUS_LED_COLOR")!= NULL) { - LED_STATUS index = find_state_index(buf); - if (index < MAX_LED_STATUS ) { - load_led_ops_data(da, index); - } else { - printk(KERN_ERR "PDDF_ERROR %s: Invalid state for dev_ops %s", __FUNCTION__, buf); - } - } - else if(strncmp(buf, "show", strlen("show"))==0 ) { - show_led_ops_data(da); - } - else if(strncmp(buf, "verify", strlen("verify"))==0 ) { - verify_led_ops_data(da); - } - else if(strncmp(buf, "get_status", strlen("get_status"))==0 ) { - get_status_led(da); - } - else if(strncmp(buf, "set_status", strlen("set_status"))==0 ) { - set_status_led(da); - } - else { - printk(KERN_ERR "PDDF_ERROR %s: Invalid value for dev_ops %s", __FUNCTION__, buf); - } - return(count); -} - -ssize_t store_config_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) -{ - int ret, num; - struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; - if(strncmp(ptr->dev_attr.attr.name, "num_psus", strlen("num_psus"))==0 ) { - ret = kstrtoint(buf,10,&num); - if (ret==0) - *(int *)(ptr->addr) = num; - if(psu_led_ops_data == NULL) { - if ((psu_led_ops_data = kzalloc(num * sizeof(LED_OPS_DATA), GFP_KERNEL)) == NULL) { - printk(KERN_ERR "PDDF_LED ERROR failed to allocate memory for PSU LED\n"); - return (count); - } - pddf_dbg(LED, "Allocate PSU LED Memory ADDR=%p\n", psu_led_ops_data); - dev_list[LED_PSU]=psu_led_ops_data; - } -#if DEBUG - pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", - ptr->dev_attr.attr.name, num, num_psus); -#endif - return(count); - } - if(strncmp(ptr->dev_attr.attr.name, "num_fantrays", strlen("num_fantrays"))==0 ) { - ret = kstrtoint(buf,10,&num); - if (ret==0) - *(int *)(ptr->addr) = num; - if (fantray_led_ops_data == NULL) { - if ((fantray_led_ops_data = kzalloc(num * sizeof(LED_OPS_DATA), GFP_KERNEL)) == NULL) { - printk(KERN_ERR "PDDF_LED ERROR failed to allocate memory for FANTRAY LED\n"); - return (count); - } - pddf_dbg(LED, "Allocate FanTray LED Memory ADDR=%p\n", fantray_led_ops_data); - dev_list[LED_FANTRAY]=fantray_led_ops_data; - } -#if DEBUG - pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", - ptr->dev_attr.attr.name, num, num_fantrays); -#endif - return(count); - } - return (count); -} - -ssize_t store_bits_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) -{ - int len = 0, num1 = 0, num2 = 0, i=0, rc1=0, rc2=0; - char mask=0xFF; - char *pptr=NULL; - char bits[NAME_SIZE]; - struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; - MASK_BITS* bits_ptr=(MASK_BITS*)(ptr->addr); - strncpy(bits_ptr->bits, buf, strlen(buf)-1); // to discard newline char form buf - bits_ptr->bits[strlen(buf)-1] = '\0'; - if((pptr=strstr(buf,":")) != NULL) { - len=pptr-buf; - sprintf(bits, buf); - bits[len]='\0'; - rc1=kstrtoint(bits,16,&num1); - if (rc1==0) - { - sprintf(bits, ++pptr); - rc2=kstrtoint(bits,16,&num2); - if (rc2==0) - { - for (i=num2; i<=num1; i++) { - mask &= ~(1 << i); - } - bits_ptr->mask_bits = mask; - bits_ptr->pos = num2; - } - } - } else { - rc1=kstrtoint(buf,16,&num1); - if (rc1==0) - { - bits_ptr->mask_bits = mask & ~(1 << num1); - bits_ptr->pos = num1; - } - } -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR Bits [%s] VALUE:%s mask:0x%x; pos:0x%x\n", - ptr->dev_attr.attr.name, bits_ptr->bits, bits_ptr->mask_bits, bits_ptr->pos); -#endif - return (count); -} - -/************************************************************************** - * platform/ attributes - **************************************************************************/ -PDDF_LED_DATA_ATTR(platform, num_psus, S_IWUSR|S_IRUGO, show_pddf_data, - store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_psus); -PDDF_LED_DATA_ATTR(platform, num_fantrays, S_IWUSR|S_IRUGO, show_pddf_data, - store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_fantrays); - -struct attribute* attrs_platform[]={ - &pddf_dev_platform_attr_num_psus.dev_attr.attr, - &pddf_dev_platform_attr_num_fantrays.dev_attr.attr, - NULL, -}; -struct attribute_group attr_group_platform={ - .attrs = attrs_platform, -}; - -/************************************************************************** - * led/ attributes - **************************************************************************/ -PDDF_LED_DATA_ATTR(dev, device_name, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.device_name); -PDDF_LED_DATA_ATTR(dev, index, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&temp_data.index); -PDDF_LED_DATA_ATTR(dev, swpld_addr, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr); -PDDF_LED_DATA_ATTR(dev, swpld_addr_offset, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr_offset); -PDDF_LED_DATA_ATTR(dev, dev_ops , S_IWUSR, NULL, - dev_operation, PDDF_CHAR, NAME_SIZE, (void*)&temp_data); - -struct attribute* attrs_dev[]={ - &pddf_dev_dev_attr_device_name.dev_attr.attr, - &pddf_dev_dev_attr_index.dev_attr.attr, - &pddf_dev_dev_attr_swpld_addr.dev_attr.attr, - &pddf_dev_dev_attr_swpld_addr_offset.dev_attr.attr, - &pddf_dev_dev_attr_dev_ops.dev_attr.attr, - NULL, -}; -struct attribute_group attr_group_dev={ - .attrs = attrs_dev, -}; - -/************************************************************************** - * state_attr/ attributes - **************************************************************************/ -#define LED_DEV_STATE_ATTR_GROUP(name, func) \ - PDDF_LED_DATA_ATTR(name, bits, S_IWUSR|S_IRUGO, show_pddf_data, \ - store_bits_data, PDDF_CHAR, NAME_SIZE, func.bits.bits); \ - PDDF_LED_DATA_ATTR(name, value, S_IWUSR|S_IRUGO, show_pddf_data, \ - store_pddf_data, PDDF_USHORT, sizeof(unsigned short), func.value); \ - struct attribute* attrs_##name[]={ \ - &pddf_dev_##name##_attr_bits.dev_attr.attr, \ - &pddf_dev_##name##_attr_value.dev_attr.attr, \ - NULL, \ - }; \ - struct attribute_group attr_group_##name={ \ - .attrs = attrs_##name, \ - }; \ - - -LED_DEV_STATE_ATTR_GROUP(state_attr, (void*)&temp_data.data[0]) - -/************************************************************************** - * cur_state/ attributes - **************************************************************************/ -PDDF_LED_DATA_ATTR(cur_state, color, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.cur_state.color); - -struct attribute* attrs_cur_state[]={ - &pddf_dev_cur_state_attr_color.dev_attr.attr, - NULL, -}; -struct attribute_group attr_group_cur_state={ - .attrs = attrs_cur_state, -}; - -/*************************************************************************/ -#define KOBJ_FREE(obj) \ - if(obj) kobject_put(obj); \ - -void free_kobjs(void) -{ - KOBJ_FREE(cur_state_kobj) - KOBJ_FREE(state_attr_kobj) - KOBJ_FREE(led_kobj) - KOBJ_FREE(platform_kobj) -} - -int KBOJ_CREATE(char* name, struct kobject* parent, struct kobject** child) -{ - if (parent) { - *child = kobject_create_and_add(name, parent); - } else { - printk(KERN_ERR "PDDF_LED ERROR to create %s kobj; null parent\n", name); - free_kobjs(); - return (-ENOMEM); - } - return (0); -} - -int LED_DEV_ATTR_CREATE(struct kobject *kobj, const struct attribute_group *attr, const char* name) -{ - int status = sysfs_create_group(kobj, attr); - if(status) { - pddf_dbg(LED, KERN_ERR "Driver ERROR: sysfs_create %s failed rc=%d\n", name, status); - } - return (status); -} - - -static int __init led_init(void) { - struct kobject *device_kobj; - pddf_dbg(LED, KERN_INFO "PDDF GENERIC LED MODULE init..\n"); - - device_kobj = get_device_i2c_kobj(); - if(!device_kobj) - return -ENOMEM; - - KBOJ_CREATE("platform", device_kobj, &platform_kobj); - KBOJ_CREATE("led", device_kobj, &led_kobj); - KBOJ_CREATE("state_attr", led_kobj, &state_attr_kobj); - KBOJ_CREATE("cur_state", led_kobj, &cur_state_kobj); - - LED_DEV_ATTR_CREATE(platform_kobj, &attr_group_platform, "attr_group_platform"); - LED_DEV_ATTR_CREATE(led_kobj, &attr_group_dev, "attr_group_dev"); - LED_DEV_ATTR_CREATE(state_attr_kobj, &attr_group_state_attr, "attr_group_state_attr"); - LED_DEV_ATTR_CREATE(cur_state_kobj, &attr_group_cur_state, "attr_group_cur_state"); - return (0); -} - - -static void __exit led_exit(void) { - pddf_dbg(LED, "PDDF GENERIC LED MODULE exit..\n"); - free_kobjs(); - if(psu_led_ops_data) kfree(psu_led_ops_data); - if(fantray_led_ops_data) kfree(fantray_led_ops_data); -} - -module_init(led_init); -module_exit(led_exit); - -MODULE_AUTHOR("Broadcom"); -MODULE_DESCRIPTION("led driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_custom_psu.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_custom_psu.c deleted file mode 100644 index 6c4db972a7f1..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_custom_psu.c +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include -#include -#include "../../../../../pddf/i2c/modules/include/pddf_psu_defs.h" -#include "../../../../../pddf/i2c/modules/include/pddf_psu_driver.h" - -static int pddf_custom_psu_present(void *client, PSU_DATA_ATTR *adata, void *data); -extern void *get_device_table(char *name); -extern PSU_SYSFS_ATTR_DATA access_psu_present; -extern PSU_SYSFS_ATTR_DATA access_psu_power_good; - -static int pddf_custom_psu_present(void *client, PSU_DATA_ATTR *adata, void *data) -{ - int ret; - struct i2c_client *client_ptr; - struct psu_attr_info *padata; - - ret = -1; - client_ptr = NULL; - padata = (struct psu_attr_info *)data; - - if (strncmp(adata->devtype, "io", strlen("io")) == 0) { - ret = inb(adata->offset); - - if (ret < 0) { - return ret; - } - - padata->val.intval = ((ret & adata->mask) == adata->cmpval); - } - - else if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0) { - client_ptr = (struct i2c_client *)get_device_table(adata->devname); - if (client_ptr) { - ret = i2c_smbus_read_byte_data(client_ptr, adata->offset); - } - - if (ret < 0) { - return ret; - } - - padata->val.intval = ((ret & adata->mask) == adata->cmpval); - } - - return 0; -} - -static int pddf_custom_psu_power_good(void *client, PSU_DATA_ATTR *adata, void *data) -{ - int ret; - struct i2c_client *client_ptr; - struct psu_attr_info *padata; - - ret = -1; - client_ptr = NULL; - padata = (struct psu_attr_info *)data; - - if (strncmp(adata->devtype, "io", strlen("io")) == 0) { - ret = inb(adata->offset); - - if (ret < 0) { - return ret; - } - - padata->val.intval = ((ret & adata->mask) == adata->cmpval); - } - - else if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0) { - client_ptr = (struct i2c_client *)get_device_table(adata->devname); - if (client_ptr) { - ret = i2c_smbus_read_byte_data(client_ptr, adata->offset); - } - - if (ret < 0) { - return ret; - } - - padata->val.intval = ((ret & adata->mask) == adata->cmpval); - } - - return 0; -} - -static int __init pddf_custom_psu_init(void) -{ - access_psu_present.do_get = pddf_custom_psu_present; - access_psu_power_good.do_get = pddf_custom_psu_power_good; - printk(KERN_ERR "pddf_custom_psu_init\n"); - return 0; -} - -static void __exit pddf_custom_psu_exit(void) -{ - printk(KERN_ERR "pddf_custom_psu_exit\n"); - return; -} - -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("pddf custom psu api"); -MODULE_LICENSE("GPL"); - -module_init(pddf_custom_psu_init); -module_exit(pddf_custom_psu_exit); - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_led_defs.h b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_led_defs.h deleted file mode 100644 index 1603f8c5af8e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/pddf_led_defs.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2019 Broadcom. - * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. - * - * 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. - * - * - * Description - * Platform LED related defines and structures - */ - - -/***************************************** - * kobj list - *****************************************/ - -struct kobject *platform_kobj=NULL; -struct kobject *led_kobj=NULL; - -struct kobject *state_attr_kobj=NULL; -struct kobject *cur_state_kobj=NULL; - -/***************************************** - * Static Data provided from user - * space JSON data file - *****************************************/ -#define NAME_SIZE 32 -typedef enum { - STATUS_LED_COLOR_GREEN, - STATUS_LED_COLOR_GREEN_BLINK, - STATUS_LED_COLOR_RED, - STATUS_LED_COLOR_RED_BLINK, - STATUS_LED_COLOR_AMBER, - STATUS_LED_COLOR_AMBER_BLINK, - STATUS_LED_COLOR_BLUE, - STATUS_LED_COLOR_BLUE_BLINK, - STATUS_LED_COLOR_OFF, - MAX_LED_STATUS -}LED_STATUS; - -char* LED_STATUS_STR[] = { - "STATUS_LED_COLOR_GREEN", - "STATUS_LED_COLOR_GREEN_BLINK", - "STATUS_LED_COLOR_RED", - "STATUS_LED_COLOR_RED_BLINK", - "STATUS_LED_COLOR_AMBER", - "STATUS_LED_COLOR_AMBER_BLINK", - "STATUS_LED_COLOR_BLUE", - "STATUS_LED_COLOR_BLUE_BLINK", - "STATUS_LED_COLOR_OFF" -}; - - -typedef struct -{ - char bits[NAME_SIZE]; - int pos; - int mask_bits; -}MASK_BITS; - -typedef struct -{ - int swpld_addr; - int swpld_addr_offset; - MASK_BITS bits; - unsigned short value; -} LED_DATA; - -typedef struct -{ - int state; - char color[NAME_SIZE]; -} CUR_STATE_DATA; - -typedef struct -{ - CUR_STATE_DATA cur_state; - char device_name[NAME_SIZE]; - int index; - LED_DATA data[MAX_LED_STATUS]; - int swpld_addr; - int swpld_addr_offset; -} LED_OPS_DATA; - -typedef enum{ - LED_SYS, - LED_PSU, - LED_FAN, - LED_FANTRAY, - LED_DIAG, - LED_LOC, - LED_TYPE_MAX -} LED_TYPE; -char* LED_TYPE_STR[LED_TYPE_MAX] = -{ - "LED_SYS", - "LED_PSU", - "LED_FAN", - "LED_FANTRAY", - "LED_DIAG", - "LED_LOC", -}; - -/***************************************** - * Data exported from kernel for - * user space plugin to get/set - *****************************************/ -#define PDDF_LED_DATA_ATTR( _prefix, _name, _mode, _show, _store, _type, _len, _addr) \ - struct pddf_data_attribute pddf_dev_##_prefix##_attr_##_name = { .dev_attr = __ATTR(_name, _mode, _show, _store), \ - .type = _type , \ - .len = _len , \ - .addr = _addr } diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/rg_cpld.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/rg_cpld.c deleted file mode 100755 index d8edb73277f6..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/rg_cpld.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * rg_cpld.c - A driver for control rg_cpld base on rg_cpld.c - * - * Copyright (c) 1998, 1999 Frodo Looijaard - * Copyright (c) 2018 support - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef enum { - DBG_START, - DBG_VERBOSE, - DBG_KEY, - DBG_WARN, - DBG_ERROR, - DBG_END, -} dbg_level_t; - -static int debuglevel = 0; -module_param(debuglevel, int, S_IRUGO | S_IWUSR); - -#define DBG_DEBUG(fmt, arg...) do { \ - if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ - printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } else if ( debuglevel >= DBG_ERROR ) { \ - printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } else { } \ -} while (0) - -#define DBG_ERROR(fmt, arg...) do { \ - if ( debuglevel > DBG_START) { \ - printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } \ - } while (0) - -static const unsigned short rg_i2c_cpld[] = { 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, I2C_CLIENT_END }; - -#define CPLD_SIZE 256 -#define CPLD_I2C_RETRY_TIMES 5 -#define CPLD_I2C_RETRY_WAIT_TIME 10 - -#define COMMON_STR_LEN (256) - - -struct cpld_data { - struct i2c_client *client; - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 data[CPLD_SIZE]; /* Register value */ -}; - -static s32 cpld_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) { - if ((ret = i2c_smbus_read_byte_data(client, command) ) >= 0 ) - break; - msleep(CPLD_I2C_RETRY_WAIT_TIME); - } - return ret; -} - -static s32 cpld_i2c_smbus_read_i2c_block_data(const struct i2c_client *client, - u8 command, u8 length, u8 *values) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) { - if ((ret = i2c_smbus_read_i2c_block_data(client, command, length, values) ) >= 0 ) - break; - msleep(CPLD_I2C_RETRY_WAIT_TIME); - } - return ret; -} - -static ssize_t show_fan_rpm_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct cpld_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int index = to_sensor_dev_attr_2(da)->index; - uint8_t size; - s32 status; - s32 ret_t; - - ret_t = 0; - status = -1; - size = 0; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_byte_data(client, index); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - data->data[0] = status; - status = cpld_i2c_smbus_read_byte_data(client, index + 1); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - data->data[1] = status; - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index, data->data[0]); - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index + 1, data->data[1]); - ret_t = (data->data[1] << 8) + data->data[0] ; - if (ret_t == 0 ) { - size = snprintf(buf, CPLD_SIZE, "%d\n", ret_t); - } else if (ret_t == 0xffff) { - size = snprintf(buf, CPLD_SIZE, "%d\n", 0); - } else { - size = snprintf(buf, CPLD_SIZE, "%d\n", 15000000 / ret_t); - } - mutex_unlock(&data->update_lock); - return size; -} - -static ssize_t set_cpld_sysfs_value(struct device *dev, struct device_attribute *da, const char *buf, size_t -count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - unsigned long val; - int err; - - err = kstrtoul(buf, 16, &val); - if (err) - return err; - if ((val < 0) || (val > 0xff)) { - DBG_ERROR("please enter 0x00 ~ 0xff\n"); - return -1; - } - mutex_lock(&data->update_lock); - data->data[0] = (u8)val; - DBG_DEBUG("pos: 0x%02x count = %ld, data = 0x%02x\n", attr->index, count, data->data[0]); - i2c_smbus_write_byte_data(client, attr->index, data->data[0]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - s32 status; - - status = -1; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_i2c_block_data(client, 0, 4, data->data); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - mutex_unlock(&data->update_lock); - return snprintf(buf, COMMON_STR_LEN, "%02x %02x %02x %02x \n", data->data[0], data->data[1], data->data[2], - data->data[3]); -} - -static ssize_t show_cpld_sysfs_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - s32 status; - - status = -1; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_byte_data(client, attr->index); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - data->data[0] = status; - DBG_DEBUG("cpld reg pos:0x%x value:0x%02x\n", attr->index, data->data[0]); - mutex_unlock(&data->update_lock); - return snprintf(buf, COMMON_STR_LEN, "%02x\n", data->data[0]); -} - -/* sys */ -static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, show_cpld_version, NULL, 0); -static SENSOR_DEVICE_ATTR(broad_back_sys, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x72); -static SENSOR_DEVICE_ATTR(broad_front_pwr, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x73); -static SENSOR_DEVICE_ATTR(broad_front_fan, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x74); - - -/* fan */ -static SENSOR_DEVICE_ATTR(fan_present, S_IRUGO, show_cpld_sysfs_value, NULL, 0x30); -static SENSOR_DEVICE_ATTR(fan_status, S_IRUGO, show_cpld_sysfs_value, NULL, 0x31); - -static SENSOR_DEVICE_ATTR(fan1_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x14); -static SENSOR_DEVICE_ATTR(fan1_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x1B); -static SENSOR_DEVICE_ATTR(fan1_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x25); -static SENSOR_DEVICE_ATTR(fan1_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3b); - - -static SENSOR_DEVICE_ATTR(fan2_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15); -static SENSOR_DEVICE_ATTR(fan2_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x1D); -static SENSOR_DEVICE_ATTR(fan2_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x27); -static SENSOR_DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3c); - - -static SENSOR_DEVICE_ATTR(fan3_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x16); -static SENSOR_DEVICE_ATTR(fan3_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x1F); -static SENSOR_DEVICE_ATTR(fan3_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x29); -static SENSOR_DEVICE_ATTR(fan3_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3d); - - -static SENSOR_DEVICE_ATTR(fan4_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x17); -static SENSOR_DEVICE_ATTR(fan4_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x21); -static SENSOR_DEVICE_ATTR(fan4_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x2b); -static SENSOR_DEVICE_ATTR(fan4_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3e); - -static SENSOR_DEVICE_ATTR(fan5_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x18); -static SENSOR_DEVICE_ATTR(fan5_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x23); -static SENSOR_DEVICE_ATTR(fan5_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x2d); -static SENSOR_DEVICE_ATTR(fan5_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3f); - -/* sfp */ -static SENSOR_DEVICE_ATTR(sfp_enable, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, -0x94); -static SENSOR_DEVICE_ATTR(sfp_presence1, S_IRUGO, show_cpld_sysfs_value, NULL, 0x10); -static SENSOR_DEVICE_ATTR(sfp_presence2, S_IRUGO, show_cpld_sysfs_value, NULL, 0x11); -static SENSOR_DEVICE_ATTR(sfp_presence3, S_IRUGO, show_cpld_sysfs_value, NULL, 0x10); -static SENSOR_DEVICE_ATTR(sfp_presence4, S_IRUGO, show_cpld_sysfs_value, NULL, 0x11); -static SENSOR_DEVICE_ATTR(sfp_led1, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x18); -static SENSOR_DEVICE_ATTR(sfp_led2, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x19); -static SENSOR_DEVICE_ATTR(sfp_led3, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x18); -static SENSOR_DEVICE_ATTR(sfp_led4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x19); -static SENSOR_DEVICE_ATTR(sfp_reset1, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x14); -static SENSOR_DEVICE_ATTR(sfp_reset2, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15); -static SENSOR_DEVICE_ATTR(sfp_reset3, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x14); -static SENSOR_DEVICE_ATTR(sfp_reset4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15); - -static struct attribute *cpld_bus2_addr_0x0d_sysfs_attrs[] = { - &sensor_dev_attr_cpld_version.dev_attr.attr, - &sensor_dev_attr_fan_present.dev_attr.attr, - &sensor_dev_attr_fan_status.dev_attr.attr, - - &sensor_dev_attr_fan1_speed_set.dev_attr.attr, - &sensor_dev_attr_fan1_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan1_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan1_led.dev_attr.attr, - - &sensor_dev_attr_fan2_speed_set.dev_attr.attr, - &sensor_dev_attr_fan2_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan2_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan2_led.dev_attr.attr, - - &sensor_dev_attr_fan3_speed_set.dev_attr.attr, - &sensor_dev_attr_fan3_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan3_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan3_led.dev_attr.attr, - - &sensor_dev_attr_fan4_speed_set.dev_attr.attr, - &sensor_dev_attr_fan4_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan4_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan4_led.dev_attr.attr, - - &sensor_dev_attr_fan5_speed_set.dev_attr.attr, - &sensor_dev_attr_fan5_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan5_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan5_led.dev_attr.attr, - NULL -}; - -static struct attribute *cpld_bus6_addr_0x0d_sysfs_attrs[] = { - &sensor_dev_attr_cpld_version.dev_attr.attr, - &sensor_dev_attr_broad_back_sys.dev_attr.attr, - &sensor_dev_attr_broad_front_pwr.dev_attr.attr, - &sensor_dev_attr_broad_front_fan.dev_attr.attr, - &sensor_dev_attr_sfp_enable.dev_attr.attr, - NULL -}; - -static struct attribute *cpld_bus8_addr_0x30_sysfs_attrs[] = { - &sensor_dev_attr_sfp_presence1.dev_attr.attr, - &sensor_dev_attr_sfp_presence2.dev_attr.attr, - &sensor_dev_attr_sfp_led1.dev_attr.attr, - &sensor_dev_attr_sfp_led2.dev_attr.attr, - &sensor_dev_attr_sfp_reset1.dev_attr.attr, - &sensor_dev_attr_sfp_reset2.dev_attr.attr, - NULL -}; - -static struct attribute *cpld_bus8_addr_0x31_sysfs_attrs[] = { - &sensor_dev_attr_sfp_presence3.dev_attr.attr, - &sensor_dev_attr_sfp_presence4.dev_attr.attr, - &sensor_dev_attr_sfp_led3.dev_attr.attr, - &sensor_dev_attr_sfp_led4.dev_attr.attr, - &sensor_dev_attr_sfp_reset3.dev_attr.attr, - &sensor_dev_attr_sfp_reset4.dev_attr.attr, - NULL -}; - -static const struct attribute_group cpld_bus2_addr_0x0d_sysfs_group = { - .attrs = cpld_bus2_addr_0x0d_sysfs_attrs, -}; - -static const struct attribute_group cpld_bus6_addr_0x0d_sysfs_group = { - .attrs = cpld_bus6_addr_0x0d_sysfs_attrs, -}; - -static const struct attribute_group cpld_bus8_addr_0x30_sysfs_group = { - .attrs = cpld_bus8_addr_0x30_sysfs_attrs, -}; - -static const struct attribute_group cpld_bus8_addr_0x31_sysfs_group = { - .attrs = cpld_bus8_addr_0x31_sysfs_attrs, -}; - -struct cpld_attr_match_group { - int bus_nr; - unsigned short addr; - const struct attribute_group *attr_group_ptr; - const struct attribute_group *attr_hwmon_ptr; -}; - -static struct cpld_attr_match_group g_cpld_attr_match[] = { - {2, 0x0d, &cpld_bus2_addr_0x0d_sysfs_group, NULL}, - /* {6, 0x0d, &cpld_bus6_addr_0x0d_sysfs_group, NULL}, */ - {8, 0x30, &cpld_bus8_addr_0x30_sysfs_group, NULL}, - {8, 0x31, &cpld_bus8_addr_0x31_sysfs_group, NULL}, -}; - -static const struct attribute_group *cpld_get_attr_group(struct i2c_client *client, int is_hwmon) -{ - int i; - struct cpld_attr_match_group *group; - - for (i = 0; i < ARRAY_SIZE(g_cpld_attr_match); i++) { - group = &g_cpld_attr_match[i]; - DBG_DEBUG("is_hwmon %d i %d client(nr:%d,addr:0x%x), group(nr:%d,addr:0x0%x) .\n", is_hwmon, - i, client->adapter->nr, client->addr, group->bus_nr, group->addr); - if ((client->addr == group->addr) && (client->adapter->nr == group->bus_nr)) { - DBG_DEBUG("is_hwmon %d i %d nr %d addr %d .\n", is_hwmon, i, client->adapter->nr, client->addr); - return (is_hwmon) ? (group->attr_hwmon_ptr) : (group->attr_group_ptr); - } - } - - DBG_DEBUG("is_hwmon %d nr %d addr %d dismatch, return NULL.\n", is_hwmon, client->adapter->nr, client->addr); - return NULL; -} - -#if 0 -static int cpld_detect(struct i2c_client *new_client, struct i2c_board_info *info) -{ - struct i2c_adapter *adapter = new_client->adapter; - int conf; - DBG_DEBUG("=========cpld_detect(0x%x)===========\n", new_client->addr); - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) - return -ENODEV; - conf = i2c_smbus_read_byte_data(new_client, 0); - if (!conf) - return -ENODEV; - strlcpy(info->type, "rg_cpld", I2C_NAME_SIZE); - return 0; -} -#endif - -static int cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct cpld_data *data; - int status; - const struct attribute_group *sysfs_group, *hwmon_group; - - status = -1; - DBG_DEBUG("=========cpld_probe(addr:0x%x, nr:%d)===========\n", client->addr, client->adapter->nr); - data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), GFP_KERNEL); - if (!data) { - return -ENOMEM; - } - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - sysfs_group = NULL; - sysfs_group = cpld_get_attr_group(client, 0); - if (sysfs_group) { - status = sysfs_create_group(&client->dev.kobj, sysfs_group); - DBG_DEBUG("=========(addr:0x%x, nr:%d) sysfs_create_group status %d===========\n", client->addr, client->adapter->nr, status); - if (status != 0) { - DBG_ERROR("sysfs_create_group status %d.\n", status); - goto error; - } - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no sysfs_create_group \n", client->addr, client->adapter->nr); - } - - hwmon_group = NULL; - hwmon_group = cpld_get_attr_group(client, 1); - if (hwmon_group) { - data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, (const struct attribute_group **)hwmon_group); - if (IS_ERR(data->hwmon_dev)) { - sysfs_remove_group(&client->dev.kobj, (const struct attribute_group *)sysfs_group); - DBG_ERROR("hwmon_device_register_with_groups failed ret %ld.\n", PTR_ERR(data->hwmon_dev)); - return PTR_ERR(data->hwmon_dev); - } - DBG_DEBUG("=========(addr:0x%x, nr:%d) hwmon_device_register_with_groups success===========\n", client->addr, client->adapter->nr); - if (status != 0) { - DBG_ERROR("sysfs_create_group status %d.\n", status); - goto error; - } - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no hwmon_device_register_with_groups \n", client->addr, client->adapter->nr); - } - -error: - return status; - -} - -static int cpld_remove(struct i2c_client *client) -{ - struct cpld_data *data = i2c_get_clientdata(client); - const struct attribute_group *sysfs_group, *hwmon_group; - - DBG_DEBUG("=========cpld_remove(addr:0x%x, nr:%d)===========\n", client->addr, client->adapter->nr); - - sysfs_group = NULL; - sysfs_group = cpld_get_attr_group(client, 0); - if (sysfs_group) { - DBG_DEBUG("=========(addr:0x%x, nr:%d) do sysfs_remove_group \n", client->addr, client->adapter->nr); - sysfs_remove_group(&client->dev.kobj, (const struct attribute_group *)sysfs_group); - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no sysfs_remove_group \n", client->addr, client->adapter->nr); - } - - hwmon_group = NULL; - hwmon_group = cpld_get_attr_group(client, 1); - if (hwmon_group) { - DBG_DEBUG("=========(addr:0x%x, nr:%d) do hwmon_device_unregister \n", client->addr, client->adapter->nr); - hwmon_device_unregister(data->hwmon_dev); - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no hwmon_device_unregister \n", client->addr, client->adapter->nr); - } - - return 0; -} - -static const struct i2c_device_id cpld_id[] = { - { "rg_cpld", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, cpld_id); - -static struct i2c_driver rg_cpld_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "rg_cpld", - }, - .probe = cpld_probe, - .remove = cpld_remove, - .id_table = cpld_id, - //.detect = cpld_detect, - // .address_list = rg_i2c_cpld, -}; - -module_i2c_driver(rg_cpld_driver); -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("ragile CPLD driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/rg_lpc_cpld.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/rg_lpc_cpld.c deleted file mode 100755 index 7f32a47436b7..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/rg_lpc_cpld.c +++ /dev/null @@ -1,237 +0,0 @@ -#include /* Wd're doing kernel work */ -#include /* specifically, a module */ -#include -#include /* Need for the macros */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ragile.h" - -int lpc_cpld_verbose = 0; -int lpc_cpld_error = 0; -module_param(lpc_cpld_verbose, int, S_IRUGO | S_IWUSR); -module_param(lpc_cpld_error, int, S_IRUGO | S_IWUSR); - - -#define LPC_CPLD_VERBOSE(fmt, args...) do { \ - if (lpc_cpld_verbose) { \ - printk(KERN_ERR "[LPC_CPLD_I2C_DEVICE][VERBOSE][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define LPC_CPLD_ERROR(fmt, args...) do { \ - if (lpc_cpld_error) { \ - printk(KERN_ERR "[LPC_CPLD_I2C_DEVICE][ERROR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ - } while (0) - -#define PCI_VENDOR_ID_D1527_LPC (0x8c54) -#define PCI_VENDOR_ID_C3000_LPC (0x19dc) - -#define MAX_CPLD_REG_SIZE (0x100) -#define LPC_GET_CPLD_ID(addr) ((addr >> 16) & 0xff) -#define LPC_GET_CPLD_OFFSET(addr) ((addr) & 0xff) -typedef struct rg_lpc_device_s { - u16 base; - u16 size; - u8 type; - u8 id; -} rg_lpc_device_t; - -typedef enum rg_lpc_dev_type_s { - LPC_DEVICE_CPLD = 1, - LPC_DEVICE_FPGA = 2, -} rg_lpc_dev_type_t; - -static rg_lpc_device_t g_rg_lpc_dev[] = { - {.base = 0x700, .size = MAX_CPLD_REG_SIZE, .type = LPC_DEVICE_CPLD, .id = 0}, - {.base = 0x900, .size = MAX_CPLD_REG_SIZE, .type = LPC_DEVICE_CPLD, .id = 1}, - {.base = 0xb00, .size = MAX_CPLD_REG_SIZE, .type = LPC_DEVICE_CPLD, .id = 2}, - /*{.base = 0x900, .size = MAX_FPGA_REG_SIZE, .type = LPC_DEVICE_FPGA, .id = 0},*/ -}; - -static rg_lpc_device_t* lpc_get_device_info(int type, int id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(g_rg_lpc_dev); i++) { - if ((g_rg_lpc_dev[i].type == type) && (g_rg_lpc_dev[i].id == id)) { - return &g_rg_lpc_dev[i]; - } - } - - return NULL; -} - -static int lpc_cpld_read(int address, u8 *val) -{ - int cpld_id; - rg_lpc_device_t *info; - - LPC_CPLD_ERROR("Enter\n"); - cpld_id = LPC_GET_CPLD_ID(address); - LPC_CPLD_ERROR("icpld_id=%d\n", cpld_id); - info = lpc_get_device_info(LPC_DEVICE_CPLD, cpld_id); - if (info == NULL) { - LPC_CPLD_ERROR("lpc_get_device_info addr 0x%x id %d failed.\r\n", address, cpld_id); - return -1; - } - - *val = inb(info->base + LPC_GET_CPLD_OFFSET(address)); - LPC_CPLD_VERBOSE("Leave info->base 0x%x, addr 0x%x, cpld_id %d, val 0x%x.\r\n", info->base, address, cpld_id, *val); - return 0; -} - -static int lpc_cpld_write(int address, u8 reg_val) -{ - int cpld_id; - rg_lpc_device_t *info; - - cpld_id = LPC_GET_CPLD_ID(address); - info = lpc_get_device_info(LPC_DEVICE_CPLD, cpld_id); - if (info == NULL) { - LPC_CPLD_ERROR("lpc_get_device_info addr 0x%x id %d failed.\r\n", address, cpld_id); - return -1; - } - - outb(reg_val, info->base + LPC_GET_CPLD_OFFSET(address)); - LPC_CPLD_VERBOSE("Leave info->base 0x%x, addr 0x%x, cpld_id %d, val 0x%x.\r\n", info->base, address, cpld_id, reg_val); - return 0; -} - -static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da, char *buf) -{ - int ret, i; - u8 data[4]; - u32 index = to_sensor_dev_attr(da)->index; - - memset(data, 0 ,sizeof(data)); - for (i = 0; i < 4; i++) { - ret = lpc_cpld_read(index + i, &data[i]); - if (ret != 0) { - memset(data, 0 ,sizeof(data)); - LPC_CPLD_ERROR("get cpld version failed!\n"); - break; - } - } - - return snprintf(buf, COMMON_STR_LEN, "%02x %02x %02x %02x \n", data[0], data[1], data[2], data[3]); - -} - -static ssize_t show_cpld_sysfs_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - u8 data; - int ret; - - ret = lpc_cpld_read(attr->index, &data); - if (ret != 0) { - LPC_CPLD_ERROR("get cpld[0x%x] value failed!\n", attr->index); - data = 0; - } - return snprintf(buf, COMMON_STR_LEN, "%02x\n", data); -} - -static ssize_t set_cpld_sysfs_value(struct device *dev, struct device_attribute *da, const char *buf, size_t -count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - u8 data; - unsigned long val; - int err; - - err = kstrtoul(buf, 16, &val); - if (err) - return err; - if ((val < 0) || (val > 0xff)) { - LPC_CPLD_ERROR("please enter 0x00 ~ 0xff\n"); - return -1; - } - - data = (u8)val; - LPC_CPLD_VERBOSE("pos: 0x%02x count = %ld, data = 0x%02x\n", attr->index, count, data); - err = lpc_cpld_write(attr->index, data); - if (err != 0) { - LPC_CPLD_ERROR("set cpld[0x%x] value[0x%x] failed!\n", attr->index, data); - count = 0; - } - - return count; -} - -/* connect board cpld 0x900 id=1 */ -static SENSOR_DEVICE_ATTR(connect_cpld_version, S_IRUGO, show_cpld_version, NULL, 0x10000); -static SENSOR_DEVICE_ATTR(broad_front_sys, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x10072); -static SENSOR_DEVICE_ATTR(psu_status, S_IRUGO, show_cpld_sysfs_value, NULL, 0x10051); -static SENSOR_DEVICE_ATTR(broad_front_pwr, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x10073); -static SENSOR_DEVICE_ATTR(broad_front_fan, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x10074); -static SENSOR_DEVICE_ATTR(sfp_enable, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x10094); - -static struct attribute *lpc_cpld_base_sysfs_attrs[] = { - &sensor_dev_attr_connect_cpld_version.dev_attr.attr, - &sensor_dev_attr_broad_front_sys.dev_attr.attr, - &sensor_dev_attr_psu_status.dev_attr.attr, - &sensor_dev_attr_broad_front_pwr.dev_attr.attr, - &sensor_dev_attr_broad_front_fan.dev_attr.attr, - &sensor_dev_attr_sfp_enable.dev_attr.attr, - NULL -}; - -static const struct attribute_group lpc_cpld_base_sysfs_group = { - .attrs = lpc_cpld_base_sysfs_attrs, -}; - -static int __init rg_lpc_cpld_init(void) -{ - struct pci_dev *pdev = NULL; - int status; - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC, pdev); - if (!pdev) { - LPC_CPLD_ERROR("pci_get_device(0x8086, 0x8c54) failed!\n"); - return -1; - } - - status = -1; - status = sysfs_create_group(&pdev->dev.kobj, &lpc_cpld_base_sysfs_group); - if (status) { - LPC_CPLD_ERROR("sysfs_create_group failed!\n"); - return -1; - } - - LPC_CPLD_VERBOSE("Leave success\n"); - return 0; -} - -static void __exit rg_lpc_cpld_exit(void) -{ - struct pci_dev *pdev = NULL; - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC, pdev); - if (!pdev) { - LPC_CPLD_ERROR("pci_get_device(0x8086, 0x8c54) failed!\n"); - return ; - } - - sysfs_remove_group(&pdev->dev.kobj, &lpc_cpld_base_sysfs_group); - - LPC_CPLD_VERBOSE("Leave.\n"); -} - -module_init(rg_lpc_cpld_init); -module_exit(rg_lpc_cpld_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("support "); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_firmware_upgrade_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_firmware_upgrade_device.c new file mode 100644 index 000000000000..1f3d4076bc4c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_firmware_upgrade_device.c @@ -0,0 +1,178 @@ +/* + * wb_firmware_upgrade.c + * Original Author: support 2021-03-17 + * + * ko for firmware device + * History + * [Version] [Author] [Date] [Description] + * v1.0 support 2021-05-07 Initial version + */ +#include +#include +#include +#include +#include +#include + +static int g_wb_firmware_upgrade_debug = 0; +static int g_wb_firmware_upgrade_error = 0; + +module_param(g_wb_firmware_upgrade_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_firmware_upgrade_error, int, S_IRUGO | S_IWUSR); + +#define WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_firmware_upgrade_debug) { \ + printk(KERN_INFO "[WB_FIRMWARE_UPGRADE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FIRMWARE_UPGRADE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_firmware_upgrade_error) { \ + printk(KERN_ERR "[WB_FIRMWARE_UPGRADE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 48, + .en_level[1] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* fpga */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "SPI_LOGIC", + .chain = 3, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x1A0000, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "SPI_LOGIC", + .chain = 4, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x0, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* bios */ +static firmware_upgrade_device_t firmware_upgrade_device_data3 = { + .type = "MTD_DEV", + .chain = 2, + .chip_index = 1, + .upg_type.sysfs = { + .mtd_name = "BIOS", + .flash_base = 0x800000, + }, + + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 4, + .dev = { + .platform_data = &firmware_upgrade_device_data3, + .release = firmware_device_release, + }, + }, + }; + + static int __init firmware_upgrade_device_init(void) + { + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; + } + + static void __exit firmware_upgrade_device_exit(void) + { + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&firmware_upgrade_device[i]); + } + } + } + + module_init(firmware_upgrade_device_init); + module_exit(firmware_upgrade_device_exit); + MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_dev_device.c new file mode 100644 index 000000000000..9a5173142e95 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_dev_device.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_dev_device_debug = 0; +static int g_wb_i2c_dev_device_error = 0; + +module_param(g_wb_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_dev_device_t i2c_dev_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x0d, + .i2c_name = "cpld2", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data1 = { + .i2c_bus = 8, + .i2c_addr = 0x30, + .i2c_name = "cpld3", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data2 = { + .i2c_bus = 8, + .i2c_addr = 0x31, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +struct i2c_board_info i2c_dev_device_info[] = { + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data0, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data1, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data2, + }, +}; + +static int __init wb_i2c_dev_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_dev_device_info); i++) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + i2c_dev_device_info[i].addr = i2c_dev_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_dev_device_data->i2c_bus); + if (adap == NULL) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_dev_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); + if (!client) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", + i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); + } else { + i2c_dev_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_dev_device_exit(void) +{ + int i; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_dev_device_info) - 1; i >= 0; i--) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + if (i2c_dev_device_data->client) { + i2c_unregister_device(i2c_dev_device_data->client); + i2c_dev_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_dev_device_init); +module_exit(wb_i2c_dev_device_exit); +MODULE_DESCRIPTION("I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 000000000000..0a2a8b203b3c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,224 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca954x_device_debug = 0; +static int g_wb_i2c_mux_pca954x_device_error = 0; + +module_param(g_wb_i2c_mux_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 16, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/cpld1", + .file_attr.offset = 0x60, + .file_attr.mask = 0x02, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data1 = { + .i2c_bus = 4, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 24, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/cpld1", + .file_attr.offset = 0x60, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data2 = { + .i2c_bus = 12, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 32, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data3 = { + .i2c_bus = 12, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 40, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data4 = { + .i2c_bus = 12, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 48, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data5 = { + .i2c_bus = 12, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 56, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data1, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data2, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data3, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data4, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data5, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (!client) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_ocores_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_ocores_device.c new file mode 100644 index 000000000000..ff7ba9d26fbc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_i2c_ocores_device.c @@ -0,0 +1,423 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_ocores_device_debug = 0; +static int g_wb_i2c_ocores_device_error = 0; + +module_param(g_wb_i2c_ocores_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_ocores_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_debug) { \ + printk(KERN_INFO "[WB_I2C_OCORE_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_OCORE_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_error) { \ + printk(KERN_ERR "[WB_I2C_OCORE_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_ocores_device_t i2c_ocores_device_data0 = { + .adap_nr = 2, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0800, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 0, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data1 = { + .adap_nr = 3, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0820, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 1, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data2 = { + .adap_nr = 4, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0840, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 2, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data3 = { + .adap_nr = 5, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0860, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 3, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data4 = { + .adap_nr = 6, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0880, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 4, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data5 = { + .adap_nr = 7, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08a0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 5, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data6 = { + .adap_nr = 8, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08c0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 6, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data7 = { + .adap_nr = 9, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08e0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 7, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data8 = { + .adap_nr = 10, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0900, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 8, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data9 = { + .adap_nr = 11, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0920, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 9, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data10 = { + .adap_nr = 12, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0940, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 10, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data11 = { + .adap_nr = 13, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0960, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 11, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data12 = { + .adap_nr = 14, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0980, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 12, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data13 = { + .adap_nr = 15, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x09a0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 13, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static void wb_i2c_ocores_device_release(struct device *dev) +{ + return; +} + +static struct platform_device i2c_ocores_device[] = { + { + .name = "wb-ocores-i2c", + .id = 1, + .dev = { + .platform_data = &i2c_ocores_device_data0, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 2, + .dev = { + .platform_data = &i2c_ocores_device_data1, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 3, + .dev = { + .platform_data = &i2c_ocores_device_data2, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 4, + .dev = { + .platform_data = &i2c_ocores_device_data3, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 5, + .dev = { + .platform_data = &i2c_ocores_device_data4, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 6, + .dev = { + .platform_data = &i2c_ocores_device_data5, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 7, + .dev = { + .platform_data = &i2c_ocores_device_data6, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 8, + .dev = { + .platform_data = &i2c_ocores_device_data7, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 9, + .dev = { + .platform_data = &i2c_ocores_device_data8, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 10, + .dev = { + .platform_data = &i2c_ocores_device_data9, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 11, + .dev = { + .platform_data = &i2c_ocores_device_data10, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 12, + .dev = { + .platform_data = &i2c_ocores_device_data11, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 13, + .dev = { + .platform_data = &i2c_ocores_device_data12, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 14, + .dev = { + .platform_data = &i2c_ocores_device_data13, + .release = wb_i2c_ocores_device_release, + }, + }, +}; + +static int __init wb_i2c_ocores_device_init(void) +{ + int i; + int ret = 0; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_ocores_device); i++) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + ret = platform_device_register(&i2c_ocores_device[i]); + if (ret < 0) { + i2c_ocores_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-ocores-i2c.%d register failed!\n", i + 1); + } else { + i2c_ocores_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_i2c_ocores_device_exit(void) +{ + int i; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_ocores_device) - 1; i >= 0; i--) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + if (i2c_ocores_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&i2c_ocores_device[i]); + } + } +} + +module_init(wb_i2c_ocores_device_init); +module_exit(wb_i2c_ocores_device_exit); +MODULE_DESCRIPTION("I2C OCORES Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..cc84938fff0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_io_dev_device.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data1 = { + .io_dev_name = "cpld1", + .io_base = 0x900, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 2, + .dev = { + .platform_data = &io_dev_device_data1, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..9b6b61a51735 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static lpc_drv_device_t lpc_drv_device_data_1 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x900, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x88, +}; + +static lpc_drv_device_t lpc_drv_device_data_2 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0xb00, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x90, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 2, + .dev = { + .platform_data = &lpc_drv_device_data_1, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 3, + .dev = { + .platform_data = &lpc_drv_device_data_2, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_pcie_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_pcie_dev_device.c new file mode 100644 index 000000000000..f79b29770d29 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/wb_pcie_dev_device.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_pcie_dev_device_debug = 0; +static int g_wb_pcie_dev_device_error = 0; + +module_param(g_wb_pcie_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_pcie_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_pcie_dev_device_debug) { \ + printk(KERN_INFO "[WB_PCIE_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PCIE_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_pcie_dev_device_error) { \ + printk(KERN_ERR "[WB_PCIE_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static pci_dev_device_t pcie_dev_device_data0 = { + .pci_dev_name = "fpga0", + .pci_domain = 0x0000, + .pci_bus = 0x08, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .upg_ctrl_base = 0xa00, + .upg_flash_base = 0x1a0000, +}; + +static void wb_pcie_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device pcie_dev_device[] = { + { + .name = "wb-pci-dev", + .id = 1, + .dev = { + .platform_data = &pcie_dev_device_data0, + .release = wb_pcie_dev_device_release, + }, + }, +}; + +static int __init wb_pcie_dev_device_init(void) +{ + int i; + int ret = 0; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(pcie_dev_device); i++) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + ret = platform_device_register(&pcie_dev_device[i]); + if (ret < 0) { + pcie_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-pci-dev.%d register failed!\n", i + 1); + } else { + pcie_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_pcie_dev_device_exit(void) +{ + int i; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(pcie_dev_device) - 1; i >= 0; i--) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + if (pcie_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&pcie_dev_device[i]); + } + } +} + +module_init(wb_pcie_dev_device_init); +module_exit(wb_pcie_dev_device_exit); +MODULE_DESCRIPTION("PCIE DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..927521a384ff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,38 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_0_2=2 +cpld_i2c_dev.addr_0_2=0x0d +cpld_i2c_dev.bus_0_3=8 +cpld_i2c_dev.addr_0_3=0x30 +cpld_i2c_dev.bus_0_4=8 +cpld_i2c_dev.addr_0_4=0x31 + + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_0=0x700 +cpld_lpc_dev_0_1=0x900 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=lpc +mode_cpld_0_1=lpc +mode_cpld_0_2=i2c +mode_cpld_0_3=i2c +mode_cpld_0_4=i2c + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=5 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..e46f690f317a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,372 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=5 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=2 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x00020030 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x00020030 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=1 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x00020030 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=2 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=cpld +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.addr_1_4=0x00020030 +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=3 + +dev_present_status.mode_1_5=config +dev_present_status.src_1_5=cpld +dev_present_status.frmt_1_5=bit +dev_present_status.pola_1_5=negative +dev_present_status.addr_1_5=0x00020030 +dev_present_status.len_1_5=1 +dev_present_status.bit_offset_1_5=4 + + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x00020031 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=0 + +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=cpld +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1= +fan_roll_status.addr_1_1=0x00020034 +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=0 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x00020031 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=1 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=cpld +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1= +fan_roll_status.addr_2_1=0x00020034 +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=1 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x00020031 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=2 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=cpld +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1= +fan_roll_status.addr_3_1=0x00020034 +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=2 + +fan_roll_status.mode_4_0=config +fan_roll_status.int_cons_4_0= +fan_roll_status.src_4_0=cpld +fan_roll_status.frmt_4_0=bit +fan_roll_status.pola_4_0=positive +fan_roll_status.fpath_4_0= +fan_roll_status.addr_4_0=0x00020031 +fan_roll_status.len_4_0=1 +fan_roll_status.bit_offset_4_0=3 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=cpld +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1= +fan_roll_status.addr_4_1=0x00020034 +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=3 + +fan_roll_status.mode_5_0=config +fan_roll_status.int_cons_5_0= +fan_roll_status.src_5_0=cpld +fan_roll_status.frmt_5_0=bit +fan_roll_status.pola_5_0=positive +fan_roll_status.fpath_5_0= +fan_roll_status.addr_5_0=0x00020031 +fan_roll_status.len_5_0=1 +fan_roll_status.bit_offset_5_0=4 + +fan_roll_status.mode_5_1=config +fan_roll_status.int_cons_5_1= +fan_roll_status.src_5_1=cpld +fan_roll_status.frmt_5_1=bit +fan_roll_status.pola_5_1=positive +fan_roll_status.fpath_5_1= +fan_roll_status.addr_5_1=0x00020034 +fan_roll_status.len_5_1=1 +fan_roll_status.bit_offset_5_1=4 + + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x0002001b +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=cpld +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1=negative +fan_speed.fpath_1_1= +fan_speed.addr_1_1=0x00020025 +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0002001d +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=cpld +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1=negative +fan_speed.fpath_2_1= +fan_speed.addr_2_1=0x00020027 +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0002001f +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=cpld +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1=negative +fan_speed.fpath_3_1= +fan_speed.addr_3_1=0x00020029 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_4_0=config +fan_speed.int_cons_4_0= +fan_speed.src_4_0=cpld +fan_speed.frmt_4_0=num_bytes +fan_speed.pola_4_0=negative +fan_speed.fpath_4_0= +fan_speed.addr_4_0=0x00020021 +fan_speed.len_4_0=2 +fan_speed.bit_offset_4_0= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=cpld +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1=negative +fan_speed.fpath_4_1= +fan_speed.addr_4_1=0x0002002b +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + +fan_speed.mode_5_0=config +fan_speed.int_cons_5_0= +fan_speed.src_5_0=cpld +fan_speed.frmt_5_0=num_bytes +fan_speed.pola_5_0=negative +fan_speed.fpath_5_0= +fan_speed.addr_5_0=0x00020023 +fan_speed.len_5_0=2 +fan_speed.bit_offset_5_0= + +fan_speed.mode_5_1=config +fan_speed.int_cons_5_1= +fan_speed.src_5_1=cpld +fan_speed.frmt_5_1=num_bytes +fan_speed.pola_5_1=negative +fan_speed.fpath_5_1= +fan_speed.addr_5_1=0x0002002d +fan_speed.len_5_1=2 +fan_speed.bit_offset_5_1= + + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x00020014 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_1_1=config +fan_ratio.int_cons_1_1= +fan_ratio.src_1_1=cpld +fan_ratio.frmt_1_1=byte +fan_ratio.pola_1_1= +fan_ratio.fpath_1_1= +fan_ratio.addr_1_1=0x00020014 +fan_ratio.len_1_1=1 +fan_ratio.bit_offset_1_1= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x00020015 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_2_1=config +fan_ratio.int_cons_2_1= +fan_ratio.src_2_1=cpld +fan_ratio.frmt_2_1=byte +fan_ratio.pola_2_1= +fan_ratio.fpath_2_1= +fan_ratio.addr_2_1=0x00020015 +fan_ratio.len_2_1=1 +fan_ratio.bit_offset_2_1= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x00020016 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= + +fan_ratio.mode_3_1=config +fan_ratio.int_cons_3_1= +fan_ratio.src_3_1=cpld +fan_ratio.frmt_3_1=byte +fan_ratio.pola_3_1= +fan_ratio.fpath_3_1= +fan_ratio.addr_3_1=0x00020016 +fan_ratio.len_3_1=1 +fan_ratio.bit_offset_3_1= + +fan_ratio.mode_4_0=config +fan_ratio.int_cons_4_0= +fan_ratio.src_4_0=cpld +fan_ratio.frmt_4_0=byte +fan_ratio.pola_4_0= +fan_ratio.fpath_4_0= +fan_ratio.addr_4_0=0x00020017 +fan_ratio.len_4_0=1 +fan_ratio.bit_offset_4_0= + +fan_ratio.mode_4_1=config +fan_ratio.int_cons_4_1= +fan_ratio.src_4_1=cpld +fan_ratio.frmt_4_1=byte +fan_ratio.pola_4_1= +fan_ratio.fpath_4_1= +fan_ratio.addr_4_1=0x00020017 +fan_ratio.len_4_1=1 +fan_ratio.bit_offset_4_1= + +fan_ratio.mode_5_0=config +fan_ratio.int_cons_5_0= +fan_ratio.src_5_0=cpld +fan_ratio.frmt_5_0=byte +fan_ratio.pola_5_0= +fan_ratio.fpath_5_0= +fan_ratio.addr_5_0=0x00020018 +fan_ratio.len_5_0=1 +fan_ratio.bit_offset_5_0= + +fan_ratio.mode_5_1=config +fan_ratio.int_cons_5_1= +fan_ratio.src_5_1=cpld +fan_ratio.frmt_5_1=byte +fan_ratio.pola_5_1= +fan_ratio.fpath_5_1= +fan_ratio.addr_5_1=0x00020018 +fan_ratio.len_5_1=1 +fan_ratio.bit_offset_5_1= diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..cc4a6dae1db3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,64 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=2 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00010051 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00010051 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00010051 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00010051 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=4 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00010051 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=5 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00010051 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=6 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..ceafe3e9c17b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,306 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=32 + + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x00030010 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x00030010 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x00030010 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x00030010 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x00030010 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x00030010 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x00030010 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x00030010 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x00030011 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x00030011 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x00030011 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x00030011 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x00030011 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x00030011 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x00030011 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x00030011 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x00040010 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x00040010 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x00040010 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x00040010 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x00040010 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x00040010 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x00040010 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x00040010 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x00040011 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x00040011 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x00040011 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x00040011 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x00040011 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x00040011 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x00040011 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x00040011 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/cfg_file_name new file mode 100644 index 000000000000..5f49420441a5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,4 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/setup.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/setup.py index f36055fb4e6d..6c3916921abb 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/setup.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/setup.py @@ -3,18 +3,25 @@ setup( name='sonic-platform', version='1.0', - description='SONiC platform API implementation on RAGILE Platforms', + description='SONiC platform API implementation', license='Apache 2.0', author='SONiC Team', - author_email='support@ragile.com', + author_email='support', url='', - maintainer='RAGILE SUPPORT TEAM', + maintainer='support', maintainer_email='', packages=[ 'sonic_platform', - 'rgutil', + 'plat_hal', + 'wbutil', 'eepromutil', - 'sonic_pcie', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', ], classifiers=[ 'Development Status :: 3 - Alpha', @@ -30,4 +37,3 @@ ], keywords='sonic SONiC platform PLATFORM', ) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_pcie/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_pcie/__init__.py deleted file mode 100644 index 73e2a89c8d74..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_pcie/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["pcie_common"] \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_pcie/pcie_common.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_pcie/pcie_common.py deleted file mode 100644 index 56e9d8664a23..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_pcie/pcie_common.py +++ /dev/null @@ -1,107 +0,0 @@ -# pcie_common.py -# Common PCIE check interfaces for SONIC -# - -import os -import yaml -import subprocess -import re -import sys -from copy import deepcopy -try: - from .pcie import PcieBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class PcieUtil(PcieBase): - """Platform-specific PCIEutil class""" - # got the config file path - def __init__(self, path): - self.config_path = path - - # load the config file - def load_config_file(self): - config_file = self.config_path + "/" + "pcie.yaml" - try: - with open(config_file) as conf_file: - self.confInfo = yaml.load(conf_file) - except IOError as e: - print("Error: {}".format(str(e))) - print("Not found config file, please add a config file manually, or generate it by running [pcieutil pcie_generate]") - sys.exit() - - # load current PCIe device - def get_pcie_device(self): - pciDict = {} - pciList = [] - p1 = "^(\w+):(\w+)\.(\w)\s(.*)\s*\(*.*\)*" - p2 = "^.*:.*:.*:(\w+)\s*\(*.*\)*" - command1 = "sudo lspci" - command2 = "sudo lspci -n" - # run command 1 - proc1 = subprocess.Popen(command1, shell=True, universal_newlines=True, stdout=subprocess.PIPE) - output1 = proc1.stdout.readlines() - proc1.communicate() - # run command 2 - proc2 = subprocess.Popen(command2, shell=True, universal_newlines=True, stdout=subprocess.PIPE) - output2 = proc2.stdout.readlines() - proc2.communicate() - - if proc1.returncode > 0: - for line1 in output1: - print(line1.strip()) - return - elif proc2.returncode > 0: - for line2 in output2: - print(line2.strip()) - return - else: - for (line1, line2) in zip(output1, output2): - pciDict.clear() - match1 = re.search(p1, line1.strip()) - match2 = re.search(p2, line2.strip()) - if match1 and match2: - Bus = match1.group(1) - Dev = match1.group(2) - Fn = match1.group(3) - Name = match1.group(4) - Id = match2.group(1) - pciDict["name"] = Name - pciDict["bus"] = Bus - pciDict["dev"] = Dev - pciDict["fn"] = Fn - pciDict["id"] = Id - pciList.append(pciDict) - pciDict = deepcopy(pciDict) - else: - print("CAN NOT MATCH PCIe DEVICE") - return pciList - - # check the sysfs tree for each PCIe device - def check_pcie_sysfs(self, domain=0, bus=0, device=0, func=0): - dev_path = os.path.join('/sys/bus/pci/devices', '%04x:%02x:%02x.%d' % (domain, bus, device, func)) - if os.path.exists(dev_path): - return True - return False - - # check the current PCIe device with config file and return the result - def get_pcie_check(self): - self.load_config_file() - for item_conf in self.confInfo: - bus_conf = item_conf["bus"] - dev_conf = item_conf["dev"] - fn_conf = item_conf["fn"] - if self.check_pcie_sysfs(bus=int(bus_conf, base=16), device=int(dev_conf, base=16), func=int(fn_conf, base=16)): - item_conf["result"] = "Passed" - else: - item_conf["result"] = "Failed" - return self.confInfo - - # generate the config file with current pci device - def dump_conf_yaml(self): - curInfo = self.get_pcie_device() - with open(self.config_path + "/" + "pcie.yaml", "w") as conf_file: - yaml.dump(curInfo, conf_file, default_flow_style=False) - return - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/__init__.py deleted file mode 100644 index d49ca9b48bbf..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# All the derived classes for PDDF -__all__ = ["platform", "chassis", "sfp", "psu", "thermal", "fan", "fan_drawer"] -from . import platform - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/chassis.py deleted file mode 100644 index ae8e74186825..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/chassis.py +++ /dev/null @@ -1,108 +0,0 @@ -############################################################################# -# PDDF -# Module contains an implementation of SONiC Chassis API -# -############################################################################# - -try: - import time - from sonic_platform_pddf_base.pddf_chassis import PddfChassis - from sonic_platform.fan_drawer import FanDrawer -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -PORT_START = 0 -PORTS_IN_BLOCK = 32 -FAN_NUM_PER_DRAWER = 2 - -class Chassis(PddfChassis): - """ - PDDF Platform-specific Chassis class - """ - - SFP_STATUS_INSERTED = "1" - SFP_STATUS_REMOVED = "0" - port_dict = {} - - def __init__(self, pddf_data=None, pddf_plugin_data=None): - PddfChassis.__init__(self, pddf_data, pddf_plugin_data) - - # fan drawer - temp = [] - drawer_index = 0 - for idx, fan in enumerate(self.get_all_fans()): - temp.append(fan) - if (idx + 1) % FAN_NUM_PER_DRAWER == 0: - drawer = FanDrawer(drawer_index + 1, temp) - self.get_all_fan_drawers().append(drawer) - temp = [] - drawer_index += 1 - - 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. - """ - - return (self.REBOOT_CAUSE_NON_HARDWARE, None) - - def get_change_event(self, timeout=0): - change_event_dict = {"fan": {}, "sfp": {}} - sfp_status, sfp_change_dict = self.get_transceiver_change_event(timeout) - change_event_dict["sfp"] = sfp_change_dict - if sfp_status is True: - return True, change_event_dict - - return False, {} - - def get_transceiver_change_event(self, timeout=0): - start_time = time.time() - currernt_port_dict = {} - forever = False - - if timeout == 0: - forever = True - elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs - else: - print("get_transceiver_change_event:Invalid timeout value", timeout) - return False, {} - - end_time = start_time + timeout - if start_time > end_time: - print( - "get_transceiver_change_event:" "time wrap / invalid timeout value", - timeout, - ) - return False, {} # Time wrap or possibly incorrect timeout - - while timeout >= 0: - # Check for OIR events and return updated port_dict - for index in range(PORT_START, PORTS_IN_BLOCK): - if self._sfp_list[index].get_presence(): - currernt_port_dict[index] = self.SFP_STATUS_INSERTED - else: - currernt_port_dict[index] = self.SFP_STATUS_REMOVED - if currernt_port_dict == self.port_dict: - if forever: - time.sleep(1) - else: - timeout = end_time - time.time() - if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity - else: - if timeout > 0: - time.sleep(timeout) - return True, {} - else: - # Update reg value - self.port_dict = currernt_port_dict - print(self.port_dict) - return True, self.port_dict - print("get_transceiver_change_event: Should not reach here.") - return False, {} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/common.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/common.py deleted file mode 100644 index c1a85f618609..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/common.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -import yaml - -from sonic_py_common import device_info - - -class Common: - - DEVICE_PATH = '/usr/share/sonic/device/' - PMON_PLATFORM_PATH = '/usr/share/sonic/platform/' - CONFIG_DIR = 'sonic_platform_config' - - HOST_CHK_CMD = "docker > /dev/null 2>&1" - - def __init__(self): - (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() - - def is_host(self): - return os.system(self.HOST_CHK_CMD) == 0 - - def load_json_file(self, path): - """ - Retrieves the json object from json file path - - Returns: - A json object - """ - with open(path, 'r') as f: - json_data = yaml.safe_load(f) - - return json_data - - def get_config_path(self, config_name): - """ - Retrieves the path to platform api config directory - - Args: - config_name: A string containing the name of config file. - - Returns: - A string containing the path to json file - """ - return os.path.join(self.DEVICE_PATH, self.platform, self.CONFIG_DIR, config_name) if self.is_host() else os.path.join(self.PMON_PLATFORM_PATH, self.CONFIG_DIR, config_name) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/component.py deleted file mode 100644 index 7c6fd2df4335..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/component.py +++ /dev/null @@ -1,85 +0,0 @@ -######################################################################## -# Ragile RA-B6510-32c -# -# Module contains an implementation of SONiC Platform Base API and -# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in -# the platform -# -######################################################################## - -try: - import subprocess - from sonic_platform_base.component_base import ComponentBase - from sonic_platform.regutil import Reg - from sonic_platform.logger import logger -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Component(ComponentBase): - """ Ragile Platform-specific Component class""" - - def __init__(self, index, config=None): - self.index = index - self.name = config.get("name") - self._reg_fm_ver = Reg(config.get("firmware_version")) - self.description = config.get("desc") - self.slot = config.get("slot") - - 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 - """ - return self.description - - def get_firmware_version(self): - """ - Retrieves the firmware version of the component - - Returns: - A string containing the firmware version of the component - """ - try: - return self._reg_fm_ver.decode() - except Exception as e: - logger.error(str(e)) - - return "" - - def install_firmware(self, image_path): - """ - Installs firmware to the component - - Args: - image_path: A string, path to firmware image - - Returns: - A boolean, True if install was successful, False if not - """ - try: - successtips = "CPLD Upgrade succeeded!" - status, output = subprocess.getstatusoutput("which firmware_upgrade") - if status or len(output) <= 0: - logger.error("no upgrade tool.") - return False - cmdstr = "%s %s cpld %d cpld"%(output,image_path,self.slot) - ret, log = subprocess.getstatusoutput(cmdstr) - if ret == 0 and successtips in log: - return True - logger.error("upgrade failed. ret:%d, log:\n%s" % (ret, log)) - except Exception as e: - logger.error(str(e)) - return False - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/config.py deleted file mode 100644 index 7d3064163b30..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/config.py +++ /dev/null @@ -1,771 +0,0 @@ -# -*- coding: utf-8 -*- - -PSU_FAN_AIRFLOW = { - "CSU550AP-3-300": "F2B", - "CSU550AP-3-500": "F2B", - "DPS-550AB-39 A": "F2B", - "DPS-1300AB-6 S": "F2B", - "FSP1200-20ERM": "F2B", - "CSU800AP-3-300": "F2B", - "CSU550AP-3-501": "B2F", - "DPS-550AB-40 A": "B2F", -} - -psutypedecode = { - 0x00: "N/A", - 0x01: "AC", - 0x02: "DC", -} - - -class Unit: - Temperature = "C" - Voltage = "V" - Current = "A" - Power = "W" - Speed = "RPM" - - -class Threshold: - PSU_TEMP_MIN = -10 * 1000 - PSU_TEMP_MAX = 60 * 1000 - - PSU_FAN_SPEED_MIN = 5220 - PSU_FAN_SPEED_MAX = 17400 - - PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 - PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 - - PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 - PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 - - PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 - PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 - - ERR_VALUE = -9999999 - - PSU_OUTPUT_POWER_MIN = 10 * 1000 - PSU_OUTPUT_POWER_MAX = 1300 * 1000 - - PSU_INPUT_POWER_MIN = 10 * 1000 - PSU_INPUT_POWER_MAX = 1444 * 1000 - - PSU_OUTPUT_CURRENT_MIN = 2 * 1000 - PSU_OUTPUT_CURRENT_MAX = 107 * 1000 - - PSU_INPUT_CURRENT_MIN = 0.2 * 1000 - PSU_INPUT_CURRENT_MAX = 7 * 1000 - - FAN_SPEED_MAX = 24000 - FAN_SPEED_MIN = 7200 - - -class DecodeFormat: - TEXT = 0 - DECIMAL = 1 - ONE_BIT_HEX = 2 - HUNDREDTH = 3 - THOUSANDTH = 4 - MILLIONTH = 5 - AND = 6 - JOIN = 7 - FRU = 8 - HEX = 9 - - -class DecodeMethod: - SYSFS = 0 - I2C = 1 - I2C_WORD = 2 - DEVMEM = 3 - SDK = 4 - IO = 5 - FRU = 6 - - -class FRU: - SN = 0 - VERSION = 1 - PART_NAME = 2 - PRODUCT_NAME = 3 - MANUFACTURER = 4 - - -class Description: - CPLD = "Used for managing IO modules, SFP+ modules and system LEDs" - BIOS = "Performs initialization of hardware components during booting" - FPGA = "Platform management controller for on-board temperature monitoring, in-chassis power, Fan and LED control" - - -FAN_LED_COLORS = { - "green": 0b0100, - "red": 0b0010, - "amber": 0b0110, -} - - -DEVICE_CONF = { - "eeprom": {"bus": 1, "loc": "0056"}, - "components": [ - { - "name": "CPLD1 (MAC Board A)", - "firmware_version": { - "bus": 8, - "addr": 0x30, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 0, - }, - { - "name": "CPLD2 (MAC Board B)", - "firmware_version": { - "bus": 8, - "addr": 0x31, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 0, - }, - { - "name": "CPLD3 (CONNECT Board A)", - "firmware_version": { - "bus": 2, - "addr": 0x0d, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 0, - }, - { - "name": "CPLD4 (CPU Board)", - "firmware_version": { - "bus": 0, - "addr": 0x0D, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 1, - }, - ], - "thermals": [ - { - "name": "INLET TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/3-004b/hwmon/*/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": None, - "temperature": { - "loc": "/sys/bus/i2c/devices/3-004b/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "OUTLET TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/3-004c/hwmon/*/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": None, - "temperature": { - "loc": "/sys/bus/i2c/devices/3-004c/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "BOARD TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/3-0049/hwmon/*/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": None, - "temperature": { - "loc": "/sys/bus/i2c/devices/3-0049/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "PHYSICAL ID 0", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp1_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 0", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp2_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp2_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp2_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 1", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp3_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp3_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp3_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 2", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp4_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp4_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp4_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 3", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp5_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp5_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp5_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - ], - "fans": [ - { - "name": "fan1", - "e2loc": {"bus": 16, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 0, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 0, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/16-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/16-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - { - "name": "fan2", - "e2loc": {"bus": 17, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/17-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/17-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_speed_set", - "format": DecodeFormat.HEX, - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - { - "name": "fan3", - "e2loc": {"bus": 18, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 2, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 2, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/18-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/18-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - { - "name": "fan4", - "e2loc": {"bus": 19, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 3, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 3, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/19-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/19-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - { - "name": "fan5", - "e2loc": {"bus": 20, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 4, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 4, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/20-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/20-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - ], - "psus": [ - { - "name": "psu1", - "present": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 0, - "way": DecodeMethod.IO - }, - "status": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - "way": DecodeMethod.IO - }, - "sn": { - "loc": "/sys/bus/i2c/devices/24-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "in_current": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/curr1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "in_voltage": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/in1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_voltage": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/in2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_current": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/curr2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/24-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - # "psu_type": { - # "loc": "/sys/bus/i2c/devices/24-0050/eeprom", - # "format": DecodeFormat.FRU, - # "fru_key": FRU.SN - # }, - "fans": [ - { - "name": "psu_fan1", - "present": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/fan1_fault", - }, - "status": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - "way": DecodeMethod.IO - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/fan1_input" - }, - "speed_setter": { - "bus": 24, - "addr": 0x58, - "offset": 0x3b, - "size": 1, - "way": DecodeMethod.I2C, - "format": DecodeFormat.HEX, - }, - "speed_max": Threshold.PSU_FAN_SPEED_MAX, - } - ], - "tolerance": 20, - "threshold_low": 1900, - } - ], - "in_power": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/power1_input", - "format": DecodeFormat.MILLIONTH, - }, - "out_power": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/power2_input", - "format": DecodeFormat.MILLIONTH, - }, - }, - { - "name": "psu2", - "present": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 4, - "way": DecodeMethod.IO - }, - "status": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 5, - "way": DecodeMethod.IO - }, - "sn": { - "loc": "/sys/bus/i2c/devices/25-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "in_current": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/curr1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "in_voltage": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/in1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_voltage": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/in2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_current": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/curr2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/25-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - # "psu_type": {"loc": "/sys/bus/i2c/devices/8-0053/psu_type"}, - "fans": [ - { - "name": "psu_fan1", - "present": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/fan1_fault", - }, - "status": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 5, - "way": DecodeMethod.IO - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/fan1_input" - }, - "speed_setter": { - "bus": 25, - "addr": 0x58, - "offset": 0x3b, - "size": 1, - "way": DecodeMethod.I2C, - "format": DecodeFormat.HEX, - }, - "speed_max": Threshold.PSU_FAN_SPEED_MAX, - } - ], - "tolerance": 20, - "threshold_low": 1900, - } - ], - "in_power": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/power1_input", - "format": DecodeFormat.MILLIONTH, - }, - "out_power": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/power2_input", - "format": DecodeFormat.MILLIONTH, - }, - }, - ], -} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/eeprom.py deleted file mode 100644 index c25d711354f5..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/eeprom.py +++ /dev/null @@ -1,12 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_eeprom import PddfEeprom -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Eeprom(PddfEeprom): - - def __init__(self, pddf_data=None, pddf_plugin_data=None): - PddfEeprom.__init__(self, 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-ragile/ra-b6510-32c/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/fan.py deleted file mode 100644 index b3dd67ed52cb..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/fan.py +++ /dev/null @@ -1,42 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_fan import PddfFan -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -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) - - # Provide the functions/variables below for which implementation is to be overwritten - # Since psu_fan airflow direction cant be read from sysfs, it is fixed as 'F2B' or 'intake' - def get_direction(self): - """ - Retrieves the direction of fan - - Returns: - A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST - depending on fan direction - """ - return self.FAN_DIRECTION_EXHAUST - - def get_speed_rpm(self): - if self.is_psu_fan: - return super().get_speed_rpm() - else: - divisor = 15000000 - mask_low = 0xff - ret = super().get_speed_rpm() - # revert ret - ret = (ret >> 8) + ((ret & mask_low) << 8) - return int(divisor/ret) - - def get_target_speed(self): - if self.is_psu_fan: - return None - - return super().get_target_speed() - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/fan_drawer.py deleted file mode 100644 index 2f83b66df94a..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/fan_drawer.py +++ /dev/null @@ -1,69 +0,0 @@ -# -# fan_drawer -# - -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): - # Device type definition. Note, this is a constant. - DEVICE_TYPE = "fan_drawer" - - def __init__(self, index, fan_list): - FanDrawerBase.__init__(self) - - self._fan_list = fan_list - self._index = index - - def get_name(self): - """ - Retrieves the name of the device - Returns: - string: The name of the device - """ - - return "fan drawer {}".format(self._index) - - def get_num_fans(self): - """ - Retrieves the number of fans available on this fan drawer - Returns: - An integer, the number of fan modules available on this fan drawer - """ - return len(self._fan_list) - - def get_all_fans(self): - """ - Retrieves all fan modules available on this fan drawer - Returns: - A list of objects derived from FanBase representing all fan - modules available on this fan drawer - """ - return self._fan_list - - 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 - """ - if self.get_num_fans() > 0: - return self._fan_list[0].set_status_led(color) - return False - - 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 - """ - if self.get_num_fans() > 0: - return self._fan_list[0].get_status_led() - return "N/A" - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/logger.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/logger.py deleted file mode 100644 index 5969781bf9a9..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/logger.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- - -import logging - - -def _init_logger(): - formatter = logging.Formatter( - "%(asctime)s %(levelname)s %(filename)s[%(funcName)s][%(lineno)s]: %(message)s" - ) - handler = logging.FileHandler("/var/log/syslog") - handler.setFormatter(formatter) - - logger = logging.getLogger(__name__) - logger.setLevel(logging.DEBUG) - logger.addHandler(handler) - return logger - - -logger = _init_logger() diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/pcie.py deleted file mode 100644 index 5a66997d33d0..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/pcie.py +++ /dev/null @@ -1,43 +0,0 @@ -# -# pcie_base.py -# -# Abstract base class for implementing platform-specific -# PCIE functionality for SONiC -# - -try: - import abc - from sonic_pcie import PcieUtil -except ImportError as e: - raise ImportError (str(e) + " - required module not found") - -class PcieBase(object): - def __init__(self, path): - """ - Constructor - Args: - pcieutil file and config file path - """ - self.pcie_util = PcieUtil(path) - - - @abc.abstractmethod - def get_pcie_device(self): - """ - get current device pcie info - - Returns: - A list including pcie device info - """ - return self.pcie_util.get_pcie_device() - - - @abc.abstractmethod - def get_pcie_check(self): - """ - Check Pcie device with config file - Returns: - A list including pcie device and test result info - """ - return self.pcie_util.get_pcie_check() - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/platform.py deleted file mode 100644 index 8595e80692df..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/platform.py +++ /dev/null @@ -1,23 +0,0 @@ -############################################################################# -# PDDF -# Module contains an implementation of SONiC Platform Base API and -# provides the platform information -# -############################################################################# - - -try: - from sonic_platform_pddf_base.pddf_platform import PddfPlatform -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Platform(PddfPlatform): - """ - PDDF Platform-Specific Platform Class - """ - - def __init__(self): - PddfPlatform.__init__(self) - - # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/psu.py deleted file mode 100644 index 240af5d2d1b5..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/psu.py +++ /dev/null @@ -1,32 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_psu import PddfPsu -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - - -class Psu(PddfPsu): - """PDDF Platform-Specific PSU class""" - - PLATFORM_PSU_CAPACITY = 1200 - - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfPsu.__init__(self, index, pddf_data, pddf_plugin_data) - - # Provide the functions/variables below for which implementation is to be overwritten - def get_maximum_supplied_power(self): - """ - Retrieves the maximum supplied power by PSU (or PSU capacity) - Returns: - A float number, the maximum power output in Watts. - e.g. 1200.1 - """ - return float(self.PLATFORM_PSU_CAPACITY) - - def get_type(self): - """ - Gets the type of the PSU - Returns: - A string, the type of PSU (AC/DC) - """ - return "DC" - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/regutil.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/regutil.py deleted file mode 100644 index bff2bd41ea55..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/regutil.py +++ /dev/null @@ -1,245 +0,0 @@ -# -*- coding: utf-8 -*- -from glob import glob -from plat_hal.osutil import osutil - -try: - from sonic_platform.config import DecodeFormat, DecodeMethod - - DECODE_FORMAT = DecodeFormat - DECODE_METHOD = DecodeMethod -except ImportError: - raise ImportError(str(e) + "- required module not found") - -ERR_CODE = "ERR" - - -class Reg(object): - """ - "e2loc": {"bus": 3, "addr": 0x53, "way": "i2c"} - "value": { - "loc": "/sys/bus/i2c/devices/2-0048/hwmon/hwmon*/temp1_input", - "way": "sysfs", - - "InputsStatus": { - "bus": 8, - "addr": 0x5B, - "offset": 0x79, - "way": "i2cword", - "mask": 0x0200, - }, - """ - - def __new__(cls, *args): - if args[0] is None or not isinstance(args[0], dict): - return None - return super(Reg, cls).__new__(cls) - - def __init__(self, data): - - self.loc = None - self.way = DECODE_METHOD.SYSFS - self.addr = None - self.bus = None - self.offset = None - self.size = 1 - self.bit = None - self.mask = None - self.digit = None - self.sdk_type = None - self.sep = None - self.format = DECODE_FORMAT.TEXT - self.__dict__.update(data) - - def _read_reg_val(self): - ret = None - try: - if self.way == DECODE_METHOD.SYSFS: - ret = self.get_sysfs() - elif self.way == DECODE_METHOD.I2C: - ret = self.get_i2c() - elif self.way == DECODE_METHOD.I2C_WORD: - ret = self.get_i2cword() - elif self.way == DECODE_METHOD.DEVMEM: - ret = self.get_devmem() - elif self.way == DECODE_METHOD.SDK: - # TODO - pass - else: - pass - except Exception as e: - raise e - - return ret - - def _write_reg_val(self, val): - try: - if self.way == DECODE_METHOD.SYSFS: - return self._write_sysfs(val) - except Exception as e: - raise e - - return False - - def _write_sysfs(self, val): - try: - with open(glob(self.loc)[0], "w") as f: - f.write(val) - f.flush() - return True - except Exception as e: - raise e - - def _format_val(self, val): - try: - if isinstance(val, str): - val = val.strip() - if self.format == DECODE_FORMAT.THOUSANDTH: - return float("%.1f" % (float(val) / 1000)) - elif self.format == DECODE_FORMAT.HUNDREDTH: - return float("%.1f" % (float(val) / 100)) - elif self.format == DECODE_FORMAT.ONE_BIT_HEX: - return (int(val, 16) & (1 << self.bit)) >> self.bit - elif self.format == DECODE_FORMAT.DECIMAL: - return int(val, 10) - elif self.format == DECODE_FORMAT.MILLIONTH: - return float("%.1f" % (float(val) / 1000 / 1000)) - elif self.format == DECODE_FORMAT.AND: - return (int(val, 16)) & self.mask - elif isinstance(val, list): - if self.format == DECODE_FORMAT.JOIN: - return self.sep.join(val) - except Exception as e: - raise e - else: - return val - - def decode(self): - """ - get value by config way - way i2c/sysfs/lpc - """ - if self.way is None: - raise ValueError("cannot found way to deal") - - ret = self._read_reg_val() - - ret = self._format_val(ret) - return ret - - def encode(self, val): - if self.way is None: - raise ValueError("cannot found way to deal") - - return self._write_reg_val(val) - - def get_sdk(self): - # TODO - pass - - def get_sysfs(self): - if self.loc is None: - raise ValueError("Not Enough Attr: loc: {}".format(self.loc)) - - ret, val = osutil.readsysfs(self.loc) - - if not ret: - raise IOError(val) - - return val - - def get_devmem(self): - if self.addr is None or self.digit is None or self.mask is None: - raise ValueError( - "Not Enough Attr: addr: {}, digit: {}, mask: {}".format( - self.addr, self.digit, self.mask - ) - ) - - ret, val = osutil.getdevmem(self.addr, self.digit, self.mask) - - if not ret: - raise IOError(val) - - return val - - def get_i2cword(self): - if self.bus is None or self.addr is None or self.offset is None: - raise ValueError( - "Not Enough Attr: bus: {}, addr: {}, offset: {}".format( - self.bus, self.addr, self.offset - ) - ) - - ret, val = osutil.geti2cword(self.bus, self.addr, self.offset) - - if not ret: - raise IOError(val) - - return val - - def get_i2c(self): - if ( - self.bus is None - or self.addr is None - or self.offset is None - or self.size is None - ): - raise ValueError( - "Not Enough Attr: bus: {}, addr: {}, offset: {}".format( - self.bus, self.addr, self.offset - ) - ) - - value = [] - for i in range(self.size): - ofs = self.offset + i - ret, val = osutil.rji2cget(self.bus, self.addr, ofs) - - if not ret: - raise IOError(val) - else: - value.append(repr(chr(val)).translate(None, r"\\x").replace("'", "")) - - return value - - def set_i2cword(self, bus, addr, offset, byte): - return self.seti2cword(bus, addr, offset, byte) - - def seti2cword(self, bus, addr, offset, byte): - return osutil.seti2cword(bus, addr, offset, byte) - - def set_i2c(self, bus, addr, offset, byte): - return self.seti2c(bus, addr, offset, byte) - - def seti2c(self, bus, addr, offset, byte): - ret, val = osutil.rji2cset(bus, addr, offset, byte) - return ret, val - - def getbcmtemp(self): - try: - sta, ret = osutil.getmactemp() - if sta == True: - mac_aver = float(ret.get("average", self.__error_ret)) - #mac_max = float(ret.get("maximum", self.__error_ret)) - mac_aver = mac_aver * 1000 - #mac_max = mac_max * 1000 - else: - return False, ret - except AttributeError as e: - return False, str(e) - return True, mac_aver - - def getbcmreg(self, reg): - ret, val = osutil.getsdkreg(reg) - return ret, val - - def logger_debug(self, msg): - baseutil.logger_debug(msg) - - def command(self, cmd): - ret, output = osutil.command(cmd) - return ret, output - - def set_val(self, val): - # TODO - pass diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/rotor.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/rotor.py deleted file mode 100644 index 3e5bcc5b9b9a..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/rotor.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- - -try: - from sonic_platform.regutil import Reg - from sonic_platform.logger import logger -except ImportError: - raise ImportError(str(e) + "- required module not found") - -class Rotor: - def __init__(self, config): - if config is not None and isinstance(config, dict): - self.__reg_speed_getter = Reg(config.get("speed_getter")) - self.__reg_speed_setter = Reg(config.get("speed_setter")) - self.__speed_max = config.get("speed_max") - else: - raise ValueError("init rotor Error: {}".format(config)) - - def get_speed(self): - try: - return int(self.__reg_speed_getter.decode()) - except Exception as e: - logger.error(str(e)) - - return 0 - - def set_speed(self, speed): - try: - return self.__reg_speed_setter.encode(speed) - except Exception as e: - logger.error(str(e)) - - return False - - def get_speed_percentage(self): - try: - speed = self.get_speed() - return (100 * speed) / self.__speed_max - except Exception as e: - logger.error(str(e)) - - return 0 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/sfp.py deleted file mode 100644 index ea8e256fe6ef..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/sfp.py +++ /dev/null @@ -1,287 +0,0 @@ -#!/usr/bin/env python - -try: - #from sonic_platform_pddf_base.pddf_sfp import * - from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId - from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom - from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId - from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom - from sonic_platform_pddf_base.pddf_sfp import PddfSfp - from sonic_platform_pddf_base.pddf_sfp import SFP_VOLT_OFFSET - from sonic_platform_pddf_base.pddf_sfp import SFP_VOLT_WIDTH - from sonic_platform_pddf_base.pddf_sfp import SFP_CHANNL_MON_OFFSET - from sonic_platform_pddf_base.pddf_sfp import SFP_CHANNL_MON_WIDTH - from sonic_platform_pddf_base.pddf_sfp import SFP_TEMPE_OFFSET - from sonic_platform_pddf_base.pddf_sfp import SFP_TEMPE_WIDTH - from sonic_platform_pddf_base.pddf_sfp import QSFP_DOM_REV_OFFSET - from sonic_platform_pddf_base.pddf_sfp import QSFP_DOM_REV_WIDTH - from sonic_platform_pddf_base.pddf_sfp import QSFP_CHANNL_MON_OFFSET - from sonic_platform_pddf_base.pddf_sfp import QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - -XCVR_DOM_CAPABILITY_OFFSET = 92 -XCVR_DOM_CAPABILITY_WIDTH = 2 -QSFP_VERSION_COMPLIANCE_OFFSET = 1 -QSFP_VERSION_COMPLIANCE_WIDTH = 2 -QSFP_OPTION_VALUE_OFFSET = 192 -QSFP_OPTION_VALUE_WIDTH = 4 - -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) - self.dom_supported = False - self.__dom_capability_detect() - - def __dom_capability_detect(self): - 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.qsfp_page3_available = False - self.calibration = 0 - if not self.get_presence(): - return - - if self.is_osfp_port: - # Not implement - return - elif self.is_qsfp_port: - 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 - else: - 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) - - # Provide the functions/variables below for which implementation is to be overwritten - - def __read_eeprom_specific_bytes(self, offset, num_bytes): - eeprom_raw = [] - if not self.get_presence(): - return None - for i in range(0, num_bytes): - eeprom_raw.append("0x00") - - try: - with open(self.eeprom_path, mode="rb", buffering=0) as eeprom: - eeprom.seek(offset) - raw = eeprom.read(num_bytes) - except Exception as e: - print("Error: Unable to open eeprom_path: %s" % (str(e))) - return None - - try: - if len(raw) == 0: - return None - for n in range(0, num_bytes): - eeprom_raw[n] = hex(raw[n])[2:].zfill(2) - except Exception as e: - print("Error: Exception info: %s" % (str(e))) - return None - - return eeprom_raw - - def get_transceiver_bulk_status(self): - # check present status - if not self.get_presence(): - return None - self.__dom_capability_detect() - - xcvr_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') - - if self.is_osfp_port: - # Below part is added to avoid fail xcvrd, shall be implemented later - pass - elif self.is_qsfp_port: - # QSFPs - xcvr_dom_info_dict = super(Sfp, self).get_transceiver_bulk_status() - - # pddf_sfp "qsfp_tx_power_support != 'on'" is wrong - - offset = 0 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return None - - qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) - if qsfp_dom_rev_raw is not None: - qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) - else: - return None - - dom_channel_monitor_data = {} - qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] - - if (qsfp_dom_rev[0:8] == 'SFF-8636' and self.dom_tx_power_supported is True): - 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) - else: - return None - - xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] - xcvr_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] - xcvr_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] - xcvr_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] - else: - # SFPs - offset = 256 - if not self.dom_supported: - return xcvr_dom_info_dict - - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return None - - sfpd_obj._calibration_type = self.calibration - - dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) - if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) - else: - return None - - dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) - if dom_voltage_raw is not None: - dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) - else: - return None - - 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) - else: - return None - - xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] - xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] - xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] - xcvr_dom_info_dict['rx2power'] = 'N/A' - xcvr_dom_info_dict['rx3power'] = 'N/A' - xcvr_dom_info_dict['rx4power'] = 'N/A' - xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] - xcvr_dom_info_dict['tx2bias'] = 'N/A' - xcvr_dom_info_dict['tx3bias'] = 'N/A' - xcvr_dom_info_dict['tx4bias'] = 'N/A' - xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] - xcvr_dom_info_dict['tx2power'] = 'N/A' - xcvr_dom_info_dict['tx3power'] = 'N/A' - xcvr_dom_info_dict['tx4power'] = 'N/A' - - xcvr_dom_info_dict['rx_los'] = self.get_rx_los() - xcvr_dom_info_dict['tx_fault'] = self.get_tx_fault() - xcvr_dom_info_dict['reset_status'] = self.get_reset_status() - xcvr_dom_info_dict['lp_mode'] = self.get_lpmode() - - return xcvr_dom_info_dict - - def get_transceiver_threshold_info(self): - # check present status - if not self.get_presence(): - return None - self.__dom_capability_detect() - - xcvr_dom_threshold_info_dict = dict.fromkeys(self.threshold_dict_keys, 'N/A') - - if self.is_osfp_port: - # Below part is added to avoid fail xcvrd, shall be implemented later - pass - elif self.is_qsfp_port: - # QSFPs - if not self.dom_supported or not self.qsfp_page3_available: - return xcvr_dom_threshold_info_dict - - return super(Sfp, self).get_transceiver_threshold_info() - - else: - # SFPs - if not self.dom_supported: - return xcvr_dom_threshold_info_dict - - return super(Sfp, self).get_transceiver_threshold_info() - - return xcvr_dom_threshold_info_dict diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/thermal.py deleted file mode 100644 index 99b743c6d343..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/thermal.py +++ /dev/null @@ -1,14 +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): - PddfThermal.__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-ragile/ra-b6510-32c/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/watchdog.py deleted file mode 100644 index 37788c2c821e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/sonic_platform/watchdog.py +++ /dev/null @@ -1,21 +0,0 @@ -############################################################################# -# -# Module contains an implementation of platform specific watchdog API's -# -############################################################################# - -try: - from sonic_platform_pddf_base.pddf_watchdog import PddfWatchdog -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -class Watchdog(PddfWatchdog): - """ - PDDF Platform-specific Chassis class - """ - - def __init__(self): - PddfWatchdog.__init__(self) - self.timeout= 180 - - # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/systemd/pddf-platform-init.service b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/systemd/pddf-platform-init.service deleted file mode 120000 index 0fd9f25b6c5e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/systemd/pddf-platform-init.service +++ /dev/null @@ -1 +0,0 @@ -../../../../pddf/i2c/service/pddf-platform-init.service \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/cpld_test_header.vme b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/cpld_test_header.vme new file mode 100644 index 0000000000000000000000000000000000000000..083fd78f3ea1919d9d3737fe0d8d0c7b8b2ce881 GIT binary patch literal 406 zcmaiu!AgWc7{^Cl9GwWZEU4QY>mrW2O9%#{v#rqDVj^@}T%AMUt^?Upr*1u1&(K43 z?FnqO2k^UmA0NNppMS~gYSXfp);#POTEzEsNrQ-{S16)+_OzzH_2yb`frh&jGzynN zocKiSc%1|*>JQ(XrjPMM;vcLbWx(?lMPV9>2xnduTlc0w*NEL#8!^N-$!~cVJr}!X zU*U-Hx_RHReT%cEsj*`cOSm-1L@17ejCweGWq851n7EkCz1hsO3AQcUK?q#pT+$Q+ zaP`9Ix{m7r0$EYyqaQexPBa5Reu@nVOwPd9@%QJs+)cP9_xx1wT$jWNHKXIBQctQq VsrNb@^ic_@K=0eZ|8`^i#~;mYW4-_Y literal 0 HcmV?d00001 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/fpga_test_header.bin b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/fpga_test_header.bin new file mode 100644 index 000000000000..bdf9ae2139e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/.upgrade_test/fpga_test_header.bin @@ -0,0 +1,10 @@ +fpga_test_header.bin +FILEHEADER( +DEVTYPE=0x404a +TYPE=fpga +CHAIN=3 +CHIPNAME=fpga +VERSION=v0 +FILETYPE=SPI-LOGIC-DEV +CRC=0x00000000 +) diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/LICENSE b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/LICENSE deleted file mode 100755 index d37122689f3e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -Copyright (C) 2016 Microsoft, Inc -Copyright (C) 2018 Ragile Network 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/MAINTAINERS b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/MAINTAINERS deleted file mode 100755 index ec8222405085..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/MAINTAINERS +++ /dev/null @@ -1,5 +0,0 @@ -# See the SONiC project governance document for more information - -Name = "support" -Email = "support@ragile.com" -Mailinglist = sonicproject@googlegroups.com diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile old mode 100755 new mode 100644 index 9e262d7c095e..1b84abef410a --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/Makefile @@ -5,10 +5,9 @@ EXTRA_CFLAGS+= -Wall SUB_BUILD_DIR = $(PWD)/build INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin -INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system/ - -KBUILD_EXTRA_SYMBOLS += $(DIR_KERNEL_SRC)/Module.symvers -export KBUILD_EXTRA_SYMBOLS +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_SYSFS_CFG_DIR = $(SUB_BUILD_DIR)/etc/plat_sysfs_cfg +INSTALL_UPGRADE_TEST_DIR = $(SUB_BUILD_DIR)/etc/.upgrade_test all: $(MAKE) -C $(KBUILD_OUTPUT) M=$(DIR_KERNEL_SRC) modules @@ -16,8 +15,12 @@ all: cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_DIR) @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi cp -r $(PWD)/config/* $(INSTALL_SCRIPT_DIR) - @if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi - cp $(PWD)/systemd/*.service $(INSTALL_SERVICE_DIR) + @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi + @if [ -d $(PWD)/hal-config/ ]; then cp -r $(PWD)/hal-config/* ${INSTALL_LIB_DIR} ;fi + @if [ ! -d ${INSTALL_SYSFS_CFG_DIR} ]; then mkdir -p ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ -d $(PWD)/plat_sysfs_cfg/ ]; then cp -r $(PWD)/plat_sysfs_cfg/* ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ ! -d ${INSTALL_UPGRADE_TEST_DIR} ]; then mkdir -p ${INSTALL_UPGRADE_TEST_DIR} ;fi + @if [ -d $(PWD)/.upgrade_test/ ]; then cp -r $(PWD)/.upgrade_test/* ${INSTALL_UPGRADE_TEST_DIR} ;fi clean: rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/README.md b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/README.md deleted file mode 100755 index 787636c4ad20..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/README.md +++ /dev/null @@ -1 +0,0 @@ -Device drivers for support of ragile platform for the SONiC project diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_config.py index 5fe30ea12848..b40926068f60 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_config.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_config.py @@ -1,484 +1,1097 @@ #!/usr/bin/python # -*- coding: UTF-8 -*- -from ragilecommon import * -PCA9548START = -1 -PCA9548BUSEND = -2 +from platform_common import * +STARTMODULE = { + "hal_fanctrl": 1, + "hal_ledctrl": 1, + "avscontrol": 1, + "dev_monitor": 1, + "pmon_syslog": 1, + "tty_console": 1, + "macledreset": 1, + "sff_temp_polling": 1, + "generate_airflow": 1, +} + +MAC_LED_RESET = {"pcibus": 8, "slot": 0, "fn": 0, "bar": 0, "offset": 64, "reset": 0x98} + +MANUINFO_CONF = { + "bios": { + "key": "BIOS", + "head": True, + "next": "onie" + }, + "bios_vendor": { + "parent": "bios", + "key": "Vendor", + "cmd": "dmidecode -t 0 |grep Vendor", + "pattern": r".*Vendor", + "separator": ":", + "arrt_index": 1, + }, + "bios_version": { + "parent": "bios", + "key": "Version", + "cmd": "dmidecode -t 0 |grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "bios_date": { + "parent": "bios", + "key": "Release Date", + "cmd": "dmidecode -t 0 |grep Release", + "pattern": r".*Release Date", + "separator": ":", + "arrt_index": 3, + }, + "onie": { + "key": "ONIE", + "next": "cpu" + }, + "onie_date": { + "parent": "onie", + "key": "Build Date", + "file": "/host/machine.conf", + "pattern": r"^onie_build_date", + "separator": "=", + "arrt_index": 1, + }, + "onie_version": { + "parent": "onie", + "key": "Version", + "file": "/host/machine.conf", + "pattern": r"^onie_version", + "separator": "=", + "arrt_index": 2, + }, + + "cpu": { + "key": "CPU", + "next": "ssd" + }, + "cpu_vendor": { + "parent": "cpu", + "key": "Vendor", + "cmd": "dmidecode --type processor |grep Manufacturer", + "pattern": r".*Manufacturer", + "separator": ":", + "arrt_index": 1, + }, + "cpu_model": { + "parent": "cpu", + "key": "Device Model", + "cmd": "dmidecode --type processor | grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "cpu_core": { + "parent": "cpu", + "key": "Core Count", + "cmd": "dmidecode --type processor | grep \"Core Count\"", + "pattern": r".*Core Count", + "separator": ":", + "arrt_index": 3, + }, + "cpu_thread": { + "parent": "cpu", + "key": "Thread Count", + "cmd": "dmidecode --type processor | grep \"Thread Count\"", + "pattern": r".*Thread Count", + "separator": ":", + "arrt_index": 4, + }, + "ssd": { + "key": "SSD", + "next": "cpld" + }, + "ssd_model": { + "parent": "ssd", + "key": "Device Model", + "cmd": "smartctl -i /dev/sda |grep \"Device Model\"", + "pattern": r".*Device Model", + "separator": ":", + "arrt_index": 1, + }, + "ssd_fw": { + "parent": "ssd", + "key": "Firmware Version", + "cmd": "smartctl -i /dev/sda |grep \"Firmware Version\"", + "pattern": r".*Firmware Version", + "separator": ":", + "arrt_index": 2, + }, + "ssd_user_cap": { + "parent": "ssd", + "key": "User Capacity", + "cmd": "smartctl -i /dev/sda |grep \"User Capacity\"", + "pattern": r".*User Capacity", + "separator": ":", + "arrt_index": 3, + }, + + "cpld": { + "key": "CPLD", + "next": "psu" + }, + + "cpld1": { + "key": "CPLD1", + "parent": "cpld", + "arrt_index": 1, + }, + "cpld1_model": { + "key": "Device Model", + "parent": "cpld1", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld1_vender": { + "key": "Vendor", + "parent": "cpld1", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld1_desc": { + "key": "Description", + "parent": "cpld1", + "config": "CPU_CPLD", + "arrt_index": 3, + }, + "cpld1_version": { + "key": "Firmware Version", + "parent": "cpld1", + "reg": { + "loc": "/dev/port", + "offset": 0x700, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld2": { + "key": "CPLD2", + "parent": "cpld", + "arrt_index": 2, + }, + "cpld2_model": { + "key": "Device Model", + "parent": "cpld2", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld2_vender": { + "key": "Vendor", + "parent": "cpld2", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld2_desc": { + "key": "Description", + "parent": "cpld2", + "config": "CONNECT_CPLD", + "arrt_index": 3, + }, + "cpld2_version": { + "key": "Firmware Version", + "parent": "cpld2", + "reg": { + "loc": "/dev/port", + "offset": 0x900, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld3": { + "key": "CPLD3", + "parent": "cpld", + "arrt_index": 3, + }, + "cpld3_model": { + "key": "Device Model", + "parent": "cpld3", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld3_vender": { + "key": "Vendor", + "parent": "cpld3", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld3_desc": { + "key": "Description", + "parent": "cpld3", + "config": "CONNECT_CPLD-FAN", + "arrt_index": 3, + }, + "cpld3_version": { + "key": "Firmware Version", + "parent": "cpld3", + "i2c": { + "bus": "2", + "loc": "0x0d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld4": { + "key": "CPLD4", + "parent": "cpld", + "arrt_index": 4, + }, + "cpld4_model": { + "key": "Device Model", + "parent": "cpld4", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld4_vender": { + "key": "Vendor", + "parent": "cpld4", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld4_desc": { + "key": "Description", + "parent": "cpld4", + "config": "MAC_CPLD1", + "arrt_index": 3, + }, + "cpld4_version": { + "key": "Firmware Version", + "parent": "cpld4", + "i2c": { + "bus": "8", + "loc": "0x30", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld5": { + "key": "CPLD5", + "parent": "cpld", + "arrt_index": 5, + }, + "cpld5_model": { + "key": "Device Model", + "parent": "cpld5", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld5_vender": { + "key": "Vendor", + "parent": "cpld5", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld5_desc": { + "key": "Description", + "parent": "cpld5", + "config": "MAC_CPLD2", + "arrt_index": 3, + }, + "cpld5_version": { + "key": "Firmware Version", + "parent": "cpld5", + "i2c": { + "bus": "8", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "psu": { + "key": "PSU", + "next": "fan" + }, + + "psu1": { + "parent": "psu", + "key": "PSU1", + "arrt_index": 1, + }, + "psu1_hw_version": { + "key": "Hardware Version", + "parent": "psu1", + "extra": { + "funcname": "getPsu", + "id": "psu1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu1_fw_version": { + "key": "Firmware Version", + "parent": "psu1", + "config": "NA", + "arrt_index": 2, + }, + + "psu2": { + "parent": "psu", + "key": "PSU2", + "arrt_index": 2, + }, + "psu2_hw_version": { + "key": "Hardware Version", + "parent": "psu2", + "extra": { + "funcname": "getPsu", + "id": "psu2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu2_fw_version": { + "key": "Firmware Version", + "parent": "psu2", + "config": "NA", + "arrt_index": 2, + }, + + "fan": { + "key": "FAN", + "next": "i210" + }, -RAGILE_CARDID = 0x0000404a -RAGILE_PRODUCTNAME = "RA-B6510-48V8C" + "fan1": { + "key": "FAN1", + "parent": "fan", + "arrt_index": 1, + }, + "fan1_hw_version": { + "key": "Hardware Version", + "parent": "fan1", + "extra": { + "funcname": "checkFan", + "id": "fan1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan1_fw_version": { + "key": "Firmware Version", + "parent": "fan1", + "config": "NA", + "arrt_index": 2, + }, + + "fan2": { + "key": "FAN2", + "parent": "fan", + "arrt_index": 2, + }, + "fan2_hw_version": { + "key": "Hardware Version", + "parent": "fan2", + "extra": { + "funcname": "checkFan", + "id": "fan2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan2_fw_version": { + "key": "Firmware Version", + "parent": "fan2", + "config": "NA", + "arrt_index": 2, + }, + + "fan3": { + "key": "FAN3", + "parent": "fan", + "arrt_index": 3, + }, + "fan3_hw_version": { + "key": "Hardware Version", + "parent": "fan3", + "extra": { + "funcname": "checkFan", + "id": "fan3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan3_fw_version": { + "key": "Firmware Version", + "parent": "fan3", + "config": "NA", + "arrt_index": 2, + }, + + "fan4": { + "key": "FAN4", + "parent": "fan", + "arrt_index": 4, + }, + "fan4_hw_version": { + "key": "Hardware Version", + "parent": "fan4", + "extra": { + "funcname": "checkFan", + "id": "fan4", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan4_fw_version": { + "key": "Firmware Version", + "parent": "fan4", + "config": "NA", + "arrt_index": 2, + }, -STARTMODULE = { - "fancontrol":1, - "avscontrol":1, - "dev_monitor":1 + "i210": { + "key": "NIC", + "next": "fpga" + }, + "i210_model": { + "parent": "i210", + "config": "NA", + "key": "Device Model", + "arrt_index": 1, + }, + "i210_vendor": { + "parent": "i210", + "config": "INTEL", + "key": "Vendor", + "arrt_index": 2, + }, + "i210_version": { + "parent": "i210", + "cmd": "ethtool -i eth0", + "pattern": r"firmware-version", + "separator": ":", + "key": "Firmware Version", + "arrt_index": 3, + }, + + "fpga": { + "key": "FPGA", + "next": "asic" + }, + "fpga_model": { + "parent": "fpga", + "config": "XC7A15T-2FGG484C", + "key": "Device Model", + "arrt_index": 1, + }, + "fpga_vendor": { + "parent": "fpga", + "config": "XILINX", + "key": "Vendor", + "arrt_index": 2, + }, + "fpga_desc": { + "parent": "fpga", + "config": "NA", + "key": "Description", + "arrt_index": 3, + }, + "fpga_hw_version": { + "parent": "fpga", + "config": "NA", + "key": "Hardware Version", + "arrt_index": 4, + }, + "fpga_fw_version": { + "parent": "fpga", + "pci": { + "bus": 8, + "slot": 0, + "fn": 0, + "bar": 0, + "offset": 0 + }, + "key": "Firmware Version", + "arrt_index": 5, + }, + "fpga_date": { + "parent": "fpga", + "pci": { + "bus": 8, + "slot": 0, + "fn": 0, + "bar": 0, + "offset": 4 + }, + "key": "Build Date", + "arrt_index": 6, + }, + "asic": { + "key": "ASIC", + }, + "sdk_model": { + "parent": "asic", + "cmd": "bcmcmd -t 1 att", + "pattern": r"^Attach", + "regular": r"(?<=\()[^)]*(?=\))", + "key": "Device Model", + "arrt_index": 1, + }, + "sdk_version": { + "parent": "asic", + "cmd": "bcmcmd -t 1 version | grep Release", + "pattern": r".*Release", + "separator": ":", + "key": "SDK Version", + "arrt_index": 2, + }, + "pci_version": { + "parent": "asic", + "cmd": "bcmcmd -t 1 \"pciephy fw version\" |grep \"PCIe FW version\"", + "pattern": r".*PCIe FW version", + "separator": ":", + "key": "PCIe Firmware Version", + "arrt_index": 3, + }, } -i2ccheck_params = {"busend":"i2c-66","retrytime":6} +PMON_SYSLOG_STATUS = { + "polling_time": 3, + "sffs": { + "present": {"path": ["/sys/wb_plat/sff/*/present"], "ABSENT": 0}, + "nochangedmsgflag": 0, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 1, + "alias": { + "sff1": "Ethernet1", + "sff2": "Ethernet2", + "sff3": "Ethernet3", + "sff4": "Ethernet4", + "sff5": "Ethernet5", + "sff6": "Ethernet6", + "sff7": "Ethernet7", + "sff8": "Ethernet8", + "sff9": "Ethernet9", + "sff10": "Ethernet10", + "sff11": "Ethernet11", + "sff12": "Ethernet12", + "sff13": "Ethernet13", + "sff14": "Ethernet14", + "sff15": "Ethernet15", + "sff16": "Ethernet16", + "sff17": "Ethernet17", + "sff18": "Ethernet18", + "sff19": "Ethernet19", + "sff20": "Ethernet20", + "sff21": "Ethernet21", + "sff22": "Ethernet22", + "sff23": "Ethernet23", + "sff24": "Ethernet24", + "sff25": "Ethernet25", + "sff26": "Ethernet26", + "sff27": "Ethernet27", + "sff28": "Ethernet28", + "sff29": "Ethernet29", + "sff30": "Ethernet30", + "sff31": "Ethernet31", + "sff32": "Ethernet32", + "sff33": "Ethernet33", + "sff34": "Ethernet34", + "sff35": "Ethernet35", + "sff36": "Ethernet36", + "sff37": "Ethernet37", + "sff38": "Ethernet38", + "sff39": "Ethernet39", + "sff40": "Ethernet40", + "sff41": "Ethernet41", + "sff42": "Ethernet42", + "sff43": "Ethernet43", + "sff44": "Ethernet44", + "sff45": "Ethernet45", + "sff46": "Ethernet46", + "sff47": "Ethernet47", + "sff48": "Ethernet48", + "sff49": "Ethernet49", + "sff50": "Ethernet50", + "sff51": "Ethernet51", + "sff52": "Ethernet52", + "sff53": "Ethernet53", + "sff54": "Ethernet54", + "sff55": "Ethernet55", + "sff56": "Ethernet56", + } + }, + "fans": { + "present": {"path": ["/sys/wb_plat/fan/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/wb_plat/fan/%s/motor0/status", 'okval': 1}, + {"path": "/sys/wb_plat/fan/%s/motor1/status", 'okval': 1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "fan1": "FAN1", + "fan2": "FAN2", + "fan3": "FAN3", + "fan4": "FAN4" + } + }, + "psus": { + "present": {"path": ["/sys/wb_plat/psu/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/wb_plat/psu/%s/output", "okval": 1}, + {"path": "/sys/wb_plat/psu/%s/alert", "okval": 0}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "psu1": "PSU1", + "psu2": "PSU2" + } + } +} + +##################### MAC Voltage adjust#################################### +MAC_DEFAULT_PARAM = [ + { + "name": "mac_core", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default": 0x74, # default value, if rov value not in range + "sdkreg": "TOP_AVS_SEL_REG", # SDK register name + "sdktype": 0, # 0: No shift operation required, 1: shift operation required + "macregloc": 24, # Shift right 24 bits + "mask": 0xff, # Use with macregloc + "rov_source": 1, # 0:get rov value from cpld, 1: get rov value from SDK + "cpld_avs": {"bus": 6, "loc": 0x0d, "offset": 0xc3, "gettype": "i2c"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x08: 0.888, + 0x72: 0.900, + 0x73: 0.894, + 0x74: 0.888, + 0x75: 0.882, + 0x76: 0.875, + 0x77: 0.869, + 0x78: 0.863, + 0x79: 0.857, + 0x7a: 0.850, + 0x7b: 0.844, + 0x7c: 0.838, + 0x7d: 0.832, + 0x7e: 0.825, + 0x7f: 0.819, + 0x80: 0.813, + 0x81: 0.807, + 0x82: 0.800, + 0x83: 0.794, + 0x84: 0.788, + 0x85: 0.782, + 0x86: 0.775, + 0x87: 0.769, + 0x88: 0.763, + 0x89: 0.757, + 0x8A: 0.750 + } + } +] + +BLACKLIST_DRIVERS = [ + {"name": "i2c_i801", "delay": 0}, +] + +DRIVERLISTS = [ + {"name": "wb_i2c_i801", "delay": 0}, + {"name": "wb_gpio_d1500", "delay": 0}, + {"name": "i2c_dev", "delay": 0}, + {"name": "wb_i2c_algo_bit", "delay": 0}, + {"name": "wb_i2c_gpio", "delay": 0}, + {"name": "i2c_mux", "delay": 0}, + {"name": "wb_gpio_device", "delay": 0}, + {"name": "wb_i2c_gpio_device gpio_sda=17 gpio_scl=1 gpio_udelay=2", "delay": 0}, + {"name": "platform_common dfd_my_type=0x404a", "delay": 0}, + {"name": "wb_lpc_drv", "delay": 0}, + {"name": "wb_lpc_drv_device", "delay": 0}, + {"name": "wb_io_dev", "delay": 0}, + {"name": "wb_io_dev_device", "delay": 0}, + {"name": "wb_fpga_pcie", "delay": 0}, + {"name": "wb_pcie_dev", "delay": 0}, + {"name": "wb_pcie_dev_device", "delay": 0}, + {"name": "wb_i2c_dev", "delay": 0}, + {"name": "wb_i2c_ocores", "delay": 0}, + {"name": "wb_i2c_ocores_device", "delay": 0}, + {"name": "wb_i2c_mux_pca9641", "delay": 0}, + {"name": "wb_i2c_mux_pca954x", "delay": 0}, + {"name": "wb_i2c_mux_pca954x_device", "delay": 0}, + {"name": "wb_i2c_dev_device", "delay": 0}, + {"name": "wb_lm75", "delay": 0}, + {"name": "wb_optoe", "delay": 0}, + {"name": "wb_at24", "delay": 0}, + {"name": "wb_mac_bsc", "delay": 0}, + {"name": "wb_pmbus_core", "delay": 0}, + {"name": "wb_isl68137", "delay": 0}, + {"name": "wb_csu550", "delay": 0}, + {"name": "wb_ina3221", "delay": 0}, + {"name": "wb_tps53622", "delay": 0}, + {"name": "firmware_driver_cpld", "delay": 0}, + {"name": "firmware_driver_ispvme", "delay": 0}, + {"name": "firmware_driver_sysfs", "delay": 0}, + {"name": "wb_firmware_upgrade_device", "delay": 0}, + {"name": "plat_dfd", "delay": 0}, + {"name": "plat_switch", "delay": 0}, + {"name": "plat_fan", "delay": 0}, + {"name": "plat_psu", "delay": 0}, + {"name": "plat_sff", "delay": 0}, +] + +DEVICE = [ + {"name": "wb_24c02", "bus": 0, "loc": 0x56}, + {"name": "wb_mac_bsc_td3", "bus": 3, "loc": 0x44}, + # fan + {"name": "wb_24c02", "bus": 16, "loc": 0x50}, + {"name": "wb_24c02", "bus": 17, "loc": 0x50}, + {"name": "wb_24c02", "bus": 18, "loc": 0x50}, + {"name": "wb_24c02", "bus": 19, "loc": 0x50}, + # psu + {"name": "wb_24c02", "bus": 24, "loc": 0x50}, + {"name": "wb_dps550", "bus": 24, "loc": 0x58}, + {"name": "wb_24c02", "bus": 25, "loc": 0x50}, + {"name": "wb_dps550", "bus": 25, "loc": 0x58}, + # temp + {"name": "wb_lm75", "bus": 3, "loc": 0x48}, + {"name": "wb_lm75", "bus": 3, "loc": 0x49}, + {"name": "wb_lm75", "bus": 3, "loc": 0x4a}, + {"name": "wb_lm75", "bus": 3, "loc": 0x4b}, + {"name": "wb_lm75", "bus": 3, "loc": 0x4c}, + # dcdc + {"name": "wb_ina3221", "bus": 7, "loc": 0x40}, + {"name": "wb_ina3221", "bus": 7, "loc": 0x41}, + {"name": "wb_ina3221", "bus": 7, "loc": 0x42}, + {"name": "wb_ina3221", "bus": 7, "loc": 0x43}, + {"name": "wb_tps53622", "bus": 7, "loc": 0x60}, + {"name": "wb_tps53622", "bus": 7, "loc": 0x6c}, + {"name": "wb_isl68127", "bus": 7, "loc": 0x64}, +] + +OPTOE = [ + {"name": "wb_optoe2", "startbus": 32, "endbus": 79}, + {"name": "wb_optoe1", "startbus": 80, "endbus": 87}, +] DEV_MONITOR_PARAM = { "polling_time": 10, "psus": [ { "name": "psu1", - "present": { - "gettype": "i2c", - "bus": 2, - "loc": 0x37, - "offset": 0x51, - "presentbit": 0, - "okval": 0, - }, + "present": {"gettype": "i2c", "bus": 6, "loc": 0x0d, "offset": 0x51, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu1pmbus", - "name": "dps550", - "bus": 7, - "loc": 0x58, - "attr": "hwmon", - }, + {"id": "psu1pmbus", "name": "wb_dps550", "bus": 24, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu1frue2", "name": "wb_24c02", "bus": 24, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "psu2", - "present": { - "gettype": "i2c", - "bus": 2, - "loc": 0x37, - "offset": 0x51, - "presentbit": 4, - "okval": 0, - }, + "present": {"gettype": "i2c", "bus": 6, "loc": 0x0d, "offset": 0x51, "presentbit": 4, "okval": 0}, "device": [ - { - "id": "psu2pmbus", - "name": "dps550", - "bus": 8, - "loc": 0x5B, - "attr": "hwmon", - }, + {"id": "psu2pmbus", "name": "wb_dps550", "bus": 25, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu2frue2", "name": "wb_24c02", "bus": 25, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "fans": [ + { + "name": "fan1", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x0d, "offset": 0x30, "presentbit": 0, "okval": 0}, + "device": [ + {"id": "fan1frue2", "name": "24c02", "bus": 16, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan2", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x0d, "offset": 0x30, "presentbit": 1, "okval": 0}, + "device": [ + {"id": "fan2frue2", "name": "24c02", "bus": 17, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan3", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x0d, "offset": 0x30, "presentbit": 2, "okval": 0}, + "device": [ + {"id": "fan3frue2", "name": "24c02", "bus": 18, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan4", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x0d, "offset": 0x30, "presentbit": 3, "okval": 0}, + "device": [ + {"id": "fan4frue2", "name": "24c02", "bus": 19, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "others": [ + { + "name": "eeprom", + "device": [ + {"id": "eeprom_1", "name": "wb_24c02", "bus": 0, "loc": 0x56, "attr": "eeprom"}, + ], + }, + { + "name": "lm75", + "device": [ + {"id": "lm75_1", "name": "wb_lm75", "bus": 3, "loc": 0x48, "attr": "hwmon"}, + {"id": "lm75_2", "name": "wb_lm75", "bus": 3, "loc": 0x49, "attr": "hwmon"}, + {"id": "lm75_3", "name": "wb_lm75", "bus": 3, "loc": 0x4a, "attr": "hwmon"}, + {"id": "lm75_4", "name": "wb_lm75", "bus": 3, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_5", "name": "wb_lm75", "bus": 3, "loc": 0x4c, "attr": "hwmon"}, ], }, + { + "name": "mac_bsc", + "device": [ + {"id": "mac_bsc_1", "name": "wb_mac_bsc_td3", "bus": 3, "loc": 0x44, "attr": "hwmon"}, + ], + }, + { + "name": "ina3221", + "device": [ + {"id": "ina3221_1", "name": "wb_ina3221", "bus": 7, "loc": 0x40, "attr": "hwmon"}, + {"id": "ina3221_2", "name": "wb_ina3221", "bus": 7, "loc": 0x41, "attr": "hwmon"}, + {"id": "ina3221_3", "name": "wb_ina3221", "bus": 7, "loc": 0x42, "attr": "hwmon"}, + {"id": "ina3221_4", "name": "wb_ina3221", "bus": 7, "loc": 0x43, "attr": "hwmon"}, + ], + }, + { + "name": "tps53622", + "device": [ + {"id": "tps53622_1", "name": "wb_tps53622", "bus": 7, "loc": 0x60, "attr": "hwmon"}, + {"id": "tps53622_2", "name": "wb_tps53622", "bus": 7, "loc": 0x6c, "attr": "hwmon"}, + ], + }, + { + "name": "isl68127", + "device": [ + {"id": "isl68127_1", "name": "wb_isl68127", "bus": 7, "loc": 0x64, "attr": "hwmon"}, + ], + } ], } -fanlevel = { - "tips":["LOW","MEDIUM","HIGH"], - "level":[51,150,255], - "low_speed":[500,7500,17000], - "high_speed":[11000,22500,28500] -} +INIT_PARAM_PRE = [ + {"loc": "7-0064/hwmon/hwmon*/avs0_vout_max", "value": "900000"}, + {"loc": "7-0064/hwmon/hwmon*/avs0_vout_min", "value": "750000"}, +] +INIT_COMMAND_PRE = [] + +INIT_PARAM = [] -# fit with pddf -fanloc = [ +INIT_COMMAND = [ + "i2cset -y -f 6 0x0d 0x91 0x48", + "i2cset -y -f 6 0x0d 0x92 0x01", # MAC_PWR_EN + "i2cset -y -f 6 0x0d 0x94 0x01", # SFF_PWR_EN + "i2cset -y -f 6 0x0d 0xbf 0x01", # enbale tty_console monitor + "i2cset -y -f 8 0x30 0x60 0x00", # enable txdis[1~8] + "i2cset -y -f 8 0x30 0x61 0x00", # enable txdis[9~16] + "i2cset -y -f 8 0x30 0x62 0x00", # enable txdis[17~24] + "i2cset -y -f 8 0x31 0x60 0x00", # enable txdis[24~32] + "i2cset -y -f 8 0x31 0x61 0x00", # enable txdis[33~40] + "i2cset -y -f 8 0x31 0x62 0x00", # enable txdis[41~48] +] + +REBOOT_CAUSE_PARA = [ { - "name": "FAN1/FAN2/FAN3/FAN4", - "location": "2-0066/fan1_pwm", - "childfans": [ - {"name": "FAN1", "location": "2-0066/fan1_input"}, - {"name": "FAN2", "location": "2-0066/fan2_input"}, - {"name": "FAN3", "location": "2-0066/fan3_input"}, - {"name": "FAN4", "location": "2-0066/fan4_input"}, - ], + "name": "cold_reboot", + "monitor_point": {"gettype": "i2c", "bus": 8, "addr": 0x30, "offset": 0x42, "okval": 0x0}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Cold reboot, ", + "path": "/var/cache/sonic/previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Cold reboot, ", "path": "/host/misc/history-reboot-cause.txt"} + ] }, + { + "name": "otp_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_reboot_flag"}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "OTP reboot, ", + "path": "/var/cache/sonic/previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "OTP reboot, ", "path": "/host/misc/history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_reboot_flag"}, + ] + } ] +UPGRADE_SUMMARY = { + "devtype": 0x404a, + "slot0": { + "subtype": 0, + "VME": { + "chain1": { + "name": "VME_CPLD", + "is_support_warm_upg": 0, + }, + }, -MONITOR_TEMP_MIN = 38 -MONITOR_K = 11 -MONITOR_MAC_IN = 35 -MONITOR_DEFAULT_SPEED = 0x60 -MONITOR_MAX_SPEED = 0xFF -MONITOR_MIN_SPEED = 0x33 -MONITOR_MAC_ERROR_SPEED = 0XBB -MONITOR_FAN_TOTAL_NUM = 4 -MONITOR_MAC_UP_TEMP = 50 -MONITOR_MAC_LOWER_TEMP = -50 -MONITOR_MAC_MAX_TEMP = 100 - -MONITOR_FALL_TEMP = 4 -MONITOR_MAC_WARNING_THRESHOLD = 100 -MONITOR_OUTTEMP_WARNING_THRESHOLD = 85 -MONITOR_BOARDTEMP_WARNING_THRESHOLD = 85 -MONITOR_CPUTEMP_WARNING_THRESHOLD = 85 -MONITOR_INTEMP_WARNING_THRESHOLD = 70 - -MONITOR_MAC_CRITICAL_THRESHOLD = 105 -MONITOR_OUTTEMP_CRITICAL_THRESHOLD = 90 -MONITOR_BOARDTEMP_CRITICAL_THRESHOLD = 90 -MONITOR_CPUTEMP_CRITICAL_THRESHOLD = 100 -MONITOR_INTEMP_CRITICAL_THRESHOLD = 80 -MONITOR_CRITICAL_NUM = 3 -MONITOR_SHAKE_TIME = 20 -MONITOR_INTERVAL = 60 - -MONITOR_SYS_LED = [ - {"bus":2,"devno":0x33, "addr":0xb2, "yellow":0x03, "red":0x02,"green":0x01}, - {"bus":2,"devno":0x37, "addr":0xb2, "yellow":0x03, "red":0x02,"green":0x01}] - -MONITOR_SYS_FAN_LED =[ - {"bus":2,"devno":0x33, "addr":0xb4, "yellow":0x06, "red":0x02,"green":0x04}, - ] -MONITOR_FANS_LED = [ - {"bus":2,"devno":0x32, "addr":0x23, "green":0x09, "red":0x0a}, - {"bus":2,"devno":0x32, "addr":0x24, "green":0x09, "red":0x0a}, - {"bus":2,"devno":0x32, "addr":0x25, "green":0x09, "red":0x0a}, - {"bus":2,"devno":0x32, "addr":0x26, "green":0x09, "red":0x0a}] - - -CPLDVERSIONS = [ - {"bus":2, "devno":0x33, "name":"MAC BOARD CPLD-A"}, - {"bus":2, "devno":0x35, "name":"MAC BOARD CPLD-B"}, - {"bus":2, "devno":0x37, "name":"CONNECT BOARD CPLD-A"}, - {"bus":0, "devno":0x0d, "name":"CPU BOARD CPLD"}, -] + "SPI-LOGIC-DEV": { + "chain3": { + "name": "FPGA", + "is_support_warm_upg": 0, + }, + }, -MONITOR_SYS_PSU_LED =[ - {"bus":2,"devno":0x33, "addr":0xb3, "yellow":0x06, "red":0x02,"green":0x04}, - ] + "MTD": { + "chain2": { + "name": "BIOS", + "is_support_warm_upg": 0, + "filesizecheck": 10240, # bios check file size, Unit: K + "init_cmd": [ + {"io_addr": 0x722, "value": 0x02, "gettype": "io"}, + {"cmd": "modprobe mtd", "gettype": "cmd"}, + {"cmd": "modprobe spi_nor", "gettype": "cmd"}, + {"cmd": "modprobe ofpart", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi writeable=1", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi_platform writeable=1", "gettype": "cmd"}, + ], + "finish_cmd": [ + {"cmd": "rmmod intel_spi_platform", "gettype": "cmd"}, + {"cmd": "rmmod intel_spi", "gettype": "cmd"}, + {"cmd": "rmmod ofpart", "gettype": "cmd"}, + {"cmd": "rmmod spi_nor", "gettype": "cmd"}, + {"cmd": "rmmod mtd", "gettype": "cmd"}, + ], + }, + }, -MONITOR_FAN_STATUS = [ - {'status':'green' , 'minOkNum':4,'maxOkNum':4}, - {'status':'yellow', 'minOkNum':3,'maxOkNum':3}, - {'status':'red' , 'minOkNum':0,'maxOkNum':2}, - ] + "TEST": { + "cpld": [ + {"chain": 1, "file": "/etc/.upgrade_test/cpld_test_header.vme", "display_name": "CPLD"}, + ], + "fpga": [ + { + "chain": 3, + "file": "/etc/.upgrade_test/fpga_test_header.bin", + "display_name": "FPGA", + }, + ], + }, + }, -MONITOR_PSU_STATUS = [ - {'status':'green' , 'minOkNum':2,'maxOkNum':2}, - {'status':'yellow', 'minOkNum':1,'maxOkNum':1}, - {'status':'red' , 'minOkNum':0,'maxOkNum':0}, - ] + "BMC": { + "name": "BMC", + "init_cmd": [ + ], + "finish_cmd": [], + }, +} -MONITOR_DEV_STATUS = { - "temperature": [ - {"name":"lm75in", "location":"/sys/bus/i2c/devices/2-0048/hwmon/*/temp1_input"}, - {"name":"lm75out", "location":"/sys/bus/i2c/devices/2-0049/hwmon/*/temp1_input"}, - {"name":"lm75hot", "location":"/sys/bus/i2c/devices/2-004a/hwmon/*/temp1_input"}, - {"name":"cpu", "location":"/sys/class/hwmon/hwmon0"}, - ], - "fans": [ +PLATFORM_E2_CONF = { + "fan": [ { - "name":"fan1", - "presentstatus":{"bus":2, "loc":0x37, "offset":0x30, 'bit':0}, - "rollstatus": [ - {"name":"motor1","bus":2, "loc":0x37, "offset":0x31, 'bit':0}, - ] + "name": "fan1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/16-0050/eeprom", + "e2_decode": [ + { + "area": "productInfoArea", "field": "productVersion", "decode_type": "func", "func_name": "fru_decode_hw" + }, + { + "area": "boardInfoArea", "field": "boardextra1", "decode_type": "func", "func_name": "fru_decode_hw" + }, + ], }, { - "name":"fan2", - "presentstatus":{"bus":2, "loc":0x37, "offset":0x30, 'bit':1}, - "rollstatus":[ - {"name":"motor1","bus":2, "loc":0x37, "offset":0x31, 'bit':1}, - ] + "name": "fan2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/17-0050/eeprom", + "e2_decode": [ + { + "area": "productInfoArea", "field": "productVersion", "decode_type": "func", "func_name": "fru_decode_hw" + }, + { + "area": "boardInfoArea", "field": "boardextra1", "decode_type": "func", "func_name": "fru_decode_hw" + }, + ], }, { - "name":"fan3", - "presentstatus":{"bus":2, "loc":0x37, "offset":0x30, 'bit':2}, - "rollstatus":[ - {"name":"motor1","bus":2, "loc":0x37, "offset":0x31, 'bit':2}, - ] + "name": "fan3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/18-0050/eeprom", + "e2_decode": [ + { + "area": "productInfoArea", "field": "productVersion", "decode_type": "func", "func_name": "fru_decode_hw" + }, + { + "area": "boardInfoArea", "field": "boardextra1", "decode_type": "func", "func_name": "fru_decode_hw" + }, + ], }, { - "name":"fan4", - "presentstatus":{"bus":2, "loc":0x37, "offset":0x30, 'bit':3}, - "rollstatus":[ - {"name":"motor1","bus":2, "loc":0x37, "offset":0x31, 'bit':3}, - ] + "name": "fan4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/19-0050/eeprom", + "e2_decode": [ + { + "area": "productInfoArea", "field": "productVersion", "decode_type": "func", "func_name": "fru_decode_hw" + }, + { + "area": "boardInfoArea", "field": "boardextra1", "decode_type": "func", "func_name": "fru_decode_hw" + }, + ], }, ], - "psus": [ - {"name":"psu1", "bus":2, "loc":0x37, "offset":0x51, "gettype":"i2c", 'presentbit': 0, 'statusbit':1,'alertbit':2}, - {"name":"psu2", "bus":2, "loc":0x37, "offset":0x51, "gettype":"i2c", 'presentbit': 4, 'statusbit':5,'alertbit':6}, - ], - "mac_temp" : { - "flag" : {"bus":2, "loc":0x33, "offset":0xd4, "gettype":"i2c", 'okbit': 0, 'okval':1}, - "loc" : [ - "2-0035/mac_temp_input", - ], - "try_bcmcmd" : 0, - }, -} - -MONITOR_DEV_STATUS_DECODE = { - 'fanpresent': {0:'PRESENT', 1:'ABSENT', 'okval':0}, - 'fanroll' : {0:'STALL' , 1:'ROLL', 'okval':1}, - 'psupresent': {0:'PRESENT', 1:'ABSENT', 'okval':0}, - 'psuoutput' : {0:'FAULT' , 1:'NORMAL', 'okval':1}, - 'psualert' : {0:'FAULT' , 1:'NORMAL', 'okval':1}, -} -################################################################### - - - -MAC_AVS_PARAM ={ - 0x72:0x0384, - 0x73:0x037e, - 0x74:0x0378, - 0x75:0x0372, - 0x76:0x036b, - 0x77:0x0365, - 0x78:0x035f, - 0x79:0x0359, - 0x7a:0x0352, - 0x7b:0x034c, - 0x7c:0x0346, - 0x7d:0x0340, - 0x7e:0x0339, - 0x7f:0x0333, - 0x80:0x032d, - 0x81:0x0327, - 0x82:0x0320, - 0x83:0x031a, - 0x84:0x0314, - 0x85:0x030e, - 0x86:0x0307, - 0x87:0x0301, - 0x88:0x02fb, - 0x89:0x02f5, - 0x8A:0x02ee -} - -MAC_DEFAULT_PARAM = { - "type": 1, - "default":0x74, - "loopaddr":0x00, - "loop":0x00, - "open":0x00, - "close":0x40, - "bus":2, - "devno":0x60, - "addr":0x21, - "protectaddr":0x10, - "sdkreg":"TOP_AVS_SEL_REG", - "sdkcmd": "scdcmd", - "sdkcmdargs": ["-t", 5], - "sdktype": 0, - "macregloc":24 , - "mask": 0xff + "psu": [ + {"name": "psu1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/24-0050/eeprom"}, + {"name": "psu2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/25-0050/eeprom"}, + ], + "syseeprom": [ + {"name": "syseeprom", "e2_type": "onie_tlv", "e2_path": "/sys/bus/i2c/devices/0-0056/eeprom"}, + ], } +AIR_FLOW_CONF = { + "psu_fan_airflow": { + "intake": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "exhaust": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] + }, + "fanairflow": { + "intake": ['M1HFAN I-F'], + "exhaust": ['M1HFAN I-R'] + }, -DEVICE = [] -DRIVERLISTS = [] - -""" -## -DRIVERLISTS = [ - {"name":"i2c_dev", "delay":0}, - {"name":"i2c_algo_bit","delay":0}, - {"name":"i2c_gpio", "delay":0}, - {"name":"i2c_mux", "delay":0}, - {"name":"i2c_mux_pca9641", "delay":0}, - {"name":"i2c_mux_pca954x force_create_bus=1", "delay":0},# force_deselect_on_exit=1 - {"name":"lm75", "delay":0}, - {"name":"optoe", "delay":0}, - {"name":"at24", "delay":0}, - {"name":"rg_sff", "delay":0}, - {"name":"ragile_b6510_platform", "delay":0}, - {"name":"ragile_platform", "delay":0}, - {"name":"rg_avs", "delay":0}, - {"name":"rg_cpld", "delay":0}, - {"name":"rg_fan", "delay":0}, - {"name":"rg_psu", "delay":0}, - {"name":"pmbus_core", "delay":0}, - {"name":"csu550", "delay":0}, - {"name":"rg_gpio_xeon", "delay":0}, - {"name":"firmware_driver", "delay":0}, - {"name":"firmware_bin", "delay":0}, - {"name":"ragile_b6510_sfputil", "delay":0}, - {"name":"ragile_common dfd_my_type=0x404a", "delay":0}, - {"name":"lpc_dbg", "delay":0}, -] - -DEVICE = [ - {"name":"pca9641","bus":0 ,"loc":0x10 }, - {"name":"pca9548","bus":2 ,"loc":0x70 }, - {"name":"lm75","bus": 2, "loc":0x48 }, - {"name":"lm75","bus": 2, "loc":0x49 }, - {"name":"lm75","bus": 2, "loc":0x4a }, - {"name":"24c02","bus":2 , "loc":0x57 }, - {"name":"rg_cpld","bus":0 ,"loc":0x32 }, - {"name":"rg_cpld","bus":1 ,"loc":0x34 }, - {"name":"rg_cpld","bus":1 ,"loc":0x36 }, - {"name":"rg_cpld","bus":2 ,"loc":0x33 }, - {"name":"rg_cpld","bus":2 ,"loc":0x35 }, - {"name":"rg_cpld","bus":2 ,"loc":0x37 }, - {"name":"rg_avs","bus": 2 ,"loc":0x60 }, - {"name":"pca9548","bus":1,"loc":0x70 }, - {"name":"pca9548","bus":1,"loc":0x71 }, - {"name":"pca9548","bus":1,"loc":0x72 }, - {"name":"pca9548","bus":1,"loc":0x73 }, - {"name":"pca9548","bus":1,"loc":0x74 }, - {"name":"pca9548","bus":1,"loc":0x75 }, - {"name":"pca9548","bus":1,"loc":0x76 }, - {"name":"rg_fan","bus":3,"loc":0x53 }, - {"name":"rg_fan","bus":4,"loc":0x53 }, - {"name":"rg_fan","bus":5,"loc":0x53 }, - {"name":"rg_fan","bus":6,"loc":0x53 }, - {"name":"rg_psu","bus":7 ,"loc":0x50 }, - {"name":"dps550","bus":7 ,"loc":0x58 }, - {"name":"rg_psu","bus":8 ,"loc":0x53 }, - {"name":"dps550","bus":8 ,"loc":0x5b }, - {"name": "optoe2", "bus": 11, "loc": 0x50}, - {"name": "optoe2", "bus": 12, "loc": 0x50}, - {"name": "optoe2", "bus": 13, "loc": 0x50}, - {"name": "optoe2", "bus": 14, "loc": 0x50}, - {"name": "optoe2", "bus": 15, "loc": 0x50}, - {"name": "optoe2", "bus": 16, "loc": 0x50}, - {"name": "optoe2", "bus": 17, "loc": 0x50}, - {"name": "optoe2", "bus": 18, "loc": 0x50}, - {"name": "optoe2", "bus": 19, "loc": 0x50}, - {"name": "optoe2", "bus": 20, "loc": 0x50}, - {"name": "optoe2", "bus": 21, "loc": 0x50}, - {"name": "optoe2", "bus": 22, "loc": 0x50}, - {"name": "optoe2", "bus": 23, "loc": 0x50}, - {"name": "optoe2", "bus": 24, "loc": 0x50}, - {"name": "optoe2", "bus": 25, "loc": 0x50}, - {"name": "optoe2", "bus": 26, "loc": 0x50}, - {"name": "optoe2", "bus": 27, "loc": 0x50}, - {"name": "optoe2", "bus": 28, "loc": 0x50}, - {"name": "optoe2", "bus": 29, "loc": 0x50}, - {"name": "optoe2", "bus": 30, "loc": 0x50}, - {"name": "optoe2", "bus": 31, "loc": 0x50}, - {"name": "optoe2", "bus": 32, "loc": 0x50}, - {"name": "optoe2", "bus": 33, "loc": 0x50}, - {"name": "optoe2", "bus": 34, "loc": 0x50}, - {"name": "optoe2", "bus": 35, "loc": 0x50}, - {"name": "optoe2", "bus": 36, "loc": 0x50}, - {"name": "optoe2", "bus": 37, "loc": 0x50}, - {"name": "optoe2", "bus": 38, "loc": 0x50}, - {"name": "optoe2", "bus": 39, "loc": 0x50}, - {"name": "optoe2", "bus": 40, "loc": 0x50}, - {"name": "optoe2", "bus": 41, "loc": 0x50}, - {"name": "optoe2", "bus": 42, "loc": 0x50}, - {"name": "optoe2", "bus": 43, "loc": 0x50}, - {"name": "optoe2", "bus": 44, "loc": 0x50}, - {"name": "optoe2", "bus": 45, "loc": 0x50}, - {"name": "optoe2", "bus": 46, "loc": 0x50}, - {"name": "optoe2", "bus": 47, "loc": 0x50}, - {"name": "optoe2", "bus": 48, "loc": 0x50}, - {"name": "optoe2", "bus": 49, "loc": 0x50}, - {"name": "optoe2", "bus": 50, "loc": 0x50}, - {"name": "optoe2", "bus": 51, "loc": 0x50}, - {"name": "optoe2", "bus": 52, "loc": 0x50}, - {"name": "optoe2", "bus": 53, "loc": 0x50}, - {"name": "optoe2", "bus": 54, "loc": 0x50}, - {"name": "optoe2", "bus": 55, "loc": 0x50}, - {"name": "optoe2", "bus": 56, "loc": 0x50}, - {"name": "optoe2", "bus": 57, "loc": 0x50}, - {"name": "optoe2", "bus": 58, "loc": 0x50}, - {"name": "optoe1", "bus": 59, "loc": 0x50}, - {"name": "optoe1", "bus": 60, "loc": 0x50}, - {"name": "optoe1", "bus": 61, "loc": 0x50}, - {"name": "optoe1", "bus": 62, "loc": 0x50}, - {"name": "optoe1", "bus": 63, "loc": 0x50}, - {"name": "optoe1", "bus": 64, "loc": 0x50}, - {"name": "optoe1", "bus": 65, "loc": 0x50}, - {"name": "optoe1", "bus": 66, "loc": 0x50}, -] - -INIT_PARAM = [ - {"loc":"1-0034/sfp_enable","value": "01"}, - {"loc":"2-0035/sfp_enable2","value":"ff"}, - {"loc":"2-0033/mac_led", "value":"ff"}, - {"loc":"1-0034/sfp_txdis1","value":"00"}, - {"loc":"1-0034/sfp_txdis2","value":"00"}, - {"loc":"1-0034/sfp_txdis3","value":"00"}, - {"loc":"1-0036/sfp_txdis4","value":"00"}, - {"loc":"1-0036/sfp_txdis5","value":"00"}, - {"loc":"1-0036/sfp_txdis6","value":"00"}, - {"loc":fanloc[0]["location"], "value":"80"}, - {"loc":"2-0033/sfp_led1_yellow","value":"ad"}, - {"loc":"2-0035/sfp_led2_yellow","value":"ad"}, -] -""" + "fans": [ + { + "name": "FAN1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/16-0050/eeprom", + "area": "productInfoArea", "field": "productName", "decode": "fanairflow" + }, + { + "name": "FAN2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/17-0050/eeprom", + "area": "productInfoArea", "field": "productName", "decode": "fanairflow" + }, + { + "name": "FAN3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/18-0050/eeprom", + "area": "productInfoArea", "field": "productName", "decode": "fanairflow" + }, + { + "name": "FAN4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/19-0050/eeprom", + "area": "productInfoArea", "field": "productName", "decode": "fanairflow" + } + ], -INIT_PARAM = [ - { - "name": "sfp_enable", - "bus": 1, - "devaddr": 0x34, - "offset": 0xa1, - "val": 0x01, - }, - { - "name": "sfp_eanble2", - "bus": 2, - "devaddr": 0x35, - "offset": 0xa0, - "val": 0xff, - }, - { - "name": "mac_led", - "bus": 2, - "devaddr": 0x33, - "offset": 0xa0, - "val": 0xff, - }, - { - "name": "sfp_txdis1", - "bus": 1, - "devaddr": 0x34, - "offset": 0x60, - "val": 0x00, - }, - { - "name": "sfp_txdis2", - "bus": 1, - "devaddr": 0x34, - "offset": 0x61, - "val": 0x00, - }, - { - "name": "sfp_txdis3", - "bus": 1, - "devaddr": 0x34, - "offset": 0x62, - "val": 0x00, - }, - { - "name": "sfp_txdis4", - "bus": 1, - "devaddr": 0x36, - "offset": 0x60, - "val": 0x00, - }, - { - "name": "sfp_txdis5", - "bus": 1, - "devaddr": 0x36, - "offset": 0x61, - "val": 0x00, - }, - { - "name": "sfp_txdis6", - "bus": 1, - "devaddr": 0x36, - "offset": 0x62, - "val": 0x00, - }, - { - "name": "sfp_led1_yellow", - "bus": 2, - "devaddr": 0x33, - "offset": 0xad, - "val": 0xad, - }, - { - "name": "sfp_led2_yellow", - "bus": 2, - "devaddr": 0x35, - "offset": 0xad, - "val": 0xad, - }, - { - "name": "fan_speed_set", - "bus": 0, - "devaddr": 0x32, - "offset": 0x15, - "val": 0x80, - }, -] + "psus": [ + { + "name": "PSU1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/24-0050/eeprom", + "area": "productInfoArea", "field": "productPartModelName", "decode": "psu_fan_airflow" + }, + { + "name": "PSU2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/25-0050/eeprom", + "area": "productInfoArea", "field": "productPartModelName", "decode": "psu_fan_airflow" + } + ] +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_port_config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_port_config.py new file mode 100644 index 000000000000..26f92a77a020 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/config/x86_64_ragile_ra_b6510_48v8c_r0_port_config.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +PLATFORM_INTF_OPTOE = { + "port_num": 56, + "optoe_start_bus": 32, +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_device.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_device.py new file mode 100644 index 000000000000..34257080c150 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_device.py @@ -0,0 +1,1212 @@ +#!/usr/bin/python3 + +psu_fan_airflow = { + "intake": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "exhaust": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] +} + +fanairflow = { + "intake": ['M1HFAN I-F'], + "exhaust": ['M1HFAN I-R'], +} + +psu_display_name = { + "PA550II-F": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "PA550II-R": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] +} + +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + + +PSU_NOT_PRESENT_PWM = 100 + + +class threshold: + PSU_TEMP_MIN = -20 * 1000 + PSU_TEMP_MAX = 60 * 1000 + + PSU_FAN_SPEED_MIN = 2000 + PSU_FAN_SPEED_MAX = 18000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 560 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 625 * 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 1 * 1000 + PSU_OUTPUT_CURRENT_MAX = 45 * 1000 + + PSU_INPUT_CURRENT_MIN = 0 * 1000 + PSU_INPUT_CURRENT_MAX = 7 * 1000 + + FRONT_FAN_SPEED_MAX = 24000 + REAR_FAN_SPEED_MAX = 22500 + FAN_SPEED_MIN = 5000 + + +class Description: + CPLD = "Used for managing IO modules, SFP+ modules and system LEDs" + BIOS = "Performs initialization of hardware components during booting" + FPGA = "Platform management controller for on-board temperature monitoring, in-chassis power" + + +devices = { + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/0-0056/eeprom", "way": "sysfs"}, + "airflow": "intake" + }, + ], + "psus": [ + { + "e2loc": {"loc": "/sys/bus/i2c/devices/24-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 24, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 24, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/25-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 25, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 25, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + } + ], + "temps": [ + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP1", + "api_name": "ASIC_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0044/hwmon/hwmon*/temp99_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 105000, + "Max": 110000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "CPU_TEMP", + "temp_id": "TEMP2", + "Temperature": { + "value": {"loc": "/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -15000, + "Low": 0, + "High": 100000, + "Max": 102000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP3", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "fix_value": { + "fix_type": "config", + "addend": -3, + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP4", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-004c/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "BOARD_TEMP", + "temp_id": "TEMP5", + "api_name": "MAC_OUT_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-004a/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "MAC_IN_TEMP", + "temp_id": "TEMP6", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU1_TEMP", + "temp_id": "TEMP7", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -20000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU2_TEMP", + "temp_id": "TEMP8", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -20000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "Temperature": { + "value": {"loc": "/tmp/highest_sff_temp", "way": "sysfs", "flock_path": "/tmp/highest_sff_temp"}, + "Min": -30000, + "Low": 0, + "High": 90000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "invalid": -10000, + "error": -9999, + } + ], + "leds": [ + { + "name": "FRONT_SYS_LED", + "led_type": "SYS_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x72, "way": "i2c"}, + "led_attrs": { + "off": 0x00, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + }, + { + "name": "FRONT_PSU_LED", + "led_type": "PSU_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x73, "way": "i2c"}, + "led_attrs": { + "off": 0x10, "red_flash": 0x11, "red": 0x12, + "green_flash": 0x13, "green": 0x14, "amber_flash": 0x15, + "amber": 0x16, "mask": 0x17 + }, + }, + { + "name": "FRONT_FAN_LED", + "led_type": "FAN_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x74, "way": "i2c"}, + "led_attrs": { + "off": 0x10, "red_flash": 0x11, "red": 0x12, + "green_flash": 0x13, "green": 0x14, "amber_flash": 0x15, + "amber": 0x16, "mask": 0x17 + }, + }, + ], + "fans": [ + { + "name": "FAN1", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-16/16-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3b, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-17/17-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-18/18-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + + { + "name": "FAN4", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-19/19-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3e, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x17, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x17, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + }, + { + "name": "CONNECT_CPLD", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + }, + { + "name": "CONNECT_CPLD-FAN", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld2", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for fan modules", + "slot": 0, + }, + { + "name": "MAC_CPLD1", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld3", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + }, + { + "name": "MAC_CPLD2", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld4", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + }, + { + "name": "FPGA", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/fpga0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + }, + ], + "dcdc": [ + { + "name": "Switch_ZSFP1_3v3_C", + "dcdc_id": "DCDC1", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 22000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_QSFP1_3v3_C", + "dcdc_id": "DCDC2", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 22000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_5v0_C", + "dcdc_id": "DCDC3", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ZSFP1_3v3_V", + "dcdc_id": "DCDC4", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_QSFP1_3v3_V", + "dcdc_id": "DCDC5", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_5v0_V", + "dcdc_id": "DCDC6", + "Min": 4000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 6000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_1v2_C", + "dcdc_id": "DCDC7", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_3v3_C", + "dcdc_id": "DCDC8", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_Cpld_3v3_C", + "dcdc_id": "DCDC9", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_1v2_V", + "dcdc_id": "DCDC10", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_3v3_V", + "dcdc_id": "DCDC11", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_Cpld_3v3_V", + "dcdc_id": "DCDC12", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_1v2_C", + "dcdc_id": "DCDC13", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1300, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_3v3_C", + "dcdc_id": "DCDC14", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2800, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_SSD_3v3_C", + "dcdc_id": "DCDC15", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 4500, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_1v2_V", + "dcdc_id": "DCDC16", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_3v3_V", + "dcdc_id": "DCDC17", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_SSD_3v3_V", + "dcdc_id": "DCDC18", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_3v3_C", + "dcdc_id": "DCDC19", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 4686, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_5v_C", + "dcdc_id": "DCDC20", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v7_C", + "dcdc_id": "DCDC21", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_3v3_V", + "dcdc_id": "DCDC22", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_5v_V", + "dcdc_id": "DCDC23", + "Min": 4000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 6000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v7_V", + "dcdc_id": "DCDC24", + "Min": 1360, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2040, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_CORE_C", + "dcdc_id": "DCDC25", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 47300, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v05_C", + "dcdc_id": "DCDC26", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 15400, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_CORE_V", + "dcdc_id": "DCDC27", + "Min": 1456, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2184, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v05_V", + "dcdc_id": "DCDC28", + "Min": 840, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1260, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_CORE_C", + "dcdc_id": "DCDC29", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 220000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ANALOG_C", + "dcdc_id": "DCDC30", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 18000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_CORE_V", + "dcdc_id": "DCDC31", + "Min": 600, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ANALOG_V", + "dcdc_id": "DCDC32", + "Min": 640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v2_C", + "dcdc_id": "DCDC33", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 9900, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_2v23_C", + "dcdc_id": "DCDC34", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v2_V", + "dcdc_id": "DCDC35", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_2v23_V", + "dcdc_id": "DCDC36", + "Min": 1784, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2676, + "format": "float(float(%s)/1000)", + }, + ], + "sfps": { + "ver": '1.0', + "port_index_start": 1, + "port_num": 56, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_cpld": { + "dev_id": { + 3: { + "offset": { + 0x30: "1-8", + 0x31: "9-16", + 0x32: "17-24", + }, + }, + 4: { + "offset": { + 0x30: "25-32", + 0x31: "33-40", + 0x32: "41-48", + 0x33: "49-56", + }, + }, + }, + }, + "presence_val_is_present": 0, + "eeprom_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/eeprom", + "eeprom_path_key": list(range(32, 88)), + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(32, 88)), + "txdis_cpld": { + "dev_id": { + 3: { + "offset": { + 0x60: "1-8", + 0x61: "9-16", + 0x62: "17-24", + }, + }, + 4: { + "offset": { + 0x60: "25-32", + 0x61: "33-40", + 0x62: "41-48", + }, + }, + }, + }, + "txdisable_val_is_on": 0, + "reset_cpld": { + "dev_id": { + 4: { + "offset": { + 0xb9: "49-56", + }, + }, + }, + }, + "reset_val_is_reset": 0, + } +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_exhaust_device.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_exhaust_device.py new file mode 100644 index 000000000000..caa7dd08d7cf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_exhaust_device.py @@ -0,0 +1,1211 @@ +#!/usr/bin/python3 + +psu_fan_airflow = { + "intake": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "exhaust": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] +} + +fanairflow = { + "intake": ['M1HFAN I-F'], + "exhaust": ['M1HFAN I-R'], +} + +psu_display_name = { + "PA550II-F": ['CSU550AP-3-500', 'DPS-550AB-39 A', 'GW-CRPS550N2C', 'CSU550AP-3-300', 'DPS-550AB-39 B'], + "PA550II-R": ['CSU550AP-3-501', 'DPS-550AB-40 A', 'GW-CRPS550N2RC'] +} + +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + + +PSU_NOT_PRESENT_PWM = 100 + + +class threshold: + PSU_TEMP_MIN = -20 * 1000 + PSU_TEMP_MAX = 60 * 1000 + + PSU_FAN_SPEED_MIN = 2000 + PSU_FAN_SPEED_MAX = 18000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 560 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 625 * 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 1 * 1000 + PSU_OUTPUT_CURRENT_MAX = 45 * 1000 + + PSU_INPUT_CURRENT_MIN = 0 * 1000 + PSU_INPUT_CURRENT_MAX = 7 * 1000 + + FRONT_FAN_SPEED_MAX = 24000 + REAR_FAN_SPEED_MAX = 22500 + FAN_SPEED_MIN = 5000 + + +class Description: + CPLD = "Used for managing IO modules, SFP+ modules and system LEDs" + BIOS = "Performs initialization of hardware components during booting" + FPGA = "Platform management controller for on-board temperature monitoring, in-chassis power" + + +devices = { + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/0-0056/eeprom", "way": "sysfs"}, + "airflow": "exhaust" + }, + ], + "psus": [ + { + "e2loc": {"loc": "/sys/bus/i2c/devices/24-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 24, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 24, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/25-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 25, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 25, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + } + ], + "temps": [ + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP1", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0044/hwmon/hwmon*/temp99_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 105000, + "Max": 110000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "CPU_TEMP", + "temp_id": "TEMP2", + "Temperature": { + "value": {"loc": "/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -15000, + "Low": 0, + "High": 100000, + "Max": 102000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP3", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-004c/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "fix_value": { + "fix_type": "config", + "addend": -3, + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP4", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "BOARD_TEMP", + "temp_id": "TEMP5", + "api_name": "MAC_OUT_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "MAC_IN_TEMP", + "temp_id": "TEMP6", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/3-004a/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -30000, + "Low": 0, + "High": 75000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU1_TEMP", + "temp_id": "TEMP7", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-24/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -20000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU2_TEMP", + "temp_id": "TEMP8", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-25/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -20000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "Temperature": { + "value": {"loc": "/tmp/highest_sff_temp", "way": "sysfs", "flock_path": "/tmp/highest_sff_temp"}, + "Min": -30000, + "Low": 0, + "High": 90000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "invalid": -10000, + "error": -9999, + } + ], + "leds": [ + { + "name": "FRONT_SYS_LED", + "led_type": "SYS_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x72, "way": "i2c"}, + "led_attrs": { + "off": 0x00, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + }, + { + "name": "FRONT_PSU_LED", + "led_type": "PSU_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x73, "way": "i2c"}, + "led_attrs": { + "off": 0x10, "red_flash": 0x11, "red": 0x12, + "green_flash": 0x13, "green": 0x14, "amber_flash": 0x15, + "amber": 0x16, "mask": 0x17 + }, + }, + { + "name": "FRONT_FAN_LED", + "led_type": "FAN_LED", + "led": {"bus": 6, "addr": 0x0d, "offset": 0x74, "way": "i2c"}, + "led_attrs": { + "off": 0x10, "red_flash": 0x11, "red": 0x12, + "green_flash": 0x13, "green": 0x14, "amber_flash": 0x15, + "amber": 0x16, "mask": 0x17 + }, + }, + ], + "fans": [ + { + "name": "FAN1", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-16/16-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3b, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-17/17-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-18/18-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + + { + "name": "FAN4", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-19/19-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 2, "addr": 0x0d, "offset": 0x3e, "way": "i2c"}, + "led_attrs": { + "off": 0x0b, "red_flash": 0x0e, "red": 0x0a, + "green_flash": 0x0d, "green": 0x09, "amber_flash": 0x07, + "amber": 0x03, "mask": 0x0f + }, + "PowerMax": 38.4, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x17, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 2, "addr": 0x0d, "offset": 0x17, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + }, + { + "name": "CONNECT_CPLD", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + }, + { + "name": "CONNECT_CPLD-FAN", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld2", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for fan modules", + "slot": 0, + }, + { + "name": "MAC_CPLD1", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld3", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + }, + { + "name": "MAC_CPLD2", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld4", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + }, + { + "name": "FPGA", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/fpga0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + }, + ], + "dcdc": [ + { + "name": "Switch_ZSFP1_3v3_C", + "dcdc_id": "DCDC1", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 22000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_QSFP1_3v3_C", + "dcdc_id": "DCDC2", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 22000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_5v0_C", + "dcdc_id": "DCDC3", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ZSFP1_3v3_V", + "dcdc_id": "DCDC4", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_QSFP1_3v3_V", + "dcdc_id": "DCDC5", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_5v0_V", + "dcdc_id": "DCDC6", + "Min": 4000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0040/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 6000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_1v2_C", + "dcdc_id": "DCDC7", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_3v3_C", + "dcdc_id": "DCDC8", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_Cpld_3v3_C", + "dcdc_id": "DCDC9", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_1v2_V", + "dcdc_id": "DCDC10", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_3v3_V", + "dcdc_id": "DCDC11", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_Cpld_3v3_V", + "dcdc_id": "DCDC12", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0041/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_1v2_C", + "dcdc_id": "DCDC13", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 1300, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_3v3_C", + "dcdc_id": "DCDC14", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2800, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_SSD_3v3_C", + "dcdc_id": "DCDC15", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 4500, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_1v2_V", + "dcdc_id": "DCDC16", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_3v3_V", + "dcdc_id": "DCDC17", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Con_SSD_3v3_V", + "dcdc_id": "DCDC18", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0042/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_3v3_C", + "dcdc_id": "DCDC19", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 4686, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_5v_C", + "dcdc_id": "DCDC20", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v7_C", + "dcdc_id": "DCDC21", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_3v3_V", + "dcdc_id": "DCDC22", + "Min": 2640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_5v_V", + "dcdc_id": "DCDC23", + "Min": 4000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 6000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v7_V", + "dcdc_id": "DCDC24", + "Min": 1360, + "value": { + "loc": "/sys/bus/i2c/devices/7-0043/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2040, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_CORE_C", + "dcdc_id": "DCDC25", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 47300, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v05_C", + "dcdc_id": "DCDC26", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 15400, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_CORE_V", + "dcdc_id": "DCDC27", + "Min": 1456, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2184, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v05_V", + "dcdc_id": "DCDC28", + "Min": 840, + "value": { + "loc": "/sys/bus/i2c/devices/7-0060/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1260, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_CORE_C", + "dcdc_id": "DCDC29", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 220000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ANALOG_C", + "dcdc_id": "DCDC30", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/curr3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 18000, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_CORE_V", + "dcdc_id": "DCDC31", + "Min": 600, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Switch_ANALOG_V", + "dcdc_id": "DCDC32", + "Min": 640, + "value": { + "loc": "/sys/bus/i2c/devices/7-0064/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 960, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v2_C", + "dcdc_id": "DCDC33", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/curr1_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 9900, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_2v23_C", + "dcdc_id": "DCDC34", + "Min": -1000, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/curr2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "A", + "Max": 2200, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_1v2_V", + "dcdc_id": "DCDC35", + "Min": 960, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1440, + "format": "float(float(%s)/1000)", + }, + + { + "name": "Cpu_2v23_V", + "dcdc_id": "DCDC36", + "Min": 1784, + "value": { + "loc": "/sys/bus/i2c/devices/7-006c/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2676, + "format": "float(float(%s)/1000)", + }, + ], + "sfps": { + "ver": '1.0', + "port_index_start": 1, + "port_num": 56, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_cpld": { + "dev_id": { + 3: { + "offset": { + 0x30: "1-8", + 0x31: "9-16", + 0x32: "17-24", + }, + }, + 4: { + "offset": { + 0x30: "25-32", + 0x31: "33-40", + 0x32: "41-48", + 0x33: "49-56", + }, + }, + }, + }, + "presence_val_is_present": 0, + "eeprom_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/eeprom", + "eeprom_path_key": list(range(32, 88)), + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(32, 88)), + "txdis_cpld": { + "dev_id": { + 3: { + "offset": { + 0x60: "1-8", + 0x61: "9-16", + 0x62: "17-24", + }, + }, + 4: { + "offset": { + 0x60: "25-32", + 0x61: "33-40", + 0x62: "41-48", + }, + }, + }, + }, + "txdisable_val_is_on": 0, + "reset_cpld": { + "dev_id": { + 4: { + "offset": { + 0xb9: "49-56", + }, + }, + }, + }, + "reset_val_is_reset": 0, + } +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_monitor.py new file mode 100644 index 000000000000..3a9eef34d880 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/hal-config/x86_64_ragile_ra_b6510_48v8c_r0_monitor.py @@ -0,0 +1,204 @@ +# coding:utf-8 + + +monitor = { + "openloop": { + "linear": { + "name": "linear", + "flag": 0, + "pwm_min": 0x80, + "pwm_max": 0xff, + "K": 11, + "tin_min": 38, + }, + "curve": { + "name": "curve", + "flag": 0, + "pwm_min": 0x5a, + "pwm_max": 0xff, + "a": 0.086, + "b": 0.318, + "c": 28, + "tin_min": 25, + }, + }, + + "pid": { + "CPU_TEMP": { + "name": "CPU_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 3, + "Ki": 0.5, + "Kd": 0.5, + "target": 89, + "value": [None, None, None], + }, + "SWITCH_TEMP": { + "name": "SWITCH_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 3, + "Ki": 0.4, + "Kd": 0.4, + "target": 82, + "value": [None, None, None], + }, + "OUTLET_TEMP": { + "name": "OUTLET_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "BOARD_TEMP": { + "name": "BOARD_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "SFF_TEMP": { + "name": "SFF_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 0.1, + "Ki": 0.4, + "Kd": 0, + "target": 60, + "value": [None, None, None], + }, + }, + + "hyst": { + "INLET_TEMP": { + "name": "INLET_TEMP", + "flag": 1, + "type": "duty", + "hyst_min": 50, # duty + "hyst_max": 100, # duty + "last_hyst_value": 50, # duty + "temp_min": 23, + "temp_max": 40, + "value": [None, None], + "rising": { + 23: 50, + 24: 50, + 25: 50, + 26: 53, + 27: 56, + 28: 59, + 29: 62, + 30: 65, + 31: 68, + 32: 71, + 33: 74, + 34: 77, + 35: 80, + 36: 84, + 37: 88, + 38: 92, + 39: 96, + 40: 100, + }, + "descending": { + 23: 50, + 24: 53, + 25: 56, + 26: 59, + 27: 62, + 28: 65, + 29: 68, + 30: 71, + 31: 74, + 32: 77, + 33: 80, + 34: 84, + 35: 88, + 36: 92, + 37: 96, + 38: 100, + 39: 100, + 40: 100, + }, + } + }, + + "temps_threshold": { + "SWITCH_TEMP": {"name": "SWITCH_TEMP", "warning": 100, "critical": 105}, + "INLET_TEMP": {"name": "INLET_TEMP", "warning": 40, "critical": 50}, + "BOARD_TEMP": {"name": "BOARD_TEMP", "warning": 70, "critical": 80}, + "OUTLET_TEMP": {"name": "OUTLET_TEMP", "warning": 70, "critical": 80}, + "CPU_TEMP": {"name": "CPU_TEMP", "warning": 100, "critical": 102}, + "SFF_TEMP": {"name": "SFF_TEMP", "warning": 999, "critical": 1000, "ignore_threshold": 1, "invalid": -10000, "error": -9999}, + }, + + "fancontrol_para": { + "interval": 5, + "fan_air_flow_monitor": 1, + "psu_air_flow_monitor": 1, + "max_pwm": 0xff, + "min_pwm": 0x80, + "abnormal_pwm": 0xff, + "warning_pwm": 0xff, + "temp_invalid_pid_pwm": 0x80, + "temp_error_pid_pwm": 0x80, + "temp_fail_num": 3, + "check_temp_fail": [ + {"temp_name": "INLET_TEMP"}, + {"temp_name": "SWITCH_TEMP"}, + {"temp_name": "CPU_TEMP"}, + ], + "temp_warning_num": 3, # temp over warning 3 times continuously + "temp_critical_num": 3, # temp over critical 3 times continuously + "temp_warning_countdown": 60, # 5 min warning speed after not warning + "temp_critical_countdown": 60, # 5 min full speed after not critical + "rotor_error_count": 6, # fan rotor error 6 times continuously + "inlet_mac_diff": 999, + "check_crit_reboot_flag": 1, + "check_crit_reboot_num": 3, + "check_crit_sleep_time": 20, + "psu_absent_fullspeed_num": 0xFF, + "fan_absent_fullspeed_num": 1, + "rotor_error_fullspeed_num": 1, + }, + + "ledcontrol_para": { + "interval": 5, + "checkpsu": 0, # 0: sys led don't follow psu led + "checkfan": 0, # 0: sys led don't follow fan led + "psu_amber_num": 1, + "fan_amber_num": 1, + "board_sys_led": [ + {"led_name": "FRONT_SYS_LED"}, + ], + "board_psu_led": [ + {"led_name": "FRONT_PSU_LED"}, + ], + "board_fan_led": [ + {"led_name": "FRONT_FAN_LED"}, + ], + "psu_air_flow_monitor": 1, + "fan_air_flow_monitor": 1, + "psu_air_flow_amber_num": 1, + "fan_air_flow_amber_num": 1, + }, + + +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/Makefile index f10216ec4d5a..e59ffd7ee67d 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/Makefile @@ -1 +1,15 @@ -obj-m := rg_cpld.o +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/app/firmware_upgrade/firmware_driver/include) + +EXTRA_CFLAGS+= -I$(MODULES_DIR) +EXTRA_CFLAGS+= -I$(MODULES_DIR)/linux-5.10 +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) + +obj-m := wb_pcie_dev_device.o +obj-m += wb_i2c_mux_pca954x_device.o +obj-m += wb_i2c_ocores_device.o +obj-m += wb_lpc_drv_device.o +obj-m += wb_i2c_dev_device.o +obj-m += wb_io_dev_device.o +obj-m += wb_firmware_upgrade_device.o diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/rg_cpld.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/rg_cpld.c deleted file mode 100755 index 885a727be683..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/rg_cpld.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - * rg_cpld.c - A driver for cpld - * - * Copyright (c) 2019 - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* debug level */ -typedef enum { - DBG_START, - DBG_VERBOSE, - DBG_KEY, - DBG_WARN, - DBG_ERROR, - DBG_END, -} dbg_level_t; - -static int debuglevel = 0; -module_param(debuglevel, int, S_IRUGO); - -#define DBG_DEBUG(fmt, arg...) do { \ - if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ - printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } else if ( debuglevel >= DBG_ERROR ) { \ - printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } else { } \ -} while (0) - -#define DBG_ERROR(fmt, arg...) do { \ - if ( debuglevel > DBG_START) { \ - printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } \ -} while (0) - -static const unsigned short rg_i2c_cpld[] = { 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, I2C_CLIENT_END }; - -#define CPLD_SIZE 256 -#define CPLD_I2C_RETRY_TIMES 3 -#define READ_TEMP_FAIL 1000000 - -struct cpld_data { - struct i2c_client *client; - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 data[CPLD_SIZE]; /* Register value */ -}; - -static s32 cpld_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) { - if ((ret = i2c_smbus_read_byte_data(client, command) ) >= 0 ) - break; - } - return ret; -} - -static s32 cpld_i2c_smbus_read_i2c_block_data(const struct i2c_client *client, - u8 command, u8 length, u8 *values) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) { - if ((ret = i2c_smbus_read_i2c_block_data(client, command, length, values) ) >= 0 ) - break; - } - return ret; -} - -static ssize_t show_fan_rpm_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct cpld_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int index = to_sensor_dev_attr_2(da)->index; - uint8_t size; - s32 status; - s32 ret_t; - - ret_t = 0; - status = -1; - size = 0; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_byte_data(client, index); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - data->data[0] = status; - status = cpld_i2c_smbus_read_byte_data(client, index + 1); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - data->data[1] = status; - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index, data->data[0]); - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index + 1, data->data[1]); - ret_t = (data->data[1] << 8) + data->data[0] ; - if (ret_t == 0 ) { - size = snprintf(buf, CPLD_SIZE, "%d\n", ret_t); - } else if (ret_t == 0xffff) { - size = snprintf(buf, CPLD_SIZE, "%d\n", 0); - } else { - size = snprintf(buf, CPLD_SIZE, "%d\n", 15000000 / ret_t); - } - mutex_unlock(&data->update_lock); - return size; -} - -static ssize_t set_cpld_sysfs_value(struct device *dev, struct device_attribute *da, const char *buf, size_t -count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - unsigned long val; - int err; - - err = kstrtoul(buf, 16, &val); - if (err) - return err; - if ((val < 0) || (val > 0xff)) { - DBG_ERROR("please enter 0x00 ~ 0xff\n"); - return -1; - } - mutex_lock(&data->update_lock); - data->data[0] = (u8)val; - DBG_DEBUG("pos: 0x%02x count = %ld, data = 0x%02x\n", attr->index, count, data->data[0]); - i2c_smbus_write_byte_data(client, attr->index, data->data[0]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - s32 status; - - status = -1; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_i2c_block_data(client, 0, 4, data->data); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - mutex_unlock(&data->update_lock); - return sprintf(buf, "%02x %02x %02x %02x \n", data->data[0], data->data[1], data->data[2], - data->data[3]); -} - -static ssize_t show_cpld_sysfs_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - s32 status; - - status = -1; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_byte_data(client, attr->index); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - data->data[0] = status; - DBG_DEBUG("cpld reg pos:0x%x value:0x%02x\n", attr->index, data->data[0]); - mutex_unlock(&data->update_lock); - return sprintf(buf, "%02x\n", data->data[0]); -} - -static ssize_t show_mac_temp_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct cpld_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int index = to_sensor_dev_attr_2(da)->index; - int tmp_value, value; - s32 status; - - status = -1; - mutex_lock(&data->update_lock); - - status = cpld_i2c_smbus_read_byte_data(client, index); - if (status < 0) { - mutex_unlock(&data->update_lock); - return snprintf(buf, CPLD_SIZE, "%d\n", -READ_TEMP_FAIL); - } - data->data[0] = status; - status = cpld_i2c_smbus_read_byte_data(client, index + 1); - if (status < 0) { - mutex_unlock(&data->update_lock); - return snprintf(buf, CPLD_SIZE, "%d\n", -READ_TEMP_FAIL); - } - data->data[1] = status; - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index, data->data[0]); - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index + 1, data->data[1]); - mutex_unlock(&data->update_lock); - - tmp_value = (data->data[1] << 8) + data->data[0]; - if (tmp_value == 0) { - DBG_ERROR("invalid cpld value : %d.\n", tmp_value); - return snprintf(buf, CPLD_SIZE, "%d\n", -READ_TEMP_FAIL); - } - - DBG_DEBUG("tmp_value = 0x%x\n", tmp_value); - value = 434100 - (12500000 / (tmp_value * 100 - 1) *535); - if ((value / 1000 < -70) || (value / 1000 > 200)) { - return snprintf(buf, CPLD_SIZE, "%d\n", -READ_TEMP_FAIL); - } - - return snprintf(buf, CPLD_SIZE, "%d\n", value); - -} - -/* common */ -static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO | S_IWUSR, show_cpld_version, NULL, 0); - -/*0x37 hwmon*/ -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1B); -static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1D); -static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1F); -static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x21); - -/* 0x32 */ -static SENSOR_DEVICE_ATTR(fan_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15); -static SENSOR_DEVICE_ATTR(fan0_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x23); -static SENSOR_DEVICE_ATTR(fan1_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x24); -static SENSOR_DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x25); -static SENSOR_DEVICE_ATTR(fan3_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x26); - -/* 0x37 */ -static SENSOR_DEVICE_ATTR(fan_present, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, NULL, 0x30); -static SENSOR_DEVICE_ATTR(fan_status, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, NULL, 0x31); -static SENSOR_DEVICE_ATTR(psu_status, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, NULL, 0x51); -static SENSOR_DEVICE_ATTR(broad_back_lct, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x2a); -static SENSOR_DEVICE_ATTR(broad_back_sys, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb2); - -/* 0x33 */ -static SENSOR_DEVICE_ATTR(mac_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa0); -static SENSOR_DEVICE_ATTR(broad_front_lct, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x2a); -static SENSOR_DEVICE_ATTR(broad_front_bmc, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb1); -static SENSOR_DEVICE_ATTR(broad_front_cpu, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb2); -static SENSOR_DEVICE_ATTR(broad_front_pwr, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb3); -static SENSOR_DEVICE_ATTR(broad_front_fan, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb4); -static SENSOR_DEVICE_ATTR(sfp_led1_yellow, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xad); -static SENSOR_DEVICE_ATTR(mac_temp_flag, S_IRUGO, show_cpld_sysfs_value, NULL, 0xd4); - -/* 0x34 */ -static SENSOR_DEVICE_ATTR(sfp_presence1, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x30); -static SENSOR_DEVICE_ATTR(sfp_presence2, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x31); -static SENSOR_DEVICE_ATTR(sfp_presence3, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x32); - -static SENSOR_DEVICE_ATTR(sfp_enable, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa1); -static SENSOR_DEVICE_ATTR(sfp_led1, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa2); -static SENSOR_DEVICE_ATTR(sfp_led2, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa3); -static SENSOR_DEVICE_ATTR(sfp_led3, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa4); -static SENSOR_DEVICE_ATTR(sfp_led_flash1, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa5); -static SENSOR_DEVICE_ATTR(sfp_led_flash2, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa6); -static SENSOR_DEVICE_ATTR(sfp_led_flash3, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa7); -static SENSOR_DEVICE_ATTR(sfp_txdis1, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x60); -static SENSOR_DEVICE_ATTR(sfp_txdis2, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x61); -static SENSOR_DEVICE_ATTR(sfp_txdis3, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x62); - -static SENSOR_DEVICE_ATTR(port_speed1, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc0); -static SENSOR_DEVICE_ATTR(port_speed2, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc1); -static SENSOR_DEVICE_ATTR(port_speed3, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc2); -static SENSOR_DEVICE_ATTR(port_speed4, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc3); -static SENSOR_DEVICE_ATTR(port_speed5, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc4); -static SENSOR_DEVICE_ATTR(port_speed6, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc5); - -/* 0x35 */ -static SENSOR_DEVICE_ATTR(sfp_enable2, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa0); -static SENSOR_DEVICE_ATTR(sfp_led2_yellow, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xad); -static SENSOR_DEVICE_ATTR(mac_temp_input, S_IRUGO, show_mac_temp_value, NULL, 0xca); - -/* 0x36 */ -static SENSOR_DEVICE_ATTR(sfp_presence4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x30); -static SENSOR_DEVICE_ATTR(sfp_presence5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x31); -static SENSOR_DEVICE_ATTR(sfp_presence6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x32); -static SENSOR_DEVICE_ATTR(sfp_presence7, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x33); -static SENSOR_DEVICE_ATTR(sfp_led4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa2); -static SENSOR_DEVICE_ATTR(sfp_led5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa3); -static SENSOR_DEVICE_ATTR(sfp_led6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa4); -static SENSOR_DEVICE_ATTR(sfp_led7, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa5); -static SENSOR_DEVICE_ATTR(sfp_led_flash4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa6); -static SENSOR_DEVICE_ATTR(sfp_led_flash5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa7); -static SENSOR_DEVICE_ATTR(sfp_led_flash6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa8); -static SENSOR_DEVICE_ATTR(sfp_led_flash7, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa9); - -static SENSOR_DEVICE_ATTR(sfp_txdis4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x60); -static SENSOR_DEVICE_ATTR(sfp_txdis5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x61); -static SENSOR_DEVICE_ATTR(sfp_txdis6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x62); - -static SENSOR_DEVICE_ATTR(port_speed7, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc0); -static SENSOR_DEVICE_ATTR(port_speed8, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc1); -static SENSOR_DEVICE_ATTR(port_speed9, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc2); -static SENSOR_DEVICE_ATTR(port_speed10, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc3); -static SENSOR_DEVICE_ATTR(port_speed11, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc4); -static SENSOR_DEVICE_ATTR(port_speed12, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc5); -static SENSOR_DEVICE_ATTR(port_speed13, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc6); -static SENSOR_DEVICE_ATTR(port_speed14, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xc7); - -static struct attribute *cpld32_sysfs_attrs[] = { - &sensor_dev_attr_fan_speed_set.dev_attr.attr, - &sensor_dev_attr_fan0_led.dev_attr.attr, - &sensor_dev_attr_fan1_led.dev_attr.attr, - &sensor_dev_attr_fan2_led.dev_attr.attr, - &sensor_dev_attr_fan3_led.dev_attr.attr, - NULL -}; - -static struct attribute *cpld37_sysfs_attrs[] = { - &sensor_dev_attr_fan_present.dev_attr.attr, - &sensor_dev_attr_fan_status.dev_attr.attr, - &sensor_dev_attr_psu_status.dev_attr.attr, - &sensor_dev_attr_broad_back_lct.dev_attr.attr, - &sensor_dev_attr_broad_back_sys.dev_attr.attr, - &sensor_dev_attr_cpld_version.dev_attr.attr, - NULL -}; - -static struct attribute *cpld33_sysfs_attrs[] = { - &sensor_dev_attr_mac_led.dev_attr.attr, - &sensor_dev_attr_broad_front_lct.dev_attr.attr, - &sensor_dev_attr_broad_front_bmc.dev_attr.attr, - &sensor_dev_attr_broad_front_cpu.dev_attr.attr, - &sensor_dev_attr_broad_front_pwr.dev_attr.attr, - &sensor_dev_attr_broad_front_fan.dev_attr.attr, - &sensor_dev_attr_sfp_led1_yellow.dev_attr.attr, - &sensor_dev_attr_mac_temp_flag.dev_attr.attr, - &sensor_dev_attr_cpld_version.dev_attr.attr, - NULL -}; - -static struct attribute *cpld34_sysfs_attrs[] = { - &sensor_dev_attr_sfp_presence1.dev_attr.attr, - &sensor_dev_attr_sfp_presence2.dev_attr.attr, - &sensor_dev_attr_sfp_presence3.dev_attr.attr, - &sensor_dev_attr_sfp_enable.dev_attr.attr, - &sensor_dev_attr_sfp_led1.dev_attr.attr, - &sensor_dev_attr_sfp_led2.dev_attr.attr, - &sensor_dev_attr_sfp_led3.dev_attr.attr, - &sensor_dev_attr_sfp_led_flash1.dev_attr.attr, - &sensor_dev_attr_sfp_led_flash2.dev_attr.attr, - &sensor_dev_attr_sfp_led_flash3.dev_attr.attr, - &sensor_dev_attr_sfp_txdis1.dev_attr.attr, - &sensor_dev_attr_sfp_txdis2.dev_attr.attr, - &sensor_dev_attr_sfp_txdis3.dev_attr.attr, - &sensor_dev_attr_port_speed1.dev_attr.attr, - &sensor_dev_attr_port_speed2.dev_attr.attr, - &sensor_dev_attr_port_speed3.dev_attr.attr, - &sensor_dev_attr_port_speed4.dev_attr.attr, - &sensor_dev_attr_port_speed5.dev_attr.attr, - &sensor_dev_attr_port_speed6.dev_attr.attr, - NULL -}; - -static struct attribute *cpld36_sysfs_attrs[] = { - &sensor_dev_attr_sfp_presence4.dev_attr.attr, - &sensor_dev_attr_sfp_presence5.dev_attr.attr, - &sensor_dev_attr_sfp_presence6.dev_attr.attr, - &sensor_dev_attr_sfp_presence7.dev_attr.attr, - &sensor_dev_attr_sfp_led4.dev_attr.attr, - &sensor_dev_attr_sfp_led5.dev_attr.attr, - &sensor_dev_attr_sfp_led6.dev_attr.attr, - &sensor_dev_attr_sfp_led7.dev_attr.attr, - &sensor_dev_attr_sfp_led_flash4.dev_attr.attr, - &sensor_dev_attr_sfp_led_flash5.dev_attr.attr, - &sensor_dev_attr_sfp_led_flash6.dev_attr.attr, - &sensor_dev_attr_sfp_led_flash7.dev_attr.attr, - &sensor_dev_attr_sfp_txdis4.dev_attr.attr, - &sensor_dev_attr_sfp_txdis5.dev_attr.attr, - &sensor_dev_attr_sfp_txdis6.dev_attr.attr, - &sensor_dev_attr_port_speed7.dev_attr.attr, - &sensor_dev_attr_port_speed8.dev_attr.attr, - &sensor_dev_attr_port_speed9.dev_attr.attr, - &sensor_dev_attr_port_speed10.dev_attr.attr, - &sensor_dev_attr_port_speed11.dev_attr.attr, - &sensor_dev_attr_port_speed12.dev_attr.attr, - &sensor_dev_attr_port_speed13.dev_attr.attr, - &sensor_dev_attr_port_speed14.dev_attr.attr, - NULL -}; - -static struct attribute *cpld35_sysfs_attrs[] = { - &sensor_dev_attr_sfp_enable2.dev_attr.attr, - &sensor_dev_attr_broad_front_lct.dev_attr.attr, - &sensor_dev_attr_broad_front_bmc.dev_attr.attr, - &sensor_dev_attr_broad_front_cpu.dev_attr.attr, - &sensor_dev_attr_broad_front_pwr.dev_attr.attr, - &sensor_dev_attr_broad_front_fan.dev_attr.attr, - &sensor_dev_attr_sfp_led2_yellow.dev_attr.attr, - &sensor_dev_attr_mac_temp_input.dev_attr.attr, - &sensor_dev_attr_cpld_version.dev_attr.attr, - NULL -}; - -static const struct attribute_group cpld32_sysfs_group = { - .attrs = cpld32_sysfs_attrs, -}; - -static const struct attribute_group cpld37_sysfs_group = { - .attrs = cpld37_sysfs_attrs, -}; - -static const struct attribute_group cpld33_sysfs_group = { - .attrs = cpld33_sysfs_attrs, -}; - -static const struct attribute_group cpld34_sysfs_group = { - .attrs = cpld34_sysfs_attrs, -}; - -static const struct attribute_group cpld36_sysfs_group = { - .attrs = cpld36_sysfs_attrs, -}; - -static const struct attribute_group cpld35_sysfs_group = { - .attrs = cpld35_sysfs_attrs, -}; - -static struct attribute *cpld_hwmon_attrs[] = { - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_fan2_input.dev_attr.attr, - &sensor_dev_attr_fan3_input.dev_attr.attr, - &sensor_dev_attr_fan4_input.dev_attr.attr, - NULL -}; -ATTRIBUTE_GROUPS(cpld_hwmon); - -struct cpld_attr_match_group { - int bus_nr; /* I2C BUS */ - unsigned short addr; /* slave addr*/ - const struct attribute_group *attr_group_ptr; - const struct attribute_group *attr_hwmon_ptr; -}; - -static struct cpld_attr_match_group g_cpld_attr_match[] = { - {0, 0x32, &cpld32_sysfs_group, NULL}, - {2, 0x37, &cpld37_sysfs_group, (struct attribute_group *)cpld_hwmon_groups}, - {2, 0x33, &cpld33_sysfs_group, NULL}, - {1, 0x34, &cpld34_sysfs_group, NULL}, - {1, 0x36, &cpld36_sysfs_group, NULL}, - {2, 0x35, &cpld35_sysfs_group, NULL}, -}; - -static const struct attribute_group *cpld_get_attr_group(struct i2c_client *client, int is_hwmon) -{ - int i; - struct cpld_attr_match_group *group; - - for (i = 0; i < ARRAY_SIZE(g_cpld_attr_match); i++) { - group = &g_cpld_attr_match[i]; - DBG_DEBUG("is_hwmon %d i %d client(nr:%d,addr:0x%x), group(nr:%d,addr:0x0%x).\n", is_hwmon, - i, client->adapter->nr, client->addr, group->bus_nr, group->addr); - if ((client->addr == group->addr) && (client->adapter->nr == group->bus_nr)) { - DBG_DEBUG("is_hwmon %d i %d nr %d addr %d .\n", is_hwmon, i, client->adapter->nr, client->addr); - return (is_hwmon) ? (group->attr_hwmon_ptr) : (group->attr_group_ptr); - } - } - - DBG_DEBUG("is_hwmon %d nr %d addr %d dismatch, return NULL.\n", is_hwmon, client->adapter->nr, client->addr); - return NULL; -} - -static int cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct cpld_data *data; - int status; - const struct attribute_group *sysfs_group, *hwmon_group; - - status = -1; - DBG_DEBUG("=========cpld_probe(addr:0x%x, nr:%d)===========\n", client->addr, client->adapter->nr); - data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), GFP_KERNEL); - if (!data) { - return -ENOMEM; - } - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - sysfs_group = NULL; - sysfs_group = cpld_get_attr_group(client, 0); - if (sysfs_group) { - status = sysfs_create_group(&client->dev.kobj, sysfs_group); - DBG_DEBUG("=========(addr:0x%x, nr:%d) sysfs_create_group status %d===========\n", client->addr, client->adapter->nr, status); - if (status != 0) { - DBG_ERROR("sysfs_create_group status %d.\n", status); - goto error; - } - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no sysfs_create_group \n", client->addr, client->adapter->nr); - } - - hwmon_group = NULL; - hwmon_group = cpld_get_attr_group(client, 1); - if (hwmon_group) { - data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, (const struct attribute_group **)hwmon_group); - if (IS_ERR(data->hwmon_dev)) { - sysfs_remove_group(&client->dev.kobj, (const struct attribute_group *)sysfs_group); - DBG_ERROR("hwmon_device_register_with_groups failed ret %ld.\n", PTR_ERR(data->hwmon_dev)); - return PTR_ERR(data->hwmon_dev); - } - DBG_DEBUG("=========(addr:0x%x, nr:%d) hwmon_device_register_with_groups success===========\n", client->addr, client->adapter->nr); - if (status != 0) { - DBG_ERROR("sysfs_create_group status %d.\n", status); - goto error; - } - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no hwmon_device_register_with_groups \n", client->addr, client->adapter->nr); - } - -error: - return status; - -} - -static int cpld_remove(struct i2c_client *client) -{ - struct cpld_data *data = i2c_get_clientdata(client); - const struct attribute_group *sysfs_group, *hwmon_group; - - DBG_DEBUG("=========cpld_remove(addr:0x%x, nr:%d)===========\n", client->addr, client->adapter->nr); - - sysfs_group = NULL; - sysfs_group = cpld_get_attr_group(client, 0); - if (sysfs_group) { - DBG_DEBUG("=========(addr:0x%x, nr:%d) do sysfs_remove_group \n", client->addr, client->adapter->nr); - sysfs_remove_group(&client->dev.kobj, (const struct attribute_group *)sysfs_group); - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no sysfs_remove_group \n", client->addr, client->adapter->nr); - } - - hwmon_group = NULL; - hwmon_group = cpld_get_attr_group(client, 1); - if (hwmon_group) { - DBG_DEBUG("=========(addr:0x%x, nr:%d) do hwmon_device_unregister \n", client->addr, client->adapter->nr); - hwmon_device_unregister(data->hwmon_dev); - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no hwmon_device_unregister \n", client->addr, client->adapter->nr); - } - - return 0; -} - - -static const struct i2c_device_id cpld_id[] = { - { "rg_cpld", 0 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, cpld_id); - -static struct i2c_driver rg_cpld_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "rg_cpld", - }, - .probe = cpld_probe, - .remove = cpld_remove, - .id_table = cpld_id, -}; - -module_i2c_driver(rg_cpld_driver); - -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("ragile CPLD driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_firmware_upgrade_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_firmware_upgrade_device.c new file mode 100644 index 000000000000..5fcaa8da1963 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_firmware_upgrade_device.c @@ -0,0 +1,178 @@ +/* + * wb_firmware_upgrade.c + * Original Author: support 2021-03-17 + * + * ko for firmware device + * History + * [Version] [Author] [Date] [Description] + * v1.0 support 2021-05-07 Initial version + */ +#include +#include +#include +#include +#include +#include + +static int g_wb_firmware_upgrade_debug = 0; +static int g_wb_firmware_upgrade_error = 0; + +module_param(g_wb_firmware_upgrade_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_firmware_upgrade_error, int, S_IRUGO | S_IWUSR); + +#define WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_firmware_upgrade_debug) { \ + printk(KERN_INFO "[WB_FIRMWARE_UPGRADE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FIRMWARE_UPGRADE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_firmware_upgrade_error) { \ + printk(KERN_ERR "[WB_FIRMWARE_UPGRADE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 48, + .en_level[1] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* fpga */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "SPI_LOGIC", + .chain = 3, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x1A0000, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "SPI_LOGIC", + .chain = 4, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x0, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* bios */ +static firmware_upgrade_device_t firmware_upgrade_device_data3 = { + .type = "MTD_DEV", + .chain = 2, + .chip_index = 1, + .upg_type.sysfs = { + .mtd_name = "BIOS", + .flash_base = 0x800000, + }, + + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 4, + .dev = { + .platform_data = &firmware_upgrade_device_data3, + .release = firmware_device_release, + }, + }, + }; + + static int __init firmware_upgrade_device_init(void) + { + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; + } + + static void __exit firmware_upgrade_device_exit(void) + { + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&firmware_upgrade_device[i]); + } + } + } + + module_init(firmware_upgrade_device_init); + module_exit(firmware_upgrade_device_exit); + MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_dev_device.c new file mode 100644 index 000000000000..865e7afea44c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_dev_device.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_dev_device_debug = 0; +static int g_wb_i2c_dev_device_error = 0; + +module_param(g_wb_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_dev_device_t i2c_dev_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x0d, + .i2c_name = "cpld2", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data1 = { + .i2c_bus = 8, + .i2c_addr = 0x30, + .i2c_name = "cpld3", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data2 = { + .i2c_bus = 8, + .i2c_addr = 0x31, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data3 = { + .i2c_bus = 6, + .i2c_addr = 0x0d, + .i2c_name = "cpld5", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +struct i2c_board_info i2c_dev_device_info[] = { + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data0, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data1, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data2, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data3, + }, +}; + +static int __init wb_i2c_dev_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_dev_device_info); i++) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + i2c_dev_device_info[i].addr = i2c_dev_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_dev_device_data->i2c_bus); + if (adap == NULL) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_dev_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); + if (!client) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", + i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); + } else { + i2c_dev_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_dev_device_exit(void) +{ + int i; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_dev_device_info) - 1; i >= 0; i--) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + if (i2c_dev_device_data->client) { + i2c_unregister_device(i2c_dev_device_data->client); + i2c_dev_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_dev_device_init); +module_exit(wb_i2c_dev_device_exit); +MODULE_DESCRIPTION("I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 000000000000..f12a71013451 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,296 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca954x_device_debug = 0; +static int g_wb_i2c_mux_pca954x_device_error = 0; + +module_param(g_wb_i2c_mux_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 16, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/cpld5", + .file_attr.offset = 0x60, + .file_attr.mask = 0x02, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data1 = { + .i2c_bus = 4, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 24, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/cpld5", + .file_attr.offset = 0x60, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data2 = { + .i2c_bus = 12, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 32, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data3 = { + .i2c_bus = 12, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 40, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data4 = { + .i2c_bus = 12, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 48, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data5 = { + .i2c_bus = 12, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 56, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data6 = { + .i2c_bus = 13, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 64, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data7 = { + .i2c_bus = 13, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 72, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data8 = { + .i2c_bus = 13, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 80, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/fpga0", + .file_attr.offset = 0x20, + .file_attr.mask = 0x01, + .file_attr.reset_on = 0x00, + .file_attr.reset_off = 0x01, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data1, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data2, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data3, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data4, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data5, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data6, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data7, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data8, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (!client) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_ocores_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_ocores_device.c new file mode 100644 index 000000000000..ff7ba9d26fbc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_i2c_ocores_device.c @@ -0,0 +1,423 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_ocores_device_debug = 0; +static int g_wb_i2c_ocores_device_error = 0; + +module_param(g_wb_i2c_ocores_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_ocores_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_debug) { \ + printk(KERN_INFO "[WB_I2C_OCORE_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_OCORE_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_error) { \ + printk(KERN_ERR "[WB_I2C_OCORE_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_ocores_device_t i2c_ocores_device_data0 = { + .adap_nr = 2, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0800, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 0, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data1 = { + .adap_nr = 3, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0820, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 1, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data2 = { + .adap_nr = 4, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0840, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 2, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data3 = { + .adap_nr = 5, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0860, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 3, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data4 = { + .adap_nr = 6, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0880, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 4, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data5 = { + .adap_nr = 7, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08a0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 5, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data6 = { + .adap_nr = 8, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08c0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 6, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data7 = { + .adap_nr = 9, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x08e0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 7, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data8 = { + .adap_nr = 10, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0900, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 8, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data9 = { + .adap_nr = 11, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0920, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 9, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data10 = { + .adap_nr = 12, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0940, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 10, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data11 = { + .adap_nr = 13, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0960, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 11, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data12 = { + .adap_nr = 14, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x0980, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 12, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data13 = { + .adap_nr = 15, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x09a0, + .reg_shift = 2, + .reg_io_width = 4, + .ip_clock_khz = 125000, + .bus_clock_khz = 100, + .irq_offset = 13, + .pci_domain = 0, + .pci_bus = 8, + .pci_slot = 0, + .pci_fn = 0, +}; + +static void wb_i2c_ocores_device_release(struct device *dev) +{ + return; +} + +static struct platform_device i2c_ocores_device[] = { + { + .name = "wb-ocores-i2c", + .id = 1, + .dev = { + .platform_data = &i2c_ocores_device_data0, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 2, + .dev = { + .platform_data = &i2c_ocores_device_data1, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 3, + .dev = { + .platform_data = &i2c_ocores_device_data2, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 4, + .dev = { + .platform_data = &i2c_ocores_device_data3, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 5, + .dev = { + .platform_data = &i2c_ocores_device_data4, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 6, + .dev = { + .platform_data = &i2c_ocores_device_data5, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 7, + .dev = { + .platform_data = &i2c_ocores_device_data6, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 8, + .dev = { + .platform_data = &i2c_ocores_device_data7, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 9, + .dev = { + .platform_data = &i2c_ocores_device_data8, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 10, + .dev = { + .platform_data = &i2c_ocores_device_data9, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 11, + .dev = { + .platform_data = &i2c_ocores_device_data10, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 12, + .dev = { + .platform_data = &i2c_ocores_device_data11, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 13, + .dev = { + .platform_data = &i2c_ocores_device_data12, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 14, + .dev = { + .platform_data = &i2c_ocores_device_data13, + .release = wb_i2c_ocores_device_release, + }, + }, +}; + +static int __init wb_i2c_ocores_device_init(void) +{ + int i; + int ret = 0; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_ocores_device); i++) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + ret = platform_device_register(&i2c_ocores_device[i]); + if (ret < 0) { + i2c_ocores_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-ocores-i2c.%d register failed!\n", i + 1); + } else { + i2c_ocores_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_i2c_ocores_device_exit(void) +{ + int i; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_ocores_device) - 1; i >= 0; i--) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + if (i2c_ocores_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&i2c_ocores_device[i]); + } + } +} + +module_init(wb_i2c_ocores_device_init); +module_exit(wb_i2c_ocores_device_exit); +MODULE_DESCRIPTION("I2C OCORES Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..cc84938fff0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_io_dev_device.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data1 = { + .io_dev_name = "cpld1", + .io_base = 0x900, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 2, + .dev = { + .platform_data = &io_dev_device_data1, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..9b6b61a51735 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static lpc_drv_device_t lpc_drv_device_data_1 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x900, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x88, +}; + +static lpc_drv_device_t lpc_drv_device_data_2 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0xb00, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x90, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 2, + .dev = { + .platform_data = &lpc_drv_device_data_1, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 3, + .dev = { + .platform_data = &lpc_drv_device_data_2, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_pcie_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_pcie_dev_device.c new file mode 100644 index 000000000000..f79b29770d29 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/modules/driver/wb_pcie_dev_device.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_pcie_dev_device_debug = 0; +static int g_wb_pcie_dev_device_error = 0; + +module_param(g_wb_pcie_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_pcie_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_pcie_dev_device_debug) { \ + printk(KERN_INFO "[WB_PCIE_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PCIE_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_pcie_dev_device_error) { \ + printk(KERN_ERR "[WB_PCIE_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static pci_dev_device_t pcie_dev_device_data0 = { + .pci_dev_name = "fpga0", + .pci_domain = 0x0000, + .pci_bus = 0x08, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .upg_ctrl_base = 0xa00, + .upg_flash_base = 0x1a0000, +}; + +static void wb_pcie_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device pcie_dev_device[] = { + { + .name = "wb-pci-dev", + .id = 1, + .dev = { + .platform_data = &pcie_dev_device_data0, + .release = wb_pcie_dev_device_release, + }, + }, +}; + +static int __init wb_pcie_dev_device_init(void) +{ + int i; + int ret = 0; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(pcie_dev_device); i++) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + ret = platform_device_register(&pcie_dev_device[i]); + if (ret < 0) { + pcie_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-pci-dev.%d register failed!\n", i + 1); + } else { + pcie_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_pcie_dev_device_exit(void) +{ + int i; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(pcie_dev_device) - 1; i >= 0; i--) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + if (pcie_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&pcie_dev_device[i]); + } + } +} + +module_init(wb_pcie_dev_device_init); +module_exit(wb_pcie_dev_device_exit); +MODULE_DESCRIPTION("PCIE DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..98d1da1750c3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,41 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_0_2=2 +cpld_i2c_dev.addr_0_2=0x0d +cpld_i2c_dev.bus_0_3=8 +cpld_i2c_dev.addr_0_3=0x30 +cpld_i2c_dev.bus_0_4=8 +cpld_i2c_dev.addr_0_4=0x31 +cpld_i2c_dev.bus_0_5=6 +cpld_i2c_dev.addr_0_5=0x0d + + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_0=0x700 +cpld_lpc_dev_0_1=0x900 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=lpc +mode_cpld_0_1=lpc +mode_cpld_0_2=i2c +mode_cpld_0_3=i2c +mode_cpld_0_4=i2c +mode_cpld_0_5=i2c + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=6 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..2350b74eb8bc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,304 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=4 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=2 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x00020030 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x00020030 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=1 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x00020030 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=2 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=cpld +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.addr_1_4=0x00020030 +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=3 + + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x00020031 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=0 + +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=cpld +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1= +fan_roll_status.addr_1_1=0x00020034 +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=0 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x00020031 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=1 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=cpld +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1= +fan_roll_status.addr_2_1=0x00020034 +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=1 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x00020031 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=2 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=cpld +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1= +fan_roll_status.addr_3_1=0x00020034 +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=2 + +fan_roll_status.mode_4_0=config +fan_roll_status.int_cons_4_0= +fan_roll_status.src_4_0=cpld +fan_roll_status.frmt_4_0=bit +fan_roll_status.pola_4_0=positive +fan_roll_status.fpath_4_0= +fan_roll_status.addr_4_0=0x00020031 +fan_roll_status.len_4_0=1 +fan_roll_status.bit_offset_4_0=3 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=cpld +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1= +fan_roll_status.addr_4_1=0x00020034 +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=3 + + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x0002001b +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=cpld +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1=negative +fan_speed.fpath_1_1= +fan_speed.addr_1_1=0x00020025 +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0002001d +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=cpld +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1=negative +fan_speed.fpath_2_1= +fan_speed.addr_2_1=0x00020027 +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0002001f +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=cpld +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1=negative +fan_speed.fpath_3_1= +fan_speed.addr_3_1=0x00020029 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_4_0=config +fan_speed.int_cons_4_0= +fan_speed.src_4_0=cpld +fan_speed.frmt_4_0=num_bytes +fan_speed.pola_4_0=negative +fan_speed.fpath_4_0= +fan_speed.addr_4_0=0x00020021 +fan_speed.len_4_0=2 +fan_speed.bit_offset_4_0= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=cpld +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1=negative +fan_speed.fpath_4_1= +fan_speed.addr_4_1=0x0002002b +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x00020014 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_1_1=config +fan_ratio.int_cons_1_1= +fan_ratio.src_1_1=cpld +fan_ratio.frmt_1_1=byte +fan_ratio.pola_1_1= +fan_ratio.fpath_1_1= +fan_ratio.addr_1_1=0x00020014 +fan_ratio.len_1_1=1 +fan_ratio.bit_offset_1_1= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x00020015 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_2_1=config +fan_ratio.int_cons_2_1= +fan_ratio.src_2_1=cpld +fan_ratio.frmt_2_1=byte +fan_ratio.pola_2_1= +fan_ratio.fpath_2_1= +fan_ratio.addr_2_1=0x00020015 +fan_ratio.len_2_1=1 +fan_ratio.bit_offset_2_1= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x00020016 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= + +fan_ratio.mode_3_1=config +fan_ratio.int_cons_3_1= +fan_ratio.src_3_1=cpld +fan_ratio.frmt_3_1=byte +fan_ratio.pola_3_1= +fan_ratio.fpath_3_1= +fan_ratio.addr_3_1=0x00020016 +fan_ratio.len_3_1=1 +fan_ratio.bit_offset_3_1= + +fan_ratio.mode_4_0=config +fan_ratio.int_cons_4_0= +fan_ratio.src_4_0=cpld +fan_ratio.frmt_4_0=byte +fan_ratio.pola_4_0= +fan_ratio.fpath_4_0= +fan_ratio.addr_4_0=0x00020017 +fan_ratio.len_4_0=1 +fan_ratio.bit_offset_4_0= + +fan_ratio.mode_4_1=config +fan_ratio.int_cons_4_1= +fan_ratio.src_4_1=cpld +fan_ratio.frmt_4_1=byte +fan_ratio.pola_4_1= +fan_ratio.fpath_4_1= +fan_ratio.addr_4_1=0x00020017 +fan_ratio.len_4_1=1 +fan_ratio.bit_offset_4_1= diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..082ef20fe97f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,64 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=2 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00050051 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00050051 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00050051 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00050051 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=4 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00050051 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=5 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00050051 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=6 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..7f57dfd93c5b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,521 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=56 + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 +sff_dir_name_33 =sff33 +sff_dir_name_34 =sff34 +sff_dir_name_35 =sff35 +sff_dir_name_36 =sff36 +sff_dir_name_37 =sff37 +sff_dir_name_38 =sff38 +sff_dir_name_39 =sff39 +sff_dir_name_40 =sff40 +sff_dir_name_41 =sff41 +sff_dir_name_42 =sff42 +sff_dir_name_43 =sff43 +sff_dir_name_44 =sff44 +sff_dir_name_45 =sff45 +sff_dir_name_46 =sff46 +sff_dir_name_47 =sff47 +sff_dir_name_48 =sff48 +sff_dir_name_49 =sff49 +sff_dir_name_50 =sff50 +sff_dir_name_51 =sff51 +sff_dir_name_52 =sff52 +sff_dir_name_53 =sff53 +sff_dir_name_54 =sff54 +sff_dir_name_55 =sff55 +sff_dir_name_56 =sff56 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x00030030 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x00030030 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x00030030 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x00030030 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x00030030 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x00030030 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x00030030 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x00030030 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x00030031 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x00030031 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x00030031 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x00030031 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x00030031 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x00030031 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x00030031 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x00030031 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x00030032 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x00030032 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x00030032 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x00030032 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x00030032 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x00030032 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x00030032 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x00030032 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x00040030 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x00040030 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x00040030 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x00040030 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x00040030 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x00040030 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x00040030 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x00040030 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +sff_cpld_reg.mode_33_8=config +sff_cpld_reg.src_33_8=cpld +sff_cpld_reg.frmt_33_8=bit +sff_cpld_reg.pola_33_8=negative +sff_cpld_reg.addr_33_8=0x00040031 +sff_cpld_reg.len_33_8=1 +sff_cpld_reg.bit_offset_33_8=0 + +sff_cpld_reg.mode_34_8=config +sff_cpld_reg.src_34_8=cpld +sff_cpld_reg.frmt_34_8=bit +sff_cpld_reg.pola_34_8=negative +sff_cpld_reg.addr_34_8=0x00040031 +sff_cpld_reg.len_34_8=1 +sff_cpld_reg.bit_offset_34_8=1 + +sff_cpld_reg.mode_35_8=config +sff_cpld_reg.src_35_8=cpld +sff_cpld_reg.frmt_35_8=bit +sff_cpld_reg.pola_35_8=negative +sff_cpld_reg.addr_35_8=0x00040031 +sff_cpld_reg.len_35_8=1 +sff_cpld_reg.bit_offset_35_8=2 + +sff_cpld_reg.mode_36_8=config +sff_cpld_reg.src_36_8=cpld +sff_cpld_reg.frmt_36_8=bit +sff_cpld_reg.pola_36_8=negative +sff_cpld_reg.addr_36_8=0x00040031 +sff_cpld_reg.len_36_8=1 +sff_cpld_reg.bit_offset_36_8=3 + +sff_cpld_reg.mode_37_8=config +sff_cpld_reg.src_37_8=cpld +sff_cpld_reg.frmt_37_8=bit +sff_cpld_reg.pola_37_8=negative +sff_cpld_reg.addr_37_8=0x00040031 +sff_cpld_reg.len_37_8=1 +sff_cpld_reg.bit_offset_37_8=4 + +sff_cpld_reg.mode_38_8=config +sff_cpld_reg.src_38_8=cpld +sff_cpld_reg.frmt_38_8=bit +sff_cpld_reg.pola_38_8=negative +sff_cpld_reg.addr_38_8=0x00040031 +sff_cpld_reg.len_38_8=1 +sff_cpld_reg.bit_offset_38_8=5 + +sff_cpld_reg.mode_39_8=config +sff_cpld_reg.src_39_8=cpld +sff_cpld_reg.frmt_39_8=bit +sff_cpld_reg.pola_39_8=negative +sff_cpld_reg.addr_39_8=0x00040031 +sff_cpld_reg.len_39_8=1 +sff_cpld_reg.bit_offset_39_8=6 + +sff_cpld_reg.mode_40_8=config +sff_cpld_reg.src_40_8=cpld +sff_cpld_reg.frmt_40_8=bit +sff_cpld_reg.pola_40_8=negative +sff_cpld_reg.addr_40_8=0x00040031 +sff_cpld_reg.len_40_8=1 +sff_cpld_reg.bit_offset_40_8=7 + +sff_cpld_reg.mode_41_8=config +sff_cpld_reg.src_41_8=cpld +sff_cpld_reg.frmt_41_8=bit +sff_cpld_reg.pola_41_8=negative +sff_cpld_reg.addr_41_8=0x00040032 +sff_cpld_reg.len_41_8=1 +sff_cpld_reg.bit_offset_41_8=0 + +sff_cpld_reg.mode_42_8=config +sff_cpld_reg.src_42_8=cpld +sff_cpld_reg.frmt_42_8=bit +sff_cpld_reg.pola_42_8=negative +sff_cpld_reg.addr_42_8=0x00040032 +sff_cpld_reg.len_42_8=1 +sff_cpld_reg.bit_offset_42_8=1 + +sff_cpld_reg.mode_43_8=config +sff_cpld_reg.src_43_8=cpld +sff_cpld_reg.frmt_43_8=bit +sff_cpld_reg.pola_43_8=negative +sff_cpld_reg.addr_43_8=0x00040032 +sff_cpld_reg.len_43_8=1 +sff_cpld_reg.bit_offset_43_8=2 + +sff_cpld_reg.mode_44_8=config +sff_cpld_reg.src_44_8=cpld +sff_cpld_reg.frmt_44_8=bit +sff_cpld_reg.pola_44_8=negative +sff_cpld_reg.addr_44_8=0x00040032 +sff_cpld_reg.len_44_8=1 +sff_cpld_reg.bit_offset_44_8=3 + +sff_cpld_reg.mode_45_8=config +sff_cpld_reg.src_45_8=cpld +sff_cpld_reg.frmt_45_8=bit +sff_cpld_reg.pola_45_8=negative +sff_cpld_reg.addr_45_8=0x00040032 +sff_cpld_reg.len_45_8=1 +sff_cpld_reg.bit_offset_45_8=4 + +sff_cpld_reg.mode_46_8=config +sff_cpld_reg.src_46_8=cpld +sff_cpld_reg.frmt_46_8=bit +sff_cpld_reg.pola_46_8=negative +sff_cpld_reg.addr_46_8=0x00040032 +sff_cpld_reg.len_46_8=1 +sff_cpld_reg.bit_offset_46_8=5 + +sff_cpld_reg.mode_47_8=config +sff_cpld_reg.src_47_8=cpld +sff_cpld_reg.frmt_47_8=bit +sff_cpld_reg.pola_47_8=negative +sff_cpld_reg.addr_47_8=0x00040032 +sff_cpld_reg.len_47_8=1 +sff_cpld_reg.bit_offset_47_8=6 + +sff_cpld_reg.mode_48_8=config +sff_cpld_reg.src_48_8=cpld +sff_cpld_reg.frmt_48_8=bit +sff_cpld_reg.pola_48_8=negative +sff_cpld_reg.addr_48_8=0x00040032 +sff_cpld_reg.len_48_8=1 +sff_cpld_reg.bit_offset_48_8=7 + +sff_cpld_reg.mode_49_8=config +sff_cpld_reg.src_49_8=cpld +sff_cpld_reg.frmt_49_8=bit +sff_cpld_reg.pola_49_8=negative +sff_cpld_reg.addr_49_8=0x00040033 +sff_cpld_reg.len_49_8=1 +sff_cpld_reg.bit_offset_49_8=0 + +sff_cpld_reg.mode_50_8=config +sff_cpld_reg.src_50_8=cpld +sff_cpld_reg.frmt_50_8=bit +sff_cpld_reg.pola_50_8=negative +sff_cpld_reg.addr_50_8=0x00040033 +sff_cpld_reg.len_50_8=1 +sff_cpld_reg.bit_offset_50_8=1 + +sff_cpld_reg.mode_51_8=config +sff_cpld_reg.src_51_8=cpld +sff_cpld_reg.frmt_51_8=bit +sff_cpld_reg.pola_51_8=negative +sff_cpld_reg.addr_51_8=0x00040033 +sff_cpld_reg.len_51_8=1 +sff_cpld_reg.bit_offset_51_8=2 + +sff_cpld_reg.mode_52_8=config +sff_cpld_reg.src_52_8=cpld +sff_cpld_reg.frmt_52_8=bit +sff_cpld_reg.pola_52_8=negative +sff_cpld_reg.addr_52_8=0x00040033 +sff_cpld_reg.len_52_8=1 +sff_cpld_reg.bit_offset_52_8=3 + +sff_cpld_reg.mode_53_8=config +sff_cpld_reg.src_53_8=cpld +sff_cpld_reg.frmt_53_8=bit +sff_cpld_reg.pola_53_8=negative +sff_cpld_reg.addr_53_8=0x00040033 +sff_cpld_reg.len_53_8=1 +sff_cpld_reg.bit_offset_53_8=4 + +sff_cpld_reg.mode_54_8=config +sff_cpld_reg.src_54_8=cpld +sff_cpld_reg.frmt_54_8=bit +sff_cpld_reg.pola_54_8=negative +sff_cpld_reg.addr_54_8=0x00040033 +sff_cpld_reg.len_54_8=1 +sff_cpld_reg.bit_offset_54_8=5 + +sff_cpld_reg.mode_55_8=config +sff_cpld_reg.src_55_8=cpld +sff_cpld_reg.frmt_55_8=bit +sff_cpld_reg.pola_55_8=negative +sff_cpld_reg.addr_55_8=0x00040033 +sff_cpld_reg.len_55_8=1 +sff_cpld_reg.bit_offset_55_8=6 + +sff_cpld_reg.mode_56_8=config +sff_cpld_reg.src_56_8=cpld +sff_cpld_reg.frmt_56_8=bit +sff_cpld_reg.pola_56_8=negative +sff_cpld_reg.addr_56_8=0x00040033 +sff_cpld_reg.len_56_8=1 +sff_cpld_reg.bit_offset_56_8=7 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/cfg_file_name new file mode 100644 index 000000000000..5f49420441a5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,4 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/scripts/pddf_post_driver_install.sh b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/scripts/pddf_post_driver_install.sh deleted file mode 100755 index badbce25589d..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/scripts/pddf_post_driver_install.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -count=10 -while [ $count -gt 0 ] -do - lsmod | grep 9641 >/dev/null 2>&1 - if [ $? -eq 0 ] - then - break - fi - count=$(( count - 1 )) - sleep 1 -done - -if [ $count -eq 0 ] -then - # mod not loaded - exit 1 -fi - -if [ ! -d "/sys/bus/i2c/devices/i2c-2" ] -then - echo pca9541 0x10 > /sys/bus/i2c/devices/i2c-0/new_device - if [ $? -ne 0 ] - then - exit $? - fi -fi - -exit 0 - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/setup.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/setup.py index f36055fb4e6d..6c3916921abb 100644 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/setup.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/setup.py @@ -3,18 +3,25 @@ setup( name='sonic-platform', version='1.0', - description='SONiC platform API implementation on RAGILE Platforms', + description='SONiC platform API implementation', license='Apache 2.0', author='SONiC Team', - author_email='support@ragile.com', + author_email='support', url='', - maintainer='RAGILE SUPPORT TEAM', + maintainer='support', maintainer_email='', packages=[ 'sonic_platform', - 'rgutil', + 'plat_hal', + 'wbutil', 'eepromutil', - 'sonic_pcie', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', ], classifiers=[ 'Development Status :: 3 - Alpha', @@ -30,4 +37,3 @@ ], keywords='sonic SONiC platform PLATFORM', ) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_pcie/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_pcie/__init__.py deleted file mode 100644 index 73e2a89c8d74..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_pcie/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["pcie_common"] \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_pcie/pcie_common.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_pcie/pcie_common.py deleted file mode 100644 index 56e9d8664a23..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_pcie/pcie_common.py +++ /dev/null @@ -1,107 +0,0 @@ -# pcie_common.py -# Common PCIE check interfaces for SONIC -# - -import os -import yaml -import subprocess -import re -import sys -from copy import deepcopy -try: - from .pcie import PcieBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class PcieUtil(PcieBase): - """Platform-specific PCIEutil class""" - # got the config file path - def __init__(self, path): - self.config_path = path - - # load the config file - def load_config_file(self): - config_file = self.config_path + "/" + "pcie.yaml" - try: - with open(config_file) as conf_file: - self.confInfo = yaml.load(conf_file) - except IOError as e: - print("Error: {}".format(str(e))) - print("Not found config file, please add a config file manually, or generate it by running [pcieutil pcie_generate]") - sys.exit() - - # load current PCIe device - def get_pcie_device(self): - pciDict = {} - pciList = [] - p1 = "^(\w+):(\w+)\.(\w)\s(.*)\s*\(*.*\)*" - p2 = "^.*:.*:.*:(\w+)\s*\(*.*\)*" - command1 = "sudo lspci" - command2 = "sudo lspci -n" - # run command 1 - proc1 = subprocess.Popen(command1, shell=True, universal_newlines=True, stdout=subprocess.PIPE) - output1 = proc1.stdout.readlines() - proc1.communicate() - # run command 2 - proc2 = subprocess.Popen(command2, shell=True, universal_newlines=True, stdout=subprocess.PIPE) - output2 = proc2.stdout.readlines() - proc2.communicate() - - if proc1.returncode > 0: - for line1 in output1: - print(line1.strip()) - return - elif proc2.returncode > 0: - for line2 in output2: - print(line2.strip()) - return - else: - for (line1, line2) in zip(output1, output2): - pciDict.clear() - match1 = re.search(p1, line1.strip()) - match2 = re.search(p2, line2.strip()) - if match1 and match2: - Bus = match1.group(1) - Dev = match1.group(2) - Fn = match1.group(3) - Name = match1.group(4) - Id = match2.group(1) - pciDict["name"] = Name - pciDict["bus"] = Bus - pciDict["dev"] = Dev - pciDict["fn"] = Fn - pciDict["id"] = Id - pciList.append(pciDict) - pciDict = deepcopy(pciDict) - else: - print("CAN NOT MATCH PCIe DEVICE") - return pciList - - # check the sysfs tree for each PCIe device - def check_pcie_sysfs(self, domain=0, bus=0, device=0, func=0): - dev_path = os.path.join('/sys/bus/pci/devices', '%04x:%02x:%02x.%d' % (domain, bus, device, func)) - if os.path.exists(dev_path): - return True - return False - - # check the current PCIe device with config file and return the result - def get_pcie_check(self): - self.load_config_file() - for item_conf in self.confInfo: - bus_conf = item_conf["bus"] - dev_conf = item_conf["dev"] - fn_conf = item_conf["fn"] - if self.check_pcie_sysfs(bus=int(bus_conf, base=16), device=int(dev_conf, base=16), func=int(fn_conf, base=16)): - item_conf["result"] = "Passed" - else: - item_conf["result"] = "Failed" - return self.confInfo - - # generate the config file with current pci device - def dump_conf_yaml(self): - curInfo = self.get_pcie_device() - with open(self.config_path + "/" + "pcie.yaml", "w") as conf_file: - yaml.dump(curInfo, conf_file, default_flow_style=False) - return - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/__init__.py deleted file mode 100644 index 593867d31c9d..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# All the derived classes for PDDF -__all__ = ["platform", "chassis", "sfp", "psu", "thermal", "fan"] -from . import platform - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/chassis.py deleted file mode 100644 index 4783c96b1801..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/chassis.py +++ /dev/null @@ -1,135 +0,0 @@ -############################################################################# -# PDDF -# Module contains an implementation of SONiC Chassis API -# -############################################################################# - -try: - import time - import subprocess - from sonic_platform_pddf_base.pddf_chassis import PddfChassis - from rgutil.logutil import Logger -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -PORT_START = 0 -PORT_END = 55 -PORTS_IN_BLOCK = 56 - -logger = Logger("CHASSIS", syslog=True) - -class Chassis(PddfChassis): - """ - PDDF Platform-specific Chassis class - """ - - SFP_STATUS_INSERTED = "1" - SFP_STATUS_REMOVED = "0" - port_dict = {} - - def __init__(self, pddf_data=None, pddf_plugin_data=None): - PddfChassis.__init__(self, pddf_data, pddf_plugin_data) - - self.enable_read = "i2cset -f -y 2 0x35 0x2a 0x01" - self.disable_read = "i2cset -f -y 2 0x35 0x2a 0x00" - self.enable_write = "i2cset -f -y 2 0x35 0x2b 0x00" - self.disable_write = "i2cset -f -y 2 0x35 0x2b 0x01" - self.enable_erase = "i2cset -f -y 2 0x35 0x2c 0x01" - self.disable_erase = "i2cset -f -y 2 0x35 0x2c 0x00" - self.read_value = "i2cget -f -y 2 0x35 0x25" - self.write_value = "i2cset -f -y 2 0x35 0x21 0x0a" - - 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. - """ - try: - is_power_loss = False - # enable read - subprocess.getstatusoutput(self.disable_write) - subprocess.getstatusoutput(self.enable_read) - ret, log = subprocess.getstatusoutput(self.read_value) - if ret == 0 and "0x0a" in log: - is_power_loss = True - - # erase i2c and e2 - subprocess.getstatusoutput(self.enable_erase) - time.sleep(1) - subprocess.getstatusoutput(self.disable_erase) - # clear data - subprocess.getstatusoutput(self.enable_write) - subprocess.getstatusoutput(self.disable_read) - subprocess.getstatusoutput(self.disable_write) - subprocess.getstatusoutput(self.enable_read) - # enable write and set data - subprocess.getstatusoutput(self.enable_write) - subprocess.getstatusoutput(self.disable_read) - subprocess.getstatusoutput(self.write_value) - if is_power_loss: - return(self.REBOOT_CAUSE_POWER_LOSS, None) - except Exception as e: - logger.error(str(e)) - - return (self.REBOOT_CAUSE_NON_HARDWARE, None) - - def get_change_event(self, timeout=0): - change_event_dict = {"fan": {}, "sfp": {}} - sfp_status, sfp_change_dict = self.get_transceiver_change_event(timeout) - change_event_dict["sfp"] = sfp_change_dict - if sfp_status is True: - return True, change_event_dict - - return False, {} - - def get_transceiver_change_event(self, timeout=0): - start_time = time.time() - currernt_port_dict = {} - forever = False - - if timeout == 0: - forever = True - elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs - else: - print("get_transceiver_change_event:Invalid timeout value", timeout) - return False, {} - - end_time = start_time + timeout - if start_time > end_time: - print( - "get_transceiver_change_event:" "time wrap / invalid timeout value", - timeout, - ) - return False, {} # Time wrap or possibly incorrect timeout - - while timeout >= 0: - # Check for OIR events and return updated port_dict - for index in range(PORT_START, PORTS_IN_BLOCK): - if self._sfp_list[index].get_presence(): - currernt_port_dict[index] = self.SFP_STATUS_INSERTED - else: - currernt_port_dict[index] = self.SFP_STATUS_REMOVED - if currernt_port_dict == self.port_dict: - if forever: - time.sleep(1) - else: - timeout = end_time - time.time() - if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity - else: - if timeout > 0: - time.sleep(timeout) - return True, {} - else: - # Update reg value - self.port_dict = currernt_port_dict - print(self.port_dict) - return True, self.port_dict - print("get_transceiver_change_event: Should not reach here.") - return False, {} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/common.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/common.py deleted file mode 100644 index c1a85f618609..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/common.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -import yaml - -from sonic_py_common import device_info - - -class Common: - - DEVICE_PATH = '/usr/share/sonic/device/' - PMON_PLATFORM_PATH = '/usr/share/sonic/platform/' - CONFIG_DIR = 'sonic_platform_config' - - HOST_CHK_CMD = "docker > /dev/null 2>&1" - - def __init__(self): - (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() - - def is_host(self): - return os.system(self.HOST_CHK_CMD) == 0 - - def load_json_file(self, path): - """ - Retrieves the json object from json file path - - Returns: - A json object - """ - with open(path, 'r') as f: - json_data = yaml.safe_load(f) - - return json_data - - def get_config_path(self, config_name): - """ - Retrieves the path to platform api config directory - - Args: - config_name: A string containing the name of config file. - - Returns: - A string containing the path to json file - """ - return os.path.join(self.DEVICE_PATH, self.platform, self.CONFIG_DIR, config_name) if self.is_host() else os.path.join(self.PMON_PLATFORM_PATH, self.CONFIG_DIR, config_name) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/component.py deleted file mode 100644 index ef9e6e3539e0..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/component.py +++ /dev/null @@ -1,85 +0,0 @@ -######################################################################## -# Ragile RA-B6510-48v8c -# -# Module contains an implementation of SONiC Platform Base API and -# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in -# the platform -# -######################################################################## - -try: - import subprocess - from sonic_platform_base.component_base import ComponentBase - from sonic_platform.regutil import Reg - from sonic_platform.logger import logger -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Component(ComponentBase): - """ Ragile Platform-specific Component class""" - - def __init__(self, index, config=None): - self.index = index - self.name = config.get("name") - self._reg_fm_ver = Reg(config.get("firmware_version")) - self.description = config.get("desc") - self.slot = config.get("slot") - - 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 - """ - return self.description - - def get_firmware_version(self): - """ - Retrieves the firmware version of the component - - Returns: - A string containing the firmware version of the component - """ - try: - return self._reg_fm_ver.decode() - except Exception as e: - logger.error(str(e)) - - return "" - - def install_firmware(self, image_path): - """ - Installs firmware to the component - - Args: - image_path: A string, path to firmware image - - Returns: - A boolean, True if install was successful, False if not - """ - try: - successtips = "CPLD Upgrade succeeded!" - status, output = subprocess.getstatusoutput("which firmware_upgrade") - if status or len(output) <= 0: - logger.error("no upgrade tool.") - return False - cmdstr = "%s %s cpld %d cpld"%(output,image_path,self.slot) - ret, log = subprocess.getstatusoutput(cmdstr) - if ret == 0 and successtips in log: - return True - logger.error("upgrade failed. ret:%d, log:\n%s" % (ret, log)) - except Exception as e: - logger.error(str(e)) - return False - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/config.py deleted file mode 100644 index 162f01680ad0..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/config.py +++ /dev/null @@ -1,558 +0,0 @@ -# -*- coding: utf-8 -*- - -PSU_FAN_AIRFLOW = { - "CSU550AP-3-300": "F2B", - "AS-40FAN-01-F-RJ": "F2B", - "CSU550AP-3-500": "F2B", - "DPS-550AB-39 A": "F2B", - "DPS-1300AB-6 S": "F2B", - "FSP1200-20ERM": "F2B", - "CSU800AP-3-300": "F2B", - "CSU550AP-3-501": "B2F", - "DPS-550AB-40 A": "B2F", -} - -FAN_AIRFLOW = { - "AS-80FAN-01-F-RJ": "F2B", - "AS-40FAN-01-F-RJ": "F2B", - "AS-80FAN-01-R-RJ": "B2F", - "AS-40FAN-01-R-RJ": "B2F", -} - -psutypedecode = { - 0x00: "N/A", - 0x01: "AC", - 0x02: "DC", -} - - -class Unit: - Temperature = "C" - Voltage = "V" - Current = "A" - Power = "W" - Speed = "RPM" - - -class Threshold: - PSU_TEMP_MIN = -10 * 1000 - PSU_TEMP_MAX = 60 * 1000 - - PSU_FAN_SPEED_MIN = 2000 - PSU_FAN_SPEED_MAX = 28000 - - PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 - PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 - - PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 - PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 - - PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 - PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 - - ERR_VALUE = -9999999 - - PSU_OUTPUT_POWER_MIN = 10 * 1000 - PSU_OUTPUT_POWER_MAX = 1300 * 1000 - - PSU_INPUT_POWER_MIN = 10 * 1000 - PSU_INPUT_POWER_MAX = 1444 * 1000 - - PSU_OUTPUT_CURRENT_MIN = 2 * 1000 - PSU_OUTPUT_CURRENT_MAX = 107 * 1000 - - PSU_INPUT_CURRENT_MIN = 0.2 * 1000 - PSU_INPUT_CURRENT_MAX = 7 * 1000 - - FAN_SPEED_MAX = 23000 - FAN_SPEED_MIN = 500 - - -class DecodeFormat: - TEXT = 0 - DECIMAL = 1 - ONE_BIT_HEX = 2 - HUNDREDTH = 3 - THOUSANDTH = 4 - MILLIONTH = 5 - AND = 6 - JOIN = 7 - - -class DecodeMethod: - SYSFS = 0 - I2C = 1 - I2C_WORD = 2 - DEVMEM = 3 - SDK = 4 - - -class Description: - CPLD = "Used for managing IO modules, SFP+ modules and system LEDs" - BIOS = "Performs initialization of hardware components during booting" - FPGA = "Platform management controller for on-board temperature monitoring, in-chassis power, Fan and LED control" - - -FAN_LED_COLORS = { - "green": 0b1001, - "red": 0b1010, - "amber": 0b0011, -} - - -DEVICE_CONF = { - "eeprom": {"bus": 2, "loc": "0057"}, - "components": [ - { - "name": "CPLD1 (MAC Board A)", - "firmware_version": { - "bus": 2, - "addr": 0x33, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 0, - }, - { - "name": "CPLD2 (MAC Board B)", - "firmware_version": { - "bus": 2, - "addr": 0x35, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 0, - }, - { - "name": "CPLD3 (CONNECT Board A)", - "firmware_version": { - "bus": 2, - "addr": 0x37, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 0, - }, - { - "name": "CPLD4 (CPU Board)", - "firmware_version": { - "bus": 0, - "addr": 0x0D, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 1, - }, - ], - "thermals": [ - { - "name": "INLET TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/2-0048/hwmon/*/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": None, - "temperature": { - "loc": "/sys/bus/i2c/devices/2-0048/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "OUTLET TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/2-0049/hwmon/*/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": None, - "temperature": { - "loc": "/sys/bus/i2c/devices/2-0049/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "BOARD TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/2-004a/hwmon/*/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": None, - "temperature": { - "loc": "/sys/bus/i2c/devices/2-004a/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "PHYSICAL ID 0", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp1_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 0", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp2_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp2_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp2_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 1", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp3_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp3_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp3_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 2", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp4_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp4_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp4_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 3", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp5_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp5_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp5_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - ], - "fans": [ - { - "name": "fan1", - "e2loc": {"bus": 3, "addr": 0x53, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 0, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 0, - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/3-0053/fan_hw_version"}, - "sn": {"loc": "/sys/bus/i2c/devices/3-0053/fan_sn"}, - "led": { - "loc": "/sys/bus/i2c/devices/0-0032/fan0_led", - "format": DecodeFormat.AND, - "mask": 0b1011, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-0037/hwmon/*/fan1_input" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/0-0032/fan_speed_set" - }, - "speed_max": Threshold.FAN_SPEED_MAX, - } - ], - }, - { - "name": "fan2", - "e2loc": {"bus": 4, "addr": 0x53, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/4-0053/fan_hw_version"}, - "sn": {"loc": "/sys/bus/i2c/devices/4-0053/fan_sn"}, - "led": { - "loc": "/sys/bus/i2c/devices/0-0032/fan1_led", - "format": DecodeFormat.AND, - "mask": 0b1011, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-0037/hwmon/*/fan2_input" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/0-0032/fan_speed_set" - }, - "speed_max": Threshold.FAN_SPEED_MAX, - } - ], - }, - { - "name": "fan3", - "e2loc": {"bus": 3, "addr": 0x53, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 2, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 2, - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/5-0053/fan_hw_version"}, - "sn": {"loc": "/sys/bus/i2c/devices/5-0053/fan_sn"}, - "led": { - "loc": "/sys/bus/i2c/devices/0-0032/fan2_led", - "format": DecodeFormat.AND, - "mask": 0b1011, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-0037/hwmon/*/fan3_input" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/0-0032/fan_speed_set" - }, - "speed_max": Threshold.FAN_SPEED_MAX, - } - ], - }, - { - "name": "fan4", - "e2loc": {"bus": 3, "addr": 0x53, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 3, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 3, - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/6-0053/fan_hw_version"}, - "sn": {"loc": "/sys/bus/i2c/devices/6-0053/fan_sn"}, - "led": { - "loc": "/sys/bus/i2c/devices/0-0032/fan3_led", - "format": DecodeFormat.AND, - "mask": 0b1011, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-0037/hwmon/*/fan4_input" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/0-0032/fan_speed_set" - }, - "speed_max": Threshold.FAN_SPEED_MAX, - } - ], - }, - ], - "psus": [ - { - "name": "psu1", - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 0, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - }, - "sn": {"loc": "/sys/bus/i2c/devices/7-0050/psu_sn"}, - "in_current": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/curr1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "in_voltage": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/in1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_voltage": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/in2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_current": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/curr2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/7-0050/psu_hw"}, - "psu_type": {"loc": "/sys/bus/i2c/devices/7-0050/psu_type"}, - "fans": [ - { - "name": "psu_fan1", - "present": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/fan1_fault", - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/fan1_input" - }, - "speed_max": Threshold.PSU_FAN_SPEED_MAX, - } - ], - } - ], - "in_power": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/power1_input", - "format": DecodeFormat.MILLIONTH, - }, - "out_power": { - "loc": "/sys/bus/i2c/devices/7-0058/hwmon/*/power2_input", - "format": DecodeFormat.MILLIONTH, - }, - }, - { - "name": "psu2", - "present": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 4, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 5, - }, - "sn": {"loc": "/sys/bus/i2c/devices/8-0053/psu_sn"}, - "in_current": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/curr1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "in_voltage": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/in1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_voltage": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/in2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_current": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/curr2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "hw_version": {"loc": "/sys/bus/i2c/devices/8-0053/psu_hw"}, - "psu_type": {"loc": "/sys/bus/i2c/devices/8-0053/psu_type"}, - "fans": [ - { - "name": "psu_fan1", - "present": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/fan1_fault", - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-0037/psu_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 5, - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/fan1_input" - }, - "speed_max": Threshold.PSU_FAN_SPEED_MAX, - } - ], - } - ], - "in_power": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/power1_input", - "format": DecodeFormat.MILLIONTH, - }, - "out_power": { - "loc": "/sys/bus/i2c/devices/8-005b/hwmon/*/power2_input", - "format": DecodeFormat.MILLIONTH, - }, - }, - ], -} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/eeprom.py deleted file mode 100644 index c25d711354f5..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/eeprom.py +++ /dev/null @@ -1,12 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_eeprom import PddfEeprom -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Eeprom(PddfEeprom): - - def __init__(self, pddf_data=None, pddf_plugin_data=None): - PddfEeprom.__init__(self, 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-ragile/ra-b6510-48v8c/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/fan.py deleted file mode 100644 index 47b5a9629c46..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/fan.py +++ /dev/null @@ -1,36 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_fan import PddfFan -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -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) - - # Provide the functions/variables below for which implementation is to be overwritten - # Since psu_fan airflow direction cant be read from sysfs, it is fixed as 'F2B' or 'intake' - def get_direction(self): - """ - Retrieves the direction of fan - - Returns: - A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST - depending on fan direction - """ - return self.FAN_DIRECTION_EXHAUST - - def get_speed_rpm(self): - if self.is_psu_fan: - return super().get_speed_rpm() - else: - divisor = 15000000 - mask_low = 0xff - ret = super().get_speed_rpm() - # revert ret - ret = (ret >> 8) + ((ret & mask_low) << 8) - return int(divisor/ret) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/fan_drawer.py deleted file mode 100644 index 4ff45cb81297..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/fan_drawer.py +++ /dev/null @@ -1,71 +0,0 @@ -# -# fan_drawer_base.py -# -# Abstract base class for implementing a platform-specific class with which -# to interact with a fan drawer module in SONiC -# - -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): - """ - Abstract base class for interfacing with a fan drawer - """ - # Device type definition. Note, this is a constant. - DEVICE_TYPE = "fan_drawer" - - def __init__(self, index, fan_list): - FanDrawerBase.__init__(self) - - self._fan_list = fan_list - self._index = index - - def get_name(self): - """ - Retrieves the name of the device - Returns: - string: The name of the device - """ - - return "fan {}".format(self._index) - - def get_num_fans(self): - """ - Retrieves the number of fans available on this fan drawer - Returns: - An integer, the number of fan modules available on this fan drawer - """ - return len(self._fan_list) - - def get_all_fans(self): - """ - Retrieves all fan modules available on this fan drawer - Returns: - A list of objects derived from FanBase representing all fan - modules available on this fan drawer - """ - return self._fan_list - - 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[self._index].set_status_led(color) - - def get_status_led(self, color): - """ - Gets the state of the fan drawer LED - Returns: - A string, one of the predefined STATUS_LED_COLOR_* strings above - """ - return self._fan_list[self._index].get_status_led(color) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/logger.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/logger.py deleted file mode 100644 index 5969781bf9a9..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/logger.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- - -import logging - - -def _init_logger(): - formatter = logging.Formatter( - "%(asctime)s %(levelname)s %(filename)s[%(funcName)s][%(lineno)s]: %(message)s" - ) - handler = logging.FileHandler("/var/log/syslog") - handler.setFormatter(formatter) - - logger = logging.getLogger(__name__) - logger.setLevel(logging.DEBUG) - logger.addHandler(handler) - return logger - - -logger = _init_logger() diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/pcie.py deleted file mode 100644 index 5a66997d33d0..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/pcie.py +++ /dev/null @@ -1,43 +0,0 @@ -# -# pcie_base.py -# -# Abstract base class for implementing platform-specific -# PCIE functionality for SONiC -# - -try: - import abc - from sonic_pcie import PcieUtil -except ImportError as e: - raise ImportError (str(e) + " - required module not found") - -class PcieBase(object): - def __init__(self, path): - """ - Constructor - Args: - pcieutil file and config file path - """ - self.pcie_util = PcieUtil(path) - - - @abc.abstractmethod - def get_pcie_device(self): - """ - get current device pcie info - - Returns: - A list including pcie device info - """ - return self.pcie_util.get_pcie_device() - - - @abc.abstractmethod - def get_pcie_check(self): - """ - Check Pcie device with config file - Returns: - A list including pcie device and test result info - """ - return self.pcie_util.get_pcie_check() - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/platform.py deleted file mode 100644 index 8595e80692df..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/platform.py +++ /dev/null @@ -1,23 +0,0 @@ -############################################################################# -# PDDF -# Module contains an implementation of SONiC Platform Base API and -# provides the platform information -# -############################################################################# - - -try: - from sonic_platform_pddf_base.pddf_platform import PddfPlatform -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Platform(PddfPlatform): - """ - PDDF Platform-Specific Platform Class - """ - - def __init__(self): - PddfPlatform.__init__(self) - - # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/psu.py deleted file mode 100644 index 240af5d2d1b5..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/psu.py +++ /dev/null @@ -1,32 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_psu import PddfPsu -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - - -class Psu(PddfPsu): - """PDDF Platform-Specific PSU class""" - - PLATFORM_PSU_CAPACITY = 1200 - - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfPsu.__init__(self, index, pddf_data, pddf_plugin_data) - - # Provide the functions/variables below for which implementation is to be overwritten - def get_maximum_supplied_power(self): - """ - Retrieves the maximum supplied power by PSU (or PSU capacity) - Returns: - A float number, the maximum power output in Watts. - e.g. 1200.1 - """ - return float(self.PLATFORM_PSU_CAPACITY) - - def get_type(self): - """ - Gets the type of the PSU - Returns: - A string, the type of PSU (AC/DC) - """ - return "DC" - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/regutil.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/regutil.py deleted file mode 100644 index bff2bd41ea55..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/regutil.py +++ /dev/null @@ -1,245 +0,0 @@ -# -*- coding: utf-8 -*- -from glob import glob -from plat_hal.osutil import osutil - -try: - from sonic_platform.config import DecodeFormat, DecodeMethod - - DECODE_FORMAT = DecodeFormat - DECODE_METHOD = DecodeMethod -except ImportError: - raise ImportError(str(e) + "- required module not found") - -ERR_CODE = "ERR" - - -class Reg(object): - """ - "e2loc": {"bus": 3, "addr": 0x53, "way": "i2c"} - "value": { - "loc": "/sys/bus/i2c/devices/2-0048/hwmon/hwmon*/temp1_input", - "way": "sysfs", - - "InputsStatus": { - "bus": 8, - "addr": 0x5B, - "offset": 0x79, - "way": "i2cword", - "mask": 0x0200, - }, - """ - - def __new__(cls, *args): - if args[0] is None or not isinstance(args[0], dict): - return None - return super(Reg, cls).__new__(cls) - - def __init__(self, data): - - self.loc = None - self.way = DECODE_METHOD.SYSFS - self.addr = None - self.bus = None - self.offset = None - self.size = 1 - self.bit = None - self.mask = None - self.digit = None - self.sdk_type = None - self.sep = None - self.format = DECODE_FORMAT.TEXT - self.__dict__.update(data) - - def _read_reg_val(self): - ret = None - try: - if self.way == DECODE_METHOD.SYSFS: - ret = self.get_sysfs() - elif self.way == DECODE_METHOD.I2C: - ret = self.get_i2c() - elif self.way == DECODE_METHOD.I2C_WORD: - ret = self.get_i2cword() - elif self.way == DECODE_METHOD.DEVMEM: - ret = self.get_devmem() - elif self.way == DECODE_METHOD.SDK: - # TODO - pass - else: - pass - except Exception as e: - raise e - - return ret - - def _write_reg_val(self, val): - try: - if self.way == DECODE_METHOD.SYSFS: - return self._write_sysfs(val) - except Exception as e: - raise e - - return False - - def _write_sysfs(self, val): - try: - with open(glob(self.loc)[0], "w") as f: - f.write(val) - f.flush() - return True - except Exception as e: - raise e - - def _format_val(self, val): - try: - if isinstance(val, str): - val = val.strip() - if self.format == DECODE_FORMAT.THOUSANDTH: - return float("%.1f" % (float(val) / 1000)) - elif self.format == DECODE_FORMAT.HUNDREDTH: - return float("%.1f" % (float(val) / 100)) - elif self.format == DECODE_FORMAT.ONE_BIT_HEX: - return (int(val, 16) & (1 << self.bit)) >> self.bit - elif self.format == DECODE_FORMAT.DECIMAL: - return int(val, 10) - elif self.format == DECODE_FORMAT.MILLIONTH: - return float("%.1f" % (float(val) / 1000 / 1000)) - elif self.format == DECODE_FORMAT.AND: - return (int(val, 16)) & self.mask - elif isinstance(val, list): - if self.format == DECODE_FORMAT.JOIN: - return self.sep.join(val) - except Exception as e: - raise e - else: - return val - - def decode(self): - """ - get value by config way - way i2c/sysfs/lpc - """ - if self.way is None: - raise ValueError("cannot found way to deal") - - ret = self._read_reg_val() - - ret = self._format_val(ret) - return ret - - def encode(self, val): - if self.way is None: - raise ValueError("cannot found way to deal") - - return self._write_reg_val(val) - - def get_sdk(self): - # TODO - pass - - def get_sysfs(self): - if self.loc is None: - raise ValueError("Not Enough Attr: loc: {}".format(self.loc)) - - ret, val = osutil.readsysfs(self.loc) - - if not ret: - raise IOError(val) - - return val - - def get_devmem(self): - if self.addr is None or self.digit is None or self.mask is None: - raise ValueError( - "Not Enough Attr: addr: {}, digit: {}, mask: {}".format( - self.addr, self.digit, self.mask - ) - ) - - ret, val = osutil.getdevmem(self.addr, self.digit, self.mask) - - if not ret: - raise IOError(val) - - return val - - def get_i2cword(self): - if self.bus is None or self.addr is None or self.offset is None: - raise ValueError( - "Not Enough Attr: bus: {}, addr: {}, offset: {}".format( - self.bus, self.addr, self.offset - ) - ) - - ret, val = osutil.geti2cword(self.bus, self.addr, self.offset) - - if not ret: - raise IOError(val) - - return val - - def get_i2c(self): - if ( - self.bus is None - or self.addr is None - or self.offset is None - or self.size is None - ): - raise ValueError( - "Not Enough Attr: bus: {}, addr: {}, offset: {}".format( - self.bus, self.addr, self.offset - ) - ) - - value = [] - for i in range(self.size): - ofs = self.offset + i - ret, val = osutil.rji2cget(self.bus, self.addr, ofs) - - if not ret: - raise IOError(val) - else: - value.append(repr(chr(val)).translate(None, r"\\x").replace("'", "")) - - return value - - def set_i2cword(self, bus, addr, offset, byte): - return self.seti2cword(bus, addr, offset, byte) - - def seti2cword(self, bus, addr, offset, byte): - return osutil.seti2cword(bus, addr, offset, byte) - - def set_i2c(self, bus, addr, offset, byte): - return self.seti2c(bus, addr, offset, byte) - - def seti2c(self, bus, addr, offset, byte): - ret, val = osutil.rji2cset(bus, addr, offset, byte) - return ret, val - - def getbcmtemp(self): - try: - sta, ret = osutil.getmactemp() - if sta == True: - mac_aver = float(ret.get("average", self.__error_ret)) - #mac_max = float(ret.get("maximum", self.__error_ret)) - mac_aver = mac_aver * 1000 - #mac_max = mac_max * 1000 - else: - return False, ret - except AttributeError as e: - return False, str(e) - return True, mac_aver - - def getbcmreg(self, reg): - ret, val = osutil.getsdkreg(reg) - return ret, val - - def logger_debug(self, msg): - baseutil.logger_debug(msg) - - def command(self, cmd): - ret, output = osutil.command(cmd) - return ret, output - - def set_val(self, val): - # TODO - pass diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/rotor.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/rotor.py deleted file mode 100644 index 3e5bcc5b9b9a..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/rotor.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- - -try: - from sonic_platform.regutil import Reg - from sonic_platform.logger import logger -except ImportError: - raise ImportError(str(e) + "- required module not found") - -class Rotor: - def __init__(self, config): - if config is not None and isinstance(config, dict): - self.__reg_speed_getter = Reg(config.get("speed_getter")) - self.__reg_speed_setter = Reg(config.get("speed_setter")) - self.__speed_max = config.get("speed_max") - else: - raise ValueError("init rotor Error: {}".format(config)) - - def get_speed(self): - try: - return int(self.__reg_speed_getter.decode()) - except Exception as e: - logger.error(str(e)) - - return 0 - - def set_speed(self, speed): - try: - return self.__reg_speed_setter.encode(speed) - except Exception as e: - logger.error(str(e)) - - return False - - def get_speed_percentage(self): - try: - speed = self.get_speed() - return (100 * speed) / self.__speed_max - except Exception as e: - logger.error(str(e)) - - return 0 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/sfp.py deleted file mode 100644 index a216a37afcf8..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/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-ragile/ra-b6510-48v8c/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/thermal.py deleted file mode 100644 index 99b743c6d343..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/thermal.py +++ /dev/null @@ -1,14 +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): - PddfThermal.__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-ragile/ra-b6510-48v8c/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/watchdog.py deleted file mode 100644 index 37788c2c821e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/sonic_platform/watchdog.py +++ /dev/null @@ -1,21 +0,0 @@ -############################################################################# -# -# Module contains an implementation of platform specific watchdog API's -# -############################################################################# - -try: - from sonic_platform_pddf_base.pddf_watchdog import PddfWatchdog -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -class Watchdog(PddfWatchdog): - """ - PDDF Platform-specific Chassis class - """ - - def __init__(self): - PddfWatchdog.__init__(self) - self.timeout= 180 - - # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/systemd/pddf-platform-init.service b/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/systemd/pddf-platform-init.service deleted file mode 120000 index 0fd9f25b6c5e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-48v8c/systemd/pddf-platform-init.service +++ /dev/null @@ -1 +0,0 @@ -../../../../pddf/i2c/service/pddf-platform-init.service \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/.upgrade_test/cpld_test_header.vme b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/.upgrade_test/cpld_test_header.vme new file mode 100644 index 0000000000000000000000000000000000000000..0fdca91f1d2fc2a072bb0a17b4398834eaff68a6 GIT binary patch literal 357 zcmYc;$VrJWNi8mk&qz&7NiEVV%T48S^Yn4`aCLNX4btFpaSaQJ3~;qIs4y`wN#+8x zlYyGJoIM;p{cH_^v}b^yqpzziSTxKvDA?2A&$i3}YzkO;n6E3BbC5I82tz~jWJA+5 zQ!Y)e)P-g7KwxO3XZSJM-6bzV+hbt z1sBH #include -/* debgu level */ typedef enum { DBG_START, DBG_VERBOSE, @@ -83,10 +82,10 @@ typedef enum dfd_dev_info_type_e { typedef struct i2c_muxs_struct_flag { - int nr; - char name[48]; - struct mutex update_lock; - int flag; + int nr; + char name[48]; + struct mutex update_lock; + int flag; }i2c_mux_flag; extern int setpca9641_muxflag(i2c_mux_flag i2c); @@ -96,7 +95,6 @@ extern int debuglevel; extern int dfd_cpld_read_chipid(int cpldid , uint32_t addr, int32_t size, unsigned char *buf); extern int dfd_cpld_read(int32_t addr, uint8_t *val); extern int dfd_cpld_write(int32_t addr, uint8_t val); -extern int ragile_setdebug(int val); #define DBG_DEBUG(fmt, arg...) do { \ if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ @@ -112,6 +110,4 @@ extern int ragile_setdebug(int val); } \ } while (0) -#define COMMON_STR_LEN (256) - #endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/rg_cpld.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/rg_cpld.c deleted file mode 100755 index 35fa2faf7d1f..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/rg_cpld.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * rg_cpld.c - A driver for control rg_cpld base on rg_cpld.c - * - * Copyright (c) 1998, 1999 Frodo Looijaard - * Copyright (c) 2018 support - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef enum { - DBG_START, - DBG_VERBOSE, - DBG_KEY, - DBG_WARN, - DBG_ERROR, - DBG_END, -} dbg_level_t; - -static int debuglevel=0; -module_param(debuglevel, int, S_IRUGO); - -#define DBG_DEBUG(fmt, arg...) do { \ - if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ - printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } else if ( debuglevel >= DBG_ERROR ) { \ - printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } else { } \ -} while (0) - -#define DBG_ERROR(fmt, arg...) do { \ - if ( debuglevel > DBG_START) { \ - printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } \ - } while (0) - -/* static const unsigned short rg_i2c_cpld[] = { 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, I2C_CLIENT_END }; */ - -#define CPLD_SIZE 256 -#define CPLD_I2C_RETRY_TIMES 3 -#define COMMON_STR_LEN (256) - -struct cpld_data { - struct i2c_client *client; - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 data[CPLD_SIZE]; /* Register value */ -}; - -static s32 cpld_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) { - if ((ret = i2c_smbus_read_byte_data(client, command) ) >= 0 ) - break; - } - return ret; -} - -static s32 cpld_i2c_smbus_read_i2c_block_data(const struct i2c_client *client, - u8 command, u8 length, u8 *values) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) { - if ((ret = i2c_smbus_read_i2c_block_data(client, command, length, values) ) >= 0 ) - break; - } - return ret; -} - -static ssize_t show_fan_rpm_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct cpld_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int index = to_sensor_dev_attr_2(da)->index; - uint8_t size; - s32 status; - s32 ret_t; - - ret_t = 0; - status = -1; - size = 0; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_byte_data(client, index); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - data->data[0] = status; - status = cpld_i2c_smbus_read_byte_data(client, index + 1); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - data->data[1] = status; - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index, data->data[0]); - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index + 1, data->data[1]); - ret_t = (data->data[1] << 8) + data->data[0] ; - if (ret_t == 0 ) { - size = snprintf(buf, CPLD_SIZE, "%d\n", ret_t); - } else if (ret_t == 0xffff) { - size = snprintf(buf, CPLD_SIZE, "%d\n", 0); - } else { - size = snprintf(buf, CPLD_SIZE, "%d\n", 15000000 / ret_t); - } - mutex_unlock(&data->update_lock); - return size; -} - -static ssize_t set_cpld_sysfs_value(struct device *dev, struct device_attribute *da, const char *buf, size_t -count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - unsigned long val; - int err; - - err = kstrtoul(buf, 16, &val); - if (err) - return err; - if ((val < 0) || (val > 0xff)) { - DBG_ERROR("please enter 0x00 ~ 0xff\n"); - return -1; - } - mutex_lock(&data->update_lock); - data->data[0] = (u8)val; - DBG_DEBUG("pos: 0x%02x count = %ld, data = 0x%02x\n", attr->index, count, data->data[0]); - i2c_smbus_write_byte_data(client, attr->index, data->data[0]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - s32 status; - - status = -1; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_i2c_block_data(client, 0, 4, data->data); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - mutex_unlock(&data->update_lock); - return snprintf(buf, COMMON_STR_LEN, "%02x %02x %02x %02x \n", - data->data[0], data->data[1], data->data[2], data->data[3]); -} - -static ssize_t show_cpld_sysfs_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - s32 status; - - status = -1; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_byte_data(client, attr->index); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - data->data[0] = status; - DBG_DEBUG("cpld reg pos:0x%x value:0x%02x\n", attr->index, data->data[0]); - mutex_unlock(&data->update_lock); - return snprintf(buf, COMMON_STR_LEN, "%02x\n", data->data[0]); -} - -/* common */ -static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO | S_IWUSR, show_cpld_version, NULL, 0); -/*0x37 hwmon*/ -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1B); -static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1D); -static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1F); -//static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x21); -/* 0x32 */ -static SENSOR_DEVICE_ATTR(fan_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15); -static SENSOR_DEVICE_ATTR(fan0_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x23); -static SENSOR_DEVICE_ATTR(fan1_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x24); -static SENSOR_DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x25); -static SENSOR_DEVICE_ATTR(fan3_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x26); -static SENSOR_DEVICE_ATTR(broad_back_lct, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x68); -static SENSOR_DEVICE_ATTR(broad_back_sys, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x72); -/* 0x37 */ -static SENSOR_DEVICE_ATTR(fan_present, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, NULL, 0x30); -static SENSOR_DEVICE_ATTR(fan_status, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, NULL, 0x31); -static SENSOR_DEVICE_ATTR(psu_status, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, NULL, 0x51); -/* 0x33 */ -static SENSOR_DEVICE_ATTR(mac_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa0); -static SENSOR_DEVICE_ATTR(broad_front_lct, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x2a); -static SENSOR_DEVICE_ATTR(broad_front_bmc, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb1); -static SENSOR_DEVICE_ATTR(broad_front_cpu, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb2); -static SENSOR_DEVICE_ATTR(broad_front_pwr, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb3); -static SENSOR_DEVICE_ATTR(broad_front_fan, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb4); -/* 0x34 */ -static SENSOR_DEVICE_ATTR(sfp_presence1, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x30); -static SENSOR_DEVICE_ATTR(sfp_presence2, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x31); -static SENSOR_DEVICE_ATTR(sfp_presence3, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x32); -static SENSOR_DEVICE_ATTR(sfp_presence8, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, NULL, 0x33); -static SENSOR_DEVICE_ATTR(sfp_enable, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa1); -static SENSOR_DEVICE_ATTR(sfp_led1_red, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa2); -static SENSOR_DEVICE_ATTR(sfp_led2_red, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa3); -static SENSOR_DEVICE_ATTR(sfp_led3_red, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa4); -static SENSOR_DEVICE_ATTR(sfp_led8_red, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa5); -static SENSOR_DEVICE_ATTR(sfp_led1_yellow, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa6); -static SENSOR_DEVICE_ATTR(sfp_led2_yellow, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa7); -static SENSOR_DEVICE_ATTR(sfp_led3_yellow, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa8); -static SENSOR_DEVICE_ATTR(sfp_led8_yellow, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa9); -static SENSOR_DEVICE_ATTR(sfp_txdis1, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x60); -static SENSOR_DEVICE_ATTR(sfp_txdis2, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x61); -static SENSOR_DEVICE_ATTR(sfp_txdis3, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x62); -/* 0x35 */ -static SENSOR_DEVICE_ATTR(sfp_enable2, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa0); -/* 0x36 */ -static SENSOR_DEVICE_ATTR(sfp_presence4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x30); -static SENSOR_DEVICE_ATTR(sfp_presence5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x31); -static SENSOR_DEVICE_ATTR(sfp_presence6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x32); -static SENSOR_DEVICE_ATTR(sfp_presence7, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, NULL, 0x33); -static SENSOR_DEVICE_ATTR(sfp_led4_red, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa2); -static SENSOR_DEVICE_ATTR(sfp_led5_red, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa3); -static SENSOR_DEVICE_ATTR(sfp_led6_red, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa4); -static SENSOR_DEVICE_ATTR(sfp_led7_red, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa5); -static SENSOR_DEVICE_ATTR(sfp_led4_yellow, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa6); -static SENSOR_DEVICE_ATTR(sfp_led5_yellow, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa7); -static SENSOR_DEVICE_ATTR(sfp_led6_yellow, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa8); -static SENSOR_DEVICE_ATTR(sfp_led7_yellow, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa9); -static SENSOR_DEVICE_ATTR(sfp_txdis4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x60); -static SENSOR_DEVICE_ATTR(sfp_txdis5, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x61); -static SENSOR_DEVICE_ATTR(sfp_txdis6, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x62); - -static SENSOR_DEVICE_ATTR(sfp_reset1, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xb9); -static SENSOR_DEVICE_ATTR(sfp_reset2, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xba); -static SENSOR_DEVICE_ATTR(sfp_reset3, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xbb); -static SENSOR_DEVICE_ATTR(sfp_reset4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0xbc); - -static struct attribute *cpld32_sysfs_attrs[] = { - &sensor_dev_attr_fan_speed_set.dev_attr.attr, - &sensor_dev_attr_fan0_led.dev_attr.attr, - &sensor_dev_attr_fan1_led.dev_attr.attr, - &sensor_dev_attr_fan2_led.dev_attr.attr, - &sensor_dev_attr_fan3_led.dev_attr.attr, - &sensor_dev_attr_broad_back_lct.dev_attr.attr, - &sensor_dev_attr_broad_back_sys.dev_attr.attr, - NULL -}; - -static struct attribute *cpld37_sysfs_attrs[] = { - &sensor_dev_attr_fan_present.dev_attr.attr, - &sensor_dev_attr_fan_status.dev_attr.attr, - &sensor_dev_attr_psu_status.dev_attr.attr, - &sensor_dev_attr_cpld_version.dev_attr.attr, - NULL -}; - -static struct attribute *cpld33_sysfs_attrs[] = { - &sensor_dev_attr_mac_led.dev_attr.attr, - &sensor_dev_attr_broad_front_lct.dev_attr.attr, - &sensor_dev_attr_broad_front_bmc.dev_attr.attr, - &sensor_dev_attr_broad_front_cpu.dev_attr.attr, - &sensor_dev_attr_broad_front_pwr.dev_attr.attr, - &sensor_dev_attr_broad_front_fan.dev_attr.attr, - &sensor_dev_attr_cpld_version.dev_attr.attr, - NULL -}; - -static struct attribute *cpld34_sysfs_attrs[] = { - &sensor_dev_attr_sfp_presence1.dev_attr.attr, - &sensor_dev_attr_sfp_presence2.dev_attr.attr, - &sensor_dev_attr_sfp_presence3.dev_attr.attr, - &sensor_dev_attr_sfp_presence8.dev_attr.attr, - &sensor_dev_attr_sfp_enable.dev_attr.attr, - &sensor_dev_attr_sfp_led1_red.dev_attr.attr, - &sensor_dev_attr_sfp_led2_red.dev_attr.attr, - &sensor_dev_attr_sfp_led3_red.dev_attr.attr, - &sensor_dev_attr_sfp_led8_red.dev_attr.attr, - &sensor_dev_attr_sfp_led1_yellow.dev_attr.attr, - &sensor_dev_attr_sfp_led2_yellow.dev_attr.attr, - &sensor_dev_attr_sfp_led3_yellow.dev_attr.attr, - &sensor_dev_attr_sfp_led8_yellow.dev_attr.attr, - &sensor_dev_attr_sfp_txdis1.dev_attr.attr, - &sensor_dev_attr_sfp_txdis2.dev_attr.attr, - &sensor_dev_attr_sfp_txdis3.dev_attr.attr, - NULL -}; - -static struct attribute *cpld36_sysfs_attrs[] = { - &sensor_dev_attr_sfp_presence4.dev_attr.attr, - &sensor_dev_attr_sfp_presence5.dev_attr.attr, - &sensor_dev_attr_sfp_presence6.dev_attr.attr, - &sensor_dev_attr_sfp_presence7.dev_attr.attr, - &sensor_dev_attr_sfp_led4_red.dev_attr.attr, - &sensor_dev_attr_sfp_led5_red.dev_attr.attr, - &sensor_dev_attr_sfp_led6_red.dev_attr.attr, - &sensor_dev_attr_sfp_led7_red.dev_attr.attr, - &sensor_dev_attr_sfp_led4_yellow.dev_attr.attr, - &sensor_dev_attr_sfp_led5_yellow.dev_attr.attr, - &sensor_dev_attr_sfp_led6_yellow.dev_attr.attr, - &sensor_dev_attr_sfp_led7_yellow.dev_attr.attr, - &sensor_dev_attr_sfp_txdis4.dev_attr.attr, - &sensor_dev_attr_sfp_txdis5.dev_attr.attr, - &sensor_dev_attr_sfp_txdis6.dev_attr.attr, - &sensor_dev_attr_sfp_reset1.dev_attr.attr, - &sensor_dev_attr_sfp_reset2.dev_attr.attr, - &sensor_dev_attr_sfp_reset3.dev_attr.attr, - &sensor_dev_attr_sfp_reset4.dev_attr.attr, - NULL -}; - -static struct attribute *cpld35_sysfs_attrs[] = { - &sensor_dev_attr_sfp_enable2.dev_attr.attr, - &sensor_dev_attr_broad_front_lct.dev_attr.attr, - &sensor_dev_attr_broad_front_bmc.dev_attr.attr, - &sensor_dev_attr_broad_front_cpu.dev_attr.attr, - &sensor_dev_attr_broad_front_pwr.dev_attr.attr, - &sensor_dev_attr_broad_front_fan.dev_attr.attr, - &sensor_dev_attr_cpld_version.dev_attr.attr, - NULL -}; - -static const struct attribute_group cpld32_sysfs_group = { - .attrs = cpld32_sysfs_attrs, -}; - -static const struct attribute_group cpld37_sysfs_group = { - .attrs = cpld37_sysfs_attrs, -}; - -static const struct attribute_group cpld33_sysfs_group = { - .attrs = cpld33_sysfs_attrs, -}; - -static const struct attribute_group cpld34_sysfs_group = { - .attrs = cpld34_sysfs_attrs, -}; - -static const struct attribute_group cpld36_sysfs_group = { - .attrs = cpld36_sysfs_attrs, -}; - -static const struct attribute_group cpld35_sysfs_group = { - .attrs = cpld35_sysfs_attrs, -}; - -static struct attribute *cpld_hwmon_attrs[] = { - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_fan2_input.dev_attr.attr, - &sensor_dev_attr_fan3_input.dev_attr.attr, - NULL -}; -ATTRIBUTE_GROUPS(cpld_hwmon); - -#if 0 -static int cpld_detect(struct i2c_client *new_client, struct i2c_board_info *info) -{ - struct i2c_adapter *adapter = new_client->adapter; - int conf; - DBG_DEBUG("=========cpld_detect(0x%x)===========\n", new_client->addr); - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) - return -ENODEV; - conf = i2c_smbus_read_byte_data(new_client, 0); - if (!conf) { - return -ENODEV; - } - strlcpy(info->type, "rg_cpld", I2C_NAME_SIZE); - return 0; -} -#endif -static int cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct cpld_data *data; - int status; - - status = -1; - DBG_DEBUG("=========cpld_probe(0x%x)===========\n", client->addr); - data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), GFP_KERNEL); - if (!data) { - return -ENOMEM; - } - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - switch (client->addr) { - case 0x32: - status = sysfs_create_group(&client->dev.kobj, &cpld32_sysfs_group); - break; - case 0x37: - status = sysfs_create_group(&client->dev.kobj, &cpld37_sysfs_group); - if (status != 0) { - break; - } - data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, cpld_hwmon_groups); - if (IS_ERR(data->hwmon_dev)) { - sysfs_remove_group(&client->dev.kobj, &cpld37_sysfs_group); - return PTR_ERR(data->hwmon_dev); - } - break; - case 0x33: - status = sysfs_create_group(&client->dev.kobj, &cpld33_sysfs_group); - break; - case 0x34: - status = sysfs_create_group(&client->dev.kobj, &cpld34_sysfs_group); - break; - case 0x35: - status = sysfs_create_group(&client->dev.kobj, &cpld35_sysfs_group); - break; - case 0x36: - status = sysfs_create_group(&client->dev.kobj, &cpld36_sysfs_group); - break; - default: - break; - } - - if (status !=0) { - DBG_ERROR("%s %d sysfs_create_group err\n", __func__, __LINE__); - } - return status; -} - -static int cpld_remove(struct i2c_client *client) -{ - struct cpld_data *data = i2c_get_clientdata(client); - DBG_DEBUG("=========cpld_probe(0x%x)===========\n", client->addr); - switch (client->addr) { - case 0x32: - sysfs_remove_group(&client->dev.kobj, &cpld32_sysfs_group); - break; - case 0x37: - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &cpld37_sysfs_group); - break; - case 0x33: - sysfs_remove_group(&client->dev.kobj, &cpld33_sysfs_group); - break; - case 0x34: - sysfs_remove_group(&client->dev.kobj, &cpld34_sysfs_group); - break; - case 0x35: - sysfs_remove_group(&client->dev.kobj, &cpld35_sysfs_group); - break; - case 0x36: - sysfs_remove_group(&client->dev.kobj, &cpld36_sysfs_group); - break; - default: - break; - } - - return 0; -} - -static const struct i2c_device_id cpld_id[] = { - { "rg_cpld", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, cpld_id); - -static struct i2c_driver rg_cpld_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "rg_cpld", - }, - .probe = cpld_probe, - .remove = cpld_remove, - .id_table = cpld_id, - /* .detect = cpld_detect, */ - /* .address_list = rg_i2c_cpld, */ -}; - -module_i2c_driver(rg_cpld_driver); -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("ragile CPLD driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_firmware_upgrade_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_firmware_upgrade_device.c new file mode 100644 index 000000000000..e203d569d897 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_firmware_upgrade_device.c @@ -0,0 +1,155 @@ +/* + * wb_firmware_upgrade.c + * Original Author: support 2021-03-17 + * + * ko for firmware device + * History + * [Version] [Author] [Date] [Description] + * v1.0 support 2021-05-07 Initial version + */ +#include +#include +#include +#include +#include +#include + +static int g_wb_firmware_upgrade_debug = 0; +static int g_wb_firmware_upgrade_error = 0; + +module_param(g_wb_firmware_upgrade_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_firmware_upgrade_error, int, S_IRUGO | S_IWUSR); + +#define WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_firmware_upgrade_debug) { \ + printk(KERN_INFO "[WB_FIRMWARE_UPGRADE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FIRMWARE_UPGRADE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_firmware_upgrade_error) { \ + printk(KERN_ERR "[WB_FIRMWARE_UPGRADE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* vme cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 32, + .tck = 65, + .tms = 6, + .tdo = 67, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 1, + .en_logic_num = 0, +}; + +/* isc cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "ISC", + .upg_type.jtag = { + .tdi = 32, + .tck = 65, + .tms = 6, + .tdo = 67, + }, + .en_gpio[0] = 26, + .en_level[0] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 1, + .en_logic_num = 0, +}; + +/* bios */ +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "MTD_DEV", + .chain = 1, + .chip_index = 1, + .upg_type.sysfs = { + .mtd_name = "BIOS", + .flash_base = 0x800000, + }, + + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, +}; + + static int __init firmware_upgrade_device_init(void) + { + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; + } + + static void __exit firmware_upgrade_device_exit(void) + { + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&firmware_upgrade_device[i]); + } + } + } + + module_init(firmware_upgrade_device_init); + module_exit(firmware_upgrade_device_exit); + MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 000000000000..3ba64250b7e0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,278 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca954x_device_debug = 0; +static int g_wb_i2c_mux_pca954x_device_error = 0; + +module_param(g_wb_i2c_mux_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 3, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 7, + .gpio_attr.reset_on = 1, + .gpio_attr.reset_off = 0, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data1 = { + .i2c_bus = 1, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 11, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data2 = { + .i2c_bus = 1, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 19, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data3 = { + .i2c_bus = 1, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 27, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data4 = { + .i2c_bus = 1, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 35, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data5 = { + .i2c_bus = 1, + .i2c_addr = 0x74, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 43, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data6 = { + .i2c_bus = 1, + .i2c_addr = 0x75, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 51, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data7 = { + .i2c_bus = 1, + .i2c_addr = 0x76, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 59, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data8 = { + .i2c_bus = 1, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 67, + .pca9548_reset_type = PCA9548_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 71, + .gpio_attr.reset_on = 0, + .gpio_attr.reset_off = 1, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data1, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data2, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data3, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data4, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data5, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data6, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data7, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data8, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (!client) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca9641_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca9641_device.c new file mode 100644 index 000000000000..5044fb2bb79d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_i2c_mux_pca9641_device.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca9641_device_debug = 0; +static int g_wb_i2c_mux_pca9641_device_error = 0; + +module_param(g_wb_i2c_mux_pca9641_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca9641_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA9641_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca9641_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA9641_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA9641_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca9641_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA9641_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca9641_device_t i2c_mux_pca9641_device_data0 = { + .i2c_bus = 0, + .i2c_addr = 0x10, + .pca9641_nr = 2, + .pca9641_reset_type = PCA9641_RESET_GPIO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .gpio_attr.gpio = 68, + .gpio_attr.reset_on = 1, + .gpio_attr.reset_off = 0, + }, +}; + +struct i2c_board_info i2c_mux_pca9641_device_info[] = { + { + .type = "wb_pca9641", + .platform_data = &i2c_mux_pca9641_device_data0, + }, +}; + +static int __init wb_i2c_mux_pca9641_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca9641_device_t *i2c_mux_pca9641_device_data; + + WB_I2C_MUX_PCA9641_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca9641_device_info); i++) { + i2c_mux_pca9641_device_data = i2c_mux_pca9641_device_info[i].platform_data; + i2c_mux_pca9641_device_info[i].addr = i2c_mux_pca9641_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca9641_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca9641_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca9641_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca9641_device_info[i]); + if (!client) { + i2c_mux_pca9641_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca9641 device %d at bus %d!\n", + i2c_mux_pca9641_device_data->i2c_addr, i2c_mux_pca9641_device_data->i2c_bus); + } else { + i2c_mux_pca9641_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca9641_device_exit(void) +{ + int i; + i2c_mux_pca9641_device_t *i2c_mux_pca9641_device_data; + + WB_I2C_MUX_PCA9641_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca9641_device_info) - 1; i >= 0; i--) { + i2c_mux_pca9641_device_data = i2c_mux_pca9641_device_info[i].platform_data; + if (i2c_mux_pca9641_device_data->client) { + i2c_unregister_device(i2c_mux_pca9641_device_data->client); + i2c_mux_pca9641_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca9641_device_init); +module_exit(wb_i2c_mux_pca9641_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA9641 Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..b05efeb70dd1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_io_dev_device.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..8371b1ce0ea4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_platform_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_platform_i2c_dev_device.c new file mode 100644 index 000000000000..fa02ca22aad5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/modules/driver/wb_platform_i2c_dev_device.c @@ -0,0 +1,199 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_platform_i2c_dev_device_debug = 0; +static int g_wb_platform_i2c_dev_device_error = 0; + +module_param(g_wb_platform_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_platform_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_platform_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_PLATFORM_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_platform_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_PLATFORM_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static platform_i2c_dev_device_t platform_i2c_dev_device_data0 = { + .i2c_bus = 0, + .i2c_addr = 0x0d, + .i2c_name = "cpld1", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data1 = { + .i2c_bus = 0, + .i2c_addr = 0x32, + .i2c_name = "cpld2", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data2 = { + .i2c_bus = 2, + .i2c_addr = 0x37, + .i2c_name = "cpld3", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data3 = { + .i2c_bus = 2, + .i2c_addr = 0x33, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data4 = { + .i2c_bus = 1, + .i2c_addr = 0x34, + .i2c_name = "cpld5", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data5 = { + .i2c_bus = 1, + .i2c_addr = 0x36, + .i2c_name = "cpld6", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static platform_i2c_dev_device_t platform_i2c_dev_device_data6 = { + .i2c_bus = 2, + .i2c_addr = 0x35, + .i2c_name = "cpld7", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static void wb_platform_i2c_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device platform_i2c_dev_device[] = { + { + .name = "wb-platform-i2c-dev", + .id = 1, + .dev = { + .platform_data = &platform_i2c_dev_device_data0, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 2, + .dev = { + .platform_data = &platform_i2c_dev_device_data1, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 3, + .dev = { + .platform_data = &platform_i2c_dev_device_data2, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 4, + .dev = { + .platform_data = &platform_i2c_dev_device_data3, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 5, + .dev = { + .platform_data = &platform_i2c_dev_device_data4, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 6, + .dev = { + .platform_data = &platform_i2c_dev_device_data5, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 7, + .dev = { + .platform_data = &platform_i2c_dev_device_data6, + .release = wb_platform_i2c_dev_device_release, + }, + }, +}; + +static int __init wb_platform_i2c_dev_device_init(void) +{ + int i; + int ret = 0; + platform_i2c_dev_device_t *platform_i2c_dev_device_data; + + WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(platform_i2c_dev_device); i++) { + platform_i2c_dev_device_data = platform_i2c_dev_device[i].dev.platform_data; + ret = platform_device_register(&platform_i2c_dev_device[i]); + if (ret < 0) { + platform_i2c_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-platform-i2c-dev.%d register failed!\n", i + 1); + } else { + platform_i2c_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_platform_i2c_dev_device_exit(void) +{ + int i; + platform_i2c_dev_device_t *platform_i2c_dev_device_data; + + WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(platform_i2c_dev_device) - 1; i >= 0; i--) { + platform_i2c_dev_device_data = platform_i2c_dev_device[i].dev.platform_data; + if (platform_i2c_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&platform_i2c_dev_device[i]); + } + } +} + +module_init(wb_platform_i2c_dev_device_init); +module_exit(wb_platform_i2c_dev_device_exit); +MODULE_DESCRIPTION("PLATFORM I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..4078bf2684d1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,48 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_0_0=0 +cpld_i2c_dev.addr_0_0=0x32 +cpld_i2c_dev.bus_0_1=2 +cpld_i2c_dev.addr_0_1=0x37 +cpld_i2c_dev.bus_0_2=2 +cpld_i2c_dev.addr_0_2=0x33 +cpld_i2c_dev.bus_0_3=1 +cpld_i2c_dev.addr_0_3=0x34 +cpld_i2c_dev.bus_0_4=2 +cpld_i2c_dev.addr_0_4=0x35 +cpld_i2c_dev.bus_0_5=1 +cpld_i2c_dev.addr_0_5=0x36 +cpld_i2c_dev.bus_0_6=0 +cpld_i2c_dev.addr_0_6=0x0d + + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_7=0x700 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=i2c +mode_cpld_0_1=i2c +mode_cpld_0_2=i2c +mode_cpld_0_3=i2c +mode_cpld_0_4=i2c +mode_cpld_0_5=i2c +mode_cpld_0_6=i2c +mode_cpld_0_7=lpc + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=8 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..89966d9897bf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,145 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=3 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=1 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x00010030 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x00010030 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=1 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x00010030 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=2 + + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x00010031 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=0 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x00010031 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=1 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x00010031 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=2 + + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x0001001b +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0001001d +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0001001f +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x00000015 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x00000015 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x00000015 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..cc4a6dae1db3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,64 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=2 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00010051 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00010051 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00010051 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00010051 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=4 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00010051 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=5 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00010051 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=6 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg new file mode 100755 index 000000000000..98136f07651e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg @@ -0,0 +1,225 @@ +# Number of temperature sensors on the mainboard +dev_num_0_1=0 + +# Number of voltage sensors on the mainboard +dev_num_0_2=10 + +# in1 +hwmon_in.mode_0x0001_0x00=config +hwmon_in.int_cons_0x0001_0x00=0 +hwmon_in.src_0x0001_0x00=cpld +hwmon_in.frmt_0x0001_0x00=num_bytes +hwmon_in.addr_0x0001_0x00=0x00020080 +hwmon_in.len_0x0001_0x00=2 +hwmon_in.int_extra1_0x0001_0x00=0x0002008e +hwmon_in.int_extra2_0x0001_0x00=2480 + +hwmon_in.mode_0x0001_0x01=str_constant +hwmon_in.str_cons_0x0001_0x01=MAC_BOARD_VDD3V3 + +hwmon_in.mode_0x0001_0x02=str_constant +hwmon_in.str_cons_0x0001_0x02=cpld + +hwmon_in.mode_0x0001_0x03=str_constant +hwmon_in.str_cons_0x0001_0x03=3542 + +hwmon_in.mode_0x0001_0x05=str_constant +hwmon_in.str_cons_0x0001_0x05=3135 + +# in2 +hwmon_in.mode_0x0002_0x00=config +hwmon_in.int_cons_0x0002_0x00=0 +hwmon_in.src_0x0002_0x00=cpld +hwmon_in.frmt_0x0002_0x00=num_bytes +hwmon_in.addr_0x0002_0x00=0x00020082 +hwmon_in.len_0x0002_0x00=2 +hwmon_in.int_extra1_0x0002_0x00=0x0002008e +hwmon_in.int_extra2_0x0002_0x00=1240 + +hwmon_in.mode_0x0002_0x01=str_constant +hwmon_in.str_cons_0x0002_0x01=MAC_BOARD_VDD1V2_MAC + +hwmon_in.mode_0x0002_0x02=str_constant +hwmon_in.str_cons_0x0002_0x02=cpld + +hwmon_in.mode_0x0002_0x03=str_constant +hwmon_in.str_cons_0x0002_0x03=126 + +hwmon_in.mode_0x0002_0x05=str_constant +hwmon_in.str_cons_0x0002_0x05=114 + +# in3 +hwmon_in.mode_0x0003_0x00=config +hwmon_in.int_cons_0x0003_0x00=0 +hwmon_in.src_0x0003_0x00=cpld +hwmon_in.frmt_0x0003_0x00=num_bytes +hwmon_in.addr_0x0003_0x00=0x00020084 +hwmon_in.len_0x0003_0x00=2 +hwmon_in.int_extra1_0x0003_0x00=0x0002008e +hwmon_in.int_extra2_0x0003_0x00=1240 + +hwmon_in.mode_0x0003_0x01=str_constant +hwmon_in.str_cons_0x0003_0x01=MAC_BOARD_VDD_CORE + +hwmon_in.mode_0x0003_0x02=str_constant +hwmon_in.str_cons_0x0003_0x02=cpld + +hwmon_in.mode_0x0003_0x03=str_constant +hwmon_in.str_cons_0x0003_0x03=945 + +hwmon_in.mode_0x0003_0x05=str_constant +hwmon_in.str_cons_0x0003_0x05=712 + +# in4 +hwmon_in.mode_0x0004_0x00=config +hwmon_in.int_cons_0x0004_0x00=0 +hwmon_in.src_0x0004_0x00=cpld +hwmon_in.frmt_0x0004_0x00=num_bytes +hwmon_in.addr_0x0004_0x00=0x00020086 +hwmon_in.len_0x0004_0x00=2 +hwmon_in.int_extra1_0x0004_0x00=0x0002008e +hwmon_in.int_extra2_0x0004_0x00=1240 + +hwmon_in.mode_0x0004_0x01=str_constant +hwmon_in.str_cons_0x0004_0x01=MAC_BOARD_VDD_ANALOG + +hwmon_in.mode_0x0004_0x02=str_constant +hwmon_in.str_cons_0x0004_0x02=cpld + +hwmon_in.mode_0x0004_0x03=str_constant +hwmon_in.str_cons_0x0004_0x03=856 + +hwmon_in.mode_0x0004_0x05=str_constant +hwmon_in.str_cons_0x0004_0x05=760 + +# in5 +hwmon_in.mode_0x0005_0x00=config +hwmon_in.int_cons_0x0005_0x00=0 +hwmon_in.src_0x0005_0x00=cpld +hwmon_in.frmt_0x0005_0x00=num_bytes +hwmon_in.addr_0x0005_0x00=0x00020088 +hwmon_in.len_0x0005_0x00=2 +hwmon_in.int_extra1_0x0005_0x00=0x0002008e +hwmon_in.int_extra2_0x0005_0x00=2480 + +hwmon_in.mode_0x0005_0x01=str_constant +hwmon_in.str_cons_0x0005_0x01=MAC_BOARD_QSFP_3V3 + +hwmon_in.mode_0x0005_0x02=str_constant +hwmon_in.str_cons_0x0005_0x02=cpld + +hwmon_in.mode_0x0005_0x03=str_constant +hwmon_in.str_cons_0x0005_0x03=3500 + +hwmon_in.mode_0x0005_0x05=str_constant +hwmon_in.str_cons_0x0005_0x05=3135 + +# in6 +hwmon_in.mode_0x0006_0x00=config +hwmon_in.int_cons_0x0006_0x00=0 +hwmon_in.src_0x0006_0x00=cpld +hwmon_in.frmt_0x0006_0x00=num_bytes +hwmon_in.addr_0x0006_0x00=0x0002008a +hwmon_in.len_0x0006_0x00=2 +hwmon_in.int_extra1_0x0006_0x00=0x0002008e +hwmon_in.int_extra2_0x0006_0x00=2480 + +hwmon_in.mode_0x0006_0x01=str_constant +hwmon_in.str_cons_0x0006_0x01=MAC_BOARD_VDD5.0V + +hwmon_in.mode_0x0006_0x02=str_constant +hwmon_in.str_cons_0x0006_0x02=cpld + +hwmon_in.mode_0x0006_0x03=str_constant +hwmon_in.str_cons_0x0006_0x03=5331 + +hwmon_in.mode_0x0006_0x05=str_constant +hwmon_in.str_cons_0x0006_0x05=4750 + +# in7 +hwmon_in.mode_0x0007_0x00=config +hwmon_in.int_cons_0x0007_0x00=0 +hwmon_in.src_0x0007_0x00=cpld +hwmon_in.frmt_0x0007_0x00=num_bytes +hwmon_in.addr_0x0007_0x00=0x0002008c +hwmon_in.len_0x0007_0x00=2 +hwmon_in.int_extra1_0x0007_0x00=0x0002008e +hwmon_in.int_extra2_0x0007_0x00=1240 + +hwmon_in.mode_0x0007_0x01=str_constant +hwmon_in.str_cons_0x0007_0x01=MAC_BOARD_VDD1.8V + +hwmon_in.mode_0x0007_0x02=str_constant +hwmon_in.str_cons_0x0007_0x02=cpld + +hwmon_in.mode_0x0007_0x03=str_constant +hwmon_in.str_cons_0x0007_0x03=1909 + +hwmon_in.mode_0x0007_0x05=str_constant +hwmon_in.str_cons_0x0007_0x05=1710 + +# in8 +hwmon_in.mode_0x0008_0x00=config +hwmon_in.int_cons_0x0008_0x00=0 +hwmon_in.src_0x0008_0x00=cpld +hwmon_in.frmt_0x0008_0x00=num_bytes +hwmon_in.addr_0x0008_0x00=0x0002008e +hwmon_in.len_0x0008_0x00=2 +hwmon_in.int_extra1_0x0008_0x00=0x0002008e +hwmon_in.int_extra2_0x0008_0x00=1000 + +hwmon_in.mode_0x0008_0x01=str_constant +hwmon_in.str_cons_0x0008_0x01=MAC_BOARD_TEST1.24V + +hwmon_in.mode_0x0008_0x02=str_constant +hwmon_in.str_cons_0x0008_0x02=cpld + +hwmon_in.mode_0x0008_0x03=str_constant +hwmon_in.str_cons_0x0008_0x03=1302 + +hwmon_in.mode_0x0008_0x05=str_constant +hwmon_in.str_cons_0x0008_0x05=1178 + +# in9 +hwmon_in.mode_0x0009_0x00=config +hwmon_in.int_cons_0x0009_0x00=0 +hwmon_in.src_0x0009_0x00=cpld +hwmon_in.frmt_0x0009_0x00=num_bytes +hwmon_in.addr_0x0009_0x00=0x0002009a +hwmon_in.len_0x0009_0x00=2 +hwmon_in.int_extra1_0x0009_0x00=0x0002008e +hwmon_in.int_extra2_0x0009_0x00=2480 + +hwmon_in.mode_0x0009_0x01=str_constant +hwmon_in.str_cons_0x0009_0x01=MAC_BOARD_ZSFP3.3V + +hwmon_in.mode_0x0009_0x02=str_constant +hwmon_in.str_cons_0x0009_0x02=cpld + +hwmon_in.mode_0x0009_0x03=str_constant +hwmon_in.str_cons_0x0009_0x03=3542 + +hwmon_in.mode_0x0009_0x05=str_constant +hwmon_in.str_cons_0x0009_0x05=3135 + +# in10 +hwmon_in.mode_0x000a_0x00=config +hwmon_in.int_cons_0x000a_0x00=0 +hwmon_in.src_0x000a_0x00=cpld +hwmon_in.frmt_0x000a_0x00=num_bytes +hwmon_in.addr_0x000a_0x00=0x0002009c +hwmon_in.len_0x000a_0x00=2 +hwmon_in.int_extra1_0x000a_0x00=0x0002008e +hwmon_in.int_extra2_0x000a_0x00=2480 + +hwmon_in.mode_0x000a_0x01=str_constant +hwmon_in.str_cons_0x000a_0x01=MAC_BOARD_VDD3V3_CLK_MCU + +hwmon_in.mode_0x000a_0x02=str_constant +hwmon_in.str_cons_0x000a_0x02=cpld + +hwmon_in.mode_0x000a_0x03=str_constant +hwmon_in.str_cons_0x000a_0x03=3542 + +hwmon_in.mode_0x000a_0x05=str_constant +hwmon_in.str_cons_0x000a_0x05=3135 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..67bec1920049 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,592 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=64 + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 +sff_dir_name_33 =sff33 +sff_dir_name_34 =sff34 +sff_dir_name_35 =sff35 +sff_dir_name_36 =sff36 +sff_dir_name_37 =sff37 +sff_dir_name_38 =sff38 +sff_dir_name_39 =sff39 +sff_dir_name_40 =sff40 +sff_dir_name_41 =sff41 +sff_dir_name_42 =sff42 +sff_dir_name_43 =sff43 +sff_dir_name_44 =sff44 +sff_dir_name_45 =sff45 +sff_dir_name_46 =sff46 +sff_dir_name_47 =sff47 +sff_dir_name_48 =sff48 +sff_dir_name_49 =sff49 +sff_dir_name_50 =sff50 +sff_dir_name_51 =sff51 +sff_dir_name_52 =sff52 +sff_dir_name_53 =sff53 +sff_dir_name_54 =sff54 +sff_dir_name_55 =sff55 +sff_dir_name_56 =sff56 +sff_dir_name_57 =sff57 +sff_dir_name_58 =sff58 +sff_dir_name_59 =sff59 +sff_dir_name_60 =sff60 +sff_dir_name_61 =sff61 +sff_dir_name_62 =sff62 +sff_dir_name_63 =sff63 +sff_dir_name_64 =sff64 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x00030030 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x00030030 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x00030030 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x00030030 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x00030030 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x00030030 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x00030030 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x00030030 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x00030031 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x00030031 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x00030031 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x00030031 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x00030031 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x00030031 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x00030031 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x00030031 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x00050030 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x00050030 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x00050030 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x00050030 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x00050030 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x00050030 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x00050030 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x00050030 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x00050031 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x00050031 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x00050031 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x00050031 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x00050031 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x00050031 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x00050031 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x00050031 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +sff_cpld_reg.mode_33_8=config +sff_cpld_reg.src_33_8=cpld +sff_cpld_reg.frmt_33_8=bit +sff_cpld_reg.pola_33_8=negative +sff_cpld_reg.addr_33_8=0x00030032 +sff_cpld_reg.len_33_8=1 +sff_cpld_reg.bit_offset_33_8=0 + +sff_cpld_reg.mode_34_8=config +sff_cpld_reg.src_34_8=cpld +sff_cpld_reg.frmt_34_8=bit +sff_cpld_reg.pola_34_8=negative +sff_cpld_reg.addr_34_8=0x00030032 +sff_cpld_reg.len_34_8=1 +sff_cpld_reg.bit_offset_34_8=1 + +sff_cpld_reg.mode_35_8=config +sff_cpld_reg.src_35_8=cpld +sff_cpld_reg.frmt_35_8=bit +sff_cpld_reg.pola_35_8=negative +sff_cpld_reg.addr_35_8=0x00030032 +sff_cpld_reg.len_35_8=1 +sff_cpld_reg.bit_offset_35_8=2 + +sff_cpld_reg.mode_36_8=config +sff_cpld_reg.src_36_8=cpld +sff_cpld_reg.frmt_36_8=bit +sff_cpld_reg.pola_36_8=negative +sff_cpld_reg.addr_36_8=0x00030032 +sff_cpld_reg.len_36_8=1 +sff_cpld_reg.bit_offset_36_8=3 + +sff_cpld_reg.mode_37_8=config +sff_cpld_reg.src_37_8=cpld +sff_cpld_reg.frmt_37_8=bit +sff_cpld_reg.pola_37_8=negative +sff_cpld_reg.addr_37_8=0x00030032 +sff_cpld_reg.len_37_8=1 +sff_cpld_reg.bit_offset_37_8=4 + +sff_cpld_reg.mode_38_8=config +sff_cpld_reg.src_38_8=cpld +sff_cpld_reg.frmt_38_8=bit +sff_cpld_reg.pola_38_8=negative +sff_cpld_reg.addr_38_8=0x00030032 +sff_cpld_reg.len_38_8=1 +sff_cpld_reg.bit_offset_38_8=5 + +sff_cpld_reg.mode_39_8=config +sff_cpld_reg.src_39_8=cpld +sff_cpld_reg.frmt_39_8=bit +sff_cpld_reg.pola_39_8=negative +sff_cpld_reg.addr_39_8=0x00030032 +sff_cpld_reg.len_39_8=1 +sff_cpld_reg.bit_offset_39_8=6 + +sff_cpld_reg.mode_40_8=config +sff_cpld_reg.src_40_8=cpld +sff_cpld_reg.frmt_40_8=bit +sff_cpld_reg.pola_40_8=negative +sff_cpld_reg.addr_40_8=0x00030032 +sff_cpld_reg.len_40_8=1 +sff_cpld_reg.bit_offset_40_8=7 + +sff_cpld_reg.mode_41_8=config +sff_cpld_reg.src_41_8=cpld +sff_cpld_reg.frmt_41_8=bit +sff_cpld_reg.pola_41_8=negative +sff_cpld_reg.addr_41_8=0x00030033 +sff_cpld_reg.len_41_8=1 +sff_cpld_reg.bit_offset_41_8=0 + +sff_cpld_reg.mode_42_8=config +sff_cpld_reg.src_42_8=cpld +sff_cpld_reg.frmt_42_8=bit +sff_cpld_reg.pola_42_8=negative +sff_cpld_reg.addr_42_8=0x00030033 +sff_cpld_reg.len_42_8=1 +sff_cpld_reg.bit_offset_42_8=1 + +sff_cpld_reg.mode_43_8=config +sff_cpld_reg.src_43_8=cpld +sff_cpld_reg.frmt_43_8=bit +sff_cpld_reg.pola_43_8=negative +sff_cpld_reg.addr_43_8=0x00030033 +sff_cpld_reg.len_43_8=1 +sff_cpld_reg.bit_offset_43_8=2 + +sff_cpld_reg.mode_44_8=config +sff_cpld_reg.src_44_8=cpld +sff_cpld_reg.frmt_44_8=bit +sff_cpld_reg.pola_44_8=negative +sff_cpld_reg.addr_44_8=0x00030033 +sff_cpld_reg.len_44_8=1 +sff_cpld_reg.bit_offset_44_8=3 + +sff_cpld_reg.mode_45_8=config +sff_cpld_reg.src_45_8=cpld +sff_cpld_reg.frmt_45_8=bit +sff_cpld_reg.pola_45_8=negative +sff_cpld_reg.addr_45_8=0x00030033 +sff_cpld_reg.len_45_8=1 +sff_cpld_reg.bit_offset_45_8=4 + +sff_cpld_reg.mode_46_8=config +sff_cpld_reg.src_46_8=cpld +sff_cpld_reg.frmt_46_8=bit +sff_cpld_reg.pola_46_8=negative +sff_cpld_reg.addr_46_8=0x00030033 +sff_cpld_reg.len_46_8=1 +sff_cpld_reg.bit_offset_46_8=5 + +sff_cpld_reg.mode_47_8=config +sff_cpld_reg.src_47_8=cpld +sff_cpld_reg.frmt_47_8=bit +sff_cpld_reg.pola_47_8=negative +sff_cpld_reg.addr_47_8=0x00030033 +sff_cpld_reg.len_47_8=1 +sff_cpld_reg.bit_offset_47_8=6 + +sff_cpld_reg.mode_48_8=config +sff_cpld_reg.src_48_8=cpld +sff_cpld_reg.frmt_48_8=bit +sff_cpld_reg.pola_48_8=negative +sff_cpld_reg.addr_48_8=0x00030033 +sff_cpld_reg.len_48_8=1 +sff_cpld_reg.bit_offset_48_8=7 + +sff_cpld_reg.mode_49_8=config +sff_cpld_reg.src_49_8=cpld +sff_cpld_reg.frmt_49_8=bit +sff_cpld_reg.pola_49_8=negative +sff_cpld_reg.addr_49_8=0x00050032 +sff_cpld_reg.len_49_8=1 +sff_cpld_reg.bit_offset_49_8=0 + +sff_cpld_reg.mode_50_8=config +sff_cpld_reg.src_50_8=cpld +sff_cpld_reg.frmt_50_8=bit +sff_cpld_reg.pola_50_8=negative +sff_cpld_reg.addr_50_8=0x00050032 +sff_cpld_reg.len_50_8=1 +sff_cpld_reg.bit_offset_50_8=1 + +sff_cpld_reg.mode_51_8=config +sff_cpld_reg.src_51_8=cpld +sff_cpld_reg.frmt_51_8=bit +sff_cpld_reg.pola_51_8=negative +sff_cpld_reg.addr_51_8=0x00050032 +sff_cpld_reg.len_51_8=1 +sff_cpld_reg.bit_offset_51_8=2 + +sff_cpld_reg.mode_52_8=config +sff_cpld_reg.src_52_8=cpld +sff_cpld_reg.frmt_52_8=bit +sff_cpld_reg.pola_52_8=negative +sff_cpld_reg.addr_52_8=0x00050032 +sff_cpld_reg.len_52_8=1 +sff_cpld_reg.bit_offset_52_8=3 + +sff_cpld_reg.mode_53_8=config +sff_cpld_reg.src_53_8=cpld +sff_cpld_reg.frmt_53_8=bit +sff_cpld_reg.pola_53_8=negative +sff_cpld_reg.addr_53_8=0x00050032 +sff_cpld_reg.len_53_8=1 +sff_cpld_reg.bit_offset_53_8=4 + +sff_cpld_reg.mode_54_8=config +sff_cpld_reg.src_54_8=cpld +sff_cpld_reg.frmt_54_8=bit +sff_cpld_reg.pola_54_8=negative +sff_cpld_reg.addr_54_8=0x00050032 +sff_cpld_reg.len_54_8=1 +sff_cpld_reg.bit_offset_54_8=5 + +sff_cpld_reg.mode_55_8=config +sff_cpld_reg.src_55_8=cpld +sff_cpld_reg.frmt_55_8=bit +sff_cpld_reg.pola_55_8=negative +sff_cpld_reg.addr_55_8=0x00050032 +sff_cpld_reg.len_55_8=1 +sff_cpld_reg.bit_offset_55_8=6 + +sff_cpld_reg.mode_56_8=config +sff_cpld_reg.src_56_8=cpld +sff_cpld_reg.frmt_56_8=bit +sff_cpld_reg.pola_56_8=negative +sff_cpld_reg.addr_56_8=0x00050032 +sff_cpld_reg.len_56_8=1 +sff_cpld_reg.bit_offset_56_8=7 +sff_cpld_reg.mode_57_8=config +sff_cpld_reg.src_57_8=cpld +sff_cpld_reg.frmt_57_8=bit +sff_cpld_reg.pola_57_8=negative +sff_cpld_reg.addr_57_8=0x00050033 +sff_cpld_reg.len_57_8=1 +sff_cpld_reg.bit_offset_57_8=0 + +sff_cpld_reg.mode_58_8=config +sff_cpld_reg.src_58_8=cpld +sff_cpld_reg.frmt_58_8=bit +sff_cpld_reg.pola_58_8=negative +sff_cpld_reg.addr_58_8=0x00050033 +sff_cpld_reg.len_58_8=1 +sff_cpld_reg.bit_offset_58_8=1 + +sff_cpld_reg.mode_59_8=config +sff_cpld_reg.src_59_8=cpld +sff_cpld_reg.frmt_59_8=bit +sff_cpld_reg.pola_59_8=negative +sff_cpld_reg.addr_59_8=0x00050033 +sff_cpld_reg.len_59_8=1 +sff_cpld_reg.bit_offset_59_8=2 + +sff_cpld_reg.mode_60_8=config +sff_cpld_reg.src_60_8=cpld +sff_cpld_reg.frmt_60_8=bit +sff_cpld_reg.pola_60_8=negative +sff_cpld_reg.addr_60_8=0x00050033 +sff_cpld_reg.len_60_8=1 +sff_cpld_reg.bit_offset_60_8=3 + +sff_cpld_reg.mode_61_8=config +sff_cpld_reg.src_61_8=cpld +sff_cpld_reg.frmt_61_8=bit +sff_cpld_reg.pola_61_8=negative +sff_cpld_reg.addr_61_8=0x00050033 +sff_cpld_reg.len_61_8=1 +sff_cpld_reg.bit_offset_61_8=4 + +sff_cpld_reg.mode_62_8=config +sff_cpld_reg.src_62_8=cpld +sff_cpld_reg.frmt_62_8=bit +sff_cpld_reg.pola_62_8=negative +sff_cpld_reg.addr_62_8=0x00050033 +sff_cpld_reg.len_62_8=1 +sff_cpld_reg.bit_offset_62_8=5 + +sff_cpld_reg.mode_63_8=config +sff_cpld_reg.src_63_8=cpld +sff_cpld_reg.frmt_63_8=bit +sff_cpld_reg.pola_63_8=negative +sff_cpld_reg.addr_63_8=0x00050033 +sff_cpld_reg.len_63_8=1 +sff_cpld_reg.bit_offset_63_8=6 + +sff_cpld_reg.mode_64_8=config +sff_cpld_reg.src_64_8=cpld +sff_cpld_reg.frmt_64_8=bit +sff_cpld_reg.pola_64_8=negative +sff_cpld_reg.addr_64_8=0x00050033 +sff_cpld_reg.len_64_8=1 +sff_cpld_reg.bit_offset_64_8=7 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/cfg_file_name new file mode 100755 index 000000000000..c3ea65365c78 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,5 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF +WB_PLAT_SENSOR diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/scripts/pddf_post_driver_install.sh b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/scripts/pddf_post_driver_install.sh deleted file mode 100755 index badbce25589d..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/scripts/pddf_post_driver_install.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -count=10 -while [ $count -gt 0 ] -do - lsmod | grep 9641 >/dev/null 2>&1 - if [ $? -eq 0 ] - then - break - fi - count=$(( count - 1 )) - sleep 1 -done - -if [ $count -eq 0 ] -then - # mod not loaded - exit 1 -fi - -if [ ! -d "/sys/bus/i2c/devices/i2c-2" ] -then - echo pca9541 0x10 > /sys/bus/i2c/devices/i2c-0/new_device - if [ $? -ne 0 ] - then - exit $? - fi -fi - -exit 0 - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py old mode 100644 new mode 100755 index 0ed22d770626..6c3916921abb --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/setup.py @@ -3,17 +3,25 @@ setup( name='sonic-platform', version='1.0', - description='SONiC platform API implementation on RAGILE Platforms', + description='SONiC platform API implementation', license='Apache 2.0', author='SONiC Team', - author_email='support@ragile.com', + author_email='support', url='', - maintainer='RAGILE SUPPORT TEAM', + maintainer='support', maintainer_email='', packages=[ 'sonic_platform', - 'rgutil', - 'eepromutil' + 'plat_hal', + 'wbutil', + 'eepromutil', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', ], classifiers=[ 'Development Status :: 3 - Alpha', @@ -29,4 +37,3 @@ ], keywords='sonic SONiC platform PLATFORM', ) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/__init__.py deleted file mode 100644 index 593867d31c9d..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# All the derived classes for PDDF -__all__ = ["platform", "chassis", "sfp", "psu", "thermal", "fan"] -from . import platform - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/chassis.py deleted file mode 100644 index f4750f4abd5f..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/chassis.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# PDDF -# Module contains an implementation of SONiC Chassis API -# -############################################################################# - -try: - import time - import subprocess - from sonic_platform_pddf_base.pddf_chassis import PddfChassis - from rgutil.logutil import Logger -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -PORT_START = 0 -PORT_END = 55 -PORTS_IN_BLOCK = 56 - -logger = Logger("CHASSIS", syslog=True) - -class Chassis(PddfChassis): - """ - PDDF Platform-specific Chassis class - """ - - SFP_STATUS_INSERTED = "1" - SFP_STATUS_REMOVED = "0" - port_dict = {} - - def __init__(self, pddf_data=None, pddf_plugin_data=None): - PddfChassis.__init__(self, pddf_data, pddf_plugin_data) - - self.enable_read = "i2cset -f -y 2 0x35 0x2a 0x01" - self.disable_read = "i2cset -f -y 2 0x35 0x2a 0x00" - self.enable_write = "i2cset -f -y 2 0x35 0x2b 0x00" - self.disable_write = "i2cset -f -y 2 0x35 0x2b 0x01" - self.enable_erase = "i2cset -f -y 2 0x35 0x2c 0x01" - self.disable_erase = "i2cset -f -y 2 0x35 0x2c 0x00" - self.read_value = "i2cget -f -y 2 0x35 0x25" - self.write_value = "i2cset -f -y 2 0x35 0x21 0x0a" - - 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. - """ - try: - is_power_loss = False - # enable read - subprocess.getstatusoutput(self.disable_write) - subprocess.getstatusoutput(self.enable_read) - ret, log = subprocess.getstatusoutput(self.read_value) - if ret == 0 and "0x0a" in log: - is_power_loss = True - - # erase i2c and e2 - subprocess.getstatusoutput(self.enable_erase) - time.sleep(1) - subprocess.getstatusoutput(self.disable_erase) - # clear data - subprocess.getstatusoutput(self.enable_write) - subprocess.getstatusoutput(self.disable_read) - subprocess.getstatusoutput(self.disable_write) - subprocess.getstatusoutput(self.enable_read) - # enable write and set data - subprocess.getstatusoutput(self.enable_write) - subprocess.getstatusoutput(self.disable_read) - subprocess.getstatusoutput(self.write_value) - if is_power_loss: - return(self.REBOOT_CAUSE_POWER_LOSS, None) - except Exception as e: - logger.error(str(e)) - - return (self.REBOOT_CAUSE_NON_HARDWARE, None) - - def get_change_event(self, timeout=0): - change_event_dict = {"fan": {}, "sfp": {}} - sfp_status, sfp_change_dict = self.get_transceiver_change_event(timeout) - change_event_dict["sfp"] = sfp_change_dict - if sfp_status is True: - return True, change_event_dict - - return False, {} - - def get_transceiver_change_event(self, timeout=0): - start_time = time.time() - currernt_port_dict = {} - forever = False - - if timeout == 0: - forever = True - elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs - else: - print("get_transceiver_change_event:Invalid timeout value", timeout) - return False, {} - - end_time = start_time + timeout - if start_time > end_time: - print( - "get_transceiver_change_event:" "time wrap / invalid timeout value", - timeout, - ) - return False, {} # Time wrap or possibly incorrect timeout - - while timeout >= 0: - # Check for OIR events and return updated port_dict - for index in range(PORT_START, PORTS_IN_BLOCK): - if self._sfp_list[index].get_presence(): - currernt_port_dict[index] = self.SFP_STATUS_INSERTED - else: - currernt_port_dict[index] = self.SFP_STATUS_REMOVED - if currernt_port_dict == self.port_dict: - if forever: - time.sleep(1) - else: - timeout = end_time - time.time() - if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity - else: - if timeout > 0: - time.sleep(timeout) - return True, {} - else: - # Update reg value - self.port_dict = currernt_port_dict - print(self.port_dict) - return True, self.port_dict - print("get_transceiver_change_event: Should not reach here.") - return False, {} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/common.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/common.py deleted file mode 100644 index c1a85f618609..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/common.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -import yaml - -from sonic_py_common import device_info - - -class Common: - - DEVICE_PATH = '/usr/share/sonic/device/' - PMON_PLATFORM_PATH = '/usr/share/sonic/platform/' - CONFIG_DIR = 'sonic_platform_config' - - HOST_CHK_CMD = "docker > /dev/null 2>&1" - - def __init__(self): - (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() - - def is_host(self): - return os.system(self.HOST_CHK_CMD) == 0 - - def load_json_file(self, path): - """ - Retrieves the json object from json file path - - Returns: - A json object - """ - with open(path, 'r') as f: - json_data = yaml.safe_load(f) - - return json_data - - def get_config_path(self, config_name): - """ - Retrieves the path to platform api config directory - - Args: - config_name: A string containing the name of config file. - - Returns: - A string containing the path to json file - """ - return os.path.join(self.DEVICE_PATH, self.platform, self.CONFIG_DIR, config_name) if self.is_host() else os.path.join(self.PMON_PLATFORM_PATH, self.CONFIG_DIR, config_name) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/eeprom.py deleted file mode 100644 index a87ecc9f6feb..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/eeprom.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python - -try: - from sonic_platform_pddf_base.pddf_eeprom import PddfEeprom -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Eeprom(PddfEeprom): - - def __init__(self, pddf_data=None, pddf_plugin_data=None): - PddfEeprom.__init__(self, 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-ragile/ra-b6910-64c/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/fan.py deleted file mode 100644 index 205676b15410..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/fan.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python - - -try: - from sonic_platform_pddf_base.pddf_fan import PddfFan -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -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) - - # Provide the functions/variables below for which implementation is to be overwritten - # Since psu_fan airflow direction cant be read from sysfs, it is fixed as 'F2B' or 'intake' - def get_direction(self): - """ - Retrieves the direction of fan - - Returns: - A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST - depending on fan direction - """ - return self.FAN_DIRECTION_EXHAUST - - def get_speed_rpm(self): - if self.is_psu_fan: - return super().get_speed_rpm() - else: - divisor = 15000000 - mask_low = 0xff - ret = super().get_speed_rpm() - # revert ret - ret = (ret >> 8) + ((ret & mask_low) << 8) - return int(divisor/ret) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/fan_drawer.py deleted file mode 100644 index 4ff45cb81297..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/fan_drawer.py +++ /dev/null @@ -1,71 +0,0 @@ -# -# fan_drawer_base.py -# -# Abstract base class for implementing a platform-specific class with which -# to interact with a fan drawer module in SONiC -# - -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): - """ - Abstract base class for interfacing with a fan drawer - """ - # Device type definition. Note, this is a constant. - DEVICE_TYPE = "fan_drawer" - - def __init__(self, index, fan_list): - FanDrawerBase.__init__(self) - - self._fan_list = fan_list - self._index = index - - def get_name(self): - """ - Retrieves the name of the device - Returns: - string: The name of the device - """ - - return "fan {}".format(self._index) - - def get_num_fans(self): - """ - Retrieves the number of fans available on this fan drawer - Returns: - An integer, the number of fan modules available on this fan drawer - """ - return len(self._fan_list) - - def get_all_fans(self): - """ - Retrieves all fan modules available on this fan drawer - Returns: - A list of objects derived from FanBase representing all fan - modules available on this fan drawer - """ - return self._fan_list - - 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[self._index].set_status_led(color) - - def get_status_led(self, color): - """ - Gets the state of the fan drawer LED - Returns: - A string, one of the predefined STATUS_LED_COLOR_* strings above - """ - return self._fan_list[self._index].get_status_led(color) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/platform.py deleted file mode 100644 index 406b1179ae1b..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/platform.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# PDDF -# Module contains an implementation of SONiC Platform Base API and -# provides the platform information -# -############################################################################# - - -try: - from sonic_platform_pddf_base.pddf_platform import PddfPlatform -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Platform(PddfPlatform): - """ - PDDF Platform-Specific Platform Class - """ - - def __init__(self): - PddfPlatform.__init__(self) - - # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/psu.py deleted file mode 100644 index 72a6d8f0825b..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/psu.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python -# - - -try: - from sonic_platform_pddf_base.pddf_psu import PddfPsu -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - - -class Psu(PddfPsu): - """PDDF Platform-Specific PSU class""" - - PLATFORM_PSU_CAPACITY = 1200 - - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfPsu.__init__(self, index, pddf_data, pddf_plugin_data) - - # Provide the functions/variables below for which implementation is to be overwritten - def get_maximum_supplied_power(self): - """ - Retrieves the maximum supplied power by PSU (or PSU capacity) - Returns: - A float number, the maximum power output in Watts. - e.g. 1200.1 - """ - return float(self.PLATFORM_PSU_CAPACITY) - - def get_type(self): - """ - Gets the type of the PSU - Returns: - A string, the type of PSU (AC/DC) - """ - return "DC" - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/sfp.py deleted file mode 100644 index d9b6e491bef4..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/sfp.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python - -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-ragile/ra-b6910-64c/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/thermal.py deleted file mode 100644 index 5b829fc26caa..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/thermal.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python - - -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): - PddfThermal.__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-ragile/ra-b6910-64c/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/watchdog.py deleted file mode 100644 index 88660b1a1faa..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/sonic_platform/watchdog.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# -# Module contains an implementation of platform specific watchdog API's -# -############################################################################# - -try: - from sonic_platform_pddf_base.pddf_watchdog import PddfWatchdog -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -class Watchdog(PddfWatchdog): - """ - PDDF Platform-specific Chassis class - """ - - def __init__(self): - PddfWatchdog.__init__(self) - self.timeout= 180 - - # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/systemd/pddf-platform-init.service b/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/systemd/pddf-platform-init.service deleted file mode 120000 index 0fd9f25b6c5e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6910-64c/systemd/pddf-platform-init.service +++ /dev/null @@ -1 +0,0 @@ -../../../../pddf/i2c/service/pddf-platform-init.service \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/.upgrade_test/board_cpld_test_header.vme b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/.upgrade_test/board_cpld_test_header.vme new file mode 100644 index 0000000000000000000000000000000000000000..2c364e44b9eea15e4541783bd3269c90d12b3b25 GIT binary patch literal 470 zcmaivK}&={7=}k(9GwWZEU4QY>#{hm!XkK(b!vsy789Y9?5;+EyAGR4o$AyN>o@cx z>ew&XX56mfcbS*rd!CnXQO!4bwq#|V)x~2yXjTQf2(Rdb`T>p4P(ah*_pQ0yq%>(;LyXAehDKU)JJ?HS)5EvTi8GcN5cgal5&Cg3wa7iu5$*;^!%_~s|$l}a%uv9_A^g99 zlYyOqiJ6&+`vtoIqacSc1ABpxf-oZkiwMIZ-YadQO#fL5I2hO%I6*qtK{^Pjt_J{6 Ct5Adh literal 0 HcmV?d00001 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/LICENSE b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/LICENSE deleted file mode 100755 index d37122689f3e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -Copyright (C) 2016 Microsoft, Inc -Copyright (C) 2018 Ragile Network 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/MAINTAINERS b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/MAINTAINERS deleted file mode 100755 index ec8222405085..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/MAINTAINERS +++ /dev/null @@ -1,5 +0,0 @@ -# See the SONiC project governance document for more information - -Name = "support" -Email = "support@ragile.com" -Mailinglist = sonicproject@googlegroups.com diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/Makefile b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/Makefile index 46415e74ab7d..1b84abef410a 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/Makefile @@ -5,10 +5,9 @@ EXTRA_CFLAGS+= -Wall SUB_BUILD_DIR = $(PWD)/build INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin -INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system/ - -KBUILD_EXTRA_SYMBOLS += $(DIR_KERNEL_SRC)/Module.symvers -export KBUILD_EXTRA_SYMBOLS +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_SYSFS_CFG_DIR = $(SUB_BUILD_DIR)/etc/plat_sysfs_cfg +INSTALL_UPGRADE_TEST_DIR = $(SUB_BUILD_DIR)/etc/.upgrade_test all: $(MAKE) -C $(KBUILD_OUTPUT) M=$(DIR_KERNEL_SRC) modules @@ -16,11 +15,14 @@ all: cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_DIR) @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi cp -r $(PWD)/config/* $(INSTALL_SCRIPT_DIR) - @if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi - cp $(PWD)/systemd/*.service $(INSTALL_SERVICE_DIR) + @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi + @if [ -d $(PWD)/hal-config/ ]; then cp -r $(PWD)/hal-config/* ${INSTALL_LIB_DIR} ;fi + @if [ ! -d ${INSTALL_SYSFS_CFG_DIR} ]; then mkdir -p ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ -d $(PWD)/plat_sysfs_cfg/ ]; then cp -r $(PWD)/plat_sysfs_cfg/* ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ ! -d ${INSTALL_UPGRADE_TEST_DIR} ]; then mkdir -p ${INSTALL_UPGRADE_TEST_DIR} ;fi + @if [ -d $(PWD)/.upgrade_test/ ]; then cp -r $(PWD)/.upgrade_test/* ${INSTALL_UPGRADE_TEST_DIR} ;fi clean: rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order rm -rf ${DIR_KERNEL_SRC}/.tmp_versions rm -rf $(SUB_BUILD_DIR) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/README.md b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/README.md deleted file mode 100755 index 787636c4ad20..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/README.md +++ /dev/null @@ -1 +0,0 @@ -Device drivers for support of ragile platform for the SONiC project diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_config.py index 51cb6992a0a0..31638b4e8caf 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_config.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_config.py @@ -1,625 +1,1676 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: UTF-8 -*- -from ragilecommon import * -PCA9548START = -1 -PCA9548BUSEND = -2 - -RAGILE_CARDID = 0x0000404d -RAGILE_PRODUCTNAME = "RA-B6920-4S" +from platform_common import * STARTMODULE = { - "fancontrol": 1, + "fancontrol": 0, + "hal_fanctrl": 1, + "hal_ledctrl": 1, "avscontrol": 1, - "sfptempmodule": 0, - "sfptempmodule_interval": 3, "slot_monitor": 1, "dev_monitor": 1, + "pmon_syslog": 1, + "sff_temp_polling": 1, + "reboot_cause": 1, } DEV_MONITOR_PARAM = { - "polling_time": 5, + "polling_time": 10, "psus": [ { "name": "psu1", - "present": {"gettype": "io", "io_addr": 0xB27, "presentbit": 0, "okval": 0}, + "present": {"gettype": "io", "io_addr": 0xb27, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu1pmbus", - "name": "fsp1200", - "bus": 23, - "loc": 0x58, - "attr": "hwmon", - }, + {"id": "psu1pmbus", "name": "wb_fsp1200", "bus": 23, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu1frue2", "name": "wb_24c02", "bus": 23, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "psu2", - "present": {"gettype": "io", "io_addr": 0xB28, "presentbit": 0, "okval": 0}, + "present": {"gettype": "io", "io_addr": 0xb28, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu2pmbus", - "name": "fsp1200", - "bus": 25, - "loc": 0x58, - "attr": "hwmon", - }, + {"id": "psu2pmbus", "name": "wb_fsp1200", "bus": 25, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu2frue2", "name": "wb_24c02", "bus": 25, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "psu3", - "present": {"gettype": "io", "io_addr": 0xB29, "presentbit": 0, "okval": 0}, + "present": {"gettype": "io", "io_addr": 0xb29, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu3pmbus", - "name": "fsp1200", - "bus": 24, - "loc": 0x58, - "attr": "hwmon", - }, + {"id": "psu3pmbus", "name": "wb_fsp1200", "bus": 24, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu3frue2", "name": "wb_24c02", "bus": 24, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "psu4", - "present": {"gettype": "io", "io_addr": 0xB2A, "presentbit": 0, "okval": 0}, + "present": {"gettype": "io", "io_addr": 0xb2a, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "psu4pmbus", - "name": "fsp1200", - "bus": 26, - "loc": 0x58, - "attr": "hwmon", - }, - ], + {"id": "psu4pmbus", "name": "wb_fsp1200", "bus": 26, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu4frue2", "name": "wb_24c02", "bus": 26, "loc": 0x50, "attr": "eeprom"}, + ], }, ], "fans": [ { "name": "fan1", - "present": { - "gettype": "i2c", - "bus": 14, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 0, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 14, "loc": 0x0d, "offset": 0x30, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "fan1frue2", - "name": "24c02", - "bus": 63, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan1frue2", "name": "wb_24c02", "bus": 63, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan2", - "present": { - "gettype": "i2c", - "bus": 13, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 0, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 13, "loc": 0x0d, "offset": 0x30, "presentbit": 0, "okval": 0}, "device": [ - { - "id": "fan2frue2", - "name": "24c02", - "bus": 55, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan2frue2", "name": "wb_24c02", "bus": 55, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan3", - "present": { - "gettype": "i2c", - "bus": 14, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 1, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 14, "loc": 0x0d, "offset": 0x30, "presentbit": 1, "okval": 0}, "device": [ - { - "id": "fan3frue2", - "name": "24c02", - "bus": 64, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan3frue2", "name": "wb_24c02", "bus": 64, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan4", - "present": { - "gettype": "i2c", - "bus": 13, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 1, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 13, "loc": 0x0d, "offset": 0x30, "presentbit": 1, "okval": 0}, "device": [ - { - "id": "fan4frue2", - "name": "24c02", - "bus": 56, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan4frue2", "name": "wb_24c02", "bus": 56, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan5", - "present": { - "gettype": "i2c", - "bus": 14, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 2, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 14, "loc": 0x0d, "offset": 0x30, "presentbit": 2, "okval": 0}, "device": [ - { - "id": "fan5frue2", - "name": "24c02", - "bus": 65, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "fan5frue2", "name": "wb_24c02", "bus": 65, "loc": 0x50, "attr": "eeprom"}, ], }, { "name": "fan6", - "present": { - "gettype": "i2c", - "bus": 13, - "loc": 0x0d, - "offset": 0x30, - "presentbit": 2, - "okval": 0 - }, + "present": {"gettype": "i2c", "bus": 13, "loc": 0x0d, "offset": 0x30, "presentbit": 2, "okval": 0}, + "device": [ + {"id": "fan6frue2", "name": "wb_24c02", "bus": 57, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "slots": [ + { + "name": "slot1", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 4, "okval": 0}, + "device": [ + {"id": "slot1frue2", "name": "wb_24c02", "bus": 3, "loc": 0x56, "attr": "eeprom"}, + {"id": "slot1tlve2", "name": "wb_24c02", "bus": 3, "loc": 0x57, "attr": "eeprom"}, + {"id": "slot1lm75a1", "name": "wb_lm75", "bus": 32, "loc": 0x48, "attr": "hwmon"}, + {"id": "slot1lm75a2", "name": "wb_lm75", "bus": 32, "loc": 0x49, "attr": "hwmon"}, + {"id": "slot1lm75a3", "name": "wb_lm75", "bus": 32, "loc": 0x4D, "attr": "hwmon"}, + ], + }, + { + "name": "slot2", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 5, "okval": 0}, + "device": [ + {"id": "slot2frue2", "name": "wb_24c02", "bus": 4, "loc": 0x56, "attr": "eeprom"}, + {"id": "slot2tlve2", "name": "wb_24c02", "bus": 4, "loc": 0x57, "attr": "eeprom"}, + {"id": "slot2lm75a1", "name": "wb_lm75", "bus": 48, "loc": 0x48, "attr": "hwmon"}, + {"id": "slot2lm75a2", "name": "wb_lm75", "bus": 48, "loc": 0x49, "attr": "hwmon"}, + {"id": "slot2lm75a3", "name": "wb_lm75", "bus": 48, "loc": 0x4D, "attr": "hwmon"}, + ], + }, + { + "name": "slot3", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 6, "okval": 0}, + "device": [ + {"id": "slot3frue2", "name": "wb_24c02", "bus": 5, "loc": 0x56, "attr": "eeprom"}, + {"id": "slot3tlve2", "name": "wb_24c02", "bus": 5, "loc": 0x57, "attr": "eeprom"}, + {"id": "slot3lm75a1", "name": "wb_lm75", "bus": 40, "loc": 0x48, "attr": "hwmon"}, + {"id": "slot3lm75a2", "name": "wb_lm75", "bus": 40, "loc": 0x49, "attr": "hwmon"}, + {"id": "slot3lm75a3", "name": "wb_lm75", "bus": 40, "loc": 0x4D, "attr": "hwmon"}, + ], + }, + { + "name": "slot4", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 7, "okval": 0}, + "device": [ + {"id": "slot4frue2", "name": "wb_24c02", "bus": 6, "loc": 0x56, "attr": "eeprom"}, + {"id": "slot4tlve2", "name": "wb_24c02", "bus": 6, "loc": 0x57, "attr": "eeprom"}, + {"id": "slot4lm75a1", "name": "wb_lm75", "bus": 16, "loc": 0x48, "attr": "hwmon"}, + {"id": "slot4lm75a2", "name": "wb_lm75", "bus": 16, "loc": 0x49, "attr": "hwmon"}, + {"id": "slot4lm75a3", "name": "wb_lm75", "bus": 16, "loc": 0x4D, "attr": "hwmon"}, + ], + }, + ], + "others": [ + { + "name": "eeprom", + "device": [ + {"id": "eeprom_1", "name": "wb_24c02", "bus": 1, "loc": 0x56, "attr": "eeprom"}, + ], + }, + { + "name": "lm75", + "device": [ + {"id": "lm75_1", "name": "wb_lm75", "bus": 28, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_2", "name": "wb_lm75", "bus": 29, "loc": 0x4f, "attr": "hwmon"}, + {"id": "lm75_3", "name": "wb_lm75", "bus": 60, "loc": 0x48, "attr": "hwmon"}, + {"id": "lm75_4", "name": "wb_lm75", "bus": 60, "loc": 0x49, "attr": "hwmon"}, + {"id": "lm75_5", "name": "wb_lm75", "bus": 68, "loc": 0x48, "attr": "hwmon"}, + {"id": "lm75_6", "name": "wb_lm75", "bus": 68, "loc": 0x49, "attr": "hwmon"}, + ], + }, + { + "name": "mac_bsc", + "device": [ + {"id": "mac_bsc_1", "name": "wb_mac_bsc_th3", "bus": 27, "loc": 0x44, "attr": "hwmon"}, + ], + }, + { + "name": "tps53622", + "device": [ + {"id": "tps53622_1", "name": "wb_tps53622", "bus": 10, "loc": 0x60, "attr": "hwmon"}, + {"id": "tps53622_2", "name": "wb_tps53622", "bus": 10, "loc": 0x6c, "attr": "hwmon"}, + ], + }, + { + "name": "tmp411", "device": [ - { - "id": "fan6frue2", - "name": "24c02", - "bus": 57, - "loc": 0x50, - "attr": "eeprom" - }, + {"id": "tmp411_1", "name": "wb_tmp411", "bus": 28, "loc": 0x4c, "attr": "hwmon"}, + {"id": "tmp411_2", "name": "wb_tmp411", "bus": 29, "loc": 0x4c, "attr": "hwmon"}, ], }, - ] + ], } +MANUINFO_CONF = { + "bios": { + "key": "BIOS", + "head": True, + "next": "onie" + }, + "bios_vendor": { + "parent": "bios", + "key": "Vendor", + "cmd": "dmidecode -t 0 |grep Vendor", + "pattern": r".*Vendor", + "separator": ":", + "arrt_index": 1, + }, + "bios_version": { + "parent": "bios", + "key": "Version", + "cmd": "dmidecode -t 0 |grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "bios_date": { + "parent": "bios", + "key": "Release Date", + "cmd": "dmidecode -t 0 |grep Release", + "pattern": r".*Release Date", + "separator": ":", + "arrt_index": 3, + }, -FRULISTS = { - "fans":[ - {"name":"fan1","bus":63,"loc":0x50, }, - {"name":"fan2","bus":55,"loc":0x50, }, - {"name":"fan3","bus":64,"loc":0x50, }, - {"name":"fan4","bus":56,"loc":0x50, }, - {"name":"fan5","bus":65,"loc":0x50, }, - {"name":"fan6","bus":57,"loc":0x50, } - ] , - "psus": [ - {"name":"psu1","bus":23,"loc":0x50}, - {"name":"psu2","bus":25,"loc":0x50 }, - {"name":"psu2","bus":24,"loc":0x50 }, - {"name":"psu2","bus":26,"loc":0x50 } - ] -} + "onie": { + "key": "ONIE", + "next": "cpu" + }, + "onie_date": { + "parent": "onie", + "key": "Build Date", + "file": "/host/machine.conf", + "pattern": r"^onie_build_date", + "separator": "=", + "arrt_index": 1, + }, + "onie_version": { + "parent": "onie", + "key": "Version", + "file": "/host/machine.conf", + "pattern": r"^onie_version", + "separator": "=", + "arrt_index": 2, + }, -# INIT_PARAM = [ -# {"loc":"3-0030/sfp_led_reset","value": "ff"}, -# {"loc":"3-0031/sfp_led_reset","value": "ff"}, -# {"loc":"4-0030/sfp_led_reset","value": "ff"}, -# {"loc":"4-0031/sfp_led_reset","value": "ff"}, -# {"loc":"5-0030/sfp_led_reset","value": "ff"}, -# {"loc":"5-0031/sfp_led_reset","value": "ff"}, -# {"loc":"6-0030/sfp_led_reset","value": "ff"}, -# {"loc":"6-0031/sfp_led_reset","value": "ff"}, -# ] -# INIT_COMMAND = [ -# "grtd_test.py io wr 0xb19 0xff", -# ] - -INIT_PARAM = [ - { - "name": "sfp_led_reset1", - "bus": 3, - "devaddr": 0x30, - "offset": 0xa0, - "val": 0xff, + "cpu": { + "key": "CPU", + "next": "ssd" }, - { - "name": "sfp_led_reset2", - "bus": 3, - "devaddr": 0x31, - "offset": 0xa0, - "val": 0xff, + "cpu_vendor": { + "parent": "cpu", + "key": "Vendor", + "cmd": "dmidecode --type processor |grep Manufacturer", + "pattern": r".*Manufacturer", + "separator": ":", + "arrt_index": 1, }, - { - "name": "sfp_led_reset3", - "bus": 4, - "devaddr": 0x30, - "offset": 0xa0, - "val": 0xff, + "cpu_model": { + "parent": "cpu", + "key": "Device Model", + "cmd": "dmidecode --type processor | grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, }, - { - "name": "sfp_led_reset4", - "bus": 4, - "devaddr": 0x31, - "offset": 0xa0, - "val": 0xff, + "cpu_core": { + "parent": "cpu", + "key": "Core Count", + "cmd": "dmidecode --type processor | grep \"Core Count\"", + "pattern": r".*Core Count", + "separator": ":", + "arrt_index": 3, }, - { - "name": "sfp_led_reset5", - "bus": 5, - "devaddr": 0x30, - "offset": 0xa0, - "val": 0xff, + "cpu_thread": { + "parent": "cpu", + "key": "Thread Count", + "cmd": "dmidecode --type processor | grep \"Thread Count\"", + "pattern": r".*Thread Count", + "separator": ":", + "arrt_index": 4, }, - { - "name": "sfp_led_reset6", - "bus": 5, - "devaddr": 0x31, - "offset": 0xa0, - "val": 0xff, + + "ssd": { + "key": "SSD", + "next": "slot" }, - { - "name": "sfp_led_reset7", - "bus": 6, - "devaddr": 0x30, - "offset": 0xa0, - "val": 0xff, + "ssd_model": { + "parent": "ssd", + "key": "Device Model", + "cmd": "smartctl -i /dev/sda |grep \"Device Model\"", + "pattern": r".*Device Model", + "separator": ":", + "arrt_index": 1, }, - { - "name": "sfp_led_reset8", - "bus": 6, - "devaddr": 0x31, - "offset": 0xa0, - "val": 0xff, + "ssd_fw": { + "parent": "ssd", + "key": "Firmware Version", + "cmd": "smartctl -i /dev/sda |grep \"Firmware Version\"", + "pattern": r".*Firmware Version", + "separator": ":", + "arrt_index": 2, + }, + "ssd_user_cap": { + "parent": "ssd", + "key": "User Capacity", + "cmd": "smartctl -i /dev/sda |grep \"User Capacity\"", + "pattern": r".*User Capacity", + "separator": ":", + "arrt_index": 3, }, - { - "name": "mac_power_on", - "type": "io", - "offset": 0xb19, - "val": 0xff - } -] -#rg_eeprom = "0-0054/eeprom" -E2_LOC = {"bus":1, "devno":0x56} -E2_PROTECT = {"io_addr":0xb45, "gettype":"io", "open":0, "close":1} - -CPLDVERSIONS = [ - {"bus":13, "devno":0x0d, "name":"FAN_CPLD_B"}, - {"bus":14, "devno":0x0d, "name":"FAN_CPLD_A"}, - {"bus":3, "devno":0x30, "name":"LC1_CPLD_1"}, - {"bus":3, "devno":0x31, "name":"LC1_CPLD_2"}, - {"bus":4, "devno":0x30, "name":"LC2_CPLD_1"}, - {"bus":4, "devno":0x31, "name":"LC2_CPLD_2"}, - {"bus":5, "devno":0x30, "name":"LC3_CPLD_1"}, - {"bus":5, "devno":0x31, "name":"LC3_CPLD_2"}, - {"bus":6, "devno":0x30, "name":"LC4_CPLD_1"}, - {"bus":6, "devno":0x31, "name":"LC4_CPLD_2"}, - {"io_addr":0x700, "name":"X86_CPLD", "gettype":"io"}, - {"io_addr":0x900, "name":"MAC_CPLD_B", "gettype":"io"}, - {"io_addr":0xb00, "name":"MAC_CPLD_A", "gettype":"io"}, -] -DRIVERLISTS = [] - - -TEMPIDCHANGE = { - "lm75in": "inlet", - "lm75out": "outlet", - "lm75hot": "hot-point", - "slot1lm75a1": "LINE CARD1 lm751", - "slot1lm75a2": "LINE CARD1 lm752", - "slot1lm75a3": "LINE CARD1 lm753", - "slot2lm75a1": "LINE CARD2 lm751", - "slot2lm75a2": "LINE CARD2 lm752", - "slot2lm75a3": "LINE CARD2 lm753", - "slot3lm75a1": "LINE CARD3 lm751", - "slot3lm75a2": "LINE CARD3 lm752", - "slot3lm75a3": "LINE CARD3 lm753", - "slot4lm75a1": "LINE CARD4 lm751", - "slot4lm75a2": "LINE CARD4 lm752", - "slot4lm75a3": "LINE CARD4 lm753", - "inlet": "lm75in", - "outlet": "lm75out", - "hot-point": "lm75hot", -} + "slot": { + "key": "SLOT", + "next": "cpld" + }, + "slot1": { + "key": "SLOT1", + "parent": "slot", + "arrt_index": 1, + }, + "slot1_hw_version": { + "key": "Hardware Version", + "parent": "slot1", + "extra": { + "funcname": "checkSlot", + "id": "slot1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "slot2": { + "key": "SLOT2", + "parent": "slot", + "arrt_index": 2, + }, + "slot2_hw_version": { + "key": "Hardware Version", + "parent": "slot2", + "extra": { + "funcname": "checkSlot", + "id": "slot2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "slot3": { + "key": "SLOT3", + "parent": "slot", + "arrt_index": 3, + }, + "slot3_hw_version": { + "key": "Hardware Version", + "parent": "slot3", + "extra": { + "funcname": "checkSlot", + "id": "slot3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "slot4": { + "key": "SLOT4", + "parent": "slot", + "arrt_index": 4, + }, + "slot4_hw_version": { + "key": "Hardware Version", + "parent": "slot4", + "extra": { + "funcname": "checkSlot", + "id": "slot4", + "key": "hw_version" + }, + "arrt_index": 1, + }, -DEVICE = [] + "cpld": { + "key": "CPLD", + "next": "psu" + }, + "cpld1": { + "key": "CPLD1", + "parent": "cpld", + "arrt_index": 1, + }, + "cpld1_model": { + "key": "Device Model", + "parent": "cpld1", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld1_vender": { + "key": "Vendor", + "parent": "cpld1", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld1_desc": { + "key": "Description", + "parent": "cpld1", + "config": "CPU_CPLD", + "arrt_index": 3, + }, + "cpld1_version": { + "key": "Firmware Version", + "parent": "cpld1", + "reg": { + "loc": "/dev/port", + "offset": 0x700, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -fanlevel = { - "tips":["LOW","MIDDLE","HIGH"], - "level":[51,128,255], - "low_speed":[1500,4500,9500], - "high_speed":[3000,7000,14000] -} + "cpld2": { + "key": "CPLD2", + "parent": "cpld", + "arrt_index": 2, + }, + "cpld2_model": { + "key": "Device Model", + "parent": "cpld2", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld2_vender": { + "key": "Vendor", + "parent": "cpld2", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld2_desc": { + "key": "Description", + "parent": "cpld2", + "config": "MAC_CPLD_A", + "arrt_index": 3, + }, + "cpld2_version": { + "key": "Firmware Version", + "parent": "cpld2", + "reg": { + "loc": "/dev/port", + "offset": 0xb00, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -fanloc =[ {"name":"FAN1", "location":"2-0020/fan1_pwm" , - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan1_input"},{"name":"BACK ROTOR", "location":"2-0020/fan2_input"} ]}, - {"name":"FAN2", "location":"2-0020/fan3_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan3_input"},{"name":"BACK ROTOR", "location":"2-0020/fan4_input"} ]}, - {"name":"FAN3", "location":"2-0020/fan5_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan5_input"},{"name":"BACK ROTOR", "location":"2-0020/fan6_input"} ]}, - {"name":"FAN4", "location":"2-0020/fan7_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan7_input"},{"name":"BACK ROTOR", "location":"2-0020/fan8_input"} ]}, - {"name":"FAN5", "location":"2-0020/fan9_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan9_input"},{"name":"BACK ROTOR", "location":"2-0020/fan10_input"} ]}, - {"name":"FAN6", "location":"2-0020/fan11_pwm", - "childfans":[{"name":"FRONT ROTOR", "location":"2-0020/fan11_input"},{"name":"BACK ROTOR", "location":"2-0020/fan12_input"} ]}, - ] - - -#################FAN speed args ############################## -MONITOR_TEMP_MIN = 30 -MONITOR_K = 14 -MONITOR_MAC_IN = 35 -MONITOR_DEFAULT_SPEED = 0x80 -MONITOR_MAX_SPEED = 0xFF -MONITOR_MIN_SPEED = 0x33 -MONITOR_MAC_ERROR_SPEED = 0XBB -MONITOR_FAN_TOTAL_NUM = 6 -MONITOR_MAC_UP_TEMP = 40 -MONITOR_MAC_LOWER_TEMP = -40 -MONITOR_MAC_MAX_TEMP = 100 - -MONITOR_FALL_TEMP = 2 -MONITOR_MAC_WARNING_THRESHOLD = 100 -MONITOR_OUTTEMP_WARNING_THRESHOLD = 85 -MONITOR_BOARDTEMP_WARNING_THRESHOLD = 85 -MONITOR_CPUTEMP_WARNING_THRESHOLD = 85 -MONITOR_INTEMP_WARNING_THRESHOLD = 70 - -MONITOR_MAC_CRITICAL_THRESHOLD = 105 -MONITOR_OUTTEMP_CRITICAL_THRESHOLD = 90 -MONITOR_BOARDTEMP_CRITICAL_THRESHOLD = 90 -MONITOR_CPUTEMP_CRITICAL_THRESHOLD = 100 -MONITOR_INTEMP_CRITICAL_THRESHOLD = 80 -MONITOR_CRITICAL_NUM = 2 -MONITOR_SHAKE_TIME = 10 -MONITOR_INTERVAL = 60 - -MONITOR_SYS_LED = [ -{ - "cmdstr":"/sys/devices/pci0000:00/0000:00:1f.0/broad_front_sys", - "yellow":0x06, - "red":0x02, - "green":0x04, - "type":"sysfs", -}, -] + "cpld3": { + "key": "CPLD3", + "parent": "cpld", + "arrt_index": 3, + }, + "cpld3_model": { + "key": "Device Model", + "parent": "cpld3", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld3_vender": { + "key": "Vendor", + "parent": "cpld3", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld3_desc": { + "key": "Description", + "parent": "cpld3", + "config": "MAC_CPLD_B", + "arrt_index": 3, + }, + "cpld3_version": { + "key": "Firmware Version", + "parent": "cpld3", + "reg": { + "loc": "/dev/port", + "offset": 0x900, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -MONITOR_SYS_FAN_LED =[ -{ - "cmdstr":"/sys/devices/pci0000:00/0000:00:1f.0/broad_front_fan", - "yellow":0x06, - "red":0x02, - "green":0x04, - "type":"sysfs", -}, -] + "cpld4": { + "key": "CPLD4", + "parent": "cpld", + "arrt_index": 4, + }, + "cpld4_model": { + "key": "Device Model", + "parent": "cpld4", + "config": "LCMXO2-2000HC-4MG132C", + "arrt_index": 1, + }, + "cpld4_vender": { + "key": "Vendor", + "parent": "cpld4", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld4_desc": { + "key": "Description", + "parent": "cpld4", + "config": "FAN_CPLD_A", + "arrt_index": 3, + }, + "cpld4_version": { + "key": "Firmware Version", + "parent": "cpld4", + "i2c": { + "bus": "14", + "loc": "0x0d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -MONITOR_FANS_LED = [ - {"bus":14,"devno":0x0d, "addr":0x3b, "green":0x04, "red":0x02}, - {"bus":13,"devno":0x0d, "addr":0x3b, "green":0x04, "red":0x02}, - {"bus":14,"devno":0x0d, "addr":0x3c, "green":0x04, "red":0x02}, - {"bus":13,"devno":0x0d, "addr":0x3c, "green":0x04, "red":0x02}, - {"bus":14,"devno":0x0d, "addr":0x3d, "green":0x04, "red":0x02}, - {"bus":13,"devno":0x0d, "addr":0x3d, "green":0x04, "red":0x02}, - ] - -DEV_LEDS = { - "SLOTLED":[ - {"name":'slot1',"bus":3,"devno":0x30, "addr":0x1a, "green":0x04, "red":0x02}, - {"name":'slot2',"bus":4,"devno":0x30, "addr":0x1a, "green":0x04, "red":0x02}, - {"name":'slot3',"bus":5,"devno":0x30, "addr":0x1a, "green":0x04, "red":0x02}, - {"name":'slot4',"bus":6,"devno":0x30, "addr":0x1a, "green":0x04, "red":0x02}, - ] -} + "cpld5": { + "key": "CPLD5", + "parent": "cpld", + "arrt_index": 5, + }, + "cpld5_model": { + "key": "Device Model", + "parent": "cpld5", + "config": "LCMXO2-2000HC-4MG132C", + "arrt_index": 1, + }, + "cpld5_vender": { + "key": "Vendor", + "parent": "cpld5", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld5_desc": { + "key": "Description", + "parent": "cpld5", + "config": "FAN_CPLD_B", + "arrt_index": 3, + }, + "cpld5_version": { + "key": "Firmware Version", + "parent": "cpld5", + "i2c": { + "bus": "13", + "loc": "0x0d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -MONITOR_SYS_PSU_LED =[ -{ - "cmdstr":"/sys/devices/pci0000:00/0000:00:1f.0/broad_front_pwr", - "yellow":0x06, - "red":0x02, - "green":0x04, - "type":"sysfs", -}, -] + "cpld6": { + "key": "CPLD6", + "parent": "cpld", + "arrt_index": 6, + }, + "cpld6_model": { + "key": "Device Model", + "parent": "cpld6", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld6_vender": { + "key": "Vendor", + "parent": "cpld6", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld6_desc": { + "key": "Description", + "parent": "cpld6", + "config": "LC1_CPLD_2", + "arrt_index": 3, + }, + "cpld6_version": { + "key": "Firmware Version", + "parent": "cpld6", + "i2c": { + "bus": "3", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, -MONITOR_FAN_STATUS = [ - {'status':'green' , 'minOkNum':6,'maxOkNum':6}, - {'status':'yellow', 'minOkNum':5,'maxOkNum':5}, - {'status':'red' , 'minOkNum':0,'maxOkNum':4}, - ] - -MONITOR_PSU_STATUS = [ - {'status':'green' , 'minOkNum':4,'maxOkNum':4}, - {'status':'yellow', 'minOkNum':3,'maxOkNum':3}, - {'status':'red' , 'minOkNum':0,'maxOkNum':2}, - ] - -MONITOR_DEV_STATUS = { - "temperature": [ - {"name":"lm75in", "location":"/sys/bus/i2c/devices/29-004f/hwmon/*/temp1_input"}, - {"name":"lm75out", "location":"/sys/bus/i2c/devices/28-004b/hwmon/*/temp1_input"}, - {"name":"lm75hot", "location":"/sys/bus/i2c/devices/28-004c/hwmon/*/temp1_input"}, - {"name":"cpu", "location":"/sys/class/hwmon/hwmon0"}, - ], - "fans": [ - { - "name":"fan1", - "presentstatus":{"bus":14, "loc":0x0d, "offset":0x30, 'bit':0}, - "rollstatus": [ - {"name":"motor1","bus":14, "loc":0x0d, "offset":0x31, 'bit':0}, - {"name":"motor2","bus":14, "loc":0x0d, "offset":0x34, 'bit':0}, - ] + "cpld7": { + "key": "CPLD7", + "parent": "cpld", + "arrt_index": 7, + }, + "cpld7_model": { + "key": "Device Model", + "parent": "cpld7", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld7_vender": { + "key": "Vendor", + "parent": "cpld7", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld7_desc": { + "key": "Description", + "parent": "cpld7", + "config": "LC1_CPLD_1", + "arrt_index": 3, + }, + "cpld7_version": { + "key": "Firmware Version", + "parent": "cpld7", + "i2c": { + "bus": "3", + "loc": "0x30", + "offset": 0, + "size": 4 }, - { - "name":"fan2", - "presentstatus":{"bus":13, "loc":0x0d, "offset":0x30, 'bit':0}, - "rollstatus": [ - {"name":"motor1","bus":13, "loc":0x0d, "offset":0x31, 'bit':0}, - {"name":"motor2","bus":13, "loc":0x0d, "offset":0x34, 'bit':0}, - ] + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld8": { + "key": "CPLD8", + "parent": "cpld", + "arrt_index": 8, + }, + "cpld8_model": { + "key": "Device Model", + "parent": "cpld8", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld8_vender": { + "key": "Vendor", + "parent": "cpld8", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld8_desc": { + "key": "Description", + "parent": "cpld8", + "config": "LC2_CPLD_2", + "arrt_index": 3, + }, + "cpld8_version": { + "key": "Firmware Version", + "parent": "cpld8", + "i2c": { + "bus": "4", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld9": { + "key": "CPLD9", + "parent": "cpld", + "arrt_index": 9, + }, + "cpld9_model": { + "key": "Device Model", + "parent": "cpld9", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld9_vender": { + "key": "Vendor", + "parent": "cpld9", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld9_desc": { + "key": "Description", + "parent": "cpld9", + "config": "LC2_CPLD_1", + "arrt_index": 3, + }, + "cpld9_version": { + "key": "Firmware Version", + "parent": "cpld9", + "i2c": { + "bus": "4", + "loc": "0x30", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld10": { + "key": "CPLD10", + "parent": "cpld", + "arrt_index": 10, + }, + "cpld10_model": { + "key": "Device Model", + "parent": "cpld10", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld10_vender": { + "key": "Vendor", + "parent": "cpld10", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld10_desc": { + "key": "Description", + "parent": "cpld10", + "config": "LC3_CPLD_2", + "arrt_index": 3, + }, + "cpld10_version": { + "key": "Firmware Version", + "parent": "cpld10", + "i2c": { + "bus": "5", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld11": { + "key": "CPLD11", + "parent": "cpld", + "arrt_index": 11, + }, + "cpld11_model": { + "key": "Device Model", + "parent": "cpld11", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld11_vender": { + "key": "Vendor", + "parent": "cpld11", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld11_desc": { + "key": "Description", + "parent": "cpld11", + "config": "LC3_CPLD_1", + "arrt_index": 3, + }, + "cpld11_version": { + "key": "Firmware Version", + "parent": "cpld11", + "i2c": { + "bus": "5", + "loc": "0x30", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld12": { + "key": "CPLD12", + "parent": "cpld", + "arrt_index": 12, + }, + "cpld12_model": { + "key": "Device Model", + "parent": "cpld12", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld12_vender": { + "key": "Vendor", + "parent": "cpld12", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld12_desc": { + "key": "Description", + "parent": "cpld12", + "config": "LC4_CPLD_2", + "arrt_index": 3, + }, + "cpld12_version": { + "key": "Firmware Version", + "parent": "cpld12", + "i2c": { + "bus": "6", + "loc": "0x31", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld13": { + "key": "CPLD13", + "parent": "cpld", + "arrt_index": 13, + }, + "cpld13_model": { + "key": "Device Model", + "parent": "cpld13", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld13_vender": { + "key": "Vendor", + "parent": "cpld13", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld13_desc": { + "key": "Description", + "parent": "cpld13", + "config": "LC4_CPLD_1", + "arrt_index": 3, + }, + "cpld13_version": { + "key": "Firmware Version", + "parent": "cpld13", + "i2c": { + "bus": "6", + "loc": "0x30", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "psu": { + "key": "PSU", + "next": "fan" + }, + + "psu1": { + "parent": "psu", + "key": "PSU1", + "arrt_index": 1, + }, + "psu1_hw_version": { + "key": "Hardware Version", + "parent": "psu1", + "extra": { + "funcname": "getPsu", + "id": "psu1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu1_fw_version": { + "key": "Firmware Version", + "parent": "psu1", + "config": "NA", + "arrt_index": 2, + }, + + "psu2": { + "parent": "psu", + "key": "PSU2", + "arrt_index": 2, + }, + "psu2_hw_version": { + "key": "Hardware Version", + "parent": "psu2", + "extra": { + "funcname": "getPsu", + "id": "psu2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu2_fw_version": { + "key": "Firmware Version", + "parent": "psu2", + "config": "NA", + "arrt_index": 2, + }, + + "psu3": { + "parent": "psu", + "key": "PSU3", + "arrt_index": 3, + }, + "psu3_hw_version": { + "key": "Hardware Version", + "parent": "psu3", + "extra": { + "funcname": "getPsu", + "id": "psu3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu3_fw_version": { + "key": "Firmware Version", + "parent": "psu3", + "config": "NA", + "arrt_index": 2, + }, + + "psu4": { + "parent": "psu", + "key": "PSU4", + "arrt_index": 4, + }, + "psu4_hw_version": { + "key": "Hardware Version", + "parent": "psu4", + "extra": { + "funcname": "getPsu", + "id": "psu4", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu4_fw_version": { + "key": "Firmware Version", + "parent": "psu4", + "config": "NA", + "arrt_index": 2, + }, + + "fan": { + "key": "FAN", + "next": "i210" + }, + + "fan1": { + "key": "FAN1", + "parent": "fan", + "arrt_index": 1, + }, + "fan1_hw_version": { + "key": "Hardware Version", + "parent": "fan1", + "extra": { + "funcname": "checkFan", + "id": "fan1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan1_fw_version": { + "key": "Firmware Version", + "parent": "fan1", + "config": "NA", + "arrt_index": 2, + }, + + "fan2": { + "key": "FAN2", + "parent": "fan", + "arrt_index": 2, + }, + "fan2_hw_version": { + "key": "Hardware Version", + "parent": "fan2", + "extra": { + "funcname": "checkFan", + "id": "fan2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan2_fw_version": { + "key": "Firmware Version", + "parent": "fan2", + "config": "NA", + "arrt_index": 2, + }, + + "fan3": { + "key": "FAN3", + "parent": "fan", + "arrt_index": 3, + }, + "fan3_hw_version": { + "key": "Hardware Version", + "parent": "fan3", + "extra": { + "funcname": "checkFan", + "id": "fan3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan3_fw_version": { + "key": "Firmware Version", + "parent": "fan3", + "config": "NA", + "arrt_index": 2, + }, + + "fan4": { + "key": "FAN4", + "parent": "fan", + "arrt_index": 4, + }, + "fan4_hw_version": { + "key": "Hardware Version", + "parent": "fan4", + "extra": { + "funcname": "checkFan", + "id": "fan4", + "key": "hw_version" }, + "arrt_index": 1, + }, + "fan4_fw_version": { + "key": "Firmware Version", + "parent": "fan4", + "config": "NA", + "arrt_index": 2, + }, + + "fan5": { + "key": "FAN5", + "parent": "fan", + "arrt_index": 5, + }, + "fan5_hw_version": { + "key": "Hardware Version", + "parent": "fan5", + "extra": { + "funcname": "checkFan", + "id": "fan5", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan5_fw_version": { + "key": "Firmware Version", + "parent": "fan5", + "config": "NA", + "arrt_index": 2, + }, + + "fan6": { + "key": "FAN6", + "parent": "fan", + "arrt_index": 6, + }, + "fan6_hw_version": { + "key": "Hardware Version", + "parent": "fan6", + "extra": { + "funcname": "checkFan", + "id": "fan6", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan6_fw_version": { + "key": "Firmware Version", + "parent": "fan6", + "config": "NA", + "arrt_index": 2, + }, + + "i210": { + "key": "NIC", + }, + "i210_model": { + "parent": "i210", + "config": "NA", + "key": "Device Model", + "arrt_index": 1, + }, + "i210_vendor": { + "parent": "i210", + "config": "INTEL", + "key": "Vendor", + "arrt_index": 2, + }, + "i210_version": { + "parent": "i210", + "cmd": "ethtool -i eth0", + "pattern": r"firmware-version", + "separator": ":", + "key": "Firmware Version", + "arrt_index": 3, + }, +} + +PMON_SYSLOG_STATUS = { + "polling_time": 3, + "sffs": { + "present": {"path": ["/sys/wb_plat/sff/*/present"], "ABSENT":0}, + "nochangedmsgflag": 0, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 1, + "alias": { + "eth1": "Eth100GE1-1", + "eth2": "Eth100GE1-2", + "eth3": "Eth100GE1-3", + "eth4": "Eth100GE1-4", + "eth5": "Eth100GE1-5", + "eth6": "Eth100GE1-6", + "eth7": "Eth100GE1-7", + "eth8": "Eth100GE1-8", + "eth9": "Eth100GE1-9", + "eth10": "Eth100GE1-10", + "eth11": "Eth100GE1-11", + "eth12": "Eth100GE1-12", + "eth13": "Eth100GE1-13", + "eth14": "Eth100GE1-14", + "eth15": "Eth100GE1-15", + "eth16": "Eth100GE1-16", + "eth17": "Eth100GE1-17", + "eth18": "Eth100GE1-18", + "eth19": "Eth100GE1-19", + "eth20": "Eth100GE1-20", + "eth21": "Eth100GE1-21", + "eth22": "Eth100GE1-22", + "eth23": "Eth100GE1-23", + "eth24": "Eth100GE1-24", + "eth25": "Eth100GE1-25", + "eth26": "Eth100GE1-26", + "eth27": "Eth100GE1-27", + "eth28": "Eth100GE1-28", + "eth29": "Eth100GE1-29", + "eth30": "Eth100GE1-30", + "eth31": "Eth100GE1-31", + "eth32": "Eth100GE1-32", + "eth33": "Eth100GE2-1", + "eth34": "Eth100GE2-2", + "eth35": "Eth100GE2-3", + "eth36": "Eth100GE2-4", + "eth37": "Eth100GE2-5", + "eth38": "Eth100GE2-6", + "eth39": "Eth100GE2-7", + "eth40": "Eth100GE2-8", + "eth41": "Eth100GE2-9", + "eth42": "Eth100GE2-10", + "eth43": "Eth100GE2-11", + "eth44": "Eth100GE2-12", + "eth45": "Eth100GE2-13", + "eth46": "Eth100GE2-14", + "eth47": "Eth100GE2-15", + "eth48": "Eth100GE2-16", + "eth49": "Eth100GE2-17", + "eth50": "Eth100GE2-18", + "eth51": "Eth100GE2-19", + "eth52": "Eth100GE2-20", + "eth53": "Eth100GE2-21", + "eth54": "Eth100GE2-22", + "eth55": "Eth100GE2-23", + "eth56": "Eth100GE2-24", + "eth57": "Eth100GE2-25", + "eth58": "Eth100GE2-26", + "eth59": "Eth100GE2-27", + "eth60": "Eth100GE2-28", + "eth61": "Eth100GE2-29", + "eth62": "Eth100GE2-30", + "eth63": "Eth100GE2-31", + "eth64": "Eth100GE2-32", + "eth65": "Eth100GE3-1", + "eth66": "Eth100GE3-2", + "eth67": "Eth100GE3-3", + "eth68": "Eth100GE3-4", + "eth69": "Eth100GE3-5", + "eth70": "Eth100GE3-6", + "eth71": "Eth100GE3-7", + "eth72": "Eth100GE3-8", + "eth73": "Eth100GE3-9", + "eth74": "Eth100GE3-10", + "eth75": "Eth100GE3-11", + "eth76": "Eth100GE3-12", + "eth77": "Eth100GE3-13", + "eth78": "Eth100GE3-14", + "eth79": "Eth100GE3-15", + "eth80": "Eth100GE3-16", + "eth81": "Eth100GE3-17", + "eth82": "Eth100GE3-18", + "eth83": "Eth100GE3-19", + "eth84": "Eth100GE3-20", + "eth85": "Eth100GE3-21", + "eth86": "Eth100GE3-22", + "eth87": "Eth100GE3-23", + "eth88": "Eth100GE3-24", + "eth89": "Eth100GE3-25", + "eth90": "Eth100GE3-26", + "eth91": "Eth100GE3-27", + "eth92": "Eth100GE3-28", + "eth93": "Eth100GE3-29", + "eth94": "Eth100GE3-30", + "eth95": "Eth100GE3-31", + "eth96": "Eth100GE3-32", + "eth97": "Eth100GE4-1", + "eth98": "Eth100GE4-2", + "eth99": "Eth100GE4-3", + "eth100": "Eth100GE4-4", + "eth101": "Eth100GE4-5", + "eth102": "Eth100GE4-6", + "eth103": "Eth100GE4-7", + "eth104": "Eth100GE4-8", + "eth105": "Eth100GE4-9", + "eth106": "Eth100GE4-10", + "eth107": "Eth100GE4-11", + "eth108": "Eth100GE4-12", + "eth109": "Eth100GE4-13", + "eth110": "Eth100GE4-14", + "eth111": "Eth100GE4-15", + "eth112": "Eth100GE4-16", + "eth113": "Eth100GE4-17", + "eth114": "Eth100GE4-18", + "eth115": "Eth100GE4-19", + "eth116": "Eth100GE4-20", + "eth117": "Eth100GE4-21", + "eth118": "Eth100GE4-22", + "eth119": "Eth100GE4-23", + "eth120": "Eth100GE4-24", + "eth121": "Eth100GE4-25", + "eth122": "Eth100GE4-26", + "eth123": "Eth100GE4-27", + "eth124": "Eth100GE4-28", + "eth125": "Eth100GE4-29", + "eth126": "Eth100GE4-30", + "eth127": "Eth100GE4-31", + "eth128": "Eth100GE4-32", + } + }, + "slots": { + "present": {"path": ["/sys/wb_plat/slot/*/status"], "ABSENT":0}, + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "slot1": "SLOT1", + "slot2": "SLOT2", + "slot3": "SLOT3", + "slot4": "SLOT4", + } + }, + "fans": { + "present": {"path": ["/sys/wb_plat/fan/*/present"], "ABSENT":0}, + "status": [ + {"path": "/sys/wb_plat/fan/%s/motor0/status", 'okval': 1}, + {"path": "/sys/wb_plat/fan/%s/motor1/status", 'okval': 1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "fan1": "FAN1", + "fan2": "FAN2", + "fan3": "FAN3", + "fan4": "FAN4", + "fan5": "FAN5", + "fan6": "FAN6" + } + }, + "psus": { + "present" : {"path": ["/sys/wb_plat/psu/*/present"], "ABSENT":0}, + "status" : [ + {"path": "/sys/wb_plat/psu/%s/output", "okval":1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "psu1": "PSU1", + "psu2": "PSU2", + "psu3": "PSU3", + "psu4": "PSU4", + } + } +} + +REBOOT_CAUSE_PARA = { + "reboot_cause_list": [ { - "name":"fan3", - "presentstatus":{"bus":14, "loc":0x0d, "offset":0x30, 'bit':1}, - "rollstatus": [ - {"name":"motor1","bus":14, "loc":0x0d, "offset":0x31, 'bit':1}, - {"name":"motor2","bus":14, "loc":0x0d, "offset":0x34, 'bit':1}, + "name": "cold_reboot", + "monitor_point": {"gettype": "io", "io_addr": 0xb88, "okval": 0}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Power Loss, ", + "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Power Loss, ", + "path": "/etc/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} ] }, { - "name":"fan4", - "presentstatus":{"bus":13, "loc":0x0d, "offset":0x30, 'bit':1}, - "rollstatus": [ - {"name":"motor1","bus":13, "loc":0x0d, "offset":0x31, 'bit':1}, - {"name":"motor2","bus":13, "loc":0x0d, "offset":0x34, 'bit':1}, - ] + "name": "reboot", + "monitor_point": {"gettype": "io", "io_addr": 0xb88, "okval": 0, "compare_mode": "great"}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Reboot, ", + "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Reboot, ", + "path": "/etc/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], }, { - "name":"fan5", - "presentstatus":{"bus":14, "loc":0x0d, "offset":0x30, 'bit':2}, - "rollstatus": [ - {"name":"motor1","bus":14, "loc":0x0d, "offset":0x31, 'bit':2}, - {"name":"motor2","bus":14, "loc":0x0d, "offset":0x34, 'bit':2}, + "name": "otp_switch_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_switch_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: ASIC, ", + "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: ASIC, ", + "path": "/etc/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_switch_reboot_flag"}, ] }, { - "name":"fan6", - "presentstatus":{"bus":13, "loc":0x0d, "offset":0x30, 'bit':2}, - "rollstatus": [ - {"name":"motor1","bus":13, "loc":0x0d, "offset":0x31, 'bit':2}, - {"name":"motor2","bus":13, "loc":0x0d, "offset":0x34, 'bit':2}, + "name": "otp_other_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_other_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: Other, ", + "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: Other, ", + "path": "/etc/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_other_reboot_flag"}, ] }, ], - "psus": [ - {"name":"psu1", "io_addr":0xb27, "gettype":"io", 'presentbit': 0, 'statusbit':1, 'alertbit':2}, - {"name":"psu2", "io_addr":0xb28, "gettype":"io", 'presentbit': 0, 'statusbit':1, 'alertbit':2}, - {"name":"psu3", "io_addr":0xb29, "gettype":"io", 'presentbit': 0, 'statusbit':1, 'alertbit':2}, - {"name":"psu4", "io_addr":0xb2a, "gettype":"io", 'presentbit': 0, 'statusbit':1, 'alertbit':2} - ], - "slots": [ - {"name":"slot1", "io_addr":0xb2c, "gettype":"io", 'presentbit': 4}, - {"name":"slot2", "io_addr":0xb2c, "gettype":"io", 'presentbit': 5}, - {"name":"slot3", "io_addr":0xb2c, "gettype":"io", 'presentbit': 6}, - {"name":"slot4", "io_addr":0xb2c, "gettype":"io", 'presentbit': 7} + "other_reboot_cause_record": [ + {"record_type": "file", "mode": "cover", "log": "Other, ", "path": "/etc/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Other, ", "path": "/etc/.reboot/.history-reboot-cause.txt"} ], - "mac_temp" : { - "loc" : [ - "28-004c/hwmon/*/temp2_input", - "29-004c/hwmon/*/temp2_input", - ], - }, } -MONITOR_DEV_STATUS_DECODE = { - 'fanpresent' : {0:'PRESENT', 1:'ABSENT', 'okval':0}, - 'fanroll' : {0:'STALL' , 1:'ROLL', 'okval':1}, - 'psupresent' : {0:'PRESENT', 1:'ABSENT', 'okval':0}, - 'psuoutput' : {0:'FAULT' , 1:'NORMAL', 'okval':1}, - 'psualert' : {0:'FAULT' , 1:'NORMAL', 'okval':1}, - 'slotpresent': {0:'PRESENT', 1:'ABSENT', 'okval':0}, -} +INIT_PARAM_PRE = [ + {"loc": "30-0064/hwmon/hwmon*/avs1_vout_max", "value": "900000"}, + {"loc": "30-0064/hwmon/hwmon*/avs1_vout_min", "value": "750000"}, +] + +INIT_COMMAND_PRE = [] + +INIT_PARAM = [] + +INIT_COMMAND = [ + "dfd_debug io_wr 0xb19 0xff", + "i2cset -y -f 3 0x30 0xa0 0xff", + "i2cset -y -f 3 0x31 0xa0 0xff", + "i2cset -y -f 4 0x30 0xa0 0xff", + "i2cset -y -f 4 0x31 0xa0 0xff", + "i2cset -y -f 5 0x30 0xa0 0xff", + "i2cset -y -f 5 0x31 0xa0 0xff", + "i2cset -y -f 6 0x30 0xa0 0xff", + "i2cset -y -f 6 0x31 0xa0 0xff", +] + +BLACKLIST_DRIVERS = [ + {"name": "i2c_i801", "delay": 0}, +] + +DRIVERLISTS = [ + {"name": "wb_i2c_i801", "delay": 0}, + {"name": "wb_gpio_d1500", "delay": 0}, + {"name": "i2c_dev", "delay": 0}, + {"name": "wb_i2c_algo_bit", "delay": 0}, + {"name": "wb_i2c_gpio", "delay": 0}, + {"name": "i2c_mux", "delay": 0}, + {"name": "wb_gpio_device", "delay": 0}, + {"name": "wb_i2c_gpio_device gpio_sda=17 gpio_scl=1 gpio_udelay=2", "delay": 0}, + {"name": "platform_common dfd_my_type_i2c_bus=1 dfd_my_type_i2c_addr=0x56", "delay": 0}, + {"name": "wb_lpc_drv", "delay": 0}, + {"name": "wb_lpc_drv_device", "delay": 0}, + {"name": "wb_io_dev", "delay": 0}, + {"name": "wb_io_dev_device", "delay": 0}, + {"name": "wb_i2c_dev", "delay": 0}, + {"name": "wb_i2c_ocores", "delay": 0}, + {"name": "wb_i2c_ocores_device", "delay": 0}, + {"name": "wb_i2c_mux_pca9641", "delay": 0}, + {"name": "wb_i2c_mux_pca954x", "delay": 0}, + {"name": "wb_i2c_mux_pca954x_device", "delay": 0}, + {"name": "wb_platform_i2c_dev", "delay": 0}, + {"name": "wb_platform_i2c_dev_device", "delay": 0}, + {"name": "wb_lm75", "delay": 0}, + {"name": "wb_tmp401", "delay": 0}, + {"name": "wb_optoe", "delay": 0}, + {"name": "wb_at24", "delay": 0}, + {"name": "wb_pmbus_core", "delay": 0}, + {"name": "wb_csu550", "delay": 0}, + {"name": "wb_isl68137", "delay": 0}, + {"name": "wb_mac_bsc", "delay": 0}, + {"name": "wb_tps53622", "delay": 0}, + {"name": "firmware_driver_cpld", "delay": 0}, + {"name": "firmware_driver_ispvme", "delay": 0}, + {"name": "firmware_driver_sysfs", "delay": 0}, + {"name": "wb_firmware_upgrade_device", "delay": 0}, + {"name": "plat_dfd", "delay": 0}, + {"name": "plat_switch", "delay": 0}, + {"name": "plat_fan", "delay": 0}, + {"name": "plat_psu", "delay": 0}, + {"name": "plat_sff", "delay": 0}, + {"name": "plat_sensor", "delay": 0}, + {"name": "plat_slot", "delay": 0}, +] + +DEVICE = [ + {"name": "wb_lm75", "bus": 28, "loc": 0x4B}, + {"name": "wb_tmp411", "bus": 28, "loc": 0x4C}, + {"name": "wb_tmp411", "bus": 29, "loc": 0x4C}, + {"name": "wb_lm75", "bus": 29, "loc": 0x4F}, + {"name": "wb_lm75", "bus": 68, "loc": 0x48}, + {"name": "wb_lm75", "bus": 68, "loc": 0x49}, + {"name": "wb_lm75", "bus": 60, "loc": 0x48}, + {"name": "wb_lm75", "bus": 60, "loc": 0x49}, + {"name": "wb_lm75", "bus": 32, "loc": 0x48}, + {"name": "wb_lm75", "bus": 32, "loc": 0x49}, + {"name": "wb_lm75", "bus": 32, "loc": 0x4D}, + {"name": "wb_lm75", "bus": 48, "loc": 0x48}, + {"name": "wb_lm75", "bus": 48, "loc": 0x49}, + {"name": "wb_lm75", "bus": 48, "loc": 0x4D}, + {"name": "wb_lm75", "bus": 40, "loc": 0x48}, + {"name": "wb_lm75", "bus": 40, "loc": 0x49}, + {"name": "wb_lm75", "bus": 40, "loc": 0x4D}, + {"name": "wb_lm75", "bus": 16, "loc": 0x48}, + {"name": "wb_lm75", "bus": 16, "loc": 0x49}, + {"name": "wb_lm75", "bus": 16, "loc": 0x4D}, + {"name": "wb_24c02", "bus": 1, "loc": 0x56}, + # fan + {"name": "wb_24c02", "bus": 63, "loc": 0x50}, + {"name": "wb_24c02", "bus": 55, "loc": 0x50}, + {"name": "wb_24c02", "bus": 64, "loc": 0x50}, + {"name": "wb_24c02", "bus": 56, "loc": 0x50}, + {"name": "wb_24c02", "bus": 65, "loc": 0x50}, + {"name": "wb_24c02", "bus": 57, "loc": 0x50}, + # slot + {"name": "wb_24c02", "bus": 3, "loc": 0x57}, + {"name": "wb_24c02", "bus": 4, "loc": 0x57}, + {"name": "wb_24c02", "bus": 5, "loc": 0x57}, + {"name": "wb_24c02", "bus": 6, "loc": 0x57}, + {"name": "wb_24c02", "bus": 3, "loc": 0x56}, + {"name": "wb_24c02", "bus": 4, "loc": 0x56}, + {"name": "wb_24c02", "bus": 5, "loc": 0x56}, + {"name": "wb_24c02", "bus": 6, "loc": 0x56}, + # psu + {"name": "wb_24c02", "bus": 23, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 23, "loc": 0x58}, + {"name": "wb_24c02", "bus": 25, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 25, "loc": 0x58}, + {"name": "wb_24c02", "bus": 24, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 24, "loc": 0x58}, + {"name": "wb_24c02", "bus": 26, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 26, "loc": 0x58}, + {"name": "wb_isl68127", "bus": 30, "loc": 0x64}, + #mac bsc + {"name": "wb_mac_bsc_th3", "bus": 27, "loc": 0x44}, + {"name": "wb_tps53622", "bus": 10, "loc": 0x60}, + {"name": "wb_tps53622", "bus": 10, "loc": 0x6c}, +] + +OPTOE = [ + {"name": "wb_optoe1", "startbus": 71, "endbus": 198}, +] SLOT_MONITOR_PARAM = { - "polling_time" : 0.5, + "polling_time": 0.5, "slots": [ - {"name":"slot1", - "present":{"gettype":"io", "io_addr":0xb2c,"presentbit": 4,"okval":0}, - "act":[ - {"io_addr":0xb19, "value":0x01, "mask":0xfe, "gettype":"io"}, - {"bus":3, "loc":0x30, "offset":0xa0, "value":0xff,"gettype":"i2c"}, - {"bus":3, "loc":0x31, "offset":0xa0, "value":0xff,"gettype":"i2c"}, + {"name": "slot1", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 4, "okval": 0}, + "act": [ + {"io_addr": 0xb19, "value": 0x01, "mask": 0xfe, "gettype": "io"}, + {"bus": 3, "loc": 0x30, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, + {"bus": 3, "loc": 0x31, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, ], - }, - {"name":"slot2", - "present":{"gettype":"io", "io_addr":0xb2c,"presentbit": 5,"okval":0}, - "act":[ - {"io_addr":0xb19, "value":0x02, "mask":0xfd, "gettype":"io"}, - {"bus":4, "loc":0x30, "offset":0xa0, "value":0xff,"gettype":"i2c"}, - {"bus":4, "loc":0x31, "offset":0xa0, "value":0xff,"gettype":"i2c"}, + }, + {"name": "slot2", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 5, "okval": 0}, + "act": [ + {"io_addr": 0xb19, "value": 0x02, "mask": 0xfd, "gettype": "io"}, + {"bus": 4, "loc": 0x30, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, + {"bus": 4, "loc": 0x31, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, ], - }, - {"name":"slot3", - "present":{"gettype":"io", "io_addr":0xb2c,"presentbit": 6,"okval":0}, - "act":[ - {"io_addr":0xb19, "value":0x04, "mask":0xfb, "gettype":"io"}, - {"bus":5, "loc":0x30, "offset":0xa0, "value":0xff,"gettype":"i2c"}, - {"bus":5, "loc":0x31, "offset":0xa0, "value":0xff,"gettype":"i2c"}, + }, + {"name": "slot3", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 6, "okval": 0}, + "act": [ + {"io_addr": 0xb19, "value": 0x04, "mask": 0xfb, "gettype": "io"}, + {"bus": 5, "loc": 0x30, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, + {"bus": 5, "loc": 0x31, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, ], - }, - {"name":"slot4", - "present":{"gettype":"io", "io_addr":0xb2c,"presentbit": 7,"okval":0}, - "act":[ - {"io_addr":0xb19, "value":0x08, "mask":0xf7, "gettype":"io"}, - {"bus":6, "loc":0x30, "offset":0xa0, "value":0xff,"gettype":"i2c"}, - {"bus":6, "loc":0x31, "offset":0xa0, "value":0xff,"gettype":"i2c"}, + }, + {"name": "slot4", + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 7, "okval": 0}, + "act": [ + {"io_addr": 0xb19, "value": 0x08, "mask": 0xf7, "gettype": "io"}, + {"bus": 6, "loc": 0x30, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, + {"bus": 6, "loc": 0x31, "offset": 0xa0, "value": 0xff, "gettype": "i2c"}, ], - }, + }, ], } -#####################MAC AVS ARGS (B6920-4S) #################################### -MAC_AVS_PARAM ={ - 0x72:0x0384 , - 0x73:0x037e , - 0x74:0x0378 , - 0x75:0x0372 , - 0x76:0x036b , - 0x77:0x0365 , - 0x78:0x035f , - 0x79:0x0359 , - 0x7a:0x0352 , - 0x7b:0x034c , - 0x7c:0x0346 , - 0x7d:0x0340 , - 0x7e:0x0339 , - 0x7f:0x0333 , - 0x80:0x032d , - 0x81:0x0327 , - 0x82:0x0320 , - 0x83:0x031a , - 0x84:0x0314 , - 0x85:0x030e , - 0x86:0x0307 , - 0x87:0x0301 , - 0x88:0x02fb , - 0x89:0x02f5 , - 0x8A:0x02ee -} +##################### MAC Voltage adjust#################################### +MAC_DEFAULT_PARAM = [ + { + "name": "mac_core", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default": 0x73, # default value, if rov value not in range + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + "cpld_avs": {"io_addr": 0x932, "gettype": "io"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/30-0064/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x72: 0.900, + 0x73: 0.894, + 0x74: 0.888, + 0x75: 0.882, + 0x76: 0.875, + 0x77: 0.869, + 0x78: 0.863, + 0x79: 0.857, + 0x7a: 0.850, + 0x7b: 0.844, + 0x7c: 0.838, + 0x7d: 0.832, + 0x7e: 0.825, + 0x7f: 0.819, + 0x80: 0.813, + 0x81: 0.807, + 0x82: 0.800, + 0x83: 0.794, + 0x84: 0.788, + 0x85: 0.782, + 0x86: 0.775, + 0x87: 0.769, + 0x88: 0.763, + 0x89: 0.757, + 0x8A: 0.750 + } + } +] + +UPGRADE_SUMMARY = { + "devtype": 0x404d, + + "slot0": { + "subtype": 0, + "VME": { + "chain1": { + "name": "BOARD_CPLD", + "is_support_warm_upg": 0, + }, + }, + + "MTD": { + "chain1": { + "name": "BIOS", + "is_support_warm_upg": 0, + "filesizecheck": 10240, # bios check file size, Unit: K + "init_cmd": [ + {"io_addr": 0x722, "value": 0x02, "gettype": "io"}, + {"cmd": "modprobe mtd", "gettype": "cmd"}, + {"cmd": "modprobe spi_nor", "gettype": "cmd"}, + {"cmd": "modprobe ofpart", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi writeable=1", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi_platform writeable=1", "gettype": "cmd"}, + ], + "finish_cmd": [ + {"io_addr": 0x722, "value": 0x02, "gettype": "io"}, + {"cmd": "rmmod intel_spi_platform", "gettype": "cmd"}, + {"cmd": "rmmod intel_spi", "gettype": "cmd"}, + {"cmd": "rmmod ofpart", "gettype": "cmd"}, + {"cmd": "rmmod spi_nor", "gettype": "cmd"}, + {"cmd": "rmmod mtd", "gettype": "cmd"}, + ], + }, + }, + + "TEST": { + "cpld": [ + {"chain": 1, "file": "/etc/.upgrade_test/board_cpld_test_header.vme", "display_name": "BOARD_CPLD"}, + ], + }, + }, + + "slot1": { + "subtype": 0x4045, + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 4, "okval": 0}, + "VME": { + "chain0": { + "name": "SLOT1_CPLD", + "is_support_warm_upg": 0, + }, + }, + + "TEST": { + "cpld": [ + {"chain": 0, "file": "/etc/.upgrade_test/slot_cpld_test_header.vme", "display_name": "SLOT1_CPLD"}, + ], + }, + }, + + "slot2": { + "subtype": 0x4045, + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 5, "okval": 0}, + "VME": { + "chain0": { + "name": "SLOT2_CPLD", + "is_support_warm_upg": 0, + }, + }, + + "TEST": { + "cpld": [ + {"chain": 0, "file": "/etc/.upgrade_test/slot_cpld_test_header.vme", "display_name": "SLOT2_CPLD"}, + ], + }, + }, + + "slot3": { + "subtype": 0x4045, + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 6, "okval": 0}, + "VME": { + "chain0": { + "name": "SLOT3_CPLD", + "is_support_warm_upg": 0, + }, + }, + + "TEST": { + "cpld": [ + {"chain": 0, "file": "/etc/.upgrade_test/slot_cpld_test_header.vme", "display_name": "SLOT3_CPLD"}, + ], + }, + }, + + "slot4": { + "subtype": 0x4045, + "present": {"gettype": "io", "io_addr": 0xb2c, "presentbit": 7, "okval": 0}, + "VME": { + "chain0": { + "name": "SLOT4_CPLD", + "is_support_warm_upg": 0, + }, + }, + "TEST": { + "cpld": [ + {"chain": 0, "file": "/etc/.upgrade_test/slot_cpld_test_header.vme", "display_name": "SLOT4_CPLD"}, + ], + }, + }, +} -MAC_DEFAULT_PARAM = { - "type": 1, - "default":0x73, - "loopaddr":0x00, - "loop":0x01, - "open":0x00, - "close":0x40, - "bus":30, - "devno":0x64, - "addr":0x21, - "protectaddr":0x10, - "sdkreg":"DMU_PCU_OTP_CONFIG_4", - "sdkcmd": "scdcmd", - "sdkcmdargs": ["-t", 5], - "sdktype": 1, - "macregloc":8, - "mask": 0xff +PLATFORM_E2_CONF = { + "fan": [ + {"name": "fan1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/63-0050/eeprom"}, + {"name": "fan2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/55-0050/eeprom"}, + {"name": "fan3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/64-0050/eeprom"}, + {"name": "fan4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/56-0050/eeprom"}, + {"name": "fan5", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/65-0050/eeprom"}, + {"name": "fan6", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/57-0050/eeprom"}, + ], + "psu": [ + {"name": "psu1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/23-0050/eeprom"}, + {"name": "psu2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/25-0050/eeprom"}, + {"name": "psu3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/24-0050/eeprom"}, + {"name": "psu4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/26-0050/eeprom"}, + ], + "syseeprom": [ + {"name": "syseeprom", "e2_type": "onie_tlv", "e2_path": "/sys/bus/i2c/devices/1-0056/eeprom"}, + ], + "slot": [ + {"name": "slot1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/3-0056/eeprom"}, + {"name": "slot2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/4-0056/eeprom"}, + {"name": "slot3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/5-0056/eeprom"}, + {"name": "slot4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/6-0056/eeprom"}, + ], } diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_port_config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_port_config.py new file mode 100755 index 000000000000..6ff11529ec9b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/config/x86_64_ragile_ra_b6920_4s_r0_port_config.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +PLATFORM_INTF_OPTOE = { + "port_num": 128, + "optoe_start_bus": 71, +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_device.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_device.py new file mode 100755 index 000000000000..046af4e0dd60 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_device.py @@ -0,0 +1,1247 @@ +# coding:utf-8 + +psu_fan_airflow = { + "intake": ['DPS-1300AB-6 S', 'GW-CRPS1300D'], +} + +fanairflow = { + "intake": ['P2EFAN I-F'], +} + +psu_display_name = { + "PA1300I-F": ['GW-CRPS1300D', 'DPS-1300AB-6 S'], +} + +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + + +class threshold: + PSU_TEMP_MIN = -10 * 1000 + PSU_TEMP_MAX = 60 * 1000 + + PSU_FAN_SPEED_MIN = 150 + PSU_FAN_SPEED_MAX = 12000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 1300 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 1444 * 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 2 * 1000 + PSU_OUTPUT_CURRENT_MAX = 107 * 1000 + + PSU_INPUT_CURRENT_MIN = 0.2 * 1000 + PSU_INPUT_CURRENT_MAX = 7 * 1000 + + FRONT_FAN_SPEED_MAX = 11000 + REAR_FAN_SPEED_MAX = 9500 + FAN_SPEED_MIN = 1500 + + +class Description: + CPLD = "Used for managing IO modules, SFP+ modules and system LEDs" + BIOS = "Performs initialization of hardware components during booting" + FPGA = "Platform management controller for on-board temperature monitoring, in-chassis power" + + +devices = { + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/1-0056/eeprom", "way": "sysfs"}, + }, + ], + "psus": [ + { + "e2loc": {"loc": "/sys/bus/i2c/devices/23-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 23, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 23, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 23, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "InputsStatus": {"bus": 23, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 23, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 23, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/23-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/25-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 25, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "InputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 25, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 25, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/25-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/24-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 24, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU3", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "InputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 24, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 24, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/24-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/26-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 26, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU4", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 26, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 26, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "InputsStatus": {"bus": 26, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 26, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 26, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": + { + "value": {"loc": "/sys/bus/i2c/devices/26-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + ], + "temps": [ + { + "name": "BOARD_TEMP", + "temp_id": "TEMP1", + "Temperature": { + "value": [ + {"loc": "/sys/bus/i2c/devices/32-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/32-004d/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/48-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/48-004d/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/40-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/40-004d/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/16-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/16-004d/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + ], + "Min": -10000, + "Low": 0, + "High": 85000, + "Max": 90000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "CPU_TEMP", + "temp_id": "TEMP2", + "Temperature": { + "value": {"loc": "/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": 2000, + "Low": 10000, + "High": 85000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP3", + "Temperature": { + "value": [ + {"loc": "/sys/bus/i2c/devices/32-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/48-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/40-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + {"loc": "/sys/bus/i2c/devices/16-0049/hwmon/hwmon*/temp1_input", "way": "sysfs"} + ], + "Min": -10000, + "Low": 0, + "High": 50000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP4", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/28-004b/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 85000, + "Max": 90000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP5", + "api_name": "ASIC_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/28-004c/hwmon/hwmon*/temp2_input", "way": "sysfs"}, + "Min": 2000, + "Low": 10000, + "High": 100000, + "Max": 105000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "Temperature": { + "value": {"loc": "/tmp/highest_sff_temp", "way": "sysfs", "flock_path": "/tmp/highest_sff_temp"}, + "Min": -15000, + "Low": 0, + "High": 80000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + ], + "leds": [ + { + "name": "BOARD_SYS_LED", + "led_type": "SYS_LED", + "led": {"loc": "/dev/cpld1", "offset": 0x21, "len": 1, "way": "devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0, "mask": 0xff + }, + }, + { + "name": "BOARD_PSU_LED", + "led_type": "PSU_LED", + "led": {"loc": "/dev/cpld1", "offset": 0x22, "len": 1, "way": "devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0, "mask": 0xff + }, + }, + { + "name": "BOARD_FAN_LED", + "led_type": "FAN_LED", + "led": {"loc": "/dev/cpld1", "offset": 0x23, "len": 1, "way": "devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0, "mask": 0xff + }, + }, + ], + "fans": [ + { + "name": "FAN1", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/63-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 14, "addr": 0x0d, "offset": 0x3b, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/55-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 13, "addr": 0x0d, "offset": 0x3b, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x14, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/64-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 14, "addr": 0x0d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN4", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/56-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 13, "addr": 0x0d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x15, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN5", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/65-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan5/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 14, "addr": 0x0d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan5/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan5/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan5/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 14, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan5/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN6", + "airflow": fanairflow, + "e2loc": {"loc": "/sys/bus/i2c/devices/57-0050/eeprom", "way": "sysfs"}, + "present": {"loc": "/sys/wb_plat/fan/fan6/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 13, "addr": 0x0d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff + }, + "Rotor": { + "Rotor1_config": {"name": "Rotor1", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan6/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan6/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan6/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": {"name": "Rotor2", + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Set_speed": {"bus": 13, "addr": 0x0d, "offset": 0x16, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan6/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + }, + { + "name": "MAC_CPLD_A", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + }, + { + "name": "MAC_CPLD_B", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld2", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + }, + { + "name": "FAN_CPLD_A", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld3", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system LEDs and FANs", + "slot": 0, + }, + { + "name": "FAN_CPLD_B", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld4", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system LEDs and FANs", + "slot": 0, + }, + { + "name": "LC1_CPLD_2", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/cpld5", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 1, + }, + { + "name": "LC1_CPLD_1", + "cpld_id": "CPLD7", + "VersionFile": {"loc": "/dev/cpld6", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 1, + }, + { + "name": "LC2_CPLD_2", + "cpld_id": "CPLD8", + "VersionFile": {"loc": "/dev/cpld7", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 2, + }, + { + "name": "LC2_CPLD_1", + "cpld_id": "CPLD9", + "VersionFile": {"loc": "/dev/cpld8", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 2, + }, + { + "name": "LC3_CPLD_2", + "cpld_id": "CPLD10", + "VersionFile": {"loc": "/dev/cpld9", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 3, + }, + { + "name": "LC3_CPLD_1", + "cpld_id": "CPLD11", + "VersionFile": {"loc": "/dev/cpld10", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 3, + }, + { + "name": "LC4_CPLD_2", + "cpld_id": "CPLD12", + "VersionFile": {"loc": "/dev/cpld11", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 4, + }, + { + "name": "LC4_CPLD_1", + "cpld_id": "CPLD13", + "VersionFile": {"loc": "/dev/cpld12", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for SFP+ modules", + "slot": 4, + }, + ], + "dcdc": [ + { + "name": "X86_BOARD_P5V_AUX_IN", + "dcdc_id": "DCDC1", + "Min": 4721, + "value": { + "loc": "/sys/wb_plat/sensor/in1/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 5250, + "format": "float(float(%s)/1000)", + }, + { + "name": "X86_BOARD_P1V7_IN", + "dcdc_id": "DCDC2", + "Min": 1615, + "value": { + "loc": "/sys/wb_plat/sensor/in2/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1792, + "format": "float(float(%s)/1000)", + }, + { + "name": "X86_BOARD_TEST1v24", + "dcdc_id": "DCDC3", + "Min": 1178, + "value": { + "loc": "/sys/wb_plat/sensor/in3/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1302, + "format": "float(float(%s)/1000)", + }, + { + "name": "X86_BOARD_P3V3_STBY_IN", + "dcdc_id": "DCDC4", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in4/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3500, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD1v8", + "dcdc_id": "DCDC5", + "Min": 1710, + "value": { + "loc": "/sys/wb_plat/sensor/in5/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1909, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_SW_VDD1v2", + "dcdc_id": "DCDC6", + "Min": 1140, + "value": { + "loc": "/sys/wb_plat/sensor/in6/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1286, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_TEST1v24", + "dcdc_id": "DCDC7", + "Min": 1178, + "value": { + "loc": "/sys/wb_plat/sensor/in7/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1302, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD1v2_MAC", + "dcdc_id": "DCDC8", + "Min": 1140, + "value": { + "loc": "/sys/wb_plat/sensor/in8/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 1260, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD_CORE", + "dcdc_id": "DCDC9", + "Min": 712, + "value": { + "loc": "/sys/wb_plat/sensor/in9/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 945, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD3v3_MCU", + "dcdc_id": "DCDC10", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in10/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3556, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD3v3_CLK", + "dcdc_id": "DCDC11", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in11/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3556, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD5V_CLK_MCU", + "dcdc_id": "DCDC12", + "Min": 4750, + "value": { + "loc": "/sys/wb_plat/sensor/in12/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 5331, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD2v5", + "dcdc_id": "DCDC13", + "Min": 2375, + "value": { + "loc": "/sys/wb_plat/sensor/in13/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 2688, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDDO", + "dcdc_id": "DCDC14", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in14/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3542, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_BC_PVDD", + "dcdc_id": "DCDC15", + "Min": 760, + "value": { + "loc": "/sys/wb_plat/sensor/in15/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 867, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_VDD3v3", + "dcdc_id": "DCDC16", + "Min": 3135, + "value": { + "loc": "/sys/wb_plat/sensor/in16/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 3542, + "format": "float(float(%s)/1000)", + }, + { + "name": "MAC_BOARD_ANLGOUT", + "dcdc_id": "DCDC17", + "Min": 760, + "value": { + "loc": "/sys/wb_plat/sensor/in17/in_input", + "way": "sysfs", + }, + "read_times": 5, + "Unit": "V", + "Max": 856, + "format": "float(float(%s)/1000)", + }, + ], + "cpu": [ + { + "name": "cpu", + "CpuResetCntReg": {"io_addr": 0xb88, "way": "io"}, + } + ], + "sfps": { + "ver": '1.0', + "port_index_start": 0, + "port_num": 128, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_cpld": { + "dev_id": { + 6: { + "offset": { + 0x10: "1-8", + 0x11: "9-16", + }, + }, + 5: { + "offset": { + 0x10: "17-24", + 0x11: "25-32", + }, + }, + 8: { + "offset": { + 0x10: "33-40", + 0x11: "41-48", + }, + }, + 7: { + "offset": { + 0x10: "49-56", + 0x11: "57-64", + }, + }, + 10: { + "offset": { + 0x10: "65-72", + 0x11: "73-80", + }, + }, + 9: { + "offset": { + 0x10: "81-88", + 0x11: "89-96", + }, + }, + 12: { + "offset": { + 0x10: "97-104", + 0x11: "105-112", + }, + }, + 11: { + "offset": { + 0x10: "113-120", + 0x11: "121-128", + }, + }, + }, + }, + "presence_val_is_present": 0, + "eeprom_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/eeprom", + "eeprom_path_key": list(range(71, 199)), + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(71, 199)), + "reset_cpld": { + "dev_id": { + 6: { + "offset": { + 0x14: "1-8", + 0x15: "9-16", + }, + }, + 5: { + "offset": { + 0x14: "17-24", + 0x15: "25-32", + }, + }, + 8: { + "offset": { + 0x14: "33-40", + 0x15: "41-48", + }, + }, + 7: { + "offset": { + 0x14: "49-56", + 0x15: "57-64", + }, + }, + 10: { + "offset": { + 0x14: "65-72", + 0x15: "73-80", + }, + }, + 9: { + "offset": { + 0x14: "81-88", + 0x15: "89-96", + }, + }, + 12: { + "offset": { + 0x14: "97-104", + 0x15: "105-112", + }, + }, + 11: { + "offset": { + 0x14: "113-120", + 0x15: "121-128", + }, + }, + } + }, + "reset_val_is_reset": 0, + } +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_monitor.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_monitor.py new file mode 100755 index 000000000000..6ab176708c27 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/hal-config/x86_64_ragile_ra_b6920_4s_r0_monitor.py @@ -0,0 +1,113 @@ +# coding:utf-8 + + +monitor = { + "openloop": { + "linear": { + "name": "linear", + "flag": 1, + "pwm_min": 0x80, + "pwm_max": 0xff, + "K": 11, + "tin_min": 28, + }, + "curve": { + "name": "curve", + "flag": 0, + "pwm_min": 0x80, + "pwm_max": 0xff, + "a": 0.183, + "b": -6.88, + "c": 120, + "tin_min": 25, + }, + }, + + "pid": { + "CPU_TEMP": { + "name": "CPU_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 1.5, + "Ki": 1, + "Kd": 0.3, + "target": 90, + "value": [None, None, None], + }, + "SWITCH_TEMP": { + "name": "SWITCH_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 1.5, + "Ki": 1, + "Kd": 0.3, + "target": 90, + "value": [None, None, None], + }, + "SFF_TEMP": { + "name": "SFF_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 0.1, + "Ki": 0.4, + "Kd": 0, + "target": 68, + "value": [None, None, None], + }, + }, + + "temps_threshold": { + "SWITCH_TEMP": {"name": "SWITCH_TEMP", "warning": 100, "critical": 105}, + "INLET_TEMP": {"name": "INLET_TEMP", "warning": 50, "critical": 60}, + "BOARD_TEMP": {"name": "BOARD_TEMP", "warning": 85, "critical": 90}, + "OUTLET_TEMP": {"name": "OUTLET_TEMP", "warning": 85, "critical": 90}, + "CPU_TEMP": {"name": "CPU_TEMP", "warning": 85, "critical": 100}, + "SFF_TEMP": {"name": "SFF_TEMP", "warning": 999, "critical": 1000, "ignore_threshold": 1, "invalid": -10000, "error": -9999}, + }, + + "fancontrol_para": { + "interval": 5, + "max_pwm": 0xff, + "min_pwm": 0x80, + "abnormal_pwm": 0xff, + "temp_fail_num": 3, + "check_temp_fail": [ + {"temp_name": "INLET_TEMP"}, + ], + "inlet_mac_diff": 50, + "check_crit_reboot_num": 3, + "check_crit_sleep_time": 20, + "psu_absent_fullspeed_num": 0xFF, + "fan_absent_fullspeed_num": 1, + "rotor_error_fullspeed_num": 1, + "psu_fan_control": 0, + }, + + "ledcontrol_para": { + "interval": 5, + "checkpsu": 0, # 0: sys led don't follow psu led + "checkfan": 0, # 0: sys led don't follow fan led + "psu_amber_num": 1, + "fan_amber_num": 1, + "board_sys_led": [ + {"led_name": "BOARD_SYS_LED"}, + ], + "board_psu_led": [ + {"led_name": "BOARD_PSU_LED"}, + ], + "board_fan_led": [ + {"led_name": "BOARD_FAN_LED"}, + ], + }, + + "otp_reboot_judge_file": { + "otp_switch_reboot_judge_file": "/etc/.otp_switch_reboot_flag", + "otp_other_reboot_judge_file": "/etc/.otp_other_reboot_flag", + }, +} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/Makefile index 2b5ac6c5aadb..dda2e92069fb 100755 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/Makefile +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/Makefile @@ -1,8 +1,14 @@ -obj-m := rg_cpld.o - -obj-m += lpc_cpld_i2c.o -obj-m += rg_lpc_cpld.o -obj-m += pddf_custom_fan.o -obj-m += pddf_custom_psu.o -obj-m += pddf_custom_xcvr.o -obj-m += pddf_custom_led_module.o +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/app/firmware_upgrade/firmware_driver/include) + +EXTRA_CFLAGS+= -I$(MODULES_DIR) +EXTRA_CFLAGS+= -I$(MODULES_DIR)/linux-5.10 +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) + +obj-m += wb_lpc_drv_device.o +obj-m += wb_io_dev_device.o +obj-m += wb_platform_i2c_dev_device.o +obj-m += wb_i2c_ocores_device.o +obj-m += wb_i2c_mux_pca954x_device.o +obj-m += wb_firmware_upgrade_device.o diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/lpc_cpld_i2c.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/lpc_cpld_i2c.c deleted file mode 100755 index 17e2025d3caa..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/lpc_cpld_i2c.c +++ /dev/null @@ -1,131 +0,0 @@ -#include /* Wd're doing kernel work */ -#include /* specifically, a module */ -#include -#include /* Need for the macros */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../../../common/modules/lpc_cpld_i2c_ocores.h" -#include "ragile.h" - -int lpc_cpld_i2c_verbose = 0; -int lpc_cpld_i2c_error = 0; -module_param(lpc_cpld_i2c_verbose, int, S_IRUGO | S_IWUSR); -module_param(lpc_cpld_i2c_error, int, S_IRUGO | S_IWUSR); - - -#define LPC_CPLD_I2C_VERBOSE(fmt, args...) do { \ - if (lpc_cpld_i2c_verbose) { \ - printk(KERN_ERR "[LPC_CPLD_I2C_DEVICE][VERBOSE][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define LPC_CPLD_I2C_ERROR(fmt, args...) do { \ - if (lpc_cpld_i2c_error) { \ - printk(KERN_ERR "[LPC_CPLD_I2C_DEVICE][ERROR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ - } while (0) - -#define PCI_VENDOR_ID_D1527_LPC (0x8c54) -#define PCI_VENDOR_ID_C3000_LPC (0x19dc) - -#define LPC_CPLD_I2C_OCORE_START_BASE (0x800) -#define MAX_LPC_CPLD_I2C_REG_SIZE (0x8) - -#define LPC_CPLD_I2C_OCORE_CTRL_START(id) ((LPC_CPLD_I2C_OCORE_START_BASE) + (id) * (MAX_LPC_CPLD_I2C_REG_SIZE)) -#define LPC_CPLD_I2C_OCORE_CTRL_END(id) ((LPC_CPLD_I2C_OCORE_START_BASE) + (id + 1) * (MAX_LPC_CPLD_I2C_REG_SIZE) - 1) - -static struct rg_ocores_cpld_i2c_platform_data rg_i2c_ocore_pdata = { - .reg_shift = 0, - .reg_io_width = 1, - .clock_khz = 33000, - .num_devices = 0, - .i2c_irq_flag = 1, -}; - -#define DEFINE_LPC_CPLD_I2C_DEVICE_RESOURCES(_id) \ - static struct resource lpc_cpld_i2c_resources_##_id[] = { \ - { \ - .start = LPC_CPLD_I2C_OCORE_CTRL_START(_id), \ - .end = LPC_CPLD_I2C_OCORE_CTRL_END(_id), \ - .flags = IORESOURCE_IO, \ - }, \ -} - -DEFINE_LPC_CPLD_I2C_DEVICE_RESOURCES(52); -DEFINE_LPC_CPLD_I2C_DEVICE_RESOURCES(48); -DEFINE_LPC_CPLD_I2C_DEVICE_RESOURCES(49); -DEFINE_LPC_CPLD_I2C_DEVICE_RESOURCES(50); -DEFINE_LPC_CPLD_I2C_DEVICE_RESOURCES(51); - -#define DEFINE_LPC_CPLD_I2C_MFD_CELL_CFG(_id) \ - { \ - .name = "rg-cpld-ocrore-i2c", \ - .id = (_id), \ - .num_resources = ARRAY_SIZE(lpc_cpld_i2c_resources_##_id), \ - .resources = lpc_cpld_i2c_resources_##_id, \ - .platform_data = &rg_i2c_ocore_pdata, \ - .pdata_size = sizeof(rg_i2c_ocore_pdata), \ - } - -static const struct mfd_cell lpc_cpld_i2c_cells_bar0_cfg0[] = { - DEFINE_LPC_CPLD_I2C_MFD_CELL_CFG(52), - DEFINE_LPC_CPLD_I2C_MFD_CELL_CFG(48), - DEFINE_LPC_CPLD_I2C_MFD_CELL_CFG(49), - DEFINE_LPC_CPLD_I2C_MFD_CELL_CFG(50), - DEFINE_LPC_CPLD_I2C_MFD_CELL_CFG(51), -}; - -static int __init lpc_cpld_i2c_init(void) -{ - struct pci_dev *pdev = NULL; - int ret; - - LPC_CPLD_I2C_VERBOSE("Enter.\n"); - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC, pdev); - if (!pdev) { - LPC_CPLD_I2C_ERROR("pci_get_device(0x8086, 0x8c54) failed!\n"); - return 0; - } - - ret = mfd_add_devices(&pdev->dev, 0, - lpc_cpld_i2c_cells_bar0_cfg0, - ARRAY_SIZE(lpc_cpld_i2c_cells_bar0_cfg0), - NULL, 0, NULL); - if (ret) { - LPC_CPLD_I2C_ERROR("mfd_add_devices failed: %d\n", ret); - return -1; - } - LPC_CPLD_I2C_VERBOSE("Leave success\n"); - return ret; -} - -static void __exit lpc_cpld_i2c_exit(void) -{ - struct pci_dev *pdev = NULL; - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC, pdev); - if (!pdev) { - LPC_CPLD_I2C_ERROR("pci_get_device(0x8086, 0x8c54) failed!\n"); - return ; - } - - mfd_remove_devices(&pdev->dev); - LPC_CPLD_I2C_VERBOSE("Leave.\n"); -} - -module_init(lpc_cpld_i2c_init); -module_exit(lpc_cpld_i2c_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("support "); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_fan.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_fan.c deleted file mode 100644 index 9367524a9427..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_fan.c +++ /dev/null @@ -1,268 +0,0 @@ -#include -#include "../../../../../pddf/i2c/modules/include/pddf_client_defs.h" -#include "../../../../../pddf/i2c/modules/include/pddf_fan_defs.h" -#include "../../../../../pddf/i2c/modules/include/pddf_fan_driver.h" -#include "../../../../../pddf/i2c/modules/include/pddf_fan_api.h" - -extern void *get_device_table(char *name); - -extern FAN_SYSFS_ATTR_DATA data_fan1_present; -extern FAN_SYSFS_ATTR_DATA data_fan2_present; -extern FAN_SYSFS_ATTR_DATA data_fan3_present; -extern FAN_SYSFS_ATTR_DATA data_fan4_present; -extern FAN_SYSFS_ATTR_DATA data_fan5_present; -extern FAN_SYSFS_ATTR_DATA data_fan6_present; -extern FAN_SYSFS_ATTR_DATA data_fan7_present; -extern FAN_SYSFS_ATTR_DATA data_fan8_present; -extern FAN_SYSFS_ATTR_DATA data_fan9_present; -extern FAN_SYSFS_ATTR_DATA data_fan10_present; -extern FAN_SYSFS_ATTR_DATA data_fan11_present; -extern FAN_SYSFS_ATTR_DATA data_fan12_present; - -extern FAN_SYSFS_ATTR_DATA data_fan1_input; -extern FAN_SYSFS_ATTR_DATA data_fan2_input; -extern FAN_SYSFS_ATTR_DATA data_fan3_input; -extern FAN_SYSFS_ATTR_DATA data_fan4_input; -extern FAN_SYSFS_ATTR_DATA data_fan5_input; -extern FAN_SYSFS_ATTR_DATA data_fan6_input; -extern FAN_SYSFS_ATTR_DATA data_fan7_input; -extern FAN_SYSFS_ATTR_DATA data_fan8_input; -extern FAN_SYSFS_ATTR_DATA data_fan9_input; -extern FAN_SYSFS_ATTR_DATA data_fan10_input; -extern FAN_SYSFS_ATTR_DATA data_fan11_input; -extern FAN_SYSFS_ATTR_DATA data_fan12_input; - -extern FAN_SYSFS_ATTR_DATA data_fan1_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan2_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan3_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan4_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan5_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan6_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan7_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan8_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan9_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan10_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan11_pwm; -extern FAN_SYSFS_ATTR_DATA data_fan12_pwm; - -extern FAN_SYSFS_ATTR_DATA data_fan1_fault; -extern FAN_SYSFS_ATTR_DATA data_fan2_fault; -extern FAN_SYSFS_ATTR_DATA data_fan3_fault; -extern FAN_SYSFS_ATTR_DATA data_fan4_fault; -extern FAN_SYSFS_ATTR_DATA data_fan5_fault; -extern FAN_SYSFS_ATTR_DATA data_fan6_fault; -extern FAN_SYSFS_ATTR_DATA data_fan7_fault; -extern FAN_SYSFS_ATTR_DATA data_fan8_fault; -extern FAN_SYSFS_ATTR_DATA data_fan9_fault; -extern FAN_SYSFS_ATTR_DATA data_fan10_fault; -extern FAN_SYSFS_ATTR_DATA data_fan11_fault; -extern FAN_SYSFS_ATTR_DATA data_fan12_fault; - -int pddf_custom_fan_present(void *client, FAN_DATA_ATTR *udata, void *info); -int pddf_custom_fan_input(void *client, FAN_DATA_ATTR *udata, void *info); -int pddf_custom_fan_fault(void *client, FAN_DATA_ATTR *udata, void *info); -int pddf_custom_fan_pwm(void *client, FAN_DATA_ATTR *udata, void *info); -int pddf_custom_fan_set_pwm(void *client, FAN_DATA_ATTR *udata, void *info); - -int pddf_custom_fan_present(void *client, FAN_DATA_ATTR *udata, void *info) -{ - uint32_t val; - struct fan_attr_info *painfo = (struct fan_attr_info *)info; - - val = 0; - - if (strcmp(udata->devtype, "cpld") == 0) { - if (udata->devname) { - client = (struct i2c_client *)get_device_table(udata->devname); - } - } - val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); - /* printk("%s read data %x\n", __FUNCTION__, val); */ - - painfo->val.intval = ((val & udata->mask) == udata->cmpval); - - return 0; -} - -int pddf_custom_fan_input(void *client, FAN_DATA_ATTR *udata, void *info) -{ - uint32_t val; - struct fan_attr_info *painfo = (struct fan_attr_info *)info; - - val = 0; - - if (strcmp(udata->devtype, "cpld") == 0) { - if (udata->devname) { - client = (struct i2c_client *)get_device_table(udata->devname); - } - } - if (udata->len == 1) { - val = i2c_smbus_read_byte_data(client, udata->offset); - } else if (udata->len == 2) { - val = i2c_smbus_read_word_swapped((struct i2c_client *)client, udata->offset); - } - - /* printk("%s read data %x\n", __FUNCTION__, val); */ - - if (udata->is_divisor) - painfo->val.intval = udata->mult / (val >> 3); - else - painfo->val.intval = udata->mult * val; - - return 0; -} - -int pddf_custom_fan_pwm(void *client, FAN_DATA_ATTR *udata, void *info) -{ - uint32_t val; - struct fan_attr_info *painfo = (struct fan_attr_info *)info; - - val = 0; - - if (strcmp(udata->devtype, "cpld") == 0) { - if (udata->devname) { - client = (struct i2c_client *)get_device_table(udata->devname); - } - } - if (udata->len == 1) { - val = i2c_smbus_read_byte_data(client, udata->offset); - } else if (udata->len == 2) { - val = i2c_smbus_read_word_swapped((struct i2c_client *)client, udata->offset); - } - /* printk("%s read data %x\n", __FUNCTION__, val); */ - - val = val & udata->mask; - painfo->val.intval = val; - - return 0; -} - -int pddf_custom_fan_set_pwm(void *client, FAN_DATA_ATTR *udata, void *info) -{ - uint32_t val; - struct fan_attr_info *painfo; - - val = 0; - painfo = (struct fan_attr_info *)info; - - val = painfo->val.intval & udata->mask; - - if (val > 255) { - return -EINVAL; - } - - if (strcmp(udata->devtype, "cpld") == 0 && udata->devname) { - client = (struct i2c_client *)get_device_table(udata->devname); - i2c_smbus_write_byte_data(client, udata->offset, val); - } - - return 0; -} - - -int pddf_custom_fan_fault(void *client, FAN_DATA_ATTR *udata, void *info) -{ - uint32_t val; - struct fan_attr_info *painfo = (struct fan_attr_info *)info; - - val = 0; - - if (strcmp(udata->devtype, "cpld") == 0) { - if (udata->devname) { - client = (struct i2c_client *)get_device_table(udata->devname); - } - } - val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset); - /* printk("%s read data %x\n", __FUNCTION__, val); */ - - val = val & udata->mask; - painfo->val.intval = val; - - return 0; -} - -int __init pddf_custom_fan_init(void) -{ - printk(KERN_ERR "pddf_custom_fan_init\n"); - - data_fan1_present.do_get = pddf_custom_fan_present; - data_fan2_present.do_get = pddf_custom_fan_present; - data_fan3_present.do_get = pddf_custom_fan_present; - data_fan4_present.do_get = pddf_custom_fan_present; - data_fan5_present.do_get = pddf_custom_fan_present; - data_fan6_present.do_get = pddf_custom_fan_present; - data_fan7_present.do_get = pddf_custom_fan_present; - data_fan8_present.do_get = pddf_custom_fan_present; - data_fan9_present.do_get = pddf_custom_fan_present; - data_fan10_present.do_get = pddf_custom_fan_present; - data_fan11_present.do_get = pddf_custom_fan_present; - data_fan12_present.do_get = pddf_custom_fan_present; - - data_fan1_input.do_get = pddf_custom_fan_input; - data_fan2_input.do_get = pddf_custom_fan_input; - data_fan3_input.do_get = pddf_custom_fan_input; - data_fan4_input.do_get = pddf_custom_fan_input; - data_fan5_input.do_get = pddf_custom_fan_input; - data_fan6_input.do_get = pddf_custom_fan_input; - data_fan7_input.do_get = pddf_custom_fan_input; - data_fan8_input.do_get = pddf_custom_fan_input; - data_fan9_input.do_get = pddf_custom_fan_input; - data_fan10_input.do_get = pddf_custom_fan_input; - data_fan11_input.do_get = pddf_custom_fan_input; - data_fan12_input.do_get = pddf_custom_fan_input; - - data_fan1_pwm.do_get = pddf_custom_fan_pwm; - data_fan2_pwm.do_get = pddf_custom_fan_pwm; - data_fan3_pwm.do_get = pddf_custom_fan_pwm; - data_fan4_pwm.do_get = pddf_custom_fan_pwm; - data_fan5_pwm.do_get = pddf_custom_fan_pwm; - data_fan6_pwm.do_get = pddf_custom_fan_pwm; - data_fan7_pwm.do_get = pddf_custom_fan_pwm; - data_fan8_pwm.do_get = pddf_custom_fan_pwm; - data_fan9_pwm.do_get = pddf_custom_fan_pwm; - data_fan10_pwm.do_get = pddf_custom_fan_pwm; - data_fan11_pwm.do_get = pddf_custom_fan_pwm; - data_fan12_pwm.do_get = pddf_custom_fan_pwm; - - data_fan1_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan2_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan3_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan4_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan5_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan6_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan7_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan8_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan9_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan10_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan11_pwm.do_set = pddf_custom_fan_set_pwm; - data_fan12_pwm.do_set = pddf_custom_fan_set_pwm; - - data_fan1_fault.do_get = pddf_custom_fan_fault; - data_fan2_fault.do_get = pddf_custom_fan_fault; - data_fan3_fault.do_get = pddf_custom_fan_fault; - data_fan4_fault.do_get = pddf_custom_fan_fault; - data_fan5_fault.do_get = pddf_custom_fan_fault; - data_fan6_fault.do_get = pddf_custom_fan_fault; - data_fan7_fault.do_get = pddf_custom_fan_fault; - data_fan8_fault.do_get = pddf_custom_fan_fault; - data_fan9_fault.do_get = pddf_custom_fan_fault; - data_fan10_fault.do_get = pddf_custom_fan_fault; - data_fan11_fault.do_get = pddf_custom_fan_fault; - data_fan12_fault.do_get = pddf_custom_fan_fault; - - return 0; -} - -void __exit pddf_custom_fan_exit(void) -{ - printk(KERN_ERR "pddf_custom_fan_exit\n"); - return; -} - -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("pddf custom fan api"); -MODULE_LICENSE("GPL"); - -module_init(pddf_custom_fan_init); -module_exit(pddf_custom_fan_exit); - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_led_module.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_led_module.c deleted file mode 100644 index 97ca23a92324..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_led_module.c +++ /dev/null @@ -1,745 +0,0 @@ -/* - * Copyright 2019 Broadcom. - * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. - * - * 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. - * - * - * A pddf kernel module to manage various LEDs of a switch - */ - -#include -#include -#include -#include -#include -#include -#include "../../../../../pddf/i2c/modules/include/pddf_led_defs.h" -#include "../../../../../pddf/i2c/modules/include/pddf_client_defs.h" -#include -#include -#include -#include - -#define DEBUG 0 -LED_OPS_DATA sys_led_ops_data[1]={0}; -LED_OPS_DATA* psu_led_ops_data=NULL; -LED_OPS_DATA diag_led_ops_data[1]= {0}; -LED_OPS_DATA fan_led_ops_data[1]= {0}; -LED_OPS_DATA loc_led_ops_data[1]= {0}; -LED_OPS_DATA* fantray_led_ops_data=NULL; -LED_OPS_DATA temp_data={0}; -LED_OPS_DATA* dev_list[LED_TYPE_MAX] = { - sys_led_ops_data, - NULL, - fan_led_ops_data, - NULL, - diag_led_ops_data, - loc_led_ops_data, -}; -int num_psus = 0; -int num_fantrays = 0; - -extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg); -extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); -extern ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, char *buf); -extern ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count); -extern void *get_device_table(char *name); - -static LED_STATUS find_state_index(const char* state_str) { - int index; - char *ptr = (char *)state_str; - while (*ptr && *ptr!= '\n' && *ptr !='\0') ptr++; - *ptr='\0'; - for ( index = 0; index < MAX_LED_STATUS; index++) { - /*int rc = strcmp(state_str, LED_STATUS_STR[index]) ;*/ - if (strcmp(state_str, LED_STATUS_STR[index]) == 0 ) { - return index; - } - } - return MAX_LED_STATUS; -} - -static LED_TYPE get_dev_type(char* name) -{ - LED_TYPE ret = LED_TYPE_MAX; - if(strcasecmp(name, "SYS_LED")==0) { - ret = LED_SYS; - } else if(strcasecmp(name, "FAN_LED")==0) { - ret = LED_FAN; - } else if(strstr(name, "PSU_LED")) { - ret = LED_PSU; - } else if(strcasecmp(name, "DIAG_LED")==0) { - ret = LED_DIAG; - } else if(strcasecmp(name, "LOC_LED")==0) { - ret = LED_LOC; - } else if(strstr(name, "FANTRAY_LED")) { - ret = LED_FANTRAY; - } -#if DEBUG > 1 - pddf_dbg(LED, KERN_INFO "LED get_dev_type: %s; %d\n", name, ret); -#endif - return (ret); -} -static int dev_index_check(LED_TYPE type, int index) -{ -#if DEBUG - pddf_dbg(LED, "dev_index_check: type:%s index:%d num_psus:%d num_fantrays:%d\n", - LED_TYPE_STR[type], index, num_psus, num_fantrays); -#endif - switch(type) - { - case LED_PSU: - if(index >= num_psus) return (-1); - break; - case LED_FANTRAY: - if(index >= num_fantrays) return (-1); - break; - default: - if(index >= 1) return (-1); - break; - } - return (0); -} - -static LED_OPS_DATA* find_led_ops_data(struct device_attribute *da) -{ - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; - LED_TYPE led_type; - if(!ptr || strlen(ptr->device_name)==0 ) return(NULL); - - - if((led_type=get_dev_type(ptr->device_name))==LED_TYPE_MAX) { - printk(KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); - return(NULL); - } - if(dev_index_check(led_type, ptr->index)==-1) { - printk(KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%s\n", __func__, ptr->index, ptr->device_name); - return(NULL); - } -#if DEBUG > 1 - pddf_dbg(LED, "find_led_ops_data: name:%s; index=%d tempAddr:%p actualAddr:%p\n", - ptr->device_name, ptr->index, ptr, dev_list[led_type]+ptr->index); -#endif - return (dev_list[led_type]+ptr->index); -} - -static void print_led_data(LED_OPS_DATA *ptr, LED_STATUS state) -{ - int i = 0; - if(!ptr) return ; - pddf_dbg(LED, KERN_INFO "Print %s index:%d num_psus:%d num_fantrays:%d ADDR=%p\n", - ptr->device_name, ptr->index, num_psus, num_fantrays, ptr); - pddf_dbg(LED, KERN_INFO "\tindex: %d\n", ptr->index); - pddf_dbg(LED, KERN_INFO "\tcur_state: %d; %s \n", ptr->cur_state.state, ptr->cur_state.color); - for (i = 0; i< MAX_LED_STATUS; i++) { - if(ptr->data[i].swpld_addr && (i == state || state == -1)) { - pddf_dbg(LED, KERN_INFO "\t\t[%s]: addr/offset:0x%x;0x%x color:%s; value:%x; mask_bits: 0x%x; pos:%d\n", - LED_STATUS_STR[i], - ptr->data[i].swpld_addr, ptr->data[i].swpld_addr_offset, - LED_STATUS_STR[i], ptr->data[i].value, ptr->data[i].bits.mask_bits, ptr->data[i].bits.pos); - } - } -} - -int get_sys_val(LED_OPS_DATA *ops_ptr, uint32_t *sys_val) -{ - int ret; - struct i2c_client *client_ptr; - - ret = -1; - - if (ops_ptr == NULL) { - pddf_dbg(LED, KERN_ERR "ERROR %s: param is NULL\n", __func__); - return ret; - } - - if (strlen(ops_ptr->device_name) != 0 && strncmp(ops_ptr->device_name, "FANTRAY_LED", strlen("FANTRAY_LED")) == 0) { - if (ops_ptr->index % 2 == 0) { - client_ptr = (struct i2c_client *)get_device_table("FAN-CPLD-B"); - } else { - client_ptr = (struct i2c_client *)get_device_table("FAN-CPLD-A"); - } - if (client_ptr == NULL) { - pddf_dbg(LED, KERN_ERR "ERROR %s: get led color by cpld fail\n", __func__); - return ret; - } - *sys_val = i2c_smbus_read_byte_data(client_ptr, ops_ptr->swpld_addr_offset); - ret = 0; - } else { - ret = inb(ops_ptr->swpld_addr_offset); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: get led color by io fail\n", __func__); - return ret; - } - *sys_val = (uint32_t)ret; - ret = 0; - } - - return ret; -} - - -ssize_t get_status_led(struct device_attribute *da) -{ - int ret=0; - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; - LED_OPS_DATA* ops_ptr=find_led_ops_data(da); - uint32_t color_val=0, sys_val=0; - int state=0; - if (!ops_ptr) { - pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot find LED Ptr", __func__); - return (-1); - } - if (ops_ptr->swpld_addr == 0x0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: device: %s %d not configured\n", __func__, - temp_data_ptr->device_name, temp_data_ptr->index); - return (-1); - } - ret = get_sys_val(ops_ptr, &sys_val); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot get sys val\n", __func__); - return (-1); - } - /* keep ret as old value */ - ret = 0; - - strcpy(temp_data.cur_state.color, "None"); - for (state=0; statedata[state].bits.mask_bits); - /* printk("color val %d p1 %x, p2 %x\n", color_val, ops_ptr->data[state].value, ops_ptr->data[state].bits.pos); */ - if ((color_val ^ (ops_ptr->data[state].value<data[state].bits.pos))==0) { - strcpy(temp_data.cur_state.color, LED_STATUS_STR[state]); - } - } -#if DEBUG > 1 - pddf_dbg(LED, KERN_ERR "Get : %s:%d addr/offset:0x%x; 0x%x value=0x%x [%s]\n", - ops_ptr->device_name, ops_ptr->index, - ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, sys_val, - temp_data.cur_state.color); -#endif - - return(ret); -} - -int set_sys_val(LED_OPS_DATA *ops_ptr, uint32_t new_val) -{ - int ret; - struct i2c_client *client_ptr; - - ret = -1; - - if (ops_ptr == NULL) { - pddf_dbg(LED, KERN_ERR "ERROR %s: param is NULL\n", __func__); - return ret; - } - - if (strlen(ops_ptr->device_name) != 0 && strncmp(ops_ptr->device_name, "FANTRAY_LED", strlen("FANTRAY_LED")) == 0) { - client_ptr = NULL; - if (ops_ptr->index % 2 == 0) { - client_ptr = (struct i2c_client *)get_device_table("FAN-CPLD-B"); - } else { - client_ptr = (struct i2c_client *)get_device_table("FAN-CPLD-A"); - } - if (client_ptr == NULL) { - pddf_dbg(LED, KERN_ERR "ERROR %s: get i2c_client fail\n", __func__); - return ret; - } - ret = i2c_smbus_write_byte_data(client_ptr, ops_ptr->swpld_addr_offset, new_val); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: set led color by cpld fail\n", __func__); - } - } - else { - outb(new_val, ops_ptr->swpld_addr_offset); - } - - return ret; -} - -ssize_t set_status_led(struct device_attribute *da) -{ - int ret=0; - uint32_t sys_val=0, new_val=0; - LED_STATUS cur_state = MAX_LED_STATUS; - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* temp_data_ptr=(LED_OPS_DATA*)_ptr->addr; - LED_OPS_DATA* ops_ptr=find_led_ops_data(da); - char* _buf=temp_data_ptr->cur_state.color; - - if (!ops_ptr) { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: Cannot find LED Ptr", __func__); - return (-1); - } - if (ops_ptr->swpld_addr == 0x0) { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: device: %s %d not configured\n", - __func__, ops_ptr->device_name, ops_ptr->index); - return (-1); - } - pddf_dbg(LED, KERN_ERR "%s: Set [%s;%d] color[%s]\n", __func__, - temp_data_ptr->device_name, temp_data_ptr->index, - temp_data_ptr->cur_state.color); - cur_state = find_state_index(_buf); - - if (cur_state == MAX_LED_STATUS) { - pddf_dbg(LED, KERN_ERR "ERROR %s: not supported: %s\n", _buf, __func__); - return (-1); - } - - if(ops_ptr->data[cur_state].swpld_addr != 0x0) { - ret = get_sys_val(ops_ptr, &sys_val); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot get sys val\n", __func__); - return (-1); - } - - new_val = (sys_val & ops_ptr->data[cur_state].bits.mask_bits) | - (ops_ptr->data[cur_state].value << ops_ptr->data[cur_state].bits.pos); - - } else { - pddf_dbg(LED, KERN_ERR "ERROR %s: %s %d state %d; %s not configured\n",__func__, - ops_ptr->device_name, ops_ptr->index, cur_state, _buf); - return (-1); - } - - ret = set_sys_val(ops_ptr, new_val); - if (ret < 0) { - pddf_dbg(LED, KERN_ERR "ERROR %s: Cannot set sys val\n", __func__); - return (-1); - } - pddf_dbg(LED, KERN_INFO "Set color:%s; 0x%x:0x%x sys_val:0x%x new_val:0x%x read:0x%x\n", - LED_STATUS_STR[cur_state], - ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset, - sys_val, new_val, - ret = board_i2c_cpld_read(ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset)); - if (ret < 0) - { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s: Error %d in reading from cpld(0x%x) offset 0x%x\n", __FUNCTION__, ret, ops_ptr->swpld_addr, ops_ptr->swpld_addr_offset); - return ret; - } - return(ret); -} - - -ssize_t show_pddf_data(struct device *dev, struct device_attribute *da, - char *buf) -{ - int ret = 0; - struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; - switch(ptr->type) - { - case PDDF_CHAR: - ret = sprintf(buf, "%s\n", ptr->addr); - break; - case PDDF_INT_DEC: - ret = sprintf(buf, "%d\n", *(int*)(ptr->addr)); - break; - case PDDF_INT_HEX: - ret = sprintf(buf, "0x%x\n", *(int*)(ptr->addr)); - break; - case PDDF_USHORT: - ret = sprintf(buf, "0x%x\n", *(unsigned short *)(ptr->addr)); - break; - case PDDF_UINT32: - ret = sprintf(buf, "0x%x\n", *(uint32_t *)(ptr->addr)); - break; - default: - break; - } -#if DEBUG > 1 - pddf_dbg(LED, "[ READ ] DATA ATTR PTR [%s] TYPE:%d, Value:[%s]\n", - ptr->dev_attr.attr.name, ptr->type, buf); -#endif - return ret; -} - -ssize_t store_pddf_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) -{ - int ret = 0, num = 0; - struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; - switch(ptr->type) - { - case PDDF_CHAR: - strncpy(ptr->addr, buf, strlen(buf)-1); // to discard newline char form buf - ptr->addr[strlen(buf)-1] = '\0'; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_CHAR VALUE:%s\n", - ptr->dev_attr.attr.name, ptr->addr); -#endif - break; - case PDDF_INT_DEC: - ret = kstrtoint(buf,10,&num); - if (ret==0) - *(int *)(ptr->addr) = num; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_DEC VALUE:%d\n", - ptr->dev_attr.attr.name, *(int *)(ptr->addr)); -#endif - break; - case PDDF_INT_HEX: - ret = kstrtoint(buf,16,&num); - if (ret==0) - *(int *)(ptr->addr) = num; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_HEX VALUE:0x%x\n", - ptr->dev_attr.attr.name, *(int *)(ptr->addr)); -#endif - break; - case PDDF_USHORT: - ret = kstrtoint(buf,16,&num); - if (ret==0) - *(unsigned short *)(ptr->addr) = (unsigned short)num; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_USHORT VALUE:%x\n", - ptr->dev_attr.attr.name, *(unsigned short *)(ptr->addr)); -#endif - break; - case PDDF_UINT32: - ret = kstrtoint(buf,16,&num); - if (ret==0) - *(uint32_t *)(ptr->addr) = (uint32_t)num; -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR [%s] PDDF_UINT32 VALUE:%d\n", - ptr->dev_attr.attr.name, *(uint32_t *)(ptr->addr)); -#endif - break; - default: - break; - } - return count; -} - -static int load_led_ops_data(struct device_attribute *da, LED_STATUS state) -{ - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; - LED_TYPE led_type; - LED_OPS_DATA* ops_ptr=NULL; - if(!ptr || strlen(ptr->device_name)==0 ) { - pddf_dbg(LED, KERN_INFO "SYSTEM_LED: load_led_ops_data return -1 device_name:%s\n", ptr? ptr->device_name:"NULL"); - return(-1); - } - if(ptr->device_name) - { - pddf_dbg(LED, KERN_INFO "[%s]: load_led_ops_data: index=%d addr=0x%x;0x%x valu=0x%x\n", - ptr->device_name, ptr->index, ptr->swpld_addr, ptr->swpld_addr_offset, ptr->data[0].value); - } - if((led_type=get_dev_type(ptr->device_name))==LED_TYPE_MAX) { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR *%s Unsupported Led Type\n", __func__); - return(-1); - } - if(dev_index_check(led_type, ptr->index)==-1) { - pddf_dbg(LED, KERN_ERR "PDDF_LED ERROR %s invalid index: %d for type:%d\n", __func__, ptr->index, led_type); - return(-1); - } - ops_ptr = dev_list[led_type]+ptr->index; - - memcpy(ops_ptr->device_name, ptr->device_name, sizeof(ops_ptr->device_name)); - ops_ptr->index = ptr->index; - memcpy(&ops_ptr->data[state], &ptr->data[0], sizeof(LED_DATA)); - ops_ptr->data[state].swpld_addr = ptr->swpld_addr; - ops_ptr->data[state].swpld_addr_offset = ptr->swpld_addr_offset; - ops_ptr->swpld_addr = ptr->swpld_addr; - ops_ptr->swpld_addr_offset = ptr->swpld_addr_offset; - - print_led_data(dev_list[led_type]+ptr->index, state); - - memset(ptr, 0, sizeof(LED_OPS_DATA)); - return (0); -} - -static int show_led_ops_data(struct device_attribute *da) -{ - LED_OPS_DATA* ops_ptr=find_led_ops_data(da); - print_led_data(ops_ptr, -1); - return(0); -} - -static int verify_led_ops_data(struct device_attribute *da) -{ - struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; - LED_OPS_DATA* ptr=(LED_OPS_DATA*)_ptr->addr; - LED_OPS_DATA* ops_ptr=find_led_ops_data(da); - - if(ops_ptr) - memcpy(ptr, ops_ptr, sizeof(LED_OPS_DATA)); - else - { - pddf_dbg(LED, "SYSTEM_LED: verify_led_ops_data: Failed to find ops_ptr name:%s; index=%d\n", ptr->device_name, ptr->index); - } - return (0); -} - - -ssize_t dev_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) -{ -#if DEBUG - pddf_dbg(LED, KERN_INFO "dev_operation [%s]\n", buf); -#endif - if(strstr(buf, "STATUS_LED_COLOR")!= NULL) { - LED_STATUS index = find_state_index(buf); - if (index < MAX_LED_STATUS ) { - load_led_ops_data(da, index); - } else { - printk(KERN_ERR "PDDF_ERROR %s: Invalid state for dev_ops %s", __FUNCTION__, buf); - } - } - else if(strncmp(buf, "show", strlen("show"))==0 ) { - show_led_ops_data(da); - } - else if(strncmp(buf, "verify", strlen("verify"))==0 ) { - verify_led_ops_data(da); - } - else if(strncmp(buf, "get_status", strlen("get_status"))==0 ) { - get_status_led(da); - } - else if(strncmp(buf, "set_status", strlen("set_status"))==0 ) { - set_status_led(da); - } - else { - printk(KERN_ERR "PDDF_ERROR %s: Invalid value for dev_ops %s", __FUNCTION__, buf); - } - return(count); -} - -ssize_t store_config_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) -{ - int ret, num; - struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; - if(strncmp(ptr->dev_attr.attr.name, "num_psus", strlen("num_psus"))==0 ) { - ret = kstrtoint(buf,10,&num); - if (ret==0) - *(int *)(ptr->addr) = num; - if(psu_led_ops_data == NULL) { - if ((psu_led_ops_data = kzalloc(num * sizeof(LED_OPS_DATA), GFP_KERNEL)) == NULL) { - printk(KERN_ERR "PDDF_LED ERROR failed to allocate memory for PSU LED\n"); - return (count); - } - pddf_dbg(LED, "Allocate PSU LED Memory ADDR=%p\n", psu_led_ops_data); - dev_list[LED_PSU]=psu_led_ops_data; - } -#if DEBUG - pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", - ptr->dev_attr.attr.name, num, num_psus); -#endif - return(count); - } - if(strncmp(ptr->dev_attr.attr.name, "num_fantrays", strlen("num_fantrays"))==0 ) { - ret = kstrtoint(buf,10,&num); - if (ret==0) - *(int *)(ptr->addr) = num; - if (fantray_led_ops_data == NULL) { - if ((fantray_led_ops_data = kzalloc(num * sizeof(LED_OPS_DATA), GFP_KERNEL)) == NULL) { - printk(KERN_ERR "PDDF_LED ERROR failed to allocate memory for FANTRAY LED\n"); - return (count); - } - pddf_dbg(LED, "Allocate FanTray LED Memory ADDR=%p\n", fantray_led_ops_data); - dev_list[LED_FANTRAY]=fantray_led_ops_data; - } -#if DEBUG - pddf_dbg(LED, "[ WRITE ] ATTR CONFIG [%s] VALUE:%d; %d\n", - ptr->dev_attr.attr.name, num, num_fantrays); -#endif - return(count); - } - return (count); -} - -ssize_t store_bits_data(struct device *dev, struct device_attribute *da, const char *buf, size_t count) -{ - int len = 0, num1 = 0, num2 = 0, i=0, rc1=0, rc2=0; - char mask=0xFF; - char *pptr=NULL; - char bits[NAME_SIZE]; - struct pddf_data_attribute *ptr = (struct pddf_data_attribute *)da; - MASK_BITS* bits_ptr=(MASK_BITS*)(ptr->addr); - strncpy(bits_ptr->bits, buf, strlen(buf)-1); // to discard newline char form buf - bits_ptr->bits[strlen(buf)-1] = '\0'; - if((pptr=strstr(buf,":")) != NULL) { - len=pptr-buf; - sprintf(bits, buf); - bits[len]='\0'; - rc1=kstrtoint(bits,16,&num1); - if (rc1==0) - { - sprintf(bits, ++pptr); - rc2=kstrtoint(bits,16,&num2); - if (rc2==0) - { - for (i=num2; i<=num1; i++) { - mask &= ~(1 << i); - } - bits_ptr->mask_bits = mask; - bits_ptr->pos = num2; - } - } - } else { - rc1=kstrtoint(buf,16,&num1); - if (rc1==0) - { - bits_ptr->mask_bits = mask & ~(1 << num1); - bits_ptr->pos = num1; - } - } -#if DEBUG - pddf_dbg(LED, KERN_ERR "[ WRITE ] ATTR PTR Bits [%s] VALUE:%s mask:0x%x; pos:0x%x\n", - ptr->dev_attr.attr.name, bits_ptr->bits, bits_ptr->mask_bits, bits_ptr->pos); -#endif - return (count); -} - -/************************************************************************** - * platform/ attributes - **************************************************************************/ -PDDF_LED_DATA_ATTR(platform, num_psus, S_IWUSR|S_IRUGO, show_pddf_data, - store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_psus); -PDDF_LED_DATA_ATTR(platform, num_fantrays, S_IWUSR|S_IRUGO, show_pddf_data, - store_config_data, PDDF_INT_DEC, sizeof(int), (void*)&num_fantrays); - -struct attribute* attrs_platform[]={ - &pddf_dev_platform_attr_num_psus.dev_attr.attr, - &pddf_dev_platform_attr_num_fantrays.dev_attr.attr, - NULL, -}; -struct attribute_group attr_group_platform={ - .attrs = attrs_platform, -}; - -/************************************************************************** - * led/ attributes - **************************************************************************/ -PDDF_LED_DATA_ATTR(dev, device_name, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.device_name); -PDDF_LED_DATA_ATTR(dev, index, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_INT_DEC, sizeof(int), (void*)&temp_data.index); -PDDF_LED_DATA_ATTR(dev, swpld_addr, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr); -PDDF_LED_DATA_ATTR(dev, swpld_addr_offset, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_INT_HEX, sizeof(int), (void*)&temp_data.swpld_addr_offset); -PDDF_LED_DATA_ATTR(dev, dev_ops , S_IWUSR, NULL, - dev_operation, PDDF_CHAR, NAME_SIZE, (void*)&temp_data); - -struct attribute* attrs_dev[]={ - &pddf_dev_dev_attr_device_name.dev_attr.attr, - &pddf_dev_dev_attr_index.dev_attr.attr, - &pddf_dev_dev_attr_swpld_addr.dev_attr.attr, - &pddf_dev_dev_attr_swpld_addr_offset.dev_attr.attr, - &pddf_dev_dev_attr_dev_ops.dev_attr.attr, - NULL, -}; -struct attribute_group attr_group_dev={ - .attrs = attrs_dev, -}; - -/************************************************************************** - * state_attr/ attributes - **************************************************************************/ -#define LED_DEV_STATE_ATTR_GROUP(name, func) \ - PDDF_LED_DATA_ATTR(name, bits, S_IWUSR|S_IRUGO, show_pddf_data, \ - store_bits_data, PDDF_CHAR, NAME_SIZE, func.bits.bits); \ - PDDF_LED_DATA_ATTR(name, value, S_IWUSR|S_IRUGO, show_pddf_data, \ - store_pddf_data, PDDF_USHORT, sizeof(unsigned short), func.value); \ - struct attribute* attrs_##name[]={ \ - &pddf_dev_##name##_attr_bits.dev_attr.attr, \ - &pddf_dev_##name##_attr_value.dev_attr.attr, \ - NULL, \ - }; \ - struct attribute_group attr_group_##name={ \ - .attrs = attrs_##name, \ - }; \ - - -LED_DEV_STATE_ATTR_GROUP(state_attr, (void*)&temp_data.data[0]) - - /************************************************************************** - * cur_state/ attributes - **************************************************************************/ - PDDF_LED_DATA_ATTR(cur_state, color, S_IWUSR|S_IRUGO, show_pddf_data, - store_pddf_data, PDDF_CHAR, NAME_SIZE, (void*)&temp_data.cur_state.color); - -struct attribute* attrs_cur_state[]={ - &pddf_dev_cur_state_attr_color.dev_attr.attr, - NULL, -}; -struct attribute_group attr_group_cur_state={ - .attrs = attrs_cur_state, -}; - -/*************************************************************************/ -#define KOBJ_FREE(obj) \ - if(obj) kobject_put(obj); \ - -void free_kobjs(void) -{ - KOBJ_FREE(cur_state_kobj) - KOBJ_FREE(state_attr_kobj) - KOBJ_FREE(led_kobj) - KOBJ_FREE(platform_kobj) -} - -int KBOJ_CREATE(char* name, struct kobject* parent, struct kobject** child) -{ - if (parent) { - *child = kobject_create_and_add(name, parent); - } else { - printk(KERN_ERR "PDDF_LED ERROR to create %s kobj; null parent\n", name); - free_kobjs(); - return (-ENOMEM); - } - return (0); -} - -int LED_DEV_ATTR_CREATE(struct kobject *kobj, const struct attribute_group *attr, const char* name) -{ - int status = sysfs_create_group(kobj, attr); - if(status) { - pddf_dbg(LED, KERN_ERR "Driver ERROR: sysfs_create %s failed rc=%d\n", name, status); - } - return (status); -} - - -static int __init led_init(void) { - struct kobject *device_kobj; - pddf_dbg(LED, KERN_INFO "PDDF GENERIC LED MODULE init..\n"); - - device_kobj = get_device_i2c_kobj(); - if(!device_kobj) - return -ENOMEM; - - KBOJ_CREATE("platform", device_kobj, &platform_kobj); - KBOJ_CREATE("led", device_kobj, &led_kobj); - KBOJ_CREATE("state_attr", led_kobj, &state_attr_kobj); - KBOJ_CREATE("cur_state", led_kobj, &cur_state_kobj); - - LED_DEV_ATTR_CREATE(platform_kobj, &attr_group_platform, "attr_group_platform"); - LED_DEV_ATTR_CREATE(led_kobj, &attr_group_dev, "attr_group_dev"); - LED_DEV_ATTR_CREATE(state_attr_kobj, &attr_group_state_attr, "attr_group_state_attr"); - LED_DEV_ATTR_CREATE(cur_state_kobj, &attr_group_cur_state, "attr_group_cur_state"); - return (0); -} - - -static void __exit led_exit(void) { - pddf_dbg(LED, "PDDF GENERIC LED MODULE exit..\n"); - free_kobjs(); - if(psu_led_ops_data) kfree(psu_led_ops_data); - if(fantray_led_ops_data) kfree(fantray_led_ops_data); -} - -module_init(led_init); -module_exit(led_exit); - -MODULE_AUTHOR("Broadcom"); -MODULE_DESCRIPTION("led driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_psu.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_psu.c deleted file mode 100644 index d061bf1ad079..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_psu.c +++ /dev/null @@ -1,320 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../../../../pddf/i2c/modules/include/pddf_psu_defs.h" -#include "../../../../../pddf/i2c/modules/include/pddf_psu_driver.h" -#include "../../../common/modules/pmbus.h" - -int pddf_custom_psu_present(void *client, PSU_DATA_ATTR *adata, void *data); -long pmbus_reg2data_liner(void *client, int data, int class); -int pddf_custom_psu_power_good(void *client, PSU_DATA_ATTR *adata, void *data); -int smbus_read_byte(struct i2c_client *client, uint8_t offset); -ssize_t pddf_psu_custom_show(struct device *dev, struct device_attribute *da, char *buf); - -extern void *get_device_table(char *name); -extern PSU_SYSFS_ATTR_DATA access_psu_present; -extern PSU_SYSFS_ATTR_DATA access_psu_power_good; -extern PSU_SYSFS_ATTR_DATA access_psu_v_out; - -int pddf_custom_psu_present(void *client, PSU_DATA_ATTR *adata, void *data) -{ - int ret; - struct i2c_client *client_ptr; - struct psu_attr_info *padata; - - ret = -1; - client_ptr = NULL; - padata = (struct psu_attr_info *)data; - - if (strncmp(adata->devtype, "io", strlen("io")) == 0) { - ret = inb(adata->offset); - /* printk("%s read data %x\n", __FUNCTION__, ret); */ - - if (ret < 0) { - return ret; - } - - padata->val.intval = ((ret & adata->mask) == adata->cmpval); - } - - else if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0) { - client_ptr = (struct i2c_client *)get_device_table(adata->devname); - if (client_ptr) { - ret = i2c_smbus_read_byte_data(client_ptr, adata->offset); - } - - if (ret < 0) { - return ret; - } - - padata->val.intval = ((ret & adata->mask) == adata->cmpval); - } - - return 0; -} - -int pddf_custom_psu_power_good(void *client, PSU_DATA_ATTR *adata, void *data) -{ - int ret; - struct i2c_client *client_ptr; - struct psu_attr_info *padata; - - ret = -1; - client_ptr = NULL; - padata = (struct psu_attr_info *)data; - - if (strncmp(adata->devtype, "io", strlen("io")) == 0) { - ret = inb(adata->offset); - /* printk("%s read data %x\n", __FUNCTION__, ret); */ - - if (ret < 0) { - return ret; - } - - padata->val.intval = ((ret & adata->mask) == adata->cmpval); - } - - else if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0) { - client_ptr = (struct i2c_client *)get_device_table(adata->devname); - if (client_ptr) { - ret = i2c_smbus_read_byte_data(client_ptr, adata->offset); - } - - if (ret < 0) { - return ret; - } - - padata->val.intval = ((ret & adata->mask) == adata->cmpval); - } - - return 0; -} - -int smbus_read_byte(struct i2c_client *client, uint8_t offset) -{ - int retry; - int status; - - retry = 10; - while (retry) { - status = i2c_smbus_read_byte_data(client, offset); - if (unlikely(status < 0)) { - msleep(60); - retry--; - continue; - } - break; - } - - if (status < 0) { - /* TODO perror*/ - } - - return status; -} - -long pmbus_reg2data_liner(void *client, int data, int class) -{ - s16 exponent; - s32 mantissa; - long val; - int vout_mode; - - vout_mode = smbus_read_byte((struct i2c_client *)client, PMBUS_VOUT_MODE); - /* printk("%s vout mode %x\n", __FUNCTION__, vout_mode); */ - if (vout_mode < 0) { - return 0; - } - - /* LINEAR16 */ - if (class == PSC_VOLTAGE_OUT) { - /* exponent = data->exponent[sensor->page]; */ - exponent = ((s8)(vout_mode << 3)) >> 3; - mantissa = (u16) data; - } else { - /* LINEAR11 */ - exponent = ((s16)data) >> 11; - mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; - } - - val = mantissa; - val = val * 1000L; - - /* scale result to micro-units for power sensors */ - if (class == PSC_POWER) { - val = val * 1000L; - } - - if (exponent >= 0) { - val <<= exponent; - } else { - val >>= -exponent; - } - - /* printk("%s class %d ex %x ma %x val %x\n", __FUNCTION__, class, exponent, mantissa, val); */ - - return val; -} - -int psu_update_attr(struct device *dev, struct psu_attr_info *data, PSU_DATA_ATTR *udata) -{ - int status; - struct i2c_client *client; - PSU_SYSFS_ATTR_DATA *sysfs_attr_data; - - status = 0; - client = to_i2c_client(dev); - sysfs_attr_data = NULL; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { - dev_dbg(&client->dev, "Starting update for %s\n", data->name); - - sysfs_attr_data = udata->access_data; - if (sysfs_attr_data->pre_get != NULL) { - status = (sysfs_attr_data->pre_get)(client, udata, data); - if (status != 0) { - printk(KERN_ERR "%s: pre_get function fails for %s attribute\n", __FUNCTION__, udata->aname); - } - } - if (sysfs_attr_data->do_get != NULL) { - status = (sysfs_attr_data->do_get)(client, udata, data); - if (status != 0) { - printk(KERN_ERR "%s: do_get function fails for %s attribute\n", __FUNCTION__, udata->aname); - } - } - if (sysfs_attr_data->post_get != NULL) { - status = (sysfs_attr_data->post_get)(client, udata, data); - if (status != 0) { - printk(KERN_ERR "%s: post_get function fails for %s attribute\n", __FUNCTION__, udata->aname); - } - } - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return 0; -} - -void get_psu_duplicate_sysfs(int idx, char *str) -{ - switch (idx) { - case PSU_V_OUT: - strcpy(str, "in3_input"); - break; - case PSU_I_OUT: - strcpy(str, "curr2_input"); - break; - case PSU_P_OUT: - strcpy(str, "power2_input"); - break; - case PSU_FAN1_SPEED: - strcpy(str, "fan1_input"); - break; - case PSU_TEMP1_INPUT: - strcpy(str, "temp1_input"); - break; - default: - break; - } - - return; -} - -ssize_t pddf_psu_custom_show(struct device *dev, struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr; - struct i2c_client *client; - struct psu_data *data; - - PSU_PDATA *pdata; - PSU_DATA_ATTR *usr_data; - PSU_SYSFS_ATTR_DATA *ptr; - struct psu_attr_info *sysfs_attr_info; - int i; - int status; - char new_str[ATTR_NAME_LEN]; - - attr = to_sensor_dev_attr(da); - client = to_i2c_client(dev); - data = i2c_get_clientdata(client); - - pdata = (PSU_PDATA *)(client->dev.platform_data); - usr_data = NULL; - ptr = NULL; - sysfs_attr_info = NULL; - status = 0; - memset(new_str, 0, ATTR_NAME_LEN); - - for (i = 0; i < data->num_attr; i++) { - ptr = (PSU_SYSFS_ATTR_DATA *)pdata->psu_attrs[i].access_data; - get_psu_duplicate_sysfs(ptr->index , new_str); - if (strcmp(attr->dev_attr.attr.name, pdata->psu_attrs[i].aname) == 0 || \ - strcmp(attr->dev_attr.attr.name, new_str) == 0 ) { - sysfs_attr_info = &data->attr_info[i]; - usr_data = &pdata->psu_attrs[i]; - /* strcpy(new_str, ""); */ - } - } - - if (sysfs_attr_info == NULL || usr_data == NULL) { - printk(KERN_ERR "%s is not supported attribute for this client\n", attr->dev_attr.attr.name); - goto exit; - } - - psu_update_attr(dev, sysfs_attr_info, usr_data); - - switch(attr->index) { - case PSU_V_OUT: - status = pmbus_reg2data_liner(client, sysfs_attr_info->val.shortval, PSC_VOLTAGE_OUT); - break; - case PSU_P_OUT: - status = pmbus_reg2data_liner(client, sysfs_attr_info->val.shortval, PSC_POWER); - break; - case PSU_I_OUT: - case PSU_V_IN: - case PSU_I_IN: - case PSU_TEMP1_INPUT: - status = pmbus_reg2data_liner(client, sysfs_attr_info->val.shortval, PSC_NUM_CLASSES); - break; - default: - printk(KERN_ERR "%s: Unable to find attribute index for %s\n", __FUNCTION__, usr_data->aname); - goto exit; - } - -exit: - return sprintf(buf, "%d\n", status); -} - -int __init pddf_custom_psu_init(void) -{ - access_psu_present.do_get = pddf_custom_psu_present; - access_psu_power_good.do_get = pddf_custom_psu_power_good; - access_psu_v_out.show = pddf_psu_custom_show; - printk(KERN_ERR "pddf_custom_psu_init\n"); - return 0; -} - -void __exit pddf_custom_psu_exit(void) -{ - printk(KERN_ERR "pddf_custom_psu_exit\n"); - return; -} - -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("pddf custom psu api"); -MODULE_LICENSE("GPL"); - -module_init(pddf_custom_psu_init); -module_exit(pddf_custom_psu_exit); - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_xcvr.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_xcvr.c deleted file mode 100644 index 5aa155ce0aa8..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/pddf_custom_xcvr.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include "../../../../../pddf/i2c/modules/include/pddf_xcvr_defs.h" -#include "../../../../../pddf/i2c/modules/include/pddf_xcvr_api.h" - -extern void *get_device_table(char *name); -extern XCVR_SYSFS_ATTR_OPS xcvr_ops[]; - -int pddf_custom_xcvr_pres(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); -int pddf_custom_xcvr_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data); - -int pddf_custom_xcvr_pres(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) -{ - int status; - uint32_t modpres; - - status = 0; - modpres = 0; - if (strcmp(info->devtype, "cpld") == 0 && info->devname) { - client = (struct i2c_client *)get_device_table(info->devname); - status = i2c_smbus_read_byte_data(client, info->offset); - if (status < 0) { - return status; - } else { - modpres = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; - /* printk(KERN_INFO "\nMod presence :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n", modpres, status, info->devaddr, info->mask, info->offset); */ - } - } - - data->modpres = modpres; - return 0; -} - -int pddf_custom_xcvr_reset(struct i2c_client *client, XCVR_ATTR *info, struct xcvr_data *data) -{ - int status; - uint32_t modreset; - - status = 0; - modreset = 0; - if (strcmp(info->devtype, "cpld") == 0 && info->devname) { - client = (struct i2c_client *)get_device_table(info->devname); - status = i2c_smbus_read_byte_data(client, info->offset); - if (status < 0) { - return status; - } else { - modreset = ((status & BIT_INDEX(info->mask)) == info->cmpval) ? 1 : 0; - /* printk(KERN_INFO "\nMod Reset :0x%x, reg_value = 0x%x\n", modreset, status); */ - } - } - - data->reset = modreset; - return 0; -} - -int __init pddf_custom_xcvr_init(void) -{ - xcvr_ops[0].do_get = pddf_custom_xcvr_pres; - xcvr_ops[1].do_get = pddf_custom_xcvr_reset; - - printk(KERN_ERR "pddf_custom_xcvr_init\n"); - return 0; -} - -void __exit pddf_custom_xcvr_exit(void) -{ - printk(KERN_ERR "pddf_custom_xcvr_exit\n"); - return; -} - -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("pddf custom xcvr api"); -MODULE_LICENSE("GPL"); - -module_init(pddf_custom_xcvr_init); -module_exit(pddf_custom_xcvr_exit); - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/ragile.h b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/platform_common.h old mode 100755 new mode 100644 similarity index 89% rename from platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/ragile.h rename to platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/platform_common.h index 338874297e55..e910b7fa15f6 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6510-32c/modules/driver/ragile.h +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/platform_common.h @@ -1,5 +1,5 @@ -#ifndef __RAGILE_H__ -#define __RAGILE_H__ +#ifndef __PLATFORM_COMMON_H__ +#define __PLATFORM_COMMON_H__ #include #include @@ -22,16 +22,16 @@ typedef enum dfd_cpld_id { CPLD2_MAC1, } dfd_cpld_id_t; -typedef enum dfd_cpld_bus { + typedef enum dfd_cpld_bus { SMBUS_BUS = 0 , PCA9641_BUS = 1, GPIO_BUS = 2, } dfd_cpld_bus_t; -typedef struct dfd_i2c_dev_s { - int bus; - int addr; -} dfd_i2c_dev_t; + typedef struct dfd_i2c_dev_s { + int bus; + int addr; + } dfd_i2c_dev_t; typedef enum dfd_cpld_addr { CPLD_ADDR_MIN = 0x31, @@ -82,10 +82,10 @@ typedef enum dfd_dev_info_type_e { typedef struct i2c_muxs_struct_flag { - int nr; - char name[48]; - struct mutex update_lock; - int flag; + int nr; + char name[48]; + struct mutex update_lock; + int flag; }i2c_mux_flag; extern int setpca9641_muxflag(i2c_mux_flag i2c); @@ -95,7 +95,6 @@ extern int debuglevel; extern int dfd_cpld_read_chipid(int cpldid , uint32_t addr, int32_t size, unsigned char *buf); extern int dfd_cpld_read(int32_t addr, uint8_t *val); extern int dfd_cpld_write(int32_t addr, uint8_t val); -extern int ragile_setdebug(int val); #define DBG_DEBUG(fmt, arg...) do { \ if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ @@ -111,6 +110,4 @@ extern int ragile_setdebug(int val); } \ } while (0) -#define COMMON_STR_LEN (256) - #endif diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/rg_cpld.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/rg_cpld.c deleted file mode 100644 index 7d9fc82a6933..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/rg_cpld.c +++ /dev/null @@ -1,559 +0,0 @@ -/* - * rg_cpld.c - A driver for control rg_cpld base on rg_cpld.c - * - * Copyright (c) 1998, 1999 Frodo Looijaard - * Copyright (c) 2018 support - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* debug level */ -typedef enum { - DBG_START, - DBG_VERBOSE, - DBG_KEY, - DBG_WARN, - DBG_ERROR, - DBG_END, -} dbg_level_t; - -static int debuglevel=0; -module_param(debuglevel, int, S_IRUGO); - -#define DBG_DEBUG(fmt, arg...) do { \ - if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ - printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } else if ( debuglevel >= DBG_ERROR ) { \ - printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } else { } \ -} while (0) - -#define DBG_ERROR(fmt, arg...) do { \ - if ( debuglevel > DBG_START) { \ - printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ - } \ - } while (0) - -static const unsigned short rg_i2c_cpld[] = { 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, I2C_CLIENT_END }; - -#define CPLD_SIZE 256 -#define CPLD_I2C_RETRY_TIMES 3 -#define COMMON_STR_LEN (256) - -struct cpld_data { - struct i2c_client *client; - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 data[CPLD_SIZE]; /* Register value */ -}; - -static s32 cpld_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) { - if ((ret = i2c_smbus_read_byte_data(client, command) ) >= 0 ) - break; - } - return ret; -} - -static s32 cpld_i2c_smbus_read_i2c_block_data(const struct i2c_client *client, - u8 command, u8 length, u8 *values) -{ - int try; - s32 ret; - - ret = -1; - for (try = 0; try < CPLD_I2C_RETRY_TIMES; try++) { - if ((ret = i2c_smbus_read_i2c_block_data(client, command, length, values) ) >= 0 ) - break; - } - return ret; -} - -static ssize_t show_fan_rpm_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct cpld_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int index = to_sensor_dev_attr_2(da)->index; - uint8_t size; - s32 status; - s32 ret_t; - u8 tmp[2]; - - ret_t = 0; - status = -1; - size = 0; - memset(tmp, 0, sizeof(tmp)); - - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_byte_data(client, index); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - tmp[0] = status; - status = cpld_i2c_smbus_read_byte_data(client, index + 1); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - tmp[1] = status; - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index, tmp[0]); - DBG_DEBUG("cpld reg pos:0x%x value:0x%x\n", index + 1, tmp[1]); - ret_t = (tmp[1] << 8) + tmp[0]; - if (ret_t == 0 ) { - size = snprintf(buf, CPLD_SIZE, "%d\n", ret_t); - } else if (ret_t == 0xffff) { - size = snprintf(buf, CPLD_SIZE, "%d\n", 0); - } else { - size = snprintf(buf, CPLD_SIZE, "%d\n", 15000000 / ret_t); - } - mutex_unlock(&data->update_lock); - return size; -} - -static ssize_t set_cpld_sysfs_value(struct device *dev, struct device_attribute *da, const char *buf, size_t -count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - unsigned long val; - int err; - - err = kstrtoul(buf, 16, &val); - if (err) - return err; - if ((val < 0) || (val > 0xff)) { - DBG_ERROR("please enter 0x00 ~ 0xff\n"); - return -1; - } - mutex_lock(&data->update_lock); - val = (u8)val; - DBG_DEBUG("pos: 0x%02x count = %ld, data = 0x%02x\n", attr->index, count, val); - i2c_smbus_write_byte_data(client, attr->index, val); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - s32 status; - u8 tmp[4]; - - memset(tmp, 0, sizeof(tmp)); - status = -1; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_i2c_block_data(client, 0, 4, tmp); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - mutex_unlock(&data->update_lock); - return snprintf(buf, COMMON_STR_LEN, "%02x %02x %02x %02x \n", tmp[0], tmp[1], tmp[2], tmp[3]); -} - -static ssize_t show_cpld_sysfs_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct cpld_data *data = i2c_get_clientdata(client); - s32 status; - - status = -1; - mutex_lock(&data->update_lock); - status = cpld_i2c_smbus_read_byte_data(client, attr->index); - if (status < 0) { - mutex_unlock(&data->update_lock); - return 0; - } - DBG_DEBUG("cpld reg pos:0x%x value:0x%02x\n", attr->index, status); - mutex_unlock(&data->update_lock); - return snprintf(buf, COMMON_STR_LEN, "%02x\n", status); -} - -/* common */ -static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO | S_IWUSR, show_cpld_version, NULL, 0); -static SENSOR_DEVICE_ATTR(cpld_card_id, S_IRUGO, show_cpld_sysfs_value, NULL, 0x04); -static SENSOR_DEVICE_ATTR(cpld_card_index, S_IRUGO, show_cpld_sysfs_value, NULL, 0x05); - -/* FAN speed rpm */ -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1B); -static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1D); -static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1F); -static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x25); -static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x27); -static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x29); - -static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1B); -static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1D); -static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x1F); -static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x25); -static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x27); -static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO | S_IWUSR ,show_fan_rpm_value, NULL, 0x29); - -/*FAN speed */ -static SENSOR_DEVICE_ATTR(fan1_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x14); -static SENSOR_DEVICE_ATTR(fan2_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x14); -static SENSOR_DEVICE_ATTR(fan3_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15); -static SENSOR_DEVICE_ATTR(fan4_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15); -static SENSOR_DEVICE_ATTR(fan5_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x16); -static SENSOR_DEVICE_ATTR(fan6_speed_set, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x16); - -static SENSOR_DEVICE_ATTR(fan1_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x1B); -static SENSOR_DEVICE_ATTR(fan2_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x1B); -static SENSOR_DEVICE_ATTR(fan3_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x1D); -static SENSOR_DEVICE_ATTR(fan4_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x1D); -static SENSOR_DEVICE_ATTR(fan5_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x1F); -static SENSOR_DEVICE_ATTR(fan6_1_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x1F); -static SENSOR_DEVICE_ATTR(fan1_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x25); -static SENSOR_DEVICE_ATTR(fan2_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x25); -static SENSOR_DEVICE_ATTR(fan3_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x27); -static SENSOR_DEVICE_ATTR(fan4_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x27); -static SENSOR_DEVICE_ATTR(fan5_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x29); -static SENSOR_DEVICE_ATTR(fan6_2_real_speed, S_IRUGO, show_fan_rpm_value, NULL, 0x29); - -/*FAN led register */ -static SENSOR_DEVICE_ATTR(fan1_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3B); -static SENSOR_DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3B); -static SENSOR_DEVICE_ATTR(fan3_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3C); -static SENSOR_DEVICE_ATTR(fan4_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3C); -static SENSOR_DEVICE_ATTR(fan5_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3D); -static SENSOR_DEVICE_ATTR(fan6_led, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x3D); -static SENSOR_DEVICE_ATTR(fan_led_control, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x40); - -/* FAN present */ -static SENSOR_DEVICE_ATTR(fan_present, S_IRUGO, show_cpld_sysfs_value, NULL, 0x30); - -/* FAN status */ -static SENSOR_DEVICE_ATTR(fan_status1, S_IRUGO, show_cpld_sysfs_value, NULL, 0x31); -static SENSOR_DEVICE_ATTR(fan_status2, S_IRUGO, show_cpld_sysfs_value, NULL, 0x34); - -/* 0x30 */ -/* sfp 1-16 present register */ -static SENSOR_DEVICE_ATTR(sfp_presence1, S_IRUGO, show_cpld_sysfs_value, NULL, 0x10); -static SENSOR_DEVICE_ATTR(sfp_presence2, S_IRUGO, show_cpld_sysfs_value, NULL, 0x11); - -/* sfp 1-16 led register */ -static SENSOR_DEVICE_ATTR(sfp_led1, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x18); -static SENSOR_DEVICE_ATTR(sfp_led2, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x19); -static SENSOR_DEVICE_ATTR(sfp_led_reset, S_IRUGO | S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0xa0); - - -/* 0x31*/ -/* sfp 17-32 present register */ -static SENSOR_DEVICE_ATTR(sfp_presence3, S_IRUGO, show_cpld_sysfs_value, NULL, 0x10); -static SENSOR_DEVICE_ATTR(sfp_presence4, S_IRUGO, show_cpld_sysfs_value, NULL, 0x11); - -/* sfp 17-32 led register */ -static SENSOR_DEVICE_ATTR(sfp_led3, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x18); -static SENSOR_DEVICE_ATTR(sfp_led4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x19); - -static SENSOR_DEVICE_ATTR(sfp_reset1, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x14); -static SENSOR_DEVICE_ATTR(sfp_reset2, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15); -static SENSOR_DEVICE_ATTR(sfp_reset3, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x14); -static SENSOR_DEVICE_ATTR(sfp_reset4, S_IRUGO | S_IWUSR ,show_cpld_sysfs_value, set_cpld_sysfs_value, 0x15); - - -static struct attribute *cpld_bus14_addr_0x0d_sysfs_attrs[] = { - &sensor_dev_attr_cpld_version.dev_attr.attr, - &sensor_dev_attr_cpld_card_id.dev_attr.attr, - &sensor_dev_attr_cpld_card_index.dev_attr.attr, - &sensor_dev_attr_fan1_speed_set.dev_attr.attr, - &sensor_dev_attr_fan3_speed_set.dev_attr.attr, - &sensor_dev_attr_fan5_speed_set.dev_attr.attr, - &sensor_dev_attr_fan1_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan3_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan5_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan1_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan3_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan5_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan_present.dev_attr.attr, - &sensor_dev_attr_fan_status1.dev_attr.attr, - &sensor_dev_attr_fan_status2.dev_attr.attr, - &sensor_dev_attr_fan1_led.dev_attr.attr, - &sensor_dev_attr_fan3_led.dev_attr.attr, - &sensor_dev_attr_fan5_led.dev_attr.attr, - &sensor_dev_attr_fan_led_control.dev_attr.attr, - NULL -}; - -static struct attribute *cpld_bus13_addr_0x0d_sysfs_attrs[] = { - &sensor_dev_attr_cpld_version.dev_attr.attr, - &sensor_dev_attr_cpld_card_id.dev_attr.attr, - &sensor_dev_attr_cpld_card_index.dev_attr.attr, - &sensor_dev_attr_fan2_speed_set.dev_attr.attr, - &sensor_dev_attr_fan4_speed_set.dev_attr.attr, - &sensor_dev_attr_fan6_speed_set.dev_attr.attr, - &sensor_dev_attr_fan2_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan4_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan6_1_real_speed.dev_attr.attr, - &sensor_dev_attr_fan2_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan4_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan6_2_real_speed.dev_attr.attr, - &sensor_dev_attr_fan_present.dev_attr.attr, - &sensor_dev_attr_fan_status1.dev_attr.attr, - &sensor_dev_attr_fan_status2.dev_attr.attr, - &sensor_dev_attr_fan2_led.dev_attr.attr, - &sensor_dev_attr_fan4_led.dev_attr.attr, - &sensor_dev_attr_fan6_led.dev_attr.attr, - &sensor_dev_attr_fan_led_control.dev_attr.attr, - NULL -}; - -static struct attribute *slot_cpld_addr_0x30_sysfs_attrs[] = { - &sensor_dev_attr_sfp_presence1.dev_attr.attr, - &sensor_dev_attr_sfp_presence2.dev_attr.attr, - &sensor_dev_attr_sfp_led1.dev_attr.attr, - &sensor_dev_attr_sfp_led2.dev_attr.attr, - &sensor_dev_attr_cpld_version.dev_attr.attr, - &sensor_dev_attr_sfp_led_reset.dev_attr.attr, - &sensor_dev_attr_sfp_reset1.dev_attr.attr, - &sensor_dev_attr_sfp_reset2.dev_attr.attr, - NULL -}; - -static struct attribute *slot_cpld_addr_0x31_sysfs_attrs[] = { - &sensor_dev_attr_sfp_presence3.dev_attr.attr, - &sensor_dev_attr_sfp_presence4.dev_attr.attr, - &sensor_dev_attr_sfp_led3.dev_attr.attr, - &sensor_dev_attr_sfp_led4.dev_attr.attr, - &sensor_dev_attr_cpld_version.dev_attr.attr, - &sensor_dev_attr_sfp_led_reset.dev_attr.attr, - &sensor_dev_attr_sfp_reset3.dev_attr.attr, - &sensor_dev_attr_sfp_reset4.dev_attr.attr, - NULL -}; - - -static const struct attribute_group cpld_bus14_addr_0x0d_sysfs_group = { - .attrs = cpld_bus14_addr_0x0d_sysfs_attrs, -}; - -static const struct attribute_group cpld_bus13_addr_0x0d_sysfs_group = { - .attrs = cpld_bus13_addr_0x0d_sysfs_attrs, -}; - -static const struct attribute_group slot_cpld_addr_0x30_sysfs_group = { - .attrs = slot_cpld_addr_0x30_sysfs_attrs, -}; - -static const struct attribute_group slot_cpld_addr_0x31_sysfs_group = { - .attrs = slot_cpld_addr_0x31_sysfs_attrs, -}; - - -static struct attribute *cpld_hwmon_bus14_attrs[] = { - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_fan5_input.dev_attr.attr, - &sensor_dev_attr_fan9_input.dev_attr.attr, - &sensor_dev_attr_fan2_input.dev_attr.attr, - &sensor_dev_attr_fan6_input.dev_attr.attr, - &sensor_dev_attr_fan10_input.dev_attr.attr, - NULL -}; -static struct attribute *cpld_hwmon_bus13_attrs[] = { - &sensor_dev_attr_fan3_input.dev_attr.attr, - &sensor_dev_attr_fan7_input.dev_attr.attr, - &sensor_dev_attr_fan11_input.dev_attr.attr, - &sensor_dev_attr_fan4_input.dev_attr.attr, - &sensor_dev_attr_fan8_input.dev_attr.attr, - &sensor_dev_attr_fan12_input.dev_attr.attr, - NULL -}; -ATTRIBUTE_GROUPS(cpld_hwmon_bus14); -ATTRIBUTE_GROUPS(cpld_hwmon_bus13); - -struct cpld_attr_match_group { - int bus_nr; - unsigned short addr; - const struct attribute_group *attr_group_ptr; - const struct attribute_group *attr_hwmon_ptr; -}; - -static struct cpld_attr_match_group g_cpld_attr_match[] = { - {14, 0x0D, &cpld_bus14_addr_0x0d_sysfs_group, (struct attribute_group *)cpld_hwmon_bus14_groups}, - {13, 0x0D, &cpld_bus13_addr_0x0d_sysfs_group, (struct attribute_group *)cpld_hwmon_bus13_groups}, - {3, 0x30, &slot_cpld_addr_0x30_sysfs_group,NULL }, - {3, 0x31, &slot_cpld_addr_0x31_sysfs_group, NULL}, - {4, 0x30, &slot_cpld_addr_0x30_sysfs_group,NULL }, - {4, 0x31, &slot_cpld_addr_0x31_sysfs_group, NULL}, - {5, 0x30, &slot_cpld_addr_0x30_sysfs_group,NULL }, - {5, 0x31, &slot_cpld_addr_0x31_sysfs_group, NULL}, - {6, 0x30, &slot_cpld_addr_0x30_sysfs_group,NULL }, - {6, 0x31, &slot_cpld_addr_0x31_sysfs_group, NULL}, -}; - -static const struct attribute_group *cpld_get_attr_group(struct i2c_client *client, int is_hwmon) -{ - int i; - struct cpld_attr_match_group *group; - - for (i = 0; i < ARRAY_SIZE(g_cpld_attr_match); i++) { - group = &g_cpld_attr_match[i]; - DBG_DEBUG("is_hwmon %d i %d client(nr:%d,addr:0x%x), group(nr:%d,addr:0x0%x) .\n", is_hwmon, - i, client->adapter->nr, client->addr, group->bus_nr, group->addr); - if ((client->addr == group->addr) && (client->adapter->nr == group->bus_nr)) { - DBG_DEBUG("is_hwmon %d i %d nr %d addr %d .\n", is_hwmon, i, client->adapter->nr, client->addr); - return (is_hwmon) ? (group->attr_hwmon_ptr) : (group->attr_group_ptr); - } - } - - DBG_DEBUG("is_hwmon %d nr %d addr %d dismatch, return NULL.\n", is_hwmon, client->adapter->nr, client->addr); - return NULL; -} - -#if 0 -static int cpld_detect(struct i2c_client *new_client, struct i2c_board_info *info) -{ - struct i2c_adapter *adapter = new_client->adapter; - int conf; - DBG_DEBUG("=========cpld_detect(0x%x)===========\n", new_client->addr); - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) - return -ENODEV; - conf = i2c_smbus_read_byte_data(new_client, 0); - if (!conf) - return -ENODEV; - strlcpy(info->type, "rg_cpld", I2C_NAME_SIZE); - return 0; -} -#endif - -static int cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct cpld_data *data; - int status; - const struct attribute_group *sysfs_group, *hwmon_group; - - status = -1; - DBG_DEBUG("=========cpld_probe(addr:0x%x, nr:%d)===========\n", client->addr, client->adapter->nr); - data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), GFP_KERNEL); - if (!data) { - return -ENOMEM; - } - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - sysfs_group = NULL; - sysfs_group = cpld_get_attr_group(client, 0); - if (sysfs_group) { - status = sysfs_create_group(&client->dev.kobj, sysfs_group); - DBG_DEBUG("=========(addr:0x%x, nr:%d) sysfs_create_group status %d===========\n", client->addr, client->adapter->nr, status); - if (status != 0) { - DBG_ERROR("sysfs_create_group status %d.\n", status); - goto error; - } - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no sysfs_create_group \n", client->addr, client->adapter->nr); - } - - hwmon_group = NULL; - hwmon_group = cpld_get_attr_group(client, 1); - if (hwmon_group) { - data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, (const struct attribute_group **)hwmon_group); - if (IS_ERR(data->hwmon_dev)) { - sysfs_remove_group(&client->dev.kobj, (const struct attribute_group *)sysfs_group); - DBG_ERROR("hwmon_device_register_with_groups failed ret %ld.\n", PTR_ERR(data->hwmon_dev)); - return PTR_ERR(data->hwmon_dev); - } - DBG_DEBUG("=========(addr:0x%x, nr:%d) hwmon_device_register_with_groups success===========\n", client->addr, client->adapter->nr); - if (status != 0) { - DBG_ERROR("sysfs_create_group status %d.\n", status); - goto error; - } - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no hwmon_device_register_with_groups \n", client->addr, client->adapter->nr); - } - -error: - return status; - -} - -static int cpld_remove(struct i2c_client *client) -{ - struct cpld_data *data = i2c_get_clientdata(client); - const struct attribute_group *sysfs_group, *hwmon_group; - - DBG_DEBUG("=========cpld_remove(addr:0x%x, nr:%d)===========\n", client->addr, client->adapter->nr); - - sysfs_group = NULL; - sysfs_group = cpld_get_attr_group(client, 0); - if (sysfs_group) { - DBG_DEBUG("=========(addr:0x%x, nr:%d) do sysfs_remove_group \n", client->addr, client->adapter->nr); - sysfs_remove_group(&client->dev.kobj, (const struct attribute_group *)sysfs_group); - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no sysfs_remove_group \n", client->addr, client->adapter->nr); - } - - hwmon_group = NULL; - hwmon_group = cpld_get_attr_group(client, 1); - if (hwmon_group) { - DBG_DEBUG("=========(addr:0x%x, nr:%d) do hwmon_device_unregister \n", client->addr, client->adapter->nr); - hwmon_device_unregister(data->hwmon_dev); - } else { - DBG_DEBUG("=========(addr:0x%x, nr:%d) no hwmon_device_unregister \n", client->addr, client->adapter->nr); - } - - return 0; -} - -static const struct i2c_device_id cpld_id[] = { - { "rg_cpld", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, cpld_id); - -static struct i2c_driver rg_cpld_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "rg_cpld", - }, - .probe = cpld_probe, - .remove = cpld_remove, - .id_table = cpld_id, - //.detect = cpld_detect, - // .address_list = rg_i2c_cpld, -}; - -module_i2c_driver(rg_cpld_driver); -MODULE_AUTHOR("support "); -MODULE_DESCRIPTION("ragile CPLD driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/rg_lpc_cpld.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/rg_lpc_cpld.c deleted file mode 100755 index 2141567bf167..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/rg_lpc_cpld.c +++ /dev/null @@ -1,250 +0,0 @@ -#include /* Wd're doing kernel work */ -#include /* specifically, a module */ -#include -#include /* Need for the macros */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ragile.h" - -int lpc_cpld_verbose = 0; -int lpc_cpld_error = 0; -module_param(lpc_cpld_verbose, int, S_IRUGO | S_IWUSR); -module_param(lpc_cpld_error, int, S_IRUGO | S_IWUSR); - - -#define LPC_CPLD_VERBOSE(fmt, args...) do { \ - if (lpc_cpld_verbose) { \ - printk(KERN_ERR "[LPC_CPLD_I2C_DEVICE][VERBOSE][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define LPC_CPLD_ERROR(fmt, args...) do { \ - if (lpc_cpld_error) { \ - printk(KERN_ERR "[LPC_CPLD_I2C_DEVICE][ERROR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ - } \ - } while (0) - -#define PCI_VENDOR_ID_D1527_LPC (0x8c54) -#define PCI_VENDOR_ID_C3000_LPC (0x19dc) - -#define MAX_CPLD_REG_SIZE (0x100) -#define LPC_GET_CPLD_ID(addr) ((addr >> 16) & 0xff) -#define LPC_GET_CPLD_OFFSET(addr) ((addr) & 0xff) -typedef struct rg_lpc_device_s { - u16 base; - u16 size; - u8 type; - u8 id; -} rg_lpc_device_t; - -typedef enum rg_lpc_dev_type_s { - LPC_DEVICE_CPLD = 1, - LPC_DEVICE_FPGA = 2, -} rg_lpc_dev_type_t; - -static rg_lpc_device_t g_rg_lpc_dev[] = { - {.base = 0x700, .size = MAX_CPLD_REG_SIZE, .type = LPC_DEVICE_CPLD, .id = 0}, - {.base = 0x900, .size = MAX_CPLD_REG_SIZE, .type = LPC_DEVICE_CPLD, .id = 1}, - {.base = 0xb00, .size = MAX_CPLD_REG_SIZE, .type = LPC_DEVICE_CPLD, .id = 2}, - /*{.base = 0x900, .size = MAX_FPGA_REG_SIZE, .type = LPC_DEVICE_FPGA, .id = 0},*/ -}; - -static rg_lpc_device_t* lpc_get_device_info(int type, int id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(g_rg_lpc_dev); i++) { - if ((g_rg_lpc_dev[i].type == type) && (g_rg_lpc_dev[i].id == id)) { - return &g_rg_lpc_dev[i]; - } - } - - return NULL; -} - -static int lpc_cpld_read(int address, u8 *val) -{ - int cpld_id; - rg_lpc_device_t *info; - - LPC_CPLD_ERROR("Enter\n"); - cpld_id = LPC_GET_CPLD_ID(address); - LPC_CPLD_ERROR("icpld_id=%d\n", cpld_id); - info = lpc_get_device_info(LPC_DEVICE_CPLD, cpld_id); - if (info == NULL) { - LPC_CPLD_ERROR("lpc_get_device_info addr 0x%x id %d failed.\r\n", address, cpld_id); - return -1; - } - - *val = inb(info->base + LPC_GET_CPLD_OFFSET(address)); - LPC_CPLD_VERBOSE("Leave info->base 0x%x, addr 0x%x, cpld_id %d, val 0x%x.\r\n", info->base, address, cpld_id, *val); - return 0; -} - -static int lpc_cpld_write(int address, u8 reg_val) -{ - int cpld_id; - rg_lpc_device_t *info; - - cpld_id = LPC_GET_CPLD_ID(address); - info = lpc_get_device_info(LPC_DEVICE_CPLD, cpld_id); - if (info == NULL) { - LPC_CPLD_ERROR("lpc_get_device_info addr 0x%x id %d failed.\r\n", address, cpld_id); - return -1; - } - - outb(reg_val, info->base + LPC_GET_CPLD_OFFSET(address)); - LPC_CPLD_VERBOSE("Leave info->base 0x%x, addr 0x%x, cpld_id %d, val 0x%x.\r\n", info->base, address, cpld_id, reg_val); - return 0; -} - -static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da, char *buf) -{ - int ret, i; - u8 data[4]; - u32 index = to_sensor_dev_attr(da)->index; - - memset(data, 0 ,sizeof(data)); - for (i = 0; i < 4; i++) { - ret = lpc_cpld_read(index + i, &data[i]); - if (ret != 0) { - memset(data, 0 ,sizeof(data)); - LPC_CPLD_ERROR("get cpld version failed!\n"); - break; - } - } - - return snprintf(buf, COMMON_STR_LEN, "%02x %02x %02x %02x \n", data[0], data[1], data[2], data[3]); - -} - -static ssize_t show_cpld_sysfs_value(struct device *dev, struct device_attribute *da, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - u8 data; - int ret; - - ret = lpc_cpld_read(attr->index, &data); - if (ret != 0) { - LPC_CPLD_ERROR("get cpld[0x%x] value failed!\n", attr->index); - data = 0; - } - return snprintf(buf, COMMON_STR_LEN, "%02x\n", data); -} - -static ssize_t set_cpld_sysfs_value(struct device *dev, struct device_attribute *da, const char *buf, size_t -count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - u8 data; - unsigned long val; - int err; - - err = kstrtoul(buf, 16, &val); - if (err) - return err; - if ((val < 0) || (val > 0xff)) { - LPC_CPLD_ERROR("please enter 0x00 ~ 0xff\n"); - return -1; - } - - data = (u8)val; - LPC_CPLD_VERBOSE("pos: 0x%02x count = %ld, data = 0x%02x\n", attr->index, count, data); - err = lpc_cpld_write(attr->index, data); - if (err != 0) { - LPC_CPLD_ERROR("set cpld[0x%x] value[0x%x] failed!\n", attr->index, data); - count = 0; - } - - return count; -} - -/* common */ -static SENSOR_DEVICE_ATTR(cpld_version_0_0, S_IRUGO, show_cpld_version, NULL, 0x10000); -static SENSOR_DEVICE_ATTR(cpld_version_0_1, S_IRUGO, show_cpld_version, NULL, 0x20000); - -static SENSOR_DEVICE_ATTR(broad_front_sys, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x20021); -static SENSOR_DEVICE_ATTR(broad_front_pwr, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x20022); -static SENSOR_DEVICE_ATTR(broad_front_fan, S_IRUGO| S_IWUSR, show_cpld_sysfs_value, set_cpld_sysfs_value, 0x20023); - -/* psu status */ -static SENSOR_DEVICE_ATTR(psu_status_1, S_IRUGO, show_cpld_sysfs_value, NULL, 0x20027); -static SENSOR_DEVICE_ATTR(psu_status_2, S_IRUGO, show_cpld_sysfs_value, NULL, 0x20028); -static SENSOR_DEVICE_ATTR(psu_status_3, S_IRUGO, show_cpld_sysfs_value, NULL, 0x20029); -static SENSOR_DEVICE_ATTR(psu_status_4, S_IRUGO, show_cpld_sysfs_value, NULL, 0x2002a); - -/* line card present status */ -static SENSOR_DEVICE_ATTR(slot_present, S_IRUGO, show_cpld_sysfs_value, NULL, 0x2002c); - -static struct attribute *lpc_cpld_base_sysfs_attrs[] = { - &sensor_dev_attr_cpld_version_0_0.dev_attr.attr, - &sensor_dev_attr_cpld_version_0_1.dev_attr.attr, - &sensor_dev_attr_broad_front_sys.dev_attr.attr, - &sensor_dev_attr_broad_front_pwr.dev_attr.attr, - &sensor_dev_attr_broad_front_fan.dev_attr.attr, - &sensor_dev_attr_psu_status_1.dev_attr.attr, - &sensor_dev_attr_psu_status_2.dev_attr.attr, - &sensor_dev_attr_psu_status_3.dev_attr.attr, - &sensor_dev_attr_psu_status_4.dev_attr.attr, - &sensor_dev_attr_slot_present.dev_attr.attr, - NULL -}; - -static const struct attribute_group lpc_cpld_base_sysfs_group = { - .attrs = lpc_cpld_base_sysfs_attrs, -}; - -static int __init rg_lpc_cpld_init(void) -{ - struct pci_dev *pdev = NULL; - int status; - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC, pdev); - if (!pdev) { - LPC_CPLD_ERROR("pci_get_device(0x8086, 0x8c54) failed!\n"); - return -1; - } - - status = -1; - status = sysfs_create_group(&pdev->dev.kobj, &lpc_cpld_base_sysfs_group); - if (status) { - LPC_CPLD_ERROR("sysfs_create_group failed!\n"); - return -1; - } - - LPC_CPLD_VERBOSE("Leave success\n"); - return 0; -} - -static void __exit rg_lpc_cpld_exit(void) -{ - struct pci_dev *pdev = NULL; - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_D1527_LPC, pdev); - if (!pdev) { - LPC_CPLD_ERROR("pci_get_device(0x8086, 0x8c54) failed!\n"); - return ; - } - - sysfs_remove_group(&pdev->dev.kobj, &lpc_cpld_base_sysfs_group); - - LPC_CPLD_VERBOSE("Leave.\n"); -} - -module_init(rg_lpc_cpld_init); -module_exit(rg_lpc_cpld_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("support "); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_firmware_upgrade_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_firmware_upgrade_device.c new file mode 100644 index 000000000000..9713f42c6634 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_firmware_upgrade_device.c @@ -0,0 +1,243 @@ +/* + * wb_firmware_upgrade.c + * Original Author: support 2021-03-17 + * + * ko for firmware device + * History + * [Version] [Author] [Date] [Description] + * v1.0 support 2021-05-07 Initial version + */ +#include +#include +#include +#include +#include +#include + +static int g_wb_firmware_upgrade_debug = 0; +static int g_wb_firmware_upgrade_error = 0; + +module_param(g_wb_firmware_upgrade_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_firmware_upgrade_error, int, S_IRUGO | S_IWUSR); + +#define WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_firmware_upgrade_debug) { \ + printk(KERN_INFO "[WB_FIRMWARE_UPGRADE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FIRMWARE_UPGRADE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_firmware_upgrade_error) { \ + printk(KERN_ERR "[WB_FIRMWARE_UPGRADE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 48, + .en_level[1] = 1, + .chain = 1, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* slot1 */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 39, + .en_level[1] = 1, + .chain = 16, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* slot2 */ +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 69, + .en_level[1] = 1, + .chain = 32, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* slot3 */ +static firmware_upgrade_device_t firmware_upgrade_device_data3 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 70, + .en_level[1] = 1, + .chain = 48, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* slot4 */ +static firmware_upgrade_device_t firmware_upgrade_device_data4 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 67, + .tck = 65, + .tms = 6, + .tdo = 32, + }, + .en_gpio[0] = 50, + .en_level[0] = 1, + .en_gpio[1] = 71, + .en_level[1] = 1, + .chain = 64, + .chip_index = 1, + + .en_gpio_num = 2, + .en_logic_num = 0, +}; + +/* bios */ +static firmware_upgrade_device_t firmware_upgrade_device_data5 = { + .type = "MTD_DEV", + .chain = 1, + .chip_index = 1, + .upg_type.sysfs = { + .mtd_name = "BIOS", + .flash_base = 0x800000, + }, + + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 4, + .dev = { + .platform_data = &firmware_upgrade_device_data3, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 5, + .dev = { + .platform_data = &firmware_upgrade_device_data4, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 6, + .dev = { + .platform_data = &firmware_upgrade_device_data5, + .release = firmware_device_release, + }, + }, +}; + +static int __init firmware_upgrade_device_init(void) +{ + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit firmware_upgrade_device_exit(void) +{ + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&firmware_upgrade_device[i]); + } + } +} + +module_init(firmware_upgrade_device_init); +module_exit(firmware_upgrade_device_exit); +MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 000000000000..f9fb5f815eb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,632 @@ +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca954x_device_debug = 0; +static int g_wb_i2c_mux_pca954x_device_error = 0; + +module_param(g_wb_i2c_mux_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x76, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 7, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x936, + .io_attr.mask = 0x10, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x10, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data1 = { + .i2c_bus = 7, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 15, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data2 = { + .i2c_bus = 8, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 23, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x10, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x10, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data3 = { + .i2c_bus = 9, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 31, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data4 = { + .i2c_bus = 11, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 39, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data5 = { + .i2c_bus = 12, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 47, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0x917, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data6 = { + .i2c_bus = 13, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 55, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb10, + .io_attr.mask = 0x80, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x80, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data7 = { + .i2c_bus = 14, + .i2c_addr = 0x77, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 1, + .pca9548_base_nr = 63, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb10, + .io_attr.mask = 0x20, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x20, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data8 = { + .i2c_bus = 3, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 71, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data9 = { + .i2c_bus = 3, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 79, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data10 = { + .i2c_bus = 3, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 87, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data11 = { + .i2c_bus = 3, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 95, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x01, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x01, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data12 = { + .i2c_bus = 4, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 103, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data13 = { + .i2c_bus = 4, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 111, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data14 = { + .i2c_bus = 4, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 119, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data15 = { + .i2c_bus = 4, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 127, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x02, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x02, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data16 = { + .i2c_bus = 5, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 135, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data17 = { + .i2c_bus = 5, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 143, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data18 = { + .i2c_bus = 5, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 151, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data19 = { + .i2c_bus = 5, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 159, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x04, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x04, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data20 = { + .i2c_bus = 6, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 167, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data21 = { + .i2c_bus = 6, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 175, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data22 = { + .i2c_bus = 6, + .i2c_addr = 0x72, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 183, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data23 = { + .i2c_bus = 6, + .i2c_addr = 0x73, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 191, + .pca9548_reset_type = PCA9548_RESET_IO, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .io_attr.io_addr = 0xb17, + .io_attr.mask = 0x08, + .io_attr.reset_on = 0, + .io_attr.reset_off = 0x08, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data1, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data2, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data3, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data4, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data5, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data6, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data7, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data8, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data9, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data10, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data11, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data12, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data13, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data14, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data15, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data16, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data17, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data18, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data19, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data20, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data21, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data22, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data23, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (!client) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_ocores_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_ocores_device.c new file mode 100644 index 000000000000..961e8edeaaff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_i2c_ocores_device.c @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_ocores_device_debug = 0; +static int g_wb_i2c_ocores_device_error = 0; + +module_param(g_wb_i2c_ocores_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_ocores_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_debug) { \ + printk(KERN_INFO "[WB_I2C_OCORE_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_OCORE_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_ocores_device_error) { \ + printk(KERN_ERR "[WB_I2C_OCORE_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_ocores_device_t i2c_ocores_device_data0 = { + .adap_nr = 2, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0xa0, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data1 = { + .adap_nr = 3, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0x80, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data2 = { + .adap_nr = 4, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0x88, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data3 = { + .adap_nr = 5, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0x90, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static i2c_ocores_device_t i2c_ocores_device_data4 = { + .adap_nr = 6, + .big_endian = 0, + .dev_name = "/dev/cpld2", + .reg_access_mode = 2, + .dev_base = 0x98, + .reg_shift = 0, + .reg_io_width = 1, + .ip_clock_khz = 25000, + .bus_clock_khz = 75, + .irq_type = 0, +}; + +static void wb_i2c_ocores_device_release(struct device *dev) +{ + return; +} + +static struct platform_device i2c_ocores_device[] = { + { + .name = "wb-ocores-i2c", + .id = 1, + .dev = { + .platform_data = &i2c_ocores_device_data0, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 2, + .dev = { + .platform_data = &i2c_ocores_device_data1, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 3, + .dev = { + .platform_data = &i2c_ocores_device_data2, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 4, + .dev = { + .platform_data = &i2c_ocores_device_data3, + .release = wb_i2c_ocores_device_release, + }, + }, + { + .name = "wb-ocores-i2c", + .id = 5, + .dev = { + .platform_data = &i2c_ocores_device_data4, + .release = wb_i2c_ocores_device_release, + }, + }, +}; + +static int __init wb_i2c_ocores_device_init(void) +{ + int i; + int ret = 0; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_ocores_device); i++) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + ret = platform_device_register(&i2c_ocores_device[i]); + if (ret < 0) { + i2c_ocores_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-ocores-i2c.%d register failed!\n", i + 1); + } else { + i2c_ocores_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_i2c_ocores_device_exit(void) +{ + int i; + i2c_ocores_device_t *i2c_ocores_device_data; + + WB_I2C_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_ocores_device) - 1; i >= 0; i--) { + i2c_ocores_device_data = i2c_ocores_device[i].dev.platform_data; + if (i2c_ocores_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&i2c_ocores_device[i]); + } + } +} + +module_init(wb_i2c_ocores_device_init); +module_exit(wb_i2c_ocores_device_exit); +MODULE_DESCRIPTION("I2C OCORES Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..454815c23369 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_io_dev_device.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data1 = { + .io_dev_name = "cpld1", + .io_base = 0xb00, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data2 = { + .io_dev_name = "cpld2", + .io_base = 0x900, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 2, + .dev = { + .platform_data = &io_dev_device_data1, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 3, + .dev = { + .platform_data = &io_dev_device_data2, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..9b6b61a51735 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static lpc_drv_device_t lpc_drv_device_data_1 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x900, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x88, +}; + +static lpc_drv_device_t lpc_drv_device_data_2 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0xb00, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x90, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 2, + .dev = { + .platform_data = &lpc_drv_device_data_1, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 3, + .dev = { + .platform_data = &lpc_drv_device_data_2, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_platform_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_platform_i2c_dev_device.c new file mode 100644 index 000000000000..42a945dc8ba2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/modules/driver/wb_platform_i2c_dev_device.c @@ -0,0 +1,263 @@ +#include +#include +#include +#include +#include + +#include + +static int g_wb_platform_i2c_dev_device_debug = 0; +static int g_wb_platform_i2c_dev_device_error = 0; + +module_param(g_wb_platform_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_platform_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_platform_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_PLATFORM_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_platform_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_PLATFORM_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* FAN CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data0 = { + .i2c_bus = 14, + .i2c_addr = 0x0d, + .i2c_name = "cpld3", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* FAN CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data1 = { + .i2c_bus = 13, + .i2c_addr = 0x0d, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT1 CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data2 = { + .i2c_bus = 3, + .i2c_addr = 0x31, + .i2c_name = "cpld5", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT1 CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data3 = { + .i2c_bus = 3, + .i2c_addr = 0x30, + .i2c_name = "cpld6", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT2 CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data4 = { + .i2c_bus = 4, + .i2c_addr = 0x31, + .i2c_name = "cpld7", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT2 CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data5 = { + .i2c_bus = 4, + .i2c_addr = 0x30, + .i2c_name = "cpld8", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT3 CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data6 = { + .i2c_bus = 5, + .i2c_addr = 0x31, + .i2c_name = "cpld9", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT3 CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data7 = { + .i2c_bus = 5, + .i2c_addr = 0x30, + .i2c_name = "cpld10", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT4 CPLDA */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data8 = { + .i2c_bus = 6, + .i2c_addr = 0x31, + .i2c_name = "cpld11", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +/* SLOT4 CPLDB */ +static platform_i2c_dev_device_t platform_i2c_dev_device_data9 = { + .i2c_bus = 6, + .i2c_addr = 0x30, + .i2c_name = "cpld12", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, +}; + +static void wb_platform_i2c_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device platform_i2c_dev_device[] = { + { + .name = "wb-platform-i2c-dev", + .id = 1, + .dev = { + .platform_data = &platform_i2c_dev_device_data0, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 2, + .dev = { + .platform_data = &platform_i2c_dev_device_data1, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 3, + .dev = { + .platform_data = &platform_i2c_dev_device_data2, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 4, + .dev = { + .platform_data = &platform_i2c_dev_device_data3, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 5, + .dev = { + .platform_data = &platform_i2c_dev_device_data4, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 6, + .dev = { + .platform_data = &platform_i2c_dev_device_data5, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 7, + .dev = { + .platform_data = &platform_i2c_dev_device_data6, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 8, + .dev = { + .platform_data = &platform_i2c_dev_device_data7, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 9, + .dev = { + .platform_data = &platform_i2c_dev_device_data8, + .release = wb_platform_i2c_dev_device_release, + }, + }, + { + .name = "wb-platform-i2c-dev", + .id = 10, + .dev = { + .platform_data = &platform_i2c_dev_device_data9, + .release = wb_platform_i2c_dev_device_release, + }, + }, +}; + +static int __init wb_platform_i2c_dev_device_init(void) +{ + int i; + int ret = 0; + platform_i2c_dev_device_t *platform_i2c_dev_device_data; + + WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(platform_i2c_dev_device); i++) { + platform_i2c_dev_device_data = platform_i2c_dev_device[i].dev.platform_data; + ret = platform_device_register(&platform_i2c_dev_device[i]); + if (ret < 0) { + platform_i2c_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-platform-i2c-dev.%d register failed!\n", i + 1); + } else { + platform_i2c_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_platform_i2c_dev_device_exit(void) +{ + int i; + platform_i2c_dev_device_t *platform_i2c_dev_device_data; + + WB_PLATFORM_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(platform_i2c_dev_device) - 1; i >= 0; i--) { + platform_i2c_dev_device_data = platform_i2c_dev_device[i].dev.platform_data; + if (platform_i2c_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&platform_i2c_dev_device[i]); + } + } +} + +module_init(wb_platform_i2c_dev_device_init); +module_exit(wb_platform_i2c_dev_device_exit); +MODULE_DESCRIPTION("PLATFORM I2C DEV Devices"); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..ad8cc36f7145 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,61 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_1_0=3 +cpld_i2c_dev.addr_1_0=0x31 +cpld_i2c_dev.bus_1_1=3 +cpld_i2c_dev.addr_1_1=0x30 +cpld_i2c_dev.bus_2_0=4 +cpld_i2c_dev.addr_2_0=0x31 +cpld_i2c_dev.bus_2_1=4 +cpld_i2c_dev.addr_2_1=0x30 +cpld_i2c_dev.bus_3_0=5 +cpld_i2c_dev.addr_3_0=0x31 +cpld_i2c_dev.bus_3_1=5 +cpld_i2c_dev.addr_3_1=0x30 +cpld_i2c_dev.bus_4_0=6 +cpld_i2c_dev.addr_4_0=0x31 +cpld_i2c_dev.bus_4_1=6 +cpld_i2c_dev.addr_4_1=0x30 +cpld_i2c_dev.bus_5_0=14 +cpld_i2c_dev.addr_5_0=0x0d +cpld_i2c_dev.bus_5_1=13 +cpld_i2c_dev.addr_5_1=0x0d + + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_0=0x700 +cpld_lpc_dev_0_1=0xb00 +cpld_lpc_dev_0_2=0x900 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=lpc +mode_cpld_0_1=lpc +mode_cpld_0_2=lpc +mode_cpld_1_0=i2c +mode_cpld_1_1=i2c +mode_cpld_2_0=i2c +mode_cpld_2_1=i2c +mode_cpld_3_0=i2c +mode_cpld_3_1=i2c +mode_cpld_4_0=i2c +mode_cpld_4_1=i2c +mode_cpld_5_0=i2c +mode_cpld_5_1=i2c + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=13 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..2d07cec07ff3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,440 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=6 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=2 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x05000030 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x05010030 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=0 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x05000030 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=1 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=cpld +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.addr_1_4=0x05010030 +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=1 + +dev_present_status.mode_1_5=config +dev_present_status.src_1_5=cpld +dev_present_status.frmt_1_5=bit +dev_present_status.pola_1_5=negative +dev_present_status.addr_1_5=0x05000030 +dev_present_status.len_1_5=1 +dev_present_status.bit_offset_1_5=2 + +dev_present_status.mode_1_6=config +dev_present_status.src_1_6=cpld +dev_present_status.frmt_1_6=bit +dev_present_status.pola_1_6=negative +dev_present_status.addr_1_6=0x05010030 +dev_present_status.len_1_6=1 +dev_present_status.bit_offset_1_6=2 + + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x05000014 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_1_1=config +fan_ratio.int_cons_1_1= +fan_ratio.src_1_1=cpld +fan_ratio.frmt_1_1=byte +fan_ratio.pola_1_1= +fan_ratio.fpath_1_1= +fan_ratio.addr_1_1=0x05000014 +fan_ratio.len_1_1=1 +fan_ratio.bit_offset_1_1= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x05010014 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_2_1=config +fan_ratio.int_cons_2_1= +fan_ratio.src_2_1=cpld +fan_ratio.frmt_2_1=byte +fan_ratio.pola_2_1= +fan_ratio.fpath_2_1= +fan_ratio.addr_2_1=0x05010014 +fan_ratio.len_2_1=1 +fan_ratio.bit_offset_2_1= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x05000015 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= + +fan_ratio.mode_3_1=config +fan_ratio.int_cons_3_1= +fan_ratio.src_3_1=cpld +fan_ratio.frmt_3_1=byte +fan_ratio.pola_3_1= +fan_ratio.fpath_3_1= +fan_ratio.addr_3_1=0x05000015 +fan_ratio.len_3_1=1 +fan_ratio.bit_offset_3_1= + +fan_ratio.mode_4_0=config +fan_ratio.int_cons_4_0= +fan_ratio.src_4_0=cpld +fan_ratio.frmt_4_0=byte +fan_ratio.pola_4_0= +fan_ratio.fpath_4_0= +fan_ratio.addr_4_0=0x05010015 +fan_ratio.len_4_0=1 +fan_ratio.bit_offset_4_0= + +fan_ratio.mode_4_1=config +fan_ratio.int_cons_4_1= +fan_ratio.src_4_1=cpld +fan_ratio.frmt_4_1=byte +fan_ratio.pola_4_1= +fan_ratio.fpath_4_1= +fan_ratio.addr_4_1=0x05010015 +fan_ratio.len_4_1=1 +fan_ratio.bit_offset_4_1= + +fan_ratio.mode_5_0=config +fan_ratio.int_cons_5_0= +fan_ratio.src_5_0=cpld +fan_ratio.frmt_5_0=byte +fan_ratio.pola_5_0= +fan_ratio.fpath_5_0= +fan_ratio.addr_5_0=0x05000016 +fan_ratio.len_5_0=1 +fan_ratio.bit_offset_5_0= + +fan_ratio.mode_5_1=config +fan_ratio.int_cons_5_1= +fan_ratio.src_5_1=cpld +fan_ratio.frmt_5_1=byte +fan_ratio.pola_5_1= +fan_ratio.fpath_5_1= +fan_ratio.addr_5_1=0x05000016 +fan_ratio.len_5_1=1 +fan_ratio.bit_offset_5_1= + +fan_ratio.mode_6_0=config +fan_ratio.int_cons_6_0= +fan_ratio.src_6_0=cpld +fan_ratio.frmt_6_0=byte +fan_ratio.pola_6_0= +fan_ratio.fpath_6_0= +fan_ratio.addr_6_0=0x05010016 +fan_ratio.len_6_0=1 +fan_ratio.bit_offset_6_0= + +fan_ratio.mode_6_1=config +fan_ratio.int_cons_6_1= +fan_ratio.src_6_1=cpld +fan_ratio.frmt_6_1=byte +fan_ratio.pola_6_1= +fan_ratio.fpath_6_1= +fan_ratio.addr_6_1=0x05010016 +fan_ratio.len_6_1=1 +fan_ratio.bit_offset_6_1= + + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x05000031 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=0 + +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=cpld +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1= +fan_roll_status.addr_1_1=0x05000034 +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=0 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x05010031 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=0 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=cpld +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1= +fan_roll_status.addr_2_1=0x05010034 +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=0 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x05000031 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=1 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=cpld +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1= +fan_roll_status.addr_3_1=0x05000034 +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=1 + +fan_roll_status.mode_4_0=config +fan_roll_status.int_cons_4_0= +fan_roll_status.src_4_0=cpld +fan_roll_status.frmt_4_0=bit +fan_roll_status.pola_4_0=positive +fan_roll_status.fpath_4_0= +fan_roll_status.addr_4_0=0x05010031 +fan_roll_status.len_4_0=1 +fan_roll_status.bit_offset_4_0=1 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=cpld +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1= +fan_roll_status.addr_4_1=0x05010034 +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=1 + +fan_roll_status.mode_5_0=config +fan_roll_status.int_cons_5_0= +fan_roll_status.src_5_0=cpld +fan_roll_status.frmt_5_0=bit +fan_roll_status.pola_5_0=positive +fan_roll_status.fpath_5_0= +fan_roll_status.addr_5_0=0x05000031 +fan_roll_status.len_5_0=1 +fan_roll_status.bit_offset_5_0=2 + +fan_roll_status.mode_5_1=config +fan_roll_status.int_cons_5_1= +fan_roll_status.src_5_1=cpld +fan_roll_status.frmt_5_1=bit +fan_roll_status.pola_5_1=positive +fan_roll_status.fpath_5_1= +fan_roll_status.addr_5_1=0x05000034 +fan_roll_status.len_5_1=1 +fan_roll_status.bit_offset_5_1=2 + +fan_roll_status.mode_6_0=config +fan_roll_status.int_cons_6_0= +fan_roll_status.src_6_0=cpld +fan_roll_status.frmt_6_0=bit +fan_roll_status.pola_6_0=positive +fan_roll_status.fpath_6_0= +fan_roll_status.addr_6_0=0x05010031 +fan_roll_status.len_6_0=1 +fan_roll_status.bit_offset_6_0=2 + +fan_roll_status.mode_6_1=config +fan_roll_status.int_cons_6_1= +fan_roll_status.src_6_1=cpld +fan_roll_status.frmt_6_1=bit +fan_roll_status.pola_6_1=positive +fan_roll_status.fpath_6_1= +fan_roll_status.addr_6_1=0x05010034 +fan_roll_status.len_6_1=1 +fan_roll_status.bit_offset_6_1=2 + + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x0500001b +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=cpld +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1=negative +fan_speed.fpath_1_1= +fan_speed.addr_1_1=0x05000025 +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0501001b +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=cpld +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1=negative +fan_speed.fpath_2_1= +fan_speed.addr_2_1=0x05010025 +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0500001d +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=cpld +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1=negative +fan_speed.fpath_3_1= +fan_speed.addr_3_1=0x05000027 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_4_0=config +fan_speed.int_cons_4_0= +fan_speed.src_4_0=cpld +fan_speed.frmt_4_0=num_bytes +fan_speed.pola_4_0=negative +fan_speed.fpath_4_0= +fan_speed.addr_4_0=0x0501001d +fan_speed.len_4_0=2 +fan_speed.bit_offset_4_0= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=cpld +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1=negative +fan_speed.fpath_4_1= +fan_speed.addr_4_1=0x05010027 +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + +fan_speed.mode_5_0=config +fan_speed.int_cons_5_0= +fan_speed.src_5_0=cpld +fan_speed.frmt_5_0=num_bytes +fan_speed.pola_5_0=negative +fan_speed.fpath_5_0= +fan_speed.addr_5_0=0x0500001f +fan_speed.len_5_0=2 +fan_speed.bit_offset_5_0= + +fan_speed.mode_5_1=config +fan_speed.int_cons_5_1= +fan_speed.src_5_1=cpld +fan_speed.frmt_5_1=num_bytes +fan_speed.pola_5_1=negative +fan_speed.fpath_5_1= +fan_speed.addr_5_1=0x05000029 +fan_speed.len_5_1=2 +fan_speed.bit_offset_5_1= + +fan_speed.mode_6_0=config +fan_speed.int_cons_6_0= +fan_speed.src_6_0=cpld +fan_speed.frmt_6_0=num_bytes +fan_speed.pola_6_0=negative +fan_speed.fpath_6_0= +fan_speed.addr_6_0=0x0501001f +fan_speed.len_6_0=2 +fan_speed.bit_offset_6_0= + +fan_speed.mode_6_1=config +fan_speed.int_cons_6_1= +fan_speed.src_6_1=cpld +fan_speed.frmt_6_1=num_bytes +fan_speed.pola_6_1=negative +fan_speed.fpath_6_1= +fan_speed.addr_6_1=0x05010029 +fan_speed.len_6_1=2 +fan_speed.bit_offset_6_1= diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..ee060135ad6c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,118 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=4 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00010027 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00010027 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00010027 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00010028 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=0 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00010028 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=1 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00010028 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=2 + +# psu3 presence status +psu_status.mode_3_0=config +psu_status.src_3_0=cpld +psu_status.frmt_3_0=bit +psu_status.pola_3_0=negative +psu_status.addr_3_0=0x00010029 +psu_status.len_3_0=1 +psu_status.bit_offset_3_0=0 + +# psu3 output status +psu_status.mode_3_1=config +psu_status.src_3_1=cpld +psu_status.frmt_3_1=bit +psu_status.pola_3_1=positive +psu_status.addr_3_1=0x00010029 +psu_status.len_3_1=1 +psu_status.bit_offset_3_1=1 + +# psu3 alert status +psu_status.mode_3_2=config +psu_status.src_3_2=cpld +psu_status.frmt_3_2=bit +psu_status.pola_3_2=negative +psu_status.addr_3_2=0x00010029 +psu_status.len_3_2=1 +psu_status.bit_offset_3_2=2 + +# psu4 presence status +psu_status.mode_4_0=config +psu_status.src_4_0=cpld +psu_status.frmt_4_0=bit +psu_status.pola_4_0=negative +psu_status.addr_4_0=0x0001002a +psu_status.len_4_0=1 +psu_status.bit_offset_4_0=0 + +# psu4 output status +psu_status.mode_4_1=config +psu_status.src_4_1=cpld +psu_status.frmt_4_1=bit +psu_status.pola_4_1=positive +psu_status.addr_4_1=0x0001002a +psu_status.len_4_1=1 +psu_status.bit_offset_4_1=1 + +# psu4 alert status +psu_status.mode_4_2=config +psu_status.src_4_2=cpld +psu_status.frmt_4_2=bit +psu_status.pola_4_2=negative +psu_status.addr_4_2=0x0001002a +psu_status.len_4_2=1 +psu_status.bit_offset_4_2=2 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg new file mode 100755 index 000000000000..d16cafec6bc0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SENSOR.cfg @@ -0,0 +1,365 @@ +# Number of temperature sensors on the mainboard +dev_num_0_1=0 + +# Number of voltage sensors on the mainboard +dev_num_0_2=17 + +# Number of current sensors on the mainboard +dev_num_0_3=0 +#sensor in1 +hwmon_in.mode_0x0001_0x00=config +hwmon_in.int_cons_0x0001_0x00=0 +hwmon_in.src_0x0001_0x00=cpld +hwmon_in.frmt_0x0001_0x00=num_bytes +hwmon_in.addr_0x0001_0x00=0x000000a0 +hwmon_in.len_0x0001_0x00=2 +hwmon_in.int_extra1_0x0001_0x00=0x000000a4 +hwmon_in.int_extra2_0x0001_0x00=1240 + +hwmon_in.mode_0x0001_0x01=str_constant +hwmon_in.str_cons_0x0001_0x01=X86_BOARD_P5V_AUX_IN + +hwmon_in.mode_0x0001_0x02=str_constant +hwmon_in.str_cons_0x0001_0x02=cpld + +hwmon_in.mode_0x0001_0x03=str_constant +hwmon_in.str_cons_0x0001_0x03=5250 + +hwmon_in.mode_0x0001_0x05=str_constant +hwmon_in.str_cons_0x0001_0x05=4721 + +hwmon_in.mode_0x0002_0x00=config +hwmon_in.int_cons_0x0002_0x00=0 +hwmon_in.src_0x0002_0x00=cpld +hwmon_in.frmt_0x0002_0x00=num_bytes +hwmon_in.addr_0x0002_0x00=0x000000a2 +hwmon_in.len_0x0002_0x00=2 +hwmon_in.int_extra1_0x0002_0x00=0x000000a4 +hwmon_in.int_extra2_0x0002_0x00=1240 + +hwmon_in.mode_0x0002_0x01=str_constant +hwmon_in.str_cons_0x0002_0x01=X86_BOARD_P1V7_IN + +hwmon_in.mode_0x0002_0x02=str_constant +hwmon_in.str_cons_0x0002_0x02=cpld + +hwmon_in.mode_0x0002_0x03=str_constant +hwmon_in.str_cons_0x0002_0x03=1792 + +hwmon_in.mode_0x0002_0x05=str_constant +hwmon_in.str_cons_0x0002_0x05=1615 + +hwmon_in.mode_0x0003_0x00=config +hwmon_in.int_cons_0x0003_0x00=0 +hwmon_in.src_0x0003_0x00=cpld +hwmon_in.frmt_0x0003_0x00=num_bytes +hwmon_in.addr_0x0003_0x00=0x000000a4 +hwmon_in.len_0x0003_0x00=2 +hwmon_in.int_extra1_0x0003_0x00=0x000000a4 +hwmon_in.int_extra2_0x0003_0x00=2000 + +hwmon_in.mode_0x0003_0x01=str_constant +hwmon_in.str_cons_0x0003_0x01=X86_BOARD_TEST1v24 + +hwmon_in.mode_0x0003_0x02=str_constant +hwmon_in.str_cons_0x0003_0x02=cpld + +hwmon_in.mode_0x0003_0x03=str_constant +hwmon_in.str_cons_0x0003_0x03=1302 + +hwmon_in.mode_0x0003_0x05=str_constant +hwmon_in.str_cons_0x0003_0x05=1178 + +hwmon_in.mode_0x0004_0x00=config +hwmon_in.int_cons_0x0004_0x00=0 +hwmon_in.src_0x0004_0x00=cpld +hwmon_in.frmt_0x0004_0x00=num_bytes +hwmon_in.addr_0x0004_0x00=0x000000a6 +hwmon_in.len_0x0004_0x00=2 +hwmon_in.int_extra1_0x0004_0x00=0x000000a4 +hwmon_in.int_extra2_0x0004_0x00=1240 + +hwmon_in.mode_0x0004_0x01=str_constant +hwmon_in.str_cons_0x0004_0x01=X86_BOARD_P3V3_STBY_IN + +hwmon_in.mode_0x0004_0x02=str_constant +hwmon_in.str_cons_0x0004_0x02=cpld + +hwmon_in.mode_0x0004_0x03=str_constant +hwmon_in.str_cons_0x0004_0x03=3500 + +hwmon_in.mode_0x0004_0x05=str_constant +hwmon_in.str_cons_0x0004_0x05=3135 + +hwmon_in.mode_0x0005_0x00=config +hwmon_in.int_cons_0x0005_0x00=0 +hwmon_in.src_0x0005_0x00=cpld +hwmon_in.frmt_0x0005_0x00=num_bytes +hwmon_in.addr_0x0005_0x00=0x00020018 +hwmon_in.len_0x0005_0x00=2 +hwmon_in.int_extra1_0x0005_0x00=0x0002001c +hwmon_in.int_extra2_0x0005_0x00=1240 + +hwmon_in.mode_0x0005_0x01=str_constant +hwmon_in.str_cons_0x0005_0x01=MAC_BOARD_VDD1v8 + +hwmon_in.mode_0x0005_0x02=str_constant +hwmon_in.str_cons_0x0005_0x02=cpld + +hwmon_in.mode_0x0005_0x03=str_constant +hwmon_in.str_cons_0x0005_0x03=1909 + +hwmon_in.mode_0x0005_0x05=str_constant +hwmon_in.str_cons_0x0005_0x05=1710 + +hwmon_in.mode_0x0006_0x00=config +hwmon_in.int_cons_0x0006_0x00=0 +hwmon_in.src_0x0006_0x00=cpld +hwmon_in.frmt_0x0006_0x00=num_bytes +hwmon_in.addr_0x0006_0x00=0x0002001a +hwmon_in.len_0x0006_0x00=2 +hwmon_in.int_extra1_0x0006_0x00=0x0002001c +hwmon_in.int_extra2_0x0006_0x00=1240 + +hwmon_in.mode_0x0006_0x01=str_constant +hwmon_in.str_cons_0x0006_0x01=MAC_BOARD_SW_VDD1v2 + +hwmon_in.mode_0x0006_0x02=str_constant +hwmon_in.str_cons_0x0006_0x02=cpld + +hwmon_in.mode_0x0006_0x03=str_constant +hwmon_in.str_cons_0x0006_0x03=1286 + +hwmon_in.mode_0x0006_0x05=str_constant +hwmon_in.str_cons_0x0006_0x05=1140 + +hwmon_in.mode_0x0007_0x00=config +hwmon_in.int_cons_0x0007_0x00=0 +hwmon_in.src_0x0007_0x00=cpld +hwmon_in.frmt_0x0007_0x00=num_bytes +hwmon_in.addr_0x0007_0x00=0x0002001c +hwmon_in.len_0x0007_0x00=2 +hwmon_in.int_extra1_0x0007_0x00=0x0002001c +hwmon_in.int_extra2_0x0007_0x00=1000 + +hwmon_in.mode_0x0007_0x01=str_constant +hwmon_in.str_cons_0x0007_0x01=MAC_BOARD_TEST1v24 + +hwmon_in.mode_0x0007_0x02=str_constant +hwmon_in.str_cons_0x0007_0x02=cpld + +hwmon_in.mode_0x0007_0x03=str_constant +hwmon_in.str_cons_0x0007_0x03=1302 + +hwmon_in.mode_0x0007_0x05=str_constant +hwmon_in.str_cons_0x0007_0x05=1178 + +hwmon_in.mode_0x0008_0x00=config +hwmon_in.int_cons_0x0008_0x00=0 +hwmon_in.src_0x0008_0x00=cpld +hwmon_in.frmt_0x0008_0x00=num_bytes +hwmon_in.addr_0x0008_0x00=0x0002001e +hwmon_in.len_0x0008_0x00=2 +hwmon_in.int_extra1_0x0008_0x00=0x0002001c +hwmon_in.int_extra2_0x0008_0x00=1240 + +hwmon_in.mode_0x0008_0x01=str_constant +hwmon_in.str_cons_0x0008_0x01=MAC_BOARD_VDD1v2_MAC + +hwmon_in.mode_0x0008_0x02=str_constant +hwmon_in.str_cons_0x0008_0x02=cpld + +hwmon_in.mode_0x0008_0x03=str_constant +hwmon_in.str_cons_0x0008_0x03=1260 + +hwmon_in.mode_0x0008_0x05=str_constant +hwmon_in.str_cons_0x0008_0x05=1140 + +hwmon_in.mode_0x0009_0x00=config +hwmon_in.int_cons_0x0009_0x00=0 +hwmon_in.src_0x0009_0x00=cpld +hwmon_in.frmt_0x0009_0x00=num_bytes +hwmon_in.addr_0x0009_0x00=0x00020020 +hwmon_in.len_0x0009_0x00=2 +hwmon_in.int_extra1_0x0009_0x00=0x0002001c +hwmon_in.int_extra2_0x0009_0x00=1240 + +hwmon_in.mode_0x0009_0x01=str_constant +hwmon_in.str_cons_0x0009_0x01=MAC_BOARD_VDD_CORE + +hwmon_in.mode_0x0009_0x02=str_constant +hwmon_in.str_cons_0x0009_0x02=cpld + +hwmon_in.mode_0x0009_0x03=str_constant +hwmon_in.str_cons_0x0009_0x03=945 + +hwmon_in.mode_0x0009_0x05=str_constant +hwmon_in.str_cons_0x0009_0x05=712 + +hwmon_in.mode_0x000a_0x00=config +hwmon_in.int_cons_0x000a_0x00=0 +hwmon_in.src_0x000a_0x00=cpld +hwmon_in.frmt_0x000a_0x00=num_bytes +hwmon_in.addr_0x000a_0x00=0x00020022 +hwmon_in.len_0x000a_0x00=2 +hwmon_in.int_extra1_0x000a_0x00=0x0002001c +hwmon_in.int_extra2_0x000a_0x00=2480 + +hwmon_in.mode_0x000a_0x01=str_constant +hwmon_in.str_cons_0x000a_0x01=MAC_BOARD_VDD3v3_MCU + +hwmon_in.mode_0x000a_0x02=str_constant +hwmon_in.str_cons_0x000a_0x02=cpld + +hwmon_in.mode_0x000a_0x03=str_constant +hwmon_in.str_cons_0x000a_0x03=3556 + +hwmon_in.mode_0x000a_0x05=str_constant +hwmon_in.str_cons_0x000a_0x05=3135 + +hwmon_in.mode_0x000b_0x00=config +hwmon_in.int_cons_0x000b_0x00=0 +hwmon_in.src_0x000b_0x00=cpld +hwmon_in.frmt_0x000b_0x00=num_bytes +hwmon_in.addr_0x000b_0x00=0x00020024 +hwmon_in.len_0x000b_0x00=2 +hwmon_in.int_extra1_0x000b_0x00=0x0002001c +hwmon_in.int_extra2_0x000b_0x00=2480 + +hwmon_in.mode_0x000b_0x01=str_constant +hwmon_in.str_cons_0x000b_0x01=MAC_BOARD_VDD3v3_CLK + +hwmon_in.mode_0x000b_0x02=str_constant +hwmon_in.str_cons_0x000b_0x02=cpld + +hwmon_in.mode_0x000b_0x03=str_constant +hwmon_in.str_cons_0x000b_0x03=3556 + +hwmon_in.mode_0x000b_0x05=str_constant +hwmon_in.str_cons_0x000b_0x05=3135 + +hwmon_in.mode_0x000c_0x00=config +hwmon_in.int_cons_0x000c_0x00=0 +hwmon_in.src_0x000c_0x00=cpld +hwmon_in.frmt_0x000c_0x00=num_bytes +hwmon_in.addr_0x000c_0x00=0x00020026 +hwmon_in.len_0x000c_0x00=2 +hwmon_in.int_extra1_0x000c_0x00=0x0002001c +hwmon_in.int_extra2_0x000c_0x00=2480 + +hwmon_in.mode_0x000c_0x01=str_constant +hwmon_in.str_cons_0x000c_0x01=MAC_BOARD_VDD5V_CLK_MCU + +hwmon_in.mode_0x000c_0x02=str_constant +hwmon_in.str_cons_0x000c_0x02=cpld + +hwmon_in.mode_0x000c_0x03=str_constant +hwmon_in.str_cons_0x000c_0x03=5331 + +hwmon_in.mode_0x000c_0x05=str_constant +hwmon_in.str_cons_0x000c_0x05=4750 + +hwmon_in.mode_0x000d_0x00=config +hwmon_in.int_cons_0x000d_0x00=0 +hwmon_in.src_0x000d_0x00=cpld +hwmon_in.frmt_0x000d_0x00=num_bytes +hwmon_in.addr_0x000d_0x00=0x00020028 +hwmon_in.len_0x000d_0x00=2 +hwmon_in.int_extra1_0x000d_0x00=0x0002001c +hwmon_in.int_extra2_0x000d_0x00=2480 + +hwmon_in.mode_0x000d_0x01=str_constant +hwmon_in.str_cons_0x000d_0x01=MAC_BOARD_VDD2v5 + +hwmon_in.mode_0x000d_0x02=str_constant +hwmon_in.str_cons_0x000d_0x02=cpld + +hwmon_in.mode_0x000d_0x03=str_constant +hwmon_in.str_cons_0x000d_0x03=2688 + +hwmon_in.mode_0x000d_0x05=str_constant +hwmon_in.str_cons_0x000d_0x05=2375 + +hwmon_in.mode_0x000e_0x00=config +hwmon_in.int_cons_0x000e_0x00=0 +hwmon_in.src_0x000e_0x00=cpld +hwmon_in.frmt_0x000e_0x00=num_bytes +hwmon_in.addr_0x000e_0x00=0x0002002a +hwmon_in.len_0x000e_0x00=2 +hwmon_in.int_extra1_0x000e_0x00=0x0002001c +hwmon_in.int_extra2_0x000e_0x00=2480 + +hwmon_in.mode_0x000e_0x01=str_constant +hwmon_in.str_cons_0x000e_0x01=MAC_BOARD_VDDO + +hwmon_in.mode_0x000e_0x02=str_constant +hwmon_in.str_cons_0x000e_0x02=cpld + +hwmon_in.mode_0x000e_0x03=str_constant +hwmon_in.str_cons_0x000e_0x03=3542 + +hwmon_in.mode_0x000e_0x05=str_constant +hwmon_in.str_cons_0x000e_0x05=3135 + +hwmon_in.mode_0x000f_0x00=config +hwmon_in.int_cons_0x000f_0x00=0 +hwmon_in.src_0x000f_0x00=cpld +hwmon_in.frmt_0x000f_0x00=num_bytes +hwmon_in.addr_0x000f_0x00=0x0002002c +hwmon_in.len_0x000f_0x00=2 +hwmon_in.int_extra1_0x000f_0x00=0x0002001c +hwmon_in.int_extra2_0x000f_0x00=1240 + +hwmon_in.mode_0x000f_0x01=str_constant +hwmon_in.str_cons_0x000f_0x01=MAC_BOARD_BC_PVDD + +hwmon_in.mode_0x000f_0x02=str_constant +hwmon_in.str_cons_0x000f_0x02=cpld + +hwmon_in.mode_0x000f_0x03=str_constant +hwmon_in.str_cons_0x000f_0x03=867 + +hwmon_in.mode_0x000f_0x05=str_constant +hwmon_in.str_cons_0x000f_0x05=760 + +hwmon_in.mode_0x0010_0x00=config +hwmon_in.int_cons_0x0010_0x00=0 +hwmon_in.src_0x0010_0x00=cpld +hwmon_in.frmt_0x0010_0x00=num_bytes +hwmon_in.addr_0x0010_0x00=0x0002002e +hwmon_in.len_0x0010_0x00=2 +hwmon_in.int_extra1_0x0010_0x00=0x0002001c +hwmon_in.int_extra2_0x0010_0x00=2480 + +hwmon_in.mode_0x0010_0x01=str_constant +hwmon_in.str_cons_0x0010_0x01=MAC_BOARD_VDD3v3 + +hwmon_in.mode_0x0010_0x02=str_constant +hwmon_in.str_cons_0x0010_0x02=cpld + +hwmon_in.mode_0x0010_0x03=str_constant +hwmon_in.str_cons_0x0010_0x03=3542 + +hwmon_in.mode_0x0010_0x05=str_constant +hwmon_in.str_cons_0x0010_0x05=3135 + +hwmon_in.mode_0x0011_0x00=config +hwmon_in.int_cons_0x0011_0x00=0 +hwmon_in.src_0x0011_0x00=cpld +hwmon_in.frmt_0x0011_0x00=num_bytes +hwmon_in.addr_0x0011_0x00=0x00020030 +hwmon_in.len_0x0011_0x00=2 +hwmon_in.int_extra1_0x0011_0x00=0x0002001c +hwmon_in.int_extra2_0x0011_0x00=1240 + +hwmon_in.mode_0x0011_0x01=str_constant +hwmon_in.str_cons_0x0011_0x01=MAC_BOARD_ANLGOUT + +hwmon_in.mode_0x0011_0x02=str_constant +hwmon_in.str_cons_0x0011_0x02=cpld + +hwmon_in.mode_0x0011_0x03=str_constant +hwmon_in.str_cons_0x0011_0x03=856 + +hwmon_in.mode_0x0011_0x05=str_constant +hwmon_in.str_cons_0x0011_0x05=760 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..7fa47c217e89 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,1169 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=128 + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 +sff_dir_name_33 =sff33 +sff_dir_name_34 =sff34 +sff_dir_name_35 =sff35 +sff_dir_name_36 =sff36 +sff_dir_name_37 =sff37 +sff_dir_name_38 =sff38 +sff_dir_name_39 =sff39 +sff_dir_name_40 =sff40 +sff_dir_name_41 =sff41 +sff_dir_name_42 =sff42 +sff_dir_name_43 =sff43 +sff_dir_name_44 =sff44 +sff_dir_name_45 =sff45 +sff_dir_name_46 =sff46 +sff_dir_name_47 =sff47 +sff_dir_name_48 =sff48 +sff_dir_name_49 =sff49 +sff_dir_name_50 =sff50 +sff_dir_name_51 =sff51 +sff_dir_name_52 =sff52 +sff_dir_name_53 =sff53 +sff_dir_name_54 =sff54 +sff_dir_name_55 =sff55 +sff_dir_name_56 =sff56 +sff_dir_name_57 =sff57 +sff_dir_name_58 =sff58 +sff_dir_name_59 =sff59 +sff_dir_name_60 =sff60 +sff_dir_name_61 =sff61 +sff_dir_name_62 =sff62 +sff_dir_name_63 =sff63 +sff_dir_name_64 =sff64 +sff_dir_name_65 =sff65 +sff_dir_name_66 =sff66 +sff_dir_name_67 =sff67 +sff_dir_name_68 =sff68 +sff_dir_name_69 =sff69 +sff_dir_name_70 =sff70 +sff_dir_name_71 =sff71 +sff_dir_name_72 =sff72 +sff_dir_name_73 =sff73 +sff_dir_name_74 =sff74 +sff_dir_name_75 =sff75 +sff_dir_name_76 =sff76 +sff_dir_name_77 =sff77 +sff_dir_name_78 =sff78 +sff_dir_name_79 =sff79 +sff_dir_name_80 =sff80 +sff_dir_name_81 =sff81 +sff_dir_name_82 =sff82 +sff_dir_name_83 =sff83 +sff_dir_name_84 =sff84 +sff_dir_name_85 =sff85 +sff_dir_name_86 =sff86 +sff_dir_name_87 =sff87 +sff_dir_name_88 =sff88 +sff_dir_name_89 =sff89 +sff_dir_name_90 =sff90 +sff_dir_name_91 =sff91 +sff_dir_name_92 =sff92 +sff_dir_name_93 =sff93 +sff_dir_name_94 =sff94 +sff_dir_name_95 =sff95 +sff_dir_name_96 =sff96 +sff_dir_name_97 =sff97 +sff_dir_name_98 =sff98 +sff_dir_name_99 =sff99 +sff_dir_name_100 =sff100 +sff_dir_name_101 =sff101 +sff_dir_name_102 =sff102 +sff_dir_name_103 =sff103 +sff_dir_name_104 =sff104 +sff_dir_name_105 =sff105 +sff_dir_name_106 =sff106 +sff_dir_name_107 =sff107 +sff_dir_name_108 =sff108 +sff_dir_name_109 =sff109 +sff_dir_name_110 =sff110 +sff_dir_name_111 =sff111 +sff_dir_name_112 =sff112 +sff_dir_name_113 =sff113 +sff_dir_name_114 =sff114 +sff_dir_name_115 =sff115 +sff_dir_name_116 =sff116 +sff_dir_name_117 =sff117 +sff_dir_name_118 =sff118 +sff_dir_name_119 =sff119 +sff_dir_name_120 =sff120 +sff_dir_name_121 =sff121 +sff_dir_name_122 =sff122 +sff_dir_name_123 =sff123 +sff_dir_name_124 =sff124 +sff_dir_name_125 =sff125 +sff_dir_name_126 =sff126 +sff_dir_name_127 =sff127 +sff_dir_name_128 =sff128 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x01010010 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x01010010 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x01010010 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x01010010 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x01010010 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x01010010 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x01010010 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x01010010 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x01010011 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x01010011 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x01010011 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x01010011 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x01010011 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x01010011 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x01010011 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x01010011 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x01000010 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x01000010 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x01000010 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x01000010 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x01000010 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x01000010 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x01000010 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x01000010 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x01000011 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x01000011 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x01000011 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x01000011 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x01000011 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x01000011 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x01000011 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x01000011 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +sff_cpld_reg.mode_33_8=config +sff_cpld_reg.src_33_8=cpld +sff_cpld_reg.frmt_33_8=bit +sff_cpld_reg.pola_33_8=negative +sff_cpld_reg.addr_33_8=0x02010010 +sff_cpld_reg.len_33_8=1 +sff_cpld_reg.bit_offset_33_8=0 + +sff_cpld_reg.mode_34_8=config +sff_cpld_reg.src_34_8=cpld +sff_cpld_reg.frmt_34_8=bit +sff_cpld_reg.pola_34_8=negative +sff_cpld_reg.addr_34_8=0x02010010 +sff_cpld_reg.len_34_8=1 +sff_cpld_reg.bit_offset_34_8=1 + +sff_cpld_reg.mode_35_8=config +sff_cpld_reg.src_35_8=cpld +sff_cpld_reg.frmt_35_8=bit +sff_cpld_reg.pola_35_8=negative +sff_cpld_reg.addr_35_8=0x02010010 +sff_cpld_reg.len_35_8=1 +sff_cpld_reg.bit_offset_35_8=2 + +sff_cpld_reg.mode_36_8=config +sff_cpld_reg.src_36_8=cpld +sff_cpld_reg.frmt_36_8=bit +sff_cpld_reg.pola_36_8=negative +sff_cpld_reg.addr_36_8=0x02010010 +sff_cpld_reg.len_36_8=1 +sff_cpld_reg.bit_offset_36_8=3 + +sff_cpld_reg.mode_37_8=config +sff_cpld_reg.src_37_8=cpld +sff_cpld_reg.frmt_37_8=bit +sff_cpld_reg.pola_37_8=negative +sff_cpld_reg.addr_37_8=0x02010010 +sff_cpld_reg.len_37_8=1 +sff_cpld_reg.bit_offset_37_8=4 + +sff_cpld_reg.mode_38_8=config +sff_cpld_reg.src_38_8=cpld +sff_cpld_reg.frmt_38_8=bit +sff_cpld_reg.pola_38_8=negative +sff_cpld_reg.addr_38_8=0x02010010 +sff_cpld_reg.len_38_8=1 +sff_cpld_reg.bit_offset_38_8=5 + +sff_cpld_reg.mode_39_8=config +sff_cpld_reg.src_39_8=cpld +sff_cpld_reg.frmt_39_8=bit +sff_cpld_reg.pola_39_8=negative +sff_cpld_reg.addr_39_8=0x02010010 +sff_cpld_reg.len_39_8=1 +sff_cpld_reg.bit_offset_39_8=6 + +sff_cpld_reg.mode_40_8=config +sff_cpld_reg.src_40_8=cpld +sff_cpld_reg.frmt_40_8=bit +sff_cpld_reg.pola_40_8=negative +sff_cpld_reg.addr_40_8=0x02010010 +sff_cpld_reg.len_40_8=1 +sff_cpld_reg.bit_offset_40_8=7 + +sff_cpld_reg.mode_41_8=config +sff_cpld_reg.src_41_8=cpld +sff_cpld_reg.frmt_41_8=bit +sff_cpld_reg.pola_41_8=negative +sff_cpld_reg.addr_41_8=0x02010011 +sff_cpld_reg.len_41_8=1 +sff_cpld_reg.bit_offset_41_8=0 + +sff_cpld_reg.mode_42_8=config +sff_cpld_reg.src_42_8=cpld +sff_cpld_reg.frmt_42_8=bit +sff_cpld_reg.pola_42_8=negative +sff_cpld_reg.addr_42_8=0x02010011 +sff_cpld_reg.len_42_8=1 +sff_cpld_reg.bit_offset_42_8=1 + +sff_cpld_reg.mode_43_8=config +sff_cpld_reg.src_43_8=cpld +sff_cpld_reg.frmt_43_8=bit +sff_cpld_reg.pola_43_8=negative +sff_cpld_reg.addr_43_8=0x02010011 +sff_cpld_reg.len_43_8=1 +sff_cpld_reg.bit_offset_43_8=2 + +sff_cpld_reg.mode_44_8=config +sff_cpld_reg.src_44_8=cpld +sff_cpld_reg.frmt_44_8=bit +sff_cpld_reg.pola_44_8=negative +sff_cpld_reg.addr_44_8=0x02010011 +sff_cpld_reg.len_44_8=1 +sff_cpld_reg.bit_offset_44_8=3 + +sff_cpld_reg.mode_45_8=config +sff_cpld_reg.src_45_8=cpld +sff_cpld_reg.frmt_45_8=bit +sff_cpld_reg.pola_45_8=negative +sff_cpld_reg.addr_45_8=0x02010011 +sff_cpld_reg.len_45_8=1 +sff_cpld_reg.bit_offset_45_8=4 + +sff_cpld_reg.mode_46_8=config +sff_cpld_reg.src_46_8=cpld +sff_cpld_reg.frmt_46_8=bit +sff_cpld_reg.pola_46_8=negative +sff_cpld_reg.addr_46_8=0x02010011 +sff_cpld_reg.len_46_8=1 +sff_cpld_reg.bit_offset_46_8=5 + +sff_cpld_reg.mode_47_8=config +sff_cpld_reg.src_47_8=cpld +sff_cpld_reg.frmt_47_8=bit +sff_cpld_reg.pola_47_8=negative +sff_cpld_reg.addr_47_8=0x02010011 +sff_cpld_reg.len_47_8=1 +sff_cpld_reg.bit_offset_47_8=6 + +sff_cpld_reg.mode_48_8=config +sff_cpld_reg.src_48_8=cpld +sff_cpld_reg.frmt_48_8=bit +sff_cpld_reg.pola_48_8=negative +sff_cpld_reg.addr_48_8=0x02010011 +sff_cpld_reg.len_48_8=1 +sff_cpld_reg.bit_offset_48_8=7 + +sff_cpld_reg.mode_49_8=config +sff_cpld_reg.src_49_8=cpld +sff_cpld_reg.frmt_49_8=bit +sff_cpld_reg.pola_49_8=negative +sff_cpld_reg.addr_49_8=0x02000010 +sff_cpld_reg.len_49_8=1 +sff_cpld_reg.bit_offset_49_8=0 + +sff_cpld_reg.mode_50_8=config +sff_cpld_reg.src_50_8=cpld +sff_cpld_reg.frmt_50_8=bit +sff_cpld_reg.pola_50_8=negative +sff_cpld_reg.addr_50_8=0x02000010 +sff_cpld_reg.len_50_8=1 +sff_cpld_reg.bit_offset_50_8=1 + +sff_cpld_reg.mode_51_8=config +sff_cpld_reg.src_51_8=cpld +sff_cpld_reg.frmt_51_8=bit +sff_cpld_reg.pola_51_8=negative +sff_cpld_reg.addr_51_8=0x02000010 +sff_cpld_reg.len_51_8=1 +sff_cpld_reg.bit_offset_51_8=2 + +sff_cpld_reg.mode_52_8=config +sff_cpld_reg.src_52_8=cpld +sff_cpld_reg.frmt_52_8=bit +sff_cpld_reg.pola_52_8=negative +sff_cpld_reg.addr_52_8=0x02000010 +sff_cpld_reg.len_52_8=1 +sff_cpld_reg.bit_offset_52_8=3 + +sff_cpld_reg.mode_53_8=config +sff_cpld_reg.src_53_8=cpld +sff_cpld_reg.frmt_53_8=bit +sff_cpld_reg.pola_53_8=negative +sff_cpld_reg.addr_53_8=0x02000010 +sff_cpld_reg.len_53_8=1 +sff_cpld_reg.bit_offset_53_8=4 + +sff_cpld_reg.mode_54_8=config +sff_cpld_reg.src_54_8=cpld +sff_cpld_reg.frmt_54_8=bit +sff_cpld_reg.pola_54_8=negative +sff_cpld_reg.addr_54_8=0x02000010 +sff_cpld_reg.len_54_8=1 +sff_cpld_reg.bit_offset_54_8=5 + +sff_cpld_reg.mode_55_8=config +sff_cpld_reg.src_55_8=cpld +sff_cpld_reg.frmt_55_8=bit +sff_cpld_reg.pola_55_8=negative +sff_cpld_reg.addr_55_8=0x02000010 +sff_cpld_reg.len_55_8=1 +sff_cpld_reg.bit_offset_55_8=6 + +sff_cpld_reg.mode_56_8=config +sff_cpld_reg.src_56_8=cpld +sff_cpld_reg.frmt_56_8=bit +sff_cpld_reg.pola_56_8=negative +sff_cpld_reg.addr_56_8=0x02000010 +sff_cpld_reg.len_56_8=1 +sff_cpld_reg.bit_offset_56_8=7 + +sff_cpld_reg.mode_57_8=config +sff_cpld_reg.src_57_8=cpld +sff_cpld_reg.frmt_57_8=bit +sff_cpld_reg.pola_57_8=negative +sff_cpld_reg.addr_57_8=0x02000011 +sff_cpld_reg.len_57_8=1 +sff_cpld_reg.bit_offset_57_8=0 + +sff_cpld_reg.mode_58_8=config +sff_cpld_reg.src_58_8=cpld +sff_cpld_reg.frmt_58_8=bit +sff_cpld_reg.pola_58_8=negative +sff_cpld_reg.addr_58_8=0x02000011 +sff_cpld_reg.len_58_8=1 +sff_cpld_reg.bit_offset_58_8=1 + +sff_cpld_reg.mode_59_8=config +sff_cpld_reg.src_59_8=cpld +sff_cpld_reg.frmt_59_8=bit +sff_cpld_reg.pola_59_8=negative +sff_cpld_reg.addr_59_8=0x02000011 +sff_cpld_reg.len_59_8=1 +sff_cpld_reg.bit_offset_59_8=2 + +sff_cpld_reg.mode_60_8=config +sff_cpld_reg.src_60_8=cpld +sff_cpld_reg.frmt_60_8=bit +sff_cpld_reg.pola_60_8=negative +sff_cpld_reg.addr_60_8=0x02000011 +sff_cpld_reg.len_60_8=1 +sff_cpld_reg.bit_offset_60_8=3 + +sff_cpld_reg.mode_61_8=config +sff_cpld_reg.src_61_8=cpld +sff_cpld_reg.frmt_61_8=bit +sff_cpld_reg.pola_61_8=negative +sff_cpld_reg.addr_61_8=0x02000011 +sff_cpld_reg.len_61_8=1 +sff_cpld_reg.bit_offset_61_8=4 + +sff_cpld_reg.mode_62_8=config +sff_cpld_reg.src_62_8=cpld +sff_cpld_reg.frmt_62_8=bit +sff_cpld_reg.pola_62_8=negative +sff_cpld_reg.addr_62_8=0x02000011 +sff_cpld_reg.len_62_8=1 +sff_cpld_reg.bit_offset_62_8=5 + +sff_cpld_reg.mode_63_8=config +sff_cpld_reg.src_63_8=cpld +sff_cpld_reg.frmt_63_8=bit +sff_cpld_reg.pola_63_8=negative +sff_cpld_reg.addr_63_8=0x02000011 +sff_cpld_reg.len_63_8=1 +sff_cpld_reg.bit_offset_63_8=6 + +sff_cpld_reg.mode_64_8=config +sff_cpld_reg.src_64_8=cpld +sff_cpld_reg.frmt_64_8=bit +sff_cpld_reg.pola_64_8=negative +sff_cpld_reg.addr_64_8=0x02000011 +sff_cpld_reg.len_64_8=1 +sff_cpld_reg.bit_offset_64_8=7 + +sff_cpld_reg.mode_65_8=config +sff_cpld_reg.src_65_8=cpld +sff_cpld_reg.frmt_65_8=bit +sff_cpld_reg.pola_65_8=negative +sff_cpld_reg.addr_65_8=0x03010010 +sff_cpld_reg.len_65_8=1 +sff_cpld_reg.bit_offset_65_8=0 + +sff_cpld_reg.mode_66_8=config +sff_cpld_reg.src_66_8=cpld +sff_cpld_reg.frmt_66_8=bit +sff_cpld_reg.pola_66_8=negative +sff_cpld_reg.addr_66_8=0x03010010 +sff_cpld_reg.len_66_8=1 +sff_cpld_reg.bit_offset_66_8=1 + +sff_cpld_reg.mode_67_8=config +sff_cpld_reg.src_67_8=cpld +sff_cpld_reg.frmt_67_8=bit +sff_cpld_reg.pola_67_8=negative +sff_cpld_reg.addr_67_8=0x03010010 +sff_cpld_reg.len_67_8=1 +sff_cpld_reg.bit_offset_67_8=2 + +sff_cpld_reg.mode_68_8=config +sff_cpld_reg.src_68_8=cpld +sff_cpld_reg.frmt_68_8=bit +sff_cpld_reg.pola_68_8=negative +sff_cpld_reg.addr_68_8=0x03010010 +sff_cpld_reg.len_68_8=1 +sff_cpld_reg.bit_offset_68_8=3 + +sff_cpld_reg.mode_69_8=config +sff_cpld_reg.src_69_8=cpld +sff_cpld_reg.frmt_69_8=bit +sff_cpld_reg.pola_69_8=negative +sff_cpld_reg.addr_69_8=0x03010010 +sff_cpld_reg.len_69_8=1 +sff_cpld_reg.bit_offset_69_8=4 + +sff_cpld_reg.mode_70_8=config +sff_cpld_reg.src_70_8=cpld +sff_cpld_reg.frmt_70_8=bit +sff_cpld_reg.pola_70_8=negative +sff_cpld_reg.addr_70_8=0x03010010 +sff_cpld_reg.len_70_8=1 +sff_cpld_reg.bit_offset_70_8=5 + +sff_cpld_reg.mode_71_8=config +sff_cpld_reg.src_71_8=cpld +sff_cpld_reg.frmt_71_8=bit +sff_cpld_reg.pola_71_8=negative +sff_cpld_reg.addr_71_8=0x03010010 +sff_cpld_reg.len_71_8=1 +sff_cpld_reg.bit_offset_71_8=6 + +sff_cpld_reg.mode_72_8=config +sff_cpld_reg.src_72_8=cpld +sff_cpld_reg.frmt_72_8=bit +sff_cpld_reg.pola_72_8=negative +sff_cpld_reg.addr_72_8=0x03010010 +sff_cpld_reg.len_72_8=1 +sff_cpld_reg.bit_offset_72_8=7 + +sff_cpld_reg.mode_73_8=config +sff_cpld_reg.src_73_8=cpld +sff_cpld_reg.frmt_73_8=bit +sff_cpld_reg.pola_73_8=negative +sff_cpld_reg.addr_73_8=0x03010011 +sff_cpld_reg.len_73_8=1 +sff_cpld_reg.bit_offset_73_8=0 + +sff_cpld_reg.mode_74_8=config +sff_cpld_reg.src_74_8=cpld +sff_cpld_reg.frmt_74_8=bit +sff_cpld_reg.pola_74_8=negative +sff_cpld_reg.addr_74_8=0x03010011 +sff_cpld_reg.len_74_8=1 +sff_cpld_reg.bit_offset_74_8=1 + +sff_cpld_reg.mode_75_8=config +sff_cpld_reg.src_75_8=cpld +sff_cpld_reg.frmt_75_8=bit +sff_cpld_reg.pola_75_8=negative +sff_cpld_reg.addr_75_8=0x03010011 +sff_cpld_reg.len_75_8=1 +sff_cpld_reg.bit_offset_75_8=2 + +sff_cpld_reg.mode_76_8=config +sff_cpld_reg.src_76_8=cpld +sff_cpld_reg.frmt_76_8=bit +sff_cpld_reg.pola_76_8=negative +sff_cpld_reg.addr_76_8=0x03010011 +sff_cpld_reg.len_76_8=1 +sff_cpld_reg.bit_offset_76_8=3 + +sff_cpld_reg.mode_77_8=config +sff_cpld_reg.src_77_8=cpld +sff_cpld_reg.frmt_77_8=bit +sff_cpld_reg.pola_77_8=negative +sff_cpld_reg.addr_77_8=0x03010011 +sff_cpld_reg.len_77_8=1 +sff_cpld_reg.bit_offset_77_8=4 + +sff_cpld_reg.mode_78_8=config +sff_cpld_reg.src_78_8=cpld +sff_cpld_reg.frmt_78_8=bit +sff_cpld_reg.pola_78_8=negative +sff_cpld_reg.addr_78_8=0x03010011 +sff_cpld_reg.len_78_8=1 +sff_cpld_reg.bit_offset_78_8=5 + +sff_cpld_reg.mode_79_8=config +sff_cpld_reg.src_79_8=cpld +sff_cpld_reg.frmt_79_8=bit +sff_cpld_reg.pola_79_8=negative +sff_cpld_reg.addr_79_8=0x03010011 +sff_cpld_reg.len_79_8=1 +sff_cpld_reg.bit_offset_79_8=6 + +sff_cpld_reg.mode_80_8=config +sff_cpld_reg.src_80_8=cpld +sff_cpld_reg.frmt_80_8=bit +sff_cpld_reg.pola_80_8=negative +sff_cpld_reg.addr_80_8=0x03010011 +sff_cpld_reg.len_80_8=1 +sff_cpld_reg.bit_offset_80_8=7 + +sff_cpld_reg.mode_81_8=config +sff_cpld_reg.src_81_8=cpld +sff_cpld_reg.frmt_81_8=bit +sff_cpld_reg.pola_81_8=negative +sff_cpld_reg.addr_81_8=0x03000010 +sff_cpld_reg.len_81_8=1 +sff_cpld_reg.bit_offset_81_8=0 + +sff_cpld_reg.mode_82_8=config +sff_cpld_reg.src_82_8=cpld +sff_cpld_reg.frmt_82_8=bit +sff_cpld_reg.pola_82_8=negative +sff_cpld_reg.addr_82_8=0x03000010 +sff_cpld_reg.len_82_8=1 +sff_cpld_reg.bit_offset_82_8=1 + +sff_cpld_reg.mode_83_8=config +sff_cpld_reg.src_83_8=cpld +sff_cpld_reg.frmt_83_8=bit +sff_cpld_reg.pola_83_8=negative +sff_cpld_reg.addr_83_8=0x03000010 +sff_cpld_reg.len_83_8=1 +sff_cpld_reg.bit_offset_83_8=2 + +sff_cpld_reg.mode_84_8=config +sff_cpld_reg.src_84_8=cpld +sff_cpld_reg.frmt_84_8=bit +sff_cpld_reg.pola_84_8=negative +sff_cpld_reg.addr_84_8=0x03000010 +sff_cpld_reg.len_84_8=1 +sff_cpld_reg.bit_offset_84_8=3 + +sff_cpld_reg.mode_85_8=config +sff_cpld_reg.src_85_8=cpld +sff_cpld_reg.frmt_85_8=bit +sff_cpld_reg.pola_85_8=negative +sff_cpld_reg.addr_85_8=0x03000010 +sff_cpld_reg.len_85_8=1 +sff_cpld_reg.bit_offset_85_8=4 + +sff_cpld_reg.mode_86_8=config +sff_cpld_reg.src_86_8=cpld +sff_cpld_reg.frmt_86_8=bit +sff_cpld_reg.pola_86_8=negative +sff_cpld_reg.addr_86_8=0x03000010 +sff_cpld_reg.len_86_8=1 +sff_cpld_reg.bit_offset_86_8=5 + +sff_cpld_reg.mode_87_8=config +sff_cpld_reg.src_87_8=cpld +sff_cpld_reg.frmt_87_8=bit +sff_cpld_reg.pola_87_8=negative +sff_cpld_reg.addr_87_8=0x03000010 +sff_cpld_reg.len_87_8=1 +sff_cpld_reg.bit_offset_87_8=6 + +sff_cpld_reg.mode_88_8=config +sff_cpld_reg.src_88_8=cpld +sff_cpld_reg.frmt_88_8=bit +sff_cpld_reg.pola_88_8=negative +sff_cpld_reg.addr_88_8=0x03000010 +sff_cpld_reg.len_88_8=1 +sff_cpld_reg.bit_offset_88_8=7 + +sff_cpld_reg.mode_89_8=config +sff_cpld_reg.src_89_8=cpld +sff_cpld_reg.frmt_89_8=bit +sff_cpld_reg.pola_89_8=negative +sff_cpld_reg.addr_89_8=0x03000011 +sff_cpld_reg.len_89_8=1 +sff_cpld_reg.bit_offset_89_8=0 + +sff_cpld_reg.mode_90_8=config +sff_cpld_reg.src_90_8=cpld +sff_cpld_reg.frmt_90_8=bit +sff_cpld_reg.pola_90_8=negative +sff_cpld_reg.addr_90_8=0x03000011 +sff_cpld_reg.len_90_8=1 +sff_cpld_reg.bit_offset_90_8=1 + +sff_cpld_reg.mode_91_8=config +sff_cpld_reg.src_91_8=cpld +sff_cpld_reg.frmt_91_8=bit +sff_cpld_reg.pola_91_8=negative +sff_cpld_reg.addr_91_8=0x03000011 +sff_cpld_reg.len_91_8=1 +sff_cpld_reg.bit_offset_91_8=2 + +sff_cpld_reg.mode_92_8=config +sff_cpld_reg.src_92_8=cpld +sff_cpld_reg.frmt_92_8=bit +sff_cpld_reg.pola_92_8=negative +sff_cpld_reg.addr_92_8=0x03000011 +sff_cpld_reg.len_92_8=1 +sff_cpld_reg.bit_offset_92_8=3 + +sff_cpld_reg.mode_93_8=config +sff_cpld_reg.src_93_8=cpld +sff_cpld_reg.frmt_93_8=bit +sff_cpld_reg.pola_93_8=negative +sff_cpld_reg.addr_93_8=0x03000011 +sff_cpld_reg.len_93_8=1 +sff_cpld_reg.bit_offset_93_8=4 + +sff_cpld_reg.mode_94_8=config +sff_cpld_reg.src_94_8=cpld +sff_cpld_reg.frmt_94_8=bit +sff_cpld_reg.pola_94_8=negative +sff_cpld_reg.addr_94_8=0x03000011 +sff_cpld_reg.len_94_8=1 +sff_cpld_reg.bit_offset_94_8=5 + +sff_cpld_reg.mode_95_8=config +sff_cpld_reg.src_95_8=cpld +sff_cpld_reg.frmt_95_8=bit +sff_cpld_reg.pola_95_8=negative +sff_cpld_reg.addr_95_8=0x03000011 +sff_cpld_reg.len_95_8=1 +sff_cpld_reg.bit_offset_95_8=6 + +sff_cpld_reg.mode_96_8=config +sff_cpld_reg.src_96_8=cpld +sff_cpld_reg.frmt_96_8=bit +sff_cpld_reg.pola_96_8=negative +sff_cpld_reg.addr_96_8=0x03000011 +sff_cpld_reg.len_96_8=1 +sff_cpld_reg.bit_offset_96_8=7 + +sff_cpld_reg.mode_97_8=config +sff_cpld_reg.src_97_8=cpld +sff_cpld_reg.frmt_97_8=bit +sff_cpld_reg.pola_97_8=negative +sff_cpld_reg.addr_97_8=0x04010010 +sff_cpld_reg.len_97_8=1 +sff_cpld_reg.bit_offset_97_8=0 + +sff_cpld_reg.mode_98_8=config +sff_cpld_reg.src_98_8=cpld +sff_cpld_reg.frmt_98_8=bit +sff_cpld_reg.pola_98_8=negative +sff_cpld_reg.addr_98_8=0x04010010 +sff_cpld_reg.len_98_8=1 +sff_cpld_reg.bit_offset_98_8=1 + +sff_cpld_reg.mode_99_8=config +sff_cpld_reg.src_99_8=cpld +sff_cpld_reg.frmt_99_8=bit +sff_cpld_reg.pola_99_8=negative +sff_cpld_reg.addr_99_8=0x04010010 +sff_cpld_reg.len_99_8=1 +sff_cpld_reg.bit_offset_99_8=2 + +sff_cpld_reg.mode_100_8=config +sff_cpld_reg.src_100_8=cpld +sff_cpld_reg.frmt_100_8=bit +sff_cpld_reg.pola_100_8=negative +sff_cpld_reg.addr_100_8=0x04010010 +sff_cpld_reg.len_100_8=1 +sff_cpld_reg.bit_offset_100_8=3 + +sff_cpld_reg.mode_101_8=config +sff_cpld_reg.src_101_8=cpld +sff_cpld_reg.frmt_101_8=bit +sff_cpld_reg.pola_101_8=negative +sff_cpld_reg.addr_101_8=0x04010010 +sff_cpld_reg.len_101_8=1 +sff_cpld_reg.bit_offset_101_8=4 + +sff_cpld_reg.mode_102_8=config +sff_cpld_reg.src_102_8=cpld +sff_cpld_reg.frmt_102_8=bit +sff_cpld_reg.pola_102_8=negative +sff_cpld_reg.addr_102_8=0x04010010 +sff_cpld_reg.len_102_8=1 +sff_cpld_reg.bit_offset_102_8=5 + +sff_cpld_reg.mode_103_8=config +sff_cpld_reg.src_103_8=cpld +sff_cpld_reg.frmt_103_8=bit +sff_cpld_reg.pola_103_8=negative +sff_cpld_reg.addr_103_8=0x04010010 +sff_cpld_reg.len_103_8=1 +sff_cpld_reg.bit_offset_103_8=6 + +sff_cpld_reg.mode_104_8=config +sff_cpld_reg.src_104_8=cpld +sff_cpld_reg.frmt_104_8=bit +sff_cpld_reg.pola_104_8=negative +sff_cpld_reg.addr_104_8=0x04010010 +sff_cpld_reg.len_104_8=1 +sff_cpld_reg.bit_offset_104_8=7 + +sff_cpld_reg.mode_105_8=config +sff_cpld_reg.src_105_8=cpld +sff_cpld_reg.frmt_105_8=bit +sff_cpld_reg.pola_105_8=negative +sff_cpld_reg.addr_105_8=0x04010011 +sff_cpld_reg.len_105_8=1 +sff_cpld_reg.bit_offset_105_8=0 + +sff_cpld_reg.mode_106_8=config +sff_cpld_reg.src_106_8=cpld +sff_cpld_reg.frmt_106_8=bit +sff_cpld_reg.pola_106_8=negative +sff_cpld_reg.addr_106_8=0x04010011 +sff_cpld_reg.len_106_8=1 +sff_cpld_reg.bit_offset_106_8=1 + +sff_cpld_reg.mode_107_8=config +sff_cpld_reg.src_107_8=cpld +sff_cpld_reg.frmt_107_8=bit +sff_cpld_reg.pola_107_8=negative +sff_cpld_reg.addr_107_8=0x04010011 +sff_cpld_reg.len_107_8=1 +sff_cpld_reg.bit_offset_107_8=2 + +sff_cpld_reg.mode_108_8=config +sff_cpld_reg.src_108_8=cpld +sff_cpld_reg.frmt_108_8=bit +sff_cpld_reg.pola_108_8=negative +sff_cpld_reg.addr_108_8=0x04010011 +sff_cpld_reg.len_108_8=1 +sff_cpld_reg.bit_offset_108_8=3 + +sff_cpld_reg.mode_109_8=config +sff_cpld_reg.src_109_8=cpld +sff_cpld_reg.frmt_109_8=bit +sff_cpld_reg.pola_109_8=negative +sff_cpld_reg.addr_109_8=0x04010011 +sff_cpld_reg.len_109_8=1 +sff_cpld_reg.bit_offset_109_8=4 + +sff_cpld_reg.mode_110_8=config +sff_cpld_reg.src_110_8=cpld +sff_cpld_reg.frmt_110_8=bit +sff_cpld_reg.pola_110_8=negative +sff_cpld_reg.addr_110_8=0x04010011 +sff_cpld_reg.len_110_8=1 +sff_cpld_reg.bit_offset_110_8=5 + +sff_cpld_reg.mode_111_8=config +sff_cpld_reg.src_111_8=cpld +sff_cpld_reg.frmt_111_8=bit +sff_cpld_reg.pola_111_8=negative +sff_cpld_reg.addr_111_8=0x04010011 +sff_cpld_reg.len_111_8=1 +sff_cpld_reg.bit_offset_111_8=6 + +sff_cpld_reg.mode_112_8=config +sff_cpld_reg.src_112_8=cpld +sff_cpld_reg.frmt_112_8=bit +sff_cpld_reg.pola_112_8=negative +sff_cpld_reg.addr_112_8=0x04010011 +sff_cpld_reg.len_112_8=1 +sff_cpld_reg.bit_offset_112_8=7 + +sff_cpld_reg.mode_113_8=config +sff_cpld_reg.src_113_8=cpld +sff_cpld_reg.frmt_113_8=bit +sff_cpld_reg.pola_113_8=negative +sff_cpld_reg.addr_113_8=0x04000010 +sff_cpld_reg.len_113_8=1 +sff_cpld_reg.bit_offset_113_8=0 + +sff_cpld_reg.mode_114_8=config +sff_cpld_reg.src_114_8=cpld +sff_cpld_reg.frmt_114_8=bit +sff_cpld_reg.pola_114_8=negative +sff_cpld_reg.addr_114_8=0x04000010 +sff_cpld_reg.len_114_8=1 +sff_cpld_reg.bit_offset_114_8=1 + +sff_cpld_reg.mode_115_8=config +sff_cpld_reg.src_115_8=cpld +sff_cpld_reg.frmt_115_8=bit +sff_cpld_reg.pola_115_8=negative +sff_cpld_reg.addr_115_8=0x04000010 +sff_cpld_reg.len_115_8=1 +sff_cpld_reg.bit_offset_115_8=2 + +sff_cpld_reg.mode_116_8=config +sff_cpld_reg.src_116_8=cpld +sff_cpld_reg.frmt_116_8=bit +sff_cpld_reg.pola_116_8=negative +sff_cpld_reg.addr_116_8=0x04000010 +sff_cpld_reg.len_116_8=1 +sff_cpld_reg.bit_offset_116_8=3 + +sff_cpld_reg.mode_117_8=config +sff_cpld_reg.src_117_8=cpld +sff_cpld_reg.frmt_117_8=bit +sff_cpld_reg.pola_117_8=negative +sff_cpld_reg.addr_117_8=0x04000010 +sff_cpld_reg.len_117_8=1 +sff_cpld_reg.bit_offset_117_8=4 + +sff_cpld_reg.mode_118_8=config +sff_cpld_reg.src_118_8=cpld +sff_cpld_reg.frmt_118_8=bit +sff_cpld_reg.pola_118_8=negative +sff_cpld_reg.addr_118_8=0x04000010 +sff_cpld_reg.len_118_8=1 +sff_cpld_reg.bit_offset_118_8=5 + +sff_cpld_reg.mode_119_8=config +sff_cpld_reg.src_119_8=cpld +sff_cpld_reg.frmt_119_8=bit +sff_cpld_reg.pola_119_8=negative +sff_cpld_reg.addr_119_8=0x04000010 +sff_cpld_reg.len_119_8=1 +sff_cpld_reg.bit_offset_119_8=6 + +sff_cpld_reg.mode_120_8=config +sff_cpld_reg.src_120_8=cpld +sff_cpld_reg.frmt_120_8=bit +sff_cpld_reg.pola_120_8=negative +sff_cpld_reg.addr_120_8=0x04000010 +sff_cpld_reg.len_120_8=1 +sff_cpld_reg.bit_offset_120_8=7 + +sff_cpld_reg.mode_121_8=config +sff_cpld_reg.src_121_8=cpld +sff_cpld_reg.frmt_121_8=bit +sff_cpld_reg.pola_121_8=negative +sff_cpld_reg.addr_121_8=0x04000011 +sff_cpld_reg.len_121_8=1 +sff_cpld_reg.bit_offset_121_8=0 + +sff_cpld_reg.mode_122_8=config +sff_cpld_reg.src_122_8=cpld +sff_cpld_reg.frmt_122_8=bit +sff_cpld_reg.pola_122_8=negative +sff_cpld_reg.addr_122_8=0x04000011 +sff_cpld_reg.len_122_8=1 +sff_cpld_reg.bit_offset_122_8=1 + +sff_cpld_reg.mode_123_8=config +sff_cpld_reg.src_123_8=cpld +sff_cpld_reg.frmt_123_8=bit +sff_cpld_reg.pola_123_8=negative +sff_cpld_reg.addr_123_8=0x04000011 +sff_cpld_reg.len_123_8=1 +sff_cpld_reg.bit_offset_123_8=2 + +sff_cpld_reg.mode_124_8=config +sff_cpld_reg.src_124_8=cpld +sff_cpld_reg.frmt_124_8=bit +sff_cpld_reg.pola_124_8=negative +sff_cpld_reg.addr_124_8=0x04000011 +sff_cpld_reg.len_124_8=1 +sff_cpld_reg.bit_offset_124_8=3 + +sff_cpld_reg.mode_125_8=config +sff_cpld_reg.src_125_8=cpld +sff_cpld_reg.frmt_125_8=bit +sff_cpld_reg.pola_125_8=negative +sff_cpld_reg.addr_125_8=0x04000011 +sff_cpld_reg.len_125_8=1 +sff_cpld_reg.bit_offset_125_8=4 + +sff_cpld_reg.mode_126_8=config +sff_cpld_reg.src_126_8=cpld +sff_cpld_reg.frmt_126_8=bit +sff_cpld_reg.pola_126_8=negative +sff_cpld_reg.addr_126_8=0x04000011 +sff_cpld_reg.len_126_8=1 +sff_cpld_reg.bit_offset_126_8=5 + +sff_cpld_reg.mode_127_8=config +sff_cpld_reg.src_127_8=cpld +sff_cpld_reg.frmt_127_8=bit +sff_cpld_reg.pola_127_8=negative +sff_cpld_reg.addr_127_8=0x04000011 +sff_cpld_reg.len_127_8=1 +sff_cpld_reg.bit_offset_127_8=6 + +sff_cpld_reg.mode_128_8=config +sff_cpld_reg.src_128_8=cpld +sff_cpld_reg.frmt_128_8=bit +sff_cpld_reg.pola_128_8=negative +sff_cpld_reg.addr_128_8=0x04000011 +sff_cpld_reg.len_128_8=1 +sff_cpld_reg.bit_offset_128_8=7 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SLOT.cfg b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SLOT.cfg new file mode 100755 index 000000000000..3298104cf1bf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/WB_PLAT_SLOT.cfg @@ -0,0 +1,1316 @@ +# Configuration item: i2c bus address of the sub-card +# Filling instructions: Format other_i2c_dev.bus_[slot_id]_[slot_index] other_i2c_dev.addr_[i2c_id]_[slot_index] +# Note: The slot_id of the child card is 5, and the slot_index starts from 1 +other_i2c_dev.bus_5_1=3 +other_i2c_dev.addr_5_1=0x56 +other_i2c_dev.bus_5_2=4 +other_i2c_dev.addr_5_2=0x56 +other_i2c_dev.bus_5_3=5 +other_i2c_dev.addr_5_3=0x56 +other_i2c_dev.bus_5_4=6 +other_i2c_dev.addr_5_4=0x56 + +slot_sysfs_name=eeprom + +# Number of sub-card +dev_num_5_0=4 + +# Number of sub-card temperature sensors +dev_num_5_1=0 + +# Number of sub-card voltage sensors +dev_num_5_2=12 + +# Number of current sensors on sub-card +dev_num_5_3=0 + +# Number of FPGA of subcards +dev_num_5_9=0 + +dev_present_status.mode_5_1=config +dev_present_status.int_cons_5_1= +dev_present_status.src_5_1=cpld +dev_present_status.frmt_5_1=bit +dev_present_status.pola_5_1=negative +dev_present_status.fpath_5_1= +dev_present_status.addr_5_1=0x0001002c +dev_present_status.len_5_1=1 +dev_present_status.bit_offset_5_1=4 + +dev_present_status.mode_5_2=config +dev_present_status.int_cons_5_2= +dev_present_status.src_5_2=cpld +dev_present_status.frmt_5_2=bit +dev_present_status.pola_5_2=negative +dev_present_status.fpath_5_2= +dev_present_status.addr_5_2=0x0001002c +dev_present_status.len_5_2=1 +dev_present_status.bit_offset_5_2=5 + +dev_present_status.mode_5_3=config +dev_present_status.int_cons_5_3= +dev_present_status.src_5_3=cpld +dev_present_status.frmt_5_3=bit +dev_present_status.pola_5_3=negative +dev_present_status.fpath_5_3= +dev_present_status.addr_5_3=0x0001002c +dev_present_status.len_5_3=1 +dev_present_status.bit_offset_5_3=6 + +dev_present_status.mode_5_4=config +dev_present_status.int_cons_5_4= +dev_present_status.src_5_4=cpld +dev_present_status.frmt_5_4=bit +dev_present_status.pola_5_4=negative +dev_present_status.fpath_5_4= +dev_present_status.addr_5_4=0x0001002c +dev_present_status.len_5_4=1 +dev_present_status.bit_offset_5_4=7 + +#slot1 in1 input +hwmon_in.mode_0x0101_0x50=config +hwmon_in.int_cons_0x0101_0x50=0 +hwmon_in.src_0x0101_0x50=cpld +hwmon_in.frmt_0x0101_0x50=num_bytes +hwmon_in.addr_0x0101_0x50=0x01000041 +hwmon_in.len_0x0101_0x50=2 +hwmon_in.int_extra1_0x0101_0x50=0x01000047 +hwmon_in.int_extra2_0x0101_0x50=2480 + +#slot1 in1 alais +hwmon_in.mode_0x0101_0x51=str_constant +hwmon_in.str_cons_0x0101_0x51=SLOT1_VDD3v3_QSFP_1 + +#slot1 in1 type +hwmon_in.mode_0x0101_0x52=str_constant +hwmon_in.str_cons_0x0101_0x52=cpld + +#slot1 in1 max +hwmon_in.mode_0x0101_0x53=str_constant +hwmon_in.str_cons_0x0101_0x53=3500 + +#slot1 in1 min +hwmon_in.mode_0x0101_0x55=str_constant +hwmon_in.str_cons_0x0101_0x55=3135 + +#slot1 in2 input +hwmon_in.mode_0x0102_0x50=config +hwmon_in.int_cons_0x0102_0x50=0 +hwmon_in.src_0x0102_0x50=cpld +hwmon_in.frmt_0x0102_0x50=num_bytes +hwmon_in.addr_0x0102_0x50=0x01000043 +hwmon_in.len_0x0102_0x50=2 +hwmon_in.int_extra1_0x0102_0x50=0x01000047 +hwmon_in.int_extra2_0x0102_0x50=2480 + +#slot1 in2 alais +hwmon_in.mode_0x0102_0x51=str_constant +hwmon_in.str_cons_0x0102_0x51=SLOT1_VDD3v3_QSFP_2 + +#slot1 in2 type +hwmon_in.mode_0x0102_0x52=str_constant +hwmon_in.str_cons_0x0102_0x52=cpld + +#slot1 in2 max +hwmon_in.mode_0x0102_0x53=str_constant +hwmon_in.str_cons_0x0102_0x53=3500 + +#slot1 in2 min +hwmon_in.mode_0x0102_0x55=str_constant +hwmon_in.str_cons_0x0102_0x55=3135 + +#slot1 in3 input +hwmon_in.mode_0x0103_0x50=config +hwmon_in.int_cons_0x0103_0x50=0 +hwmon_in.src_0x0103_0x50=cpld +hwmon_in.frmt_0x0103_0x50=num_bytes +hwmon_in.addr_0x0103_0x50=0x01000045 +hwmon_in.len_0x0103_0x50=2 +hwmon_in.int_extra1_0x0103_0x50=0x01000047 +hwmon_in.int_extra2_0x0103_0x50=1240 + +#slot1 in3 alais +hwmon_in.mode_0x0103_0x51=str_constant +hwmon_in.str_cons_0x0103_0x51=SLOT1_VDD1v8 + +#slot1 in3 type +hwmon_in.mode_0x0103_0x52=str_constant +hwmon_in.str_cons_0x0103_0x52=cpld + +#slot1 in3 max +hwmon_in.mode_0x0103_0x53=str_constant +hwmon_in.str_cons_0x0103_0x53=1926 + +#slot1 in3 min +hwmon_in.mode_0x0103_0x55=str_constant +hwmon_in.str_cons_0x0103_0x55=1710 + +#slot1 in4 input +hwmon_in.mode_0x0104_0x50=config +hwmon_in.int_cons_0x0104_0x50=0 +hwmon_in.src_0x0104_0x50=cpld +hwmon_in.frmt_0x0104_0x50=num_bytes +hwmon_in.addr_0x0104_0x50=0x01000047 +hwmon_in.len_0x0104_0x50=2 +hwmon_in.int_extra1_0x0104_0x50=0x01000047 +hwmon_in.int_extra2_0x0104_0x50=1000 + +#slot1 in4 alais +hwmon_in.mode_0x0104_0x51=str_constant +hwmon_in.str_cons_0x0104_0x51=SLOT1_TEST1v24 + +#slot1 in4 type +hwmon_in.mode_0x0104_0x52=str_constant +hwmon_in.str_cons_0x0104_0x52=cpld + +#slot1 in4 max +hwmon_in.mode_0x0104_0x53=str_constant +hwmon_in.str_cons_0x0104_0x53=1302 + +#slot1 in4 min +hwmon_in.mode_0x0104_0x55=str_constant +hwmon_in.str_cons_0x0104_0x55=1178 + +#slot1 in5 input +hwmon_in.mode_0x0105_0x50=config +hwmon_in.int_cons_0x0105_0x50=0 +hwmon_in.src_0x0105_0x50=cpld +hwmon_in.frmt_0x0105_0x50=num_bytes +hwmon_in.addr_0x0105_0x50=0x01000049 +hwmon_in.len_0x0105_0x50=2 +hwmon_in.int_extra1_0x0105_0x50=0x01000047 +hwmon_in.int_extra2_0x0105_0x50=2480 + +#slot1 in5 alais +hwmon_in.mode_0x0105_0x51=str_constant +hwmon_in.str_cons_0x0105_0x51=SLOT1_VDD3v3_CLK + +#slot1 in5 type +hwmon_in.mode_0x0105_0x52=str_constant +hwmon_in.str_cons_0x0105_0x52=cpld + +#slot1 in5 max +hwmon_in.mode_0x0105_0x53=str_constant +hwmon_in.str_cons_0x0105_0x53=3556 + +#slot1 in5 min +hwmon_in.mode_0x0105_0x55=str_constant +hwmon_in.str_cons_0x0105_0x55=3135 + +#slot1 in6 input +hwmon_in.mode_0x0106_0x50=config +hwmon_in.int_cons_0x0106_0x50=0 +hwmon_in.src_0x0106_0x50=cpld +hwmon_in.frmt_0x0106_0x50=num_bytes +hwmon_in.addr_0x0106_0x50=0x0100004b +hwmon_in.len_0x0106_0x50=2 +hwmon_in.int_extra1_0x0106_0x50=0x01000047 +hwmon_in.int_extra2_0x0106_0x50=2480 + +#slot1 in6 alais +hwmon_in.mode_0x0106_0x51=str_constant +hwmon_in.str_cons_0x0106_0x51=SLOT1_VDD5v0 + +#slot1 in6 type +hwmon_in.mode_0x0106_0x52=str_constant +hwmon_in.str_cons_0x0106_0x52=cpld + +#slot1 in6 max +hwmon_in.mode_0x0106_0x53=str_constant +hwmon_in.str_cons_0x0106_0x53=5331 + +#slot1 in6 min +hwmon_in.mode_0x0106_0x55=str_constant +hwmon_in.str_cons_0x0106_0x55=4750 + +#slot1 in7 input +hwmon_in.mode_0x0107_0x50=config +hwmon_in.int_cons_0x0107_0x50=0 +hwmon_in.src_0x0107_0x50=cpld +hwmon_in.frmt_0x0107_0x50=num_bytes +hwmon_in.addr_0x0107_0x50=0x0100004d +hwmon_in.len_0x0107_0x50=2 +hwmon_in.int_extra1_0x0107_0x50=0x01000047 +hwmon_in.int_extra2_0x0107_0x50=2480 + +#slot1 in7 alais +hwmon_in.mode_0x0107_0x51=str_constant +hwmon_in.str_cons_0x0107_0x51=SLOT1_VDD3v7_CLK_MCU + +#slot1 in7 type +hwmon_in.mode_0x0107_0x52=str_constant +hwmon_in.str_cons_0x0107_0x52=cpld + +#slot1 in7 max +hwmon_in.mode_0x0107_0x53=str_constant +hwmon_in.str_cons_0x0107_0x53=4022 + +#slot1 in7 min +hwmon_in.mode_0x0107_0x55=str_constant +hwmon_in.str_cons_0x0107_0x55=3639 + +#slot1 in8 input +hwmon_in.mode_0x0108_0x50=config +hwmon_in.int_cons_0x0108_0x50=0 +hwmon_in.src_0x0108_0x50=cpld +hwmon_in.frmt_0x0108_0x50=num_bytes +hwmon_in.addr_0x0108_0x50=0x0100004f +hwmon_in.len_0x0108_0x50=2 +hwmon_in.int_extra1_0x0108_0x50=0x01000047 +hwmon_in.int_extra2_0x0108_0x50=1240 + +#slot1 in8 alais +hwmon_in.mode_0x0108_0x51=str_constant +hwmon_in.str_cons_0x0108_0x51=SLOT1_VDD1v2 + +#slot1 in8 type +hwmon_in.mode_0x0108_0x52=str_constant +hwmon_in.str_cons_0x0108_0x52=cpld + +#slot1 in8 max +hwmon_in.mode_0x0108_0x53=str_constant +hwmon_in.str_cons_0x0108_0x53=1260 + +#slot1 in8 min +hwmon_in.mode_0x0108_0x55=str_constant +hwmon_in.str_cons_0x0108_0x55=1140 + +#slot1 in9 input +hwmon_in.mode_0x0109_0x50=config +hwmon_in.int_cons_0x0109_0x50=0 +hwmon_in.src_0x0109_0x50=cpld +hwmon_in.frmt_0x0109_0x50=num_bytes +hwmon_in.addr_0x0109_0x50=0x01000051 +hwmon_in.len_0x0109_0x50=2 +hwmon_in.int_extra1_0x0109_0x50=0x01000047 +hwmon_in.int_extra2_0x0109_0x50=2480 + +#slot1 in9 alais +hwmon_in.mode_0x0109_0x51=str_constant +hwmon_in.str_cons_0x0109_0x51=SLOT1_VDD3v3 + +#slot1 in9 type +hwmon_in.mode_0x0109_0x52=str_constant +hwmon_in.str_cons_0x0109_0x52=cpld + +#slot1 in9 max +hwmon_in.mode_0x0109_0x53=str_constant +hwmon_in.str_cons_0x0109_0x53=3539 + +#slot1 in9 min +hwmon_in.mode_0x0109_0x55=str_constant +hwmon_in.str_cons_0x0109_0x55=3135 + +#slot1 in10 input +hwmon_in.mode_0x010a_0x50=config +hwmon_in.int_cons_0x010a_0x50=0 +hwmon_in.src_0x010a_0x50=cpld +hwmon_in.frmt_0x010a_0x50=num_bytes +hwmon_in.addr_0x010a_0x50=0x01000053 +hwmon_in.len_0x010a_0x50=2 +hwmon_in.int_extra1_0x010a_0x50=0x01000047 +hwmon_in.int_extra2_0x010a_0x50=1240 + +#slot1 in10 alais +hwmon_in.mode_0x010a_0x51=str_constant +hwmon_in.str_cons_0x010a_0x51=SLOT1_DVDD_0V8 + +#slot1 in10 type +hwmon_in.mode_0x010a_0x52=str_constant +hwmon_in.str_cons_0x010a_0x52=cpld + +#slot1 in10 max +hwmon_in.mode_0x010a_0x53=str_constant +hwmon_in.str_cons_0x010a_0x53=772 + +#slot1 in10 min +hwmon_in.mode_0x010a_0x55=str_constant +hwmon_in.str_cons_0x010a_0x55=684 + +#slot1 in11 input +hwmon_in.mode_0x010b_0x50=config +hwmon_in.int_cons_0x010b_0x50=0 +hwmon_in.src_0x010b_0x50=cpld +hwmon_in.frmt_0x010b_0x50=num_bytes +hwmon_in.addr_0x010b_0x50=0x01000055 +hwmon_in.len_0x010b_0x50=2 +hwmon_in.int_extra1_0x010b_0x50=0x01000047 +hwmon_in.int_extra2_0x010b_0x50=1240 + +#slot1 in11 alais +hwmon_in.mode_0x010b_0x51=str_constant +hwmon_in.str_cons_0x010b_0x51=SLOT1_VDD1V8_CPLD + +#slot1 in11 type +hwmon_in.mode_0x010b_0x52=str_constant +hwmon_in.str_cons_0x010b_0x52=cpld + +#slot1 in11 max +hwmon_in.mode_0x010b_0x53=str_constant +hwmon_in.str_cons_0x010b_0x53=1909 + +#slot1 in11 min +hwmon_in.mode_0x010b_0x55=str_constant +hwmon_in.str_cons_0x010b_0x55=1710 + +#slot1 in12 input +hwmon_in.mode_0x010c_0x50=config +hwmon_in.int_cons_0x010c_0x50=0 +hwmon_in.src_0x010c_0x50=cpld +hwmon_in.frmt_0x010c_0x50=num_bytes +hwmon_in.addr_0x010c_0x50=0x01000057 +hwmon_in.len_0x010c_0x50=2 +hwmon_in.int_extra1_0x010c_0x50=0x01000047 +hwmon_in.int_extra2_0x010c_0x50=1240 + +#slot1 in12 alais +hwmon_in.mode_0x010c_0x51=str_constant +hwmon_in.str_cons_0x010c_0x51=SLOT1_AVDD0V8 + +#slot1 in12 type +hwmon_in.mode_0x010c_0x52=str_constant +hwmon_in.str_cons_0x010c_0x52=cpld + +#slot1 in12 max +hwmon_in.mode_0x010c_0x53=str_constant +hwmon_in.str_cons_0x010c_0x53=877 + +#slot1 in12 min +hwmon_in.mode_0x010c_0x55=str_constant +hwmon_in.str_cons_0x010c_0x55=776 + +#slot2 in1 input +hwmon_in.mode_0x0201_0x50=config +hwmon_in.int_cons_0x0201_0x50=0 +hwmon_in.src_0x0201_0x50=cpld +hwmon_in.frmt_0x0201_0x50=num_bytes +hwmon_in.addr_0x0201_0x50=0x02000041 +hwmon_in.len_0x0201_0x50=2 +hwmon_in.int_extra1_0x0201_0x50=0x02000047 +hwmon_in.int_extra2_0x0201_0x50=2480 + +#slot2 in1 alais +hwmon_in.mode_0x0201_0x51=str_constant +hwmon_in.str_cons_0x0201_0x51=SLOT2_VDD3v3_QSFP_1 + +#slot2 in1 type +hwmon_in.mode_0x0201_0x52=str_constant +hwmon_in.str_cons_0x0201_0x52=cpld + +#slot2 in1 max +hwmon_in.mode_0x0201_0x53=str_constant +hwmon_in.str_cons_0x0201_0x53=3500 + +#slot2 in1 min +hwmon_in.mode_0x0201_0x55=str_constant +hwmon_in.str_cons_0x0201_0x55=3135 + +#slot2 in2 input +hwmon_in.mode_0x0202_0x50=config +hwmon_in.int_cons_0x0202_0x50=0 +hwmon_in.src_0x0202_0x50=cpld +hwmon_in.frmt_0x0202_0x50=num_bytes +hwmon_in.addr_0x0202_0x50=0x02000043 +hwmon_in.len_0x0202_0x50=2 +hwmon_in.int_extra1_0x0202_0x50=0x02000047 +hwmon_in.int_extra2_0x0202_0x50=2480 + +#slot2 in2 alais +hwmon_in.mode_0x0202_0x51=str_constant +hwmon_in.str_cons_0x0202_0x51=SLOT2_VDD3v3_QSFP_2 + +#slot2 in2 type +hwmon_in.mode_0x0202_0x52=str_constant +hwmon_in.str_cons_0x0202_0x52=cpld + +#slot2 in2 max +hwmon_in.mode_0x0202_0x53=str_constant +hwmon_in.str_cons_0x0202_0x53=3500 + +#slot2 in2 min +hwmon_in.mode_0x0202_0x55=str_constant +hwmon_in.str_cons_0x0202_0x55=3135 + +#slot2 in3 input +hwmon_in.mode_0x0203_0x50=config +hwmon_in.int_cons_0x0203_0x50=0 +hwmon_in.src_0x0203_0x50=cpld +hwmon_in.frmt_0x0203_0x50=num_bytes +hwmon_in.addr_0x0203_0x50=0x02000045 +hwmon_in.len_0x0203_0x50=2 +hwmon_in.int_extra1_0x0203_0x50=0x02000047 +hwmon_in.int_extra2_0x0203_0x50=1240 + +#slot2 in3 alais +hwmon_in.mode_0x0203_0x51=str_constant +hwmon_in.str_cons_0x0203_0x51=SLOT2_VDD1v8 + +#slot2 in3 type +hwmon_in.mode_0x0203_0x52=str_constant +hwmon_in.str_cons_0x0203_0x52=cpld + +#slot2 in3 max +hwmon_in.mode_0x0203_0x53=str_constant +hwmon_in.str_cons_0x0203_0x53=1926 + +#slot2 in3 min +hwmon_in.mode_0x0203_0x55=str_constant +hwmon_in.str_cons_0x0203_0x55=1710 + +#slot2 in4 input +hwmon_in.mode_0x0204_0x50=config +hwmon_in.int_cons_0x0204_0x50=0 +hwmon_in.src_0x0204_0x50=cpld +hwmon_in.frmt_0x0204_0x50=num_bytes +hwmon_in.addr_0x0204_0x50=0x02000047 +hwmon_in.len_0x0204_0x50=2 +hwmon_in.int_extra1_0x0204_0x50=0x02000047 +hwmon_in.int_extra2_0x0204_0x50=1000 + +#slot2 in4 alais +hwmon_in.mode_0x0204_0x51=str_constant +hwmon_in.str_cons_0x0204_0x51=SLOT2_TEST1v24 + +#slot2 in4 type +hwmon_in.mode_0x0204_0x52=str_constant +hwmon_in.str_cons_0x0204_0x52=cpld + +#slot2 in4 max +hwmon_in.mode_0x0204_0x53=str_constant +hwmon_in.str_cons_0x0204_0x53=1302 + +#slot2 in4 min +hwmon_in.mode_0x0204_0x55=str_constant +hwmon_in.str_cons_0x0204_0x55=1178 + +#slot2 in5 input +hwmon_in.mode_0x0205_0x50=config +hwmon_in.int_cons_0x0205_0x50=0 +hwmon_in.src_0x0205_0x50=cpld +hwmon_in.frmt_0x0205_0x50=num_bytes +hwmon_in.addr_0x0205_0x50=0x02000049 +hwmon_in.len_0x0205_0x50=2 +hwmon_in.int_extra1_0x0205_0x50=0x02000047 +hwmon_in.int_extra2_0x0205_0x50=2480 + +#slot2 in5 alais +hwmon_in.mode_0x0205_0x51=str_constant +hwmon_in.str_cons_0x0205_0x51=SLOT2_VDD3v3_CLK + +#slot2 in5 type +hwmon_in.mode_0x0205_0x52=str_constant +hwmon_in.str_cons_0x0205_0x52=cpld + +#slot2 in5 max +hwmon_in.mode_0x0205_0x53=str_constant +hwmon_in.str_cons_0x0205_0x53=3556 + +#slot2 in5 min +hwmon_in.mode_0x0205_0x55=str_constant +hwmon_in.str_cons_0x0205_0x55=3135 + +#slot2 in6 input +hwmon_in.mode_0x0206_0x50=config +hwmon_in.int_cons_0x0206_0x50=0 +hwmon_in.src_0x0206_0x50=cpld +hwmon_in.frmt_0x0206_0x50=num_bytes +hwmon_in.addr_0x0206_0x50=0x0200004b +hwmon_in.len_0x0206_0x50=2 +hwmon_in.int_extra1_0x0206_0x50=0x02000047 +hwmon_in.int_extra2_0x0206_0x50=2480 + +#slot2 in6 alais +hwmon_in.mode_0x0206_0x51=str_constant +hwmon_in.str_cons_0x0206_0x51=SLOT2_VDD5v0 + +#slot2 in6 type +hwmon_in.mode_0x0206_0x52=str_constant +hwmon_in.str_cons_0x0206_0x52=cpld + +#slot2 in6 max +hwmon_in.mode_0x0206_0x53=str_constant +hwmon_in.str_cons_0x0206_0x53=5331 + +#slot2 in6 min +hwmon_in.mode_0x0206_0x55=str_constant +hwmon_in.str_cons_0x0206_0x55=4750 + +#slot2 in7 input +hwmon_in.mode_0x0207_0x50=config +hwmon_in.int_cons_0x0207_0x50=0 +hwmon_in.src_0x0207_0x50=cpld +hwmon_in.frmt_0x0207_0x50=num_bytes +hwmon_in.addr_0x0207_0x50=0x0200004d +hwmon_in.len_0x0207_0x50=2 +hwmon_in.int_extra1_0x0207_0x50=0x02000047 +hwmon_in.int_extra2_0x0207_0x50=2480 + +#slot2 in7 alais +hwmon_in.mode_0x0207_0x51=str_constant +hwmon_in.str_cons_0x0207_0x51=SLOT2_VDD3v7_CLK_MCU + +#slot2 in7 type +hwmon_in.mode_0x0207_0x52=str_constant +hwmon_in.str_cons_0x0207_0x52=cpld + +#slot2 in7 max +hwmon_in.mode_0x0207_0x53=str_constant +hwmon_in.str_cons_0x0207_0x53=4022 + +#slot2 in7 min +hwmon_in.mode_0x0207_0x55=str_constant +hwmon_in.str_cons_0x0207_0x55=3639 + +#slot2 in8 input +hwmon_in.mode_0x0208_0x50=config +hwmon_in.int_cons_0x0208_0x50=0 +hwmon_in.src_0x0208_0x50=cpld +hwmon_in.frmt_0x0208_0x50=num_bytes +hwmon_in.addr_0x0208_0x50=0x0200004f +hwmon_in.len_0x0208_0x50=2 +hwmon_in.int_extra1_0x0208_0x50=0x02000047 +hwmon_in.int_extra2_0x0208_0x50=1240 + +#slot2 in8 alais +hwmon_in.mode_0x0208_0x51=str_constant +hwmon_in.str_cons_0x0208_0x51=SLOT2_VDD1v2 + +#slot2 in8 type +hwmon_in.mode_0x0208_0x52=str_constant +hwmon_in.str_cons_0x0208_0x52=cpld + +#slot2 in8 max +hwmon_in.mode_0x0208_0x53=str_constant +hwmon_in.str_cons_0x0208_0x53=1260 + +#slot2 in8 min +hwmon_in.mode_0x0208_0x55=str_constant +hwmon_in.str_cons_0x0208_0x55=1140 + +#slot2 in9 input +hwmon_in.mode_0x0209_0x50=config +hwmon_in.int_cons_0x0209_0x50=0 +hwmon_in.src_0x0209_0x50=cpld +hwmon_in.frmt_0x0209_0x50=num_bytes +hwmon_in.addr_0x0209_0x50=0x02000051 +hwmon_in.len_0x0209_0x50=2 +hwmon_in.int_extra1_0x0209_0x50=0x02000047 +hwmon_in.int_extra2_0x0209_0x50=2480 + +#slot2 in9 alais +hwmon_in.mode_0x0209_0x51=str_constant +hwmon_in.str_cons_0x0209_0x51=SLOT2_VDD3v3 + +#slot2 in9 type +hwmon_in.mode_0x0209_0x52=str_constant +hwmon_in.str_cons_0x0209_0x52=cpld + +#slot2 in9 max +hwmon_in.mode_0x0209_0x53=str_constant +hwmon_in.str_cons_0x0209_0x53=3539 + +#slot2 in9 min +hwmon_in.mode_0x0209_0x55=str_constant +hwmon_in.str_cons_0x0209_0x55=3135 + +#slot2 in10 input +hwmon_in.mode_0x020a_0x50=config +hwmon_in.int_cons_0x020a_0x50=0 +hwmon_in.src_0x020a_0x50=cpld +hwmon_in.frmt_0x020a_0x50=num_bytes +hwmon_in.addr_0x020a_0x50=0x02000053 +hwmon_in.len_0x020a_0x50=2 +hwmon_in.int_extra1_0x020a_0x50=0x02000047 +hwmon_in.int_extra2_0x020a_0x50=1240 + +#slot2 in10 alais +hwmon_in.mode_0x020a_0x51=str_constant +hwmon_in.str_cons_0x020a_0x51=SLOT2_DVDD_0V8 + +#slot2 in10 type +hwmon_in.mode_0x020a_0x52=str_constant +hwmon_in.str_cons_0x020a_0x52=cpld + +#slot2 in10 max +hwmon_in.mode_0x020a_0x53=str_constant +hwmon_in.str_cons_0x020a_0x53=772 + +#slot2 in10 min +hwmon_in.mode_0x020a_0x55=str_constant +hwmon_in.str_cons_0x020a_0x55=684 + +#slot2 in11 input +hwmon_in.mode_0x020b_0x50=config +hwmon_in.int_cons_0x020b_0x50=0 +hwmon_in.src_0x020b_0x50=cpld +hwmon_in.frmt_0x020b_0x50=num_bytes +hwmon_in.addr_0x020b_0x50=0x02000055 +hwmon_in.len_0x020b_0x50=2 +hwmon_in.int_extra1_0x020b_0x50=0x02000047 +hwmon_in.int_extra2_0x020b_0x50=1240 + +#slot2 in11 alais +hwmon_in.mode_0x020b_0x51=str_constant +hwmon_in.str_cons_0x020b_0x51=SLOT2_VDD1V8_CPLD + +#slot2 in11 type +hwmon_in.mode_0x020b_0x52=str_constant +hwmon_in.str_cons_0x020b_0x52=cpld + +#slot2 in11 max +hwmon_in.mode_0x020b_0x53=str_constant +hwmon_in.str_cons_0x020b_0x53=1909 + +#slot2 in11 min +hwmon_in.mode_0x020b_0x55=str_constant +hwmon_in.str_cons_0x020b_0x55=1710 + +#slot2 in12 input +hwmon_in.mode_0x020c_0x50=config +hwmon_in.int_cons_0x020c_0x50=0 +hwmon_in.src_0x020c_0x50=cpld +hwmon_in.frmt_0x020c_0x50=num_bytes +hwmon_in.addr_0x020c_0x50=0x02000057 +hwmon_in.len_0x020c_0x50=2 +hwmon_in.int_extra1_0x020c_0x50=0x02000047 +hwmon_in.int_extra2_0x020c_0x50=1240 + +#slot2 in12 alais +hwmon_in.mode_0x020c_0x51=str_constant +hwmon_in.str_cons_0x020c_0x51=SLOT2_AVDD0V8 + +#slot2 in12 type +hwmon_in.mode_0x020c_0x52=str_constant +hwmon_in.str_cons_0x020c_0x52=cpld + +#slot2 in12 max +hwmon_in.mode_0x020c_0x53=str_constant +hwmon_in.str_cons_0x020c_0x53=877 + +#slot2 in12 min +hwmon_in.mode_0x020c_0x55=str_constant +hwmon_in.str_cons_0x020c_0x55=776 + +#slot3 in1 input +hwmon_in.mode_0x0301_0x50=config +hwmon_in.int_cons_0x0301_0x50=0 +hwmon_in.src_0x0301_0x50=cpld +hwmon_in.frmt_0x0301_0x50=num_bytes +hwmon_in.addr_0x0301_0x50=0x03000041 +hwmon_in.len_0x0301_0x50=2 +hwmon_in.int_extra1_0x0301_0x50=0x03000047 +hwmon_in.int_extra2_0x0301_0x50=2480 + +#slot3 in1 alais +hwmon_in.mode_0x0301_0x51=str_constant +hwmon_in.str_cons_0x0301_0x51=SLOT3_VDD3v3_QSFP_1 + +#slot3 in1 type +hwmon_in.mode_0x0301_0x52=str_constant +hwmon_in.str_cons_0x0301_0x52=cpld + +#slot3 in1 max +hwmon_in.mode_0x0301_0x53=str_constant +hwmon_in.str_cons_0x0301_0x53=3500 + +#slot3 in1 min +hwmon_in.mode_0x0301_0x55=str_constant +hwmon_in.str_cons_0x0301_0x55=3135 + +#slot3 in2 input +hwmon_in.mode_0x0302_0x50=config +hwmon_in.int_cons_0x0302_0x50=0 +hwmon_in.src_0x0302_0x50=cpld +hwmon_in.frmt_0x0302_0x50=num_bytes +hwmon_in.addr_0x0302_0x50=0x03000043 +hwmon_in.len_0x0302_0x50=2 +hwmon_in.int_extra1_0x0302_0x50=0x03000047 +hwmon_in.int_extra2_0x0302_0x50=2480 + +#slot3 in2 alais +hwmon_in.mode_0x0302_0x51=str_constant +hwmon_in.str_cons_0x0302_0x51=SLOT3_VDD3v3_QSFP_2 + +#slot3 in2 type +hwmon_in.mode_0x0302_0x52=str_constant +hwmon_in.str_cons_0x0302_0x52=cpld + +#slot3 in2 max +hwmon_in.mode_0x0302_0x53=str_constant +hwmon_in.str_cons_0x0302_0x53=3500 + +#slot3 in2 min +hwmon_in.mode_0x0302_0x55=str_constant +hwmon_in.str_cons_0x0302_0x55=3135 + +#slot3 in3 input +hwmon_in.mode_0x0303_0x50=config +hwmon_in.int_cons_0x0303_0x50=0 +hwmon_in.src_0x0303_0x50=cpld +hwmon_in.frmt_0x0303_0x50=num_bytes +hwmon_in.addr_0x0303_0x50=0x03000045 +hwmon_in.len_0x0303_0x50=2 +hwmon_in.int_extra1_0x0303_0x50=0x03000047 +hwmon_in.int_extra2_0x0303_0x50=1240 + +#slot3 in3 alais +hwmon_in.mode_0x0303_0x51=str_constant +hwmon_in.str_cons_0x0303_0x51=SLOT3_VDD1v8 + +#slot3 in3 type +hwmon_in.mode_0x0303_0x52=str_constant +hwmon_in.str_cons_0x0303_0x52=cpld + +#slot3 in3 max +hwmon_in.mode_0x0303_0x53=str_constant +hwmon_in.str_cons_0x0303_0x53=1926 + +#slot3 in3 min +hwmon_in.mode_0x0303_0x55=str_constant +hwmon_in.str_cons_0x0303_0x55=1710 + +#slot3 in4 input +hwmon_in.mode_0x0304_0x50=config +hwmon_in.int_cons_0x0304_0x50=0 +hwmon_in.src_0x0304_0x50=cpld +hwmon_in.frmt_0x0304_0x50=num_bytes +hwmon_in.addr_0x0304_0x50=0x03000047 +hwmon_in.len_0x0304_0x50=2 +hwmon_in.int_extra1_0x0304_0x50=0x03000047 +hwmon_in.int_extra2_0x0304_0x50=1000 + +#slot3 in4 alais +hwmon_in.mode_0x0304_0x51=str_constant +hwmon_in.str_cons_0x0304_0x51=SLOT3_TEST1v24 + +#slot3 in4 type +hwmon_in.mode_0x0304_0x52=str_constant +hwmon_in.str_cons_0x0304_0x52=cpld + +#slot3 in4 max +hwmon_in.mode_0x0304_0x53=str_constant +hwmon_in.str_cons_0x0304_0x53=1302 + +#slot3 in4 min +hwmon_in.mode_0x0304_0x55=str_constant +hwmon_in.str_cons_0x0304_0x55=1178 + +#slot3 in5 input +hwmon_in.mode_0x0305_0x50=config +hwmon_in.int_cons_0x0305_0x50=0 +hwmon_in.src_0x0305_0x50=cpld +hwmon_in.frmt_0x0305_0x50=num_bytes +hwmon_in.addr_0x0305_0x50=0x03000049 +hwmon_in.len_0x0305_0x50=2 +hwmon_in.int_extra1_0x0305_0x50=0x03000047 +hwmon_in.int_extra2_0x0305_0x50=2480 + +#slot3 in5 alais +hwmon_in.mode_0x0305_0x51=str_constant +hwmon_in.str_cons_0x0305_0x51=SLOT3_VDD3v3_CLK + +#slot3 in5 type +hwmon_in.mode_0x0305_0x52=str_constant +hwmon_in.str_cons_0x0305_0x52=cpld + +#slot3 in5 max +hwmon_in.mode_0x0305_0x53=str_constant +hwmon_in.str_cons_0x0305_0x53=3556 + +#slot3 in5 min +hwmon_in.mode_0x0305_0x55=str_constant +hwmon_in.str_cons_0x0305_0x55=3135 + +#slot3 in6 input +hwmon_in.mode_0x0306_0x50=config +hwmon_in.int_cons_0x0306_0x50=0 +hwmon_in.src_0x0306_0x50=cpld +hwmon_in.frmt_0x0306_0x50=num_bytes +hwmon_in.addr_0x0306_0x50=0x0300004b +hwmon_in.len_0x0306_0x50=2 +hwmon_in.int_extra1_0x0306_0x50=0x03000047 +hwmon_in.int_extra2_0x0306_0x50=2480 + +#slot3 in6 alais +hwmon_in.mode_0x0306_0x51=str_constant +hwmon_in.str_cons_0x0306_0x51=SLOT3_VDD5v0 + +#slot3 in6 type +hwmon_in.mode_0x0306_0x52=str_constant +hwmon_in.str_cons_0x0306_0x52=cpld + +#slot3 in6 max +hwmon_in.mode_0x0306_0x53=str_constant +hwmon_in.str_cons_0x0306_0x53=5331 + +#slot3 in6 min +hwmon_in.mode_0x0306_0x55=str_constant +hwmon_in.str_cons_0x0306_0x55=4750 + +#slot3 in7 input +hwmon_in.mode_0x0307_0x50=config +hwmon_in.int_cons_0x0307_0x50=0 +hwmon_in.src_0x0307_0x50=cpld +hwmon_in.frmt_0x0307_0x50=num_bytes +hwmon_in.addr_0x0307_0x50=0x0300004d +hwmon_in.len_0x0307_0x50=2 +hwmon_in.int_extra1_0x0307_0x50=0x03000047 +hwmon_in.int_extra2_0x0307_0x50=2480 + +#slot3 in7 alais +hwmon_in.mode_0x0307_0x51=str_constant +hwmon_in.str_cons_0x0307_0x51=SLOT3_VDD3v7_CLK_MCU + +#slot3 in7 type +hwmon_in.mode_0x0307_0x52=str_constant +hwmon_in.str_cons_0x0307_0x52=cpld + +#slot3 in7 max +hwmon_in.mode_0x0307_0x53=str_constant +hwmon_in.str_cons_0x0307_0x53=4022 + +#slot3 in7 min +hwmon_in.mode_0x0307_0x55=str_constant +hwmon_in.str_cons_0x0307_0x55=3639 + +#slot3 in8 input +hwmon_in.mode_0x0308_0x50=config +hwmon_in.int_cons_0x0308_0x50=0 +hwmon_in.src_0x0308_0x50=cpld +hwmon_in.frmt_0x0308_0x50=num_bytes +hwmon_in.addr_0x0308_0x50=0x0300004f +hwmon_in.len_0x0308_0x50=2 +hwmon_in.int_extra1_0x0308_0x50=0x03000047 +hwmon_in.int_extra2_0x0308_0x50=1240 + +#slot3 in8 alais +hwmon_in.mode_0x0308_0x51=str_constant +hwmon_in.str_cons_0x0308_0x51=SLOT3_VDD1v2 + +#slot3 in8 type +hwmon_in.mode_0x0308_0x52=str_constant +hwmon_in.str_cons_0x0308_0x52=cpld + +#slot3 in8 max +hwmon_in.mode_0x0308_0x53=str_constant +hwmon_in.str_cons_0x0308_0x53=1260 + +#slot3 in8 min +hwmon_in.mode_0x0308_0x55=str_constant +hwmon_in.str_cons_0x0308_0x55=1140 + +#slot3 in9 input +hwmon_in.mode_0x0309_0x50=config +hwmon_in.int_cons_0x0309_0x50=0 +hwmon_in.src_0x0309_0x50=cpld +hwmon_in.frmt_0x0309_0x50=num_bytes +hwmon_in.addr_0x0309_0x50=0x03000051 +hwmon_in.len_0x0309_0x50=2 +hwmon_in.int_extra1_0x0309_0x50=0x03000047 +hwmon_in.int_extra2_0x0309_0x50=2480 + +#slot3 in9 alais +hwmon_in.mode_0x0309_0x51=str_constant +hwmon_in.str_cons_0x0309_0x51=SLOT3_VDD3v3 + +#slot3 in9 type +hwmon_in.mode_0x0309_0x52=str_constant +hwmon_in.str_cons_0x0309_0x52=cpld + +#slot3 in9 max +hwmon_in.mode_0x0309_0x53=str_constant +hwmon_in.str_cons_0x0309_0x53=3539 + +#slot3 in9 min +hwmon_in.mode_0x0309_0x55=str_constant +hwmon_in.str_cons_0x0309_0x55=3135 + +#slot3 in10 input +hwmon_in.mode_0x030a_0x50=config +hwmon_in.int_cons_0x030a_0x50=0 +hwmon_in.src_0x030a_0x50=cpld +hwmon_in.frmt_0x030a_0x50=num_bytes +hwmon_in.addr_0x030a_0x50=0x03000053 +hwmon_in.len_0x030a_0x50=2 +hwmon_in.int_extra1_0x030a_0x50=0x03000047 +hwmon_in.int_extra2_0x030a_0x50=1240 + +#slot3 in10 alais +hwmon_in.mode_0x030a_0x51=str_constant +hwmon_in.str_cons_0x030a_0x51=SLOT3_DVDD_0V8 + +#slot3 in10 type +hwmon_in.mode_0x030a_0x52=str_constant +hwmon_in.str_cons_0x030a_0x52=cpld + +#slot3 in10 max +hwmon_in.mode_0x030a_0x53=str_constant +hwmon_in.str_cons_0x030a_0x53=772 + +#slot3 in10 min +hwmon_in.mode_0x030a_0x55=str_constant +hwmon_in.str_cons_0x030a_0x55=684 + +#slot3 in11 input +hwmon_in.mode_0x030b_0x50=config +hwmon_in.int_cons_0x030b_0x50=0 +hwmon_in.src_0x030b_0x50=cpld +hwmon_in.frmt_0x030b_0x50=num_bytes +hwmon_in.addr_0x030b_0x50=0x03000055 +hwmon_in.len_0x030b_0x50=2 +hwmon_in.int_extra1_0x030b_0x50=0x03000047 +hwmon_in.int_extra2_0x030b_0x50=1240 + +#slot3 in11 alais +hwmon_in.mode_0x030b_0x51=str_constant +hwmon_in.str_cons_0x030b_0x51=SLOT3_VDD1V8_CPLD + +#slot3 in11 type +hwmon_in.mode_0x030b_0x52=str_constant +hwmon_in.str_cons_0x030b_0x52=cpld + +#slot3 in11 max +hwmon_in.mode_0x030b_0x53=str_constant +hwmon_in.str_cons_0x030b_0x53=1909 + +#slot3 in11 min +hwmon_in.mode_0x030b_0x55=str_constant +hwmon_in.str_cons_0x030b_0x55=1710 + +#slot3 in12 input +hwmon_in.mode_0x030c_0x50=config +hwmon_in.int_cons_0x030c_0x50=0 +hwmon_in.src_0x030c_0x50=cpld +hwmon_in.frmt_0x030c_0x50=num_bytes +hwmon_in.addr_0x030c_0x50=0x03000057 +hwmon_in.len_0x030c_0x50=2 +hwmon_in.int_extra1_0x030c_0x50=0x03000047 +hwmon_in.int_extra2_0x030c_0x50=1240 + +#slot3 in12 alais +hwmon_in.mode_0x030c_0x51=str_constant +hwmon_in.str_cons_0x030c_0x51=SLOT3_AVDD0V8 + +#slot3 in12 type +hwmon_in.mode_0x030c_0x52=str_constant +hwmon_in.str_cons_0x030c_0x52=cpld + +#slot3 in12 max +hwmon_in.mode_0x030c_0x53=str_constant +hwmon_in.str_cons_0x030c_0x53=877 + +#slot3 in12 min +hwmon_in.mode_0x030c_0x55=str_constant +hwmon_in.str_cons_0x030c_0x55=776 + +#slot4 in1 input +hwmon_in.mode_0x0401_0x50=config +hwmon_in.int_cons_0x0401_0x50=0 +hwmon_in.src_0x0401_0x50=cpld +hwmon_in.frmt_0x0401_0x50=num_bytes +hwmon_in.addr_0x0401_0x50=0x04000041 +hwmon_in.len_0x0401_0x50=2 +hwmon_in.int_extra1_0x0401_0x50=0x04000047 +hwmon_in.int_extra2_0x0401_0x50=2480 + +#slot4 in1 alais +hwmon_in.mode_0x0401_0x51=str_constant +hwmon_in.str_cons_0x0401_0x51=SLOT4_VDD3v3_QSFP_1 + +#slot4 in1 type +hwmon_in.mode_0x0401_0x52=str_constant +hwmon_in.str_cons_0x0401_0x52=cpld + +#slot4 in1 max +hwmon_in.mode_0x0401_0x53=str_constant +hwmon_in.str_cons_0x0401_0x53=3500 + +#slot4 in1 min +hwmon_in.mode_0x0401_0x55=str_constant +hwmon_in.str_cons_0x0401_0x55=3135 + +#slot4 in2 input +hwmon_in.mode_0x0402_0x50=config +hwmon_in.int_cons_0x0402_0x50=0 +hwmon_in.src_0x0402_0x50=cpld +hwmon_in.frmt_0x0402_0x50=num_bytes +hwmon_in.addr_0x0402_0x50=0x04000043 +hwmon_in.len_0x0402_0x50=2 +hwmon_in.int_extra1_0x0402_0x50=0x04000047 +hwmon_in.int_extra2_0x0402_0x50=2480 + +#slot4 in2 alais +hwmon_in.mode_0x0402_0x51=str_constant +hwmon_in.str_cons_0x0402_0x51=SLOT4_VDD3v3_QSFP_2 + +#slot4 in2 type +hwmon_in.mode_0x0402_0x52=str_constant +hwmon_in.str_cons_0x0402_0x52=cpld + +#slot4 in2 max +hwmon_in.mode_0x0402_0x53=str_constant +hwmon_in.str_cons_0x0402_0x53=3500 + +#slot4 in2 min +hwmon_in.mode_0x0402_0x55=str_constant +hwmon_in.str_cons_0x0402_0x55=3135 + +#slot4 in3 input +hwmon_in.mode_0x0403_0x50=config +hwmon_in.int_cons_0x0403_0x50=0 +hwmon_in.src_0x0403_0x50=cpld +hwmon_in.frmt_0x0403_0x50=num_bytes +hwmon_in.addr_0x0403_0x50=0x04000045 +hwmon_in.len_0x0403_0x50=2 +hwmon_in.int_extra1_0x0403_0x50=0x04000047 +hwmon_in.int_extra2_0x0403_0x50=1240 + +#slot4 in3 alais +hwmon_in.mode_0x0403_0x51=str_constant +hwmon_in.str_cons_0x0403_0x51=SLOT4_VDD1v8 + +#slot4 in3 type +hwmon_in.mode_0x0403_0x52=str_constant +hwmon_in.str_cons_0x0403_0x52=cpld + +#slot4 in3 max +hwmon_in.mode_0x0403_0x53=str_constant +hwmon_in.str_cons_0x0403_0x53=1926 + +#slot4 in3 min +hwmon_in.mode_0x0403_0x55=str_constant +hwmon_in.str_cons_0x0403_0x55=1710 + +#slot4 in4 input +hwmon_in.mode_0x0404_0x50=config +hwmon_in.int_cons_0x0404_0x50=0 +hwmon_in.src_0x0404_0x50=cpld +hwmon_in.frmt_0x0404_0x50=num_bytes +hwmon_in.addr_0x0404_0x50=0x04000047 +hwmon_in.len_0x0404_0x50=2 +hwmon_in.int_extra1_0x0404_0x50=0x04000047 +hwmon_in.int_extra2_0x0404_0x50=1000 + +#slot4 in4 alais +hwmon_in.mode_0x0404_0x51=str_constant +hwmon_in.str_cons_0x0404_0x51=SLOT4_TEST1v24 + +#slot4 in4 type +hwmon_in.mode_0x0404_0x52=str_constant +hwmon_in.str_cons_0x0404_0x52=cpld + +#slot4 in4 max +hwmon_in.mode_0x0404_0x53=str_constant +hwmon_in.str_cons_0x0404_0x53=1302 + +#slot4 in4 min +hwmon_in.mode_0x0404_0x55=str_constant +hwmon_in.str_cons_0x0404_0x55=1178 + +#slot4 in5 input +hwmon_in.mode_0x0405_0x50=config +hwmon_in.int_cons_0x0405_0x50=0 +hwmon_in.src_0x0405_0x50=cpld +hwmon_in.frmt_0x0405_0x50=num_bytes +hwmon_in.addr_0x0405_0x50=0x04000049 +hwmon_in.len_0x0405_0x50=2 +hwmon_in.int_extra1_0x0405_0x50=0x04000047 +hwmon_in.int_extra2_0x0405_0x50=2480 + +#slot4 in5 alais +hwmon_in.mode_0x0405_0x51=str_constant +hwmon_in.str_cons_0x0405_0x51=SLOT4_VDD3v3_CLK + +#slot4 in5 type +hwmon_in.mode_0x0405_0x52=str_constant +hwmon_in.str_cons_0x0405_0x52=cpld + +#slot4 in5 max +hwmon_in.mode_0x0405_0x53=str_constant +hwmon_in.str_cons_0x0405_0x53=3556 + +#slot4 in5 min +hwmon_in.mode_0x0405_0x55=str_constant +hwmon_in.str_cons_0x0405_0x55=3135 + +#slot4 in6 input +hwmon_in.mode_0x0406_0x50=config +hwmon_in.int_cons_0x0406_0x50=0 +hwmon_in.src_0x0406_0x50=cpld +hwmon_in.frmt_0x0406_0x50=num_bytes +hwmon_in.addr_0x0406_0x50=0x0400004b +hwmon_in.len_0x0406_0x50=2 +hwmon_in.int_extra1_0x0406_0x50=0x04000047 +hwmon_in.int_extra2_0x0406_0x50=2480 + +#slot4 in6 alais +hwmon_in.mode_0x0406_0x51=str_constant +hwmon_in.str_cons_0x0406_0x51=SLOT4_VDD5v0 + +#slot4 in6 type +hwmon_in.mode_0x0406_0x52=str_constant +hwmon_in.str_cons_0x0406_0x52=cpld + +#slot4 in6 max +hwmon_in.mode_0x0406_0x53=str_constant +hwmon_in.str_cons_0x0406_0x53=5331 + +#slot4 in6 min +hwmon_in.mode_0x0406_0x55=str_constant +hwmon_in.str_cons_0x0406_0x55=4750 + +#slot4 in7 input +hwmon_in.mode_0x0407_0x50=config +hwmon_in.int_cons_0x0407_0x50=0 +hwmon_in.src_0x0407_0x50=cpld +hwmon_in.frmt_0x0407_0x50=num_bytes +hwmon_in.addr_0x0407_0x50=0x0400004d +hwmon_in.len_0x0407_0x50=2 +hwmon_in.int_extra1_0x0407_0x50=0x04000047 +hwmon_in.int_extra2_0x0407_0x50=2480 + +#slot4 in7 alais +hwmon_in.mode_0x0407_0x51=str_constant +hwmon_in.str_cons_0x0407_0x51=SLOT4_VDD3v7_CLK_MCU + +#slot4 in7 type +hwmon_in.mode_0x0407_0x52=str_constant +hwmon_in.str_cons_0x0407_0x52=cpld + +#slot4 in7 max +hwmon_in.mode_0x0407_0x53=str_constant +hwmon_in.str_cons_0x0407_0x53=4022 + +#slot4 in7 min +hwmon_in.mode_0x0407_0x55=str_constant +hwmon_in.str_cons_0x0407_0x55=3639 + +#slot4 in8 input +hwmon_in.mode_0x0408_0x50=config +hwmon_in.int_cons_0x0408_0x50=0 +hwmon_in.src_0x0408_0x50=cpld +hwmon_in.frmt_0x0408_0x50=num_bytes +hwmon_in.addr_0x0408_0x50=0x0400004f +hwmon_in.len_0x0408_0x50=2 +hwmon_in.int_extra1_0x0408_0x50=0x04000047 +hwmon_in.int_extra2_0x0408_0x50=1240 + +#slot4 in8 alais +hwmon_in.mode_0x0408_0x51=str_constant +hwmon_in.str_cons_0x0408_0x51=SLOT4_VDD1v2 + +#slot4 in8 type +hwmon_in.mode_0x0408_0x52=str_constant +hwmon_in.str_cons_0x0408_0x52=cpld + +#slot4 in8 max +hwmon_in.mode_0x0408_0x53=str_constant +hwmon_in.str_cons_0x0408_0x53=1260 + +#slot4 in8 min +hwmon_in.mode_0x0408_0x55=str_constant +hwmon_in.str_cons_0x0408_0x55=1140 + +#slot4 in9 input +hwmon_in.mode_0x0409_0x50=config +hwmon_in.int_cons_0x0409_0x50=0 +hwmon_in.src_0x0409_0x50=cpld +hwmon_in.frmt_0x0409_0x50=num_bytes +hwmon_in.addr_0x0409_0x50=0x04000051 +hwmon_in.len_0x0409_0x50=2 +hwmon_in.int_extra1_0x0409_0x50=0x04000047 +hwmon_in.int_extra2_0x0409_0x50=2480 + +#slot4 in9 alais +hwmon_in.mode_0x0409_0x51=str_constant +hwmon_in.str_cons_0x0409_0x51=SLOT4_VDD3v3 + +#slot4 in9 type +hwmon_in.mode_0x0409_0x52=str_constant +hwmon_in.str_cons_0x0409_0x52=cpld + +#slot4 in9 max +hwmon_in.mode_0x0409_0x53=str_constant +hwmon_in.str_cons_0x0409_0x53=3539 + +#slot4 in9 min +hwmon_in.mode_0x0409_0x55=str_constant +hwmon_in.str_cons_0x0409_0x55=3135 + +#slot4 in10 input +hwmon_in.mode_0x040a_0x50=config +hwmon_in.int_cons_0x040a_0x50=0 +hwmon_in.src_0x040a_0x50=cpld +hwmon_in.frmt_0x040a_0x50=num_bytes +hwmon_in.addr_0x040a_0x50=0x04000053 +hwmon_in.len_0x040a_0x50=2 +hwmon_in.int_extra1_0x040a_0x50=0x04000047 +hwmon_in.int_extra2_0x040a_0x50=1240 + +#slot4 in10 alais +hwmon_in.mode_0x040a_0x51=str_constant +hwmon_in.str_cons_0x040a_0x51=SLOT4_DVDD_0V8 + +#slot4 in10 type +hwmon_in.mode_0x040a_0x52=str_constant +hwmon_in.str_cons_0x040a_0x52=cpld + +#slot4 in10 max +hwmon_in.mode_0x040a_0x53=str_constant +hwmon_in.str_cons_0x040a_0x53=772 + +#slot4 in10 min +hwmon_in.mode_0x040a_0x55=str_constant +hwmon_in.str_cons_0x040a_0x55=684 + +#slot4 in11 input +hwmon_in.mode_0x040b_0x50=config +hwmon_in.int_cons_0x040b_0x50=0 +hwmon_in.src_0x040b_0x50=cpld +hwmon_in.frmt_0x040b_0x50=num_bytes +hwmon_in.addr_0x040b_0x50=0x04000055 +hwmon_in.len_0x040b_0x50=2 +hwmon_in.int_extra1_0x040b_0x50=0x04000047 +hwmon_in.int_extra2_0x040b_0x50=1240 + +#slot4 in11 alais +hwmon_in.mode_0x040b_0x51=str_constant +hwmon_in.str_cons_0x040b_0x51=SLOT4_VDD1V8_CPLD + +#slot4 in11 type +hwmon_in.mode_0x040b_0x52=str_constant +hwmon_in.str_cons_0x040b_0x52=cpld + +#slot4 in11 max +hwmon_in.mode_0x040b_0x53=str_constant +hwmon_in.str_cons_0x040b_0x53=1909 + +#slot4 in11 min +hwmon_in.mode_0x040b_0x55=str_constant +hwmon_in.str_cons_0x040b_0x55=1710 + +#slot4 in12 input +hwmon_in.mode_0x040c_0x50=config +hwmon_in.int_cons_0x040c_0x50=0 +hwmon_in.src_0x040c_0x50=cpld +hwmon_in.frmt_0x040c_0x50=num_bytes +hwmon_in.addr_0x040c_0x50=0x04000057 +hwmon_in.len_0x040c_0x50=2 +hwmon_in.int_extra1_0x040c_0x50=0x04000047 +hwmon_in.int_extra2_0x040c_0x50=1240 + +#slot4 in12 alais +hwmon_in.mode_0x040c_0x51=str_constant +hwmon_in.str_cons_0x040c_0x51=SLOT4_AVDD0V8 + +#slot4 in12 type +hwmon_in.mode_0x040c_0x52=str_constant +hwmon_in.str_cons_0x040c_0x52=cpld + +#slot4 in12 max +hwmon_in.mode_0x040c_0x53=str_constant +hwmon_in.str_cons_0x040c_0x53=877 + +#slot4 in12 min +hwmon_in.mode_0x040c_0x55=str_constant +hwmon_in.str_cons_0x040c_0x55=776 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/cfg_file_name new file mode 100755 index 000000000000..d31debee1cd2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,6 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF +WB_PLAT_SENSOR +WB_PLAT_SLOT diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/scripts/pddf_post_device_create.sh b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/scripts/pddf_post_device_create.sh deleted file mode 100755 index 952e034c5b5e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/scripts/pddf_post_device_create.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# create tmp411 device -function create_tmp411() -{ - bus=$1 - addr=$2 - if [ -d "/sys/bus/i2c/devices/i2c-${bus}" ] - then - echo "tmp411 ${addr}" > /sys/bus/i2c/devices/i2c-${bus}/new_device - fi -} - -create_tmp411 "28" "0x4c" -create_tmp411 "29" "0x4c" - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py old mode 100644 new mode 100755 index f36055fb4e6d..6c3916921abb --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py +++ b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/setup.py @@ -3,18 +3,25 @@ setup( name='sonic-platform', version='1.0', - description='SONiC platform API implementation on RAGILE Platforms', + description='SONiC platform API implementation', license='Apache 2.0', author='SONiC Team', - author_email='support@ragile.com', + author_email='support', url='', - maintainer='RAGILE SUPPORT TEAM', + maintainer='support', maintainer_email='', packages=[ 'sonic_platform', - 'rgutil', + 'plat_hal', + 'wbutil', 'eepromutil', - 'sonic_pcie', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', ], classifiers=[ 'Development Status :: 3 - Alpha', @@ -30,4 +37,3 @@ ], keywords='sonic SONiC platform PLATFORM', ) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_pcie/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_pcie/__init__.py deleted file mode 100644 index 73e2a89c8d74..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_pcie/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["pcie_common"] \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_pcie/pcie_common.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_pcie/pcie_common.py deleted file mode 100644 index 56e9d8664a23..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_pcie/pcie_common.py +++ /dev/null @@ -1,107 +0,0 @@ -# pcie_common.py -# Common PCIE check interfaces for SONIC -# - -import os -import yaml -import subprocess -import re -import sys -from copy import deepcopy -try: - from .pcie import PcieBase -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class PcieUtil(PcieBase): - """Platform-specific PCIEutil class""" - # got the config file path - def __init__(self, path): - self.config_path = path - - # load the config file - def load_config_file(self): - config_file = self.config_path + "/" + "pcie.yaml" - try: - with open(config_file) as conf_file: - self.confInfo = yaml.load(conf_file) - except IOError as e: - print("Error: {}".format(str(e))) - print("Not found config file, please add a config file manually, or generate it by running [pcieutil pcie_generate]") - sys.exit() - - # load current PCIe device - def get_pcie_device(self): - pciDict = {} - pciList = [] - p1 = "^(\w+):(\w+)\.(\w)\s(.*)\s*\(*.*\)*" - p2 = "^.*:.*:.*:(\w+)\s*\(*.*\)*" - command1 = "sudo lspci" - command2 = "sudo lspci -n" - # run command 1 - proc1 = subprocess.Popen(command1, shell=True, universal_newlines=True, stdout=subprocess.PIPE) - output1 = proc1.stdout.readlines() - proc1.communicate() - # run command 2 - proc2 = subprocess.Popen(command2, shell=True, universal_newlines=True, stdout=subprocess.PIPE) - output2 = proc2.stdout.readlines() - proc2.communicate() - - if proc1.returncode > 0: - for line1 in output1: - print(line1.strip()) - return - elif proc2.returncode > 0: - for line2 in output2: - print(line2.strip()) - return - else: - for (line1, line2) in zip(output1, output2): - pciDict.clear() - match1 = re.search(p1, line1.strip()) - match2 = re.search(p2, line2.strip()) - if match1 and match2: - Bus = match1.group(1) - Dev = match1.group(2) - Fn = match1.group(3) - Name = match1.group(4) - Id = match2.group(1) - pciDict["name"] = Name - pciDict["bus"] = Bus - pciDict["dev"] = Dev - pciDict["fn"] = Fn - pciDict["id"] = Id - pciList.append(pciDict) - pciDict = deepcopy(pciDict) - else: - print("CAN NOT MATCH PCIe DEVICE") - return pciList - - # check the sysfs tree for each PCIe device - def check_pcie_sysfs(self, domain=0, bus=0, device=0, func=0): - dev_path = os.path.join('/sys/bus/pci/devices', '%04x:%02x:%02x.%d' % (domain, bus, device, func)) - if os.path.exists(dev_path): - return True - return False - - # check the current PCIe device with config file and return the result - def get_pcie_check(self): - self.load_config_file() - for item_conf in self.confInfo: - bus_conf = item_conf["bus"] - dev_conf = item_conf["dev"] - fn_conf = item_conf["fn"] - if self.check_pcie_sysfs(bus=int(bus_conf, base=16), device=int(dev_conf, base=16), func=int(fn_conf, base=16)): - item_conf["result"] = "Passed" - else: - item_conf["result"] = "Failed" - return self.confInfo - - # generate the config file with current pci device - def dump_conf_yaml(self): - curInfo = self.get_pcie_device() - with open(self.config_path + "/" + "pcie.yaml", "w") as conf_file: - yaml.dump(curInfo, conf_file, default_flow_style=False) - return - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/__init__.py deleted file mode 100644 index d49ca9b48bbf..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# All the derived classes for PDDF -__all__ = ["platform", "chassis", "sfp", "psu", "thermal", "fan", "fan_drawer"] -from . import platform - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/chassis.py deleted file mode 100644 index 5d428f668567..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/chassis.py +++ /dev/null @@ -1,108 +0,0 @@ -############################################################################# -# PDDF -# Module contains an implementation of SONiC Chassis API -# -############################################################################# - -try: - import time - from sonic_platform_pddf_base.pddf_chassis import PddfChassis - from sonic_platform.fan_drawer import FanDrawer -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -PORT_START = 0 -PORTS_IN_BLOCK = 128 -FAN_NUM_PER_DRAWER = 2 - -class Chassis(PddfChassis): - """ - PDDF Platform-specific Chassis class - """ - - SFP_STATUS_INSERTED = "1" - SFP_STATUS_REMOVED = "0" - port_dict = {} - - def __init__(self, pddf_data=None, pddf_plugin_data=None): - PddfChassis.__init__(self, pddf_data, pddf_plugin_data) - - # fan drawer - temp = [] - drawer_index = 0 - for idx, fan in enumerate(self.get_all_fans()): - temp.append(fan) - if (idx + 1) % FAN_NUM_PER_DRAWER == 0: - drawer = FanDrawer(drawer_index + 1, temp) - self.get_all_fan_drawers().append(drawer) - temp = [] - drawer_index += 1 - - 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. - """ - - return (self.REBOOT_CAUSE_NON_HARDWARE, None) - - def get_change_event(self, timeout=0): - change_event_dict = {"fan": {}, "sfp": {}} - sfp_status, sfp_change_dict = self.get_transceiver_change_event(timeout) - change_event_dict["sfp"] = sfp_change_dict - if sfp_status is True: - return True, change_event_dict - - return False, {} - - def get_transceiver_change_event(self, timeout=0): - start_time = time.time() - currernt_port_dict = {} - forever = False - - if timeout == 0: - forever = True - elif timeout > 0: - timeout = timeout / float(1000) # Convert to secs - else: - print("get_transceiver_change_event:Invalid timeout value", timeout) - return False, {} - - end_time = start_time + timeout - if start_time > end_time: - print( - "get_transceiver_change_event:" "time wrap / invalid timeout value", - timeout, - ) - return False, {} # Time wrap or possibly incorrect timeout - - while timeout >= 0: - # Check for OIR events and return updated port_dict - for index in range(PORT_START, PORTS_IN_BLOCK): - if self._sfp_list[index].get_presence(): - currernt_port_dict[index] = self.SFP_STATUS_INSERTED - else: - currernt_port_dict[index] = self.SFP_STATUS_REMOVED - if currernt_port_dict == self.port_dict: - if forever: - time.sleep(1) - else: - timeout = end_time - time.time() - if timeout >= 1: - time.sleep(1) # We poll at 1 second granularity - else: - if timeout > 0: - time.sleep(timeout) - return True, {} - else: - # Update reg value - self.port_dict = currernt_port_dict - print(self.port_dict) - return True, self.port_dict - print("get_transceiver_change_event: Should not reach here.") - return False, {} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/common.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/common.py deleted file mode 100644 index c1a85f618609..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/common.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -import yaml - -from sonic_py_common import device_info - - -class Common: - - DEVICE_PATH = '/usr/share/sonic/device/' - PMON_PLATFORM_PATH = '/usr/share/sonic/platform/' - CONFIG_DIR = 'sonic_platform_config' - - HOST_CHK_CMD = "docker > /dev/null 2>&1" - - def __init__(self): - (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() - - def is_host(self): - return os.system(self.HOST_CHK_CMD) == 0 - - def load_json_file(self, path): - """ - Retrieves the json object from json file path - - Returns: - A json object - """ - with open(path, 'r') as f: - json_data = yaml.safe_load(f) - - return json_data - - def get_config_path(self, config_name): - """ - Retrieves the path to platform api config directory - - Args: - config_name: A string containing the name of config file. - - Returns: - A string containing the path to json file - """ - return os.path.join(self.DEVICE_PATH, self.platform, self.CONFIG_DIR, config_name) if self.is_host() else os.path.join(self.PMON_PLATFORM_PATH, self.CONFIG_DIR, config_name) - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/component.py deleted file mode 100644 index 7c6fd2df4335..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/component.py +++ /dev/null @@ -1,85 +0,0 @@ -######################################################################## -# Ragile RA-B6510-32c -# -# Module contains an implementation of SONiC Platform Base API and -# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in -# the platform -# -######################################################################## - -try: - import subprocess - from sonic_platform_base.component_base import ComponentBase - from sonic_platform.regutil import Reg - from sonic_platform.logger import logger -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Component(ComponentBase): - """ Ragile Platform-specific Component class""" - - def __init__(self, index, config=None): - self.index = index - self.name = config.get("name") - self._reg_fm_ver = Reg(config.get("firmware_version")) - self.description = config.get("desc") - self.slot = config.get("slot") - - 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 - """ - return self.description - - def get_firmware_version(self): - """ - Retrieves the firmware version of the component - - Returns: - A string containing the firmware version of the component - """ - try: - return self._reg_fm_ver.decode() - except Exception as e: - logger.error(str(e)) - - return "" - - def install_firmware(self, image_path): - """ - Installs firmware to the component - - Args: - image_path: A string, path to firmware image - - Returns: - A boolean, True if install was successful, False if not - """ - try: - successtips = "CPLD Upgrade succeeded!" - status, output = subprocess.getstatusoutput("which firmware_upgrade") - if status or len(output) <= 0: - logger.error("no upgrade tool.") - return False - cmdstr = "%s %s cpld %d cpld"%(output,image_path,self.slot) - ret, log = subprocess.getstatusoutput(cmdstr) - if ret == 0 and successtips in log: - return True - logger.error("upgrade failed. ret:%d, log:\n%s" % (ret, log)) - except Exception as e: - logger.error(str(e)) - return False - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/config.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/config.py deleted file mode 100644 index 7d3064163b30..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/config.py +++ /dev/null @@ -1,771 +0,0 @@ -# -*- coding: utf-8 -*- - -PSU_FAN_AIRFLOW = { - "CSU550AP-3-300": "F2B", - "CSU550AP-3-500": "F2B", - "DPS-550AB-39 A": "F2B", - "DPS-1300AB-6 S": "F2B", - "FSP1200-20ERM": "F2B", - "CSU800AP-3-300": "F2B", - "CSU550AP-3-501": "B2F", - "DPS-550AB-40 A": "B2F", -} - -psutypedecode = { - 0x00: "N/A", - 0x01: "AC", - 0x02: "DC", -} - - -class Unit: - Temperature = "C" - Voltage = "V" - Current = "A" - Power = "W" - Speed = "RPM" - - -class Threshold: - PSU_TEMP_MIN = -10 * 1000 - PSU_TEMP_MAX = 60 * 1000 - - PSU_FAN_SPEED_MIN = 5220 - PSU_FAN_SPEED_MAX = 17400 - - PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 - PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 - - PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 - PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 - - PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 - PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 - - ERR_VALUE = -9999999 - - PSU_OUTPUT_POWER_MIN = 10 * 1000 - PSU_OUTPUT_POWER_MAX = 1300 * 1000 - - PSU_INPUT_POWER_MIN = 10 * 1000 - PSU_INPUT_POWER_MAX = 1444 * 1000 - - PSU_OUTPUT_CURRENT_MIN = 2 * 1000 - PSU_OUTPUT_CURRENT_MAX = 107 * 1000 - - PSU_INPUT_CURRENT_MIN = 0.2 * 1000 - PSU_INPUT_CURRENT_MAX = 7 * 1000 - - FAN_SPEED_MAX = 24000 - FAN_SPEED_MIN = 7200 - - -class DecodeFormat: - TEXT = 0 - DECIMAL = 1 - ONE_BIT_HEX = 2 - HUNDREDTH = 3 - THOUSANDTH = 4 - MILLIONTH = 5 - AND = 6 - JOIN = 7 - FRU = 8 - HEX = 9 - - -class DecodeMethod: - SYSFS = 0 - I2C = 1 - I2C_WORD = 2 - DEVMEM = 3 - SDK = 4 - IO = 5 - FRU = 6 - - -class FRU: - SN = 0 - VERSION = 1 - PART_NAME = 2 - PRODUCT_NAME = 3 - MANUFACTURER = 4 - - -class Description: - CPLD = "Used for managing IO modules, SFP+ modules and system LEDs" - BIOS = "Performs initialization of hardware components during booting" - FPGA = "Platform management controller for on-board temperature monitoring, in-chassis power, Fan and LED control" - - -FAN_LED_COLORS = { - "green": 0b0100, - "red": 0b0010, - "amber": 0b0110, -} - - -DEVICE_CONF = { - "eeprom": {"bus": 1, "loc": "0056"}, - "components": [ - { - "name": "CPLD1 (MAC Board A)", - "firmware_version": { - "bus": 8, - "addr": 0x30, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 0, - }, - { - "name": "CPLD2 (MAC Board B)", - "firmware_version": { - "bus": 8, - "addr": 0x31, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 0, - }, - { - "name": "CPLD3 (CONNECT Board A)", - "firmware_version": { - "bus": 2, - "addr": 0x0d, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 0, - }, - { - "name": "CPLD4 (CPU Board)", - "firmware_version": { - "bus": 0, - "addr": 0x0D, - "offset": 0, - "size": 4, - "way": DecodeMethod.I2C, - "format": DecodeFormat.JOIN, - "sep": "/", - }, - "desc": Description.CPLD, - "slot": 1, - }, - ], - "thermals": [ - { - "name": "INLET TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/3-004b/hwmon/*/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": None, - "temperature": { - "loc": "/sys/bus/i2c/devices/3-004b/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "OUTLET TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/3-004c/hwmon/*/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": None, - "temperature": { - "loc": "/sys/bus/i2c/devices/3-004c/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "BOARD TEMP", - "high": { - "loc": "/sys/bus/i2c/devices/3-0049/hwmon/*/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": None, - "temperature": { - "loc": "/sys/bus/i2c/devices/3-0049/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "PHYSICAL ID 0", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp1_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp1_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 0", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp2_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp2_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp2_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 1", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp3_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp3_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp3_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 2", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp4_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp4_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp4_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - { - "name": "CPU CORE 3", - "high": { - "loc": "/sys/class/hwmon/hwmon0/temp5_max", - "format": DecodeFormat.THOUSANDTH, - }, - "low": None, - "crit_low": None, - "crit_high": { - "loc": "/sys/class/hwmon/hwmon0/temp5_crit", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/class/hwmon/hwmon0/temp5_input", - "format": DecodeFormat.THOUSANDTH, - }, - }, - ], - "fans": [ - { - "name": "fan1", - "e2loc": {"bus": 16, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 0, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 0, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/16-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/16-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan1_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - { - "name": "fan2", - "e2loc": {"bus": 17, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/17-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/17-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan2_speed_set", - "format": DecodeFormat.HEX, - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - { - "name": "fan3", - "e2loc": {"bus": 18, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 2, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 2, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/18-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/18-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan3_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - { - "name": "fan4", - "e2loc": {"bus": 19, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 3, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 3, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/19-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/19-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan4_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - { - "name": "fan5", - "e2loc": {"bus": 20, "addr": 0x50, "way": "i2c", "size": "256"}, - "present": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_present", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 4, - }, - "status": { - "loc": "/sys/bus/i2c/devices/2-000d/fan_status", - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 4, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/20-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - "sn": { - "loc": "/sys/bus/i2c/devices/20-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "led": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_led", - "format": DecodeFormat.AND, - "mask": 0b1111, - }, - "led_colors": FAN_LED_COLORS, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_1_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - }, - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_2_real_speed" - }, - "speed_setter": { - "loc": "/sys/bus/i2c/devices/2-000d/fan5_speed_set", - "format": DecodeFormat.HEX - }, - "speed_max": Threshold.FAN_SPEED_MAX, - "slope": 236.51, - "intercept": 82.571, - } - ], - "tolerance": 20, - "threshold": 30, - "target_default": 0, - }, - ], - "psus": [ - { - "name": "psu1", - "present": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 0, - "way": DecodeMethod.IO - }, - "status": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - "way": DecodeMethod.IO - }, - "sn": { - "loc": "/sys/bus/i2c/devices/24-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "in_current": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/curr1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "in_voltage": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/in1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_voltage": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/in2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_current": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/curr2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/24-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - # "psu_type": { - # "loc": "/sys/bus/i2c/devices/24-0050/eeprom", - # "format": DecodeFormat.FRU, - # "fru_key": FRU.SN - # }, - "fans": [ - { - "name": "psu_fan1", - "present": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/fan1_fault", - }, - "status": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 1, - "way": DecodeMethod.IO - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/fan1_input" - }, - "speed_setter": { - "bus": 24, - "addr": 0x58, - "offset": 0x3b, - "size": 1, - "way": DecodeMethod.I2C, - "format": DecodeFormat.HEX, - }, - "speed_max": Threshold.PSU_FAN_SPEED_MAX, - } - ], - "tolerance": 20, - "threshold_low": 1900, - } - ], - "in_power": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/power1_input", - "format": DecodeFormat.MILLIONTH, - }, - "out_power": { - "loc": "/sys/bus/i2c/devices/24-0058/hwmon/*/power2_input", - "format": DecodeFormat.MILLIONTH, - }, - }, - { - "name": "psu2", - "present": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 4, - "way": DecodeMethod.IO - }, - "status": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 5, - "way": DecodeMethod.IO - }, - "sn": { - "loc": "/sys/bus/i2c/devices/25-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.SN - }, - "in_current": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/curr1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "in_voltage": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/in1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_voltage": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/in2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "out_current": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/curr2_input", - "format": DecodeFormat.THOUSANDTH, - }, - "temperature": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/temp1_input", - "format": DecodeFormat.THOUSANDTH, - }, - "hw_version": { - "loc": "/sys/bus/i2c/devices/25-0050/eeprom", - "format": DecodeFormat.FRU, - "fru_key": FRU.VERSION - }, - # "psu_type": {"loc": "/sys/bus/i2c/devices/8-0053/psu_type"}, - "fans": [ - { - "name": "psu_fan1", - "present": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/fan1_fault", - }, - "status": { - "addr": 0x951, - "format": DecodeFormat.ONE_BIT_HEX, - "bit": 5, - "way": DecodeMethod.IO - }, - "rotors": [ - { - "speed_getter": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/fan1_input" - }, - "speed_setter": { - "bus": 25, - "addr": 0x58, - "offset": 0x3b, - "size": 1, - "way": DecodeMethod.I2C, - "format": DecodeFormat.HEX, - }, - "speed_max": Threshold.PSU_FAN_SPEED_MAX, - } - ], - "tolerance": 20, - "threshold_low": 1900, - } - ], - "in_power": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/power1_input", - "format": DecodeFormat.MILLIONTH, - }, - "out_power": { - "loc": "/sys/bus/i2c/devices/25-0058/hwmon/*/power2_input", - "format": DecodeFormat.MILLIONTH, - }, - }, - ], -} diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/eeprom.py deleted file mode 100644 index c25d711354f5..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/eeprom.py +++ /dev/null @@ -1,12 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_eeprom import PddfEeprom -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Eeprom(PddfEeprom): - - def __init__(self, pddf_data=None, pddf_plugin_data=None): - PddfEeprom.__init__(self, 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-ragile/ra-b6920-4s/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/fan.py deleted file mode 100644 index 14895ec47e3f..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/fan.py +++ /dev/null @@ -1,42 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_fan import PddfFan -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -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) - - # Provide the functions/variables below for which implementation is to be overwritten - # Since psu_fan airflow direction cant be read from sysfs, it is fixed as 'F2B' or 'intake' - def get_direction(self): - """ - Retrieves the direction of fan - - Returns: - A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST - depending on fan direction - """ - return self.FAN_DIRECTION_EXHAUST - - def get_speed_rpm(self): - if self.is_psu_fan: - return int(round(super().get_speed_rpm())) - else: - divisor = 15000000 - mask_low = 0xff - ret = super().get_speed_rpm() - # revert ret - ret = (ret >> 8) + ((ret & mask_low) << 8) - return int(round(divisor/ret)) - - def get_target_speed(self): - if self.is_psu_fan: - return None - - return super().get_target_speed() - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/fan_drawer.py deleted file mode 100644 index 2f83b66df94a..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/fan_drawer.py +++ /dev/null @@ -1,69 +0,0 @@ -# -# fan_drawer -# - -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): - # Device type definition. Note, this is a constant. - DEVICE_TYPE = "fan_drawer" - - def __init__(self, index, fan_list): - FanDrawerBase.__init__(self) - - self._fan_list = fan_list - self._index = index - - def get_name(self): - """ - Retrieves the name of the device - Returns: - string: The name of the device - """ - - return "fan drawer {}".format(self._index) - - def get_num_fans(self): - """ - Retrieves the number of fans available on this fan drawer - Returns: - An integer, the number of fan modules available on this fan drawer - """ - return len(self._fan_list) - - def get_all_fans(self): - """ - Retrieves all fan modules available on this fan drawer - Returns: - A list of objects derived from FanBase representing all fan - modules available on this fan drawer - """ - return self._fan_list - - 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 - """ - if self.get_num_fans() > 0: - return self._fan_list[0].set_status_led(color) - return False - - 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 - """ - if self.get_num_fans() > 0: - return self._fan_list[0].get_status_led() - return "N/A" - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/logger.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/logger.py deleted file mode 100644 index 5969781bf9a9..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/logger.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- - -import logging - - -def _init_logger(): - formatter = logging.Formatter( - "%(asctime)s %(levelname)s %(filename)s[%(funcName)s][%(lineno)s]: %(message)s" - ) - handler = logging.FileHandler("/var/log/syslog") - handler.setFormatter(formatter) - - logger = logging.getLogger(__name__) - logger.setLevel(logging.DEBUG) - logger.addHandler(handler) - return logger - - -logger = _init_logger() diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/pcie.py deleted file mode 100644 index 5a66997d33d0..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/pcie.py +++ /dev/null @@ -1,43 +0,0 @@ -# -# pcie_base.py -# -# Abstract base class for implementing platform-specific -# PCIE functionality for SONiC -# - -try: - import abc - from sonic_pcie import PcieUtil -except ImportError as e: - raise ImportError (str(e) + " - required module not found") - -class PcieBase(object): - def __init__(self, path): - """ - Constructor - Args: - pcieutil file and config file path - """ - self.pcie_util = PcieUtil(path) - - - @abc.abstractmethod - def get_pcie_device(self): - """ - get current device pcie info - - Returns: - A list including pcie device info - """ - return self.pcie_util.get_pcie_device() - - - @abc.abstractmethod - def get_pcie_check(self): - """ - Check Pcie device with config file - Returns: - A list including pcie device and test result info - """ - return self.pcie_util.get_pcie_check() - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/psu.py deleted file mode 100644 index 57dd5117a2c4..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/psu.py +++ /dev/null @@ -1,32 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_psu import PddfPsu -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - - -class Psu(PddfPsu): - """PDDF Platform-Specific PSU class""" - - PLATFORM_PSU_CAPACITY = 1200 - - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfPsu.__init__(self, index, pddf_data, pddf_plugin_data) - - # Provide the functions/variables below for which implementation is to be overwritten - def get_maximum_supplied_power(self): - """ - Retrieves the maximum supplied power by PSU (or PSU capacity) - Returns: - A float number, the maximum power output in Watts. - e.g. 1200.1 - """ - return float(self.PLATFORM_PSU_CAPACITY) - - def get_type(self): - """ - Gets the type of the PSU - Returns: - A string, the type of PSU (AC/DC) - """ - return "DC" - diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/regutil.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/regutil.py deleted file mode 100644 index bff2bd41ea55..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/regutil.py +++ /dev/null @@ -1,245 +0,0 @@ -# -*- coding: utf-8 -*- -from glob import glob -from plat_hal.osutil import osutil - -try: - from sonic_platform.config import DecodeFormat, DecodeMethod - - DECODE_FORMAT = DecodeFormat - DECODE_METHOD = DecodeMethod -except ImportError: - raise ImportError(str(e) + "- required module not found") - -ERR_CODE = "ERR" - - -class Reg(object): - """ - "e2loc": {"bus": 3, "addr": 0x53, "way": "i2c"} - "value": { - "loc": "/sys/bus/i2c/devices/2-0048/hwmon/hwmon*/temp1_input", - "way": "sysfs", - - "InputsStatus": { - "bus": 8, - "addr": 0x5B, - "offset": 0x79, - "way": "i2cword", - "mask": 0x0200, - }, - """ - - def __new__(cls, *args): - if args[0] is None or not isinstance(args[0], dict): - return None - return super(Reg, cls).__new__(cls) - - def __init__(self, data): - - self.loc = None - self.way = DECODE_METHOD.SYSFS - self.addr = None - self.bus = None - self.offset = None - self.size = 1 - self.bit = None - self.mask = None - self.digit = None - self.sdk_type = None - self.sep = None - self.format = DECODE_FORMAT.TEXT - self.__dict__.update(data) - - def _read_reg_val(self): - ret = None - try: - if self.way == DECODE_METHOD.SYSFS: - ret = self.get_sysfs() - elif self.way == DECODE_METHOD.I2C: - ret = self.get_i2c() - elif self.way == DECODE_METHOD.I2C_WORD: - ret = self.get_i2cword() - elif self.way == DECODE_METHOD.DEVMEM: - ret = self.get_devmem() - elif self.way == DECODE_METHOD.SDK: - # TODO - pass - else: - pass - except Exception as e: - raise e - - return ret - - def _write_reg_val(self, val): - try: - if self.way == DECODE_METHOD.SYSFS: - return self._write_sysfs(val) - except Exception as e: - raise e - - return False - - def _write_sysfs(self, val): - try: - with open(glob(self.loc)[0], "w") as f: - f.write(val) - f.flush() - return True - except Exception as e: - raise e - - def _format_val(self, val): - try: - if isinstance(val, str): - val = val.strip() - if self.format == DECODE_FORMAT.THOUSANDTH: - return float("%.1f" % (float(val) / 1000)) - elif self.format == DECODE_FORMAT.HUNDREDTH: - return float("%.1f" % (float(val) / 100)) - elif self.format == DECODE_FORMAT.ONE_BIT_HEX: - return (int(val, 16) & (1 << self.bit)) >> self.bit - elif self.format == DECODE_FORMAT.DECIMAL: - return int(val, 10) - elif self.format == DECODE_FORMAT.MILLIONTH: - return float("%.1f" % (float(val) / 1000 / 1000)) - elif self.format == DECODE_FORMAT.AND: - return (int(val, 16)) & self.mask - elif isinstance(val, list): - if self.format == DECODE_FORMAT.JOIN: - return self.sep.join(val) - except Exception as e: - raise e - else: - return val - - def decode(self): - """ - get value by config way - way i2c/sysfs/lpc - """ - if self.way is None: - raise ValueError("cannot found way to deal") - - ret = self._read_reg_val() - - ret = self._format_val(ret) - return ret - - def encode(self, val): - if self.way is None: - raise ValueError("cannot found way to deal") - - return self._write_reg_val(val) - - def get_sdk(self): - # TODO - pass - - def get_sysfs(self): - if self.loc is None: - raise ValueError("Not Enough Attr: loc: {}".format(self.loc)) - - ret, val = osutil.readsysfs(self.loc) - - if not ret: - raise IOError(val) - - return val - - def get_devmem(self): - if self.addr is None or self.digit is None or self.mask is None: - raise ValueError( - "Not Enough Attr: addr: {}, digit: {}, mask: {}".format( - self.addr, self.digit, self.mask - ) - ) - - ret, val = osutil.getdevmem(self.addr, self.digit, self.mask) - - if not ret: - raise IOError(val) - - return val - - def get_i2cword(self): - if self.bus is None or self.addr is None or self.offset is None: - raise ValueError( - "Not Enough Attr: bus: {}, addr: {}, offset: {}".format( - self.bus, self.addr, self.offset - ) - ) - - ret, val = osutil.geti2cword(self.bus, self.addr, self.offset) - - if not ret: - raise IOError(val) - - return val - - def get_i2c(self): - if ( - self.bus is None - or self.addr is None - or self.offset is None - or self.size is None - ): - raise ValueError( - "Not Enough Attr: bus: {}, addr: {}, offset: {}".format( - self.bus, self.addr, self.offset - ) - ) - - value = [] - for i in range(self.size): - ofs = self.offset + i - ret, val = osutil.rji2cget(self.bus, self.addr, ofs) - - if not ret: - raise IOError(val) - else: - value.append(repr(chr(val)).translate(None, r"\\x").replace("'", "")) - - return value - - def set_i2cword(self, bus, addr, offset, byte): - return self.seti2cword(bus, addr, offset, byte) - - def seti2cword(self, bus, addr, offset, byte): - return osutil.seti2cword(bus, addr, offset, byte) - - def set_i2c(self, bus, addr, offset, byte): - return self.seti2c(bus, addr, offset, byte) - - def seti2c(self, bus, addr, offset, byte): - ret, val = osutil.rji2cset(bus, addr, offset, byte) - return ret, val - - def getbcmtemp(self): - try: - sta, ret = osutil.getmactemp() - if sta == True: - mac_aver = float(ret.get("average", self.__error_ret)) - #mac_max = float(ret.get("maximum", self.__error_ret)) - mac_aver = mac_aver * 1000 - #mac_max = mac_max * 1000 - else: - return False, ret - except AttributeError as e: - return False, str(e) - return True, mac_aver - - def getbcmreg(self, reg): - ret, val = osutil.getsdkreg(reg) - return ret, val - - def logger_debug(self, msg): - baseutil.logger_debug(msg) - - def command(self, cmd): - ret, output = osutil.command(cmd) - return ret, output - - def set_val(self, val): - # TODO - pass diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/rotor.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/rotor.py deleted file mode 100644 index 3e5bcc5b9b9a..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/rotor.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- - -try: - from sonic_platform.regutil import Reg - from sonic_platform.logger import logger -except ImportError: - raise ImportError(str(e) + "- required module not found") - -class Rotor: - def __init__(self, config): - if config is not None and isinstance(config, dict): - self.__reg_speed_getter = Reg(config.get("speed_getter")) - self.__reg_speed_setter = Reg(config.get("speed_setter")) - self.__speed_max = config.get("speed_max") - else: - raise ValueError("init rotor Error: {}".format(config)) - - def get_speed(self): - try: - return int(self.__reg_speed_getter.decode()) - except Exception as e: - logger.error(str(e)) - - return 0 - - def set_speed(self, speed): - try: - return self.__reg_speed_setter.encode(speed) - except Exception as e: - logger.error(str(e)) - - return False - - def get_speed_percentage(self): - try: - speed = self.get_speed() - return (100 * speed) / self.__speed_max - except Exception as e: - logger.error(str(e)) - - return 0 diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/sfp.py deleted file mode 100644 index ea8e256fe6ef..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/sfp.py +++ /dev/null @@ -1,287 +0,0 @@ -#!/usr/bin/env python - -try: - #from sonic_platform_pddf_base.pddf_sfp import * - from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId - from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom - from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId - from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom - from sonic_platform_pddf_base.pddf_sfp import PddfSfp - from sonic_platform_pddf_base.pddf_sfp import SFP_VOLT_OFFSET - from sonic_platform_pddf_base.pddf_sfp import SFP_VOLT_WIDTH - from sonic_platform_pddf_base.pddf_sfp import SFP_CHANNL_MON_OFFSET - from sonic_platform_pddf_base.pddf_sfp import SFP_CHANNL_MON_WIDTH - from sonic_platform_pddf_base.pddf_sfp import SFP_TEMPE_OFFSET - from sonic_platform_pddf_base.pddf_sfp import SFP_TEMPE_WIDTH - from sonic_platform_pddf_base.pddf_sfp import QSFP_DOM_REV_OFFSET - from sonic_platform_pddf_base.pddf_sfp import QSFP_DOM_REV_WIDTH - from sonic_platform_pddf_base.pddf_sfp import QSFP_CHANNL_MON_OFFSET - from sonic_platform_pddf_base.pddf_sfp import QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - -XCVR_DOM_CAPABILITY_OFFSET = 92 -XCVR_DOM_CAPABILITY_WIDTH = 2 -QSFP_VERSION_COMPLIANCE_OFFSET = 1 -QSFP_VERSION_COMPLIANCE_WIDTH = 2 -QSFP_OPTION_VALUE_OFFSET = 192 -QSFP_OPTION_VALUE_WIDTH = 4 - -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) - self.dom_supported = False - self.__dom_capability_detect() - - def __dom_capability_detect(self): - 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.qsfp_page3_available = False - self.calibration = 0 - if not self.get_presence(): - return - - if self.is_osfp_port: - # Not implement - return - elif self.is_qsfp_port: - 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 - else: - 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) - - # Provide the functions/variables below for which implementation is to be overwritten - - def __read_eeprom_specific_bytes(self, offset, num_bytes): - eeprom_raw = [] - if not self.get_presence(): - return None - for i in range(0, num_bytes): - eeprom_raw.append("0x00") - - try: - with open(self.eeprom_path, mode="rb", buffering=0) as eeprom: - eeprom.seek(offset) - raw = eeprom.read(num_bytes) - except Exception as e: - print("Error: Unable to open eeprom_path: %s" % (str(e))) - return None - - try: - if len(raw) == 0: - return None - for n in range(0, num_bytes): - eeprom_raw[n] = hex(raw[n])[2:].zfill(2) - except Exception as e: - print("Error: Exception info: %s" % (str(e))) - return None - - return eeprom_raw - - def get_transceiver_bulk_status(self): - # check present status - if not self.get_presence(): - return None - self.__dom_capability_detect() - - xcvr_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') - - if self.is_osfp_port: - # Below part is added to avoid fail xcvrd, shall be implemented later - pass - elif self.is_qsfp_port: - # QSFPs - xcvr_dom_info_dict = super(Sfp, self).get_transceiver_bulk_status() - - # pddf_sfp "qsfp_tx_power_support != 'on'" is wrong - - offset = 0 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return None - - qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) - if qsfp_dom_rev_raw is not None: - qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) - else: - return None - - dom_channel_monitor_data = {} - qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] - - if (qsfp_dom_rev[0:8] == 'SFF-8636' and self.dom_tx_power_supported is True): - 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) - else: - return None - - xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] - xcvr_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] - xcvr_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] - xcvr_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] - else: - # SFPs - offset = 256 - if not self.dom_supported: - return xcvr_dom_info_dict - - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return None - - sfpd_obj._calibration_type = self.calibration - - dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) - if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) - else: - return None - - dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) - if dom_voltage_raw is not None: - dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) - else: - return None - - 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) - else: - return None - - xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] - xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] - xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] - xcvr_dom_info_dict['rx2power'] = 'N/A' - xcvr_dom_info_dict['rx3power'] = 'N/A' - xcvr_dom_info_dict['rx4power'] = 'N/A' - xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] - xcvr_dom_info_dict['tx2bias'] = 'N/A' - xcvr_dom_info_dict['tx3bias'] = 'N/A' - xcvr_dom_info_dict['tx4bias'] = 'N/A' - xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] - xcvr_dom_info_dict['tx2power'] = 'N/A' - xcvr_dom_info_dict['tx3power'] = 'N/A' - xcvr_dom_info_dict['tx4power'] = 'N/A' - - xcvr_dom_info_dict['rx_los'] = self.get_rx_los() - xcvr_dom_info_dict['tx_fault'] = self.get_tx_fault() - xcvr_dom_info_dict['reset_status'] = self.get_reset_status() - xcvr_dom_info_dict['lp_mode'] = self.get_lpmode() - - return xcvr_dom_info_dict - - def get_transceiver_threshold_info(self): - # check present status - if not self.get_presence(): - return None - self.__dom_capability_detect() - - xcvr_dom_threshold_info_dict = dict.fromkeys(self.threshold_dict_keys, 'N/A') - - if self.is_osfp_port: - # Below part is added to avoid fail xcvrd, shall be implemented later - pass - elif self.is_qsfp_port: - # QSFPs - if not self.dom_supported or not self.qsfp_page3_available: - return xcvr_dom_threshold_info_dict - - return super(Sfp, self).get_transceiver_threshold_info() - - else: - # SFPs - if not self.dom_supported: - return xcvr_dom_threshold_info_dict - - return super(Sfp, self).get_transceiver_threshold_info() - - return xcvr_dom_threshold_info_dict diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/thermal.py deleted file mode 100644 index 99b743c6d343..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/thermal.py +++ /dev/null @@ -1,14 +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): - PddfThermal.__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-ragile/ra-b6920-4s/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/watchdog.py deleted file mode 100644 index 37788c2c821e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/sonic_platform/watchdog.py +++ /dev/null @@ -1,21 +0,0 @@ -############################################################################# -# -# Module contains an implementation of platform specific watchdog API's -# -############################################################################# - -try: - from sonic_platform_pddf_base.pddf_watchdog import PddfWatchdog -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -class Watchdog(PddfWatchdog): - """ - PDDF Platform-specific Chassis class - """ - - def __init__(self): - PddfWatchdog.__init__(self) - self.timeout= 180 - - # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/systemd/pddf-platform-init.service b/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/systemd/pddf-platform-init.service deleted file mode 120000 index 0fd9f25b6c5e..000000000000 --- a/platform/broadcom/sonic-platform-modules-ragile/ra-b6920-4s/systemd/pddf-platform-init.service +++ /dev/null @@ -1 +0,0 @@ -../../../../pddf/i2c/service/pddf-platform-init.service \ No newline at end of file diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index c1f70dc7be65..5c40f413ff5f 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -167,6 +167,7 @@ ifp_inports_support_enable port_flex_enable pdma_descriptor_prefetch_enable pktdma_poll_mode_channel_bitmap +warmboot_knet_shutdown_mode num_queues_pci num_queues_uc0 num_queues_uc1 @@ -312,3 +313,8 @@ port_gmii_mode phy_force_firmware_load phy_pcs_repeater l3_alpm_hit_skip +sai_fdb_entry_l2_discard_src_enable +svi_my_station_optimization +sai_nbr_bcast_ifp_optimized +sai_pfc_defaults_disable +sai_optimized_mmu From d2cf2ee462b3c22b7406405c0f4d3f5d81d4f572 Mon Sep 17 00:00:00 2001 From: pettershao-ragilenetworks <81281940+pettershao-ragilenetworks@users.noreply.github.com> Date: Mon, 27 Mar 2023 19:17:04 +0800 Subject: [PATCH 3/4] Update ssd_util.py --- .../ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py index e92782a0969b..adca0493cdde 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py @@ -165,6 +165,7 @@ def parse_virtium_info(self): try: self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) except (ValueError, ZeroDivisionError): + # Invalid avg_erase_count or nand_endurance. pass def fetch_vendor_ssd_info(self, diskdev, model): @@ -180,9 +181,9 @@ def check_readonly2(self, partition, filesystem): column_list = line.split() if line == '': continue - if column_list[0] == partition and column_list[2] == filesystem: + if column_list[0] == str(partition) and column_list[2] == filesystem: if column_list[5].split(',')[0][1:] == "ro": - return partition + return str(partition) else: return NOT_AVAILABLE From 77bcc80d6a6edffdd88168f16f6299d156f749a1 Mon Sep 17 00:00:00 2001 From: pettershao-ragilenetworks <81281940+pettershao-ragilenetworks@users.noreply.github.com> Date: Mon, 27 Mar 2023 19:17:04 +0800 Subject: [PATCH 4/4] [Platform/Ragile] Adapt kernel 5.10 for broadcom Signed-off-by: pettershao-ragilenetworks --- .../x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py | 5 +++-- .../platform-modules-ragile-ra-b6510-32c.install | 1 + .../platform-modules-ragile-ra-b6510-32c.postinst | 10 ++++++++++ .../platform-modules-ragile-ra-b6910-64c.install | 1 + .../platform-modules-ragile-ra-b6910-64c.postinst | 10 ++++++++++ .../platform-modules-ragile-ra-b6920-4s.postinst | 10 ++++++++++ .../sonic-platform-modules-ragile/debian/rule.mk | 8 ++++++++ 7 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-32c.install create mode 100644 platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-32c.postinst create mode 100644 platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6910-64c.install create mode 100755 platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6910-64c.postinst create mode 100644 platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.postinst create mode 100644 platform/broadcom/sonic-platform-modules-ragile/debian/rule.mk diff --git a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py index e92782a0969b..adca0493cdde 100644 --- a/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py +++ b/device/ragile/x86_64-ragile_ra-b6510-32c-r0/plugins/ssd_util.py @@ -165,6 +165,7 @@ def parse_virtium_info(self): try: self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) except (ValueError, ZeroDivisionError): + # Invalid avg_erase_count or nand_endurance. pass def fetch_vendor_ssd_info(self, diskdev, model): @@ -180,9 +181,9 @@ def check_readonly2(self, partition, filesystem): column_list = line.split() if line == '': continue - if column_list[0] == partition and column_list[2] == filesystem: + if column_list[0] == str(partition) and column_list[2] == filesystem: if column_list[5].split(',')[0][1:] == "ro": - return partition + return str(partition) else: return NOT_AVAILABLE diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-32c.install b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-32c.install new file mode 100644 index 000000000000..ff53effb4b66 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-32c.install @@ -0,0 +1 @@ +ra-b6510-32c/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-ragile_ra-b6510-32c-r0 diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-32c.postinst b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-32c.postinst new file mode 100644 index 000000000000..a8132f4f65a9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6510-32c.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +# postinst + +kernel_version=$(uname -r) + +if [ -e /boot/System.map-${kernel_version} ]; then + depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true +fi + +#DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6910-64c.install b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6910-64c.install new file mode 100644 index 000000000000..15c71f5716b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6910-64c.install @@ -0,0 +1 @@ +ra-b6910-64c/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-ragile_ra-b6910-64c-r0 diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6910-64c.postinst b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6910-64c.postinst new file mode 100755 index 000000000000..a8132f4f65a9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6910-64c.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +# postinst + +kernel_version=$(uname -r) + +if [ -e /boot/System.map-${kernel_version} ]; then + depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true +fi + +#DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.postinst b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.postinst new file mode 100644 index 000000000000..a8132f4f65a9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/platform-modules-ragile-ra-b6920-4s.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +# postinst + +kernel_version=$(uname -r) + +if [ -e /boot/System.map-${kernel_version} ]; then + depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true +fi + +#DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-ragile/debian/rule.mk b/platform/broadcom/sonic-platform-modules-ragile/debian/rule.mk new file mode 100644 index 000000000000..5cde67eb1359 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ragile/debian/rule.mk @@ -0,0 +1,8 @@ +currentdir = $(shell pwd) + +MODULE_DIRS := ra-b6510-48v8c +MODULE_DIRS += ra-b6510-32c +MODULE_DIRS += ra-b6910-64c +MODULE_DIRS += ra-b6920-4s + +export MODULE_DIRS