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

CMIS 'ConfigSuccess" failure while changing default ApSel code for 800G DR8/FR8 modules #459

Merged
merged 16 commits into from
May 17, 2024
Merged
51 changes: 51 additions & 0 deletions sonic-xcvrd/tests/test_xcvrd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1523,6 +1523,21 @@ def test_CmisManagerTask_task_run_stop(self, mock_chassis):
cmis_manager.join()
assert not cmis_manager.is_alive()

@pytest.mark.parametrize("app_new, lane_appl_code, expected", [
(2, {0 : 1, 1 : 1, 2 : 1, 3 : 1, 4 : 2, 5 : 2, 6 : 2, 7 : 2}, True),
(0, {0 : 1, 1 : 1, 2 : 1, 3 : 1}, True),
(1, {0 : 0, 1 : 0, 2 : 0, 3 : 0, 4 : 0, 5 : 0, 6 : 0, 7 : 0}, False)
])
def test_CmisManagerTask_is_appl_reconfigure_required(self, app_new, lane_appl_code, expected):
mock_xcvr_api = MagicMock()
def get_application(lane):
return lane_appl_code.get(lane, 0)
mock_xcvr_api.get_application = MagicMock(side_effect=get_application)
port_mapping = PortMapping()
stop_event = threading.Event()
task = CmisManagerTask(DEFAULT_NAMESPACE, port_mapping, stop_event)
assert task.is_appl_reconfigure_required(mock_xcvr_api, app_new) == expected

DEFAULT_DP_STATE = {
'DP1State': 'DataPathActivated',
'DP2State': 'DataPathActivated',
Expand Down Expand Up @@ -1865,6 +1880,8 @@ def test_CmisManagerTask_task_worker(self, mock_chassis, mock_get_status_tbl):
task.configure_laser_frequency = MagicMock(return_value=1)

# Case 1: Module Inserted --> DP_DEINIT
task.is_appl_reconfigure_required = MagicMock(return_value=True)
mock_xcvr_api.decommission_all_datapaths = MagicMock(return_value=True)
task.task_stopping_event.is_set = MagicMock(side_effect=[False, False, True])
task.task_worker()
assert get_cmis_state_from_state_db('Ethernet0', task.xcvr_table_helper.get_status_tbl(task.port_mapping.get_asic_id_for_logical_port('Ethernet0'))) == CMIS_STATE_DP_DEINIT
Expand Down Expand Up @@ -1900,6 +1917,40 @@ def test_CmisManagerTask_task_worker(self, mock_chassis, mock_get_status_tbl):
assert task.post_port_active_apsel_to_db.call_count == 1
assert get_cmis_state_from_state_db('Ethernet0', task.xcvr_table_helper.get_status_tbl(task.port_mapping.get_asic_id_for_logical_port('Ethernet0'))) == CMIS_STATE_READY

# Fail test coverage - Module Inserted state failing to reach DP_DEINIT
port_mapping = PortMapping()
stop_event = threading.Event()
task = CmisManagerTask(DEFAULT_NAMESPACE, port_mapping, stop_event)
task.port_mapping.logical_port_list = ['Ethernet1']
task.xcvr_table_helper.get_status_tbl.return_value = mock_get_status_tbl
task.task_stopping_event.is_set = MagicMock(side_effect=[False, False, True])
task.task_worker()
assert get_cmis_state_from_state_db('Ethernei1', task.xcvr_table_helper.get_status_tbl(task.port_mapping.get_asic_id_for_logical_port('Ethernet1'))) == CMIS_STATE_UNKNOWN

task.port_mapping.logical_port_list = MagicMock()
port_change_event = PortChangeEvent('PortConfigDone', -1, 0, PortChangeEvent.PORT_SET)
task.on_port_update_event(port_change_event)
assert task.isPortConfigDone

port_change_event = PortChangeEvent('Ethernet1', 1, 0, PortChangeEvent.PORT_SET,
{'speed':'400000', 'lanes':'1,2,3,4,5,6,7,8'})
task.on_port_update_event(port_change_event)
assert len(task.port_dict) == 1
assert get_cmis_state_from_state_db('Ethernet1', task.xcvr_table_helper.get_status_tbl(task.port_mapping.get_asic_id_for_logical_port('Ethernet1'))) == CMIS_STATE_INSERTED

task.get_host_tx_status = MagicMock(return_value='true')
task.get_port_admin_status = MagicMock(return_value='up')
task.get_configured_tx_power_from_db = MagicMock(return_value=-13)
task.get_configured_laser_freq_from_db = MagicMock(return_value=193100)
task.configure_tx_output_power = MagicMock(return_value=1)
task.configure_laser_frequency = MagicMock(return_value=1)

task.is_appl_reconfigure_required = MagicMock(return_value=True)
mock_xcvr_api.decommission_all_datapaths = MagicMock(return_value=False)
task.task_stopping_event.is_set = MagicMock(side_effect=[False, False, True])
task.task_worker()
assert get_cmis_state_from_state_db('Ethernet1', task.xcvr_table_helper.get_status_tbl(task.port_mapping.get_asic_id_for_logical_port('Ethernet1'))) == CMIS_STATE_FAILED

@pytest.mark.parametrize("lport, expected_dom_polling", [
('Ethernet0', 'disabled'),
('Ethernet4', 'disabled'),
Expand Down
18 changes: 18 additions & 0 deletions sonic-xcvrd/xcvrd/xcvrd.py
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,16 @@ def get_cmis_media_lanes_mask(self, api, appl, lport, subport):

return media_lanes_mask

def is_appl_reconfigure_required(self, api, app_new):
AnoopKamath marked this conversation as resolved.
Show resolved Hide resolved
"""
Reset app code if non default app code needs to configured
"""
for lane in range(self.CMIS_MAX_HOST_LANES):
app_cur = api.get_application(lane)
if app_cur != 0 and app_cur != app_new:
return True
return False

def is_cmis_application_update_required(self, api, app_new, host_lanes_mask):
"""
Check if the CMIS application update is required
Expand Down Expand Up @@ -1465,6 +1475,14 @@ def task_worker(self):
else:
self.log_notice("{} Successfully configured Tx power = {}".format(lport, tx_power))

# Set all the DP lanes AppSel to unused(0) when non default app code needs to be configured
if True == self.is_appl_reconfigure_required(api, appl):
self.log_notice("{}: Decommissioning all lanes/datapaths to default AppSel=0".format(lport))
if True != api.decommission_all_datapaths():
self.log_notifce("{}: Failed to default to AppSel=0".format(lport))
self.force_cmis_reinit(lport, retries + 1)
continue

need_update = self.is_cmis_application_update_required(api, appl, host_lanes_mask)

# For ZR module, Datapath needes to be re-initlialized on new channel selection
Expand Down
Loading