Skip to content

Commit

Permalink
Adding frequency grid validation for ZR optics (#466)
Browse files Browse the repository at this point in the history
* Update test_xcvrd.py

Added test case for frequency config validation for ZR optics

* Update xcvrd.py

Added change to call validation routine for laser frequency grid check.

* Added 100Ghz grid check

* Addresses indentation xcvrd.py

* Updated xcvrd.py with proper return enum values

* Updated test cases for coverage

* Update for code optimisation

* Added frequency and grid information is failure cases

* renamed the function to validate_frequency_and_grid
  • Loading branch information
balram-csco committed Apr 29, 2024
1 parent 759862e commit 6655396
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
22 changes: 21 additions & 1 deletion sonic-xcvrd/tests/test_xcvrd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1699,6 +1699,7 @@ def test_CmisManagerTask_task_worker(self, mock_chassis, mock_get_status_tbl):
mock_xcvr_api.get_module_pwr_up_duration = MagicMock(return_value=70000.0)
mock_xcvr_api.get_datapath_deinit_duration = MagicMock(return_value=600000.0)
mock_xcvr_api.get_cmis_rev = MagicMock(return_value='5.0')
mock_xcvr_api.get_supported_freq_config = MagicMock(return_value=(0xA0,0,0,191300,196100))
mock_xcvr_api.get_dpinit_pending = MagicMock(return_value={
'DPInitPending1': True,
'DPInitPending2': True,
Expand Down Expand Up @@ -2573,7 +2574,7 @@ def test_DaemonXcvrd_init_deinit_cold(self):
xcvrdaemon.deinit()

status_tbl.hdel.assert_called()

@patch('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs', MagicMock(return_value=(test_path, '/invalid/path')))
def test_load_optical_si_file_from_platform_folder(self):
assert optics_si_parser.load_optics_si_settings() != {}
Expand All @@ -2589,6 +2590,25 @@ def test_load_media_settings_file_from_platform_folder(self):
@patch('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs', MagicMock(return_value=('/invalid/path', test_path)))
def test_load_media_settings_file_from_hwsku_folder(self):
assert media_settings_parser.load_media_settings() != {}

@pytest.mark.parametrize("lport, freq, grid, expected", [
(1, 193100, 75, True),
(1, 193100, 100, False),
(1, 193125, 75, False),
(1, 193100, 25, False),
(1, 191295, 75, False),
(1, 196105, 75, False)
])
def test_CmisManagerTask_validate_frequency_and_grid(self, lport, freq, grid, expected):
mock_xcvr_api = MagicMock()
mock_xcvr_api.get_supported_freq_config = MagicMock()
mock_xcvr_api.get_supported_freq_config.return_value = (0x80, 0, 0, 191300, 196100)
port_mapping = PortMapping()
stop_event = threading.Event()
task = CmisManagerTask(DEFAULT_NAMESPACE, port_mapping, stop_event)
result = task.validate_frequency_and_grid(mock_xcvr_api, lport, freq, grid)
assert result == expected


def wait_until(total_wait_time, interval, call_back, *args, **kwargs):
wait_time = 0
Expand Down
41 changes: 31 additions & 10 deletions sonic-xcvrd/xcvrd/xcvrd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1207,15 +1207,32 @@ def configure_tx_output_power(self, api, lport, tx_power):
self.log_error("{} configured tx power {} > maximum power {} supported".format(lport, tx_power, max_p))
return api.set_tx_power(tx_power)

def configure_laser_frequency(self, api, lport, freq, grid=75):
_, _, _, lowf, highf = api.get_supported_freq_config()
def validate_frequency_and_grid(self, api, lport, freq, grid=75):
supported_grid, _, _, lowf, highf = api.get_supported_freq_config()
if freq < lowf:
self.log_error("{} configured freq:{} GHz is lower than the supported freq:{} GHz".format(lport, freq, lowf))
return False
if freq > highf:
self.log_error("{} configured freq:{} GHz is higher than the supported freq:{} GHz".format(lport, freq, highf))
chan = int(round((freq - 193100)/25))
if chan % 3 != 0:
self.log_error("{} configured freq:{} GHz is NOT in 75GHz grid".format(lport, freq))
return False
if grid == 75:
if (supported_grid >> 7) & 0x1 != 1:
self.log_error("{} configured freq:{}GHz supported grid:{} 75GHz is not supported".format(lport, freq, supported_grid))
return False
chan = int(round((freq - 193100)/25))
if chan % 3 != 0:
self.log_error("{} configured freq:{}GHz is NOT in 75GHz grid".format(lport, freq))
return False
elif grid == 100:
if (supported_grid >> 5) & 0x1 != 1:
self.log_error("{} configured freq:{}GHz 100GHz is not supported".format(lport, freq))
return False
else:
self.log_error("{} configured freq:{}GHz {}GHz is not supported".format(lport, freq, grid))
return False
return True

def configure_laser_frequency(self, api, lport, freq, grid=75):
if api.get_tuning_in_progress():
self.log_error("{} Tuning in progress, subport selection may fail!".format(lport))
return api.set_laser_freq(freq, grid)
Expand Down Expand Up @@ -1442,11 +1459,15 @@ def task_worker(self):

# For ZR module, Datapath needes to be re-initlialized on new channel selection
if api.is_coherent_module():
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():
need_update = True
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():
if self.validate_frequency_and_grid(api, lport, freq) == True:
need_update = True
else:
# clear setting of invalid frequency config
self.port_dict[lport]['laser_freq'] = 0

if not need_update:
# No application updates
Expand Down

0 comments on commit 6655396

Please sign in to comment.