Skip to content

Commit

Permalink
Add flag to read partial VDM (sonic-net#397)
Browse files Browse the repository at this point in the history
It spend much time to read full VDM.
Add flag to read VDM for real value, threshold or flag.

Signed-off-by: chiourung_huang <[email protected]>
Co-authored-by: Prince George <[email protected]>
  • Loading branch information
chiourung and prgeor authored Mar 20, 2024
1 parent 56921d8 commit 2606cd5
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 45 deletions.
12 changes: 7 additions & 5 deletions sonic_platform_base/sonic_xcvr/api/public/cmis.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def get_transceiver_bulk_status(self):
bulk_status["tx%dpower" % i] = float("{:.3f}".format(self.mw_to_dbm(tx_power[i - 1]))) if tx_power[i - 1] != 'N/A' else 'N/A'

laser_temp_dict = self.get_laser_temperature()
self.vdm_dict = self.get_vdm()
self.vdm_dict = self.get_vdm(self.vdm.VDM_REAL_VALUE)
try:
bulk_status['laser_temperature'] = laser_temp_dict['monitor value']
bulk_status['prefec_ber'] = self.vdm_dict['Pre-FEC BER Average Media Input'][1][0]
Expand Down Expand Up @@ -303,7 +303,7 @@ def get_transceiver_threshold_info(self):
threshold_info_dict['lasertemplowwarning'] = laser_temp_dict['low warn']
except (KeyError, TypeError):
pass
self.vdm_dict = self.get_vdm()
self.vdm_dict = self.get_vdm(self.vdm.VDM_THRESHOLD)
try:
threshold_info_dict['prefecberhighalarm'] = self.vdm_dict['Pre-FEC BER Average Media Input'][1][1]
threshold_info_dict['prefecberlowalarm'] = self.vdm_dict['Pre-FEC BER Average Media Input'][1][2]
Expand Down Expand Up @@ -1132,11 +1132,13 @@ def set_loopback_mode(self, loopback_mode):
else:
return False

def get_vdm(self):
def get_vdm(self, field_option=None):
'''
This function returns all the VDM items, including real time monitor value, threholds and flags
'''
vdm = self.vdm.get_vdm_allpage() if self.vdm is not None else {}
if field_option is None:
field_option = self.vdm.ALL_FIELD
vdm = self.vdm.get_vdm_allpage(field_option) if self.vdm is not None else {}
return vdm

def get_module_firmware_fault_state_changed(self):
Expand Down Expand Up @@ -1860,7 +1862,7 @@ def get_transceiver_status(self):
trans_status['txbiaslowalarm_flag%d' % lane] = tx_bias_flag_dict['tx_bias_low_alarm']['TxBiasLowAlarmFlag%d' % lane]
trans_status['txbiashighwarning_flag%d' % lane] = tx_bias_flag_dict['tx_bias_high_warn']['TxBiasHighWarnFlag%d' % lane]
trans_status['txbiaslowwarning_flag%d' % lane] = tx_bias_flag_dict['tx_bias_low_warn']['TxBiasLowWarnFlag%d' % lane]
self.vdm_dict = self.get_vdm()
self.vdm_dict = self.get_vdm(self.vdm.VDM_FLAG)
try:
trans_status['prefecberhighalarm_flag'] = self.vdm_dict['Pre-FEC BER Average Media Input'][1][5]
trans_status['prefecberlowalarm_flag'] = self.vdm_dict['Pre-FEC BER Average Media Input'][1][6]
Expand Down
99 changes: 67 additions & 32 deletions sonic_platform_base/sonic_xcvr/api/public/cmisVDM.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
VDM_UNFREEZE = 0

class CmisVdmApi(XcvrApi):

VDM_REAL_VALUE = 0x1
VDM_THRESHOLD = 0x2
VDM_FLAG = 0x4
ALL_FIELD = 0xff

def __init__(self, xcvr_eeprom):
super(CmisVdmApi, self).__init__(xcvr_eeprom)

Expand All @@ -30,7 +36,7 @@ def get_F16(self, value):
result = mantissa*10**(scale_exponent-24)
return result

def get_vdm_page(self, page, VDM_flag_page):
def get_vdm_page(self, page, VDM_flag_page, field_option=ALL_FIELD):
'''
This function returns VDM items from a specific VDM page.
Output format is a dictionary. Key is observable type; value is a dictionary.
Expand Down Expand Up @@ -67,42 +73,55 @@ def get_vdm_page(self, page, VDM_flag_page):
for index, typeID in enumerate(vdm_typeID):
if typeID not in VDM_TYPE_DICT:
continue
else:
vdm_info_dict = VDM_TYPE_DICT[typeID]
thrshID = VDM_thresholdID[index]
vdm_type = vdm_info_dict[0]
vdm_format = vdm_info_dict[1]
scale = vdm_info_dict[2]

vdm_value_offset = vdm_valuePage * PAGE_SIZE + PAGE_OFFSET + VDM_SIZE * index
vdm_high_alarm_offset = vdm_thrshPage * PAGE_SIZE + PAGE_OFFSET + THRSH_SPACING * thrshID
vdm_low_alarm_offset = vdm_high_alarm_offset + 2
vdm_high_warn_offset = vdm_high_alarm_offset + 4
vdm_low_warn_offset = vdm_high_alarm_offset + 6

vdm_info_dict = VDM_TYPE_DICT[typeID]
thrshID = VDM_thresholdID[index]
vdm_type = vdm_info_dict[0]
vdm_format = vdm_info_dict[1]
scale = vdm_info_dict[2]

vdm_value_offset = vdm_valuePage * PAGE_SIZE + PAGE_OFFSET + VDM_SIZE * index
vdm_high_alarm_offset = vdm_thrshPage * PAGE_SIZE + PAGE_OFFSET + THRSH_SPACING * thrshID
vdm_low_alarm_offset = vdm_high_alarm_offset + 2
vdm_high_warn_offset = vdm_high_alarm_offset + 4
vdm_low_warn_offset = vdm_high_alarm_offset + 6

if field_option & self.VDM_REAL_VALUE:
vdm_value_raw = self.xcvr_eeprom.read_raw(vdm_value_offset, VDM_SIZE, True)
vdm_thrsh_high_alarm_raw = self.xcvr_eeprom.read_raw(vdm_high_alarm_offset, VDM_SIZE, True)
vdm_thrsh_low_alarm_raw = self.xcvr_eeprom.read_raw(vdm_low_alarm_offset, VDM_SIZE, True)
vdm_thrsh_high_warn_raw = self.xcvr_eeprom.read_raw(vdm_high_warn_offset, VDM_SIZE, True)
vdm_thrsh_low_warn_raw = self.xcvr_eeprom.read_raw(vdm_low_warn_offset, VDM_SIZE, True)
if not vdm_value_raw or not vdm_thrsh_high_alarm_raw or not vdm_thrsh_low_alarm_raw \
or not vdm_high_warn_offset or not vdm_thrsh_low_warn_raw:
return {}
if not vdm_value_raw:
continue
if vdm_format == 'S16':
vdm_value = struct.unpack('>h',vdm_value_raw)[0] * scale
elif vdm_format == 'U16':
vdm_value = struct.unpack('>H',vdm_value_raw)[0] * scale
elif vdm_format == 'F16':
vdm_value_int = struct.unpack('>H',vdm_value_raw)[0]
vdm_value = self.get_F16(vdm_value_int)
else:
continue
else:
vdm_value = None

if field_option & self.VDM_THRESHOLD:
vdm_thrsh_raw = self.xcvr_eeprom.read_raw(vdm_high_alarm_offset, VDM_SIZE*4, True)
if not vdm_thrsh_raw:
continue
vdm_thrsh_high_alarm_raw = vdm_thrsh_raw[0:2]
vdm_thrsh_low_alarm_raw = vdm_thrsh_raw[2:4]
vdm_thrsh_high_warn_raw = vdm_thrsh_raw[4:6]
vdm_thrsh_low_warn_raw = vdm_thrsh_raw[6:8]

if vdm_format == 'S16':
vdm_thrsh_high_alarm = struct.unpack('>h', vdm_thrsh_high_alarm_raw)[0] * scale
vdm_thrsh_low_alarm = struct.unpack('>h', vdm_thrsh_low_alarm_raw)[0] * scale
vdm_thrsh_high_warn = struct.unpack('>h', vdm_thrsh_high_warn_raw)[0] * scale
vdm_thrsh_low_warn = struct.unpack('>h', vdm_thrsh_low_warn_raw)[0] * scale
elif vdm_format == 'U16':
vdm_value = struct.unpack('>H',vdm_value_raw)[0] * scale
vdm_thrsh_high_alarm = struct.unpack('>H', vdm_thrsh_high_alarm_raw)[0] * scale
vdm_thrsh_low_alarm = struct.unpack('>H', vdm_thrsh_low_alarm_raw)[0] * scale
vdm_thrsh_high_warn = struct.unpack('>H', vdm_thrsh_high_warn_raw)[0] * scale
vdm_thrsh_low_warn = struct.unpack('>H', vdm_thrsh_low_warn_raw)[0] * scale
elif vdm_format == 'F16':
vdm_value_int = struct.unpack('>H',vdm_value_raw)[0]
vdm_value = self.get_F16(vdm_value_int)
vdm_thrsh_high_alarm_int = struct.unpack('>H', vdm_thrsh_high_alarm_raw)[0]
vdm_thrsh_low_alarm_int = struct.unpack('>H', vdm_thrsh_low_alarm_raw)[0]
vdm_thrsh_high_warn_int = struct.unpack('>H', vdm_thrsh_high_warn_raw)[0]
Expand All @@ -113,13 +132,24 @@ def get_vdm_page(self, page, VDM_flag_page):
vdm_thrsh_low_warn = self.get_F16(vdm_thrsh_low_warn_int)
else:
continue
else:
vdm_thrsh_high_alarm = None
vdm_thrsh_low_alarm = None
vdm_thrsh_high_warn = None
vdm_thrsh_low_warn = None

vdm_flag_offset = 32 * (page - 0x20) + index//2
bit_offset = 4*(index%2)
vdm_high_alarm_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset)) & 0x1)
vdm_low_alarm_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset+1)) & 0x1)
vdm_high_warn_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset+2)) & 0x1)
vdm_low_warn_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset+3)) & 0x1)
if VDM_flag_page:
vdm_flag_offset = 32 * (page - 0x20) + index//2
bit_offset = 4*(index%2)
vdm_high_alarm_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset)) & 0x1)
vdm_low_alarm_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset+1)) & 0x1)
vdm_high_warn_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset+2)) & 0x1)
vdm_low_warn_flag = bool((VDM_flag_page[vdm_flag_offset] >> (bit_offset+3)) & 0x1)
else:
vdm_high_alarm_flag = None
vdm_low_alarm_flag = None
vdm_high_warn_flag = None
vdm_low_warn_flag = None

if vdm_type not in vdm_Page_data:
vdm_Page_data[vdm_type] = {
Expand Down Expand Up @@ -148,7 +178,7 @@ def get_vdm_page(self, page, VDM_flag_page):
vdm_low_warn_flag]
return vdm_Page_data

def get_vdm_allpage(self):
def get_vdm_allpage(self, field_option=ALL_FIELD ):
'''
This function returns VDM items from all advertised VDM pages.
Output format is a dictionary. Key is observable type; value is a dictionary.
Expand All @@ -170,8 +200,13 @@ def get_vdm_allpage(self):
return None
VDM_START_PAGE = 0x20
vdm = dict()
vdm_flag_page = self.xcvr_eeprom.read_raw(VDM_FLAG_PAGE * PAGE_SIZE + PAGE_OFFSET, PAGE_SIZE)

if field_option & self.VDM_FLAG:
vdm_flag_page = self.xcvr_eeprom.read_raw(VDM_FLAG_PAGE * PAGE_SIZE + PAGE_OFFSET, PAGE_SIZE)
else:
vdm_flag_page = None

for page in range(VDM_START_PAGE, VDM_START_PAGE + vdm_page_supported_raw + 1):
vdm_current_page = self.get_vdm_page(page, vdm_flag_page)
vdm_current_page = self.get_vdm_page(page, vdm_flag_page, field_option)
vdm.update(vdm_current_page)
return vdm
16 changes: 8 additions & 8 deletions tests/sonic_xcvr/test_cmisVDM.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ def test_get_F16(self, input_param, expected):
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'), bytearray(b'\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00'),
bytearray(b'\x00\x00'), bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00'),
],
{
'Pre-FEC BER Minimum Media Input': {1: [0, 0, 0, 0, 0, False, False, False, False]},
Expand Down

0 comments on commit 2606cd5

Please sign in to comment.