Skip to content

Commit 4257c79

Browse files
author
Wirut Getbamrung
authored
[device/celestica]: Add xcvrd event support for Seastone-DX010 (#5896)
- Add sysfs interrupt to notify userspace app of external interrupt - Implement get_change_event() in chassis api.
1 parent 9580b04 commit 4257c79

File tree

7 files changed

+1419
-231
lines changed

7 files changed

+1419
-231
lines changed

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

+41-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
try:
1010
import sys
1111
from sonic_platform_base.chassis_base import ChassisBase
12+
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
13+
from sonic_py_common import device_info
14+
from .event import SfpEvent
1215
from .helper import APIHelper
1316
except ImportError as e:
1417
raise ImportError(str(e) + "- required module not found")
@@ -45,9 +48,14 @@ def __init__(self):
4548
self.__initialize_components()
4649

4750
def __initialize_sfp(self):
51+
sfputil_helper = SfpUtilHelper()
52+
port_config_file_path = device_info.get_path_to_port_config_file()
53+
sfputil_helper.read_porttab_mappings(port_config_file_path, 0)
54+
4855
from sonic_platform.sfp import Sfp
4956
for index in range(0, NUM_SFP):
50-
sfp = Sfp(index)
57+
name_idx = 0 if index+1 == NUM_SFP else index+1
58+
sfp = Sfp(index, sfputil_helper.logical[name_idx])
5159
self._sfp_list.append(sfp)
5260
self.sfp_module_initialized = True
5361

@@ -141,6 +149,38 @@ def get_reboot_cause(self):
141149

142150
return prev_reboot_cause
143151

152+
153+
def get_change_event(self, timeout=0):
154+
"""
155+
Returns a nested dictionary containing all devices which have
156+
experienced a change at chassis level
157+
Args:
158+
timeout: Timeout in milliseconds (optional). If timeout == 0,
159+
this method will block until a change is detected.
160+
Returns:
161+
(bool, dict):
162+
- True if call successful, False if not;
163+
- A nested dictionary where key is a device type,
164+
value is a dictionary with key:value pairs in the format of
165+
{'device_id':'device_event'},
166+
where device_id is the device ID for this device and
167+
device_event,
168+
status='1' represents device inserted,
169+
status='0' represents device removed.
170+
Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}}
171+
indicates that fan 0 has been removed, fan 2
172+
has been inserted and sfp 11 has been removed.
173+
"""
174+
# SFP event
175+
if not self.sfp_module_initialized:
176+
self.__initialize_sfp()
177+
178+
sfp_event = SfpEvent(self._sfp_list).get_sfp_event(timeout)
179+
if sfp_event:
180+
return True, {'sfp': sfp_event}
181+
182+
return False, {'sfp': {}}
183+
144184
##############################################################
145185
######################## SFP methods #########################
146186
##############################################################
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
try:
2+
import select
3+
from .helper import APIHelper
4+
from sonic_py_common.logger import Logger
5+
except ImportError as e:
6+
raise ImportError(repr(e) + " - required module not found")
7+
8+
9+
class SfpEvent:
10+
''' Listen to insert/remove sfp events '''
11+
12+
QSFP_MODPRS_IRQ = '/sys/devices/platform/dx010_cpld/qsfp_modprs_irq'
13+
GPIO_SUS6 = "/sys/devices/platform/slx-ich.0/sci_int_gpio_sus6"
14+
15+
def __init__(self, sfp_list):
16+
self._api_helper = APIHelper()
17+
self._sfp_list = sfp_list
18+
self._logger = Logger()
19+
20+
def get_sfp_event(self, timeout):
21+
epoll = select.epoll()
22+
port_dict = {}
23+
timeout_sec = timeout/1000
24+
25+
try:
26+
# We get notified when there is an SCI interrupt from GPIO SUS6
27+
fd = open(self.GPIO_SUS6, "r")
28+
fd.read()
29+
30+
epoll.register(fd.fileno(), select.EPOLLIN & select.EPOLLET)
31+
events = epoll.poll(timeout=timeout_sec if timeout != 0 else -1)
32+
if events:
33+
# Read the QSFP ABS interrupt & status registers
34+
port_changes = self._api_helper.read_one_line_file(
35+
self.QSFP_MODPRS_IRQ)
36+
changes = int(port_changes, 16)
37+
for sfp in self._sfp_list:
38+
change = (changes >> sfp.port_num-1) & 1
39+
if change == 1:
40+
port_dict[str(sfp.port_num)] = str(
41+
int(sfp.get_presence()))
42+
43+
return port_dict
44+
except Exception as e:
45+
self._logger.log_error("Failed to detect SfpEvent - " + repr(e))
46+
return False
47+
48+
finally:
49+
fd.close()
50+
epoll.close()
51+
52+
return False

device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py

+3-17
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
1818
from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
1919
from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId
20-
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
2120
from .helper import APIHelper
2221
except ImportError as e:
2322
raise ImportError(str(e) + "- required module not found")
@@ -166,19 +165,16 @@ class Sfp(SfpBase):
166165
RESET_PATH = "/sys/devices/platform/dx010_cpld/qsfp_reset"
167166
LP_PATH = "/sys/devices/platform/dx010_cpld/qsfp_lpmode"
168167
PRS_PATH = "/sys/devices/platform/dx010_cpld/qsfp_modprs"
169-
PLATFORM_ROOT_PATH = "/usr/share/sonic/device"
170-
PMON_HWSKU_PATH = "/usr/share/sonic/hwsku"
171168

172-
def __init__(self, sfp_index):
169+
def __init__(self, sfp_index, sfp_name):
173170
SfpBase.__init__(self)
174171
# Init index
175172
self.index = sfp_index
176173
self.port_num = self.index + 1
177174
self.dom_supported = False
178175
self.sfp_type, self.port_name = self.__get_sfp_info()
179176
self._api_helper = APIHelper()
180-
self.platform = self._api_helper.platform
181-
self.hwsku = self._api_helper.hwsku
177+
self.name = sfp_name
182178

183179
# Init eeprom path
184180
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
@@ -233,12 +229,6 @@ def __convert_string_to_num(self, value_str):
233229
else:
234230
return 'N/A'
235231

236-
def __get_path_to_port_config_file(self):
237-
platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.platform])
238-
hwsku_path = "/".join([platform_path, self.hwsku]
239-
) if self._api_helper.is_host() else self.PMON_HWSKU_PATH
240-
return "/".join([hwsku_path, "port_config.ini"])
241-
242232
def __read_eeprom_specific_bytes(self, offset, num_bytes):
243233
sysfsfile_eeprom = None
244234
eeprom_raw = []
@@ -1317,11 +1307,7 @@ def get_name(self):
13171307
Returns:
13181308
string: The name of the device
13191309
"""
1320-
sfputil_helper = SfpUtilHelper()
1321-
sfputil_helper.read_porttab_mappings(
1322-
self.__get_path_to_port_config_file())
1323-
name = sfputil_helper.logical[self.index] or "Unknown"
1324-
return name
1310+
return self.name
13251311

13261312
def get_presence(self):
13271313
"""

platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ start)
4646
modprobe dx010_wdt
4747
modprobe leds-dx010
4848
modprobe lm75
49+
modprobe slx_gpio_ich
4950

5051
found=0
5152
for devnum in 0 1; do
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o
1+
obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o slx_gpio_ich.o

0 commit comments

Comments
 (0)