[Mellanox] optimize new platform api (#3289)

optimize SFP module operations and fix issues.

- split initialization of variant categories of devices and initialize each category of devices only when needed, so that unnecessary dependencies can be avoided.
- update watchdog logic, only initializing watchdog when referenced.
- support platform.py and enable to initialize variant devices on a host/docker basis
- update init so that sonic_platform can be imported as a whole.
This commit is contained in:
Stephen Sun 2019-08-29 02:59:37 +08:00 committed by lguohan
parent 4c36866a26
commit 5c2d71138b
4 changed files with 303 additions and 160 deletions

View File

@ -0,0 +1,2 @@
__all__ = ["platform", "chassis"]
from sonic_platform import *

View File

@ -10,15 +10,7 @@
try: try:
from sonic_platform_base.chassis_base import ChassisBase from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.psu import Psu
from sonic_platform.fan import Fan
from sonic_platform.fan import FAN_PATH
from sonic_platform.sfp import SFP
from sonic_platform.thermal import Thermal, initialize_thermals
from sonic_platform.watchdog import get_watchdog
from sonic_daemon_base.daemon_base import Logger from sonic_daemon_base.daemon_base import Logger
from eeprom import Eeprom
from sfp_event import sfp_event
from os import listdir from os import listdir
from os.path import isfile, join from os.path import isfile, join
import sys import sys
@ -43,11 +35,6 @@ HWMGMT_SYSTEM_ROOT = '/var/run/hw-management/system/'
#reboot cause related definitions #reboot cause related definitions
REBOOT_CAUSE_ROOT = HWMGMT_SYSTEM_ROOT REBOOT_CAUSE_ROOT = HWMGMT_SYSTEM_ROOT
REBOOT_CAUSE_POWER_LOSS_FILE = 'reset_main_pwr_fail'
REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE = 'reset_asic_thermal'
REBOOT_CAUSE_WATCHDOG_FILE = 'reset_hotswap_or_wd'
REBOOT_CAUSE_MLNX_FIRMWARE_RESET = 'reset_fw_reset'
REBOOT_CAUSE_FILE_LENGTH = 1 REBOOT_CAUSE_FILE_LENGTH = 1
#version retrieving related definitions #version retrieving related definitions
@ -84,14 +71,30 @@ class Chassis(ChassisBase):
# Initialize SKU name # Initialize SKU name
self.sku_name = self._get_sku_name() self.sku_name = self._get_sku_name()
# move the initialization of each components to their dedicated initializer
# which will be called from platform
self.sfp_module_initialized = False
self.sfp_event_initialized = False
self.reboot_cause_initialized = False
logger.log_info("Chassis loaded successfully")
def __del__(self):
if self.sfp_event_initialized:
self.sfp_event.deinitialize()
def initialize_psu(self):
from sonic_platform.psu import Psu
# Initialize PSU list # Initialize PSU list
self.psu_module = Psu
for index in range(MLNX_NUM_PSU): for index in range(MLNX_NUM_PSU):
psu = Psu(index, self.sku_name) psu = Psu(index, self.sku_name)
self._psu_list.append(psu) self._psu_list.append(psu)
# Initialize watchdog def initialize_fan(self):
self._watchdog = get_watchdog() from sonic_platform.fan import Fan
from sonic_platform.fan import FAN_PATH
self.fan_module = Fan
self.fan_path = FAN_PATH
# Initialize FAN list # Initialize FAN list
multi_rotor_in_drawer = False multi_rotor_in_drawer = False
num_of_fan, num_of_drawer = self._extract_num_of_fans_and_fan_drawers() num_of_fan, num_of_drawer = self._extract_num_of_fans_and_fan_drawers()
@ -104,6 +107,11 @@ class Chassis(ChassisBase):
fan = Fan(index, index) fan = Fan(index, index)
self._fan_list.append(fan) self._fan_list.append(fan)
def initialize_sfp(self):
from sonic_platform.sfp import SFP
self.sfp_module = SFP
# Initialize SFP list # Initialize SFP list
port_position_tuple = self._get_port_position_tuple_by_sku_name() port_position_tuple = self._get_port_position_tuple_by_sku_name()
self.PORT_START = port_position_tuple[0] self.PORT_START = port_position_tuple[0]
@ -118,31 +126,82 @@ class Chassis(ChassisBase):
sfp_module = SFP(index, 'SFP') sfp_module = SFP(index, 'SFP')
self._sfp_list.append(sfp_module) self._sfp_list.append(sfp_module)
self.sfp_module_initialized = True
def initialize_thermals(self):
from sonic_platform.thermal import initialize_thermals
# Initialize thermals # Initialize thermals
initialize_thermals(self.sku_name, self._thermal_list, self._psu_list) initialize_thermals(self.sku_name, self._thermal_list, self._psu_list)
def initialize_eeprom(self):
from eeprom import Eeprom
# Initialize EEPROM # Initialize EEPROM
self.eeprom = Eeprom() self._eeprom = Eeprom()
def initialize_components_list(self):
# Initialize component list # Initialize component list
self._component_name_list.append(COMPONENT_BIOS) self._component_name_list.append(COMPONENT_BIOS)
self._component_name_list.append(COMPONENT_FIRMWARE) self._component_name_list.append(COMPONENT_FIRMWARE)
self._component_name_list.append(COMPONENT_CPLD1) self._component_name_list.append(COMPONENT_CPLD1)
self._component_name_list.append(COMPONENT_CPLD2) self._component_name_list.append(COMPONENT_CPLD2)
# Initialize sfp-change-listening stuff ##############################################
self._init_sfp_change_event() # SFP methods
##############################################
def get_num_sfps(self):
"""
Retrieves the number of sfps available on this chassis
def _init_sfp_change_event(self): Returns:
self.sfp_event = sfp_event() An integer, the number of sfps available on this chassis
self.sfp_event.initialize() """
self.MAX_SELECT_EVENT_RETURNED = self.PORT_END if not self.sfp_module_initialized:
self.initialize_sfp()
return len(self._sfp_list)
def get_all_sfps(self):
"""
Retrieves all sfps available on this chassis
Returns:
A list of objects derived from SfpBase representing all sfps
available on this chassis
"""
if not self.sfp_module_initialized:
self.initialize_sfp()
return self._sfp_list
def get_sfp(self, index):
"""
Retrieves sfp represented by (0-based) index <index>
Args:
index: An integer, the index (0-based) of the sfp to retrieve.
The index should be the sequence of a physical port in a chassis,
starting from 0.
For example, 0 for Ethernet0, 1 for Ethernet4 and so on.
Returns:
An object dervied from SfpBase representing the specified sfp
"""
if not self.sfp_module_initialized:
self.initialize_sfp()
sfp = None
try:
sfp = self._sfp_list[index]
except IndexError:
sys.stderr.write("SFP index {} out of range (0-{})\n".format(
index, len(self._sfp_list)-1))
return sfp
def _extract_num_of_fans_and_fan_drawers(self): def _extract_num_of_fans_and_fan_drawers(self):
num_of_fan = 0 num_of_fan = 0
num_of_drawer = 0 num_of_drawer = 0
for f in listdir(FAN_PATH): for f in listdir(self.fan_path):
if isfile(join(FAN_PATH, f)): if isfile(join(self.fan_path, f)):
match_obj = re.match('fan(\d+)_speed_get', f) match_obj = re.match('fan(\d+)_speed_get', f)
if match_obj != None: if match_obj != None:
if int(match_obj.group(1)) > num_of_fan: if int(match_obj.group(1)) > num_of_fan:
@ -163,6 +222,30 @@ class Chassis(ChassisBase):
position_tuple = port_position_tuple_list[hwsku_dict_port[self.sku_name]] position_tuple = port_position_tuple_list[hwsku_dict_port[self.sku_name]]
return position_tuple return position_tuple
def get_watchdog(self):
"""
Retrieves hardware watchdog device on this chassis
Returns:
An object derived from WatchdogBase representing the hardware
watchdog device
Note:
We overload this method to ensure that watchdog is only initialized
when it is referenced. Currently, only one daemon can open the watchdog.
To initialize watchdog in the constructor causes multiple daemon
try opening watchdog when loading and constructing a chassis object
and fail. By doing so we can eliminate that risk.
"""
try:
if self._watchdog is None:
from sonic_platform.watchdog import get_watchdog
self._watchdog = get_watchdog()
except Exception as e:
logger.log_info("Fail to load watchdog due to {}".format(repr(e)))
return self._watchdog
def get_base_mac(self): def get_base_mac(self):
""" """
Retrieves the base MAC address for the chassis Retrieves the base MAC address for the chassis
@ -171,7 +254,7 @@ class Chassis(ChassisBase):
A string containing the MAC address in the format A string containing the MAC address in the format
'XX:XX:XX:XX:XX:XX' 'XX:XX:XX:XX:XX:XX'
""" """
return self.eeprom.get_base_mac() return self._eeprom.get_base_mac()
def get_serial_number(self): def get_serial_number(self):
""" """
@ -180,7 +263,7 @@ class Chassis(ChassisBase):
Returns: Returns:
A string containing the hardware serial number for this chassis. A string containing the hardware serial number for this chassis.
""" """
return self.eeprom.get_serial_number() return self._eeprom.get_serial_number()
def get_system_eeprom_info(self): def get_system_eeprom_info(self):
""" """
@ -191,7 +274,7 @@ class Chassis(ChassisBase):
OCP ONIE TlvInfo EEPROM format and values are their corresponding OCP ONIE TlvInfo EEPROM format and values are their corresponding
values. values.
""" """
return self.eeprom.get_system_eeprom_info() return self._eeprom.get_system_eeprom_info()
def _read_generic_file(self, filename, len): def _read_generic_file(self, filename, len):
""" """
@ -205,7 +288,7 @@ class Chassis(ChassisBase):
return result return result
except Exception as e: except Exception as e:
logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) logger.log_info("Fail to read file {} due to {}".format(filename, repr(e)))
return '' return '0'
def _verify_reboot_cause(self, filename): def _verify_reboot_cause(self, filename):
''' '''
@ -215,6 +298,31 @@ class Chassis(ChassisBase):
''' '''
return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n'))) return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n')))
def initialize_reboot_cause(self):
self.reboot_major_cause_dict = {
'reset_main_pwr_fail' : self.REBOOT_CAUSE_POWER_LOSS,
'reset_aux_pwr_or_ref' : self.REBOOT_CAUSE_POWER_LOSS,
'reset_asic_thermal' : self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC,
'reset_hotswap_or_wd' : self.REBOOT_CAUSE_WATCHDOG,
'reset_swb_wd' : self.REBOOT_CAUSE_WATCHDOG,
'reset_sff_wd' : self.REBOOT_CAUSE_WATCHDOG
}
self.reboot_minor_cause_dict = {
'reset_fw_reset' : "Reset by ASIC firmware",
'reset_long_pb' : "Reset by long press on power button",
'reset_short_pb' : "Reset by short press on power button",
'reset_comex_thermal' : "ComEx thermal shutdown",
'reset_comex_pwr_fail' : "ComEx power fail",
'reset_comex_wd' : "Reset requested from ComEx",
'reset_from_asic' : "Reset requested from ASIC",
'reset_reload_bios' : "Reset caused by BIOS reload",
'reset_sw_reset' : "Software reset",
'reset_hotswap_or_halt' : "Reset caused by hotswap or halt",
'reset_from_comex' : "Reset from ComEx",
'reset_voltmon_upgrade_fail': "Reset due to voltage monitor devices upgrade failure"
}
self.reboot_cause_initialized = True
def get_reboot_cause(self): def get_reboot_cause(self):
""" """
Retrieves the cause of the previous reboot Retrieves the cause of the previous reboot
@ -227,21 +335,18 @@ class Chassis(ChassisBase):
to pass a description of the reboot cause. to pass a description of the reboot cause.
""" """
#read reboot causes files in the following order #read reboot causes files in the following order
minor_cause = '' if not self.reboot_cause_initialized:
if self._verify_reboot_cause(REBOOT_CAUSE_POWER_LOSS_FILE): self.initialize_reboot_cause()
major_cause = self.REBOOT_CAUSE_POWER_LOSS
elif self._verify_reboot_cause(REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE):
major_cause = self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC
elif self._verify_reboot_cause(REBOOT_CAUSE_WATCHDOG_FILE):
major_cause = self.REBOOT_CAUSE_WATCHDOG
else:
major_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
if self._verify_reboot_cause(REBOOT_CAUSE_MLNX_FIRMWARE_RESET):
minor_cause = "Reset by ASIC firmware"
else:
major_cause = self.REBOOT_CAUSE_NON_HARDWARE
return major_cause, minor_cause for reset_file, reset_cause in self.reboot_major_cause_dict.iteritems():
if self._verify_reboot_cause(reset_file):
return reset_cause, ''
for reset_file, reset_cause in self.reboot_minor_cause_dict.iteritems():
if self._verify_reboot_cause(reset_file):
return self.REBOOT_CAUSE_HARDWARE_OTHER, reset_cause
return self.REBOOT_CAUSE_NON_HARDWARE, ''
def _get_cpld_version(self, version_file): def _get_cpld_version(self, version_file):
cpld_version = self._read_generic_file(join(CPLD_VERSION_ROOT, version_file), CPLD_VERSION_MAX_LENGTH) cpld_version = self._read_generic_file(join(CPLD_VERSION_ROOT, version_file), CPLD_VERSION_MAX_LENGTH)
@ -383,6 +488,14 @@ class Chassis(ChassisBase):
indicates that fan 0 has been removed, fan 2 indicates that fan 0 has been removed, fan 2
has been inserted and sfp 11 has been removed. has been inserted and sfp 11 has been removed.
""" """
# Initialize SFP event first
if not self.sfp_event_initialized:
from sonic_platform.sfp_event import sfp_event
self.sfp_event = sfp_event()
self.sfp_event.initialize()
self.MAX_SELECT_EVENT_RETURNED = self.PORT_END
self.sfp_event_initialized = True
wait_for_ever = (timeout == 0) wait_for_ever = (timeout == 0)
port_dict = {} port_dict = {}
if wait_for_ever: if wait_for_ever:

View File

@ -0,0 +1,45 @@
#!/usr/bin/env python
#############################################################################
# Mellanox
#
# implementation of new platform api
#############################################################################
try:
import subprocess
from sonic_platform_base.platform_base import PlatformBase
from sonic_platform.chassis import Chassis
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Platform(PlatformBase):
def __init__(self):
PlatformBase.__init__(self)
if self._is_host():
self._chassis = Chassis()
else:
self._chassis = Chassis()
self._chassis.initialize_psu()
self._chassis.initialize_fan()
self._chassis.initialize_eeprom()
self._chassis.initialize_components_list()
def _is_host(self):
"""
Test whether current process is running on the host or an docker
return True for host and False for docker
"""
is_host = False
try:
proc = subprocess.Popen("docker --version 2>/dev/null", stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
proc.wait()
result = stdout.rstrip('\n')
if result != '':
is_host = True
except OSError, e:
pass
return is_host

View File

@ -63,6 +63,24 @@ XCVR_VENDOR_DATE_OFFSET = 84
XCVR_VENDOR_DATE_WIDTH = 8 XCVR_VENDOR_DATE_WIDTH = 8
XCVR_DOM_CAPABILITY_OFFSET = 92 XCVR_DOM_CAPABILITY_OFFSET = 92
XCVR_DOM_CAPABILITY_WIDTH = 2 XCVR_DOM_CAPABILITY_WIDTH = 2
# to improve performance we retrieve all eeprom data via a single ethtool command
# in function get_transceiver_info and get_transceiver_bulk_status
# XCVR_INTERFACE_DATA_SIZE stands for the max size to be read
# this variable is only used by get_transceiver_info.
# please be noted that each time some new value added to the function
# we should make sure that it falls into the area
# [XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE] or
# adjust XCVR_INTERFACE_MAX_SIZE to contain the new data
# It's same for [QSFP_DOM_BULK_DATA_START, QSFP_DOM_BULK_DATA_SIZE] and
# [SFP_DOM_BULK_DATA_START, SFP_DOM_BULK_DATA_SIZE] which are used by
# get_transceiver_bulk_status
XCVR_INTERFACE_DATA_START = 0
XCVR_INTERFACE_DATA_SIZE = 92
QSFP_DOM_BULK_DATA_START = 22
QSFP_DOM_BULK_DATA_SIZE = 36
SFP_DOM_BULK_DATA_START = 96
SFP_DOM_BULK_DATA_SIZE = 10
# definitions of the offset for values in OSFP info eeprom # definitions of the offset for values in OSFP info eeprom
OSFP_TYPE_OFFSET = 0 OSFP_TYPE_OFFSET = 0
@ -229,7 +247,7 @@ class SFP(SfpBase):
bool: True if device is present, False if not bool: True if device is present, False if not
""" """
presence = False presence = False
ethtool_cmd = "ethtool -m sfp{} 2>/dev/null".format(self.index) ethtool_cmd = "ethtool -m sfp{} hex on offset 0 length 4 2>/dev/null".format(self.index)
try: try:
proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
stdout = proc.communicate()[0] stdout = proc.communicate()[0]
@ -261,6 +279,15 @@ class SFP(SfpBase):
return eeprom_raw return eeprom_raw
def _dom_capability_detect(self): def _dom_capability_detect(self):
if not self.get_presence():
self.dom_supported = False
self.dom_temp_supported = False
self.dom_volt_supported = False
self.dom_rx_power_supported = False
self.dom_tx_power_supported = False
self.calibration = 0
return
if self.sfp_type == "QSFP": if self.sfp_type == "QSFP":
self.calibration = 1 self.calibration = 1
sfpi_obj = sff8436InterfaceId() sfpi_obj = sff8436InterfaceId()
@ -466,47 +493,37 @@ class SFP(SfpBase):
print("Error: sfp_object open failed") print("Error: sfp_object open failed")
return None return None
sfp_interface_bulk_raw = self._read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) sfp_interface_bulk_raw = self._read_eeprom_specific_bytes(offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE)
if sfp_interface_bulk_raw is not None: if sfp_interface_bulk_raw is None:
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0)
else:
return None return None
sfp_vendor_name_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START
if sfp_vendor_name_raw is not None: end = start + interface_info_bulk_width
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw[start : end], 0)
else:
return None
sfp_vendor_pn_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START
if sfp_vendor_pn_raw is not None: end = start + XCVR_VENDOR_NAME_WIDTH
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_interface_bulk_raw[start : end], 0)
else:
return None
sfp_vendor_rev_raw = self._read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), vendor_rev_width) start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START
if sfp_vendor_rev_raw is not None: end = start + XCVR_VENDOR_PN_WIDTH
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_interface_bulk_raw[start : end], 0)
else:
return None
sfp_vendor_sn_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START
if sfp_vendor_sn_raw is not None: end = start + vendor_rev_width
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_interface_bulk_raw[start : end], 0)
else:
return None
sfp_vendor_oui_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START
if sfp_vendor_oui_raw is not None: end = start + XCVR_VENDOR_SN_WIDTH
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_interface_bulk_raw[start : end], 0)
else:
return None
sfp_vendor_date_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START
if sfp_vendor_date_raw is not None: end = start + XCVR_VENDOR_OUI_WIDTH
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_interface_bulk_raw[start : end], 0)
else:
return None start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START
end = start + XCVR_VENDOR_DATE_WIDTH
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_interface_bulk_raw[start : end], 0)
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value']
@ -578,84 +595,63 @@ class SFP(SfpBase):
""" """
transceiver_dom_info_dict = {} 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 self.sfp_type == OSFP_TYPE: if self.sfp_type == OSFP_TYPE:
transceiver_dom_info_dict['temperature'] = 'N/A' pass
transceiver_dom_info_dict['voltage'] = 'N/A'
transceiver_dom_info_dict['rx1power'] = 'N/A'
transceiver_dom_info_dict['rx2power'] = 'N/A'
transceiver_dom_info_dict['rx3power'] = 'N/A'
transceiver_dom_info_dict['rx4power'] = 'N/A'
transceiver_dom_info_dict['tx1bias'] = 'N/A'
transceiver_dom_info_dict['tx2bias'] = 'N/A'
transceiver_dom_info_dict['tx3bias'] = 'N/A'
transceiver_dom_info_dict['tx4bias'] = 'N/A'
transceiver_dom_info_dict['tx1power'] = 'N/A'
transceiver_dom_info_dict['tx2power'] = 'N/A'
transceiver_dom_info_dict['tx3power'] = 'N/A'
transceiver_dom_info_dict['tx4power'] = 'N/A'
elif self.sfp_type == QSFP_TYPE: elif self.sfp_type == QSFP_TYPE:
if not self.dom_supported: if not self.dom_supported:
return None return transceiver_dom_info_dict
offset = 0 offset = 0
sfpd_obj = sff8436Dom() sfpd_obj = sff8436Dom()
if sfpd_obj is None: if sfpd_obj is None:
return None return transceiver_dom_info_dict
dom_data_raw = self._read_eeprom_specific_bytes((offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE)
if dom_data_raw is None:
return transceiver_dom_info_dict
if self.dom_temp_supported: if self.dom_temp_supported:
dom_temperature_raw = self._read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START
if dom_temperature_raw is not None: end = start + QSFP_TEMPE_WIDTH
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) dom_temperature_data = sfpd_obj.parse_temperature(dom_data_raw[start : end], 0)
temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value'])
if temp is not None: if temp is not None:
transceiver_dom_info_dict['temperature'] = temp transceiver_dom_info_dict['temperature'] = temp
else:
transceiver_dom_info_dict['temperature'] = 'N/A'
else:
return None
else:
transceiver_dom_info_dict['temperature'] = 'N/A'
if self.dom_volt_supported: if self.dom_volt_supported:
dom_voltage_raw = self._read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START
if dom_voltage_raw is not None: end = start + QSFP_VOLT_WIDTH
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) dom_voltage_data = sfpd_obj.parse_voltage(dom_data_raw[start : end], 0)
volt = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) volt = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value'])
if volt is not None: if volt is not None:
transceiver_dom_info_dict['voltage'] = volt transceiver_dom_info_dict['voltage'] = volt
else:
transceiver_dom_info_dict['voltage'] = 'N/A'
else:
return None
else:
transceiver_dom_info_dict['voltage'] = 'N/A'
dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START
if dom_channel_monitor_raw is not None: end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_data_raw[start : end], 0)
if self.dom_tx_power_supported: if self.dom_tx_power_supported:
transceiver_dom_info_dict['tx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value']) transceiver_dom_info_dict['tx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value'])
transceiver_dom_info_dict['tx2power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value']) transceiver_dom_info_dict['tx2power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value'])
transceiver_dom_info_dict['tx3power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value']) transceiver_dom_info_dict['tx3power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value'])
transceiver_dom_info_dict['tx4power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value']) transceiver_dom_info_dict['tx4power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value'])
else:
transceiver_dom_info_dict['tx1power'] = 'N/A'
transceiver_dom_info_dict['tx2power'] = 'N/A'
transceiver_dom_info_dict['tx3power'] = 'N/A'
transceiver_dom_info_dict['tx4power'] = 'N/A'
if self.dom_rx_power_supported: if self.dom_rx_power_supported:
transceiver_dom_info_dict['rx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value']) transceiver_dom_info_dict['rx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value'])
transceiver_dom_info_dict['rx2power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value']) transceiver_dom_info_dict['rx2power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value'])
transceiver_dom_info_dict['rx3power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value']) transceiver_dom_info_dict['rx3power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value'])
transceiver_dom_info_dict['rx4power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value']) transceiver_dom_info_dict['rx4power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value'])
else:
transceiver_dom_info_dict['rx1power'] = 'N/A'
transceiver_dom_info_dict['rx2power'] = 'N/A'
transceiver_dom_info_dict['rx3power'] = 'N/A'
transceiver_dom_info_dict['rx4power'] = 'N/A'
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value']
transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value']
@ -664,46 +660,33 @@ class SFP(SfpBase):
else: else:
if not self.dom_supported: if not self.dom_supported:
return None return transceiver_dom_info_dict
offset = 256 offset = 256
sfpd_obj = sff8472Dom() sfpd_obj = sff8472Dom()
if sfpd_obj is None: if sfpd_obj is None:
return None return transceiver_dom_info_dict
sfpd_obj._calibration_type = self.calibration sfpd_obj._calibration_type = self.calibration
dom_temperature_raw = self._read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) dom_data_raw = self._read_eeprom_specific_bytes((offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE)
if dom_temperature_raw is not None:
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
else:
return None
dom_voltage_raw = self._read_eeprom_specific_bytes((offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START
if dom_voltage_raw is not None: end = start + SFP_TEMPE_WIDTH
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) dom_temperature_data = sfpd_obj.parse_temperature(dom_data_raw[start: end], 0)
else:
return None
dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START
if dom_channel_monitor_raw is not None: end = start + SFP_VOLT_WIDTH
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) dom_voltage_data = sfpd_obj.parse_voltage(dom_data_raw[start: end], 0)
else:
return None start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START
end = start + SFP_CHANNL_MON_WIDTH
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_data_raw[start: end], 0)
transceiver_dom_info_dict['temperature'] = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) transceiver_dom_info_dict['temperature'] = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value'])
transceiver_dom_info_dict['voltage'] = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) transceiver_dom_info_dict['voltage'] = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value'])
transceiver_dom_info_dict['rx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RXPower']['value']) transceiver_dom_info_dict['rx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RXPower']['value'])
transceiver_dom_info_dict['rx2power'] = 'N/A'
transceiver_dom_info_dict['rx3power'] = 'N/A'
transceiver_dom_info_dict['rx4power'] = 'N/A'
transceiver_dom_info_dict['tx1bias'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TXBias']['value']) transceiver_dom_info_dict['tx1bias'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TXBias']['value'])
transceiver_dom_info_dict['tx2bias'] = 'N/A'
transceiver_dom_info_dict['tx3bias'] = 'N/A'
transceiver_dom_info_dict['tx4bias'] = 'N/A'
transceiver_dom_info_dict['tx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TXPower']['value']) transceiver_dom_info_dict['tx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TXPower']['value'])
transceiver_dom_info_dict['tx2power'] = 'N/A'
transceiver_dom_info_dict['tx3power'] = 'N/A'
transceiver_dom_info_dict['tx4power'] = 'N/A'
return transceiver_dom_info_dict return transceiver_dom_info_dict
@ -1036,7 +1019,7 @@ class SFP(SfpBase):
sfpd_obj = sff8472Dom() sfpd_obj = sff8472Dom()
if sfpd_obj is None: if sfpd_obj is None:
return None return None
sfpd_obj._calibration_type = 1 sfpd_obj._calibration_type = self.calibration
if self.dom_supported: if self.dom_supported:
dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
@ -1145,7 +1128,7 @@ class SFP(SfpBase):
return None return None
if self.dom_supported: if self.dom_supported:
sfpd_obj._calibration_type = 1 sfpd_obj._calibration_type = self.calibration
dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
if dom_channel_monitor_raw is not None: if dom_channel_monitor_raw is not None: