From 6b12b4c86e6a543d5c784d58a55d7c3902e55c47 Mon Sep 17 00:00:00 2001 From: Kuanyu Chen Date: Wed, 20 Jan 2021 01:46:41 +0800 Subject: [PATCH] [sfp] Add parsing the dom_capability to sff8472 (#102) - What I did Following SFF-8472 to read diagnostic monitoring type register. Use that register to check if diagnostic monitoring function implemented or not. - How I did it Check the register position from SFF-8472 document. Read the register value from the EEPROM. --- sonic_platform_base/sonic_sfp/sff8436.py | 4 +-- sonic_platform_base/sonic_sfp/sff8472.py | 10 ++++++++ sonic_platform_base/sonic_sfp/sfputilbase.py | 26 +++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/sonic_platform_base/sonic_sfp/sff8436.py b/sonic_platform_base/sonic_sfp/sff8436.py index 0146bfcea..13b1277e7 100644 --- a/sonic_platform_base/sonic_sfp/sff8436.py +++ b/sonic_platform_base/sonic_sfp/sff8436.py @@ -506,14 +506,14 @@ def parse_vendor_sn(self, sn_raw_data, start_pos): def parse_vendor_date(self, sn_raw_data, start_pos): return sffbase.parse(self, self.vendor_date, sn_raw_data, start_pos) - + def parse_vendor_oui(self, sn_raw_data, start_pos): return sffbase.parse(self, self.vendor_oui, sn_raw_data, start_pos) def parse_ext_specification_compliance(self, sn_raw_data, start_pos): return sffbase.parse(self, self.sfp_ext_specification_compliance, sn_raw_data, start_pos) - def parse_qsfp_dom_capability(self, sn_raw_data, start_pos): + def parse_dom_capability(self, sn_raw_data, start_pos): return sffbase.parse(self, self.qsfp_dom_capability, sn_raw_data, start_pos) def dump_pretty(self): diff --git a/sonic_platform_base/sonic_sfp/sff8472.py b/sonic_platform_base/sonic_sfp/sff8472.py index 9ded3f4e7..46e0b318c 100644 --- a/sonic_platform_base/sonic_sfp/sff8472.py +++ b/sonic_platform_base/sonic_sfp/sff8472.py @@ -519,6 +519,13 @@ class sff8472InterfaceId(sffbase): 'type': 'date'} } + sfp_dom_capability = { + 'sff8472_dom_support': + {'offset': 0, + 'bit': 6, + 'type': 'bitvalue'} + } + # Returns calibration type def _get_calibration_type(self, eeprom_data): try: @@ -568,6 +575,9 @@ def parse_vendor_date(self, sn_raw_data, start_pos): def parse_vendor_oui(self, sn_raw_data, start_pos): return sffbase.parse(self, self.vendor_oui, sn_raw_data, start_pos) + def parse_dom_capability(self, dom_type_raw_data, start_pos): + return sffbase.parse(self, self.sfp_dom_capability, dom_type_raw_data, start_pos) + def dump_pretty(self): if self.interface_data == None: print('Object not initialized, nothing to print') diff --git a/sonic_platform_base/sonic_sfp/sfputilbase.py b/sonic_platform_base/sonic_sfp/sfputilbase.py index 3dcd31416..8d5117266 100644 --- a/sonic_platform_base/sonic_sfp/sfputilbase.py +++ b/sonic_platform_base/sonic_sfp/sfputilbase.py @@ -122,6 +122,12 @@ 'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media', 'Fibre Channel Speed') +qsfp_dom_capability_tup = ('Tx_power_support', 'Rx_power_support', + 'Voltage_support', 'Temp_support') + +# Add an EOL to prevent this being viewed as string instead of list +sfp_dom_capability_tup = ('sff8472_dom_support', 'EOL') + class SfpUtilError(Exception): """Base class for exceptions in this module.""" pass @@ -818,6 +824,7 @@ def get_eeprom_dict(self, port_num): def get_transceiver_info_dict(self, port_num): transceiver_info_dict = {} compliance_code_dict = {} + dom_capability_dict = {} # ToDo: OSFP tranceiver info parsing not fully supported. # in inf8628.py lack of some memory map definition @@ -902,6 +909,7 @@ def get_transceiver_info_dict(self, port_num): transceiver_info_dict['specification_compliance'] = '{}' transceiver_info_dict['nominal_bit_rate'] = 'N/A' transceiver_info_dict['application_advertisement'] = 'N/A' + transceiver_info_dict['dom_capability'] = '{}' else: file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) @@ -988,6 +996,12 @@ def get_transceiver_info_dict(self, port_num): else: return None + sfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability_data = sfpi_obj.parse_dom_capability(sfp_dom_capability_raw, 0) + else: + return None + try: sysfsfile_eeprom.close() except IOError: @@ -1021,6 +1035,11 @@ def get_transceiver_info_dict(self, port_num): compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + for key in qsfp_dom_capability_tup: + if key in sfp_dom_capability_data['data']: + dom_capability_dict[key] = "yes" if sfp_dom_capability_data['data'][key]['value'] == 'on' else "no" + transceiver_info_dict['dom_capability'] = str(dom_capability_dict) + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) else: for key in sfp_cable_length_tup: @@ -1033,6 +1052,11 @@ def get_transceiver_info_dict(self, port_num): compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + for key in sfp_dom_capability_tup: + if key in sfp_dom_capability_data['data']: + dom_capability_dict[key] = "yes" if sfp_dom_capability_data['data'][key]['value'] == 'on' else "no" + transceiver_info_dict['dom_capability'] = str(dom_capability_dict) + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) return transceiver_info_dict @@ -1092,7 +1116,7 @@ def get_transceiver_dom_info_dict(self, port_num): # in SFF-8636 dom capability definitions evolving with the versions. qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) if qsfp_dom_capability_raw is not None: - qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + qspf_dom_capability_data = sfpi_obj.parse_dom_capability(qsfp_dom_capability_raw, 0) else: return None