Skip to content

Commit aa601f4

Browse files
Wirut Getbamrungpjaipakdee19pphuchar
authored
[device/celestica]: Implement Seastone2 platform API (#5080)
Implement Seastone2 platform API: 1. Implement Fan APIs. 2. Implement Psu APIs. 3. Implement Thermal APIs. 4. Implement Component APIs. 5. Implement Chassis APIs. 6. Implement Sfp APIs. 7. Implement Watchdog APIs. (Required new CPLD version) 8. Upgrade switchboard driver to support port insert/remove interrupt 9. Init all above APIs class on chassis API. Co-authored-by: pjaipakdee <jai.peerapong@gmail.com> Co-authored-by: Pradchaya P <pphuchar@celestica.com>
1 parent e9918ba commit aa601f4

File tree

25 files changed

+5482
-739
lines changed

25 files changed

+5482
-739
lines changed

device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"skip_ledd": true,
33
"skip_xcvrd": false,
44
"skip_psud": false,
5-
"skip_syseepromd": false
5+
"skip_syseepromd": false,
6+
"skip_fancontrol": true
67
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"eeprom": "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom",
3+
"get_reboot_cause": {
4+
"output_source": "ipmitool",
5+
"command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x06",
6+
"output_translator": {
7+
"00": "Hardware - Other",
8+
"11": "Hardware - Other",
9+
"22": "Non-Hardware",
10+
"33": "Hardware - Other",
11+
"44": "Non-Hardware",
12+
"55": "Non-Hardware",
13+
"77": "Watchdog",
14+
"88": "Thermal Overload: CPU",
15+
"99": "Thermal Overload: ASIC"
16+
}
17+
},
18+
"get_reboot_description": {
19+
"output_source": "ipmitool",
20+
"command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x06",
21+
"output_translator": {
22+
"00": "The last reset is power cycle reset (set register 0xA164)",
23+
"11": "The last reset is Power on reset",
24+
"22": "The last reset is soft-set CPU warm reset",
25+
"33": "The last reset is soft-set CPU cold reset",
26+
"44": "The last reset is CPU warm reset",
27+
"55": "The last reset is CPU cold reset",
28+
"77": "The last reset is watchdog reset",
29+
"88": "The last reset is CPU thermal overload",
30+
"99": "The last reset is ASIC thermal overload"
31+
}
32+
},
33+
"get_watchdog": {
34+
"output_source": "class",
35+
"host_path": "/usr/share/sonic/device/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py",
36+
"pmon_path": "/usr/share/sonic/platform/sonic_platform_config/watchdog.py",
37+
"class": "Watchdog"
38+
},
39+
"get_change_event": {
40+
"output_source": "class",
41+
"host_path": "/usr/share/sonic/device/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py",
42+
"pmon_path": "/usr/share/sonic/platform/sonic_platform_config/event.py",
43+
"class": "SfpEvent"
44+
}
45+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"component_num": 5,
3+
"get_name": {
4+
"output_source": "value_list",
5+
"value_list": [
6+
"BIOS",
7+
"CPLD_BASEBOARD",
8+
"CPLD_SWITCHBOARD",
9+
"FPGA",
10+
"BMC"
11+
]
12+
},
13+
"get_description": {
14+
"output_source": "value_list",
15+
"value_list": [
16+
"Used to perform hardware initialization during the booting process",
17+
"Used to control the system power & reset, Control FAN, UART Mux etc",
18+
"Used for managing QSFP ports",
19+
"Used for managing I2C, SPI, PCIe etc",
20+
"Used for monitoring and managing whole system"
21+
]
22+
},
23+
"get_firmware_version": {
24+
"output_source": "function",
25+
"function": [
26+
"_get_bios_ver",
27+
"_get_base_cpld_ver",
28+
"_get_sw_cpld_ver",
29+
"_get_fpga_ver",
30+
"_get_bmc_ver"
31+
]
32+
},
33+
"_get_bmc_ver": {
34+
"output_source": "ipmitool",
35+
"command": "ipmitool mc info | grep 'Firmware Revision'",
36+
"output_translator": "'{}'.split(':')[-1].strip()"
37+
},
38+
"_get_bios_ver": {
39+
"output_source": "txt_file",
40+
"path": "/sys/class/dmi/id/bios_version"
41+
},
42+
"_get_base_cpld_ver": {
43+
"output_source": "hex_version_file",
44+
"num_of_points": 1,
45+
"num_of_bits": 8,
46+
"path": "/sys/devices/platform/baseboard/version"
47+
},
48+
"_get_sw_cpld_ver": {
49+
"output_source": "hex_version_getreg",
50+
"num_of_points": 1,
51+
"num_of_bits": 8,
52+
"reg_addr": "0x00",
53+
"path": "/sys/devices/platform/switchboard/CPLD1/getreg"
54+
},
55+
"_get_fpga_ver": {
56+
"output_source": "hex_version_getreg",
57+
"num_of_points": 1,
58+
"num_of_bits": 32,
59+
"reg_addr": "0x00",
60+
"path": "/sys/devices/platform/switchboard/FPGA/getreg"
61+
}
62+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env python
2+
3+
#############################################################################
4+
# Celestica Seastone2
5+
#
6+
# SfpEvent contains an implementation of SONiC Platform Base API
7+
#
8+
#############################################################################
9+
try:
10+
import time
11+
import os
12+
from sonic_platform.common import Common
13+
except ImportError as e:
14+
raise ImportError(str(e) + "- required module not found")
15+
16+
17+
PLATFORM_PATH = "/sys/devices/platform/"
18+
SWITCH_BRD_PLATFORM = "switchboard"
19+
POLL_INTERVAL = 1
20+
21+
22+
class SfpEvent:
23+
''' Listen to insert/remove sfp events '''
24+
25+
PORT_INFO_DIR = 'SFF'
26+
PATH_INT_SYSFS = "{0}/{port_name}/{type_prefix}_isr_flags"
27+
PATH_INTMASK_SYSFS = "{0}/{port_name}/{type_prefix}_isr_mask"
28+
PATH_PRS_SYSFS = "{0}/{port_name}/{prs_file_name}"
29+
PRESENT_EN = 0x01
30+
31+
def __init__(self, sfp_list):
32+
self.num_sfp = len(sfp_list)
33+
self._api_common = Common()
34+
self._initialize_interrupts()
35+
36+
def _initialize_interrupts(self):
37+
sfp_info_obj = {}
38+
port_info_path = os.path.join(
39+
PLATFORM_PATH, SWITCH_BRD_PLATFORM, self.PORT_INFO_DIR)
40+
41+
for index in range(self.num_sfp):
42+
port_num = index + 1
43+
port_name = "QSFP{}".format(port_num)
44+
port_type = "qsfp"
45+
sysfs_prs_file = "{}_modprs".format(port_type)
46+
47+
sfp_info_obj[index] = {}
48+
sfp_info_obj[index]['intmask_sysfs'] = self.PATH_INTMASK_SYSFS.format(
49+
port_info_path,
50+
port_name=port_name,
51+
type_prefix=port_type)
52+
53+
sfp_info_obj[index]['int_sysfs'] = self.PATH_INT_SYSFS.format(
54+
port_info_path,
55+
port_name=port_name,
56+
type_prefix=port_type)
57+
58+
sfp_info_obj[index]['prs_sysfs'] = self.PATH_PRS_SYSFS.format(
59+
port_info_path,
60+
port_name=port_name,
61+
prs_file_name=sysfs_prs_file)
62+
63+
self._api_common.write_txt_file(
64+
sfp_info_obj[index]["intmask_sysfs"], hex(self.PRESENT_EN))
65+
66+
self.sfp_info_obj = sfp_info_obj
67+
68+
def _is_port_device_present(self, port_idx):
69+
prs_path = self.sfp_info_obj[port_idx]["prs_sysfs"]
70+
is_present = 1 - int(self._api_common.read_txt_file(prs_path))
71+
return is_present
72+
73+
def _update_port_event_object(self, interrup_devices, port_dict):
74+
for port_idx in interrup_devices:
75+
device_id = str(port_idx + 1)
76+
port_dict[device_id] = str(self._is_port_device_present(port_idx))
77+
return port_dict
78+
79+
def _clear_event_flag(self, path):
80+
self._api_common.write_txt_file(path, hex(0xff))
81+
time.sleep(0.1)
82+
self._api_common.write_txt_file(path, hex(0x0))
83+
84+
def _check_all_port_interrupt_event(self):
85+
interrupt_devices = {}
86+
for i in range(self.num_sfp):
87+
int_sysfs = self.sfp_info_obj[i]["int_sysfs"]
88+
interrupt_flags = self._api_common.read_txt_file(int_sysfs)
89+
if interrupt_flags != '0x00':
90+
interrupt_devices[i] = 1
91+
self._clear_event_flag(int_sysfs)
92+
return interrupt_devices
93+
94+
def get_event(self, timeout):
95+
sleep_time = min(
96+
timeout, POLL_INTERVAL) if timeout != 0 else POLL_INTERVAL
97+
start_milli_time = int(round(time.time() * 1000))
98+
int_sfp = {}
99+
100+
while True:
101+
chk_sfp = self._check_all_port_interrupt_event()
102+
int_sfp = self._update_port_event_object(
103+
chk_sfp, int_sfp) if chk_sfp else int_sfp
104+
current_milli_time = int(round(time.time() * 1000))
105+
if (int_sfp) or \
106+
(timeout != 0 and current_milli_time - start_milli_time > timeout):
107+
break
108+
109+
time.sleep(sleep_time)
110+
111+
change_dict = dict()
112+
change_dict['sfp'] = int_sfp
113+
114+
return True, change_dict

0 commit comments

Comments
 (0)