Skip to content

Commit 516fec8

Browse files
committed
Credo AEC 400G firmware v4.1 needs to set low power mode when change to DPDeinit state
Description Credo AEC 400G needs to set low power mode when changing to DPDeinit state on firmware v4.1. After #254 is merged, low power mode will not be set when changing to DPDeinit state. Motivation and Context This patch adds the code to set low power mode only when changing to DPDeinit state when the transceiver's vendor is 'Credo' and 'host_assign' is '1'(Which means the application mode only has 1 logical port on the transceiver). With this patch, the Credo AEC 400G can work correctly.
1 parent 7a0813a commit 516fec8

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

sonic-xcvrd/tests/test_xcvrd.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,21 @@ def test_CmisManagerTask_get_configured_tx_power_from_db(self, mock_table_helper
17411741
task.xcvr_table_helper.get_cfg_port_tbl = mock_table_helper.get_cfg_port_tbl
17421742
assert task.get_configured_tx_power_from_db('Ethernet0') == -10
17431743

1744+
@pytest.mark.parametrize("appl, host_assign, vendor, expected", [
1745+
(1, 0x1, 'Credo', True),
1746+
(2, 0x11, 'Credo', False),
1747+
(1, 0x1, 'Molex', False)
1748+
])
1749+
def test_CmisManagerTask_is_need_low_power_first(self, appl, host_assign, vendor, expected):
1750+
port_mapping = PortMapping()
1751+
stop_event = threading.Event()
1752+
task = CmisManagerTask(DEFAULT_NAMESPACE, port_mapping, stop_event)
1753+
1754+
mock_xcvr_api = MagicMock()
1755+
mock_xcvr_api.get_manufacturer = MagicMock(return_value=vendor)
1756+
mock_xcvr_api.get_host_lane_assignment_option = MagicMock(return_value=host_assign)
1757+
assert task.need_lp_mode_for_dpdeinit(mock_xcvr_api, appl) == expected
1758+
17441759
@patch('xcvrd.xcvrd.platform_chassis')
17451760
@patch('xcvrd.xcvrd.is_fast_reboot_enabled', MagicMock(return_value=(False)))
17461761
@patch('xcvrd.xcvrd.PortChangeObserver', MagicMock(handle_port_update_event=MagicMock()))

sonic-xcvrd/xcvrd/xcvrd.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,31 @@ def wait_for_port_config_done(self, namespace):
11441144
if key in ["PortConfigDone", "PortInitDone"]:
11451145
break
11461146

1147+
def need_lp_mode_for_dpdeinit(self, api, appl):
1148+
"""
1149+
Determine whether the cmis transceiver needs to enter
1150+
low power mode when the state is changed to DPDeinit.
1151+
"""
1152+
host_assign = api.get_host_lane_assignment_option(appl)
1153+
vendor = api.get_manufacturer().strip()
1154+
1155+
if vendor == "Credo" and host_assign == 0x1:
1156+
"""
1157+
Credo AEC 400G needs this operation to work correctly on
1158+
firmware v4.1. Only one application mode 400GAUI-8 is supported
1159+
on firmware v4.1. When 'host_assign' is 1, it means the
1160+
application mode 400GAUI-8 is adopted.
1161+
Firmware v5.1 supports more application modes like 200GAUI-4,
1162+
It is not required to set low power mode when entering
1163+
DPDeinit on v5.1, and it also works fine when set low power
1164+
mode is set. In conclusion, set low power mode is only
1165+
required on Credo AEC 400G when host_assign is 0x1 to
1166+
ensure it works correctly.
1167+
"""
1168+
return True
1169+
else:
1170+
return False
1171+
11471172
def task_worker(self):
11481173
self.xcvr_table_helper = XcvrTableHelper(self.namespaces)
11491174

@@ -1357,7 +1382,19 @@ def task_worker(self):
13571382
continue
13581383
self.log_notice("{}: force Datapath reinit".format(lport))
13591384
self.update_port_transceiver_status_table_sw_cmis_state(lport, CMIS_STATE_DP_DEINIT)
1385+
if self.need_lp_mode_for_dpdeinit(api, appl):
1386+
api.set_lpmode(True)
1387+
now = datetime.datetime.now()
1388+
modulePwrDownDuration = self.get_cmis_module_power_down_duration_secs(api)
1389+
self.log_notice("{}: ModulePwrDown duration {} secs".format(lport, modulePwrDownDuration))
1390+
self.port_dict[lport]['cmis_expired'] = now + datetime.timedelta(seconds=modulePwrDownDuration)
13601391
elif state == CMIS_STATE_DP_DEINIT:
1392+
if self.need_lp_mode_for_dpdeinit(api, appl):
1393+
if not self.check_module_state(api, ['ModuleLowPwr']):
1394+
if (expired is not None) and (expired <= now):
1395+
self.log_notice("{}: timeout for 'ModuleLowPwr'".format(lport))
1396+
self.force_cmis_reinit(lport, retries + 1)
1397+
continue
13611398
# D.2.2 Software Deinitialization
13621399
api.set_datapath_deinit(host_lanes_mask)
13631400

0 commit comments

Comments
 (0)