[Mellanox] [202106] Fix issue: SFP might not be re-initialized after cable plug in (#9387)

- Why I did it
Fix issue: SFP might not be re-initialized after cable plug in. There could be case like:
1. The SFP object was initialized as QSFP type
2. User use adapter to connect a SFP to a QSFP port
3. The SFP object treat the SFP as QSFP and failed to process EEPROM

- How I did it
If a new SFP is plugged, always re-initialize the SFP

- How to verify it
Added unit test case
This commit is contained in:
Junchao-Mellanox 2021-12-14 22:27:26 +08:00 committed by GitHub
parent 3ae3eeda35
commit 73a17d8876
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 13 deletions

View File

@ -84,7 +84,7 @@ class Chassis(ChassisBase):
# Initialize DMI data
self.dmi_data = None
# move the initialization of each components to their dedicated initializer
# which will be called from platform
#
@ -261,7 +261,7 @@ class Chassis(ChassisBase):
def get_revision(self):
"""
Retrieves the hardware revision of the device
Returns:
string: Revision value of device
"""
@ -269,7 +269,7 @@ class Chassis(ChassisBase):
self.dmi_data = self._parse_dmi(DMI_FILE)
return self.dmi_data.get(DMI_VERSION, "N/A")
##############################################
# SFP methods
##############################################
@ -290,7 +290,7 @@ class Chassis(ChassisBase):
Retrieves all sfps available on this chassis
Returns:
A list of objects derived from SfpBase representing all sfps
A list of objects derived from SfpBase representing all sfps
available on this chassis
"""
if not self.sfp_module_full_initialized:
@ -361,7 +361,7 @@ class Chassis(ChassisBase):
Note:
We overload this method to ensure that watchdog is only initialized
when it is referenced. Currently, only one daemon can open the watchdog.
To initialize watchdog in the constructor causes multiple daemon
To initialize watchdog in the constructor causes multiple daemon
try opening watchdog when loading and constructing a chassis object
and fail. By doing so we can eliminate that risk.
"""
@ -450,7 +450,7 @@ class Chassis(ChassisBase):
def _verify_reboot_cause(self, filename):
'''
Open and read the reboot cause file in
Open and read the reboot cause file in
/var/run/hwmanagement/system (which is defined as REBOOT_CAUSE_ROOT)
If a reboot cause file doesn't exists, returns '0'.
'''
@ -550,7 +550,7 @@ class Chassis(ChassisBase):
- True if call successful, False if not;
- A nested dictionary where key is a device type,
value is a dictionary with key:value pairs in the format of
{'device_id':'device_event'},
{'device_id':'device_event'},
where device_id is the device ID for this device and
device_event,
status='1' represents device inserted,
@ -594,10 +594,6 @@ class Chassis(ChassisBase):
:param port_dict: SFP event data
:return:
"""
# SFP not initialize yet, do nothing
if not self.sfp_module_full_initialized:
return
from . import sfp
for index, status in port_dict.items():
if status == sfp.SFP_STATUS_INSERTED:

View File

@ -1,7 +1,7 @@
import os
import sys
import pytest
from mock import MagicMock
from mock import MagicMock, patch
from .mock_platform import MockFan
test_path = os.path.dirname(os.path.abspath(__file__))
@ -11,7 +11,7 @@ sys.path.insert(0, modules_path)
os.environ["PLATFORM_API_UNIT_TESTING"] = "1"
from sonic_py_common import device_info
from sonic_platform.sfp import SFP, SX_PORT_MODULE_STATUS_INITIALIZING, SX_PORT_MODULE_STATUS_PLUGGED, SX_PORT_MODULE_STATUS_UNPLUGGED, SX_PORT_MODULE_STATUS_PLUGGED_WITH_ERROR, SX_PORT_MODULE_STATUS_PLUGGED_DISABLED
from sonic_platform.sfp import SFP, SX_PORT_MODULE_STATUS_INITIALIZING, SX_PORT_MODULE_STATUS_PLUGGED, SX_PORT_MODULE_STATUS_UNPLUGGED, SX_PORT_MODULE_STATUS_PLUGGED_WITH_ERROR, SX_PORT_MODULE_STATUS_PLUGGED_DISABLED, SFP_STATUS_INSERTED
from sonic_platform.chassis import Chassis
@ -123,3 +123,16 @@ def test_sfp_get_error_status():
description = sfp.get_error_description()
assert description == expected_description
@patch('sonic_platform.sfp.SFP.reinit')
def test_reinit_sfps(mock_reinit_sfps):
port_dict = {}
chassis = Chassis()
chassis.reinit_sfps(port_dict)
assert not mock_reinit_sfps.called
port_dict = {1: SFP_STATUS_INSERTED}
chassis.reinit_sfps(port_dict)
assert mock_reinit_sfps.called
assert chassis._sfp_list[0] is not None