From b0de8b28636ba8fc1715dae35bc23a81f836a3da Mon Sep 17 00:00:00 2001 From: kuanyu_chen Date: Mon, 13 Jul 2020 17:07:36 +0800 Subject: [PATCH] [sfp] Add parsing the dom_capability to sff8472 * Read the diagnostic monitoring type register to get dom_capability * Provide basic dom_capability info table as transceiver info * Unify the name of parsing dom_capability function for both QSFP and SFP --- 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 0b88dafa6..a9c0dd95a 100644 --- a/sonic_platform_base/sonic_sfp/sff8436.py +++ b/sonic_platform_base/sonic_sfp/sff8436.py @@ -508,14 +508,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 d72b28978..f5cda90c3 100644 --- a/sonic_platform_base/sonic_sfp/sff8472.py +++ b/sonic_platform_base/sonic_sfp/sff8472.py @@ -521,6 +521,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: @@ -570,6 +577,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 56845c579..ddf17fbb2 100644 --- a/sonic_platform_base/sonic_sfp/sfputilbase.py +++ b/sonic_platform_base/sonic_sfp/sfputilbase.py @@ -123,6 +123,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 @@ -751,6 +757,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 @@ -835,6 +842,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) @@ -921,6 +929,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: @@ -954,6 +968,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: @@ -966,6 +985,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 @@ -1025,7 +1049,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