From 910b38bc5d94eb3475cd670a42a0f95250bdc184 Mon Sep 17 00:00:00 2001 From: mssonicbld <79238446+mssonicbld@users.noreply.github.com> Date: Tue, 29 Sep 2026 05:14:39 +1000 Subject: [PATCH] [CMIS] Fix VDM freeze/unfreeze as per CMIS 5.4 (#767) #### Description Fix VDM Freeze/Unfreeze as per CMIS 5.4 #### Motivation and Context VDM Freeze/Unfreeze is NOT working in modules following 5.4 spec #### How Has This Been Tested? Tested this on module following CMIS 5.3 and 5.4 Signed-off-by: Sonic Build Admin #### Additional Information (Optional) --- .../sonic_xcvr/api/public/cmis.py | 6 +++--- .../sonic_xcvr/api/public/cmisVDM.py | 2 -- .../sonic_xcvr/fields/consts.py | 4 ++++ .../mem_maps/public/cmis/pages/page2f.py | 9 ++++++++- tests/sonic_xcvr/test_cmis.py | 19 +++++++++++++++++++ 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 9e0784a..964cbfe 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -23,7 +23,7 @@ logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) -VDM_FREEZE = 128 +VDM_FREEZE = 1 VDM_UNFREEZE = 0 DATAPATH_INIT_DURATION_MULTIPLIER = 10 @@ -211,7 +211,7 @@ def freeze_vdm_stats(self): Returns True if the provision succeeds and False incase of failure. ''' - return self.xcvr_eeprom.write(consts.VDM_CONTROL, VDM_FREEZE) + return self.xcvr_eeprom.write(consts.VDM_FREEZE_REQUEST, VDM_FREEZE) def get_vdm_freeze_status(self): ''' @@ -229,7 +229,7 @@ def unfreeze_vdm_stats(self): Returns True if the provision succeeds and False incase of failure. ''' - return self.xcvr_eeprom.write(consts.VDM_CONTROL, VDM_UNFREEZE) + return self.xcvr_eeprom.write(consts.VDM_FREEZE_REQUEST, VDM_UNFREEZE) def get_vdm_unfreeze_status(self): ''' diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmisVDM.py b/sonic_platform_base/sonic_xcvr/api/public/cmisVDM.py index e12f7fe..998416b 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmisVDM.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmisVDM.py @@ -14,8 +14,6 @@ THRSH_SPACING = 8 VDM_SIZE = 2 VDM_FLAG_PAGE = 0x2c -VDM_FREEZE = 128 -VDM_UNFREEZE = 0 class CmisVdmApi(XcvrApi): diff --git a/sonic_platform_base/sonic_xcvr/fields/consts.py b/sonic_platform_base/sonic_xcvr/fields/consts.py index c4881da..921a7c2 100644 --- a/sonic_platform_base/sonic_xcvr/fields/consts.py +++ b/sonic_platform_base/sonic_xcvr/fields/consts.py @@ -428,9 +428,13 @@ VDM_SUPPORTED = "VdmSupported" VDM_SUPPORTED_PAGE = "VdmSupportedPage" VDM_CONTROL = "VdmControl" +VDM_FREEZE_REQUEST = "VdmFreezeRequest" +VDM_POWER_SAVING_MODE = "VdmPowerSavingMode" +VDM_MON_DUTY_CYCLE = "VdmMonDutyCycle" VDM_STATUS = "VdmStatus" VDM_FREEZE_DONE = "VdmFreezeDone" VDM_UNFREEZE_DONE = "VdmUnfreezeDone" +VDM_RESERVED = "VdmReserved" MEDIA_LANE_FEC_PM = "Media Lane FEC Performance Monitoring" MEDIA_LANE_LINK_PM = "Media Lane Link Performance Monitoring" diff --git a/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis/pages/page2f.py b/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis/pages/page2f.py index b14b1fd..ee83d65 100644 --- a/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis/pages/page2f.py +++ b/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis/pages/page2f.py @@ -9,6 +9,7 @@ from .....fields.xcvr_field import ( NumberRegField, RegBitField, + RegBitsField, ) from .....fields import consts @@ -22,7 +23,13 @@ def __init__(self, codes, bank=0, page=VDM_ADVERTISING_CTRL_PAGE): NumberRegField(consts.VDM_SUPPORTED_PAGE, self.getaddr(128), *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 2)) ), - NumberRegField(consts.VDM_CONTROL, self.getaddr(144), size=1, ro=False), + NumberRegField(consts.VDM_CONTROL, self.getaddr(144), + RegBitsField(consts.VDM_FREEZE_REQUEST, bitpos=7, size=1, ro=False), + RegBitsField(consts.VDM_POWER_SAVING_MODE, bitpos=6, size=1, ro=False), + RegBitsField(consts.VDM_MON_DUTY_CYCLE, bitpos=2, size=4, ro=False), + RegBitsField(consts.VDM_RESERVED, bitpos=0, size=2, ro=True), + ro=False + ), NumberRegField(consts.VDM_STATUS, self.getaddr(145), RegBitField(consts.VDM_UNFREEZE_DONE, 6), RegBitField(consts.VDM_FREEZE_DONE, 7), diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index ec29e95..2704aeb 100755 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -113,6 +113,25 @@ def test_linear_offset_specific_worked_examples(self, bank, page, offset, expect future reader can verify the formula without redoing the arithmetic.""" assert CmisPage.linear_offset(page, bank, offset) == expected + @pytest.mark.parametrize("api_method, initial_value, expected_value", [ + ("freeze_vdm_stats", 0x55, 0xD5), + ("unfreeze_vdm_stats", 0xD5, 0x55), + ]) + def test_vdm_freeze_request_preserves_other_control_bits( + self, api_method, initial_value, expected_value): + """FreezeRequest is Page 2Fh byte 144 bit 7 in CMIS 5.4.""" + mem_map = CmisMemMap(self.codes) + freeze_request = mem_map.get_field(consts.VDM_FREEZE_REQUEST) + reader = MagicMock(return_value=bytes([initial_value])) + writer = MagicMock(return_value=True) + api = CmisApi(XcvrEeprom(reader, writer, mem_map)) + reader.reset_mock() + + assert getattr(api, api_method)() is True + reader.assert_called_once_with(freeze_request.get_offset(), 1) + writer.assert_called_once_with( + freeze_request.get_offset(), 1, bytearray([expected_value])) + class TestCmis(object): codes = CmisCodes