From 03a4addff10a435741666bb64eaafb247d258a09 Mon Sep 17 00:00:00 2001 From: Prince George <45705344+prgeor@users.noreply.github.com> Date: Wed, 14 Jul 2021 11:23:28 +0530 Subject: [PATCH] Introduce mgmtinit delay after transceiver module insertion (#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 --- sonic-xcvrd/xcvrd/xcvrd.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 563145a8e956..384a75d37ae6 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -39,6 +39,12 @@ SELECT_TIMEOUT_MSECS = 1000 +# Mgminit time required as per CMIS spec +MGMT_INIT_TIME_DELAY_SECS = 2 + +# SFP insert event poll duration +SFP_INSERT_EVENT_POLL_PERIOD_MSECS = 1000 + DOM_INFO_UPDATE_PERIOD_SECS = 60 TIME_FOR_SFP_READY_SECS = 1 XCVRD_MAIN_THREAD_SLEEP_SECS = 60 @@ -171,6 +177,20 @@ def _wrapper_get_transceiver_dom_threshold_info(physical_port): pass return platform_sfputil.get_transceiver_dom_threshold_info_dict(physical_port) +# Soak SFP insert event until management init completes +def _wrapper_soak_sfp_insert_event(sfp_insert_events, port_dict): + for key, value in list(port_dict.items()): + if value == sfp_status_helper.SFP_STATUS_INSERTED: + sfp_insert_events[key] = time.time() + del port_dict[key] + elif value == sfp_status_helper.SFP_STATUS_REMOVED: + if key in sfp_insert_events: + del sfp_insert_events[key] + + for key, itime in list(sfp_insert_events.items()): + if time.time() - itime >= MGMT_INIT_TIME_DELAY_SECS: + port_dict[key] = sfp_status_helper.SFP_STATUS_INSERTED + del sfp_insert_events[key] def _wrapper_get_transceiver_change_event(timeout): if platform_chassis is not None: @@ -201,8 +221,8 @@ def _wrapper_get_sfp_error_description(physical_port): except NotImplementedError: pass return None -# Remove unnecessary unit from the raw data +# Remove unnecessary unit from the raw data def beautify_dom_info_dict(dom_info_dict, physical_port): 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): # Update port sfp info in db - def post_port_sfp_info_to_db(logical_port_name, table, transceiver_dict, stop_event=threading.Event()): ganged_port = False @@ -903,6 +922,7 @@ class SfpStateUpdateTask(object): def __init__(self): self.task_process = None self.task_stopping_event = multiprocessing.Event() + self.sfp_insert_events = {} def _mapping_event_from_change_event(self, status, port_dict): """ @@ -1020,7 +1040,13 @@ def task_worker(self, stopping_event, sfp_error_event, y_cable_presence): while not stopping_event.is_set(): next_state = state time_start = time.time() + # Ensure not to block for any event if sfp insert event is pending + if self.sfp_insert_events: + timeout = SFP_INSERT_EVENT_POLL_PERIOD_MSECS status, port_dict, error_dict = _wrapper_get_transceiver_change_event(timeout) + if status: + # Soak SFP insert events across various ports (updates port_dict) + _wrapper_soak_sfp_insert_event(self.sfp_insert_events, port_dict) if not port_dict: continue helper_logger.log_debug("Got event {} {} in state {}".format(status, port_dict, state))