5
5
6
6
try :
7
7
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
9
14
except ImportError as e :
10
15
raise ImportError ("%s - required module not found" % str (e ))
11
16
12
17
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
+
13
177
class SfpUtil (SfpUtilBase ):
14
178
"""Platform-specific SfpUtil class"""
15
179
@@ -22,6 +186,7 @@ class SfpUtil(SfpUtilBase):
22
186
23
187
EEPROM_OFFSET = 9
24
188
PORT_INFO_PATH = '/sys/class/silverstone_fpga'
189
+ QSFP_DD_DOM_OFFSET = 2304
25
190
26
191
_port_name = ""
27
192
_port_to_eeprom_mapping = {}
@@ -61,7 +226,7 @@ def get_port_name(self, port_num):
61
226
def get_eeprom_dom_raw (self , port_num ):
62
227
if port_num in self .osfp_ports :
63
228
# 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 )
65
230
else :
66
231
# Read dom eeprom at addr 0x51
67
232
return self ._read_eeprom_devid (port_num , self .DOM_EEPROM_ADDR , 256 )
@@ -184,3 +349,54 @@ def get_transceiver_change_event(self, timeout=0):
184
349
TBD
185
350
"""
186
351
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