-
Notifications
You must be signed in to change notification settings - Fork 209
Fix xcvrd to support 400G ZR optic #293
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
Changes from 8 commits
ccbad28
f7f910b
97a6780
96b025d
8fd66f6
3a3b96a
8b52afc
88641db
ea29589
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1073,6 +1073,12 @@ def get_cmis_application_desired(self, api, channel, speed): | |
|
|
||
| return (appl_code & 0xf) | ||
|
|
||
| def get_cmis_dp_init_duration_secs(self, api): | ||
| return api.get_datapath_init_duration()/1000 | ||
|
|
||
| def get_cmis_dp_deinit_duration_secs(self, api): | ||
| return api.get_datapath_deinit_duration()/1000 | ||
|
|
||
| def is_cmis_application_update_required(self, api, channel, speed): | ||
| """ | ||
| Check if the CMIS application update is required | ||
|
|
@@ -1176,6 +1182,32 @@ def check_config_error(self, api, channel, states): | |
|
|
||
| return done | ||
|
|
||
| def check_datapath_init_pending(self, api, channel): | ||
| """ | ||
| Check if the CMIS datapath init is pending | ||
|
|
||
| Args: | ||
| api: | ||
| XcvrApi object | ||
| channel: | ||
| Integer, a bitmask of the lanes on the host side | ||
| e.g. 0x5 for lane 0 and lane 2. | ||
|
|
||
| Returns: | ||
| Boolean, true if all lanes are pending datapath init, otherwise false | ||
| """ | ||
| pending = True | ||
| dpinit_pending_dict = api.get_dpinit_pending() | ||
| for lane in range(self.CMIS_NUM_CHANNELS): | ||
| if ((1 << lane) & channel) == 0: | ||
| continue | ||
| key = "DPInitPending{}".format(lane + 1) | ||
| if not dpinit_pending_dict[key]: | ||
| pending = False | ||
| break | ||
|
|
||
| return pending | ||
|
|
||
| def check_datapath_state(self, api, channel, states): | ||
| """ | ||
| Check if the CMIS datapath states are in the specified state | ||
|
|
@@ -1458,7 +1490,7 @@ def task_worker(self): | |
| # TODO: Make sure this doesn't impact other datapaths | ||
| api.set_lpmode(False) | ||
| self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_AP_CONF | ||
| self.port_dict[lport]['cmis_expired'] = now + datetime.timedelta(seconds=self.CMIS_DEF_EXPIRED) | ||
| self.port_dict[lport]['cmis_expired'] = now + datetime.timedelta(seconds=self.get_cmis_dp_deinit_duration_secs(api)) | ||
|
||
| elif state == self.CMIS_STATE_AP_CONF: | ||
| # TODO: Use fine grained time when the CMIS memory map is available | ||
| if not self.check_module_state(api, ['ModuleReady']): | ||
|
|
@@ -1494,8 +1526,14 @@ def task_worker(self): | |
| self.force_cmis_reinit(lport, retries + 1) | ||
| continue | ||
|
|
||
| # TODO: Use fine grained time when the CMIS memory map is available | ||
| self.port_dict[lport]['cmis_expired'] = now + datetime.timedelta(seconds=self.CMIS_DEF_EXPIRED) | ||
| if getattr(api, 'get_cmis_rev', None): | ||
| # Check datapath init pending on module that supports CMIS 5.x | ||
| majorRev = int(api.get_cmis_rev().split('.')[0]) | ||
| if majorRev >= 5 and not self.check_datapath_init_pending(api, host_lanes): | ||
| self.log_notice("{}: datapath init not pending".format(lport)) | ||
| self.force_cmis_reinit(lport, retries + 1) | ||
| continue | ||
|
|
||
| self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_INIT | ||
| elif state == self.CMIS_STATE_DP_INIT: | ||
| if not self.check_config_error(api, host_lanes, ['ConfigSuccess']): | ||
|
|
@@ -1515,8 +1553,7 @@ def task_worker(self): | |
|
|
||
| # D.1.3 Software Configuration and Initialization | ||
| api.set_datapath_init(host_lanes) | ||
| # TODO: Use fine grained timeout when the CMIS memory map is available | ||
| self.port_dict[lport]['cmis_expired'] = now + datetime.timedelta(seconds=self.CMIS_DEF_EXPIRED) | ||
| self.port_dict[lport]['cmis_expired'] = now + datetime.timedelta(seconds=self.get_cmis_dp_init_duration_secs(api)) | ||
|
||
| self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_TXON | ||
| elif state == self.CMIS_STATE_DP_TXON: | ||
| if not self.check_datapath_state(api, host_lanes, ['DataPathInitialized']): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should check if DpInitPending is set for ALL host lanes and return TRUE. Return False if any of the lanes has DpInitPending=0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On further thought and checking , please look further into this.
should this be interpreted as: as long as one of the lanes is found in DPInitPending state, outcome is pending (i.e. true). Caller of this function on getting 'true', would perform force_cmis_reinit() instead of setting state to CMIS_STATE_DP_INIT (& proceeding with normal workflow)