Skip to content

Commit 78d38a9

Browse files
[Edgecore][device][platform] sfp.py modify write_eeprom() function
-Reason: FPGA driver can't write more than one byte to eeprom. Signed-off-by: michael_shih <[email protected]>
1 parent f6e52de commit 78d38a9

File tree

1 file changed

+93
-63
lines changed
  • platform/broadcom/sonic-platform-modules-accton/as9736-64d/sonic_platform

1 file changed

+93
-63
lines changed

platform/broadcom/sonic-platform-modules-accton/as9736-64d/sonic_platform/sfp.py

Lines changed: 93 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from ctypes import create_string_buffer
1515

1616
try:
17+
from sonic_py_common.logger import Logger
1718
from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase
1819
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
1920
from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
@@ -31,25 +32,6 @@
3132
QSFP_CONTROL_OFFSET = 86
3233
QSFP_POWEROVERRIDE_OFFSET = 93
3334

34-
SFP_TYPE_CODE_LIST = [
35-
0x03, # SFP/SFP+/SFP28
36-
0x0b # DWDM-SFP/SFP+
37-
]
38-
QSFP_TYPE_CODE_LIST = [
39-
0x0c, # QSFP
40-
0x0d, # QSFP+ or later
41-
0x11, # QSFP28 or later
42-
0xE1 # QSFP28 EDFA
43-
]
44-
QSFP_DD_TYPE_CODE_LIST = [
45-
0x18 # QSFP-DD Double Density 8X Pluggable Transceiver
46-
]
47-
48-
SFP_TYPE = "SFP"
49-
QSFP_TYPE = "QSFP"
50-
OSFP_TYPE = "OSFP"
51-
QSFP_DD_TYPE = "QSFP_DD"
52-
5335
NULL_VAL = 'N/A'
5436

5537

@@ -62,6 +44,7 @@
6244
PCIE_UDB_BIND_PATH = "/sys/bus/platform/drivers/pcie_udb_fpga_device/{0}"
6345
PCIE_LDB_BIND_PATH = "/sys/bus/platform/drivers/pcie_ldb_fpga_device/{0}"
6446

47+
logger = Logger()
6548
class Sfp(SfpOptoeBase):
6649
"""Platform-specific Sfp class"""
6750
HOST_CHK_CMD = "which systemctl > /dev/null 2>&1"
@@ -72,6 +55,32 @@ class Sfp(SfpOptoeBase):
7255
QSFP_PORT_START = 1
7356
QSFP_PORT_END = 64
7457

58+
SFP_TYPE_CODE_LIST = [
59+
0x03, # SFP/SFP+/SFP28
60+
0x0b # DWDM-SFP/SFP+
61+
]
62+
QSFP_TYPE_CODE_LIST = [
63+
0x0c, # QSFP
64+
0x0d, # QSFP+ or later
65+
0x11, # QSFP28 or later
66+
0xe1 # QSFP28 EDFA
67+
]
68+
QSFP_DD_TYPE_CODE_LIST = [
69+
0x18 # QSFP-DD Double Density 8X Pluggable Transceiver
70+
]
71+
OSFP_TYPE_CODE_LIST = [
72+
0x19 # OSFP
73+
]
74+
75+
SFP_TYPE = "SFP"
76+
QSFP_TYPE = "QSFP"
77+
OSFP_TYPE = "OSFP"
78+
QSFP_DD_TYPE = "QSFP_DD"
79+
80+
UPDATE_DONE = "Done"
81+
EEPROM_DATA_NOT_READY = "eeprom not ready"
82+
UNKNOWN_SFP_TYPE_ID = "unknow sfp ID"
83+
7584
# Path to sysfs
7685
PLATFORM_ROOT_PATH = "/usr/share/sonic/device"
7786
PMON_HWSKU_PATH = "/usr/share/sonic/hwsku"
@@ -91,13 +100,15 @@ def __init__(self, sfp_index=0, sfp_name=None):
91100
self._api_helper = APIHelper()
92101
self._name = sfp_name
93102

94-
self._refresh_optoe_dev_class()
103+
self.sfp_type = self.QSFP_TYPE
104+
self.update_sfp_type()
105+
self.refresh_optoe_dev_class()
95106

96107
def __write_txt_file(self, file_path, value):
97108
try:
98109
reg_file = open(file_path, "w")
99110
except IOError as e:
100-
print("Error: unable to open file: %s" % str(e))
111+
logger.log_error("Error: unable to open file: %s" % str(e))
101112
return False
102113

103114
reg_file.write(str(value))
@@ -165,25 +176,19 @@ def read_eeprom(self, offset, num_bytes):
165176
except (OSError, IOError):
166177
return None
167178

168-
def _detect_sfp_type(self):
169-
sfp_type = QSFP_TYPE
170-
eeprom_raw = []
171-
eeprom_raw = self.read_eeprom(XCVR_TYPE_OFFSET, XCVR_TYPE_WIDTH)
172-
if eeprom_raw:
173-
if eeprom_raw[0] in SFP_TYPE_CODE_LIST:
174-
self.sfp_type = SFP_TYPE
175-
elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST:
176-
self.sfp_type = QSFP_TYPE
177-
elif eeprom_raw[0] in QSFP_DD_TYPE_CODE_LIST:
178-
self.sfp_type = QSFP_DD_TYPE
179-
else:
180-
self.sfp_type = sfp_type
181-
else:
182-
self.sfp_type = sfp_type
183179

184-
def _refresh_optoe_dev_class(self):
185-
self._detect_sfp_type()
180+
def write_eeprom(self, offset, num_bytes, write_buffer):
181+
try:
182+
with open(self.get_eeprom_path(), mode='r+b', buffering=0) as f:
183+
for i in range(num_bytes):
184+
f.seek(offset+i)
185+
f.write(write_buffer[i:i+1])
186+
except (OSError, IOError):
187+
return False
188+
return True
186189

190+
191+
def refresh_optoe_dev_class(self):
187192
if self.index < 32:
188193
port = "pcie_udb_fpga_device.{}".format(self.index)
189194
port_dev_unbind = PCIE_UDB_BIND_PATH.format("unbind")
@@ -193,17 +198,8 @@ def _refresh_optoe_dev_class(self):
193198
port_dev_unbind = PCIE_LDB_BIND_PATH.format("unbind")
194199
port_dev_bind = PCIE_LDB_BIND_PATH.format("bind")
195200

196-
if self.sfp_type == QSFP_TYPE:
197-
self._api_helper.write_txt_file(port_dev_unbind, port)
198-
self._api_helper.write_txt_file(port_dev_bind, port)
199-
elif self.sfp_type == SFP_TYPE:
200-
self._api_helper.write_txt_file(port_dev_unbind, port)
201-
self._api_helper.write_txt_file(port_dev_bind, port)
202-
elif self.sfp_type == QSFP_DD_TYPE:
203-
self._api_helper.write_txt_file(port_dev_unbind, port)
204-
self._api_helper.write_txt_file(port_dev_bind, port)
205-
else:
206-
return False
201+
self._api_helper.write_txt_file(port_dev_unbind, port)
202+
self._api_helper.write_txt_file(port_dev_bind, port)
207203

208204
def get_reset_status(self):
209205
"""
@@ -247,13 +243,17 @@ def get_lpmode(self):
247243
# SFP doesn't support this feature
248244
return False
249245

250-
lpmode_path = "{}{}{}".format(FPGA_PCIE_PATH, '/module_lp_mode_', self.port_num)
251-
252-
val=self._api_helper.read_txt_file(lpmode_path)
253-
if val is not None:
254-
return int(val, 10)==1
246+
if self.sfp_type == self.QSFP_DD_TYPE:
247+
api = self.get_xcvr_api()
248+
return api.get_lpmode()
255249
else:
256-
return False
250+
lpmode_path = "{}{}{}".format(FPGA_PCIE_PATH, '/module_lp_mode_', self.port_num)
251+
252+
val=self._api_helper.read_txt_file(lpmode_path)
253+
if val is not None:
254+
return int(val, 10)==1
255+
else:
256+
return False
257257

258258
def reset(self):
259259
"""
@@ -289,7 +289,7 @@ def tx_disable(self, tx_disable):
289289
Returns:
290290
A boolean, True if tx_disable is set successfully, False if not
291291
"""
292-
if self.sfp_type == QSFP_TYPE:
292+
if self.sfp_type == self.QSFP_TYPE:
293293
sysfsfile_eeprom = None
294294
try:
295295
tx_disable_value = 0xf if tx_disable else 0x0
@@ -321,14 +321,19 @@ def set_lpmode(self, lpmode):
321321
if not self.get_presence():
322322
return False
323323

324-
lpmode_path = "{}{}{}".format(FPGA_PCIE_PATH, 'module_lp_mode_', self.port_num)
324+
if self.sfp_type == self.QSFP_DD_TYPE:
325+
api = self.get_xcvr_api()
326+
api.set_lpmode(lpmode)
327+
return True
328+
else:
329+
lpmode_path = "{}{}{}".format(FPGA_PCIE_PATH, 'module_lp_mode_', self.port_num)
325330

326-
if lpmode is True:
327-
ret = self.__write_txt_file(lpmode_path, 1) #enable lpmode
328-
else:
329-
ret = self.__write_txt_file(lpmode_path, 0) #disable lpmode
331+
if lpmode is True:
332+
ret = self.__write_txt_file(lpmode_path, 1) #enable lpmode
333+
else:
334+
ret = self.__write_txt_file(lpmode_path, 0) #disable lpmode
330335

331-
return ret
336+
return ret
332337

333338
def _convert_raw_to_byte(self, raw, num_bytes):
334339
"""
@@ -414,7 +419,7 @@ def set_power_override(self, power_override, power_set):
414419
fd.close()
415420

416421
except Exception as e:
417-
print ('Error: unable to open file: ', str(e))
422+
logger.log_error("Error: unable to open file: %s" % str(e))
418423
return False
419424

420425
return True
@@ -471,3 +476,28 @@ def is_replaceable(self):
471476
A boolean value, True if replaceable
472477
"""
473478
return True
479+
480+
def update_sfp_type(self):
481+
"""
482+
Updates the sfp type
483+
484+
"""
485+
ret = self.UPDATE_DONE
486+
eeprom_raw = []
487+
eeprom_raw = self.read_eeprom(0, 1)
488+
if eeprom_raw and hasattr(self,'sfp_type'):
489+
if eeprom_raw[0] in self.SFP_TYPE_CODE_LIST:
490+
self.sfp_type = self.SFP_TYPE
491+
elif eeprom_raw[0] in self.QSFP_TYPE_CODE_LIST:
492+
self.sfp_type = self.QSFP_TYPE
493+
elif eeprom_raw[0] in self.QSFP_DD_TYPE_CODE_LIST:
494+
self.sfp_type = self.QSFP_DD_TYPE
495+
elif eeprom_raw[0] in self.OSFP_TYPE_CODE_LIST:
496+
self.sfp_type = self.OSFP_TYPE
497+
else:
498+
ret = self.UNKNOWN_SFP_TYPE_ID
499+
else:
500+
ret = self.EEPROM_DATA_NOT_READY
501+
502+
return ret
503+

0 commit comments

Comments
 (0)