diff --git a/sonic_platform_base/sfp_base.py b/sonic_platform_base/sfp_base.py index 3fe4288d437a..ae95deee4d2e 100644 --- a/sonic_platform_base/sfp_base.py +++ b/sonic_platform_base/sfp_base.py @@ -22,7 +22,7 @@ def get_transceiver_info(self): Returns: A dict which contains following keys/values : - ======================================================================== + ================================================================================ keys |Value Format |Information ---------------------------|---------------|---------------------------- type |1*255VCHAR |type of SFP @@ -39,7 +39,8 @@ def get_transceiver_info(self): specification_compliance |1*255VCHAR |specification compliance vendor_date |1*255VCHAR |vendor date vendor_oui |1*255VCHAR |vendor OUI - ======================================================================== + application_advertisement |1*255VCHAR |supported applications advertisement + ================================================================================ """ raise NotImplementedError diff --git a/sonic_platform_base/sonic_sfp/qsfp_dd.py b/sonic_platform_base/sonic_sfp/qsfp_dd.py new file mode 100644 index 000000000000..33c9737b0613 --- /dev/null +++ b/sonic_platform_base/sonic_sfp/qsfp_dd.py @@ -0,0 +1,729 @@ +#! /usr/bin/env python +#---------------------------------------------------------------------------- +# QSFP-DD 8X Transceiver (QSFP Double Density) +#---------------------------------------------------------------------------- + +from __future__ import print_function + +try: + from sff8024 import type_of_transceiver # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import type_abbrv_name # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import connector_dict # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import ext_type_of_transceiver # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import type_of_media_interface # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import host_electrical_interface # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import nm_850_media_interface # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import sm_media_interface # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import passive_copper_media_interface # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import active_cable_media_interface # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sff8024 import base_t_media_interface # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from sonic_platform_base.sonic_sfp.sffbase import sffbase # Dot module supports both Python 2 and Python 3 using explicit relative import methods +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +#------------------------------------------------------------------------------ + +class qsfp_dd_InterfaceId(sffbase): + + def decode_revision_compliance(self, eeprom_data, offset, size): + # first nibble and second nibble represent the version + return '%c.%c' % (str((eeprom_data[offset][0] >> 4) & 0x0f), str((eeprom_data[offset][0] & 0x0f))) + + def decode_module_state(self, eeprom_data, offset, size): + module_state_byte = eeprom_data[offset] + # bits 1-3 + module_state = (int(module_state_byte, 16) >> 1) & 3 + if module_state == 1: + return 'Low Power state (Flat memory passive cable assemblies)' + elif module_state == 2: + return 'Power Up State' + elif module_state == 3: + return 'Ready State' + elif module_state == 4: + return 'Power Down State' + elif module_state == 5: + return 'Fault State' + return 'Unknown State %s' % module_state + + def decode_connector(self, eeprom_data, offset, size): + connector_id = eeprom_data[offset] + return connector_dict[connector_id] + + def decode_ext_id(self, eeprom_data, offset, size): + # bits 5-7 represent Module Card Power Class + ext_id_power_class_byte = eeprom_data[offset] + ext_id_power_class_code = (int(ext_id_power_class_byte, 16) >> 5) & 3 + # Max power is in multiply of 0.25W + ext_id_max_power_byte = eeprom_data[offset + 1] + ext_id_max_power_value = int(ext_id_max_power_byte, 16) + return ext_type_of_transceiver[str(ext_id_power_class_code)] + "({}W Max)".format(ext_id_max_power_value * 0.25) + + def decode_cable_len(self, eeprom_data, offset, size): + cable_byte = eeprom_data[offset] + # base length im meters 0-5 bits + base_len = int(cable_byte, 16) & 0x3f + # mult_code 6-7 bits + mult_code = (int(cable_byte, 16) >> 6) & 0x03 + if mult_code == 0: + mult = 0.1 + elif mult_code == 1: + mult = 1 + elif mult_code == 2: + mult = 10 + else: + mult = 100 + + return base_len * mult + + def decode_media_type(self, eeprom_data, offset, size): + media_type_code = eeprom_data[0] + dict_name = type_of_media_interface[media_type_code] + if dict_name == "nm_850_media_interface": + return nm_850_media_interface + elif dict_name == "sm_media_interface": + return sm_media_interface + elif dict_name == "passive_copper_media_interface": + return passive_copper_media_interface + elif dict_name == "active_cable_media_interface": + return active_cable_media_interface + elif dict_name == "base_t_media_interface": + return base_t_media_interface + else: + return None + + def parse_application(self, sfp_media_type_dict, host_interface, media_interface): + host_result = host_electrical_interface[host_interface] + media_result = sfp_media_type_dict[media_interface] + return host_result, media_result + + version = '1.0' + + connector = { + 'Connector': + {'offset':0, + 'type' : 'func', + 'decode': {'func': decode_connector}} + } + + sfp_type = { + 'type': + {'offset': 0, + 'size': 1, + 'type': 'enum', + 'decode': type_of_transceiver} + } + + ext_iden = { + 'Extended Identifier': + {'offset': 0, + 'type': 'func', + 'decode': {'func': decode_ext_id}} + } + + cable_len = { + 'Length Cable Assembly(m)': + {'offset': 0, + 'type': 'func', + 'decode': {'func': decode_cable_len}} + } + + rev_comp = { + 'Revision Compliance': + {'offset': 0, + 'type': 'func', + 'decode': {'func': decode_revision_compliance}} + } + + sfp_type_abbrv_name = { + 'type_abbrv_name': + {'offset': 0, + 'size': 1, + 'type': 'enum', + 'decode': type_abbrv_name} + } + + vendor_name = { + 'Vendor Name': + {'offset': 0, + 'size': 16, + 'type': 'str'} + } + + vendor_pn = { + 'Vendor PN': + {'offset': 0, + 'size': 16, + 'type': 'str'} + } + + vendor_rev = { + 'Vendor Rev': + {'offset': 0, + 'size': 2, + 'type': 'str'} + } + + vendor_sn = { + 'Vendor SN': + {'offset': 0, + 'size': 16, + 'type': 'str'} + } + + vendor_oui = { + 'Vendor OUI': + {'offset':0, + 'size':3, + 'type' : 'hex'} + } + + qsfp_dd_dom_capability = { + 'Flat_MEM': + {'offset': 0, + 'bit': 7, + 'type': 'bitvalue'} + } + + vendor_date = { + 'VendorDataCode(YYYY-MM-DD Lot)': + {'offset':0, + 'size':8, + 'type': 'date'} + } + + def parse_sfp_type(self, type_raw_data, start_pos): + return sffbase.parse(self, self.sfp_type, type_raw_data, start_pos) + + def parse_sfp_type_abbrv_name(self, type_raw_data, start_pos): + return sffbase.parse(self, self.sfp_type_abbrv_name, type_raw_data, start_pos) + + def parse_vendor_name(self, name_raw_data, start_pos): + return sffbase.parse(self, self.vendor_name, name_raw_data, start_pos) + + def parse_vendor_rev(self, rev_raw_data, start_pos): + return sffbase.parse(self, self.vendor_rev, rev_raw_data, start_pos) + + def parse_vendor_pn(self, pn_raw_data, start_pos): + return sffbase.parse(self, self.vendor_pn, pn_raw_data, start_pos) + + def parse_vendor_sn(self, sn_raw_data, start_pos): + return sffbase.parse(self, self.vendor_sn, sn_raw_data, start_pos) + + def parse_vendor_date(self, date_raw_data, start_pos): + return sffbase.parse(self, self.vendor_date, date_raw_data, start_pos) + + def parse_vendor_oui(self, vendor_oui_data, start_pos): + return sffbase.parse(self, self.vendor_oui, vendor_oui_data, start_pos) + + def parse_connector(self, connector_data, start_pos): + return sffbase.parse(self, self.connector, connector_data, start_pos) + + def parse_ext_iden(self, ext_iden_data, start_pos): + return sffbase.parse(self, self.ext_iden, ext_iden_data, start_pos) + + def parse_cable_len(self, cable_len_data, start_pos): + return sffbase.parse(self, self.cable_len, cable_len_data, start_pos) + + def parse_qsfp_dom_capability(self, qsfp_dom_capability_raw_data, start_pos): + return sffbase.parse(self, self.qsfp_dd_dom_capability, qsfp_dom_capability_raw_data, start_pos) + + def parse_media_type(self, qsfp_media_type_raw_data, start_pos): + return self.decode_media_type(qsfp_media_type_raw_data, start_pos, 1) + +class qsfp_dd_Dom(sffbase): + + version = '1.0' + + def calc_temperature(self, eeprom_data, offset, size): + try: + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = self.twos_comp(result, 16) + + result = float(result / 256.0) + retval = '%.4f' %result + 'C' + + except Exception as err: + retval = str(err) + + return retval + + + def calc_voltage(self, eeprom_data, offset, size): + try: + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + result = (msb << 8) | (lsb & 0xff) + + result = float(result * 0.0001) + retval = '%.4f' %result + 'Volts' + + except Exception as err: + retval = str(err) + + return retval + + + def calc_bias(self, eeprom_data, offset, size): + try: + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + result = (msb << 8) | (lsb & 0xff) + + result = float(result * 0.002) + retval = '%.4f' %result + 'mA' + + except Exception as err: + retval = str(err) + + return retval + + + def calc_tx_power(self, eeprom_data, offset, size): + try: + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + result = (msb << 8) | (lsb & 0xff) + + result = float(result * 0.0001) + retval = self.power_in_dbm_str(result) + + except Exception as err: + retval = str(err) + + return retval + + + def calc_rx_power(self, eeprom_data, offset, size): + try: + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + result = (msb << 8) | (lsb & 0xff) + + result = float(result * 0.0001) + retval = self.power_in_dbm_str(result) + + except Exception as err: + retval = str(err) + + return retval + + dom_channel_status = { + 'Status': + {'offset': 0, + 'bit': 3, + 'type': 'bitvalue'}} + + dom_channel_monitor_params = { + 'TX8Bias': + {'offset': 30, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX7Bias': + {'offset': 28, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX6Bias': + {'offset': 26, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX5Bias': + {'offset': 24, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX4Bias': + {'offset': 22, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX3Bias': + {'offset': 20, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX2Bias': + {'offset': 18, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX1Bias': + {'offset': 16, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'RX8Power': + {'offset': 46, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX7Power': + {'offset': 44, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX6Power': + {'offset': 42, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX5Power': + {'offset': 40, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX4Power': + {'offset': 38, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX3Power': + {'offset': 36, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX2Power': + {'offset': 34, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX1Power': + {'offset': 32, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'TX8Power': + {'offset': 14, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX7Power': + {'offset': 12, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX6Power': + {'offset': 10, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX5Power': + {'offset': 8, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX4Power': + {'offset': 6, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX3Power': + {'offset': 4, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX2Power': + {'offset': 2, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX1Power': + {'offset': 0, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}} + } + + dom_tx_bias = { + 'TX8Bias': + {'offset': 14, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX7Bias': + {'offset': 12, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX6Bias': + {'offset': 10, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX5Bias': + {'offset': 8, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX4Bias': + {'offset': 6, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX3Bias': + {'offset': 4, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX2Bias': + {'offset': 2, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}}, + 'TX1Bias': + {'offset': 0, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_bias}} + } + + dom_rx_power = { + 'RX8Power': + {'offset': 14, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX7Power': + {'offset': 12, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX6Power': + {'offset': 10, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX5Power': + {'offset': 8, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX4Power': + {'offset': 6, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX3Power': + {'offset': 4, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX2Power': + {'offset': 2, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}}, + 'RX1Power': + {'offset': 0, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_rx_power}} + } + + dom_tx_power = { + 'TX8Power': + {'offset': 14, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX7Power': + {'offset': 12, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX6Power': + {'offset': 10, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX5Power': + {'offset': 8, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX4Power': + {'offset': 6, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX3Power': + {'offset': 4, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX2Power': + {'offset': 2, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}}, + 'TX1Power': + {'offset': 0, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_tx_power}} + } + + dom_module_temperature = { + 'Temperature': + {'offset': 0, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_temperature}} + } + + dom_module_voltage = { + 'Vcc': + {'offset': 0, + 'size': 2, + 'type': 'func', + 'decode': {'func': calc_voltage}} + } + + dom_module_threshold_values = { + 'TempHighAlarm': + {'offset':0, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_temperature}}, + 'TempLowAlarm': + {'offset':2, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_temperature}}, + 'TempHighWarning': + {'offset':4, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_temperature}}, + 'TempLowWarning': + {'offset':6, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_temperature}}, + 'VccHighAlarm': + {'offset':8, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccLowAlarm': + {'offset':10, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccHighWarning': + {'offset':12, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccLowWarning': + {'offset':14, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'RxPowerHighAlarm': + {'offset':64, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerLowAlarm': + {'offset':66, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerHighWarning': + {'offset':68, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerLowWarning': + {'offset':70, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'TxBiasHighAlarm': + {'offset':56, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasLowAlarm': + {'offset':58, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasHighWarning': + {'offset':60, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasLowWarning': + {'offset':62, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxPowerHighAlarm': + {'offset':48, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_tx_power}}, + 'TxPowerLowAlarm': + {'offset':50, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_tx_power}}, + 'TxPowerHighWarning': + {'offset':52, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_tx_power}}, + 'TxPowerLowWarning': + {'offset':54, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_tx_power}} + } + + def parse_temperature(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_module_temperature, eeprom_raw_data, + start_pos) + + def parse_voltage(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_module_voltage, eeprom_raw_data, + start_pos) + + def parse_channel_monitor_params(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_channel_monitor_params, eeprom_raw_data, + start_pos) + + def parse_dom_tx_bias(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_tx_bias, eeprom_raw_data, + start_pos) + + def parse_dom_rx_power(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_rx_power, eeprom_raw_data, + start_pos) + + def parse_dom_tx_power(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_tx_power, eeprom_raw_data, + start_pos) + + def parse_module_threshold_values(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_module_threshold_values, eeprom_raw_data, + start_pos) + + def parse_dom_channel_status(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_channel_status, eeprom_raw_data, + start_pos) + + def parse_dom_tx_fault(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_tx_fault, eeprom_raw_data, + start_pos) + + def parse_dom_tx_disable (self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_tx_disable, eeprom_raw_data, + start_pos) + diff --git a/sonic_platform_base/sonic_sfp/sff8024.py b/sonic_platform_base/sonic_sfp/sff8024.py index 2a8e5542661b..6f5ee5b4c932 100644 --- a/sonic_platform_base/sonic_sfp/sff8024.py +++ b/sonic_platform_base/sonic_sfp/sff8024.py @@ -64,3 +64,239 @@ '19': 'OSFP-8X', '1a': 'SFP-DD' } + +connector_dict = { + '00': 'Unknown or unspecified', + '01': 'SC', + '02': 'FC Style 1 copper connector', + '03': 'FC Style 2 copper connector', + '04': 'BNC/TNC', + '05': 'FC coax headers', + '06': 'Fiberjack', + '07': 'LC', + '08': 'MT-RJ', + '09': 'MU', + '0a': 'SG', + '0b': 'Optical Pigtail', + '0c': 'MPO 1x12', + '0d': 'MPO 2x16', + '20': 'HSSDC II', + '21': 'Copper pigtail', + '22': 'RJ45', + '23': 'No separable connector', + '24': 'MXC 2x16', + '25': 'CS optical connector', + '26': 'SN optical connector', + '27': 'MPO 2x12', + '28': 'MPO 1x16', + } + +ext_type_of_transceiver = { + '0': 'Power Class 1', + '1': 'Power Class 2', + '2': 'Power Class 3', + '3': 'Power Class 4', + '4': 'Power Class 5', + '5': 'Power Class 6', + '6': 'Power Class 7', + '7': 'Power Class 8' + } + +type_of_media_interface = { + '00': 'Undefined', + '01': 'nm_850_media_interface', + '02': 'sm_media_interface', + '03': 'passive_copper_media_interface', + '04': 'active_cable_media_interface', + '05': 'base_t_media_interface', + } + +host_electrical_interface = { + '00': 'Undefined', + '01': '1000BASE -CX(Clause 39)', + '02': 'XAUI(Clause 47)', + '03': 'XFI (SFF INF-8071i)', + '04': 'SFI (SFF-8431)', + '05': '25GAUI C2M (Annex 109B)', + '06': 'XLAUI C2M (Annex 83B)', + '07': 'XLPPI (Annex 86A)', + '08': 'LAUI-2 C2M (Annex 135C)', + '09': '50GAUI-2 C2M (Annex 135E)', + '0a': '50GAUI-1 C2M (Annex 135G)', + '0b': 'CAUI-4 C2M (Annex 83E)', + '41': 'CAUI-4 C2M (Annex 83E) without FEC', + '42': 'CAUI-4 C2M (Annex 83E) with RS(528,514) FEC', + '0c': '100GAUI-4 C2M (Annex 135E)', + '0d': '100GAUI-2 C2M (Annex 135G)', + '0e': '200GAUI-8 C2M (Annex 120C)', + '0f': '200GAUI-4 C2M (Annex 120E)', + '10': '400GAUI-16 C2M (Annex 120C)', + '11': '400GAUI-8 C2M (Annex 120E)', + '13': '10GBASE-CX4 (Clause 54)', + '14': '25GBASE-CR CA-L (Clause 110)', + '15': '25GBASE-CR CA-S (Clause 110)', + '16': '25GBASE-CR CA-N (Clause 110)', + '17': '40GBASE-CR4 (Clause 85)', + '43': '50GBASE-CR2 with RS (Clause 91) FEC', + '44': '50GBASE-CR2 with BASE-R (Clause 74 Fire code) FEC', + '45': '50GBASE-CR2 with no FEC', + '18': '50GBASE-CR (Clause 126)', + '19': '100GBASE-CR10 (Clause 85)', + '1a': '100GBASE-CR4 (Clause 92)', + '1b': '100GBASE-CR2 (Clause 136)', + '1c': '200GBASE-CR4 (Clause 136)', + '1d': '400G CR8', + '1e': '1000BASE-T (Clause 40)', + '1f': '2.5GBASE-T (Clause 126)', + '20': '5GBASE-T (Clause 126)', + '21': '10GBASE-T (Clause 55)', + '22': '25GBASE-T (Clause 113)', + '23': '40GBASE-T (Clause 113)', + '24': '50GBASE-T (Placeholder)', + '25': '8GFC (FC-PI-4)', + '26': '10GFC (10GFC)', + '27': '16GFC (FC-PI-5)', + '28': '32GFC (FC-PI-6)', + '29': '64GFC (FC-PI-7)', + '2a': '128GFC (FC-PI-6P)', + '2b': '256GFC (FC-PI-7P)', + '2c': 'IB SDR (Arch.Spec.Vol.2)', + '2d': 'IB DDR (Arch.Spec.Vol.2)', + '2e': 'IB QDR (Arch.Spec.Vol.2)', + '2f': 'IB FDR (Arch.Spec.Vol.2)', + '30': 'IB EDR (Arch.Spec.Vol.2)', + '31': 'IB HDR (Arch.Spec.Vol.2)', + '32': 'IB NDR', + '33': 'E.96 (CPRI Specification V7.0)', + '34': 'E.99 (CPRI Specification V7.0)', + '35': 'E.119 (CPRI Specification V7.0)', + '36': 'E.238 (CPRI Specification V7.0)', + '37': 'OTL3.4 (ITU-T G.709/Y.1331 G.Sup58)', + '38': 'OTL4.10 (ITU-T G.709/Y.1331 G.Sup58)', + '39': 'OTL4.4 (ITU-T G.709/Y.1331 G.Sup58)', + '3a': 'OTLC.4 (ITU-T G.709.1/Y.1331 G.Sup58)', + '3b': 'FOIC1.4 (ITU-T G.709.1/Y.1331 G.Sup58)', + '3c': 'FOIC1.2 (ITU-T G.709.1/Y.1331 G.Sup58)', + '3d': 'FOIC2.8 (ITU-T G.709.1/Y.1331 G.Sup58)', + '3e': 'FOIC2.4 (ITU-T G.709.1/Y.1331 G.Sup58)', + '3f': 'FOIC4.16 (ITU-T G.709.1 G.Sup58)', + '40': 'FOIC4.8 (ITU-T G.709.1 G.Sup58)', + } + +nm_850_media_interface = { + '00': 'Undefined', + '01': '10GBASE-SW (Clause 52)', + '02': '10GBASE-SR (Clause 52)', + '03': '25GBASE-SR (Clause 112)', + '04': '40GBASE-SR4 (Clause 86)', + '05': '40GE SWDM4 MSA Spec', + '06': '40GE BiDi', + '07': '50GBASE-SR (Clause 138)', + '08': '100GBASE-SR10 (Clause 86)', + '09': '100GBASE-SR4 (Clause 95)', + '0a': '100GE SWDM4 MSA Spec', + '0b': '100GE BiDi', + '0c': '100GBASE-SR2 (Clause 138)', + '0d': '100G-SR (Placeholder)', + '0e': '200GBASE-SR4 (Clause 138)', + '0f': '400GBASE-SR16 (Clause 123)', + '10': '400GBASE-SR8 (Clause 138)', + '11': '400G-SR4 (Placeholder)', + '12': '800G-SR8 (Placeholder)', + '1a': '400GBASE-SR4.2 (Clause 150) (400GE BiDi)', + '13': '8GFC-MM (FC-PI-4)', + '14': '10GFC-MM (10GFC)', + '15': '16GFC-MM (FC-PI-5)', + '16': '32GFC-MM (FC-PI-6)', + '17': '64GFC-MM (FC-PI 7)', + '18': '128GFC-MM4 (FC-PI-6P)', + '19': '256GFC-MM4 (FC-PI-7P)', + } + +sm_media_interface = { + '00': 'Undefined', + '01': '10GBASE-LW (Cl 52)', + '02': '10GBASE-EW (Cl 52)', + '03': '10G-ZW', + '04': '10GBASE-LR (Cl 52)', + '05': '10GBASE-ER (Cl 52)', + '06': '10G-ZR', + '07': '25GBASE-LR (Cl 114)', + '08': '25GBASE-ER (Cl 114)', + '09': '40GBASE-LR4 (Cl 87)', + '0a': '40GBASE-FR (Cl 89)', + '0b': '50GBASE-FR (Cl 139)', + '0c': '50GBASE-LR (Cl 139)', + '40': '50GBASE-ER (Cl 139)', + '0d': '100GBASE-LR4 (Cl 88)', + '0e': '100GBASE-ER4 (Cl 88)', + '0f': '100G PSM4 MSA Spec', + '34': '100G CWDM4-OCP', + '10': '100G CWDM4 MSA Spec', + '11': '100G 4WDM-10 MSA Spec', + '12': '100G 4WDM-20 MSA Spec', + '13': '100G 4WDM-40 MSA Spec', + '14': '100GBASE-DR (Cl 140)', + '15': '100G-FR/100GBASE-FR1 (Cl 140)', + '16': '100G-LR/100GBASE-LR1 (Cl 140)', + '17': '200GBASE-DR4 (Cl 121)', + '18': '200GBASE-FR4 (Cl 122)', + '19': '200GBASE-LR4 (Cl 122)', + '41': '200GBASE-ER4 (Cl 122)', + '1a': '400GBASE-FR8 (Cl 122)', + '1b': '400GBASE-LR8 (Cl 122)', + '42': '400GBASE-ER8 (Cl 122)', + '1c': '400GBASE-DR4 (Cl 124)', + '1d': '400G-FR4/400GBASE-FR4 (Cl 151)', + '43': '400GBASE-LR4-6 (Cl 151)', + '1e': '400G-LR4-10', + '1f': '8GFC-SM (FC-PI-4)', + '20': '10GFC-SM (10GFC)', + '21': '16GFC-SM (FC-PI-5)', + '22': '32GFC-SM (FC-PI-6)', + '23': '64GFC-SM (FC-PI-7)', + '24': '128GFC-PSM4 (FC-PI-6P)', + '25': '256GFC-PSM4 (FC-PI-7P)', + '26': '128GFC-CWDM4 (FC-PI-6P)', + '27': '256GFC-CWDM4 (FC-PI-7P)', + '2c': '4I1-9D1F (G.959.1)', + '2d': '4L1-9C1F (G.959.1)', + '2e': '4L1-9D1F (G.959.1)', + '2f': 'C4S1-9D1F (G.695)', + '30': 'C4S1-4D1F (G.695)', + '31': '4I1-4D1F (G.959.1)', + '32': '8R1-4D1F (G.959.1)', + '33': '8I1-4D1F (G.959.1)', + '38': '10G-SR', + '39': '10G-LR', + '3a': '25G-SR', + '3b': '25G-LR', + '3c': '10G-LR-BiDi', + '3d': '25G-LR-BiDi', + '3e': '400ZR, DWDM, amplified', + '3f': '400ZR, Single Wavelength, Unamplified', + } + +passive_copper_media_interface = { + '00': 'Undefined', + '01': 'Copper cable', + '02': 'Passive Loopback module', + } + +active_cable_media_interface = { + '00': 'Undefined', + '01': 'Active Cable assembly with BER < 10^-12', + '02': 'Active Cable assembly with BER < 5x10^-5', + '03': 'Active Cable assembly with BER < 2.6x10^-4', + '04': 'Active Cable assembly with BER < 10^-6', + 'bf': 'Active Loopback module', + } + +base_t_media_interface = { + '00': 'Undefined', + '01': '1000BASE-T (Clause 40)', + '02': '2.5GBASE-T (Clause 126)', + '03': '5GBASE-T (Clause 126)', + '04': '10GBASE-T (Clause 55)', + } +