From 53103db91674d76db4fb548dace3140dc6ed2f46 Mon Sep 17 00:00:00 2001 From: Sridhar Ravindran Date: Wed, 29 May 2019 11:06:35 -0700 Subject: [PATCH 1/5] sonic_sfp: Support for DOM Threshold values for EEPROM dump --- sonic_sfp/sff8436.py | 469 +++++++++++++++++++++++++++++++++++++++ sonic_sfp/sfputilbase.py | 72 +++++- 2 files changed, 539 insertions(+), 2 deletions(-) diff --git a/sonic_sfp/sff8436.py b/sonic_sfp/sff8436.py index 98f6a0f12..96c2e68c3 100644 --- a/sonic_sfp/sff8436.py +++ b/sonic_sfp/sff8436.py @@ -1229,3 +1229,472 @@ def get_data(self): def get_data_pretty(self): return sffbase.get_data_pretty(self, self.dom_data) + +class sff8436DomThreshold(sffbase): + + version = '1.0' + + def get_calibration_type(self): + return self._calibration_type + + def calc_temperature(self, eeprom_data, offset, size): + try: + cal_type = self.get_calibration_type() + + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = self.twos_comp(result, 16) + + if cal_type == 1: + + # Internal calibration + + result = float(result / 256.0) + retval = '%.4f' %result + 'C' + elif cal_type == 2: + + # External calibration + + # T(C) = T_Slope * T_AD + T_Offset + off = self.dom_ext_calibration_constants['T_Slope']['offset'] + msb_t = int(eeprom_data[off], 16) + lsb_t = int(eeprom_data[off + 1], 16) + t_slope = (msb_t << 8) | (lsb_t & 0xff) + + off = self.dom_ext_calibration_constants['T_Offset']['offset'] + msb_t = int(eeprom_data[off], 16) + lsb_t = int(eeprom_data[off + 1], 16) + t_offset = (msb_t << 8) | (lsb_t & 0xff) + t_offset = self.twos_comp(t_offset, 16) + + result = t_slope * result + t_offset + result = float(result / 256.0) + retval = '%.4f' %result + 'C' + else: + retval = 'Unknown' + except Exception as err: + retval = str(err) + + return retval + + def calc_voltage(self, eeprom_data, offset, size): + try: + cal_type = self.get_calibration_type() + + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + result = (msb << 8) | (lsb & 0xff) + + if cal_type == 1: + + # Internal Calibration + + result = float(result * 0.0001) + retval = '%.4f' %result + 'Volts' + elif cal_type == 2: + + # External Calibration + + # V(uV) = V_Slope * VAD + V_Offset + off = self.dom_ext_calibration_constants['V_Slope']['offset'] + msb_v = int(eeprom_data[off], 16) + lsb_v = int(eeprom_data[off + 1], 16) + v_slope = (msb_v << 8) | (lsb_v & 0xff) + + off = self.dom_ext_calibration_constants['V_Offset']['offset'] + msb_v = int(eeprom_data[off], 16) + lsb_v = int(eeprom_data[off + 1], 16) + v_offset = (msb_v << 8) | (lsb_v & 0xff) + v_offset = self.twos_comp(v_offset, 16) + + result = v_slope * result + v_offset + result = float(result * 0.0001) + retval = '%.4f' %result + 'Volts' + else: + retval = 'Unknown' + except Exception as err: + retval = str(err) + + return retval + + + def calc_bias(self, eeprom_data, offset, size): + try: + cal_type = self.get_calibration_type() + + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + result = (msb << 8) | (lsb & 0xff) + + if cal_type == 1: + # Internal Calibration + + result = float(result * 0.002) + retval = '%.4f' %result + 'mA' + + elif cal_type == 2: + # External Calibration + + # I(uA) = I_Slope * I_AD + I_Offset + off = self.dom_ext_calibration_constants['I_Slope']['offset'] + msb_i = int(eeprom_data[off], 16) + lsb_i = int(eeprom_data[off + 1], 16) + i_slope = (msb_i << 8) | (lsb_i & 0xff) + + off = self.dom_ext_calibration_constants['I_Offset']['offset'] + msb_i = int(eeprom_data[off], 16) + lsb_i = int(eeprom_data[off + 1], 16) + i_offset = (msb_i << 8) | (lsb_i & 0xff) + i_offset = self.twos_comp(i_offset, 16) + + result = i_slope * result + i_offset + result = float(result * 0.002) + retval = '%.4f' %result + 'mA' + else: + retval = 'Unknown' + except Exception as err: + retval = str(err) + + return retval + + def calc_rx_power(self, eeprom_data, offset, size): + try: + cal_type = self.get_calibration_type() + + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + result = (msb << 8) | (lsb & 0xff) + + if cal_type == 1: + + # Internal Calibration + result = float(result * 0.0001) + retval = self.power_in_dbm_str(result) + + elif cal_type == 2: + + # External Calibration + + # RX_PWR(uW) = RX_PWR_4 * RX_PWR_AD + + # RX_PWR_3 * RX_PWR_AD + + # RX_PWR_2 * RX_PWR_AD + + # RX_PWR_1 * RX_PWR_AD + + # RX_PWR(0) + off = self.dom_ext_calibration_constants['RX_PWR_4']['offset'] + rx_pwr_byte3 = int(eeprom_data[off], 16) + rx_pwr_byte2 = int(eeprom_data[off + 1], 16) + rx_pwr_byte1 = int(eeprom_data[off + 2], 16) + rx_pwr_byte0 = int(eeprom_data[off + 3], 16) + rx_pwr_4 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) + + + off = self.dom_ext_calibration_constants['RX_PWR_3']['offset'] + rx_pwr_byte3 = int(eeprom_data[off], 16) + rx_pwr_byte2 = int(eeprom_data[off + 1], 16) + rx_pwr_byte1 = int(eeprom_data[off + 2], 16) + rx_pwr_byte0 = int(eeprom_data[off + 3], 16) + rx_pwr_3 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) + + off = self.dom_ext_calibration_constants['RX_PWR_2']['offset'] + rx_pwr_byte3 = int(eeprom_data[off], 16) + rx_pwr_byte2 = int(eeprom_data[off + 1], 16) + rx_pwr_byte1 = int(eeprom_data[off + 2], 16) + rx_pwr_byte0 = int(eeprom_data[off + 3], 16) + rx_pwr_2 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) + + off = self.dom_ext_calibration_constants['RX_PWR_1']['offset'] + rx_pwr_byte3 = int(eeprom_data[off], 16) + rx_pwr_byte2 = int(eeprom_data[off + 1], 16) + rx_pwr_byte1 = int(eeprom_data[off + 2], 16) + rx_pwr_byte0 = int(eeprom_data[off + 3], 16) + rx_pwr_1 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) + + off = self.dom_ext_calibration_constants['RX_PWR_0']['offset'] + rx_pwr_byte3 = int(eeprom_data[off], 16) + rx_pwr_byte2 = int(eeprom_data[off + 1], 16) + rx_pwr_byte1 = int(eeprom_data[off + 2], 16) + rx_pwr_byte0 = int(eeprom_data[off + 3], 16) + rx_pwr_0 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) + + rx_pwr = (rx_pwr_4 * result) + (rx_pwr_3 * result) + (rx_pwr_2 * result) + (rx_pwr_1 * result) + rx_pwr_0 + + result = float(result * 0.0001) + else: + retval = 'Unknown' + except Exception as err: + retval = str(err) + + return retval + + + 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':16, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccLowAlarm': + {'offset':18, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccHighWarning': + {'offset':20, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccLowWarning': + {'offset':22, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}} + + + dom_channel_threshold_values = { + 'RxPowerHighAlarm': + {'offset':0, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerLowAlarm': + {'offset':2, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerHighWarning': + {'offset':4, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerLowWarning': + {'offset':6, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'TxBiasHighAlarm': + {'offset':8, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasLowAlarm': + {'offset':10, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasHighWarning': + {'offset':12, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasLowWarning': + {'offset':14, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}} + + dom_channel_monitor_masks = { + 'Rx1PowerHighAlarm': + {'offset':0, + 'bit': 7, + 'type': 'bitvalue'}, + 'Rx1PowerLowAlarm': + {'offset':0, + 'bit': 6, + 'type': 'bitvalue'}, + 'Rx1PowerHighWarning': + {'offset':0, + 'bit': 5, + 'type': 'bitvalue'}, + 'Rx1PowerLowWarning': + {'offset':0, + 'bit': 4, + 'type': 'bitvalue'}, + 'Rx2PowerHighAlarm': + {'offset':0, + 'bit': 3, + 'type': 'bitvalue'}, + 'Rx2PowerLowAlarm': + {'offset':0, + 'bit': 2, + 'type': 'bitvalue'}, + 'Rx2PowerHighWarning': + {'offset':0, + 'bit': 1, + 'type': 'bitvalue'}, + 'Rx2PowerLowWarning': + {'offset':0, + 'bit': 0, + 'type': 'bitvalue'}, + 'Rx3PowerHighAlarm': + {'offset':1, + 'bit': 7, + 'type': 'bitvalue'}, + 'Rx3PowerLowAlarm': + {'offset':1, + 'bit': 6, + 'type': 'bitvalue'}, + 'Rx3PowerHighWarning': + {'offset':1, + 'bit': 5, + 'type': 'bitvalue'}, + 'Rx3PowerLowWarning': + {'offset':1, + 'bit': 4, + 'type': 'bitvalue'}, + 'Rx4PowerHighAlarm': + {'offset':1, + 'bit': 3, + 'type': 'bitvalue'}, + 'Rx4PowerLowAlarm': + {'offset':1, + 'bit': 2, + 'type': 'bitvalue'}, + 'Rx4PowerHighWarning': + {'offset':1, + 'bit': 1, + 'type': 'bitvalue'}, + 'Rx4PowerLowWarning': + {'offset':1, + 'bit': 0, + 'type': 'bitvalue'}, + 'Tx1BiasHighAlarm': + {'offset':2, + 'bit': 7, + 'type': 'bitvalue'}, + 'Tx1BiasLowAlarm': + {'offset':2, + 'bit': 6, + 'type': 'bitvalue'}, + 'Tx1BiasHighWarning': + {'offset':2, + 'bit': 5, + 'type': 'bitvalue'}, + 'Tx1BiasLowWarning': + {'offset':2, + 'bit': 4, + 'type': 'bitvalue'}, + 'Tx2BiasHighAlarm': + {'offset':2, + 'bit': 3, + 'type': 'bitvalue'}, + 'Tx2BiasLowAlarm': + {'offset':2, + 'bit': 2, + 'type': 'bitvalue'}, + 'Tx2BiasHighWarning': + {'offset':2, + 'bit': 1, + 'type': 'bitvalue'}, + 'Tx2BiasLowWarning': + {'offset':2, + 'bit': 0, + 'type': 'bitvalue'}, + 'Tx3BiasHighAlarm': + {'offset':3, + 'bit': 7, + 'type': 'bitvalue'}, + 'Tx3BiasLowAlarm': + {'offset':3, + 'bit': 6, + 'type': 'bitvalue'}, + 'Tx3BiasHighWarning': + {'offset': 3, + 'bit': 5, + 'type': 'bitvalue'}, + 'Tx3BiasLowWarning': + {'offset': 3, + 'bit': 4, + 'type': 'bitvalue'}, + 'Tx4BiasHighAlarm': + {'offset': 3, + 'bit': 3, + 'type': 'bitvalue'}, + 'Tx4BiasLowAlarm': + {'offset': 3, + 'bit': 2, + 'type': 'bitvalue'}, + 'Tx4BiasHighWarning': + {'offset': 3, + 'bit': 1, + 'type': 'bitvalue'}, + 'Tx4BiasLowWarning': + {'offset': 3, + 'bit': 0, + 'type': 'bitvalue'}} + + dom_threshold_map = { + 'ChannelThresholdValues': + {'offset': 11, + 'size': 2, + 'type': 'nested', + 'decode': dom_channel_threshold_values}, + 'ChannelMonitorMasks': + {'offset': 12, + 'size': 2, + 'type': 'nested', + 'decode': dom_channel_monitor_masks}, + 'ModuleThresholdValues': + {'offset': 13, + 'size': 2, + 'type': 'nested', + 'decode': dom_module_threshold_values}} + + def __init__(self, eeprom_raw_data=None, calibration_type=1): + self._calibration_type = calibration_type + start_pos = 0 + + if eeprom_raw_data != None: + self.dom_threshold_data = sffbase.parse(self, + self.dom_threshold_map, eeprom_raw_data, start_pos) + + def parse(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_threshold_map, eeprom_raw_data, + start_pos) + + # Parser functions for specific values interested by SNMP + 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_channel_threshold_values(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_channel_threshold_values, eeprom_raw_data, + start_pos) + + def parse_channel_monitor_mask(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_channel_monitor_masks, eeprom_raw_data, + start_pos) + + + def dump_pretty(self): + if self.dom_threshold_data == None: + print ('Object not initialized, nothing to print') + return + sffbase.dump_pretty(self, self.dom_threshold_data) + + def get_data(self): + return self.dom_threshold_data + + def get_data_pretty(self): + return sffbase.get_data_pretty(self, self.dom_threshold_data) diff --git a/sonic_sfp/sfputilbase.py b/sonic_sfp/sfputilbase.py index 772c9c725..45bad4f07 100644 --- a/sonic_sfp/sfputilbase.py +++ b/sonic_sfp/sfputilbase.py @@ -16,6 +16,7 @@ from .sff8472 import sff8472Dom # Dot module supports both Python 2 and Python 3 using explicit relative import methods from .sff8436 import sff8436InterfaceId # Dot module supports both Python 2 and Python 3 using explicit relative import methods from .sff8436 import sff8436Dom # Dot module supports both Python 2 and Python 3 using explicit relative import methods + from .sff8436 import sff8436DomThreshold # Dot module supports both Python 2 and Python 3 using explicit relative import methods from .inf8628 import inf8628InterfaceId # Dot module supports both Python 2 and Python 3 using explicit relative import methods except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -70,11 +71,17 @@ QSFP_DOM_REV_WIDTH = 1 QSFP_TEMPE_OFFSET = 22 QSFP_TEMPE_WIDTH = 2 -QSFP_VLOT_OFFSET = 26 +QSFP_VOLT_OFFSET = 26 QSFP_VOLT_WIDTH = 2 QSFP_CHANNL_MON_OFFSET = 34 QSFP_CHANNL_MON_WIDTH = 16 QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 SFP_TEMPE_OFFSET = 96 SFP_TEMPE_WIDTH = 2 @@ -889,6 +896,22 @@ def get_transceiver_info_dict(self, port_num): def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = {} + dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + 'temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_info_dict.fromkeys(dom_info_dict_keys, 'N/A') + if port_num in self.osfp_ports: # Below part is added to avoid fail xcvrd, shall be implemented later transceiver_dom_info_dict['temperature'] = 'N/A' @@ -923,6 +946,10 @@ def get_transceiver_dom_info_dict(self, port_num): if sfpd_obj is None: return None + sfpdth_obj = sff8436DomThreshold() + if sfpdth_obj is None: + return None + sfpi_obj = sff8436InterfaceId() if sfpi_obj is None: return None @@ -943,7 +970,7 @@ def get_transceiver_dom_info_dict(self, port_num): else: return None - dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VLOT_OFFSET), QSFP_VOLT_WIDTH) + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) if dom_voltage_raw is not None: dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) else: @@ -958,6 +985,29 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpdth_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return None + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpdth_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return None + + offset = 0 + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 # and claimed that it support tx_power with one indicator bit. dom_channel_monitor_data = {} @@ -1003,6 +1053,24 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + # Threshold Data + transceiver_dom_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + else: offset = 256 file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) From aed01273db30e9c2475bb5a85e27911cb6dd0c1a Mon Sep 17 00:00:00 2001 From: Sridhar Ravindran Date: Sat, 15 Jun 2019 11:12:34 -0700 Subject: [PATCH 2/5] Addressing Review comments for sonic_sfp: Support for DOM Threshold --- sonic_sfp/sff8436.py | 699 +++++++++++++-------------------------- sonic_sfp/sff8472.py | 4 + sonic_sfp/sfputilbase.py | 44 ++- 3 files changed, 282 insertions(+), 465 deletions(-) diff --git a/sonic_sfp/sff8436.py b/sonic_sfp/sff8436.py index 96c2e68c3..80cc429e9 100644 --- a/sonic_sfp/sff8436.py +++ b/sonic_sfp/sff8436.py @@ -1186,6 +1186,237 @@ def calc_rx_power(self, eeprom_data, offset, size): 'decode': {'func': calc_tx_power}} } + 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':16, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccLowAlarm': + {'offset':18, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccHighWarning': + {'offset':20, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccLowWarning': + {'offset':22, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}} + + dom_channel_threshold_values = { + 'RxPowerHighAlarm': + {'offset':0, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerLowAlarm': + {'offset':2, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerHighWarning': + {'offset':4, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerLowWarning': + {'offset':6, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'TxBiasHighAlarm': + {'offset':8, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasLowAlarm': + {'offset':10, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasHighWarning': + {'offset':12, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasLowWarning': + {'offset':14, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}} + + dom_channel_monitor_masks = { + 'Rx1PowerHighAlarm': + {'offset':0, + 'bit': 7, + 'type': 'bitvalue'}, + 'Rx1PowerLowAlarm': + {'offset':0, + 'bit': 6, + 'type': 'bitvalue'}, + 'Rx1PowerHighWarning': + {'offset':0, + 'bit': 5, + 'type': 'bitvalue'}, + 'Rx1PowerLowWarning': + {'offset':0, + 'bit': 4, + 'type': 'bitvalue'}, + 'Rx2PowerHighAlarm': + {'offset':0, + 'bit': 3, + 'type': 'bitvalue'}, + 'Rx2PowerLowAlarm': + {'offset':0, + 'bit': 2, + 'type': 'bitvalue'}, + 'Rx2PowerHighWarning': + {'offset':0, + 'bit': 1, + 'type': 'bitvalue'}, + 'Rx2PowerLowWarning': + {'offset':0, + 'bit': 0, + 'type': 'bitvalue'}, + 'Rx3PowerHighAlarm': + {'offset':1, + 'bit': 7, + 'type': 'bitvalue'}, + 'Rx3PowerLowAlarm': + {'offset':1, + 'bit': 6, + 'type': 'bitvalue'}, + 'Rx3PowerHighWarning': + {'offset':1, + 'bit': 5, + 'type': 'bitvalue'}, + 'Rx3PowerLowWarning': + {'offset':1, + 'bit': 4, + 'type': 'bitvalue'}, + 'Rx4PowerHighAlarm': + {'offset':1, + 'bit': 3, + 'type': 'bitvalue'}, + 'Rx4PowerLowAlarm': + {'offset':1, + 'bit': 2, + 'type': 'bitvalue'}, + 'Rx4PowerHighWarning': + {'offset':1, + 'bit': 1, + 'type': 'bitvalue'}, + 'Rx4PowerLowWarning': + {'offset':1, + 'bit': 0, + 'type': 'bitvalue'}, + 'Tx1BiasHighAlarm': + {'offset':2, + 'bit': 7, + 'type': 'bitvalue'}, + 'Tx1BiasLowAlarm': + {'offset':2, + 'bit': 6, + 'type': 'bitvalue'}, + 'Tx1BiasHighWarning': + {'offset':2, + 'bit': 5, + 'type': 'bitvalue'}, + 'Tx1BiasLowWarning': + {'offset':2, + 'bit': 4, + 'type': 'bitvalue'}, + 'Tx2BiasHighAlarm': + {'offset':2, + 'bit': 3, + 'type': 'bitvalue'}, + 'Tx2BiasLowAlarm': + {'offset':2, + 'bit': 2, + 'type': 'bitvalue'}, + 'Tx2BiasHighWarning': + {'offset':2, + 'bit': 1, + 'type': 'bitvalue'}, + 'Tx2BiasLowWarning': + {'offset':2, + 'bit': 0, + 'type': 'bitvalue'}, + 'Tx3BiasHighAlarm': + {'offset':3, + 'bit': 7, + 'type': 'bitvalue'}, + 'Tx3BiasLowAlarm': + {'offset':3, + 'bit': 6, + 'type': 'bitvalue'}, + 'Tx3BiasHighWarning': + {'offset': 3, + 'bit': 5, + 'type': 'bitvalue'}, + 'Tx3BiasLowWarning': + {'offset': 3, + 'bit': 4, + 'type': 'bitvalue'}, + 'Tx4BiasHighAlarm': + {'offset': 3, + 'bit': 3, + 'type': 'bitvalue'}, + 'Tx4BiasLowAlarm': + {'offset': 3, + 'bit': 2, + 'type': 'bitvalue'}, + 'Tx4BiasHighWarning': + {'offset': 3, + 'bit': 1, + 'type': 'bitvalue'}, + 'Tx4BiasLowWarning': + {'offset': 3, + 'bit': 0, + 'type': 'bitvalue'}} + + dom_threshold_map = { + 'ChannelThresholdValues': + {'offset': 11, + 'size': 2, + 'type': 'nested', + 'decode': dom_channel_threshold_values}, + 'ChannelMonitorMasks': + {'offset': 12, + 'size': 2, + 'type': 'nested', + 'decode': dom_channel_monitor_masks}, + 'ModuleThresholdValues': + {'offset': 13, + 'size': 2, + 'type': 'nested', + 'decode': dom_module_threshold_values}} + def __init__(self, eeprom_raw_data=None, calibration_type=1): self._calibration_type = calibration_type start_pos = 0 @@ -1218,462 +1449,6 @@ def parse_channel_monitor_params_with_tx_power(self, eeprom_raw_data, start_pos) return sffbase.parse(self, self.dom_channel_monitor_params_with_tx_power, eeprom_raw_data, start_pos) - def dump_pretty(self): - if self.dom_data == None: - print('Object not initialized, nothing to print') - return - sffbase.dump_pretty(self, self.dom_data) - - def get_data(self): - return self.dom_data - - def get_data_pretty(self): - return sffbase.get_data_pretty(self, self.dom_data) - -class sff8436DomThreshold(sffbase): - - version = '1.0' - - def get_calibration_type(self): - return self._calibration_type - - def calc_temperature(self, eeprom_data, offset, size): - try: - cal_type = self.get_calibration_type() - - msb = int(eeprom_data[offset], 16) - lsb = int(eeprom_data[offset + 1], 16) - - result = (msb << 8) | (lsb & 0xff) - result = self.twos_comp(result, 16) - - if cal_type == 1: - - # Internal calibration - - result = float(result / 256.0) - retval = '%.4f' %result + 'C' - elif cal_type == 2: - - # External calibration - - # T(C) = T_Slope * T_AD + T_Offset - off = self.dom_ext_calibration_constants['T_Slope']['offset'] - msb_t = int(eeprom_data[off], 16) - lsb_t = int(eeprom_data[off + 1], 16) - t_slope = (msb_t << 8) | (lsb_t & 0xff) - - off = self.dom_ext_calibration_constants['T_Offset']['offset'] - msb_t = int(eeprom_data[off], 16) - lsb_t = int(eeprom_data[off + 1], 16) - t_offset = (msb_t << 8) | (lsb_t & 0xff) - t_offset = self.twos_comp(t_offset, 16) - - result = t_slope * result + t_offset - result = float(result / 256.0) - retval = '%.4f' %result + 'C' - else: - retval = 'Unknown' - except Exception as err: - retval = str(err) - - return retval - - def calc_voltage(self, eeprom_data, offset, size): - try: - cal_type = self.get_calibration_type() - - msb = int(eeprom_data[offset], 16) - lsb = int(eeprom_data[offset + 1], 16) - result = (msb << 8) | (lsb & 0xff) - - if cal_type == 1: - - # Internal Calibration - - result = float(result * 0.0001) - retval = '%.4f' %result + 'Volts' - elif cal_type == 2: - - # External Calibration - - # V(uV) = V_Slope * VAD + V_Offset - off = self.dom_ext_calibration_constants['V_Slope']['offset'] - msb_v = int(eeprom_data[off], 16) - lsb_v = int(eeprom_data[off + 1], 16) - v_slope = (msb_v << 8) | (lsb_v & 0xff) - - off = self.dom_ext_calibration_constants['V_Offset']['offset'] - msb_v = int(eeprom_data[off], 16) - lsb_v = int(eeprom_data[off + 1], 16) - v_offset = (msb_v << 8) | (lsb_v & 0xff) - v_offset = self.twos_comp(v_offset, 16) - - result = v_slope * result + v_offset - result = float(result * 0.0001) - retval = '%.4f' %result + 'Volts' - else: - retval = 'Unknown' - except Exception as err: - retval = str(err) - - return retval - - - def calc_bias(self, eeprom_data, offset, size): - try: - cal_type = self.get_calibration_type() - - msb = int(eeprom_data[offset], 16) - lsb = int(eeprom_data[offset + 1], 16) - result = (msb << 8) | (lsb & 0xff) - - if cal_type == 1: - # Internal Calibration - - result = float(result * 0.002) - retval = '%.4f' %result + 'mA' - - elif cal_type == 2: - # External Calibration - - # I(uA) = I_Slope * I_AD + I_Offset - off = self.dom_ext_calibration_constants['I_Slope']['offset'] - msb_i = int(eeprom_data[off], 16) - lsb_i = int(eeprom_data[off + 1], 16) - i_slope = (msb_i << 8) | (lsb_i & 0xff) - - off = self.dom_ext_calibration_constants['I_Offset']['offset'] - msb_i = int(eeprom_data[off], 16) - lsb_i = int(eeprom_data[off + 1], 16) - i_offset = (msb_i << 8) | (lsb_i & 0xff) - i_offset = self.twos_comp(i_offset, 16) - - result = i_slope * result + i_offset - result = float(result * 0.002) - retval = '%.4f' %result + 'mA' - else: - retval = 'Unknown' - except Exception as err: - retval = str(err) - - return retval - - def calc_rx_power(self, eeprom_data, offset, size): - try: - cal_type = self.get_calibration_type() - - msb = int(eeprom_data[offset], 16) - lsb = int(eeprom_data[offset + 1], 16) - result = (msb << 8) | (lsb & 0xff) - - if cal_type == 1: - - # Internal Calibration - result = float(result * 0.0001) - retval = self.power_in_dbm_str(result) - - elif cal_type == 2: - - # External Calibration - - # RX_PWR(uW) = RX_PWR_4 * RX_PWR_AD + - # RX_PWR_3 * RX_PWR_AD + - # RX_PWR_2 * RX_PWR_AD + - # RX_PWR_1 * RX_PWR_AD + - # RX_PWR(0) - off = self.dom_ext_calibration_constants['RX_PWR_4']['offset'] - rx_pwr_byte3 = int(eeprom_data[off], 16) - rx_pwr_byte2 = int(eeprom_data[off + 1], 16) - rx_pwr_byte1 = int(eeprom_data[off + 2], 16) - rx_pwr_byte0 = int(eeprom_data[off + 3], 16) - rx_pwr_4 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) - - - off = self.dom_ext_calibration_constants['RX_PWR_3']['offset'] - rx_pwr_byte3 = int(eeprom_data[off], 16) - rx_pwr_byte2 = int(eeprom_data[off + 1], 16) - rx_pwr_byte1 = int(eeprom_data[off + 2], 16) - rx_pwr_byte0 = int(eeprom_data[off + 3], 16) - rx_pwr_3 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) - - off = self.dom_ext_calibration_constants['RX_PWR_2']['offset'] - rx_pwr_byte3 = int(eeprom_data[off], 16) - rx_pwr_byte2 = int(eeprom_data[off + 1], 16) - rx_pwr_byte1 = int(eeprom_data[off + 2], 16) - rx_pwr_byte0 = int(eeprom_data[off + 3], 16) - rx_pwr_2 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) - - off = self.dom_ext_calibration_constants['RX_PWR_1']['offset'] - rx_pwr_byte3 = int(eeprom_data[off], 16) - rx_pwr_byte2 = int(eeprom_data[off + 1], 16) - rx_pwr_byte1 = int(eeprom_data[off + 2], 16) - rx_pwr_byte0 = int(eeprom_data[off + 3], 16) - rx_pwr_1 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) - - off = self.dom_ext_calibration_constants['RX_PWR_0']['offset'] - rx_pwr_byte3 = int(eeprom_data[off], 16) - rx_pwr_byte2 = int(eeprom_data[off + 1], 16) - rx_pwr_byte1 = int(eeprom_data[off + 2], 16) - rx_pwr_byte0 = int(eeprom_data[off + 3], 16) - rx_pwr_0 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff) - - rx_pwr = (rx_pwr_4 * result) + (rx_pwr_3 * result) + (rx_pwr_2 * result) + (rx_pwr_1 * result) + rx_pwr_0 - - result = float(result * 0.0001) - else: - retval = 'Unknown' - except Exception as err: - retval = str(err) - - return retval - - - 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':16, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_voltage}}, - 'VccLowAlarm': - {'offset':18, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_voltage}}, - 'VccHighWarning': - {'offset':20, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_voltage}}, - 'VccLowWarning': - {'offset':22, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_voltage}}} - - - dom_channel_threshold_values = { - 'RxPowerHighAlarm': - {'offset':0, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_rx_power}}, - 'RxPowerLowAlarm': - {'offset':2, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_rx_power}}, - 'RxPowerHighWarning': - {'offset':4, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_rx_power}}, - 'RxPowerLowWarning': - {'offset':6, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_rx_power}}, - 'TxBiasHighAlarm': - {'offset':8, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_bias}}, - 'TxBiasLowAlarm': - {'offset':10, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_bias}}, - 'TxBiasHighWarning': - {'offset':12, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_bias}}, - 'TxBiasLowWarning': - {'offset':14, - 'size':2, - 'type': 'func', - 'decode': { 'func':calc_bias}}} - - dom_channel_monitor_masks = { - 'Rx1PowerHighAlarm': - {'offset':0, - 'bit': 7, - 'type': 'bitvalue'}, - 'Rx1PowerLowAlarm': - {'offset':0, - 'bit': 6, - 'type': 'bitvalue'}, - 'Rx1PowerHighWarning': - {'offset':0, - 'bit': 5, - 'type': 'bitvalue'}, - 'Rx1PowerLowWarning': - {'offset':0, - 'bit': 4, - 'type': 'bitvalue'}, - 'Rx2PowerHighAlarm': - {'offset':0, - 'bit': 3, - 'type': 'bitvalue'}, - 'Rx2PowerLowAlarm': - {'offset':0, - 'bit': 2, - 'type': 'bitvalue'}, - 'Rx2PowerHighWarning': - {'offset':0, - 'bit': 1, - 'type': 'bitvalue'}, - 'Rx2PowerLowWarning': - {'offset':0, - 'bit': 0, - 'type': 'bitvalue'}, - 'Rx3PowerHighAlarm': - {'offset':1, - 'bit': 7, - 'type': 'bitvalue'}, - 'Rx3PowerLowAlarm': - {'offset':1, - 'bit': 6, - 'type': 'bitvalue'}, - 'Rx3PowerHighWarning': - {'offset':1, - 'bit': 5, - 'type': 'bitvalue'}, - 'Rx3PowerLowWarning': - {'offset':1, - 'bit': 4, - 'type': 'bitvalue'}, - 'Rx4PowerHighAlarm': - {'offset':1, - 'bit': 3, - 'type': 'bitvalue'}, - 'Rx4PowerLowAlarm': - {'offset':1, - 'bit': 2, - 'type': 'bitvalue'}, - 'Rx4PowerHighWarning': - {'offset':1, - 'bit': 1, - 'type': 'bitvalue'}, - 'Rx4PowerLowWarning': - {'offset':1, - 'bit': 0, - 'type': 'bitvalue'}, - 'Tx1BiasHighAlarm': - {'offset':2, - 'bit': 7, - 'type': 'bitvalue'}, - 'Tx1BiasLowAlarm': - {'offset':2, - 'bit': 6, - 'type': 'bitvalue'}, - 'Tx1BiasHighWarning': - {'offset':2, - 'bit': 5, - 'type': 'bitvalue'}, - 'Tx1BiasLowWarning': - {'offset':2, - 'bit': 4, - 'type': 'bitvalue'}, - 'Tx2BiasHighAlarm': - {'offset':2, - 'bit': 3, - 'type': 'bitvalue'}, - 'Tx2BiasLowAlarm': - {'offset':2, - 'bit': 2, - 'type': 'bitvalue'}, - 'Tx2BiasHighWarning': - {'offset':2, - 'bit': 1, - 'type': 'bitvalue'}, - 'Tx2BiasLowWarning': - {'offset':2, - 'bit': 0, - 'type': 'bitvalue'}, - 'Tx3BiasHighAlarm': - {'offset':3, - 'bit': 7, - 'type': 'bitvalue'}, - 'Tx3BiasLowAlarm': - {'offset':3, - 'bit': 6, - 'type': 'bitvalue'}, - 'Tx3BiasHighWarning': - {'offset': 3, - 'bit': 5, - 'type': 'bitvalue'}, - 'Tx3BiasLowWarning': - {'offset': 3, - 'bit': 4, - 'type': 'bitvalue'}, - 'Tx4BiasHighAlarm': - {'offset': 3, - 'bit': 3, - 'type': 'bitvalue'}, - 'Tx4BiasLowAlarm': - {'offset': 3, - 'bit': 2, - 'type': 'bitvalue'}, - 'Tx4BiasHighWarning': - {'offset': 3, - 'bit': 1, - 'type': 'bitvalue'}, - 'Tx4BiasLowWarning': - {'offset': 3, - 'bit': 0, - 'type': 'bitvalue'}} - - dom_threshold_map = { - 'ChannelThresholdValues': - {'offset': 11, - 'size': 2, - 'type': 'nested', - 'decode': dom_channel_threshold_values}, - 'ChannelMonitorMasks': - {'offset': 12, - 'size': 2, - 'type': 'nested', - 'decode': dom_channel_monitor_masks}, - 'ModuleThresholdValues': - {'offset': 13, - 'size': 2, - 'type': 'nested', - 'decode': dom_module_threshold_values}} - - def __init__(self, eeprom_raw_data=None, calibration_type=1): - self._calibration_type = calibration_type - start_pos = 0 - - if eeprom_raw_data != None: - self.dom_threshold_data = sffbase.parse(self, - self.dom_threshold_map, eeprom_raw_data, start_pos) - - def parse(self, eeprom_raw_data, start_pos): - return sffbase.parse(self, self.dom_threshold_map, eeprom_raw_data, - start_pos) - - # Parser functions for specific values interested by SNMP 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) @@ -1686,15 +1461,15 @@ def parse_channel_monitor_mask(self, eeprom_raw_data, start_pos): return sffbase.parse(self, self.dom_channel_monitor_masks, eeprom_raw_data, start_pos) - def dump_pretty(self): - if self.dom_threshold_data == None: - print ('Object not initialized, nothing to print') + if self.dom_data == None: + print('Object not initialized, nothing to print') return - sffbase.dump_pretty(self, self.dom_threshold_data) + sffbase.dump_pretty(self, self.dom_data) def get_data(self): - return self.dom_threshold_data + return self.dom_data def get_data_pretty(self): - return sffbase.get_data_pretty(self, self.dom_threshold_data) + return sffbase.get_data_pretty(self, self.dom_data) + diff --git a/sonic_sfp/sff8472.py b/sonic_sfp/sff8472.py index ba0c6d081..f2741e9f5 100644 --- a/sonic_sfp/sff8472.py +++ b/sonic_sfp/sff8472.py @@ -1194,6 +1194,10 @@ 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_alarm_warning_threshold(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_aw_thresholds, eeprom_raw_data, + start_pos) + def dump_pretty(self): if self.dom_data == None: print('Object not initialized, nothing to print') diff --git a/sonic_sfp/sfputilbase.py b/sonic_sfp/sfputilbase.py index 45bad4f07..5bb883392 100644 --- a/sonic_sfp/sfputilbase.py +++ b/sonic_sfp/sfputilbase.py @@ -85,7 +85,7 @@ SFP_TEMPE_OFFSET = 96 SFP_TEMPE_WIDTH = 2 -SFP_VLOT_OFFSET = 98 +SFP_VOLT_OFFSET = 98 SFP_VOLT_WIDTH = 2 SFP_CHANNL_MON_OFFSET = 100 SFP_CHANNL_MON_WIDTH = 6 @@ -910,7 +910,7 @@ def get_transceiver_dom_info_dict(self, port_num): 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning' ] - transceiver_dom_info_dict.fromkeys(dom_info_dict_keys, 'N/A') + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') if port_num in self.osfp_ports: # Below part is added to avoid fail xcvrd, shall be implemented later @@ -1093,7 +1093,7 @@ def get_transceiver_dom_info_dict(self, port_num): else: return None - dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) if dom_voltage_raw is not None: dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) else: @@ -1105,6 +1105,22 @@ def get_transceiver_dom_info_dict(self, port_num): else: return None + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_monitor_params(dom_module_threshold_raw, 0) + else: + return None + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_CHANNL_THRESHOLD_OFFSET), + SFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_monitor_params(dom_channel_threshold_raw, 0) + else: + return None + try: sysfsfile_eeprom.close() except IOError: @@ -1126,6 +1142,28 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx3power'] = 'N/A' transceiver_dom_info_dict['tx4power'] = 'N/A' + # Threshold Data + transceiver_dom_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + transceiver_dom_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + return transceiver_dom_info_dict @abc.abstractmethod From 174bdfb30b5d59db79733e4124507b5847e98435 Mon Sep 17 00:00:00 2001 From: Sridhar Ravindran Date: Tue, 25 Jun 2019 09:04:33 -0700 Subject: [PATCH 3/5] Addressing Review Comments for DOM Threshold --- sonic_sfp/sfputilbase.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sonic_sfp/sfputilbase.py b/sonic_sfp/sfputilbase.py index 15b11db3a..b27fe5bf7 100644 --- a/sonic_sfp/sfputilbase.py +++ b/sonic_sfp/sfputilbase.py @@ -16,7 +16,6 @@ from .sff8472 import sff8472Dom # Dot module supports both Python 2 and Python 3 using explicit relative import methods from .sff8436 import sff8436InterfaceId # Dot module supports both Python 2 and Python 3 using explicit relative import methods from .sff8436 import sff8436Dom # Dot module supports both Python 2 and Python 3 using explicit relative import methods - from .sff8436 import sff8436DomThreshold # Dot module supports both Python 2 and Python 3 using explicit relative import methods from .inf8628 import inf8628InterfaceId # Dot module supports both Python 2 and Python 3 using explicit relative import methods except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -909,6 +908,8 @@ def get_transceiver_dom_info_dict(self, port_num): 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning' ] @@ -948,10 +949,6 @@ def get_transceiver_dom_info_dict(self, port_num): if sfpd_obj is None: return None - sfpdth_obj = sff8436DomThreshold() - if sfpdth_obj is None: - return None - sfpi_obj = sff8436InterfaceId() if sfpi_obj is None: return None @@ -995,7 +992,7 @@ def get_transceiver_dom_info_dict(self, port_num): (offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) if dom_module_threshold_raw is not None: - dom_module_threshold_data = sfpdth_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) else: return None @@ -1004,7 +1001,7 @@ def get_transceiver_dom_info_dict(self, port_num): (offset + QSFP_CHANNL_THRESHOLD_OFFSET), QSFP_CHANNL_THRESHOLD_WIDTH) if dom_channel_threshold_raw is not None: - dom_channel_threshold_data = sfpdth_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) else: return None From 94ee68551ae820872ddc596a26e1c3ac2d309af1 Mon Sep 17 00:00:00 2001 From: Sridhar Ravindran Date: Wed, 26 Jun 2019 03:24:29 -0700 Subject: [PATCH 4/5] DeCoupling Dom Values from DomThreshold --- sonic_sfp/sfputilbase.py | 225 ++++++++++++++++++++++++--------------- 1 file changed, 137 insertions(+), 88 deletions(-) diff --git a/sonic_sfp/sfputilbase.py b/sonic_sfp/sfputilbase.py index b27fe5bf7..40aca8ea2 100644 --- a/sonic_sfp/sfputilbase.py +++ b/sonic_sfp/sfputilbase.py @@ -902,16 +902,6 @@ def get_transceiver_dom_info_dict(self, port_num): 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power', - 'temphighalarm', 'temphighwarning', - 'templowalarm', 'templowwarning', - 'vcchighalarm', 'vcchighwarning', - 'vcclowalarm', 'vcclowwarning', - 'rxpowerhighalarm', 'rxpowerhighwarning', - 'rxpowerlowalarm', 'rxpowerlowwarning', - 'txpowerhighalarm', 'txpowerhighwarning', - 'txpowerlowalarm', 'txpowerlowwarning', - 'txbiashighalarm', 'txbiashighwarning', - 'txbiaslowalarm', 'txbiaslowwarning' ] transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') @@ -984,29 +974,6 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] - # Dom Threshold data starts from offset 384 - # Revert offset back to 0 once data is retrieved - offset = 384 - dom_module_threshold_raw = self._read_eeprom_specific_bytes( - sysfsfile_eeprom, - (offset + QSFP_MODULE_THRESHOLD_OFFSET), - QSFP_MODULE_THRESHOLD_WIDTH) - if dom_module_threshold_raw is not None: - dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) - else: - return None - - dom_channel_threshold_raw = self._read_eeprom_specific_bytes( - sysfsfile_eeprom, - (offset + QSFP_CHANNL_THRESHOLD_OFFSET), - QSFP_CHANNL_THRESHOLD_WIDTH) - if dom_channel_threshold_raw is not None: - dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) - else: - return None - - offset = 0 - # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 # and claimed that it support tx_power with one indicator bit. dom_channel_monitor_data = {} @@ -1052,24 +1019,6 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] - # Threshold Data - transceiver_dom_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] - transceiver_dom_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] - transceiver_dom_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] - transceiver_dom_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] - transceiver_dom_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] - transceiver_dom_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] - transceiver_dom_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] - transceiver_dom_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] - transceiver_dom_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] - transceiver_dom_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] - transceiver_dom_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] - transceiver_dom_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] - transceiver_dom_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] - transceiver_dom_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] - transceiver_dom_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] - transceiver_dom_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] - else: offset = 256 file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) @@ -1104,22 +1053,6 @@ def get_transceiver_dom_info_dict(self, port_num): else: return None - dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, - (offset + SFP_MODULE_THRESHOLD_OFFSET), - SFP_MODULE_THRESHOLD_WIDTH) - if dom_module_threshold_raw is not None: - dom_module_threshold_data = sfpd_obj.parse_module_monitor_params(dom_module_threshold_raw, 0) - else: - return None - - dom_channel_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, - (offset + SFP_CHANNL_THRESHOLD_OFFSET), - SFP_CHANNL_THRESHOLD_WIDTH) - if dom_channel_threshold_raw is not None: - dom_channel_threshold_data = sfpd_obj.parse_channel_monitor_params(dom_channel_threshold_raw, 0) - else: - return None - try: sysfsfile_eeprom.close() except IOError: @@ -1141,29 +1074,145 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx3power'] = 'N/A' transceiver_dom_info_dict['tx4power'] = 'N/A' + return transceiver_dom_info_dict + + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return None + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + # Threshold Data - transceiver_dom_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] - transceiver_dom_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] - transceiver_dom_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] - transceiver_dom_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] - transceiver_dom_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] - transceiver_dom_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] - transceiver_dom_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] - transceiver_dom_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] - transceiver_dom_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['BiasHighAlarm']['value'] - transceiver_dom_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['BiasLowAlarm']['value'] - transceiver_dom_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['BiasHighWarning']['value'] - transceiver_dom_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['BiasLowWarning']['value'] - transceiver_dom_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] - transceiver_dom_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] - transceiver_dom_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] - transceiver_dom_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] - transceiver_dom_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] - transceiver_dom_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] - transceiver_dom_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] - transceiver_dom_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] - return transceiver_dom_info_dict + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_monitor_params(dom_module_threshold_raw, 0) + else: + return None + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_CHANNL_THRESHOLD_OFFSET), + SFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_monitor_params(dom_channel_threshold_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict @abc.abstractmethod def get_presence(self, port_num): From 694b0ac6666e27d770603791904e03d53acec9fc Mon Sep 17 00:00:00 2001 From: Sridhar Ravindran Date: Thu, 27 Jun 2019 09:06:24 -0700 Subject: [PATCH 5/5] Addressing Review Comments, Porting sonic_sfp changes into sonic_platform_base/sonic_sfp --- sonic_platform_base/sonic_sfp/sff8436.py | 244 +++++++++++++++++++ sonic_platform_base/sonic_sfp/sff8472.py | 4 + sonic_platform_base/sonic_sfp/sfputilbase.py | 160 +++++++++++- 3 files changed, 404 insertions(+), 4 deletions(-) diff --git a/sonic_platform_base/sonic_sfp/sff8436.py b/sonic_platform_base/sonic_sfp/sff8436.py index 98f6a0f12..80cc429e9 100644 --- a/sonic_platform_base/sonic_sfp/sff8436.py +++ b/sonic_platform_base/sonic_sfp/sff8436.py @@ -1186,6 +1186,237 @@ def calc_rx_power(self, eeprom_data, offset, size): 'decode': {'func': calc_tx_power}} } + 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':16, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccLowAlarm': + {'offset':18, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccHighWarning': + {'offset':20, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}, + 'VccLowWarning': + {'offset':22, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_voltage}}} + + dom_channel_threshold_values = { + 'RxPowerHighAlarm': + {'offset':0, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerLowAlarm': + {'offset':2, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerHighWarning': + {'offset':4, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'RxPowerLowWarning': + {'offset':6, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_rx_power}}, + 'TxBiasHighAlarm': + {'offset':8, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasLowAlarm': + {'offset':10, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasHighWarning': + {'offset':12, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}, + 'TxBiasLowWarning': + {'offset':14, + 'size':2, + 'type': 'func', + 'decode': { 'func':calc_bias}}} + + dom_channel_monitor_masks = { + 'Rx1PowerHighAlarm': + {'offset':0, + 'bit': 7, + 'type': 'bitvalue'}, + 'Rx1PowerLowAlarm': + {'offset':0, + 'bit': 6, + 'type': 'bitvalue'}, + 'Rx1PowerHighWarning': + {'offset':0, + 'bit': 5, + 'type': 'bitvalue'}, + 'Rx1PowerLowWarning': + {'offset':0, + 'bit': 4, + 'type': 'bitvalue'}, + 'Rx2PowerHighAlarm': + {'offset':0, + 'bit': 3, + 'type': 'bitvalue'}, + 'Rx2PowerLowAlarm': + {'offset':0, + 'bit': 2, + 'type': 'bitvalue'}, + 'Rx2PowerHighWarning': + {'offset':0, + 'bit': 1, + 'type': 'bitvalue'}, + 'Rx2PowerLowWarning': + {'offset':0, + 'bit': 0, + 'type': 'bitvalue'}, + 'Rx3PowerHighAlarm': + {'offset':1, + 'bit': 7, + 'type': 'bitvalue'}, + 'Rx3PowerLowAlarm': + {'offset':1, + 'bit': 6, + 'type': 'bitvalue'}, + 'Rx3PowerHighWarning': + {'offset':1, + 'bit': 5, + 'type': 'bitvalue'}, + 'Rx3PowerLowWarning': + {'offset':1, + 'bit': 4, + 'type': 'bitvalue'}, + 'Rx4PowerHighAlarm': + {'offset':1, + 'bit': 3, + 'type': 'bitvalue'}, + 'Rx4PowerLowAlarm': + {'offset':1, + 'bit': 2, + 'type': 'bitvalue'}, + 'Rx4PowerHighWarning': + {'offset':1, + 'bit': 1, + 'type': 'bitvalue'}, + 'Rx4PowerLowWarning': + {'offset':1, + 'bit': 0, + 'type': 'bitvalue'}, + 'Tx1BiasHighAlarm': + {'offset':2, + 'bit': 7, + 'type': 'bitvalue'}, + 'Tx1BiasLowAlarm': + {'offset':2, + 'bit': 6, + 'type': 'bitvalue'}, + 'Tx1BiasHighWarning': + {'offset':2, + 'bit': 5, + 'type': 'bitvalue'}, + 'Tx1BiasLowWarning': + {'offset':2, + 'bit': 4, + 'type': 'bitvalue'}, + 'Tx2BiasHighAlarm': + {'offset':2, + 'bit': 3, + 'type': 'bitvalue'}, + 'Tx2BiasLowAlarm': + {'offset':2, + 'bit': 2, + 'type': 'bitvalue'}, + 'Tx2BiasHighWarning': + {'offset':2, + 'bit': 1, + 'type': 'bitvalue'}, + 'Tx2BiasLowWarning': + {'offset':2, + 'bit': 0, + 'type': 'bitvalue'}, + 'Tx3BiasHighAlarm': + {'offset':3, + 'bit': 7, + 'type': 'bitvalue'}, + 'Tx3BiasLowAlarm': + {'offset':3, + 'bit': 6, + 'type': 'bitvalue'}, + 'Tx3BiasHighWarning': + {'offset': 3, + 'bit': 5, + 'type': 'bitvalue'}, + 'Tx3BiasLowWarning': + {'offset': 3, + 'bit': 4, + 'type': 'bitvalue'}, + 'Tx4BiasHighAlarm': + {'offset': 3, + 'bit': 3, + 'type': 'bitvalue'}, + 'Tx4BiasLowAlarm': + {'offset': 3, + 'bit': 2, + 'type': 'bitvalue'}, + 'Tx4BiasHighWarning': + {'offset': 3, + 'bit': 1, + 'type': 'bitvalue'}, + 'Tx4BiasLowWarning': + {'offset': 3, + 'bit': 0, + 'type': 'bitvalue'}} + + dom_threshold_map = { + 'ChannelThresholdValues': + {'offset': 11, + 'size': 2, + 'type': 'nested', + 'decode': dom_channel_threshold_values}, + 'ChannelMonitorMasks': + {'offset': 12, + 'size': 2, + 'type': 'nested', + 'decode': dom_channel_monitor_masks}, + 'ModuleThresholdValues': + {'offset': 13, + 'size': 2, + 'type': 'nested', + 'decode': dom_module_threshold_values}} + def __init__(self, eeprom_raw_data=None, calibration_type=1): self._calibration_type = calibration_type start_pos = 0 @@ -1218,6 +1449,18 @@ def parse_channel_monitor_params_with_tx_power(self, eeprom_raw_data, start_pos) return sffbase.parse(self, self.dom_channel_monitor_params_with_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_channel_threshold_values(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_channel_threshold_values, eeprom_raw_data, + start_pos) + + def parse_channel_monitor_mask(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_channel_monitor_masks, eeprom_raw_data, + start_pos) + def dump_pretty(self): if self.dom_data == None: print('Object not initialized, nothing to print') @@ -1229,3 +1472,4 @@ def get_data(self): def get_data_pretty(self): return sffbase.get_data_pretty(self, self.dom_data) + diff --git a/sonic_platform_base/sonic_sfp/sff8472.py b/sonic_platform_base/sonic_sfp/sff8472.py index ba0c6d081..f2741e9f5 100644 --- a/sonic_platform_base/sonic_sfp/sff8472.py +++ b/sonic_platform_base/sonic_sfp/sff8472.py @@ -1194,6 +1194,10 @@ 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_alarm_warning_threshold(self, eeprom_raw_data, start_pos): + return sffbase.parse(self, self.dom_aw_thresholds, eeprom_raw_data, + start_pos) + def dump_pretty(self): if self.dom_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 772c9c725..3dd6f4f68 100644 --- a/sonic_platform_base/sonic_sfp/sfputilbase.py +++ b/sonic_platform_base/sonic_sfp/sfputilbase.py @@ -70,15 +70,21 @@ QSFP_DOM_REV_WIDTH = 1 QSFP_TEMPE_OFFSET = 22 QSFP_TEMPE_WIDTH = 2 -QSFP_VLOT_OFFSET = 26 +QSFP_VOLT_OFFSET = 26 QSFP_VOLT_WIDTH = 2 QSFP_CHANNL_MON_OFFSET = 34 QSFP_CHANNL_MON_WIDTH = 16 QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 SFP_TEMPE_OFFSET = 96 SFP_TEMPE_WIDTH = 2 -SFP_VLOT_OFFSET = 98 +SFP_VOLT_OFFSET = 98 SFP_VOLT_WIDTH = 2 SFP_CHANNL_MON_OFFSET = 100 SFP_CHANNL_MON_WIDTH = 6 @@ -889,6 +895,14 @@ def get_transceiver_info_dict(self, port_num): def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = {} + dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + if port_num in self.osfp_ports: # Below part is added to avoid fail xcvrd, shall be implemented later transceiver_dom_info_dict['temperature'] = 'N/A' @@ -943,7 +957,7 @@ def get_transceiver_dom_info_dict(self, port_num): else: return None - dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VLOT_OFFSET), QSFP_VOLT_WIDTH) + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) if dom_voltage_raw is not None: dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) else: @@ -1025,7 +1039,7 @@ def get_transceiver_dom_info_dict(self, port_num): else: return None - dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) if dom_voltage_raw is not None: dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) else: @@ -1060,6 +1074,144 @@ def get_transceiver_dom_info_dict(self, port_num): return transceiver_dom_info_dict + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return None + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_monitor_params(dom_module_threshold_raw, 0) + else: + return None + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_CHANNL_THRESHOLD_OFFSET), + SFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_monitor_params(dom_channel_threshold_raw, 0) + else: + return None + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict + @abc.abstractmethod def get_presence(self, port_num): """