Skip to content

Commit 583b300

Browse files
author
Wirut Getbamrung
authored
[device/celestica]: Add QSFP-DD DOM parser into sfputil of silverstone (#89)
* [device/celestica]: Add QSFP-DD DOM parser into sfputil of silverstone device * [device/celestica]: add EOF to silverstone sfputil
1 parent f08b9b5 commit 583b300

File tree

1 file changed

+218
-2
lines changed
  • device/celestica/x86_64-cel_silverstone-r0/plugins

1 file changed

+218
-2
lines changed

device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py

+218-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,175 @@
55

66
try:
77
import time
8-
from sonic_sfp.sfputilbase import SfpUtilBase
8+
from sonic_platform_base.sonic_sfp.sfputilbase import SfpUtilBase
9+
from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId, sff8472Dom
10+
from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId, sff8436Dom
11+
from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId
12+
from sonic_platform_base.sonic_sfp.qsfp_dd import qsfp_dd_InterfaceId, qsfp_dd_Dom
13+
from sonic_platform_base.sonic_sfp.sffbase import sffbase
914
except ImportError as e:
1015
raise ImportError("%s - required module not found" % str(e))
1116

1217

18+
class QSFPDDDomPaser(qsfp_dd_Dom):
19+
20+
def __init__(self, eeprom_raw_data):
21+
22+
start_pos = 0
23+
dom_offset = 256
24+
25+
dom_module_monitor_values = {
26+
'Temperature':
27+
{'offset': 14,
28+
'size': 2,
29+
'type': 'func',
30+
'decode': {'func': qsfp_dd_Dom.calc_temperature}},
31+
'Vcc':
32+
{'offset': 16,
33+
'size': 2,
34+
'type': 'func',
35+
'decode': {'func': qsfp_dd_Dom.calc_voltage}}
36+
}
37+
38+
dom_channel_monitor_params = {
39+
'RX8Power':
40+
{'offset': 72 + dom_offset,
41+
'size': 2,
42+
'type': 'func',
43+
'decode': {'func': qsfp_dd_Dom.calc_rx_power}},
44+
'RX7Power':
45+
{'offset': 70 + dom_offset,
46+
'size': 2,
47+
'type': 'func',
48+
'decode': {'func': qsfp_dd_Dom.calc_rx_power}},
49+
'RX6Power':
50+
{'offset': 68 + dom_offset,
51+
'size': 2,
52+
'type': 'func',
53+
'decode': {'func': qsfp_dd_Dom.calc_rx_power}},
54+
'RX5Power':
55+
{'offset': 66 + dom_offset,
56+
'size': 2,
57+
'type': 'func',
58+
'decode': {'func': qsfp_dd_Dom.calc_rx_power}},
59+
'RX4Power':
60+
{'offset': 64 + dom_offset,
61+
'size': 2,
62+
'type': 'func',
63+
'decode': {'func': qsfp_dd_Dom.calc_rx_power}},
64+
'RX3Power':
65+
{'offset': 62 + dom_offset,
66+
'size': 2,
67+
'type': 'func',
68+
'decode': {'func': qsfp_dd_Dom.calc_rx_power}},
69+
'RX2Power':
70+
{'offset': 60 + dom_offset,
71+
'size': 2,
72+
'type': 'func',
73+
'decode': {'func': qsfp_dd_Dom.calc_rx_power}},
74+
'RX1Power':
75+
{'offset': 58 + dom_offset,
76+
'size': 2,
77+
'type': 'func',
78+
'decode': {'func': qsfp_dd_Dom.calc_rx_power}},
79+
'TX8Bias':
80+
{'offset': 56 + dom_offset,
81+
'size': 2,
82+
'type': 'func',
83+
'decode': {'func': qsfp_dd_Dom.calc_bias}},
84+
'TX7Bias':
85+
{'offset': 54 + dom_offset,
86+
'size': 2,
87+
'type': 'func',
88+
'decode': {'func': qsfp_dd_Dom.calc_bias}},
89+
'TX6Bias':
90+
{'offset': 52 + dom_offset,
91+
'size': 2,
92+
'type': 'func',
93+
'decode': {'func': qsfp_dd_Dom.calc_bias}},
94+
'TX5Bias':
95+
{'offset': 50 + dom_offset,
96+
'size': 2,
97+
'type': 'func',
98+
'decode': {'func': qsfp_dd_Dom.calc_bias}},
99+
'TX4Bias':
100+
{'offset': 48 + dom_offset,
101+
'size': 2,
102+
'type': 'func',
103+
'decode': {'func': qsfp_dd_Dom.calc_bias}},
104+
'TX3Bias':
105+
{'offset': 46 + dom_offset,
106+
'size': 2,
107+
'type': 'func',
108+
'decode': {'func': qsfp_dd_Dom.calc_bias}},
109+
'TX2Bias':
110+
{'offset': 44 + dom_offset,
111+
'size': 2,
112+
'type': 'func',
113+
'decode': {'func': qsfp_dd_Dom.calc_bias}},
114+
'TX1Bias':
115+
{'offset': 42 + dom_offset,
116+
'size': 2,
117+
'type': 'func',
118+
'decode': {'func': qsfp_dd_Dom.calc_bias}},
119+
'TX8Power':
120+
{'offset': 40 + dom_offset,
121+
'size': 2,
122+
'type': 'func',
123+
'decode': {'func': qsfp_dd_Dom.calc_tx_power}},
124+
'TX7Power':
125+
{'offset': 38 + dom_offset,
126+
'size': 2,
127+
'type': 'func',
128+
'decode': {'func': qsfp_dd_Dom.calc_tx_power}},
129+
'TX6Power':
130+
{'offset': 36 + dom_offset,
131+
'size': 2,
132+
'type': 'func',
133+
'decode': {'func': qsfp_dd_Dom.calc_tx_power}},
134+
'TX5Power':
135+
{'offset': 34 + dom_offset,
136+
'size': 2,
137+
'type': 'func',
138+
'decode': {'func': qsfp_dd_Dom.calc_tx_power}},
139+
'TX4Power':
140+
{'offset': 32 + dom_offset,
141+
'size': 2,
142+
'type': 'func',
143+
'decode': {'func': qsfp_dd_Dom.calc_tx_power}},
144+
'TX3Power':
145+
{'offset': 30 + dom_offset,
146+
'size': 2,
147+
'type': 'func',
148+
'decode': {'func': qsfp_dd_Dom.calc_tx_power}},
149+
'TX2Power':
150+
{'offset': 28 + dom_offset,
151+
'size': 2,
152+
'type': 'func',
153+
'decode': {'func': qsfp_dd_Dom.calc_tx_power}},
154+
'TX1Power':
155+
{'offset': 26 + dom_offset,
156+
'size': 2,
157+
'type': 'func',
158+
'decode': {'func': qsfp_dd_Dom.calc_tx_power}}
159+
}
160+
161+
dom_map = {
162+
'ModuleMonitorValues':
163+
{'type': 'nested',
164+
'decode': dom_module_monitor_values},
165+
'ChannelMonitorValues':
166+
{'type': 'nested',
167+
'decode': dom_channel_monitor_params}
168+
}
169+
170+
self.dom_data = sffbase.parse(
171+
self, dom_map, eeprom_raw_data, start_pos)
172+
173+
def get_data_pretty(self):
174+
return sffbase.get_data_pretty(self, self.dom_data)
175+
176+
13177
class SfpUtil(SfpUtilBase):
14178
"""Platform-specific SfpUtil class"""
15179

@@ -22,6 +186,7 @@ class SfpUtil(SfpUtilBase):
22186

23187
EEPROM_OFFSET = 9
24188
PORT_INFO_PATH = '/sys/class/silverstone_fpga'
189+
QSFP_DD_DOM_OFFSET = 2304
25190

26191
_port_name = ""
27192
_port_to_eeprom_mapping = {}
@@ -61,7 +226,7 @@ def get_port_name(self, port_num):
61226
def get_eeprom_dom_raw(self, port_num):
62227
if port_num in self.osfp_ports:
63228
# QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw
64-
return None
229+
return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, self.QSFP_DD_DOM_OFFSET, 128)
65230
else:
66231
# Read dom eeprom at addr 0x51
67232
return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 256)
@@ -184,3 +349,54 @@ def get_transceiver_change_event(self, timeout=0):
184349
TBD
185350
"""
186351
raise NotImplementedError
352+
353+
def get_qsfp_data(self, eeprom_ifraw):
354+
sfp_data = {}
355+
sfpi_obj = sff8436InterfaceId(eeprom_ifraw)
356+
sfpd_obj = sff8436Dom(eeprom_ifraw) if sfpi_obj else {}
357+
358+
sfp_data['interface'] = sfpi_obj.get_data_pretty() if sfpi_obj else {}
359+
sfp_data['dom'] = sfpd_obj.get_data_pretty() if sfpd_obj else {}
360+
return sfp_data
361+
362+
def get_eeprom_dict(self, port_num):
363+
"""Returns dictionary of interface and dom data.
364+
format: {<port_num> : {'interface': {'version' : '1.0', 'data' : {...}},
365+
'dom' : {'version' : '1.0', 'data' : {...}}}}
366+
"""
367+
368+
sfp_data = {}
369+
370+
eeprom_ifraw = self.get_eeprom_raw(port_num)
371+
eeprom_domraw = self.get_eeprom_dom_raw(port_num)
372+
373+
if eeprom_ifraw is None:
374+
return None
375+
376+
if port_num in self.osfp_ports:
377+
sfpi_obj = inf8628InterfaceId(eeprom_ifraw)
378+
if sfpi_obj:
379+
sfp_data['interface'] = sfpi_obj.get_data_pretty()
380+
381+
# check if it is a 100G module
382+
if sfp_data['interface']['data']['Identifier'] == 'QSFP28 or later':
383+
return self.get_qsfp_data(eeprom_ifraw)
384+
385+
sfpd_obj = QSFPDDDomPaser(
386+
eeprom_ifraw + eeprom_domraw) if eeprom_domraw else None
387+
sfp_data['dom'] = sfpd_obj.get_data_pretty() if sfpd_obj else {}
388+
389+
return sfp_data
390+
else:
391+
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
392+
if sfpi_obj is not None:
393+
sfp_data['interface'] = sfpi_obj.get_data_pretty()
394+
cal_type = sfpi_obj.get_calibration_type()
395+
396+
if eeprom_domraw is not None:
397+
sfpd_obj = sff8472Dom(eeprom_domraw, cal_type)
398+
if sfpd_obj is not None:
399+
sfp_data['dom'] = sfpd_obj.get_data_pretty()
400+
401+
return sfp_data
402+
return

0 commit comments

Comments
 (0)