From 853df763a6463a4a14f4488aba6592265cc01cd3 Mon Sep 17 00:00:00 2001 From: Prince George Date: Thu, 27 Feb 2025 23:51:27 +0000 Subject: [PATCH 1/4] Restore optoe page to default 0 for active cables --- sonic_platform_base/sonic_xcvr/sfp_optoe_base.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py index 9dac9d1da..0005db208 100644 --- a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py +++ b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py @@ -7,6 +7,8 @@ from ..sfp_base import SfpBase +SFP_OPTOE_PAGE_OFFSET = 127 + class SfpOptoeBase(SfpBase): def __init__(self): SfpBase.__init__(self) @@ -261,6 +263,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_OFFSET, 1) + + def set_page0(self): + self.write_eeprom(SFP_OPTOE_PAGE_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 +281,10 @@ 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 > 127 and offset < 256 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): From 5d9a6388c72bf765b2596087453d4c58bc2ba774 Mon Sep 17 00:00:00 2001 From: Prince George Date: Fri, 28 Feb 2025 00:32:02 +0000 Subject: [PATCH 2/4] Address review comment --- sonic_platform_base/sonic_xcvr/sfp_optoe_base.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py index 0005db208..5b17adb74 100644 --- a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py +++ b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py @@ -7,7 +7,9 @@ from ..sfp_base import SfpBase -SFP_OPTOE_PAGE_OFFSET = 127 +SFP_OPTOE_PAGE_SELECT_OFFSET = 127 +SFP_OPTOE_UPPER_PAGE0_OFFSET = 128 +SFP_OPTOE_PAGE_SIZE = 128 class SfpOptoeBase(SfpBase): def __init__(self): @@ -264,10 +266,10 @@ def set_optoe_write_max(self, write_max): pass def get_optoe_current_page(self): - return self.read_eeprom(SFP_OPTOE_PAGE_OFFSET, 1) + return self.read_eeprom(SFP_OPTOE_PAGE_SELECT_OFFSET, 1)[0] def set_page0(self): - self.write_eeprom(SFP_OPTOE_PAGE_OFFSET, 1, bytearray([0x00])) + 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() @@ -281,7 +283,9 @@ 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 > 127 and offset < 256 and self.get_optoe_current_page() != 0: + 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() From f592129d9db9a0d7310c88bbc70472a063986a0f Mon Sep 17 00:00:00 2001 From: Prince George <45705344+prgeor@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:43:17 -0800 Subject: [PATCH 3/4] Update sonic_platform_base/sonic_xcvr/sfp_optoe_base.py Co-authored-by: mihirpat1 <112018033+mihirpat1@users.noreply.github.com> --- sonic_platform_base/sonic_xcvr/sfp_optoe_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py index 5b17adb74..0e1a3909a 100644 --- a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py +++ b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py @@ -286,8 +286,8 @@ def read_eeprom(self, offset, num_bytes): 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 + # 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)) From 09737c83bdcb09e3b10b5f9da0052754eb9cc28f Mon Sep 17 00:00:00 2001 From: Prince George Date: Sat, 1 Mar 2025 05:42:45 +0000 Subject: [PATCH 4/4] Add unit test coverage --- tests/sonic_xcvr/test_sfp_optoe_base.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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