Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Newapi-based-daemon supported #4

Closed
wants to merge 8 commits into from
35 changes: 29 additions & 6 deletions platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
from sonic_platform.sfp import SFP
from sonic_platform.thermal import Thermal, initialize_thermals
from sonic_platform.watchdog import get_watchdog
from sonic_platform.eeprom import Eeprom
from sonic_daemon_base.daemon_base import Logger
from eeprom import Eeprom
from sfp_event import sfp_event
from os import listdir
from os.path import isfile, join
Expand Down Expand Up @@ -90,7 +90,7 @@ def __init__(self):
self._psu_list.append(psu)

# Initialize watchdog
self._watchdog = get_watchdog()
self._watchdog = None

# Initialize FAN list
multi_rotor_in_drawer = False
Expand Down Expand Up @@ -122,7 +122,7 @@ def __init__(self):
initialize_thermals(self.sku_name, self._thermal_list, self._psu_list)

# Initialize EEPROM
self.eeprom = Eeprom()
self._eeprom = Eeprom()

# Initialize component list
self._component_name_list.append(COMPONENT_BIOS)
Expand Down Expand Up @@ -163,6 +163,29 @@ def _get_port_position_tuple_by_sku_name(self):
position_tuple = port_position_tuple_list[hwsku_dict_port[self.sku_name]]
return position_tuple

def get_watchdog(self):
"""
Retreives 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:
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):
"""
Retrieves the base MAC address for the chassis
Expand All @@ -171,7 +194,7 @@ def get_base_mac(self):
A string containing the MAC address in the format
'XX:XX:XX:XX:XX:XX'
"""
return self.eeprom.get_base_mac()
return self._eeprom.get_base_mac()

def get_serial_number(self):
"""
Expand All @@ -180,7 +203,7 @@ def get_serial_number(self):
Returns:
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):
"""
Expand All @@ -191,7 +214,7 @@ def get_system_eeprom_info(self):
OCP ONIE TlvInfo EEPROM format and values are their corresponding
values.
"""
return self.eeprom.get_system_eeprom_info()
return self._eeprom.get_system_eeprom_info()

def _read_generic_file(self, filename, len):
"""
Expand Down
18 changes: 18 additions & 0 deletions platform/mellanox/mlnx-platform-api/sonic_platform/platform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python

#############################################################################
# Mellanox
#
# implementation of new platform api
#############################################################################

try:
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)
self._chassis = Chassis()
87 changes: 34 additions & 53 deletions platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def get_presence(self):
bool: True if device is present, False if not
"""
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:
proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
Expand Down Expand Up @@ -261,6 +261,15 @@ def _read_eeprom_specific_bytes(self, offset, num_bytes):
return eeprom_raw

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":
self.calibration = 1
sfpi_obj = sff8436InterfaceId()
Expand Down Expand Up @@ -578,30 +587,27 @@ def get_transceiver_bulk_status(self):
"""
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:
transceiver_dom_info_dict['temperature'] = 'N/A'
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'
pass

elif self.sfp_type == QSFP_TYPE:
if not self.dom_supported:
return None
return transceiver_dom_info_dict

offset = 0
sfpd_obj = sff8436Dom()
if sfpd_obj is None:
return None
return transceiver_dom_info_dict

if self.dom_temp_supported:
dom_temperature_raw = self._read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH)
Expand All @@ -610,12 +616,8 @@ def get_transceiver_bulk_status(self):
temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value'])
if temp is not None:
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'
return transceiver_dom_info_dict

if self.dom_volt_supported:
dom_voltage_raw = self._read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH)
Expand All @@ -624,38 +626,26 @@ def get_transceiver_bulk_status(self):
volt = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value'])
if volt is not None:
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'
return transceiver_dom_info_dict

dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH)
if dom_channel_monitor_raw is not None:
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0)
else:
return transceiver_dom_info_dict

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['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['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:
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['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'])
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['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value']
Expand All @@ -664,46 +654,37 @@ def get_transceiver_bulk_status(self):

else:
if not self.dom_supported:
return None
return transceiver_dom_info_dict

offset = 256
sfpd_obj = sff8472Dom()
if sfpd_obj is None:
return None
return transceiver_dom_info_dict
sfpd_obj._calibration_type = self.calibration

dom_temperature_raw = self._read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
if dom_temperature_raw is not None:
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
else:
return None
return transceiver_dom_info_dict

dom_voltage_raw = self._read_eeprom_specific_bytes((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:
return None
return transceiver_dom_info_dict

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:
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
else:
return None
return transceiver_dom_info_dict

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['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['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['tx2power'] = 'N/A'
transceiver_dom_info_dict['tx3power'] = 'N/A'
transceiver_dom_info_dict['tx4power'] = 'N/A'

return transceiver_dom_info_dict

Expand Down Expand Up @@ -1036,7 +1017,7 @@ def get_tx_bias(self):
sfpd_obj = sff8472Dom()
if sfpd_obj is None:
return None
sfpd_obj._calibration_type = 1
sfpd_obj._calibration_type = self.calibration

if self.dom_supported:
dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
Expand Down Expand Up @@ -1145,7 +1126,7 @@ def get_tx_power(self):
return None

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)
if dom_channel_monitor_raw is not None:
Expand Down
10 changes: 10 additions & 0 deletions src/sonic-daemon-base/sonic_daemon_base/daemon_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ def load_platform_util(self, module_name, class_name):

return platform_util

def load_chassis(self):
try:
import sonic_platform.platform
platform = sonic_platform.platform.Platform()
chassis = platform.get_chassis()
return chassis
except ImportError, e:
print "Import module sonic_platform failed due to {}".format(repr(e))
return None

# Runs daemon
def run(self):
raise NotImplementedError()