[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:
parent
3ae3eeda35
commit
73a17d8876
@ -84,7 +84,7 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
# Initialize DMI data
|
# Initialize DMI data
|
||||||
self.dmi_data = None
|
self.dmi_data = None
|
||||||
|
|
||||||
# move the initialization of each components to their dedicated initializer
|
# move the initialization of each components to their dedicated initializer
|
||||||
# which will be called from platform
|
# which will be called from platform
|
||||||
#
|
#
|
||||||
@ -261,7 +261,7 @@ class Chassis(ChassisBase):
|
|||||||
def get_revision(self):
|
def get_revision(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the hardware revision of the device
|
Retrieves the hardware revision of the device
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
string: Revision value of device
|
string: Revision value of device
|
||||||
"""
|
"""
|
||||||
@ -269,7 +269,7 @@ class Chassis(ChassisBase):
|
|||||||
self.dmi_data = self._parse_dmi(DMI_FILE)
|
self.dmi_data = self._parse_dmi(DMI_FILE)
|
||||||
|
|
||||||
return self.dmi_data.get(DMI_VERSION, "N/A")
|
return self.dmi_data.get(DMI_VERSION, "N/A")
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
# SFP methods
|
# SFP methods
|
||||||
##############################################
|
##############################################
|
||||||
@ -290,7 +290,7 @@ class Chassis(ChassisBase):
|
|||||||
Retrieves all sfps available on this chassis
|
Retrieves all sfps available on this chassis
|
||||||
|
|
||||||
Returns:
|
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
|
available on this chassis
|
||||||
"""
|
"""
|
||||||
if not self.sfp_module_full_initialized:
|
if not self.sfp_module_full_initialized:
|
||||||
@ -361,7 +361,7 @@ class Chassis(ChassisBase):
|
|||||||
Note:
|
Note:
|
||||||
We overload this method to ensure that watchdog is only initialized
|
We overload this method to ensure that watchdog is only initialized
|
||||||
when it is referenced. Currently, only one daemon can open the watchdog.
|
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
|
try opening watchdog when loading and constructing a chassis object
|
||||||
and fail. By doing so we can eliminate that risk.
|
and fail. By doing so we can eliminate that risk.
|
||||||
"""
|
"""
|
||||||
@ -450,7 +450,7 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
def _verify_reboot_cause(self, filename):
|
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)
|
/var/run/hwmanagement/system (which is defined as REBOOT_CAUSE_ROOT)
|
||||||
If a reboot cause file doesn't exists, returns '0'.
|
If a reboot cause file doesn't exists, returns '0'.
|
||||||
'''
|
'''
|
||||||
@ -550,7 +550,7 @@ class Chassis(ChassisBase):
|
|||||||
- True if call successful, False if not;
|
- True if call successful, False if not;
|
||||||
- A nested dictionary where key is a device type,
|
- A nested dictionary where key is a device type,
|
||||||
value is a dictionary with key:value pairs in the format of
|
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
|
where device_id is the device ID for this device and
|
||||||
device_event,
|
device_event,
|
||||||
status='1' represents device inserted,
|
status='1' represents device inserted,
|
||||||
@ -594,10 +594,6 @@ class Chassis(ChassisBase):
|
|||||||
:param port_dict: SFP event data
|
:param port_dict: SFP event data
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
# SFP not initialize yet, do nothing
|
|
||||||
if not self.sfp_module_full_initialized:
|
|
||||||
return
|
|
||||||
|
|
||||||
from . import sfp
|
from . import sfp
|
||||||
for index, status in port_dict.items():
|
for index, status in port_dict.items():
|
||||||
if status == sfp.SFP_STATUS_INSERTED:
|
if status == sfp.SFP_STATUS_INSERTED:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import pytest
|
import pytest
|
||||||
from mock import MagicMock
|
from mock import MagicMock, patch
|
||||||
from .mock_platform import MockFan
|
from .mock_platform import MockFan
|
||||||
|
|
||||||
test_path = os.path.dirname(os.path.abspath(__file__))
|
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"
|
os.environ["PLATFORM_API_UNIT_TESTING"] = "1"
|
||||||
|
|
||||||
from sonic_py_common import device_info
|
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
|
from sonic_platform.chassis import Chassis
|
||||||
|
|
||||||
@ -123,3 +123,16 @@ def test_sfp_get_error_status():
|
|||||||
description = sfp.get_error_description()
|
description = sfp.get_error_description()
|
||||||
|
|
||||||
assert description == expected_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
|
||||||
|
Reference in New Issue
Block a user