diff --git a/sonic_platform_base/sonic_sfp/sff8436.py b/sonic_platform_base/sonic_sfp/sff8436.py index 98f6a0f12eff..80cc429e99fb 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 ba0c6d0810ef..f2741e9f5220 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 772c9c7257ce..3dd6f4f68807 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): """ diff --git a/sonic_sfp/sff8436.py b/sonic_sfp/sff8436.py index a0c892290480..691153e9f4d8 100644 --- a/sonic_sfp/sff8436.py +++ b/sonic_sfp/sff8436.py @@ -1192,6 +1192,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 @@ -1224,6 +1455,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') @@ -1235,3 +1478,4 @@ def get_data(self): def get_data_pretty(self): return sffbase.get_data_pretty(self, self.dom_data) + diff --git a/sonic_sfp/sff8472.py b/sonic_sfp/sff8472.py index 6eeb33d6b7ef..d0d3441b3e83 100644 --- a/sonic_sfp/sff8472.py +++ b/sonic_sfp/sff8472.py @@ -1200,6 +1200,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 763fcd5b67b0..40aca8ea2d24 100644 --- a/sonic_sfp/sfputilbase.py +++ b/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 @@ -891,6 +897,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' @@ -945,7 +959,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: @@ -1027,7 +1041,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: @@ -1062,6 +1076,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): """