Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 46 additions & 19 deletions platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from sonic_py_common import device_info
from functools import reduce
from .utils import extract_RJ45_ports_index
from .utils import extract_cpo_ports_index
from . import module_host_mgmt_initializer
from . import utils
from .device_data import DeviceDataManager
Expand Down Expand Up @@ -120,6 +121,10 @@ def __init__(self):
self._RJ45_port_inited = False
self._RJ45_port_list = None

# Build the CPO port list from platform.json and hwsku.json
self._cpo_port_inited = False
self._cpo_port_list = None

Chassis.chassis_instance = self

self.module_host_mgmt_initializer = module_host_mgmt_initializer.ModuleHostMgmtInitializer()
Expand All @@ -139,6 +144,13 @@ def RJ45_port_list(self):
self._RJ45_port_inited = True
return self._RJ45_port_list

@property
def cpo_port_list(self):
if not self._cpo_port_inited:
self._cpo_port_list = extract_cpo_ports_index()
self._cpo_port_inited = True
return self._cpo_port_list

##############################################
# PSU methods
##############################################
Expand Down Expand Up @@ -277,6 +289,8 @@ def initialize_single_sfp(self, index):
sfp_module = self._import_sfp_module()
if self.RJ45_port_list and index in self.RJ45_port_list:
self._sfp_list[index] = sfp_module.RJ45Port(index)
elif self.cpo_port_list and index in self.cpo_port_list:
self._sfp_list[index] = sfp_module.CpoPort(index)
else:
self._sfp_list[index] = sfp_module.SFP(index)
self.sfp_initialized_count += 1
Expand All @@ -294,6 +308,8 @@ def initialize_sfp(self):
for index in range(sfp_count):
if self.RJ45_port_list and index in self.RJ45_port_list:
sfp_object = sfp_module.RJ45Port(index)
elif self.cpo_port_list and index in self.cpo_port_list:
sfp_object = sfp_module.CpoPort(index)
else:
sfp_object = sfp_module.SFP(index)
self._sfp_list.append(sfp_object)
Expand All @@ -304,6 +320,8 @@ def initialize_sfp(self):
if self._sfp_list[index] is None:
if self.RJ45_port_list and index in self.RJ45_port_list:
self._sfp_list[index] = sfp_module.RJ45Port(index)
elif self.cpo_port_list and index in self.cpo_port_list:
self._sfp_list[index] = sfp_module.CpoPort(index)
else:
self._sfp_list[index] = sfp_module.SFP(index)
self.sfp_initialized_count = len(self._sfp_list)
Expand All @@ -315,13 +333,22 @@ def get_num_sfps(self):
Returns:
An integer, the number of sfps available on this chassis
"""
num_sfps = 0
if not self._RJ45_port_inited:
self._RJ45_port_list = extract_RJ45_ports_index()
self._RJ45_port_inited = True

if not self._cpo_port_inited:
self._cpo_port_list = extract_cpo_ports_index()
self._cpo_port_inited = True

num_sfps = DeviceDataManager.get_sfp_count()
if self._RJ45_port_list is not None:
return DeviceDataManager.get_sfp_count() + len(self._RJ45_port_list)
else:
return DeviceDataManager.get_sfp_count()
num_sfps += len(self._RJ45_port_list)
if self._cpo_port_list is not None:
num_sfps += len(self._cpo_port_list)

return num_sfps

def get_all_sfps(self):
"""
Expand All @@ -330,7 +357,7 @@ def get_all_sfps(self):
Returns:
A list of objects derived from SfpBase representing all sfps
available on this chassis
"""
"""
if DeviceDataManager.is_module_host_management_mode():
self.module_host_mgmt_initializer.initialize(self)
else:
Expand Down Expand Up @@ -410,7 +437,7 @@ def get_change_event(self, timeout=0):
else:
self.initialize_sfp()
return self.get_change_event_legacy(timeout)

def get_change_event_for_module_host_management_mode(self, timeout):
"""Get SFP change event when module host management mode is enabled.

Expand Down Expand Up @@ -442,24 +469,24 @@ def get_change_event_for_module_host_management_mode(self, timeout):
self.registered_fds[fd.fileno()] = (s.sdk_index, fd, fd_type)

logger.log_debug(f'Registered SFP file descriptors for polling: {self.registered_fds}')

from . import sfp

wait_forever = (timeout == 0)
# poll timeout should be no more than 1000ms to ensure fast shutdown flow
timeout = 1000.0 if timeout >= 1000 else float(timeout)
port_dict = {}
error_dict = {}
begin = time.monotonic()
wait_ready_task = sfp.SFP.get_wait_ready_task()
while True:

while True:
fds_events = self.poll_obj.poll(timeout)
for fileno, _ in fds_events:
if fileno not in self.registered_fds:
logger.log_error(f'Unknown file no {fileno} from poll event, registered files are {self.registered_fds}')
continue

sfp_index, fd, fd_type = self.registered_fds[fileno]
s = self._sfp_list[sfp_index]
fd.seek(0)
Expand All @@ -483,7 +510,7 @@ def get_change_event_for_module_host_management_mode(self, timeout):
# FW control cable got an error, no need trigger state machine
sfp_status, error_desc = s.get_error_info_from_sdk_error_type()
port_dict[sfp_index + 1] = sfp_status
if error_desc:
if error_desc:
error_dict[sfp_index + 1] = error_desc
continue
elif str(fd_value) == sfp.SFP_STATUS_INSERTED:
Expand All @@ -499,14 +526,14 @@ def get_change_event_for_module_host_management_mode(self, timeout):
# event could be EVENT_POWER_GOOD or EVENT_POWER_BAD
event = sfp.EVENT_POWER_BAD if fd_value == 0 else sfp.EVENT_POWER_GOOD
s.on_event(event)

if s.in_stable_state():
self.sfp_module.SFP.wait_sfp_eeprom_ready([s], 2)
s.fill_change_event(port_dict)
s.refresh_poll_obj(self.poll_obj, self.registered_fds)
else:
logger.log_debug(f'SFP {sfp_index} does not reach stable state, state={s.state}')

ready_sfp_set = wait_ready_task.get_ready_set()
for sfp_index in ready_sfp_set:
s = self._sfp_list[sfp_index]
Expand All @@ -517,7 +544,7 @@ def get_change_event_for_module_host_management_mode(self, timeout):
s.refresh_poll_obj(self.poll_obj, self.registered_fds)
else:
logger.log_error(f'SFP {sfp_index} failed to reach stable state, state={s.state}')

if port_dict:
logger.log_notice(f'Sending SFP change event: {port_dict}, error event: {error_dict}')
self.reinit_sfps(port_dict)
Expand Down Expand Up @@ -564,23 +591,23 @@ def get_change_event_legacy(self, timeout):
self.sfp_states_before_first_poll[s.sdk_index] = s.get_module_status()

logger.log_debug(f'Registered SFP file descriptors for polling: {self.registered_fds}')

from . import sfp

wait_forever = (timeout == 0)
# poll timeout should be no more than 1000ms to ensure fast shutdown flow
timeout = 1000.0 if timeout >= 1000 else float(timeout)
port_dict = {}
error_dict = {}
begin = time.monotonic()

while True:
fds_events = self.poll_obj.poll(timeout)
for fileno, _ in fds_events:
if fileno not in self.registered_fds:
logger.log_error(f'Unknown file no {fileno} from poll event, registered files are {self.registered_fds}')
continue

sfp_index, fd = self.registered_fds[fileno]
fd.seek(0)
fd.read()
Expand Down Expand Up @@ -948,7 +975,7 @@ def _parse_vpd_data(self, filename):
return result

result = utils.read_key_value_file(filename, delimeter=": ")

except Exception as e:
logger.log_error("Fail to decode vpd_data {} due to {}".format(filename, repr(e)))

Expand Down
Loading