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

Use tx_disable_channel with media_lanes_mask #353

Merged
merged 9 commits into from
May 12, 2023
Merged
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
6 changes: 4 additions & 2 deletions sonic-xcvrd/tests/test_xcvrd.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,14 +796,16 @@ def test_CmisManagerTask_task_worker(self, mock_chassis):
'module_media_interface_id': '400GBASE-DR4 (Cl 124)',
'media_lane_count': 4,
'host_lane_count': 8,
'host_lane_assignment_options': 1
'host_lane_assignment_options': 1,
'media_lane_assignment_options': 1
},
2: {
'host_electrical_interface_id': '100GAUI-2 C2M (Annex 135G)',
'module_media_interface_id': '100G-FR/100GBASE-FR1 (Cl 140)',
'media_lane_count': 1,
'host_lane_count': 2,
'host_lane_assignment_options': 85
'host_lane_assignment_options': 85,
'media_lane_assignment_options': 15
}
})
mock_xcvr_api.get_module_state = MagicMock(return_value='ModuleReady')
Expand Down
64 changes: 60 additions & 4 deletions sonic-xcvrd/xcvrd/xcvrd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,45 @@ def get_cmis_host_lanes_mask(self, api, appl, host_lane_count, subport):

return host_lanes_mask

def get_cmis_media_lanes_mask(self, api, appl, lport, subport):
"""
Retrieves mask of active media lanes based on appl, lport and subport

Args:
api:
XcvrApi object
appl:
Integer, the transceiver-specific application code
lport:
String, logical port name
subport:
Integer, 1-based logical port number of the physical port after breakout
0 means port is a non-breakout port

Returns:
Integer, a mask of the active lanes on the media side
e.g. 0xf for lane 0, lane 1, lane 2 and lane 3.
"""
media_lanes_mask = 0
media_lane_count = self.port_dict[lport]['media_lane_count']
media_lane_assignment_option = self.port_dict[lport]['media_lane_assignment_options']

if appl < 1 or media_lane_count <= 0 or subport < 0:
self.log_error("Invalid input to get media lane mask - appl {} media_lane_count {} "
rajann marked this conversation as resolved.
Show resolved Hide resolved
"lport {} subport {}!".format(appl, media_lane_count, lport, subport))
return media_lanes_mask

media_lane_start_bit = (media_lane_count * (0 if subport == 0 else subport - 1))
if media_lane_assignment_option & (1 << media_lane_start_bit):
media_lanes_mask = ((1 << media_lane_count) - 1) << media_lane_start_bit
else:
self.log_error("Unable to find starting media lane - media_lane_assignment_option {}"
rajann marked this conversation as resolved.
Show resolved Hide resolved
" media_lane_start_bit {} media_lane_count {} lport {} subport {} appl {}!".format(
media_lane_assignment_option, media_lane_start_bit, media_lane_count,
lport, subport, appl))

return media_lanes_mask

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 @@ -1515,13 +1554,28 @@ def task_worker(self):
self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_FAILED
continue
host_lanes_mask = self.port_dict[lport]['host_lanes_mask']
self.log_notice("{}: Setting lanemask=0x{:x}".format(lport, host_lanes_mask))
self.log_notice("{}: Setting host_lanemask=0x{:x}".format(lport, host_lanes_mask))

self.port_dict[lport]['media_lane_count'] = int(api.get_media_lane_count(appl))
self.port_dict[lport]['media_lane_assignment_options'] = int(api.get_media_lane_assignment_option(appl))
media_lane_count = self.port_dict[lport]['media_lane_count']
media_lane_assignment_options = self.port_dict[lport]['media_lane_assignment_options']
rajann marked this conversation as resolved.
Show resolved Hide resolved
self.port_dict[lport]['media_lanes_mask'] = self.get_cmis_media_lanes_mask(api,
appl, lport, subport)
if self.port_dict[lport]['media_lanes_mask'] <= 0:
self.log_error("{}: Invalid media lane mask received - media_lane_count {} "
"media_lane_assignment_options {} lport{} subport {}"
" appl {}!".format(media_lane_count,media_lane_assignment_options,lport,subport,appl))
self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_FAILED
continue
media_lanes_mask = self.port_dict[lport]['media_lanes_mask']
self.log_notice("{}: Setting media_lanemask=0x{:x}".format(lport, media_lanes_mask))

if self.port_dict[lport]['host_tx_ready'] != 'true' or \
self.port_dict[lport]['admin_status'] != 'up':
self.log_notice("{} Forcing Tx laser OFF".format(lport))
# Force DataPath re-init
api.tx_disable_channel(host_lanes_mask, True)
api.tx_disable_channel(media_lanes_mask, True)
self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_READY
continue
# Configure the target output power if ZR module
Expand Down Expand Up @@ -1556,7 +1610,8 @@ def task_worker(self):
api.set_datapath_deinit(host_lanes_mask)

# D.1.3 Software Configuration and Initialization
if not api.tx_disable_channel(host_lanes_mask, True):
media_lanes_mask = self.port_dict[lport]['media_lanes_mask']
if not api.tx_disable_channel(media_lanes_mask, True):
self.log_notice("{}: unable to turn off tx power with host_lanes_mask {}".format(lport, host_lanes_mask))
self.port_dict[lport]['cmis_retries'] = retries + 1
continue
Expand Down Expand Up @@ -1637,7 +1692,8 @@ def task_worker(self):
continue

# Turn ON the laser
api.tx_disable_channel(host_lanes_mask, False)
media_lanes_mask = self.port_dict[lport]['media_lanes_mask']
api.tx_disable_channel(media_lanes_mask, False)
self.log_notice("{}: Turning ON tx power".format(lport))
self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_ACTIVATE
elif state == self.CMIS_STATE_DP_ACTIVATE:
Expand Down