diff --git a/sonic-xcvrd/tests/gearbox_media_settings.json b/sonic-xcvrd/tests/gearbox_media_settings.json new file mode 100644 index 000000000..d78a3ac07 --- /dev/null +++ b/sonic-xcvrd/tests/gearbox_media_settings.json @@ -0,0 +1,350 @@ +{ + "PORT_MEDIA_SETTINGS": { + "1": { + "COPPER50": { + "gb_line_pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "gb_line_pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "gb_line_pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "gb_line_main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "gb_line_post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "gb_line_post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "gb_system_pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_main": { + "lane0": "0x00000080", + "lane1": "0x00000080", + "lane2": "0x00000080", + "lane3": "0x00000080" + }, + "gb_system_post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + }, + "OPTICAL50": { + "gb_line_pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "gb_line_pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "gb_line_pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "gb_line_main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "gb_line_post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "gb_line_post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "gb_system_pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_main": { + "lane0": "0x00000080", + "lane1": "0x00000080", + "lane2": "0x00000080", + "lane3": "0x00000080" + }, + "gb_system_post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + }, + "COPPER25": { + "gb_line_pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_line_pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_line_pre1": { + "lane0": "0xfffffff6", + "lane1": "0xfffffff6", + "lane2": "0xfffffff6", + "lane3": "0xfffffff6" + }, + "gb_line_main": { + "lane0": "0x00000070", + "lane1": "0x00000070", + "lane2": "0x00000070", + "lane3": "0x00000070" + }, + "gb_line_post1": { + "lane0": "0xfffffffe", + "lane1": "0xfffffffe", + "lane2": "0xfffffffe", + "lane3": "0xfffffffe" + }, + "gb_line_post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_main": { + "lane0": "0x00000080", + "lane1": "0x00000080", + "lane2": "0x00000080", + "lane3": "0x00000080" + }, + "gb_system_post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + }, + "OPTICAL25": { + "gb_line_pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_line_pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_line_pre1": { + "lane0": "0xfffffff6", + "lane1": "0xfffffff6", + "lane2": "0xfffffff6", + "lane3": "0xfffffff6" + }, + "gb_line_main": { + "lane0": "0x00000070", + "lane1": "0x00000070", + "lane2": "0x00000070", + "lane3": "0x00000070" + }, + "gb_line_post1": { + "lane0": "0xfffffffe", + "lane1": "0xfffffffe", + "lane2": "0xfffffffe", + "lane3": "0xfffffffe" + }, + "gb_line_post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_pre1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_main": { + "lane0": "0x00000080", + "lane1": "0x00000080", + "lane2": "0x00000080", + "lane3": "0x00000080" + }, + "gb_system_post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "gb_system_post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + } + } +} diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index abee8351b..91ef57acf 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -53,6 +53,9 @@ with open(os.path.join(test_path, 'media_settings.json'), 'r') as f: media_settings_dict = json.load(f) +with open(os.path.join(test_path, 'gearbox_media_settings.json'), 'r') as f: + gearbox_media_settings_dict = json.load(f) + media_settings_with_comma_dict = copy.deepcopy(media_settings_dict) global_media_settings = media_settings_with_comma_dict['GLOBAL_MEDIA_SETTINGS'].pop('1-32') media_settings_with_comma_dict['GLOBAL_MEDIA_SETTINGS']['1-5,6,7-20,21-32'] = global_media_settings @@ -1755,6 +1758,49 @@ def test_notify_media_setting_with_comma(self): self._check_notify_media_setting(1, True, {'preemphasis': ','.join(['0x164509'] * 2)}) self._check_notify_media_setting(6, True, {'preemphasis': ','.join(['0x124A08'] * 2)}) + @patch('xcvrd.xcvrd_utilities.common._wrapper_get_presence', MagicMock(return_value=True)) + @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) + @patch('xcvrd.xcvrd.XcvrTableHelper.get_cfg_port_tbl', MagicMock()) + @patch('xcvrd.xcvrd_utilities.media_settings_parser.g_dict', gearbox_media_settings_dict) + @patch('xcvrd.xcvrd_utilities.media_settings_parser.get_speed_lane_count_and_subport', MagicMock(return_value=(400000, 4, 0))) + def test_notify_media_setting_with_gearbox(self): + """ + Test notify_media_setting() with gearbox media settings. + + This test verifies that the notify_media_setting() function correctly handles + gearbox-specific media settings from gearbox_media_settings.json. The test covers: + - COPPER50 settings with 8 line lanes and 4 system lanes + - OPTICAL50 settings with 8 line lanes and 4 system lanes + - COPPER25 settings with 4 line lanes and 4 system lanes + - OPTICAL25 settings with 4 line lanes and 4 system lanes + + The gearbox settings include both line-side (gb_line_*) and system-side (gb_system_*) + SerDes parameters that need to be correctly extracted and formatted. + """ + # Test COPPER50 with gearbox (8 line lanes, 4 system lanes) + with patch('xcvrd.xcvrd_utilities.media_settings_parser.get_media_settings_key', + MagicMock(return_value={'vendor_key': 'TEST-VENDOR', 'media_key': 'TEST-MEDIA', + 'lane_speed_key': 'speed:50G', 'medium_lane_speed_key': 'COPPER50'})): + self._check_notify_media_setting_with_gearbox(1, 8, 4) + + # Test OPTICAL50 with gearbox (8 line lanes, 4 system lanes) + with patch('xcvrd.xcvrd_utilities.media_settings_parser.get_media_settings_key', + MagicMock(return_value={'vendor_key': 'TEST-VENDOR', 'media_key': 'TEST-MEDIA', + 'lane_speed_key': 'speed:50G', 'medium_lane_speed_key': 'OPTICAL50'})): + self._check_notify_media_setting_with_gearbox(1, 8, 4) + + # Test COPPER25 with gearbox (4 line lanes, 4 system lanes) + with patch('xcvrd.xcvrd_utilities.media_settings_parser.get_media_settings_key', + MagicMock(return_value={'vendor_key': 'TEST-VENDOR', 'media_key': 'TEST-MEDIA', + 'lane_speed_key': 'speed:25G', 'medium_lane_speed_key': 'COPPER25'})): + self._check_notify_media_setting_with_gearbox(1, 4, 4) + + # Test OPTICAL25 with gearbox (4 line lanes, 4 system lanes) + with patch('xcvrd.xcvrd_utilities.media_settings_parser.get_media_settings_key', + MagicMock(return_value={'vendor_key': 'TEST-VENDOR', 'media_key': 'TEST-MEDIA', + 'lane_speed_key': 'speed:25G', 'medium_lane_speed_key': 'OPTICAL25'})): + self._check_notify_media_setting_with_gearbox(1, 4, 4) + def _check_notify_media_setting(self, index, expected_found=False, expected_value=None, xcvr_info_dict=None): xcvr_table_helper = XcvrTableHelper(DEFAULT_NAMESPACE) cfg_port_tbl = MagicMock() @@ -1783,6 +1829,64 @@ def _check_notify_media_setting(self, index, expected_found=False, expected_valu assert found == expected_found assert result_dict == expected_value + def _check_notify_media_setting_with_gearbox(self, index, gearbox_line_lanes, system_lanes, xcvr_info_dict=None): + """ + Helper method to test notify_media_setting with gearbox configuration. + + Args: + index: Physical port index + gearbox_line_lanes: Number of gearbox line lanes + system_lanes: Number of system lanes + xcvr_info_dict: Optional transceiver info dictionary + """ + xcvr_table_helper = XcvrTableHelper(DEFAULT_NAMESPACE) + cfg_port_tbl = MagicMock() + mock_cfg_table = xcvr_table_helper.get_cfg_port_tbl = MagicMock(return_value=cfg_port_tbl) + + logical_port_name = 'Ethernet0' + xcvr_info_dict = { + index: { + 'manufacturer': 'TestVendor', + 'model': 'TestModel', + 'cable_type': 'Length Cable Assembly(m)', + 'cable_length': '1', + 'specification_compliance': "passive_copper_media_interface", + 'type_abbrv_name': 'QSFP-DD' + } + } if xcvr_info_dict is None else xcvr_info_dict + + app_port_tbl = Table("APPL_DB", 'PORT_TABLE') + xcvr_table_helper.get_app_port_tbl = MagicMock(return_value=app_port_tbl) + xcvr_table_helper.is_npu_si_settings_update_required = MagicMock(return_value=True) + + # Mock gearbox_line_lanes_dict to simulate gearbox configuration + gearbox_lanes_dict = {logical_port_name: gearbox_line_lanes} + xcvr_table_helper.get_gearbox_line_lanes_dict = MagicMock(return_value=gearbox_lanes_dict) + + port_mapping = PortMapping() + port_change_event = PortChangeEvent(logical_port_name, index, 0, PortChangeEvent.PORT_ADD) + port_mapping.handle_port_change_event(port_change_event) + + media_settings_parser.notify_media_setting(logical_port_name, xcvr_info_dict, xcvr_table_helper, port_mapping) + + found, result = app_port_tbl.get(logical_port_name) + result_dict = dict(result) if result else None + + # Verify that settings were found + assert found == True + assert result_dict is not None + + # Verify that gearbox line settings have the correct number of lanes + for key in result_dict: + if 'gb_line' in key: + lane_values = result_dict[key].split(',') + assert len(lane_values) == gearbox_line_lanes, \ + f"Expected {gearbox_line_lanes} lanes for {key}, got {len(lane_values)}" + elif 'gb_system' in key: + lane_values = result_dict[key].split(',') + assert len(lane_values) == system_lanes, \ + f"Expected {system_lanes} lanes for {key}, got {len(lane_values)}" + @patch('xcvrd.xcvrd_utilities.optics_si_parser.g_optics_si_dict', optics_si_settings_dict) @patch('xcvrd.xcvrd_utilities.common._wrapper_get_presence', MagicMock(return_value=True)) def test_fetch_optics_si_setting(self): diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py index 2a47566ea..6060eb3f9 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -375,6 +375,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, asic_index = port_mapping.get_asic_id_for_logical_port(logical_port_name) port_speed, lane_count, subport_num = get_speed_lane_count_and_subport(logical_port_name, xcvr_table_helper.get_cfg_port_tbl(asic_index)) + gearbox_lanes_dict = xcvr_table_helper.get_gearbox_line_lanes_dict() ganged_port = False ganged_member_num = 1 @@ -399,7 +400,12 @@ def notify_media_setting(logical_port_name, transceiver_dict, ganged_member_num, ganged_port) ganged_member_num += 1 - key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) + # If the port has a gearbox, then we need to calculate the media settings key based on the number of + # lanes on the line-side of the gearbox + if logical_port_name in gearbox_lanes_dict: + key = get_media_settings_key(physical_port, transceiver_dict, port_speed, gearbox_lanes_dict[logical_port_name]) + else: + key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) helper_logger.log_notice("Retrieving media settings for port {} speed {} num_lanes {}, using key {}".format(logical_port_name, port_speed, lane_count, key)) media_dict = get_media_settings_value(physical_port, key) @@ -410,10 +416,14 @@ def notify_media_setting(logical_port_name, transceiver_dict, fvs = swsscommon.FieldValuePairs(len(media_dict)) index = 0 - helper_logger.log_notice("Publishing ASIC-side SI setting for port {} in APP_DB:".format(logical_port_name)) + helper_logger.log_notice("Publishing SI setting for port {} in APP_DB:".format(logical_port_name)) for media_key in media_dict: if type(media_dict[media_key]) is dict: - val_str = get_serdes_si_setting_val_str(media_dict[media_key], lane_count, subport_num) + if "gb_line" in media_key: + lane_count_si = gearbox_lanes_dict[logical_port_name] + else: + lane_count_si = lane_count + val_str = get_serdes_si_setting_val_str(media_dict[media_key], lane_count_si, subport_num) else: val_str = media_dict[media_key] helper_logger.log_notice("{}:({},{}) ".format(index, str(media_key), str(val_str))) @@ -422,5 +432,5 @@ def notify_media_setting(logical_port_name, transceiver_dict, xcvr_table_helper.get_app_port_tbl(asic_index).set(port_name, fvs) xcvr_table_helper.get_state_port_tbl(asic_index).set(logical_port_name, [(NPU_SI_SETTINGS_SYNC_STATUS_KEY, NPU_SI_SETTINGS_NOTIFIED_VALUE)]) - helper_logger.log_notice("Notify media setting: Published ASIC-side SI setting " + helper_logger.log_notice("Notify media setting: Published SI setting " "for lport {} in APP_DB".format(logical_port_name))