Skip to content

Commit c8eceec

Browse files
qinchuanaresprgeor
andauthored
400zr initial support (#228)
Co-authored-by: Prince George <[email protected]>
1 parent ef55364 commit c8eceec

File tree

18 files changed

+6384
-133
lines changed

18 files changed

+6384
-133
lines changed

sonic_platform_base/sonic_xcvr/api/public/c_cmis.py

Lines changed: 923 additions & 0 deletions
Large diffs are not rendered by default.

sonic_platform_base/sonic_xcvr/api/public/cmis.py

Lines changed: 1409 additions & 27 deletions
Large diffs are not rendered by default.

sonic_platform_base/sonic_xcvr/api/public/cmisCDB.py

Lines changed: 480 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
"""
2+
cmisCDB.py
3+
4+
Implementation of APIs related to VDMs
5+
"""
6+
7+
from ...fields import consts
8+
from ..xcvr_api import XcvrApi
9+
import struct
10+
import time
11+
12+
PAGE_SIZE = 128
13+
PAGE_OFFSET = 128
14+
THRSH_SPACING = 8
15+
VDM_SIZE = 2
16+
VDM_FLAG_PAGE = 0x2c
17+
VDM_FREEZE = 128
18+
VDM_UNFREEZE = 0
19+
20+
class CmisVdmApi(XcvrApi):
21+
def __init__(self, xcvr_eeprom):
22+
super(CmisVdmApi, self).__init__(xcvr_eeprom)
23+
24+
def get_F16(self, value):
25+
'''
26+
This function converts raw data to "F16" format defined in cmis.
27+
'''
28+
scale_exponent = (value >> 11) & 0x1f
29+
mantissa = value & 0x7ff
30+
result = mantissa*10**(scale_exponent-24)
31+
return result
32+
33+
def get_vdm_page(self, page, VDM_flag_page):
34+
'''
35+
This function returns VDM items from a specific VDM page.
36+
Output format is a dictionary. Key is observable type; value is a dictionary.
37+
In the inside dictionary, key is lane; value is a list
38+
[
39+
vdm_value,
40+
vdm_thrsh_high_alarm,
41+
vdm_thrsh_low_alarm,
42+
vdm_thrsh_high_warn,
43+
vdm_thrsh_low_warn,
44+
vdm_high_alarm_flag,
45+
vdm_low_alarm_flag,
46+
vdm_high_warn_flag,
47+
vdm_low_warn_flag
48+
]
49+
'''
50+
if page not in [0x20, 0x21, 0x22, 0x23]:
51+
raise ValueError('Page not in VDM Descriptor range!')
52+
vdm_descriptor = self.xcvr_eeprom.read_raw(page * PAGE_SIZE + PAGE_OFFSET, PAGE_SIZE)
53+
54+
# Odd Adress VDM observable type ID, real-time monitored value in Page + 4
55+
vdm_typeID = vdm_descriptor[1::2]
56+
# Even Address
57+
# Bit 7-4: Threshold set ID in Page + 8, in group of 8 bytes, 16 sets/page
58+
# Bit 3-0: n. Monitored lane n+1
59+
vdm_lane = [(elem & 0xf) for elem in vdm_descriptor[0::2]]
60+
VDM_thresholdID = [(elem>>4) for elem in vdm_descriptor[0::2]]
61+
vdm_valuePage = page + 4
62+
vdm_thrshPage = page + 8
63+
vdm_Page_data = {}
64+
VDM_TYPE_DICT = self.xcvr_eeprom.mem_map.codes.VDM_TYPE
65+
for index, typeID in enumerate(vdm_typeID):
66+
if typeID not in VDM_TYPE_DICT:
67+
continue
68+
else:
69+
vdm_info_dict = VDM_TYPE_DICT[typeID]
70+
thrshID = VDM_thresholdID[index]
71+
vdm_type = vdm_info_dict[0]
72+
vdm_format = vdm_info_dict[1]
73+
scale = vdm_info_dict[2]
74+
75+
vdm_value_offset = vdm_valuePage * PAGE_SIZE + PAGE_OFFSET + VDM_SIZE * index
76+
vdm_high_alarm_offset = vdm_thrshPage * PAGE_SIZE + PAGE_OFFSET + THRSH_SPACING * thrshID
77+
vdm_low_alarm_offset = vdm_high_alarm_offset + 2
78+
vdm_high_warn_offset = vdm_high_alarm_offset + 4
79+
vdm_low_warn_offset = vdm_high_alarm_offset + 6
80+
81+
vdm_value_raw = self.xcvr_eeprom.read_raw(vdm_value_offset, VDM_SIZE, True)
82+
vdm_thrsh_high_alarm_raw = self.xcvr_eeprom.read_raw(vdm_high_alarm_offset, VDM_SIZE, True)
83+
vdm_thrsh_low_alarm_raw = self.xcvr_eeprom.read_raw(vdm_low_alarm_offset, VDM_SIZE, True)
84+
vdm_thrsh_high_warn_raw = self.xcvr_eeprom.read_raw(vdm_high_warn_offset, VDM_SIZE, True)
85+
vdm_thrsh_low_warn_raw = self.xcvr_eeprom.read_raw(vdm_low_warn_offset, VDM_SIZE, True)
86+
if vdm_format == 'S16':
87+
vdm_value = struct.unpack('>h',vdm_value_raw)[0] * scale
88+
vdm_thrsh_high_alarm = struct.unpack('>h', vdm_thrsh_high_alarm_raw)[0] * scale
89+
vdm_thrsh_low_alarm = struct.unpack('>h', vdm_thrsh_low_alarm_raw)[0] * scale
90+
vdm_thrsh_high_warn = struct.unpack('>h', vdm_thrsh_high_warn_raw)[0] * scale
91+
vdm_thrsh_low_warn = struct.unpack('>h', vdm_thrsh_low_warn_raw)[0] * scale
92+
elif vdm_format == 'U16':
93+
vdm_value = struct.unpack('>H',vdm_value_raw)[0] * scale
94+
vdm_thrsh_high_alarm = struct.unpack('>H', vdm_thrsh_high_alarm_raw)[0] * scale
95+
vdm_thrsh_low_alarm = struct.unpack('>H', vdm_thrsh_low_alarm_raw)[0] * scale
96+
vdm_thrsh_high_warn = struct.unpack('>H', vdm_thrsh_high_warn_raw)[0] * scale
97+
vdm_thrsh_low_warn = struct.unpack('>H', vdm_thrsh_low_warn_raw)[0] * scale
98+
elif vdm_format == 'F16':
99+
vdm_value_int = struct.unpack('>H',vdm_value_raw)[0]
100+
vdm_value = self.get_F16(vdm_value_int)
101+
vdm_thrsh_high_alarm_int = struct.unpack('>H', vdm_thrsh_high_alarm_raw)[0]
102+
vdm_thrsh_low_alarm_int = struct.unpack('>H', vdm_thrsh_low_alarm_raw)[0]
103+
vdm_thrsh_high_warn_int = struct.unpack('>H', vdm_thrsh_high_warn_raw)[0]
104+
vdm_thrsh_low_warn_int = struct.unpack('>H', vdm_thrsh_low_warn_raw)[0]
105+
vdm_thrsh_high_alarm = self.get_F16(vdm_thrsh_high_alarm_int)
106+
vdm_thrsh_low_alarm = self.get_F16(vdm_thrsh_low_alarm_int)
107+
vdm_thrsh_high_warn = self.get_F16(vdm_thrsh_high_warn_int)
108+
vdm_thrsh_low_warn = self.get_F16(vdm_thrsh_low_warn_int)
109+
else:
110+
continue
111+
112+
vdm_flag_offset = 32 * (page - 0x20) + index//2
113+
bit_offset = 4*(index%2)
114+
vdm_high_alarm_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset)) & 0x1)
115+
vdm_low_alarm_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset+1)) & 0x1)
116+
vdm_high_warn_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset+2)) & 0x1)
117+
vdm_low_warn_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset+3)) & 0x1)
118+
119+
if vdm_type not in vdm_Page_data:
120+
vdm_Page_data[vdm_type] = {
121+
vdm_lane[index]+1: [
122+
vdm_value,
123+
vdm_thrsh_high_alarm,
124+
vdm_thrsh_low_alarm,
125+
vdm_thrsh_high_warn,
126+
vdm_thrsh_low_warn,
127+
vdm_high_alarm_flag,
128+
vdm_low_alarm_flag,
129+
vdm_high_warn_flag,
130+
vdm_low_warn_flag]
131+
}
132+
133+
else:
134+
vdm_Page_data[vdm_info_dict[0]][vdm_lane[index]+1] = [
135+
vdm_value,
136+
vdm_thrsh_high_alarm,
137+
vdm_thrsh_low_alarm,
138+
vdm_thrsh_high_warn,
139+
vdm_thrsh_low_warn,
140+
vdm_high_alarm_flag,
141+
vdm_low_alarm_flag,
142+
vdm_high_warn_flag,
143+
vdm_low_warn_flag]
144+
return vdm_Page_data
145+
146+
def get_vdm_allpage(self):
147+
'''
148+
This function returns VDM items from all advertised VDM pages.
149+
Output format is a dictionary. Key is observable type; value is a dictionary.
150+
In the inside dictionary, key is lane; value is a list
151+
[
152+
vdm_value,
153+
vdm_thrsh_high_alarm,
154+
vdm_thrsh_low_alarm,
155+
vdm_thrsh_high_warn,
156+
vdm_thrsh_low_warn,
157+
vdm_high_alarm_flag,
158+
vdm_low_alarm_flag,
159+
vdm_high_warn_flag,
160+
vdm_low_warn_flag
161+
]
162+
'''
163+
vdm_page_supported_raw = self.xcvr_eeprom.read(consts.VDM_SUPPORTED_PAGE)
164+
if vdm_page_supported_raw is None:
165+
return None
166+
VDM_START_PAGE = 0x20
167+
vdm = dict()
168+
# When raised by the host, causes the module to freeze and hold all
169+
# reported statistics reporting registers (minimum, maximum and
170+
# average values)in Pages 24h-27h.
171+
# When ceased by the host, releases the freeze request, allowing the
172+
# reported minimum, maximum and average values to update again.
173+
self.xcvr_eeprom.write(consts.VDM_CONTROL, VDM_FREEZE)
174+
time.sleep(1)
175+
self.xcvr_eeprom.write(consts.VDM_CONTROL, VDM_UNFREEZE)
176+
vdm_flag_page = self.xcvr_eeprom.read_raw(VDM_FLAG_PAGE * PAGE_SIZE + PAGE_OFFSET, PAGE_SIZE)
177+
for page in range(VDM_START_PAGE, VDM_START_PAGE + vdm_page_supported_raw + 1):
178+
vdm_current_page = self.get_vdm_page(page, vdm_flag_page)
179+
vdm.update(vdm_current_page)
180+
return vdm

sonic_platform_base/sonic_xcvr/codes/public/cmis.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,122 @@ class CmisCodes(Sff8024):
2020
4: "active_cable_media_interface",
2121
5: "base_t_media_interface",
2222
}
23+
24+
MEDIA_INTERFACE_TECH = {
25+
0: '850 nm VCSEL',
26+
1: '1310 nm VCSEL',
27+
2: '1550 nm VCSEL',
28+
3: '1310 nm FP',
29+
4: '1310 nm DFB',
30+
5: '1550 nm DFB',
31+
6: '1310 nm EML',
32+
7: '1550 nm EML',
33+
8: 'Others',
34+
9: '1490 nm DFB',
35+
10: 'Copper cable unequalized',
36+
11: 'Copper cable passive equalized',
37+
12: 'Copper cable, near and far end limiting active equalizers',
38+
13: 'Copper cable, far end limiting active equalizers',
39+
14: 'Copper cable, near end limiting active equalizers',
40+
15: 'Copper cable, linear active equalizers',
41+
16: 'C-band tunable laser',
42+
17: 'L-band tunable laser',
43+
}
44+
45+
MODULE_STATE = {
46+
1: 'ModuleLowPwr',
47+
2: 'ModulePwrUp',
48+
3: 'ModuleReady',
49+
4: 'ModulePwrDn',
50+
5: 'ModuleFault',
51+
}
52+
53+
MODULE_FAULT_CAUSE = {
54+
0: 'No Fault detected',
55+
1: 'TEC runawawy',
56+
2: 'Data memory corrupted',
57+
3: 'Program memory corrupted',
58+
}
59+
60+
DATAPATH_STATE = {
61+
1: 'DataPathDeactivated',
62+
2: 'DataPathInit',
63+
3: 'DataPathDeinit',
64+
4: 'DataPathActivated',
65+
5: 'DataPathTxTurnOn',
66+
6: 'DataPathTxTurnOff',
67+
7: 'DataPathInitialized',
68+
}
69+
70+
CONFIG_STATUS = {
71+
0: 'ConfigUndefined',
72+
1: 'ConfigSuccess',
73+
2: 'ConfigRejected',
74+
3: 'ConfigRejectedInvalidAppSel',
75+
4: 'ConfigRejectedInvalidDataPath',
76+
5: 'ConfigRejectedInvalidSI',
77+
6: 'ConfigRejectedLaneInUse',
78+
7: 'ConfigRejectedPartialDataPath',
79+
12: 'ConfigInProgress',
80+
}
81+
82+
VDM_TYPE = {
83+
# VDM_ID: [VDM_NAME, DATA_TYPE, SCALE]
84+
1: ['Laser Age [%]', 'U16', 1],
85+
2: ['TEC Current [%]', 'S16', 100.0/32767],
86+
3: ['Laser Frequency Error [MHz]', 'S16', 10],
87+
4: ['Laser Temperature [C]', 'S16', 1.0/256],
88+
5: ['eSNR Media Input [dB]', 'U16', 1.0/256],
89+
6: ['eSNR Host Input [dB]', 'U16', 1.0/256],
90+
7: ['PAM4 Level Transition Parameter Media Input [dB]', 'U16', 1.0/256],
91+
8: ['PAM4 Level Transition Parameter Host Input [dB]', 'U16', 1.0/256],
92+
9: ['Pre-FEC BER Minimum Media Input', 'F16', 1],
93+
10: ['Pre-FEC BER Minimum Host Input', 'F16', 1],
94+
11: ['Pre-FEC BER Maximum Media Input', 'F16', 1],
95+
12: ['Pre-FEC BER Maximum Host Input', 'F16', 1],
96+
13: ['Pre-FEC BER Average Media Input', 'F16', 1],
97+
14: ['Pre-FEC BER Average Host Input', 'F16', 1],
98+
15: ['Pre-FEC BER Current Value Media Input', 'F16', 1],
99+
16: ['Pre-FEC BER Current Value Host Input', 'F16', 1],
100+
17: ['Errored Frames Minimum Media Input', 'F16', 1],
101+
18: ['Errored Frames Minimum Host Input', 'F16', 1],
102+
19: ['Errored Frames Maximum Media Input', 'F16', 1],
103+
20: ['Errored Frames Maximum Host Input', 'F16', 1],
104+
21: ['Errored Frames Average Media Input', 'F16', 1],
105+
22: ['Errored Frames Average Host Input', 'F16', 1],
106+
23: ['Errored Frames Current Value Media Input', 'F16', 1],
107+
24: ['Errored Frames Current Value Host Input', 'F16', 1],
108+
128: ['Modulator Bias X/I [%]', 'U16', 100.0/65535],
109+
129: ['Modulator Bias X/Q [%]', 'U16', 100.0/65535],
110+
130: ['Modulator Bias Y/I [%]', 'U16', 100.0/65535],
111+
131: ['Modulator Bias Y/Q [%]', 'U16', 100.0/65535],
112+
132: ['Modulator Bias X_Phase [%]', 'U16', 100.0/65535],
113+
133: ['Modulator Bias Y_Phase [%]', 'U16', 100.0/65535],
114+
134: ['CD high granularity, short link [ps/nm]', 'S16', 1],
115+
135: ['CD low granularity, long link [ps/nm]', 'S16', 20],
116+
136: ['DGD [ps]', 'U16', 0.01],
117+
137: ['SOPMD [ps^2]', 'U16', 0.01],
118+
138: ['PDL [dB]', 'U16', 0.1],
119+
139: ['OSNR [dB]', 'U16', 0.1],
120+
140: ['eSNR [dB]', 'U16', 0.1],
121+
141: ['CFO [MHz]', 'S16', 1],
122+
142: ['EVM_modem [%]', 'U16', 100.0/65535],
123+
143: ['Tx Power [dBm]', 'S16', 0.01],
124+
144: ['Rx Total Power [dBm]', 'S16', 0.01],
125+
145: ['Rx Signal Power [dBm]', 'S16', 0.01],
126+
146: ['SOP ROC [krad/s]', 'U16', 1],
127+
147: ['MER [dB]', 'U16', 0.1]
128+
}
129+
130+
CDB_FAIL_STATUS = {
131+
0: 'reserved',
132+
1: 'CMDID unknown',
133+
2: 'Parameter range error or parameter not supported',
134+
3: 'Previous CMD was not properly ABORTED',
135+
4: 'Command checking time out',
136+
5: 'CdbChkCode Error',
137+
6: 'Password related error',
138+
7: 'Command not compatible with operating status'
139+
}
140+
141+
# TODO: Add other codes

0 commit comments

Comments
 (0)