Skip to content

Commit 66877d3

Browse files
author
Wirut Getbamrung
authored
Merge pull request sonic-net#196 from mudsut4ke/201911_cel_wb_questone2bd_get_event_change
[device/celestica]: Add support for fan/voltage event to questone2bd get_change_event api
2 parents c8c8294 + 28cb4b6 commit 66877d3

File tree

3 files changed

+375
-132
lines changed

3 files changed

+375
-132
lines changed

device/celestica/x86_64-cel_questone2bd-r0/sonic_platform/chassis.py

+74-112
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@
3838
BASE_CPLD_PLATFORM = "questone2bd.cpldb"
3939
BASE_GETREG_PATH = "/sys/devices/platform/{}/getreg".format(BASE_CPLD_PLATFORM)
4040

41-
SWITCH_BRD_PLATFORM = "questone2bd.switchboard"
42-
PORT_INFO_PATH = "/sys/devices/platform/{}/SFF".format(SWITCH_BRD_PLATFORM)
43-
PATH_INT_SYSFS = "{0}/{port_name}/{type_prefix}_isr_flags"
44-
PATH_INTMASK_SYSFS = "{0}/{port_name}/{type_prefix}_isr_mask"
45-
PATH_PRS_SYSFS = "{0}/{port_name}/{prs_file_name}"
4641

4742
class Chassis(ChassisBase):
4843
"""Platform-specific Chassis class"""
@@ -51,14 +46,13 @@ def __init__(self):
5146
ChassisBase.__init__(self)
5247
self._api_helper = APIHelper()
5348
self.sfp_module_initialized = False
49+
self.fan_module_initialized = False
5450
self.__initialize_eeprom()
55-
self.POLL_INTERVAL = 1
5651

5752
if not self._api_helper.is_host():
5853
self.__initialize_fan()
5954
self.__initialize_psu()
6055
self.__initialize_thermals()
61-
self.__initialize_interrupts()
6256
else:
6357
self.__initialize_components()
6458

@@ -81,6 +75,7 @@ def __initialize_fan(self):
8175
for fan_index in range(0, NUM_FAN):
8276
fan = Fan(fant_index, fan_index)
8377
self._fan_list.append(fan)
78+
self.fan_module_initialized = True
8479

8580
def __initialize_thermals(self):
8681
from sonic_platform.thermal import Thermal
@@ -98,46 +93,6 @@ def __initialize_components(self):
9893
component = Component(index)
9994
self._component_list.append(component)
10095

101-
def __initialize_interrupts(self):
102-
# Initial Interrupt MASK for QSFP, SFP
103-
sfp_info_obj = {}
104-
105-
present_en = 0x10
106-
Rxlos_IntL_en = 0x01
107-
event_mask = present_en
108-
109-
for index in range(NUM_SFP):
110-
port_num = index + 1
111-
if port_num in range(SFP_PORT_START, SFP_PORT_END+1):
112-
port_name = "SFP{}".format(str(port_num - SFP_PORT_START + 1))
113-
port_type = "sfp"
114-
sysfs_prs_file = "{}_modabs".format(port_type)
115-
elif port_num in range(QSFP_PORT_START, QSFP_PORT_END+1):
116-
port_name = "QSFP{}".format(str(port_num - QSFP_PORT_START + 1))
117-
port_type = "qsfp"
118-
sysfs_prs_file = "{}_modprs".format(port_type)
119-
120-
sfp_info_obj[index] = {}
121-
sfp_info_obj[index]['intmask_sysfs'] = PATH_INTMASK_SYSFS.format(
122-
PORT_INFO_PATH,
123-
port_name = port_name,
124-
type_prefix = port_type)
125-
126-
sfp_info_obj[index]['int_sysfs'] = PATH_INT_SYSFS.format(
127-
PORT_INFO_PATH,
128-
port_name = port_name,
129-
type_prefix = port_type)
130-
131-
sfp_info_obj[index]['prs_sysfs'] = PATH_PRS_SYSFS.format(
132-
PORT_INFO_PATH,
133-
port_name = port_name,
134-
prs_file_name = sysfs_prs_file)
135-
136-
self._api_helper.write_file(
137-
sfp_info_obj[index]["intmask_sysfs"], hex(event_mask))
138-
139-
self.sfp_info_obj = sfp_info_obj
140-
14196
def get_base_mac(self):
14297
"""
14398
Retrieves the base MAC address for the chassis
@@ -304,78 +259,85 @@ def get_status(self):
304259
###################### Event methods #########################
305260
##############################################################
306261

307-
def __is_port_device_present(self, port_idx):
308-
prs_path = self.sfp_info_obj[port_idx]["prs_sysfs"]
309-
is_present = 1 - int(self._api_helper.read_txt_file(prs_path))
310-
return is_present
311-
312-
def __update_port_event_object(self, interrup_devices):
313-
port_dict = {}
314-
event_obj = {'sfp':port_dict}
315-
for port_idx in interrup_devices:
316-
device_id = str(port_idx + 1)
317-
port_dict[device_id] = str(self.__is_port_device_present(port_idx))
318-
319-
if len(port_dict):
320-
event_obj['sfp'] = port_dict
321-
322-
return event_obj
323-
324-
def __check_all_port_interrupt_event(self):
325-
interrupt_devices = {}
326-
for i in range(NUM_SFP):
327-
int_sysfs = self.sfp_info_obj[i]["int_sysfs"]
328-
interrupt_flags = self._api_helper.read_txt_file(int_sysfs)
329-
if interrupt_flags != '0x00':
330-
interrupt_devices[i] = 1
331-
return interrupt_devices
332-
333262
def get_change_event(self, timeout=0):
334263
"""
335264
Returns a nested dictionary containing all devices which have
336265
experienced a change at chassis level
266+
337267
Args:
338268
timeout: Timeout in milliseconds (optional). If timeout == 0,
339269
this method will block until a change is detected.
270+
340271
Returns:
341272
(bool, dict):
342-
- True if call successful, False if not;
343-
- A nested dictionary where key is a device type,
344-
value is a dictionary with key:value pairs in the
345-
format of {'device_id':'device_event'},
346-
where device_id is the device ID for this device and
347-
device_event,
348-
status='1' represents device inserted,
349-
status='0' represents device removed.
350-
Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}}
351-
indicates that fan 0 has been removed, fan 2
352-
has been inserted and sfp 11 has been removed.
273+
- bool: True if call successful, False if not;
274+
- dict: A nested dictionary where key is a device type,
275+
value is a dictionary with key:value pairs in the format of
276+
{'device_id':'device_event'}, where device_id is the device ID
277+
for this device and device_event.
278+
The known devices's device_id and device_event was defined as table below.
279+
-----------------------------------------------------------------
280+
device | device_id | device_event | annotate
281+
-----------------------------------------------------------------
282+
'fan' '<fan number>' '0' Fan removed
283+
'1' Fan inserted
284+
285+
'sfp' '<sfp number>' '0' Sfp removed
286+
'1' Sfp inserted
287+
'2' I2C bus stuck
288+
'3' Bad eeprom
289+
'4' Unsupported cable
290+
'5' High Temperature
291+
'6' Bad cable
292+
293+
'voltage' '<monitor point>' '0' Vout normal
294+
'1' Vout abnormal
295+
--------------------------------------------------------------------
296+
Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0', '12':'1'},
297+
'voltage':{'U20':'0', 'U21':'1'}}
298+
Indicates that:
299+
fan 0 has been removed, fan 2 has been inserted.
300+
sfp 11 has been removed, sfp 12 has been inserted.
301+
monitored voltage U20 became normal, voltage U21 became abnormal.
302+
Note: For sfp, when event 3-6 happened, the module will not be avalaible,
303+
XCVRD shall stop to read eeprom before SFP recovered from error status.
353304
"""
354-
if timeout == 0:
355-
timer = self.POLL_INTERVAL
356-
while True:
357-
interrupt_devices = self.__check_all_port_interrupt_event()
358-
if len(interrupt_devices):
359-
break
360-
else:
361-
time.sleep(timer)
362-
events_dict = self.__update_port_event_object(interrupt_devices)
363-
return (True, events_dict)
364-
else:
365-
timeout = timeout / float(1000)
366-
timer = min(timeout, self.POLL_INTERVAL)
367-
368-
while True:
369-
start_time = time.time()
370-
interrupt_devices = self.__check_all_port_interrupt_event()
371-
if len(interrupt_devices):
372-
break
373-
374-
if timeout <= 0:
375-
break
376-
else:
377-
time.sleep(timer)
378-
elasped_time = time.time() - start_time
379-
timeout = round(timeout - elasped_time, 3)
380-
events_dict = self.__update_port_event_object(interrupt_devices)
381-
return (True, events_dict)
305+
from sonic_platform.event import FanEvent, SfpEvent, VoltageEvent, POLL_INTERVAL
306+
307+
if not self.fan_module_initialized:
308+
self.__initialize_fan()
309+
310+
if not self.sfp_module_initialized:
311+
self.__initialize_sfp()
312+
313+
fan_event = FanEvent(self._fan_list)
314+
sfp_event = SfpEvent(self._sfp_list)
315+
voltage_event = VoltageEvent()
316+
317+
cur_fan_state = fan_event.get_fan_state()
318+
cur_volt_state = voltage_event.get_voltage_state()
319+
start_milli_time = int(round(time.time() * 1000))
320+
int_sfp, int_fan, int_volt = {}, {}, {}
321+
322+
sleep_time = min(
323+
timeout, POLL_INTERVAL) if timeout != 0 else POLL_INTERVAL
324+
while True:
325+
chk_sfp = sfp_event.check_all_port_interrupt_event()
326+
int_sfp = sfp_event.update_port_event_object(
327+
chk_sfp, int_sfp) if chk_sfp else int_sfp
328+
int_fan = fan_event.check_fan_status(cur_fan_state, int_fan)
329+
int_volt = voltage_event.check_voltage_status(cur_volt_state, int_volt)
330+
331+
current_milli_time = int(round(time.time() * 1000))
332+
if (int_sfp or int_fan or int_volt) or \
333+
(timeout != 0 and current_milli_time - start_milli_time > timeout):
334+
break
335+
336+
time.sleep(sleep_time)
337+
338+
change_dict = dict()
339+
change_dict['fan'] = int_fan
340+
change_dict['sfp'] = int_sfp
341+
change_dict['voltage'] = int_volt
342+
343+
return True, change_dict

0 commit comments

Comments
 (0)