From f5c4d3a9e90d03ea2da61ca9d3a9cb2888e51b33 Mon Sep 17 00:00:00 2001 From: Yuanzhe <150663541+yuazhe@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:19:46 +0800 Subject: [PATCH] [Mellanox] fix sfp eeprom unreadable after switching from SW to FW control mode (#19563) - Why I did it The reading of eeprom instantly after switch the module from sw control to fw control might fail, so add a delay Signed-off-by: Yuanzhe, Liu --- .../sonic_platform/chassis.py | 4 +++- .../mlnx-platform-api/sonic_platform/sfp.py | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 935a2fa5f1f8..113bb572d9cd 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -513,16 +513,18 @@ def get_change_event_for_module_host_management_mode(self, timeout): s.on_event(event) if s.in_stable_state(): + self.sfp_module.SFP.wait_sfp_eeprom_ready([s], 2) s.fill_change_event(port_dict) s.refresh_poll_obj(self.poll_obj, self.registered_fds) else: logger.log_debug(f'SFP {sfp_index} does not reach stable state, state={s.state}') - + ready_sfp_set = wait_ready_task.get_ready_set() for sfp_index in ready_sfp_set: s = self._sfp_list[sfp_index] s.on_event(sfp.EVENT_RESET_DONE) if s.in_stable_state(): + self.sfp_module.SFP.wait_sfp_eeprom_ready([s], 2) s.fill_change_event(port_dict) s.refresh_poll_obj(self.poll_obj, self.registered_fds) else: diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index e140c9b02455..20bfa997d97a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -500,6 +500,21 @@ def get_presence(self): return False eeprom_raw = self._read_eeprom(0, 1, log_on_error=False) return eeprom_raw is not None + + @classmethod + def wait_sfp_eeprom_ready(cls, sfp_list, wait_time): + not_ready_list = sfp_list + + while wait_time > 0: + not_ready_list = [s for s in not_ready_list if s.state == STATE_FW_CONTROL and s._read_eeprom(0, 2,False) is None] + if not_ready_list: + time.sleep(0.1) + wait_time -= 0.1 + else: + return + + for s in not_ready_list: + logger.log_error(f'SFP {s.sdk_index} eeprom is not ready') # read eeprom specfic bytes beginning from offset with size as num_bytes def read_eeprom(self, offset, num_bytes): @@ -1724,7 +1739,8 @@ def initialize_sfp_modules(cls, sfp_list): logger.log_error(f'SFP {index} is not in stable state after initializing, state={s.state}') logger.log_notice(f'SFP {index} is in state {s.state} after module initialization') - + cls.wait_sfp_eeprom_ready(sfp_list, 2) + class RJ45Port(NvidiaSFPCommon): """class derived from SFP, representing RJ45 ports"""