Skip to content

Commit

Permalink
Use tx_disable_channel with media_lanes_mask (sonic-net#353)
Browse files Browse the repository at this point in the history
* Use tx_disable_channel with media_lanes_mask

Invoke tx_disable_channel() api using the correct media_lanes_mask in case of subport shut/no shut operations
  • Loading branch information
rajann authored May 12, 2023
1 parent f743d7c commit 1d79bb4
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 6 deletions.
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 {} "
"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 {}"
" 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']
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

0 comments on commit 1d79bb4

Please sign in to comment.