diff --git a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py index 9dac9d1da..0e1a3909a 100644 --- a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py +++ b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py @@ -7,6 +7,10 @@ from ..sfp_base import SfpBase +SFP_OPTOE_PAGE_SELECT_OFFSET = 127 +SFP_OPTOE_UPPER_PAGE0_OFFSET = 128 +SFP_OPTOE_PAGE_SIZE = 128 + class SfpOptoeBase(SfpBase): def __init__(self): SfpBase.__init__(self) @@ -261,6 +265,12 @@ def set_optoe_write_max(self, write_max): except (OSError, IOError): pass + def get_optoe_current_page(self): + return self.read_eeprom(SFP_OPTOE_PAGE_SELECT_OFFSET, 1)[0] + + def set_page0(self): + self.write_eeprom(SFP_OPTOE_PAGE_SELECT_OFFSET, 1, bytearray([0x00])) + def set_optoe_write_timeout(self, write_timeout): sys_path = self.get_eeprom_path() sys_path = sys_path.replace("eeprom", "write_timeout") @@ -273,6 +283,12 @@ def set_optoe_write_timeout(self, write_timeout): def read_eeprom(self, offset, num_bytes): try: with open(self.get_eeprom_path(), mode='rb', buffering=0) as f: + if offset >= SFP_OPTOE_UPPER_PAGE0_OFFSET and \ + offset < (SFP_OPTOE_UPPER_PAGE0_OFFSET+SFP_OPTOE_PAGE_SIZE) and \ + self.get_optoe_current_page() != 0: + # Restoring the page to 0 helps in cases where the optoe driver failed to restore + # the page when say the module was busy with CDB command processing + self.set_page0() f.seek(offset) return bytearray(f.read(num_bytes)) except (OSError, IOError): diff --git a/tests/sonic_xcvr/test_sfp_optoe_base.py b/tests/sonic_xcvr/test_sfp_optoe_base.py index 2992f0e63..6dc8b901f 100644 --- a/tests/sonic_xcvr/test_sfp_optoe_base.py +++ b/tests/sonic_xcvr/test_sfp_optoe_base.py @@ -2,7 +2,7 @@ from mock import MagicMock from mock import patch import pytest -from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase +from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase, SFP_OPTOE_UPPER_PAGE0_OFFSET, SFP_OPTOE_PAGE_SELECT_OFFSET from sonic_platform_base.sonic_xcvr.api.public.c_cmis import CCmisApi from sonic_platform_base.sonic_xcvr.api.public.cmis import CmisApi from sonic_platform_base.sonic_xcvr.mem_maps.public.c_cmis import CCmisMemMap @@ -132,3 +132,13 @@ def test_set_power(self): exception_raised = True assert exception_raised + def test_default_page(self): + with patch("builtins.open", mock_open(read_data=b'\x01')) as mocked_file: + self.sfp_optoe_api.write_eeprom = MagicMock(return_value=True) + self.sfp_optoe_api.get_optoe_current_page = MagicMock(return_value=0x10) + self.sfp_optoe_api.get_eeprom_path = MagicMock(return_value='/sys/class/eeprom') + data = self.sfp_optoe_api.read_eeprom(SFP_OPTOE_UPPER_PAGE0_OFFSET, 1) + mocked_file.assert_called_once_with("/sys/class/eeprom", mode='rb', buffering=0) + assert data == b'\x01' + self.sfp_optoe_api.write_eeprom.assert_called_once_with(SFP_OPTOE_PAGE_SELECT_OFFSET, 1, b'\x00') + self.sfp_optoe_api.get_optoe_current_page.assert_called_once() \ No newline at end of file