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

Xcvrd changes to support 400G ZR configuration #270

Merged
merged 4 commits into from
Aug 2, 2022

Conversation

prgeor
Copy link
Collaborator

@prgeor prgeor commented Jul 1, 2022

Description

400G ZR configuration support

Motivation and Context

400G ZR needs configuration changes for laser frequency and Tx target output power

How Has This Been Tested?

Xcvrd honors the configuration changes for both Tx power and laser frequency:

  1. When Xcvrd is running
  2. When Xcvrd comes up
root@sonic:~# sfputil show eeprom -d -p Ethernet0
Ethernet0: SFP EEPROM detected
        Active App Selection Host Lane 1: 1
        Active App Selection Host Lane 2: 1
        Active App Selection Host Lane 3: 1
        Active App Selection Host Lane 4: 1
        Active App Selection Host Lane 5: 1
        Active App Selection Host Lane 6: 1
        Active App Selection Host Lane 7: 1
        Active App Selection Host Lane 8: 1
        Active Firmware Version: 61.20
        Application Advertisement: {1: {'host_electrical_interface_id': '400GAUI-8 C2M (Annex 120E)', 'module_media_interface_id': '400ZR, DWDM, amplified', 'media_lane_count': 1, 'host_lane_count': 8, 'host_lane_assignment_options': 1}, 2: {'host_electrical_interface_id': '400GAUI-8 C2M (Annex 120E)', 'module_media_interface_id': '400ZR, Single Wavelength, Unamplified', 'media_lane_count': 1, 'host_lane_count': 8, 'host_lane_assignment_options': 1}, 3: {'host_electrical_interface_id': '100GAUI-2 C2M (Annex 135G)', 'module_media_interface_id': '400ZR, DWDM, amplified', 'media_lane_count': 1, 'host_lane_count': 2, 'host_lane_assignment_options': 85}}
        CMIS Revision: 4.1
        Connector: LC
        Encoding: N/A
        Extended Identifier: Power Class 8 (20.0W Max)
        Extended RateSelect Compliance: N/A
        Hardware Revision: 1.1
        Host Electrical Interface: 400GAUI-8 C2M (Annex 120E)
        Host Lane Assignment Options: 1
        Host Lane Count: 8
        Identifier: QSFP-DD Double Density 8X Pluggable Transceiver
        Inactive Firmware Version: 161.10
        Length Cable Assembly(m): 0.0
        Media Interface Code: 400ZR, DWDM, amplified
        Media Interface Technology: 1550 nm DFB
        Media Lane Assignment Options: 1
        Media Lane Count: 1
        Nominal Bit Rate(100Mbs): 0
        Specification compliance: sm_media_interface
        Supported Max Laser Frequency: 196100GHz
        Supported Max TX Power: 4.0dBm
        Supported Min Laser Frequency: 191300GHz
        Supported Min TX Power: -22.9dBm
        Vendor Date Code(YYYY-MM-DD Lot): 2021-11-19   
        Vendor Name: Acacia Comm Inc.
        Vendor OUI: 7c-b2-5c
        Vendor PN: DP04QSDD-E20-001
        Vendor Rev: A 
        Vendor SN: 214455197       
        ChannelMonitorValues:
                RX1Power: -11.884249941294067dBm
                RX2Power: -infdBm
                RX3Power: -infdBm
                RX4Power: -infdBm
                RX5Power: -infdBm
                RX6Power: -infdBm
                RX7Power: -infdBm
                RX8Power: -infdBm
                TX1Bias: 241.496mA
                TX1Power: -13.585258894959004dBm
                TX2Bias: 0.0mA
                TX2Power: -infdBm
                TX3Bias: 0.0mA
                TX3Power: -infdBm
                TX4Bias: 0.0mA
                TX4Power: -infdBm
                TX5Bias: 0.0mA
                TX5Power: -infdBm
                TX6Bias: 0.0mA
                TX6Power: -infdBm
                TX7Bias: 0.0mA
                TX7Power: -infdBm
                TX8Bias: 0.0mA
                TX8Power: -infdBm
        ChannelThresholdValues:
                RxPowerHighAlarm  : 2.0dBm
                RxPowerHighWarning: 0.0dBm
                RxPowerLowAlarm   : -23.01dBm
                RxPowerLowWarning : -20.0dBm
                TxBiasHighAlarm   : 0.0mA
                TxBiasHighWarning : 0.0mA
                TxBiasLowAlarm    : 0.0mA
                TxBiasLowWarning  : 0.0mA
                TxPowerHighAlarm  : 0.0dBm
                TxPowerHighWarning: -2.0dBm
                TxPowerLowAlarm   : -18.013dBm
                TxPowerLowWarning : -16.003dBm
        ModuleMonitorValues:
                Temperature: 66.0C
                Vcc: 3.321Volts
        ModuleThresholdValues:
                TempHighAlarm  : 80.0C
                TempHighWarning: 75.0C
                TempLowAlarm   : -5.0C
                TempLowWarning : 15.0C
                VccHighAlarm   : 3.465Volts
                VccHighWarning : 3.432Volts
                VccLowAlarm    : 3.135Volts
                VccLowWarning  : 3.168Volts


root@sonic:~# 

Configured frequency

root@sonic:/# python3
Python 3.7.3 (default, Jan 22 2021, 20:04:44) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from sonic_platform.chassis import Chassis
>>> c = Chassis()
>>> sfp = c.get_sfp(1)
>>> api = sfp.get_xcvr_api()
>>> api.get_current_laser_freq()
193175.0
>>> 

Additional Information (Optional)

except AttributeError:
# Skip if these essential routines are not available
self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_READY
assert 1 == 0
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this

@rlhui rlhui added the Chassis label Jul 12, 2022
@rlhui rlhui requested a review from judyjoseph July 12, 2022 09:35
@prgeor
Copy link
Collaborator Author

prgeor commented Jul 12, 2022

@snider-nokia can you review?

@prgeor
Copy link
Collaborator Author

prgeor commented Jul 12, 2022

@jaganbal-a @shyam77git please review

@prgeor
Copy link
Collaborator Author

prgeor commented Jul 12, 2022

@qinchuanares please review

Copy link

@jaganbal-a jaganbal-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the unit test log.


found, port_info = port_tbl.get(lport)
if found and 'laser_freq' in dict(port_info):
freq = dict(port_info)['laser_freq']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if found is True but no frequency is configured in port_info? It's likely to happen when a ZR module is plugged but freq config is missing. Do we see the port to be err-disabled?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the port_info{} dictionary represents the PORT table in CONFIG_DB. If laser frequency is NOT configured, then we move on with the module's default frequency.

Copy link
Contributor

@qinchuanares qinchuanares Jul 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

freq init value == 0 in this function. Does it mean when we see freq == 0, it will set module frequency to the default frequency? Can we test this feature with a ZR module by erasing the port's frequency config and see how the module will be configured.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes module comes with default frequency if not configured


found, port_info = port_tbl.get(lport)
if found and 'tx_power' in dict(port_info):
power = dict(port_info)['tx_power']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly. What if found is True but no tx power is configured on the port. Should we enable a default power setting?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default is the module's default. This API gets the value explicitly configured by the user

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the previous comment, Can we test this feature with a ZR module by erasing the port's tx power config and see how the module will be configured.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If tx power is not configured, module comes with module's default Tx power.

if api.is_coherent_module():
tx_power = self.port_dict[lport]['tx_power']
# Prevent configuring same tx power multiple times
if 0 != tx_power and tx_power != api.get_tx_config_power():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does it mean when tx_power == 0?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it means no 'tx_power' missing in the PORT table of CONFIG_DB. See get_configured_tx_power()

freq = self.port_dict[lport]['laser_freq']
# If user requested frequency is NOT the same as configured on the module
# force datapath re-initialization
if 0 != freq and freq != api.get_laser_config_freq():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does it mean when freq == 0?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means 'laser_freq' is missing in PORT table of CONFIG_DB. see get_configured_laser_freq()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. It means the no laser_freq is configured in config_db.

@@ -443,6 +443,27 @@ def test_CmisManagerTask_handle_port_change_event(self):
task.on_port_update_event(port_change_event)
assert len(task.port_dict) == 1


@patch('xcvrd.xcvrd.XcvrTableHelper')
def test_CmisManagerTask_get_configured_freq(self, mock_table_helper):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add failure case? For instance, 1. when config_freq is out of allowed freq range. 2. when config_freq does not fall on 75GHz grid.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API tests get_configured_laser_freq() which obtains the configured value from the PORT table of CONFIG_DB. Invalid frequency is validated here sonic-net/sonic-utilities#2197

Copy link
Contributor

@qinchuanares qinchuanares Jul 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I looking at the correct place https://github.com/prgeor/sonic-utilities/blob/ba58d985b2483d24fb68821f11c6507dd08de567/scripts/portconfig#L337? seems like it's only validating the case when freq is <= 0? Does it verify the provisioned frequency is within the min and max advertised supported freq values?

assert task.get_configured_laser_freq('Ethernet0') == 193100

@patch('xcvrd.xcvrd.XcvrTableHelper')
def test_CmisManagerTask_get_configured_tx_power(self, mock_table_helper):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly can we add failure case? 1. when configured tx power is out of range.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API simply get the configured tx_power from the CONFIG_DB. The user input for TX power is validated here sonic-net/sonic-utilities#2197. Please do note, tx_power can be configured even if transceiver is NOT plugged in, so we cannot validate tx_power in that case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the right place that it validates tx power https://github.com/prgeor/sonic-utilities/blob/ba58d985b2483d24fb68821f11c6507dd08de567/scripts/portconfig#L332? Does it mean it only allows one digit after decimal point? Does it verify the configured tx power is within the min and max advertised supported tx power values?

if api.is_coherent_module():
tx_power = self.port_dict[lport]['tx_power']
# Prevent configuring same tx power multiple times
if 0 != tx_power and tx_power != api.get_tx_config_power():

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this check helps preventing reprogramming during xcvrd restart?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this check helps preventing reprogramming during xcvrd restart?

@jaganbal-a YES

if 'tx_power' not in self.port_dict[lport]:
self.port_dict[lport]['tx_power'] = self.get_configured_tx_power(lport)
if 'laser_freq' not in self.port_dict[lport]:
self.port_dict[lport]['laser_freq'] = self.get_configured_laser_freq(lport)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think get_configured_tx_power_from_dict() naming is appropriate as it reading from dict and not from the device. similar for get_configured_laser_freq().

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaganbal-a the configured frequency is read from the DB. see comment inside get_configured_tx_power()

Copy link

@jaganbal-a jaganbal-a Jul 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the get_configured_tx_power() read from DB, but the naming sounds like it read from the device.
So I would suggest the naming get_configured_tx_power_from_dict()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaganbal-a please check latest changes

self.port_dict[lport]['laser_freq'] = int(port_change_event.port_dict['laser_freq'])
if 'tx_power' in port_change_event.port_dict:
self.port_dict[lport]['tx_power'] = float(port_change_event.port_dict['tx_power'])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With CMIS state reset to INSERTED upon any event for the port, the coherent module will be read continuously for Tx power and frequency.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

port_dict[] is updated by reading the configuration values from the DB, not by reading the module

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not about port_dict[].
When the CMIS state is reset, the state changes to INSERTED. Once the CMIS state is INSERTED, the below piece of code executed continuously in the CMIS mgr task worker. api.get_tx_config_power() and api.get_laser_config_freq() query the device with that.

Configure the target output power if ZR module

                    if api.is_coherent_module():
                       tx_power = self.port_dict[lport]['tx_power']
                       # Prevent configuring same tx power multiple times
                       if 0 != tx_power and tx_power != api.get_tx_config_power():

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as discussed offline, this is not specific to tx_power or laser_freq. Currently don't have a subscription mechanism to listen only to the interested fields. This is the git issue to improve on this #259

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree and hopefully #259 converges soon.
Note: currently there is no overhead due to this issue. But with the this PR changes the optical module will be read for both freq and tx-power register offsets in continuous fashion.

@prgeor prgeor added the CMIS label Jul 27, 2022
@prgeor
Copy link
Collaborator Author

prgeor commented Jul 27, 2022

ZR-log.txt
@jaganbal-a added the log

@qinchuanares
Copy link
Contributor

@prgeor I checked the test log. For TX power configuration, we would not want data path to be reinitialized. It should be done when data path is always activated and tx is enabled.

@jaganbal-a
Copy link

ZR-log.txt @jaganbal-a added the log

Can you please capture show interface transceiver eeprom -d for the interfaces having ZR with tx and freq configuration?

Copy link

@jaganbal-a jaganbal-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added response to the existing comments.

@prgeor
Copy link
Collaborator Author

prgeor commented Jul 27, 2022

@prgeor I checked the test log. For TX power configuration, we would not want data path to be reinitialized. It should be done when data path is always activated and tx is enabled.

@qinchuanares can you point me to the CMIS reference where you find this requirement. Here is what I in section 7.5.2. There is no strict requirement to program TX power in datapath activated state. At CMIS_STATE_INSERTED, module is either in Low power mode or in High power mode.

image

@prgeor
Copy link
Collaborator Author

prgeor commented Jul 27, 2022

ZR-log.txt @jaganbal-a added the log

Can you please capture show interface transceiver eeprom -d for the interfaces having ZR with tx and freq configuration?

Added the log in the description. please check

jaganbal-a
jaganbal-a previously approved these changes Jul 28, 2022
Copy link

@jaganbal-a jaganbal-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@jaganbal-a
Copy link

Frequency should be displayed as part of show int transceiver CLI. Please raise a git issue.

qinchuanares
qinchuanares previously approved these changes Jul 28, 2022
vdahiya12
vdahiya12 previously approved these changes Jul 28, 2022
@prgeor
Copy link
Collaborator Author

prgeor commented Jul 28, 2022

@rlhui @lguohan please merge

Copy link

@lizhuhuams lizhuhuams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge for Prince.

lizhuhuams
lizhuhuams previously approved these changes Jul 28, 2022
judyjoseph
judyjoseph previously approved these changes Jul 29, 2022
@prgeor prgeor merged commit cc56367 into sonic-net:master Aug 2, 2022
dprital added a commit to dprital/sonic-buildimage that referenced this pull request Aug 9, 2022
Update sonic-platform-daemons submodule pointer to include the following:
* Xcvrd changes to support 400G ZR configuration ([sonic-net#270](sonic-net/sonic-platform-daemons#270))
* [ycabled] add secure channel support for grpc dualtor active-active connectivity  ([sonic-net#275](sonic-net/sonic-platform-daemons#275))

Signed-off-by: dprital <drorp@nvidia.com>
yxieca pushed a commit that referenced this pull request Aug 17, 2022
* Xcvrd changes to support 400G ZR configuration

* Fix test failures

* Improve code coverage

* Addressed review comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants