diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-Board-AC5X-xb.md5 b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-Board-AC5X-xb.md5 index 16326740c2..64cb21addf 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-Board-AC5X-xb.md5 +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-Board-AC5X-xb.md5 @@ -1 +1 @@ -8668dc21ae107bff2d5e4242fe532e38 \ No newline at end of file +ee44e299ca857b9f0abf2e804ec4850f \ No newline at end of file diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-Board-AC5X-xb.xml b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-Board-AC5X-xb.xml index 839af3d55d..08936c1339 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-Board-AC5X-xb.xml +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-Board-AC5X-xb.xml @@ -1,5 +1,5 @@ - + @@ -677,7 +677,7 @@ lowercase characters. 0 ASK-PP-AC5X-xb.xml ASK-L1-AC5X-xb.xml - na + sip6 0 @@ -694,6 +694,10 @@ lowercase characters. 0 + + 63 + false + 1 @@ -711,6 +715,10 @@ lowercase characters. 0 + + 63 + false + 2 @@ -728,6 +736,10 @@ lowercase characters. 0 + + 63 + false + 3 @@ -745,6 +757,10 @@ lowercase characters. 0 + + 63 + false + 4 @@ -762,6 +778,10 @@ lowercase characters. 0 + + 63 + false + 5 @@ -779,6 +799,10 @@ lowercase characters. 0 + + 63 + false + 6 @@ -796,6 +820,10 @@ lowercase characters. 0 + + 63 + false + 7 @@ -813,6 +841,10 @@ lowercase characters. 0 + + 63 + false + 8 @@ -830,6 +862,10 @@ lowercase characters. 0 + + 63 + false + 9 @@ -847,6 +883,10 @@ lowercase characters. 0 + + 63 + false + 10 @@ -864,6 +904,10 @@ lowercase characters. 0 + + 63 + false + 11 @@ -881,6 +925,10 @@ lowercase characters. 0 + + 63 + false + 12 @@ -898,6 +946,10 @@ lowercase characters. 0 + + 63 + false + 13 @@ -915,6 +967,10 @@ lowercase characters. 0 + + 63 + false + 14 @@ -932,6 +988,10 @@ lowercase characters. 0 + + 63 + false + 15 @@ -949,6 +1009,10 @@ lowercase characters. 0 + + 63 + false + 16 @@ -966,6 +1030,10 @@ lowercase characters. 0 + + 63 + false + 17 @@ -983,6 +1051,10 @@ lowercase characters. 0 + + 63 + false + 18 @@ -1000,6 +1072,10 @@ lowercase characters. 0 + + 63 + false + 19 @@ -1017,6 +1093,10 @@ lowercase characters. 0 + + 63 + false + 20 @@ -1034,6 +1114,10 @@ lowercase characters. 0 + + 63 + false + 21 @@ -1051,6 +1135,10 @@ lowercase characters. 0 + + 63 + false + 22 @@ -1068,6 +1156,10 @@ lowercase characters. 0 + + 63 + false + 23 @@ -1085,6 +1177,10 @@ lowercase characters. 0 + + 63 + false + 24 @@ -1102,6 +1198,10 @@ lowercase characters. 1 + + 63 + false + 25 @@ -1119,6 +1219,10 @@ lowercase characters. 1 + + 63 + false + 26 @@ -1136,6 +1240,10 @@ lowercase characters. 1 + + 63 + false + 27 @@ -1153,6 +1261,10 @@ lowercase characters. 1 + + 63 + false + 28 @@ -1170,6 +1282,10 @@ lowercase characters. 1 + + 63 + false + 29 @@ -1187,6 +1303,10 @@ lowercase characters. 1 + + 63 + false + 30 @@ -1204,6 +1324,10 @@ lowercase characters. 1 + + 63 + false + 31 @@ -1221,6 +1345,10 @@ lowercase characters. 1 + + 63 + false + 32 @@ -1238,6 +1366,10 @@ lowercase characters. 1 + + 63 + false + 33 @@ -1255,6 +1387,10 @@ lowercase characters. 1 + + 63 + false + 34 @@ -1272,6 +1408,10 @@ lowercase characters. 1 + + 63 + false + 35 @@ -1289,6 +1429,10 @@ lowercase characters. 1 + + 63 + false + 36 @@ -1306,6 +1450,10 @@ lowercase characters. 1 + + 63 + false + 37 @@ -1323,6 +1471,10 @@ lowercase characters. 1 + + 63 + false + 38 @@ -1340,6 +1492,10 @@ lowercase characters. 1 + + 63 + false + 39 @@ -1357,6 +1513,10 @@ lowercase characters. 1 + + 63 + false + 40 @@ -1374,6 +1534,10 @@ lowercase characters. 1 + + 63 + false + 41 @@ -1391,6 +1555,10 @@ lowercase characters. 1 + + 63 + false + 42 @@ -1408,6 +1576,10 @@ lowercase characters. 1 + + 63 + false + 43 @@ -1425,6 +1597,10 @@ lowercase characters. 1 + + 63 + false + 44 @@ -1442,6 +1618,10 @@ lowercase characters. 1 + + 63 + false + 45 @@ -1459,6 +1639,10 @@ lowercase characters. 1 + + 63 + false + 46 @@ -1476,6 +1660,10 @@ lowercase characters. 1 + + 63 + false + 47 @@ -1493,6 +1681,10 @@ lowercase characters. 1 + + 63 + false + 48 @@ -1507,6 +1699,14 @@ lowercase characters. NA + + 0 + + 2 + false + + false + 49 @@ -1521,6 +1721,14 @@ lowercase characters. NA + + 1 + + 2 + false + + false + 50 @@ -1535,6 +1743,14 @@ lowercase characters. NA + + 0 + + 2 + false + + false + 51 @@ -1549,6 +1765,14 @@ lowercase characters. NA + + 1 + + 2 + false + + false + 60 @@ -1570,6 +1794,157 @@ lowercase characters. NETWORK + + 0 + false + false + + + 1 + false + false + + + 2 + false + false + + + 3 + false + false + + + 4 + false + false + + + 5 + false + false + + + 6 + true + false + + + 7 + false + false + + + 8 + true + false + + + 9 + false + false + + + 10 + false + false + + + 11 + false + false + + + 0 + + ORDER_MODE_BY_PORT + BLINK_DUTY_CYCLE_1 + BLINK_DURATION_2 + BLINK_DUTY_CYCLE_1 + BLINK_DURATION_2 + PULSE_STRETCH_1 + false + 1627 + true + + 1 + true + + + 2 + true + + + 3 + true + + + 4 + 0 + 15 + false + + + 5 + 0 + 15 + false + + + 6 + true + + + 7 + true + + + 8 + true + + + 9 + true + + + 10 + true + + + 11 + true + + + 12 + true + + + 13 + true + + + 14 + true + + + 15 + true + + + 16 + true + + + + 2 + PORT_TYPE_XG + true + BLINK_SELECT_1 + false + false + true + + . diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-L1-AC5X-xb.md5 b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-L1-AC5X-xb.md5 index 5205acca39..e8daa7b6f3 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-L1-AC5X-xb.md5 +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-L1-AC5X-xb.md5 @@ -1 +1 @@ -6d7161d3d4fdf922d5f26243642d8110 \ No newline at end of file +8d006b7a29c75f81b641df68102a6aa3 \ No newline at end of file diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-L1-AC5X-xb.xml b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-L1-AC5X-xb.xml index 2e612d014e..534b218554 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-L1-AC5X-xb.xml +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-L1-AC5X-xb.xml @@ -1,5 +1,5 @@ - + diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-PP-AC5X-xb.md5 b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-PP-AC5X-xb.md5 index e0b9509d1d..de23afe955 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-PP-AC5X-xb.md5 +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-PP-AC5X-xb.md5 @@ -1 +1 @@ -75737f56687883d181ea3da8d1c24da6 \ No newline at end of file +b42f2a2be9da6c7752c0807f9dee48bf \ No newline at end of file diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-PP-AC5X-xb.xml b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-PP-AC5X-xb.xml index 50daefc694..ad457fe7db 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-PP-AC5X-xb.xml +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/ASK-PP-AC5X-xb.xml @@ -1,5 +1,5 @@ - + diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/SAI-AC5X-xb.md5 b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/SAI-AC5X-xb.md5 index ee93b73e25..951dd3007b 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/SAI-AC5X-xb.md5 +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/SAI-AC5X-xb.md5 @@ -1 +1 @@ -ac4217e114fbd773ddbc6e0053948000 \ No newline at end of file +b43a871130f9e59ac21a74940574558f \ No newline at end of file diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/SAI-AC5X-xb.xml b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/SAI-AC5X-xb.xml index 6f45980f2c..5e374fdb06 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/SAI-AC5X-xb.xml +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/Nokia-7215-A1/SAI-AC5X-xb.xml @@ -1,5 +1,5 @@ - + diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/platform.json b/device/nokia/arm64-nokia_ixs7215_52xb-r0/platform.json index 633d92d7b5..0ddd1f3958 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/platform.json +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/platform.json @@ -11,28 +11,46 @@ ], "fans": [ { - "name": "Fan1" + "name": "Fan1", + "status_led": { + "controllable": false + } }, { - "name": "Fan2" + "name": "Fan2", + "status_led": { + "controllable": false + } } ], "fan_drawers": [ { "name": "drawer1", + "status_led": { + "controllable": false + }, "max_consumed_power": false, "fans": [ { - "name": "Fan1" + "name": "Fan1", + "status_led": { + "controllable": false + } } ] }, { "name": "drawer2", + "status_led": { + "controllable": false + }, "max_consumed_power": false, "fans": [ { - "name": "Fan2" + "name": "Fan2", + "status_led": { + "controllable": false + } } ] } @@ -40,6 +58,9 @@ "psus": [ { "name": "PSU1", + "status_led": { + "controllable": false + }, "current": false, "power": false, "max_power": false, @@ -49,6 +70,9 @@ }, { "name": "PSU2", + "status_led": { + "controllable": false + }, "current": false, "power": false, "max_power": false, @@ -73,12 +97,18 @@ "high-crit-threshold": false }, { - "name": "CPU Core", + "name": "AC5X CORE", + "controllable": false, + "low-threshold": false, + "low-crit-threshold": false, + "high-crit-threshold": false + }, + { + "name": "OOB PHY", "controllable": false, "low-threshold": false, "high-threshold": false, - "low-crit-threshold": false, - "high-crit-threshold": false + "low-crit-threshold": false } ], "sfps": [ @@ -227,16 +257,16 @@ "name": "Ethernet47" }, { - "name": "Ethernet48" + "name": "SFP48" }, { - "name": "Ethernet49" + "name": "SFP49" }, { - "name": "Ethernet50" + "name": "SFP50" }, { - "name": "Ethernet51" + "name": "SFP51" } ] }, diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/platform_reboot b/device/nokia/arm64-nokia_ixs7215_52xb-r0/platform_reboot old mode 100755 new mode 100644 diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/plugins/led_control.py b/device/nokia/arm64-nokia_ixs7215_52xb-r0/plugins/led_control.py new file mode 100644 index 0000000000..0a2dfdd7fc --- /dev/null +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/plugins/led_control.py @@ -0,0 +1,119 @@ +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + from sonic_led.led_control_base import LedControlBase + import os + import time + import syslog + import sonic_platform.platform + import sonic_platform.chassis +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + +CPLD_DIR = "/sys/bus/i2c/devices/0-0041/" + +def DBG_PRINT(str): + syslog.openlog("nokia-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Constructor + def __init__(self): + self.chassis = sonic_platform.platform.Platform().get_chassis() + self._initDefaultConfig() + + def _initDefaultConfig(self): + # The fan tray leds and system led managed by new chassis class API + # leaving only a couple other front panel leds to be done old style + DBG_PRINT("starting system leds") + self._initSystemLed() + DBG_PRINT(" led done") + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _write_sysfs_file(self, sysfs_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'w') as fd: + rv = fd.write(str(value)) + except Exception as e: + rv = 'ERR' + + return rv + + def _initSystemLed(self): + # Front Panel System LEDs setting + oldfan = 0xf # 0=amber, 1=green + oldpsu = 0xf # 0=amber, 1=green + + # Write sys led + status = self._write_sysfs_file(CPLD_DIR+"system_led", "green") + if status == "ERR": + DBG_PRINT(" System LED NOT set correctly") + else: + DBG_PRINT(" System LED set O.K. ") + + # Timer loop to monitor and set front panel Status, Fan, and PSU LEDs + while True: + # Front Panel FAN Panel LED setting + if (self.chassis.get_fan(0).get_status() == self.chassis.get_fan(1).get_status() == True): + if (os.path.isfile(CPLD_DIR+"fan_led")): + if oldfan != 0x1: + self._write_sysfs_file(CPLD_DIR+"fan_led", "green") + oldfan = 0x1 + else: + oldfan = 0xf + else: + if (os.path.isfile(CPLD_DIR+"fan_led")): + if oldfan != 0x0: + self._write_sysfs_file(CPLD_DIR+"fan_led", "amber") + oldfan = 0x0 + else: + oldfan = 0xf + + # Front Panel PSU Panel LED setting + if (self.chassis.get_psu(0).get_status() == self.chassis.get_psu(1).get_status() == True): + if (os.path.isfile(CPLD_DIR+"psu_led")): + if oldpsu != 0x1: + self._write_sysfs_file(CPLD_DIR+"psu_led", "green") + oldpsu = 0x1 + else: + oldpsu = 0xf + else: + if (os.path.isfile(CPLD_DIR+"psu_led")): + if oldpsu != 0x0: + status = self._write_sysfs_file(CPLD_DIR+"psu_led", "amber") + oldpsu = 0x0 + else: + oldpsu = 0xf + + time.sleep(6) + diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/pmon_daemon_control.json b/device/nokia/arm64-nokia_ixs7215_52xb-r0/pmon_daemon_control.json new file mode 100644 index 0000000000..f6445f8759 --- /dev/null +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_pcied": true +} diff --git a/device/nokia/arm64-nokia_ixs7215_52xb-r0/thermal_policy.json b/device/nokia/arm64-nokia_ixs7215_52xb-r0/thermal_policy.json index fb6e044e26..d20c3b817a 100644 --- a/device/nokia/arm64-nokia_ixs7215_52xb-r0/thermal_policy.json +++ b/device/nokia/arm64-nokia_ixs7215_52xb-r0/thermal_policy.json @@ -43,7 +43,9 @@ "actions": [ { "type": "thermal.temp_check_and_set_all_fan_speed", - "default_speed": "50", + "default_speed": "25", + "threshold1_speed": "40", + "threshold2_speed": "75", "hightemp_speed": "100" } ] diff --git a/platform/marvell-arm64/platform.conf b/platform/marvell-arm64/platform.conf index 4de0dadd28..2fa347b68b 100644 --- a/platform/marvell-arm64/platform.conf +++ b/platform/marvell-arm64/platform.conf @@ -37,11 +37,11 @@ if [ $PLATFORM_AC5X -eq 1 ]; then fit_addr=0x210000000 initrd_addr=0x206000000 - fdt_fname="/boot/ac5x.dtb" + fdt_fname="/usr/lib/linux-image-${kernel_version}/marvell/7215-ixs-a1.dtb" FW_ENV_DEFAULT='/dev/mtd0 0x400000 0x10000 0x10000' demo_part=2 - fit_conf_name="#conf_ac5x" + fit_conf_name="#conf_7215_a1" mmc_bus="mmc0:0001" else fdt_addr=0x1000000 @@ -205,6 +205,7 @@ prepare_boot_menu() { fw_setenv ${FW_ARG} kernel_addr $kernel_addr > /dev/null fw_setenv ${FW_ARG} fdt_addr $fdt_addr > /dev/null fw_setenv ${FW_ARG} fit_addr $fit_addr > /dev/null + fw_setenv ${FW_ARG} fit_conf_name $fit_conf_name > /dev/null fw_setenv ${FW_ARG} initrd_addr $initrd_addr > /dev/null MMC_LOAD='ext4load mmc 0:'$demo_part' $fit_addr $fit_name' fw_setenv ${FW_ARG} sonic_boot_load "$MMC_LOAD" > /dev/null diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/modules/Makefile b/platform/marvell-arm64/sonic-platform-nokia/7215/modules/Makefile index 47e1492f15..73d6e5f388 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/modules/Makefile +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/modules/Makefile @@ -1 +1 @@ -obj-m:= nokia_7215_ixs_a1_cpld.o +obj-m:= nokia_7215_ixs_a1_cpld.o ac5_thermal_sensor.o diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/modules/ac5_thermal_sensor.c b/platform/marvell-arm64/sonic-platform-nokia/7215/modules/ac5_thermal_sensor.c new file mode 100644 index 0000000000..faf4402ffe --- /dev/null +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/modules/ac5_thermal_sensor.c @@ -0,0 +1,218 @@ +/* + * HWMON Driver for AC5x thermal sensor + * + * Author: Natarajan Subbiramani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define AC5_DEFAULT_TEMP_CRIT 100000 +#define AC5_DEFAULT_TEMP_MAX 110000 + +#define AC5_TEMP_BASE_ADDR 0x944F80D0 +static unsigned long thermal_base_addr=AC5_TEMP_BASE_ADDR; +module_param(thermal_base_addr, ulong, 0444); +MODULE_PARM_DESC(thermal_base_addr, + "Initialize the base address of the thermal sensor"); + +struct ac5_thermal_data { + struct device *dev; + struct device *hwmon_dev; + uint8_t * __iomem temp_base; + int temp_input; + int temp_crit; + int temp_max; +}; + +static long ac5_thermal_read_reg_in_mcelcius(struct device *dev, struct ac5_thermal_data *data) +{ + volatile uint8_t * __iomem temp_base = data->temp_base; + uint32_t regval; + long output=data->temp_max; + + //STOP MEASUREMENT + writel(0xF0F01034, temp_base); + + //delay for 1ms + mdelay(1); + + //Read thermal value + regval = readl(temp_base+0xC); + + //RE-START MEASUREMENT + writel(0xF0F01035, temp_base); + + //Validate data + if(regval & 0x10000) { + //Calibrate it to milli-celcius + output = (regval>> 6) & 0x3FF; + output = ((output*42)-27250)*10; + } + + return output; +} +static int ac5_thermal_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct ac5_thermal_data *data = dev_get_drvdata(dev); + + switch (type) { + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + *val = ac5_thermal_read_reg_in_mcelcius(dev, data); + break; + case hwmon_temp_crit: + *val = data->temp_crit; + break; + case hwmon_temp_max: + *val = data->temp_max; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + return 0; +} + +static int ac5_thermal_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + struct ac5_thermal_data *data = dev_get_drvdata(dev); + switch (type) { + case hwmon_temp: + switch (attr) { + case hwmon_temp_crit: + data->temp_crit = val; + break; + case hwmon_temp_max: + data->temp_max = val; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + return 0; +} + + +static umode_t ac5_thermal_is_visible(const void *data, enum hwmon_sensor_types type, + u32 attr, int channel) +{ + switch (type) { + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + return 0444; + case hwmon_temp_crit: + case hwmon_temp_max: + return 0644; + } + break; + default: + break; + } + return 0; +} + +static const struct hwmon_channel_info *ac5_thermal_info[] = { + HWMON_CHANNEL_INFO(temp, + HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT), + NULL +}; + +static const struct hwmon_ops ac5_thermal_hwmon_ops = { + .is_visible = ac5_thermal_is_visible, + .read = ac5_thermal_read, + .write = ac5_thermal_write, +}; + +static const struct hwmon_chip_info ac5_thermal_chip_info = { + .ops = &ac5_thermal_hwmon_ops, + .info = ac5_thermal_info, +}; + +static const struct file_operations fops = { + .owner = THIS_MODULE, +}; + +struct miscdevice ac5_thermal_misc_device = { + .minor = TEMP_MINOR, + .name = "ac5_thermal", + .fops = &fops, +}; + +static int __init ac5_thermal_init_misc_driver(void) +{ + struct device *dev; + struct ac5_thermal_data *thermal_data; + int err; + void * __iomem reg; + + err = misc_register(&ac5_thermal_misc_device); + if (err) { + pr_err("ac5_thermal misc_register failed!!!\n"); + return err; + } + + dev = ac5_thermal_misc_device.this_device; + thermal_data = devm_kzalloc(dev, sizeof(struct ac5_thermal_data), GFP_KERNEL); + if (!thermal_data) + return -ENOMEM; + + thermal_data->dev = dev; + thermal_data->temp_crit = AC5_DEFAULT_TEMP_CRIT; + thermal_data->temp_max = AC5_DEFAULT_TEMP_MAX; + + thermal_data->hwmon_dev = devm_hwmon_device_register_with_info(dev, ac5_thermal_misc_device.name, + thermal_data, &ac5_thermal_chip_info, + NULL); + if (IS_ERR(thermal_data->hwmon_dev)) { + dev_err(dev, "%s: hwmon registration failed.\n", ac5_thermal_misc_device.name); + return PTR_ERR(thermal_data->hwmon_dev); + } + + reg = devm_ioremap(dev, thermal_base_addr, 16); + if (IS_ERR(reg)) { + dev_err(dev, "%s: base addr remap failed\n", ac5_thermal_misc_device.name); + return PTR_ERR(reg); + } + thermal_data->temp_base = reg; + /*Enable measurement*/ + writel(0xF0F01035, thermal_data->temp_base); + writel(0x0584e680, thermal_data->temp_base+8); + + dev_info(dev, "%s: initialized. base_addr: 0x%lx\n", dev_name(thermal_data->hwmon_dev), thermal_base_addr); + + return 0; +} + +static void __exit ac5_thermal_exit_misc_driver(void) +{ + misc_deregister(&ac5_thermal_misc_device); +} + +module_init(ac5_thermal_init_misc_driver); +module_exit(ac5_thermal_exit_misc_driver); + +MODULE_AUTHOR("Natarajan Subbiramani "); +MODULE_DESCRIPTION("AC5 Thermal sensor Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/scripts/nokia-7215-init.sh b/platform/marvell-arm64/sonic-platform-nokia/7215/scripts/nokia-7215-init.sh index 9659bee7c7..b105c0f711 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/scripts/nokia-7215-init.sh +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/scripts/nokia-7215-init.sh @@ -4,9 +4,9 @@ # Load required kernel-mode drivers load_kernel_drivers() { -#placeholder for now - echo "Loading Kernel Drivers" + echo "Loading Kernel Drivers" sudo insmod /lib/modules/5.10.0-18-2-arm64/nokia_7215_ixs_a1_cpld.ko + sudo insmod /lib/modules/5.10.0-18-2-arm64/ac5_thermal_sensor.ko } nokia_7215_profile() @@ -16,23 +16,28 @@ nokia_7215_profile() sudo ifconfig eth0 hw ether $MAC_ADDR echo "Nokia-7215-A1: Updating switch mac address ${MAC_ADDR}" } +file_exists() { + # Wait 10 seconds max till file exists + for((i=0; i<10; i++)); + do + if [ -f $1 ]; then + return 1 + fi + sleep 1 + done + return 0 + } # - Main entry # Install kernel drivers required for i2c bus access load_kernel_drivers +# Enumerate RTC +echo m41t11 0x68 > /sys/bus/i2c/devices/i2c-0/new_device -# LOGIC to enumerate SFP eeprom devices - send 0x50 to kernel i2c driver - initialize devices -# the mux may be enumerated at number 4 or 5 so we check for the mux and skip if needed -# Get list of the mux channels # Enumerate the SFP eeprom device on each mux channel -#echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device - -# Enumerate system eeprom -echo 24c64 0x53 > /sys/class/i2c-adapter/i2c-0/new_device -sleep 2 -chmod 644 /sys/class/i2c-adapter/i2c-0/0-0053/eeprom +echo pca9546 0x70> /sys/bus/i2c/devices/i2c-1/new_device # Enumerate power monitor echo ina230 0x40 > /sys/bus/i2c/devices/i2c-0/new_device @@ -40,17 +45,52 @@ echo ina230 0x40 > /sys/bus/i2c/devices/i2c-0/new_device # Enumerate fan echo emc2305 0x2e > /sys/bus/i2c/devices/i2c-0/new_device -# Enumerate RTC -echo m41t11 0x68 > /sys/bus/i2c/devices/i2c-0/new_device - # Enumerate Thermals - echo tmp75 0x48 > /sys/bus/i2c/devices/i2c-0/new_device echo tmp75 0x49 > /sys/bus/i2c/devices/i2c-0/new_device +#Enumerate CPLD echo nokia_7215_a1_cpld 0x41 > /sys/bus/i2c/devices/i2c-0/new_device +# Enumerate system eeprom +echo 24c64 0x53 > /sys/class/i2c-adapter/i2c-0/new_device + +file_exists /sys/class/i2c-adapter/i2c-0/0-0053/eeprom +status=$? +if [ "$status" == "1" ]; then + chmod 644 /sys/class/i2c-adapter/i2c-0/0-0053/eeprom +else + echo "SYSEEPROM file not foud" +fi + +# Get list of the mux channels +for((i=0; i<10; i++)); + do + ismux_bus=$(i2cdetect -l|grep mux|cut -f1) + if [[ $ismux_bus ]]; then + break; + fi + sleep 1 + done + +# Enumerate the SFP eeprom device on each mux channel +for mux in ${ismux_bus} +do + echo optoe2 0x50 > /sys/class/i2c-adapter/${mux}/new_device +done + +# Enable optical SFP Tx +for i in {49..52} +do + echo 0 > /sys/bus/i2c/devices/0-0041/sfp${i}_tx_disable +done + +#slow down fan speed to 50 untill thermal algorithm kicks in% +i2c_path="/sys/bus/i2c/devices/0-002e/hwmon/hwmon?" +echo 128 > $i2c_path/pwm1 +echo 128 > $i2c_path/pwm2 + # Ensure switch is programmed with base MAC addr nokia_7215_profile -exit 0 \ No newline at end of file +exit 0 diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/chassis.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/chassis.py index c5f3c1db18..11eeb15106 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/chassis.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/chassis.py @@ -35,7 +35,7 @@ MAX_7215_COMPONENT=2 MAX_7215_FAN_DRAWERS = 2 MAX_7215_FANS_PER_DRAWER = 1 MAX_7215_PSU = 2 -MAX_7215_THERMAL = 3 +MAX_7215_THERMAL = 4 CPLD_DIR = "/sys/bus/i2c/devices/0-0041/" SYSLOG_IDENTIFIER = "chassis" @@ -64,11 +64,10 @@ class Chassis(ChassisBase): sfp_node = Sfp(index, 'COPPER', 'N/A', 'N/A') self._sfp_list.append(sfp_node) - """ # Verify optoe2 driver SFP eeprom devices were enumerated and exist # then create the sfp nodes eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" - mux_dev = sorted(glob.glob("/sys/class/i2c-adapter/i2c-0/i2c-[0-9]")) + mux_dev = sorted(glob.glob("/sys/class/i2c-adapter/i2c-1/i2c-[0-9]")) y = 0 for index in range(self.SFP_PORT_START, self.SFP_PORT_END+1): mux_dev_num = mux_dev[y] @@ -80,7 +79,6 @@ class Chassis(ChassisBase): sfp_node = Sfp(index, 'SFP', port_eeprom_path, port_i2c_map) self._sfp_list.append(sfp_node) self.sfp_event_initialized = False - """ # Instantiate system eeprom object self._eeprom = Eeprom() @@ -196,11 +194,11 @@ class Chassis(ChassisBase): def get_serial(self): """ - Retrieves the serial number of the chassis (Service tag) + Retrieves the serial number of the chassis Returns: string: Serial number of chassis """ - return self._eeprom.serial_str() + return self._eeprom.serial_number_str() def get_status(self): """ @@ -221,15 +219,13 @@ class Chassis(ChassisBase): """ return self._eeprom.base_mac_addr() - def get_serial_number(self): + def get_service_tag(self): """ - Retrieves the hardware serial number for the chassis - + Retrieves the Service Tag of the chassis Returns: - A string containing the hardware serial number for this - chassis. + string: Service Tag of chassis """ - return self._eeprom.serial_number_str() + return self._eeprom.service_tag_str() def get_revision(self): """ @@ -275,6 +271,13 @@ class Chassis(ChassisBase): Returns: An object derived from WatchdogBase representing the hardware watchdog device + + Note: + We overload this method to ensure that watchdog is only initialized + when it is referenced. Currently, only one daemon can open the + watchdog. To initialize watchdog in the constructor causes multiple + daemon try opening watchdog when loading and constructing a chassis + object and fail. By doing so we can eliminate that risk. """ try: if self._watchdog is None: @@ -405,31 +408,6 @@ class Chassis(ChassisBase): return color - def get_watchdog(self): - """ - Retrieves hardware watchdog device on this chassis - - Returns: - An object derived from WatchdogBase representing the hardware - watchdog device - - Note: - We overload this method to ensure that watchdog is only initialized - when it is referenced. Currently, only one daemon can open the - watchdog. To initialize watchdog in the constructor causes multiple - daemon try opening watchdog when loading and constructing a chassis - object and fail. By doing so we can eliminate that risk. - """ - try: - if self._watchdog is None: - from sonic_platform.watchdog import WatchdogImplBase - watchdog_device_path = "/dev/watchdog0" - self._watchdog = WatchdogImplBase(watchdog_device_path) - except Exception as e: - sonic_logger.log_warning(" Fail to load watchdog {}".format(repr(e))) - - return self._watchdog - def get_position_in_parent(self): """ Retrieves 1-based relative physical position in parent device. If the agent diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/component.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/component.py index f510bde804..cda5abc3c2 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/component.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/component.py @@ -34,10 +34,7 @@ class Component(ComponentBase): ["System-CPLD", "Used for managing SFPs, LEDs, PSUs and FANs "], ["U-Boot", "Performs initialization during booting"], ] - CPLD_UPDATE_COMMAND1 = ['cp', '/usr/sbin/vme', '/tmp'] - CPLD_UPDATE_COMMAND2 = ['cp', '', '/tmp'] - CPLD_UPDATE_COMMAND3 = ['cd', '/tmp'] - CPLD_UPDATE_COMMAND4 = ['./vme', ''] + CPLD_UPDATE_COMMAND = ['./cpldupd_A1', ''] def __init__(self, component_index): self.index = component_index @@ -192,23 +189,25 @@ class Component(ComponentBase): A boolean, True if install was successful, False if not """ image_name = ntpath.basename(image_path) - print(" ixs7215 - install cpld {}".format(image_name)) + print(" ixs-7215-A1 - install cpld {}".format(image_name)) # check whether the image file exists if not os.path.isfile(image_path): print("ERROR: the cpld image {} doesn't exist ".format(image_path)) return False - self.CPLD_UPDATE_COMMAND2[1] = image_path - self.CPLD_UPDATE_COMMAND4[1] = image_name + # check whether the cpld exe exists + if not os.path.isfile('/tmp/cpldupd_A1'): + print("ERROR: the cpld exe {} doesn't exist ".format('/tmp/cpldupd_A1')) + return False + + self.CPLD_UPDATE_COMMAND[1] = image_name success_flag = False try: - subprocess.check_call(self.CPLD_UPDATE_COMMAND1, stderr=subprocess.STDOUT) - subprocess.check_call(self.CPLD_UPDATE_COMMAND2, stderr=subprocess.STDOUT) - subprocess.check_call(self.CPLD_UPDATE_COMMAND3, stderr=subprocess.STDOUT) - subprocess.check_call(self.CPLD_UPDATE_COMMAND4, stderr=subprocess.STDOUT) + subprocess.check_call(self.CPLD_UPDATE_COMMAND, stderr=subprocess.STDOUT) + success_flag = True except subprocess.CalledProcessError as e: print("ERROR: Failed to upgrade CPLD: rc={}".format(e.returncode)) diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/eeprom.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/eeprom.py index ada5e979ee..4abfad47be 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/eeprom.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/eeprom.py @@ -27,23 +27,28 @@ class Eeprom(TlvInfoDecoder): self.is_psu_eeprom = is_psu self.is_fan_eeprom = is_fan self.is_sys_eeprom = not (is_psu | is_fan) + + if self.is_sys_eeprom: + self.start_offset = 0 + self.eeprom_path = self.I2C_DIR + "i2c-0/0-0053/eeprom" + # System EEPROM is in ONIE TlvInfo EEPROM format + super(Eeprom, self).__init__(self.eeprom_path, + self.start_offset, '', True) + self._load_system_eeprom() + + else: + if self.is_psu_eeprom: + self.index = psu_index + self.part_number = '1' + self.model_str = 'PJT-12V100WBBA' + self.serial_number = 'NA' + self.serial_number = 'NA' - self.start_offset = 0 - self.eeprom_path = self.I2C_DIR + "i2c-0/0-0053/eeprom" - # System EEPROM is in ONIE TlvInfo EEPROM format - super(Eeprom, self).__init__(self.eeprom_path, - self.start_offset, '', True) - self._load_system_eeprom() - - if self.is_psu_eeprom: - self.index = psu_index - self.part_number = '1' - self.model_str = 'PJT-12V100WBBA' - - if self.is_fan_eeprom: - self.index = fan_index - self.part_number = '1' - self.model_str = 'FFB0412UHN-BC2EA12' + if self.is_fan_eeprom: + self.index = fan_index + self.part_number = '1' + self.model_str = 'FFB0412UHN-BC2EA12' + self.serial_number = 'NA' def _load_system_eeprom(self): @@ -61,7 +66,7 @@ class Eeprom(TlvInfoDecoder): self.serial_number = 'NA' self.part_number = 'NA' self.model_str = 'NA' - self.serial = 'NA' + self.service_tag = 'NA' self.eeprom_tlv_dict = dict() else: eeprom = self.eeprom_data @@ -73,7 +78,7 @@ class Eeprom(TlvInfoDecoder): self.serial_number = 'NA' self.part_number = 'NA' self.model_str = 'NA' - self.serial = 'NA' + self.service_tag = 'NA' return total_length = (eeprom[9] << 8) | eeprom[10] @@ -88,12 +93,7 @@ class Eeprom(TlvInfoDecoder): + eeprom[tlv_index + 1]] code = "0x%02X" % (tlv[0]) - if tlv[0] == self._TLV_CODE_VENDOR_EXT: - value = str((tlv[2] << 24) | (tlv[3] << 16) | - (tlv[4]<< 8) | tlv[5]) - value += str(tlv[6:6 + tlv[1]]) - else: - name, value = self.decoder(None, tlv) + name, value = self.decoder(None, tlv) self.eeprom_tlv_dict[code] = value if eeprom[tlv_index] == self._TLV_CODE_CRC_32: @@ -109,7 +109,7 @@ class Eeprom(TlvInfoDecoder): "0x%X" % (self._TLV_CODE_PART_NUMBER), 'NA') self.model_str = self.eeprom_tlv_dict.get( "0x%X" % (self._TLV_CODE_PRODUCT_NAME), 'NA') - self.serial = self.eeprom_tlv_dict.get( + self.service_tag = self.eeprom_tlv_dict.get( "0x%X" % (self._TLV_CODE_SERVICE_TAG), 'NA') def _get_eeprom_field(self, field_name): @@ -160,11 +160,11 @@ class Eeprom(TlvInfoDecoder): """ return self.model_str - def serial_str(self): + def service_tag_str(self): """ Returns the servicetag number. """ - return self.serial + return self.service_tag def system_eeprom_info(self): """ diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/fan.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/fan.py index f03122686f..aa4a51a95d 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/fan.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/fan.py @@ -16,8 +16,9 @@ try: except ImportError as e: raise ImportError(str(e) + "- required module not found") -MAX_IXS7215_FAN_SPEED = 23000 -WORKING_IXS7215_FAN_SPEED = 2300 +MAX_IXS7215_FAN_SPEED = 24000 +WORKING_IXS7215_FAN_SPEED = 2400 + sonic_logger = logger.Logger('fan') @@ -27,9 +28,11 @@ class Fan(FanBase): def __init__(self, fan_index, fan_drawer, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan + EMC2302_DIR = " " i2c_path = "/sys/bus/i2c/devices/0-002e/hwmon/" - hwmon_node = os.listdir(i2c_path)[0] - EMC2302_DIR = i2c_path + hwmon_node + '/' + if(os.path.exists(i2c_path)): + hwmon_node = os.listdir(i2c_path)[0] + EMC2302_DIR = i2c_path + hwmon_node + '/' if not self.is_psu_fan: # Fan is 1-based in Nokia platforms @@ -140,7 +143,7 @@ class Fan(FanBase): Returns: string: Service Tag of Fan """ - return self.eeprom.serial_str() + return self.eeprom.service_tag_str() def get_status(self): """ @@ -217,7 +220,7 @@ class Fan(FanBase): """ if self.get_presence(): # The tolerance value is fixed as 25% for this platform - tolerance = 25 + tolerance = 50 else: tolerance = 0 @@ -235,17 +238,16 @@ class Fan(FanBase): if self.is_psu_fan: return False - # Set current fan duty cycle - # - 0x00 : fan off - # - 0x40 : 25% duty cycle - # - 0x80 : 50% duty cycle (default) - # - 0xff : 100% duty cycle (full speed) if speed in range(0, 6): fandutycycle = 0x00 - elif speed in range(6, 41): + elif speed in range(6, 26): fandutycycle = 64 - elif speed in range(41, 76): + elif speed in range(26, 41): + fandutycycle = 102 + elif speed in range(41, 52): fandutycycle = 128 + elif speed in range(52, 76): + fandutycycle = 192 elif speed in range(76, 101): fandutycycle = 255 else: @@ -300,9 +302,13 @@ class Fan(FanBase): speed = 0 elif dutyspeed == 64: speed = 25 + elif dutyspeed == 102: + speed = 40 elif dutyspeed == 128: speed = 50 + elif dutyspeed == 192: + speed = 75 elif dutyspeed == 255: speed = 100 - return speed \ No newline at end of file + return speed diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/psu.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/psu.py index bd45ed0546..eb8aeeaedf 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/psu.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/psu.py @@ -167,11 +167,11 @@ class Psu(PsuBase): e.g. 12.1 """ if(self.get_status()): - psu_voltage = self._read_sysfs_file(INA230_DIR+"in_voltage1_scale") + psu_voltage = self._read_sysfs_file(INA230_DIR+"in_voltage1_raw") else: psu_voltage = 0.0 - psu_voltage = float(psu_voltage)*10 + psu_voltage = (float(psu_voltage)*1.25)/1000 return psu_voltage @@ -184,8 +184,8 @@ class Psu(PsuBase): """ num_psus = self._get_active_psus() if(self.get_status()): - psu_current = self._read_sysfs_file(INA230_DIR+"in_current3_scale") - psu_current = (float(psu_current)*10)/num_psus + psu_current = self._read_sysfs_file(INA230_DIR+"in_current3_raw") + psu_current = ((float(psu_current)*0.5)/1000)/num_psus else: psu_current = 0.0 diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/sfp.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/sfp.py index c7b659c00f..4cb96ed470 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/sfp.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/sfp.py @@ -1,13 +1,14 @@ # Name: sfp.py, version: 1.0 # # Description: Module contains the definitions of SFP related APIs -# for Nokia IXR 7250 platform. +# for Nokia IXS 7215 platform. # # Copyright (c) 2023, Nokia # All rights reserved. # try: + import os from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase from sonic_py_common.logger import Logger from sonic_py_common import device_info @@ -18,20 +19,13 @@ except ImportError as e: import subprocess as cmd -smbus_present = 1 - -try: - import smbus -except ImportError as e: - smbus_present = 0 - COPPER_TYPE = "COPPER" SFP_TYPE = "SFP" # SFP PORT numbers SFP_PORT_START = 49 SFP_PORT_END = 52 - +CPLD_DIR = "/sys/bus/i2c/devices/0-0041/" logger = Logger() class Sfp(SfpOptoeBase): @@ -71,7 +65,24 @@ class Sfp(SfpOptoeBase): logger.log_debug("Sfp __init__ index {} setting name to {} and eeprom_path to {}".format(index, self.name, self.eeprom_path)) Sfp.instances.append(self) - + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + def get_eeprom_path(self): return self.eeprom_path @@ -83,22 +94,8 @@ class Sfp(SfpOptoeBase): """ if self.sfp_type == COPPER_TYPE: return False - - if smbus_present == 0: # if called from sfputil outside of pmon - # cmdstatus, sfpstatus = cmd.getstatusoutput('sudo i2cget -y 0 0x41 0x3') - cmdstatus, sfpstatus = getstatusoutput_noshell(['sudo', 'i2cget', '-y', '0', '0x41', '0x3']) - sfpstatus = int(sfpstatus, 16) - else: - bus = smbus.SMBus(0) - DEVICE_ADDRESS = 0x41 - DEVICE_REG = 0x3 - sfpstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) - - pos = [1, 2, 4, 8] - bit_pos = pos[self.index-SFP_PORT_START] - sfpstatus = sfpstatus & (bit_pos) - - if sfpstatus == 0: + sfpstatus = self._read_sysfs_file(CPLD_DIR+"sfp{}_present".format(self.index)) + if sfpstatus == '1': return True return False @@ -157,7 +154,6 @@ class Sfp(SfpOptoeBase): error_description = self.SFP_STATUS_OK return error_description - # return NotImplementedError def get_reset_status(self): """ diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/sfp_event.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/sfp_event.py index 34fc2bc6ae..92f759b978 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/sfp_event.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/sfp_event.py @@ -1,17 +1,11 @@ ''' listen for the SFP change event and return to chassis. ''' +import os import time from sonic_py_common import logger from sonic_py_common.general import getstatusoutput_noshell -smbus_present = 1 - -try: - import smbus -except ImportError as e: - smbus_present = 0 - # system level event/error EVENT_ON_ALL_SFP = '-1' SYSTEM_NOT_READY = 'system_not_ready' @@ -21,6 +15,7 @@ SYSTEM_FAIL = 'system_fail' # SFP PORT numbers SFP_PORT_START = 49 SFP_PORT_END = 52 +CPLD_DIR = "/sys/bus/i2c/devices/0-0041/" SYSLOG_IDENTIFIER = "sfp_event" sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) @@ -32,6 +27,23 @@ class sfp_event: def __init__(self): self.handle = None + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + def initialize(self): self.modprs_register = 0 # Get Transceiver status @@ -44,18 +56,13 @@ class sfp_event: return def _get_transceiver_status(self): - if smbus_present == 0: - sonic_logger.log_info(" PMON - smbus ERROR - DEBUG sfp_event ") - cmdstatus, sfpstatus = getstatusoutput_noshell(['sudo', 'i2cget', '-y', '0', '0x41', '0x3']) - sfpstatus = int(sfpstatus, 16) - else: - bus = smbus.SMBus(0) - DEVICE_ADDRESS = 0x41 - DEVICE_REG = 0x3 - sfpstatus = bus.read_byte_data(DEVICE_ADDRESS, DEVICE_REG) - sfpstatus = ~sfpstatus - sfpstatus = sfpstatus & 0xF + pos = [1, 2, 4, 8] + sfpstatus = 0 + for port in range (SFP_PORT_START,SFP_PORT_END+1): + status = self._read_sysfs_file(CPLD_DIR+"sfp{}_present".format(port)) + bit_pos = pos[port-SFP_PORT_START] + sfpstatus = sfpstatus + (bit_pos * (int(status))) return sfpstatus diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py index f63dd02412..bee72e022e 100755 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/test/test-eeprom.py @@ -13,7 +13,7 @@ def main(): eeprom = chassis.get_eeprom() print(" Model: {}, Service Tag: {}".format(eeprom.modelstr(), - eeprom.serial_str())) + eeprom. service_tag_str())) print(" Part#: {}, Serial#: {}".format(eeprom.part_number_str(), eeprom.serial_number_str())) print(" Base MAC: {}".format(eeprom.base_mac_addr())) diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal.py index 4af8fce144..5a8a084cfc 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal.py @@ -24,8 +24,9 @@ class Thermal(ThermalBase): ['i2c-0/0-0049/hwmon/', 1]) HWMON_CLASS_DIR = "/sys/class/hwmon/hwmon0/" + AC5X_THERMAL_DIR = "/sys/class/hwmon/hwmon1/" - THERMAL_NAME = ("PCB BACK", "PCB FRONT", "CPU Core") + THERMAL_NAME = ("PCB BACK", "PCB FRONT", "AC5X CORE", "OOB PHY") def __init__(self, thermal_index): ThermalBase.__init__(self) @@ -39,12 +40,19 @@ class Thermal(ThermalBase): if self.index < 3: i2c_path = self.I2C_CLASS_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] sensor_index = self.I2C_DEV_MAPPING[self.index - 1][1] - sensor_high_suffix = None - sensor_high_crit_suffix = "max" + sensor_high_suffix = "max" + sensor_high_crit_suffix = None hwmon_node = os.listdir(i2c_path)[0] self.SENSOR_DIR = i2c_path + hwmon_node + '/' # SOC temperature sensor + elif self.index == 3: + dev_path = self.AC5X_THERMAL_DIR + sensor_index = 1 + sensor_high_suffix = "max" + sensor_high_crit_suffix = None + self.SENSOR_DIR = dev_path + # else: dev_path = self.HWMON_CLASS_DIR sensor_index = 1 diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py index a829fd80a5..4dc9b6ab5b 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal_actions.py @@ -13,13 +13,17 @@ class SetFanSpeedAction(ThermalPolicyActionBase): # JSON field definition JSON_FIELD_SPEED = 'speed' JSON_FIELD_DEFAULT_SPEED = 'default_speed' + JSON_FIELD_THRESHOLD1_SPEED = 'threshold1_speed' + JSON_FIELD_THRESHOLD2_SPEED = 'threshold2_speed' JSON_FIELD_HIGHTEMP_SPEED = 'hightemp_speed' def __init__(self): """ Constructor of SetFanSpeedAction """ - self.default_speed = 50 + self.default_speed = 25 + self.threshold1_speed=40 + self.threshold2_speed=75 self.hightemp_speed = 100 self.speed = self.default_speed @@ -77,7 +81,9 @@ class ThermalRecoverAction(SetFanSpeedAction): Construct ThermalRecoverAction via JSON. JSON example: { "type": "thermal.temp_check_and_set_all_fan_speed" - "default_speed": "50" + "default_speed": "25", + "threshold1_speed": "40", + "threshold2_speed": "75", "hightemp_speed": "100" } :param json_obj: A JSON object representing a ThermalRecoverAction action. @@ -93,6 +99,26 @@ class ThermalRecoverAction(SetFanSpeedAction): raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. format(SetFanSpeedAction.JSON_FIELD_DEFAULT_SPEED)) + if SetFanSpeedAction.JSON_FIELD_THRESHOLD1_SPEED in json_obj: + threshold1_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_THRESHOLD1_SPEED]) + if threshold1_speed < 0 or threshold1_speed > 100: + raise ValueError('SetFanSpeedAction invalid default speed value {} in JSON policy file, valid value should be [0, 100]'. + format(threshold1_speed)) + self.threshold1_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_THRESHOLD1_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_THRESHOLD1_SPEED)) + + if SetFanSpeedAction.JSON_FIELD_THRESHOLD2_SPEED in json_obj: + threshold2_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_THRESHOLD2_SPEED]) + if threshold2_speed < 0 or threshold2_speed > 100: + raise ValueError('SetFanSpeedAction invalid default speed value {} in JSON policy file, valid value should be [0, 100]'. + format(threshold2_speed)) + self.threshold2_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_THRESHOLD2_SPEED]) + else: + raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. + format(SetFanSpeedAction.JSON_FIELD_THRESHOLD2_SPEED)) + if SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED in json_obj: hightemp_speed = float(json_obj[SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED]) if hightemp_speed < 0 or hightemp_speed > 100: @@ -103,7 +129,7 @@ class ThermalRecoverAction(SetFanSpeedAction): raise ValueError('SetFanSpeedAction missing mandatory field {} in JSON policy file'. format(SetFanSpeedAction.JSON_FIELD_HIGHTEMP_SPEED)) - sonic_logger.log_warning("ThermalRecoverAction: default: {}, hightemp: {}".format(self.default_speed, self.hightemp_speed)) + sonic_logger.log_warning("ThermalRecoverAction: default: {}, threshold1: {}, threshold2: {}, hightemp: {}".format(self.default_speed, self.threshold1_speed, self.threshold2_speed, self.hightemp_speed)) def execute(self, thermal_info_dict): """ @@ -116,9 +142,13 @@ class ThermalRecoverAction(SetFanSpeedAction): isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): thermal_info_obj = thermal_info_dict[ThermalInfo.INFO_NAME] - if thermal_info_obj.is_warm_up_and_over_high_threshold(): - ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.hightemp_speed) - elif thermal_info_obj.is_cool_down_and_below_low_threshold(): + if thermal_info_obj.is_set_fan_high_temp_speed(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.hightemp_speed) + elif thermal_info_obj.is_set_fan_threshold_two_speed(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.threshold2_speed) + elif thermal_info_obj.is_set_fan_threshold_one_speed(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.threshold1_speed) + elif thermal_info_obj.is_set_fan_default_speed(): ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.default_speed) diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py index cd0a0591cd..cf9b0cdee6 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/thermal_infos.py @@ -1,6 +1,8 @@ from sonic_platform_base.sonic_thermal_control.thermal_info_base import ThermalPolicyInfoBase from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object +from sonic_py_common.logger import Logger +logger = Logger() @thermal_json_object('fan_info') class FanInfo(ThermalPolicyInfoBase): @@ -67,12 +69,17 @@ class ThermalInfo(ThermalPolicyInfoBase): INFO_NAME = 'thermal_info' def __init__(self): - self.init = False - self._old_avg_temp = 0 - self._current_avg_temp = 0 + self._old_threshold_level = -1 + self._current_threshold_level = 0 + self._num_fan_levels = 3 self._high_crital_threshold = 75 - self._high_threshold = 45 - self._low_threshold = 40 + self._level_up_threshold = [[31,39,58,46], + [39,46,65,54], + [51,57,77,68]] + + self._level_down_threshold = [[24,31,47,40], + [31,38,53,46], + [48,54,72,63]] def collect(self, chassis): """ @@ -82,46 +89,84 @@ class ThermalInfo(ThermalPolicyInfoBase): """ self._temps = [] self._over_high_critical_threshold = False - self._warm_up_and_over_high_threshold = False - self._cool_down_and_below_low_threshold = False + self._set_fan_default_speed = False + self._set_fan_threshold_one_speed = False + self._set_fan_threshold_two_speed = False + self._set_fan_high_temp_speed = False # Calculate average temp within the device - temp = 0 num_of_thermals = chassis.get_num_thermals() for index in range(num_of_thermals): self._temps.insert(index, chassis.get_thermal(index).get_temperature()) - temp += self._temps[index] + - self._current_avg_temp = temp / num_of_thermals + # Find current required threshold level + max_level =0 + min_level = [self._num_fan_levels for i in range(num_of_thermals)] + for index in range(num_of_thermals): + for level in range(self._num_fan_levels): - # Special case if first time - if self.init is False: - self._old_avg_temp = self._current_avg_temp - self.init = True + if self._temps[index]>self._level_up_threshold[level][index]: + if max_levellevel: + min_level[index]=level - # Check if new average temp exceeds high threshold value - if self._current_avg_temp >= self._old_avg_temp and self._current_avg_temp >= self._high_threshold: - self._warm_up_and_over_high_threshold = True + max_of_min_level=max(min_level) - # Check if new average temp exceeds low threshold value - if self._current_avg_temp <= self._old_avg_temp and self._current_avg_temp <= self._low_threshold: - self._cool_down_and_below_low_threshold = True + #compare with running threshold level + if max_of_min_level > self._old_threshold_level: + max_of_min_level=self._old_threshold_level + + self._current_threshold_level = max(max_of_min_level,max_level) + + #set fan to max speed if one fan is down + for fan in chassis.get_all_fans(): + if not fan.get_status() : + self._current_threshold_level = 3 + + # Decide fan speed based on threshold level - self._old_avg_temp = self._current_avg_temp + if self._current_threshold_level != self._old_threshold_level: + if self._current_threshold_level == 0: + self._set_fan_default_speed = True + elif self._current_threshold_level == 1: + self._set_fan_threshold_one_speed = True + elif self._current_threshold_level == 2: + self._set_fan_threshold_two_speed = True + elif self._current_threshold_level == 3: + self._set_fan_high_temp_speed = True - def is_warm_up_and_over_high_threshold(self): + self._old_threshold_level=self._current_threshold_level + + def is_set_fan_default_speed(self): """ Retrieves if the temperature is warm up and over high threshold :return: True if the temperature is warm up and over high threshold else False """ - return self._warm_up_and_over_high_threshold + return self._set_fan_default_speed - def is_cool_down_and_below_low_threshold(self): + def is_set_fan_threshold_one_speed(self): """ - Retrieves if the temperature is cold down and below low threshold - :return: True if the temperature is cold down and below low threshold else False + Retrieves if the temperature is warm up and over high threshold + :return: True if the temperature is warm up and over high threshold else False """ - return self._cool_down_and_below_low_threshold + return self._set_fan_threshold_one_speed + + def is_set_fan_threshold_two_speed(self): + """ + Retrieves if the temperature is warm up and over high threshold + :return: True if the temperature is warm up and over high threshold else False + """ + return self._set_fan_threshold_two_speed + + def is_set_fan_high_temp_speed(self): + """ + Retrieves if the temperature is warm up and over high threshold + :return: True if the temperature is warm up and over high threshold else False + """ + return self._set_fan_high_temp_speed def is_over_high_critical_threshold(self): """ diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/watchdog.py b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/watchdog.py index e351c90fe5..cf655448d6 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/watchdog.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/sonic_platform/watchdog.py @@ -11,6 +11,7 @@ from sonic_platform_base.watchdog_base import WatchdogBase from sonic_py_common import logger """ ioctl constants """ +IO_WRITE = 0x40000000 IO_READ = 0x80000000 IO_SIZE_INT = 0x00040000 IO_READ_WRITE = 0xC0000000 @@ -24,6 +25,8 @@ 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 """ @@ -49,6 +52,7 @@ class WatchdogImplBase(WatchdogBase): Open a watchdog handle @param wd_device_path Path to watchdog device """ + super(WatchdogImplBase, self).__init__() self.watchdog_path = wd_device_path self.watchdog = os.open(self.watchdog_path, os.O_WRONLY) diff --git a/platform/marvell-arm64/sonic-platform-nokia/7215/utils/sonic_ssd.py b/platform/marvell-arm64/sonic-platform-nokia/7215/utils/sonic_ssd.py index 5065b47086..563a0b22ce 100644 --- a/platform/marvell-arm64/sonic-platform-nokia/7215/utils/sonic_ssd.py +++ b/platform/marvell-arm64/sonic-platform-nokia/7215/utils/sonic_ssd.py @@ -44,6 +44,4 @@ class EmmcUtil(SsdBase): return '' def SsdUtil(diskdev): - if os.path.basename(diskdev).startswith('mmcblk'): - return EmmcUtil(diskdev) - return SsdUtilDefault(diskdev) + return EmmcUtil('/dev/mmcblk0') diff --git a/platform/marvell-arm64/sonic_fit.its b/platform/marvell-arm64/sonic_fit.its index b70877b277..1671dd19ef 100644 --- a/platform/marvell-arm64/sonic_fit.its +++ b/platform/marvell-arm64/sonic_fit.its @@ -29,6 +29,17 @@ algo = "sha1"; }; }; + fdt_7215_a1 { + description = "Flattened Device Tree blob for 7215_IXS_A1"; + data = /incbin/("/usr/lib/linux-image-5.10.0-18-2-arm64/marvell/7215-ixs-a1.dtb"); + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + load = <0x2 0x1000000>; + hash@1 { + algo = "sha1"; + }; + }; ramdisk_ac5x { description = "ramdisk for AC5x"; data = /incbin/("/boot/initrd.img-5.10.0-18-2-arm64"); @@ -54,5 +65,14 @@ algo = "sha1"; }; }; + conf_7215_a1 { + description = "Boot Linux kernel with FDT blob + ramdisk for 7125_IXS_A1"; + kernel = "kernel_ac5x"; + fdt = "fdt_7215_a1"; + ramdisk = "ramdisk_ac5x"; + hash@1 { + algo = "sha1"; + }; + }; }; };