Skip to content

Commit f679a67

Browse files
authored
Restore optoe page to default 0 for active cables (sonic-net#550)
<!-- Provide a general summary of your changes in the Title above --> #### Description Restore the optoe's page to page ZERO before reading the Lower page > 127 #### Motivation and Context When the module is busy with CDB command, the optoe kernel driver at the end of user page read request, tries to restore the page to Page ZERO and if this write fails because the module could be busy with CDB command (since these modules donot support background CDB mode). Because of this when Xcvrd tries to read offset (> 127) in Lower page, since optoe does not restore the page to 0 for any Lower page access, the page read to these offset will result in wrong page to be read (because of previous page select write failure) and Xcvrd parsing fails causing crash. Now in optoe EEPROM read API we ensure to restore the Page to ZERO page if the Page select byte is non-zero #### How Has This Been Tested? TBD: 1. Test on Arista switch 2. Test on Cisco switch #### Additional Information (Optional)
1 parent c735073 commit f679a67

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

sonic_platform_base/sonic_xcvr/sfp_optoe_base.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
from ..sfp_base import SfpBase
99

10+
SFP_OPTOE_PAGE_SELECT_OFFSET = 127
11+
SFP_OPTOE_UPPER_PAGE0_OFFSET = 128
12+
SFP_OPTOE_PAGE_SIZE = 128
13+
1014
class SfpOptoeBase(SfpBase):
1115
def __init__(self):
1216
SfpBase.__init__(self)
@@ -261,6 +265,12 @@ def set_optoe_write_max(self, write_max):
261265
except (OSError, IOError):
262266
pass
263267

268+
def get_optoe_current_page(self):
269+
return self.read_eeprom(SFP_OPTOE_PAGE_SELECT_OFFSET, 1)[0]
270+
271+
def set_page0(self):
272+
self.write_eeprom(SFP_OPTOE_PAGE_SELECT_OFFSET, 1, bytearray([0x00]))
273+
264274
def set_optoe_write_timeout(self, write_timeout):
265275
sys_path = self.get_eeprom_path()
266276
sys_path = sys_path.replace("eeprom", "write_timeout")
@@ -273,6 +283,12 @@ def set_optoe_write_timeout(self, write_timeout):
273283
def read_eeprom(self, offset, num_bytes):
274284
try:
275285
with open(self.get_eeprom_path(), mode='rb', buffering=0) as f:
286+
if offset >= SFP_OPTOE_UPPER_PAGE0_OFFSET and \
287+
offset < (SFP_OPTOE_UPPER_PAGE0_OFFSET+SFP_OPTOE_PAGE_SIZE) and \
288+
self.get_optoe_current_page() != 0:
289+
# Restoring the page to 0 helps in cases where the optoe driver failed to restore
290+
# the page when say the module was busy with CDB command processing
291+
self.set_page0()
276292
f.seek(offset)
277293
return bytearray(f.read(num_bytes))
278294
except (OSError, IOError):

tests/sonic_xcvr/test_sfp_optoe_base.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from mock import MagicMock
33
from mock import patch
44
import pytest
5-
from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase
5+
from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase, SFP_OPTOE_UPPER_PAGE0_OFFSET, SFP_OPTOE_PAGE_SELECT_OFFSET
66
from sonic_platform_base.sonic_xcvr.api.public.c_cmis import CCmisApi
77
from sonic_platform_base.sonic_xcvr.api.public.cmis import CmisApi
88
from sonic_platform_base.sonic_xcvr.mem_maps.public.c_cmis import CCmisMemMap
@@ -132,3 +132,13 @@ def test_set_power(self):
132132
exception_raised = True
133133
assert exception_raised
134134

135+
def test_default_page(self):
136+
with patch("builtins.open", mock_open(read_data=b'\x01')) as mocked_file:
137+
self.sfp_optoe_api.write_eeprom = MagicMock(return_value=True)
138+
self.sfp_optoe_api.get_optoe_current_page = MagicMock(return_value=0x10)
139+
self.sfp_optoe_api.get_eeprom_path = MagicMock(return_value='/sys/class/eeprom')
140+
data = self.sfp_optoe_api.read_eeprom(SFP_OPTOE_UPPER_PAGE0_OFFSET, 1)
141+
mocked_file.assert_called_once_with("/sys/class/eeprom", mode='rb', buffering=0)
142+
assert data == b'\x01'
143+
self.sfp_optoe_api.write_eeprom.assert_called_once_with(SFP_OPTOE_PAGE_SELECT_OFFSET, 1, b'\x00')
144+
self.sfp_optoe_api.get_optoe_current_page.assert_called_once()

0 commit comments

Comments
 (0)