Skip to content

Commit 03a4add

Browse files
authored
Introduce mgmtinit delay after transceiver module insertion (sonic-net#201)
As per CMIS spec : http://www.qsfp-dd.com/wp-content/uploads/2021/05/CMIS5p0.pdf (see D.1.3 Software Configuration and Initialization) after module is inserted, delay of 2 seconds is required for MgmtInit to complete. Signed-off-by: Prince George <[email protected]>
1 parent 66e7817 commit 03a4add

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

sonic-xcvrd/xcvrd/xcvrd.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939

4040
SELECT_TIMEOUT_MSECS = 1000
4141

42+
# Mgminit time required as per CMIS spec
43+
MGMT_INIT_TIME_DELAY_SECS = 2
44+
45+
# SFP insert event poll duration
46+
SFP_INSERT_EVENT_POLL_PERIOD_MSECS = 1000
47+
4248
DOM_INFO_UPDATE_PERIOD_SECS = 60
4349
TIME_FOR_SFP_READY_SECS = 1
4450
XCVRD_MAIN_THREAD_SLEEP_SECS = 60
@@ -171,6 +177,20 @@ def _wrapper_get_transceiver_dom_threshold_info(physical_port):
171177
pass
172178
return platform_sfputil.get_transceiver_dom_threshold_info_dict(physical_port)
173179

180+
# Soak SFP insert event until management init completes
181+
def _wrapper_soak_sfp_insert_event(sfp_insert_events, port_dict):
182+
for key, value in list(port_dict.items()):
183+
if value == sfp_status_helper.SFP_STATUS_INSERTED:
184+
sfp_insert_events[key] = time.time()
185+
del port_dict[key]
186+
elif value == sfp_status_helper.SFP_STATUS_REMOVED:
187+
if key in sfp_insert_events:
188+
del sfp_insert_events[key]
189+
190+
for key, itime in list(sfp_insert_events.items()):
191+
if time.time() - itime >= MGMT_INIT_TIME_DELAY_SECS:
192+
port_dict[key] = sfp_status_helper.SFP_STATUS_INSERTED
193+
del sfp_insert_events[key]
174194

175195
def _wrapper_get_transceiver_change_event(timeout):
176196
if platform_chassis is not None:
@@ -201,8 +221,8 @@ def _wrapper_get_sfp_error_description(physical_port):
201221
except NotImplementedError:
202222
pass
203223
return None
204-
# Remove unnecessary unit from the raw data
205224

225+
# Remove unnecessary unit from the raw data
206226

207227
def beautify_dom_info_dict(dom_info_dict, physical_port):
208228
dom_info_dict['temperature'] = strip_unit_and_beautify(dom_info_dict['temperature'], TEMP_UNIT)
@@ -262,7 +282,6 @@ def beautify_dom_threshold_info_dict(dom_info_dict):
262282

263283
# Update port sfp info in db
264284

265-
266285
def post_port_sfp_info_to_db(logical_port_name, table, transceiver_dict,
267286
stop_event=threading.Event()):
268287
ganged_port = False
@@ -903,6 +922,7 @@ class SfpStateUpdateTask(object):
903922
def __init__(self):
904923
self.task_process = None
905924
self.task_stopping_event = multiprocessing.Event()
925+
self.sfp_insert_events = {}
906926

907927
def _mapping_event_from_change_event(self, status, port_dict):
908928
"""
@@ -1020,7 +1040,13 @@ def task_worker(self, stopping_event, sfp_error_event, y_cable_presence):
10201040
while not stopping_event.is_set():
10211041
next_state = state
10221042
time_start = time.time()
1043+
# Ensure not to block for any event if sfp insert event is pending
1044+
if self.sfp_insert_events:
1045+
timeout = SFP_INSERT_EVENT_POLL_PERIOD_MSECS
10231046
status, port_dict, error_dict = _wrapper_get_transceiver_change_event(timeout)
1047+
if status:
1048+
# Soak SFP insert events across various ports (updates port_dict)
1049+
_wrapper_soak_sfp_insert_event(self.sfp_insert_events, port_dict)
10241050
if not port_dict:
10251051
continue
10261052
helper_logger.log_debug("Got event {} {} in state {}".format(status, port_dict, state))

0 commit comments

Comments
 (0)