[Mellanox] Implement low power mode for cmis host management (#17159)

- Why I did it
For cmis host management mode, the prevous sysfs cannot be used for low power mode setting. This PR reuses existing low power mode implementation in sonic_xcvr package when CMIS host management mode is enabled

- How I did it
Use sonic_xcvr low power mode implementation when CMIS host management mode is enabled.

- How to verify it
Manual test for CMIS host management mode
Regression test for old mode and backward compatible test
This commit is contained in:
Junchao-Mellanox 2023-12-11 16:42:01 +08:00 committed by GitHub
parent ee598deced
commit b0bb3d40d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 0 deletions

View File

@ -397,6 +397,18 @@ class SFP(NvidiaSFPCommon):
Returns:
A Boolean, True if lpmode is enabled, False if disabled
"""
try:
if self.is_sw_control():
api = self.get_xcvr_api()
return api.get_lpmode() if api else False
elif DeviceDataManager.is_independent_mode():
file_path = SFP_SDK_MODULE_SYSFS_ROOT_TEMPLATE.format(self.sdk_index) + SFP_SYSFS_POWER_MODE
power_mode = utils.read_int_from_file(file_path)
return power_mode == POWER_MODE_LOW
except Exception as e:
print(e)
return False
if utils.is_host():
# To avoid performance issue,
# call class level method to avoid initialize the whole sonic platform API
@ -573,6 +585,24 @@ class SFP(NvidiaSFPCommon):
Returns:
A boolean, True if lpmode is set successfully, False if not
"""
try:
if self.is_sw_control():
api = self.get_xcvr_api()
if not api:
return False
if api.get_lpmode() == lpmode:
return True
api.set_lpmode(lpmode)
return api.get_lpmode() == lpmode
elif DeviceDataManager.is_independent_mode():
# FW control under CMIS host management mode.
# Currently, we don't support set LPM under this mode.
# Just return False to indicate set Fail
return False
except Exception as e:
print(e)
return False
if utils.is_host():
# To avoid performance issue,
# call class level method to avoid initialize the whole sonic platform API

View File

@ -312,6 +312,8 @@ class TestSfp:
with pytest.raises(Exception):
sfp.is_sw_control()
@mock.patch('sonic_platform.device_data.DeviceDataManager.is_independent_mode', mock.MagicMock(return_value=False))
@mock.patch('sonic_platform.sfp.SFP.is_sw_control', mock.MagicMock(return_value=False))
@mock.patch('sonic_platform.utils.is_host', mock.MagicMock(side_effect = [True, True, False, False]))
@mock.patch('subprocess.check_output', mock.MagicMock(side_effect = ['True', 'False']))
@mock.patch('sonic_platform.sfp.SFP._get_lpmode', mock.MagicMock(side_effect = [True, False]))
@ -323,6 +325,8 @@ class TestSfp:
assert sfp.get_lpmode()
assert not sfp.get_lpmode()
@mock.patch('sonic_platform.device_data.DeviceDataManager.is_independent_mode', mock.MagicMock(return_value=False))
@mock.patch('sonic_platform.sfp.SFP.is_sw_control', mock.MagicMock(return_value=False))
@mock.patch('sonic_platform.utils.is_host', mock.MagicMock(side_effect = [True, True, False, False]))
@mock.patch('subprocess.check_output', mock.MagicMock(side_effect = ['True', 'False']))
@mock.patch('sonic_platform.sfp.SFP._set_lpmode', mock.MagicMock(side_effect = [True, False]))
@ -333,3 +337,45 @@ class TestSfp:
assert not sfp.set_lpmode(True)
assert sfp.set_lpmode(False)
assert not sfp.set_lpmode(False)
@mock.patch('sonic_platform.device_data.DeviceDataManager.is_independent_mode', mock.MagicMock(return_value=True))
@mock.patch('sonic_platform.utils.read_int_from_file')
@mock.patch('sonic_platform.sfp.SFP.is_sw_control')
def test_get_lpmode_cmis_host_mangagement(self, mock_control, mock_read):
mock_control.return_value = True
sfp = SFP(0)
sfp.get_xcvr_api = mock.MagicMock(return_value=None)
assert not sfp.get_lpmode()
mock_api = mock.MagicMock()
sfp.get_xcvr_api.return_value = mock_api
mock_api.get_lpmode = mock.MagicMock(return_value=False)
assert not sfp.get_lpmode()
mock_api.get_lpmode.return_value = True
assert sfp.get_lpmode()
mock_control.return_value = False
mock_read.return_value = 1
assert sfp.get_lpmode()
mock_read.return_value = 2
assert not sfp.get_lpmode()
@mock.patch('sonic_platform.device_data.DeviceDataManager.is_independent_mode', mock.MagicMock(return_value=True))
@mock.patch('sonic_platform.sfp.SFP.is_sw_control')
def test_set_lpmode_cmis_host_mangagement(self, mock_control):
mock_control.return_value = True
sfp = SFP(0)
sfp.get_xcvr_api = mock.MagicMock(return_value=None)
assert not sfp.set_lpmode(False)
mock_api = mock.MagicMock()
sfp.get_xcvr_api.return_value = mock_api
mock_api.get_lpmode = mock.MagicMock(return_value=False)
assert sfp.set_lpmode(False)
assert not sfp.set_lpmode(True)
mock_control.return_value = False
assert not sfp.set_lpmode(True)
assert not sfp.set_lpmode(False)