From ba78303489b9d73e71be6216e1102148d2b2dac5 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Mon, 11 Sep 2023 07:24:16 +0000 Subject: [PATCH 01/39] xcvrd changes to configure modules with logs --- sonic-xcvrd/xcvrd/xcvrd.py | 463 +++++++++++++++++++++++++++++++++++-- 1 file changed, 446 insertions(+), 17 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index ab06b9ab1..059609602 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -28,6 +28,11 @@ from .xcvrd_utilities import sfp_status_helper from .xcvrd_utilities import port_mapping from .xcvrd_utilities import optics_si_parser + + + from sonic_platform_base.sonic_xcvr.api.public.c_cmis import CmisApi + + except ImportError as e: raise ImportError(str(e) + " - required module not found") @@ -94,6 +99,12 @@ # Global chassis object based on new platform api platform_chassis = None + + +SI_PER_SPEED_INDICATION_STR = "speed:" + + + # Global logger instance for helper functions and classes # TODO: Refactor so that we only need the logger inherited # by DaemonXcvrd @@ -103,6 +114,156 @@ # Helper functions ============================================================= # + + + + +#TODO: remove this function. It is duplicated from CMIS thread +def get_cmis_application_desired(api, host_lane_count, speed): + """ + Get the CMIS application code that matches the specified host side configurations + + Args: + api: + XcvrApi object + host_lane_count: + Number of lanes on the host side + speed: + Integer, the port speed of the host interface + + Returns: + Integer, the transceiver-specific application code + """ + + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: api = {api}") + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(api) = {type(api)}") + # (api.split('.'[-1])).split()[0] + + app_found = False + + if speed == 0 or host_lane_count == 0: + return 0 + + appl_code = 0 + # if api == sonic_platform_base.sonic_xcvr.api.public.c_cmis.CmisApi: + if type(api) == CmisApi: + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: inside if type(api) == CmisApi") + appl_dict = api.get_application_advertisement() + helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: appl_dict == {appl_dict}") + for c in appl_dict.keys(): + helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: c == {c}") + d = appl_dict[c] + helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: d == {d}") + + helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: d.lane_count = {d.get('host_lane_count')} ~~~ lane_count = {host_lane_count}") + helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: d.speed = {get_interface_speed(d.get('host_electrical_interface_id'))} ~~~ speed = {speed}") + + if d.get('host_lane_count') != host_lane_count: + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: inside if d.get('host_lane_count') != host_lane_count") + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(get_interface_speed(d.get('host_electrical_interface_id'))) = {type(get_interface_speed(d.get('host_electrical_interface_id')))}") + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(speed) = {type(speed)}") + continue + if get_interface_speed(d.get('host_electrical_interface_id')) != speed: + helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: inside if get_interface_speed(d.get('host_electrical_interface_id')) != speed") + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(get_interface_speed(d.get('host_electrical_interface_id'))) = {type(get_interface_speed(d.get('host_electrical_interface_id')))}") + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(speed) = {type(speed)}") + continue + helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: found something") + appl_code = c + app_found = True + + result_index = appl_code & 0xf + # helper_logger.log_error(f"---- tomer2 ---- get_cmis_application_desired: result_index = {result_index}") + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: appl_dict[result_index] = {appl_dict[result_index]}") + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: appl_dict[result_index]['host_electrical_interface_id'] = {appl_dict[result_index]['host_electrical_interface_id']}") + + + # helper_logger.log_error(f"---- tomer2 ---- get_cmis_application_desired: appl_dict[result_index] = {appl_dict[result_index]}") + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: gaui_key_returned = {appl_dict[result_index].get('host_lane_count')}") + # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: gaui_key_returned = {appl_dict[result_index].get('host_lane_count')}") + + helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: gaui_key_returned = {appl_dict[result_index].get('host_electrical_interface_id')}") + break + + if app_found: + return (appl_code & 0xf) + + return None + + +# #TODO: remove this function. It is duplicated from CMIS thread +# def get_cmis_application_desired(api, host_lane_count, speed): +# """ +# Get the CMIS application code that matches the specified host side configurations + +# Args: +# api: +# XcvrApi object +# host_lane_count: +# Number of lanes on the host side +# speed: +# Integer, the port speed of the host interface + +# Returns: +# Integer, the transceiver-specific application code +# """ + +# if speed == 0 or host_lane_count == 0: +# return 0 + +# appl_code = 0 +# if type(api) == CmisApi: +# appl_dict = api.get_application_advertisement() +# for c in appl_dict.keys(): +# d = appl_dict[c] +# if d.get('host_lane_count') != host_lane_count: +# continue +# if get_interface_speed(d.get('host_electrical_interface_id')) != speed: +# continue +# appl_code = c +# break + +# return (appl_code & 0xf) + +# return None + +#TODO: remove this function. It is duplicated from CMIS thread +def get_interface_speed(ifname): + """ + Get the port speed from the host interface name + + Args: + ifname: String, interface name + + Returns: + Integer, the port speed if success otherwise 0 + """ + # see HOST_ELECTRICAL_INTERFACE of sff8024.py + speed = 0 + if '400G' in ifname: + speed = 400000 + elif '200G' in ifname: + speed = 200000 + elif '100G' in ifname or 'CAUI-4' in ifname: + speed = 100000 + elif '50G' in ifname or 'LAUI-2' in ifname: + speed = 50000 + elif '40G' in ifname or 'XLAUI' in ifname or 'XLPPI' in ifname: + speed = 40000 + elif '25G' in ifname: + speed = 25000 + elif '10G' in ifname or 'SFI' in ifname or 'XFI' in ifname: + speed = 10000 + elif '1000BASE' in ifname: + speed = 1000 + return speed + + + + + + + # Get physical port name @@ -576,6 +737,129 @@ def check_port_in_range(range_str, physical_port): return False + + +# original +# def get_media_settings_value(physical_port, key): +# GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' +# PORT_MEDIA_SETTINGS_KEY = 'PORT_MEDIA_SETTINGS' +# DEFAULT_KEY = 'Default' +# RANGE_SEPARATOR = '-' +# COMMA_SEPARATOR = ',' +# media_dict = {} +# default_dict = {} +# # Keys under global media settings can be a list or range or list of ranges +# # of physical port numbers. Below are some examples +# # 1-32 +# # 1,2,3,4,5 +# # 1-4,9-12 +# if GLOBAL_MEDIA_SETTINGS_KEY in g_dict: +# for keys in g_dict[GLOBAL_MEDIA_SETTINGS_KEY]: +# if COMMA_SEPARATOR in keys: +# port_list = keys.split(COMMA_SEPARATOR) +# for port in port_list: +# if RANGE_SEPARATOR in port: +# if check_port_in_range(port, physical_port): +# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] +# break +# elif str(physical_port) == port: +# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] +# break +# elif RANGE_SEPARATOR in keys: +# if check_port_in_range(keys, physical_port): +# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] +# # If there is a match in the global profile for a media type, +# # fetch those values +# if key[0] in media_dict: +# return media_dict[key[0]] +# elif key[1] in media_dict: +# return media_dict[key[1]] +# elif DEFAULT_KEY in media_dict: +# default_dict = media_dict[DEFAULT_KEY] +# media_dict = {} +# if PORT_MEDIA_SETTINGS_KEY in g_dict: +# for keys in g_dict[PORT_MEDIA_SETTINGS_KEY]: +# if int(keys) == physical_port: +# media_dict = g_dict[PORT_MEDIA_SETTINGS_KEY][keys] +# break +# if len(media_dict) == 0: +# if len(default_dict) != 0: +# return default_dict +# else: +# helper_logger.log_error("Error: No values for physical port '{}'".format(physical_port)) +# return {} +# if key[0] in media_dict: +# return media_dict[key[0]] +# elif key[1] in media_dict: +# return media_dict[key[1]] +# elif DEFAULT_KEY in media_dict: +# return media_dict[DEFAULT_KEY] +# elif len(default_dict) != 0: +# return default_dict +# else: +# if len(default_dict) != 0: +# return default_dict +# return {} + + +def is_si_per_speed_supported(media_dict): + #SI_PER_SPEED_INDICATION_STR = "speed:" + return SI_PER_SPEED_INDICATION_STR in list(media_dict.keys())[0] + + +# Before session with Prince # TODO: delete +# def get_media_settings_value(physical_port, key): +# GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' +# PORT_MEDIA_SETTINGS_KEY = 'PORT_MEDIA_SETTINGS' +# DEFAULT_KEY = 'Default' +# RANGE_SEPARATOR = '-' +# COMMA_SEPARATOR = ',' +# media_dict = {} +# default_dict = {} +# # Keys under global media settings can be a list or range or list of ranges +# # of physical port numbers. Below are some examples +# # 1-32 +# # 1,2,3,4,5 +# # 1-4,9-12 +# if GLOBAL_MEDIA_SETTINGS_KEY in g_dict: +# for keys in g_dict[GLOBAL_MEDIA_SETTINGS_KEY]: +# if COMMA_SEPARATOR in keys: +# port_list = keys.split(COMMA_SEPARATOR) +# for port in port_list: +# if RANGE_SEPARATOR in port: +# if check_port_in_range(port, physical_port): +# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] +# break +# elif str(physical_port) == port: +# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] +# break +# elif RANGE_SEPARATOR in keys: +# if check_port_in_range(keys, physical_port): +# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] +# # If there is a match in the global profile for a media type, +# # fetch those values +# if key[0] in media_dict: +# return media_dict[key[0]] +# elif key[1] in media_dict: +# if is_si_per_speed_supported(media_dict[key[1]]): +# if key[2] in media_dict[key[1]]: +# return media_dict[key[1]][key[2]] +# else: +# return {} +# else: +# return media_dict[key[1]] +# elif DEFAULT_KEY in media_dict: + + + + + + + + + + + def get_media_settings_value(physical_port, key): GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' PORT_MEDIA_SETTINGS_KEY = 'PORT_MEDIA_SETTINGS' @@ -611,11 +895,21 @@ def get_media_settings_value(physical_port, key): # If there is a match in the global profile for a media type, # fetch those values if key[0] in media_dict: - return media_dict[key[0]] - elif key[0].split('-')[0] in media_dict: - return media_dict[key[0].split('-')[0]] + if is_si_per_speed_supported(media_dict[key[0]]): + if key[2] in media_dict[key[0]]: + return media_dict[key[0]][key[2]] + else: + return {} + else: + return media_dict[key[0]] elif key[1] in media_dict: - return media_dict[key[1]] + if is_si_per_speed_supported(media_dict[key[1]]): + if key[2] in media_dict[key[1]]: + return media_dict[key[1]][key[2]] + else: + return {} + else: + return media_dict[key[1]] elif DEFAULT_KEY in media_dict: default_dict = media_dict[DEFAULT_KEY] @@ -631,15 +925,25 @@ def get_media_settings_value(physical_port, key): if len(default_dict) != 0: return default_dict else: - helper_logger.log_error("Error: No values for physical port '{}'".format(physical_port)) + print("Error: No values for physical port '{}'".format(physical_port)) return {} if key[0] in media_dict: - return media_dict[key[0]] - elif key[0].split('-')[0] in media_dict: - return media_dict[key[0].split('-')[0]] + if is_si_per_speed_supported(media_dict[key[0]]): + if key[2] in media_dict[key[0]]: + return media_dict[key[0]][key[2]] + else: + return {} + else: + return media_dict[key[0]] elif key[1] in media_dict: - return media_dict[key[1]] + if is_si_per_speed_supported(media_dict[key[1]]): + if key[2] in media_dict[key[1]]: + return media_dict[key[1]][key[2]] + else: + return {} + else: + return media_dict[key[1]] elif DEFAULT_KEY in media_dict: return media_dict[DEFAULT_KEY] elif len(default_dict) != 0: @@ -651,7 +955,41 @@ def get_media_settings_value(physical_port, key): return {} -def get_media_settings_key(physical_port, transceiver_dict): + + + + +def get_speed_and_lane_count(port, cfg_port_tbl): + port_speed, lane_count = -1, -1 + found, port_info = cfg_port_tbl.get(port) + if found and 'speed' in dict(port_info) and 'lanes' in dict(port_info): + port_speed = dict(port_info).get('speed', '-1') + lanes = dict(port_info).get('lanes', '-1') + lane_count = len(lanes.split(',')) + return port_speed, lane_count + +def get_gaui_key(physical_port, port_speed, lane_count): + sfp = platform_chassis.get_sfp(physical_port) + api = sfp.get_xcvr_api() + speed_index = get_cmis_application_desired(api, int(lane_count), int(port_speed)) + + appl_dict = None + #TODO: instead of this neted if, just initialize gaui_key with None at the begining + #TODO: rename gaui_key to lane_speed_key + if type(api) == CmisApi: + appl_dict = api.get_application_advertisement() + helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {physical_port} ---> appl_dict = {appl_dict}") + if speed_index is None: + gaui_key = None + else: + gaui_key = SI_PER_SPEED_INDICATION_STR + (appl_dict[speed_index].get('host_electrical_interface_id')).split()[0] + else: + gaui_key = None + return gaui_key + + + +def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count): sup_compliance_str = '10/40G Ethernet Compliance Code' sup_len_str = 'Length Cable Assembly(m)' vendor_name_str = transceiver_dict[physical_port]['manufacturer'] @@ -694,7 +1032,22 @@ def get_media_settings_key(physical_port, transceiver_dict): else: media_key += '-' + '*' - return [vendor_key, media_key] + + gaui_key = get_gaui_key(physical_port, port_speed, lane_count) + + return [vendor_key, media_key, gaui_key] + + + + + + + + + + + + def get_media_val_str_from_dict(media_dict): LANE_STR = 'lane' @@ -740,9 +1093,34 @@ def get_media_val_str(num_logical_ports, lane_dict, logical_idx): return media_val_str + + + def notify_media_setting(logical_port_name, transceiver_dict, - app_port_tbl, port_mapping): + app_port_tbl, cfg_port_tbl, port_mapping): + + + + helper_logger.log_error(f"---- tomer ---- notify_media_setting(): entered notify_media_setting()") + + + helper_logger.log_error(f"---- tomer ---- notify_media_setting(): logical_port_name = {logical_port_name}") + + # port_speed, lane_count = -1, -1 + # found, port_info = cfg_port_tbl.get(logical_port_name) + # if found and 'speed' in dict(port_info) and 'lanes' in dict(port_info): + # port_speed = dict(port_info).get('speed', '-1') + # lanes = dict(port_info).get('lanes', '-1') + # lane_count = len(lanes.split(',')) + port_speed, lane_count = get_speed_and_lane_count(logical_port_name, cfg_port_tbl) + + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): port_speed = {port_speed}") + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): lane_count = {lane_count}") + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): lanes = {lanes}") + + if not g_dict: + helper_logger.log_error(f"---- tomer ---- g_dict is None") return ganged_port = False @@ -750,6 +1128,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, physical_port_list = port_mapping.logical_port_name_to_physical_port_list(logical_port_name) if physical_port_list is None: + helper_logger.log_error(f"---- tomer ---- notify_media_setting(): No physical ports found for logical port {logical_port_name}") helper_logger.log_error("Error: No physical ports found for logical port '{}'".format(logical_port_name)) return PHYSICAL_PORT_NOT_EXIST @@ -757,6 +1136,35 @@ def notify_media_setting(logical_port_name, transceiver_dict, ganged_port = True for physical_port in physical_port_list: + + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): inside loop: physical_port = {physical_port}") + # sfp = platform_chassis.get_sfp(physical_port) + # api = sfp.get_xcvr_api() + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> api = {api}") + + # speed_index = get_cmis_application_desired(api, int(lane_count), int(port_speed)) + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> final speed_index = {speed_index}") + + # appl_dict = None + # if type(api) == CmisApi: + # appl_dict = api.get_application_advertisement() + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> appl_dict = {appl_dict}") + # if speed_index is None: + # gaui_key = None + # else: + # gaui_key = (appl_dict[speed_index].get('host_electrical_interface_id')).split()[0] + # else: + # gaui_key = None + + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> final gaui_key = {gaui_key}") + + # gaui_from_fnction = get_gaui_key(physical_port, port_speed, lane_count) + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> final gaui_key from function = {gaui_from_fnction}") + + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") + + + logical_port_list = port_mapping.get_physical_to_logical(physical_port) num_logical_ports = len(logical_port_list) logical_idx = logical_port_list.index(logical_port_name) @@ -769,9 +1177,19 @@ def notify_media_setting(logical_port_name, transceiver_dict, port_name = get_physical_port_name(logical_port_name, ganged_member_num, ganged_port) + + helper_logger.log_error(f"---- tomer ---- notify_media_setting(): physical port_name = {port_name}") + ganged_member_num += 1 - key = get_media_settings_key(physical_port, transceiver_dict) + + key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) + helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} ---> whole_key = {key}") media_dict = get_media_settings_value(physical_port, key) + helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} ---> whole_value = {media_dict}") + + # helper_logger.log_error(f"---- tomer ---- key = {key}") + # helper_logger.log_error(f"---- tomer ---- value = {media_dict}") + if len(media_dict) == 0: helper_logger.log_error("Error in obtaining media setting for {}".format(logical_port_name)) @@ -790,9 +1208,18 @@ def notify_media_setting(logical_port_name, transceiver_dict, fvs[index] = (str(media_key), str(media_val_str)) index += 1 + + # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): ~~~~ writing pair to APP_DB: ~~~~ {port_name} --> {fvs.fv_dict}") + app_port_tbl.set(port_name, fvs) + + + + + + def waiting_time_compensation_with_sleep(time_start, time_to_wait): time_now = time.time() time_diff = time_now - time_start @@ -1919,7 +2346,7 @@ def _post_port_sfp_info_and_dom_thr_to_db_once(self, port_mapping, xcvr_table_he # Do not notify media settings during warm reboot to avoid dataplane traffic impact if is_warm_start == False: - notify_media_setting(logical_port_name, transceiver_dict, xcvr_table_helper.get_app_port_tbl(asic_index), port_mapping) + notify_media_setting(logical_port_name, transceiver_dict, xcvr_table_helper.get_app_port_tbl(asic_index), xcvr_table_helper.get_cfg_port_tbl(asic_index), port_mapping) transceiver_dict.clear() else: retry_eeprom_set.add(logical_port_name) @@ -2141,7 +2568,7 @@ def task_worker(self, stopping_event, sfp_error_event): if rc != SFP_EEPROM_NOT_READY: post_port_dom_threshold_info_to_db(logical_port, self.port_mapping, self.xcvr_table_helper.get_dom_threshold_tbl(asic_index)) - notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.port_mapping) + notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) transceiver_dict.clear() elif value == sfp_status_helper.SFP_STATUS_REMOVED: helper_logger.log_notice("{}: Got SFP removed event".format(logical_port)) @@ -2340,7 +2767,8 @@ def on_add_logical_port(self, port_change_event): self.retry_eeprom_set.add(port_change_event.port_name) else: post_port_dom_threshold_info_to_db(port_change_event.port_name, self.port_mapping, dom_threshold_tbl) - notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.port_mapping) + notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) + #notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.port_mapping) else: status = sfp_status_helper.SFP_STATUS_REMOVED if not status else status update_port_transceiver_status_table_sw(port_change_event.port_name, status_tbl, status, error_description) @@ -2366,7 +2794,8 @@ def retry_eeprom_reading(self): rc = post_port_sfp_info_to_db(logical_port, self.port_mapping, self.xcvr_table_helper.get_intf_tbl(asic_index), transceiver_dict) if rc != SFP_EEPROM_NOT_READY: post_port_dom_threshold_info_to_db(logical_port, self.port_mapping, self.xcvr_table_helper.get_dom_threshold_tbl(asic_index)) - notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.port_mapping) + # notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.port_mapping) + notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) transceiver_dict.clear() retry_success_set.add(logical_port) # Update retry EEPROM set From f0f0489ddcc2d2fd8a0abbfdbcc999a7a272ebeb Mon Sep 17 00:00:00 2001 From: tshalvi Date: Mon, 18 Sep 2023 16:16:23 +0000 Subject: [PATCH 02/39] sonic-platform-daemons changes before moving to combined codebase --- sonic-xcvrd/tests/optics_si_settings.json | 437 +++++++++--------- sonic-xcvrd/tests/test_xcvrd.py | 1 + sonic-xcvrd/xcvrd/xcvrd.py | 63 ++- .../xcvrd/xcvrd_utilities/optics_si_parser.py | 4 + 4 files changed, 276 insertions(+), 229 deletions(-) diff --git a/sonic-xcvrd/tests/optics_si_settings.json b/sonic-xcvrd/tests/optics_si_settings.json index 2b9defc81..295bb7a69 100644 --- a/sonic-xcvrd/tests/optics_si_settings.json +++ b/sonic-xcvrd/tests/optics_si_settings.json @@ -1,222 +1,223 @@ { - "GLOBAL_MEDIA_SETTINGS":{ - "0-31":{ - "100G_SPEED":{ - "CREDO-CAC82X321M2MC0HW":{ - "OutputEqPreCursorTargetRx":{ - "OutputEqPreCursorTargetRx1":3, - "OutputEqPreCursorTargetRx2":3, - "OutputEqPreCursorTargetRx3":3, - "OutputEqPreCursorTargetRx4":3, - "OutputEqPreCursorTargetRx5":3, - "OutputEqPreCursorTargetRx6":3, - "OutputEqPreCursorTargetRx7":3, - "OutputEqPreCursorTargetRx8":3 - }, - "OutputEqPostCursorTargetRx":{ - "OutputEqPostCursorTargetRx1":0, - "OutputEqPostCursorTargetRx2":0, - "OutputEqPostCursorTargetRx3":0, - "OutputEqPostCursorTargetRx4":0, - "OutputEqPostCursorTargetRx5":0, - "OutputEqPostCursorTargetRx6":0, - "OutputEqPostCursorTargetRx7":0, - "OutputEqPostCursorTargetRx8":0 - }, - "OutputAmplitudeTargetRx":{ - "OutputAmplitudeTargetRx1":0, - "OutputAmplitudeTargetRx2":0, - "OutputAmplitudeTargetRx3":0, - "OutputAmplitudeTargetRx4":0, - "OutputAmplitudeTargetRx5":0, - "OutputAmplitudeTargetRx6":0, - "OutputAmplitudeTargetRx7":0, - "OutputAmplitudeTargetRx8":0 - } - } - } + "GLOBAL_MEDIA_SETTINGS": { + "0-31": { + "50G_SPEED": { + "Default": { + "OutputEqPreCursorTargetRx": { + "OutputEqPreCursorTargetRx1": 0, + "OutputEqPreCursorTargetRx2": 0, + "OutputEqPreCursorTargetRx3": 0, + "OutputEqPreCursorTargetRx4": 0, + "OutputEqPreCursorTargetRx5": 0, + "OutputEqPreCursorTargetRx6": 0, + "OutputEqPreCursorTargetRx7": 0, + "OutputEqPreCursorTargetRx8": 0 + }, + "OutputEqPostCursorTargetRx": { + "OutputEqPostCursorTargetRx1": 0, + "OutputEqPostCursorTargetRx2": 0, + "OutputEqPostCursorTargetRx3": 0, + "OutputEqPostCursorTargetRx4": 0, + "OutputEqPostCursorTargetRx5": 0, + "OutputEqPostCursorTargetRx6": 0, + "OutputEqPostCursorTargetRx7": 0, + "OutputEqPostCursorTargetRx8": 0 + }, + "OutputAmplitudeTargetRx": { + "OutputAmplitudeTargetRx1":0, + "OutputAmplitudeTargetRx2":0, + "OutputAmplitudeTargetRx3":0, + "OutputAmplitudeTargetRx4":0, + "OutputAmplitudeTargetRx5":0, + "OutputAmplitudeTargetRx6":0, + "OutputAmplitudeTargetRx7":0, + "OutputAmplitudeTargetRx8":0 + } + } } - }, - "PORT_MEDIA_SETTINGS":{ - "0":{ - "100G_SPEED":{ - "CREDO-CAC82X321M2MC0HW":{ - "OutputEqPreCursorTargetRx":{ - "OutputEqPreCursorTargetRx1":3, - "OutputEqPreCursorTargetRx2":3, - "OutputEqPreCursorTargetRx3":3, - "OutputEqPreCursorTargetRx4":3, - "OutputEqPreCursorTargetRx5":3, - "OutputEqPreCursorTargetRx6":3, - "OutputEqPreCursorTargetRx7":3, - "OutputEqPreCursorTargetRx8":3 - }, - "OutputEqPostCursorTargetRx":{ - "OutputEqPostCursorTargetRx1":0, - "OutputEqPostCursorTargetRx2":0, - "OutputEqPostCursorTargetRx3":0, - "OutputEqPostCursorTargetRx4":0, - "OutputEqPostCursorTargetRx5":0, - "OutputEqPostCursorTargetRx6":0, - "OutputEqPostCursorTargetRx7":0, - "OutputEqPostCursorTargetRx8":0 - }, - "OutputAmplitudeTargetRx":{ - "OutputAmplitudeTargetRx1":0, - "OutputAmplitudeTargetRx2":0, - "OutputAmplitudeTargetRx3":0, - "OutputAmplitudeTargetRx4":0, - "OutputAmplitudeTargetRx5":0, - "OutputAmplitudeTargetRx6":0, - "OutputAmplitudeTargetRx7":0, - "OutputAmplitudeTargetRx8":0 - } - } - } - }, - "1":{ - "100G_SPEED":{ - "Default":{ - "OutputEqPreCursorTargetRx":{ - "OutputEqPreCursorTargetRx1":3, - "OutputEqPreCursorTargetRx2":3, - "OutputEqPreCursorTargetRx3":3, - "OutputEqPreCursorTargetRx4":3, - "OutputEqPreCursorTargetRx5":3, - "OutputEqPreCursorTargetRx6":3, - "OutputEqPreCursorTargetRx7":3, - "OutputEqPreCursorTargetRx8":3 - }, - "OutputEqPostCursorTargetRx":{ - "OutputEqPostCursorTargetRx1":0, - "OutputEqPostCursorTargetRx2":0, - "OutputEqPostCursorTargetRx3":0, - "OutputEqPostCursorTargetRx4":0, - "OutputEqPostCursorTargetRx5":0, - "OutputEqPostCursorTargetRx6":0, - "OutputEqPostCursorTargetRx7":0, - "OutputEqPostCursorTargetRx8":0 - }, - "OutputAmplitudeTargetRx":{ - "OutputAmplitudeTargetRx1":1, - "OutputAmplitudeTargetRx2":1, - "OutputAmplitudeTargetRx3":1, - "OutputAmplitudeTargetRx4":1, - "OutputAmplitudeTargetRx5":1, - "OutputAmplitudeTargetRx6":1, - "OutputAmplitudeTargetRx7":1, - "OutputAmplitudeTargetRx8":1 - } - } - } - }, - "10":{ - "100G_SPEED":{ - "Default":{ - "OutputEqPreCursorTargetRx":{ - "OutputEqPreCursorTargetRx1":3, - "OutputEqPreCursorTargetRx2":3, - "OutputEqPreCursorTargetRx3":3, - "OutputEqPreCursorTargetRx4":3, - "OutputEqPreCursorTargetRx5":3, - "OutputEqPreCursorTargetRx6":3, - "OutputEqPreCursorTargetRx7":3, - "OutputEqPreCursorTargetRx8":3 - }, - "OutputEqPostCursorTargetRx":{ - "OutputEqPostCursorTargetRx1":0, - "OutputEqPostCursorTargetRx2":0, - "OutputEqPostCursorTargetRx3":0, - "OutputEqPostCursorTargetRx4":0, - "OutputEqPostCursorTargetRx5":0, - "OutputEqPostCursorTargetRx6":0, - "OutputEqPostCursorTargetRx7":0, - "OutputEqPostCursorTargetRx8":0 - }, - "OutputAmplitudeTargetRx":{ - "OutputAmplitudeTargetRx1":1, - "OutputAmplitudeTargetRx2":1, - "OutputAmplitudeTargetRx3":1, - "OutputAmplitudeTargetRx4":1, - "OutputAmplitudeTargetRx5":1, - "OutputAmplitudeTargetRx6":1, - "OutputAmplitudeTargetRx7":1, - "OutputAmplitudeTargetRx8":1 - } - } - } - }, - "11":{ - "100G_SPEED":{ - "Default":{ - "OutputEqPreCursorTargetRx":{ - "OutputEqPreCursorTargetRx1":3, - "OutputEqPreCursorTargetRx2":3, - "OutputEqPreCursorTargetRx3":3, - "OutputEqPreCursorTargetRx4":3, - "OutputEqPreCursorTargetRx5":3, - "OutputEqPreCursorTargetRx6":3, - "OutputEqPreCursorTargetRx7":3, - "OutputEqPreCursorTargetRx8":3 - }, - "OutputEqPostCursorTargetRx":{ - "OutputEqPostCursorTargetRx1":0, - "OutputEqPostCursorTargetRx2":0, - "OutputEqPostCursorTargetRx3":0, - "OutputEqPostCursorTargetRx4":0, - "OutputEqPostCursorTargetRx5":0, - "OutputEqPostCursorTargetRx6":0, - "OutputEqPostCursorTargetRx7":0, - "OutputEqPostCursorTargetRx8":0 - }, - "OutputAmplitudeTargetRx":{ - "OutputAmplitudeTargetRx1":1, - "OutputAmplitudeTargetRx2":1, - "OutputAmplitudeTargetRx3":1, - "OutputAmplitudeTargetRx4":1, - "OutputAmplitudeTargetRx5":1, - "OutputAmplitudeTargetRx6":1, - "OutputAmplitudeTargetRx7":1, - "OutputAmplitudeTargetRx8":1 - } - } - } - }, - "12":{ - "100G_SPEED":{ - "Default":{ - "OutputEqPreCursorTargetRx":{ - "OutputEqPreCursorTargetRx1":3, - "OutputEqPreCursorTargetRx2":3, - "OutputEqPreCursorTargetRx3":3, - "OutputEqPreCursorTargetRx4":3, - "OutputEqPreCursorTargetRx5":3, - "OutputEqPreCursorTargetRx6":3, - "OutputEqPreCursorTargetRx7":3, - "OutputEqPreCursorTargetRx8":3 - }, - "OutputEqPostCursorTargetRx":{ - "OutputEqPostCursorTargetRx1":0, - "OutputEqPostCursorTargetRx2":0, - "OutputEqPostCursorTargetRx3":0, - "OutputEqPostCursorTargetRx4":0, - "OutputEqPostCursorTargetRx5":0, - "OutputEqPostCursorTargetRx6":0, - "OutputEqPostCursorTargetRx7":0, - "OutputEqPostCursorTargetRx8":0 - }, - "OutputAmplitudeTargetRx":{ - "OutputAmplitudeTargetRx1":1, - "OutputAmplitudeTargetRx2":1, - "OutputAmplitudeTargetRx3":1, - "OutputAmplitudeTargetRx4":1, - "OutputAmplitudeTargetRx5":1, - "OutputAmplitudeTargetRx6":1, - "OutputAmplitudeTargetRx7":1, - "OutputAmplitudeTargetRx8":1 - } - } - } + } + }, + "PORT_MEDIA_SETTINGS": { + "0": { + "50G_SPEED": { + "Default": { + "OutputEqPreCursorTargetRx": { + "OutputEqPreCursorTargetRx1": 3, + "OutputEqPreCursorTargetRx2": 3, + "OutputEqPreCursorTargetRx3": 3, + "OutputEqPreCursorTargetRx4": 3, + "OutputEqPreCursorTargetRx5": 3, + "OutputEqPreCursorTargetRx6": 3, + "OutputEqPreCursorTargetRx7": 3, + "OutputEqPreCursorTargetRx8": 3 + }, + "OutputEqPostCursorTargetRx": { + "OutputEqPostCursorTargetRx1": 0, + "OutputEqPostCursorTargetRx2": 0, + "OutputEqPostCursorTargetRx3": 0, + "OutputEqPostCursorTargetRx4": 0, + "OutputEqPostCursorTargetRx5": 0, + "OutputEqPostCursorTargetRx6": 0, + "OutputEqPostCursorTargetRx7": 0, + "OutputEqPostCursorTargetRx8": 0 + }, + "OutputAmplitudeTargetRx": { + "OutputAmplitudeTargetRx1": 0, + "OutputAmplitudeTargetRx2": 0, + "OutputAmplitudeTargetRx3": 0, + "OutputAmplitudeTargetRx4": 0, + "OutputAmplitudeTargetRx5": 0, + "OutputAmplitudeTargetRx6": 0, + "OutputAmplitudeTargetRx7": 0, + "OutputAmplitudeTargetRx8": 0 + } + } } - } + }, + "1": { + "50G_SPEED": { + "Default": { + "OutputEqPreCursorTargetRx": { + "OutputEqPreCursorTargetRx1": 3, + "OutputEqPreCursorTargetRx2": 3, + "OutputEqPreCursorTargetRx3": 3, + "OutputEqPreCursorTargetRx4": 3, + "OutputEqPreCursorTargetRx5": 3, + "OutputEqPreCursorTargetRx6": 3, + "OutputEqPreCursorTargetRx7": 3, + "OutputEqPreCursorTargetRx8": 3 + }, + "OutputEqPostCursorTargetRx": { + "OutputEqPostCursorTargetRx1": 0, + "OutputEqPostCursorTargetRx2": 0, + "OutputEqPostCursorTargetRx3": 0, + "OutputEqPostCursorTargetRx4": 0, + "OutputEqPostCursorTargetRx5": 0, + "OutputEqPostCursorTargetRx6": 0, + "OutputEqPostCursorTargetRx7": 0, + "OutputEqPostCursorTargetRx8": 0 + }, + "OutputAmplitudeTargetRx": { + "OutputAmplitudeTargetRx1": 1, + "OutputAmplitudeTargetRx2": 1, + "OutputAmplitudeTargetRx3": 1, + "OutputAmplitudeTargetRx4": 1, + "OutputAmplitudeTargetRx5": 1, + "OutputAmplitudeTargetRx6": 1, + "OutputAmplitudeTargetRx7": 1, + "OutputAmplitudeTargetRx8": 1 + } + } + } + }, + "10": { + "50G_SPEED": { + "Default": { + "OutputEqPreCursorTargetRx": { + "OutputEqPreCursorTargetRx1": 3, + "OutputEqPreCursorTargetRx2": 3, + "OutputEqPreCursorTargetRx3": 3, + "OutputEqPreCursorTargetRx4": 3, + "OutputEqPreCursorTargetRx5": 3, + "OutputEqPreCursorTargetRx6": 3, + "OutputEqPreCursorTargetRx7": 3, + "OutputEqPreCursorTargetRx8": 3 + }, + "OutputEqPostCursorTargetRx": { + "OutputEqPostCursorTargetRx1": 0, + "OutputEqPostCursorTargetRx2": 0, + "OutputEqPostCursorTargetRx3": 0, + "OutputEqPostCursorTargetRx4": 0, + "OutputEqPostCursorTargetRx5": 0, + "OutputEqPostCursorTargetRx6": 0, + "OutputEqPostCursorTargetRx7": 0, + "OutputEqPostCursorTargetRx8": 0 + }, + "OutputAmplitudeTargetRx": { + "OutputAmplitudeTargetRx1": 1, + "OutputAmplitudeTargetRx2": 1, + "OutputAmplitudeTargetRx3": 1, + "OutputAmplitudeTargetRx4": 1, + "OutputAmplitudeTargetRx5": 1, + "OutputAmplitudeTargetRx6": 1, + "OutputAmplitudeTargetRx7": 1, + "OutputAmplitudeTargetRx8": 1 + } + } + } + }, + "11": { + "50G_SPEED": { + "Default": { + "OutputEqPreCursorTargetRx": { + "OutputEqPreCursorTargetRx1": 3, + "OutputEqPreCursorTargetRx2": 3, + "OutputEqPreCursorTargetRx3": 3, + "OutputEqPreCursorTargetRx4": 3, + "OutputEqPreCursorTargetRx5": 3, + "OutputEqPreCursorTargetRx6": 3, + "OutputEqPreCursorTargetRx7": 3, + "OutputEqPreCursorTargetRx8": 3 + }, + "OutputEqPostCursorTargetRx": { + "OutputEqPostCursorTargetRx1": 0, + "OutputEqPostCursorTargetRx2": 0, + "OutputEqPostCursorTargetRx3": 0, + "OutputEqPostCursorTargetRx4": 0, + "OutputEqPostCursorTargetRx5": 0, + "OutputEqPostCursorTargetRx6": 0, + "OutputEqPostCursorTargetRx7": 0, + "OutputEqPostCursorTargetRx8": 0 + }, + "OutputAmplitudeTargetRx": { + "OutputAmplitudeTargetRx1": 1, + "OutputAmplitudeTargetRx2": 1, + "OutputAmplitudeTargetRx3": 1, + "OutputAmplitudeTargetRx4": 1, + "OutputAmplitudeTargetRx5": 1, + "OutputAmplitudeTargetRx6": 1, + "OutputAmplitudeTargetRx7": 1, + "OutputAmplitudeTargetRx8": 1 + } + } + } + }, + "12": { + "50G_SPEED": { + "Default": { + "OutputEqPreCursorTargetRx": { + "OutputEqPreCursorTargetRx1": 3, + "OutputEqPreCursorTargetRx2": 3, + "OutputEqPreCursorTargetRx3": 3, + "OutputEqPreCursorTargetRx4": 3, + "OutputEqPreCursorTargetRx5": 3, + "OutputEqPreCursorTargetRx6": 3, + "OutputEqPreCursorTargetRx7": 3, + "OutputEqPreCursorTargetRx8": 3 + }, + "OutputEqPostCursorTargetRx": { + "OutputEqPostCursorTargetRx1": 0, + "OutputEqPostCursorTargetRx2": 0, + "OutputEqPostCursorTargetRx3": 0, + "OutputEqPostCursorTargetRx4": 0, + "OutputEqPostCursorTargetRx5": 0, + "OutputEqPostCursorTargetRx6": 0, + "OutputEqPostCursorTargetRx7": 0, + "OutputEqPostCursorTargetRx8": 0 + }, + "OutputAmplitudeTargetRx": { + "OutputAmplitudeTargetRx1": 1, + "OutputAmplitudeTargetRx2": 1, + "OutputAmplitudeTargetRx3": 1, + "OutputAmplitudeTargetRx4": 1, + "OutputAmplitudeTargetRx5": 1, + "OutputAmplitudeTargetRx6": 1, + "OutputAmplitudeTargetRx7": 1, + "OutputAmplitudeTargetRx8": 1 + } + } + } + } + } } + diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index a3adf5823..cea88f4f5 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -1635,3 +1635,4 @@ def wait_until(total_wait_time, interval, call_back, *args, **kwargs): time.sleep(interval) wait_time += interval return False + diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 059609602..fbf03f770 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -34,6 +34,7 @@ except ImportError as e: + helper_logger.log_error("---- shalvi ---- EXCEPTION 1") raise ImportError(str(e) + " - required module not found") # @@ -1815,11 +1816,14 @@ def wait_for_port_config_done(self, namespace): break def task_worker(self): + helper_logger.log_error("---- shalvi ---- Entered CMIS task_worker") self.xcvr_table_helper = XcvrTableHelper(self.namespaces) - + self.log_notice("Waiting for PortConfigDone...") for namespace in self.namespaces: self.wait_for_port_config_done(namespace) + + helper_logger.log_error("---- shalvi ---- received PortConfigDone") # APPL_DB for CONFIG updates, and STATE_DB for insertion/removal sel, asic_context = port_mapping.subscribe_port_update_event(self.namespaces, helper_logger) @@ -1928,11 +1932,14 @@ def task_worker(self): continue try: + helper_logger.log_error("---- shalvi ---- Starting CMIS state machine") # CMIS state transitions if state == self.CMIS_STATE_INSERTED: + helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_INSERTED") self.port_dict[lport]['appl'] = self.get_cmis_application_desired(api, host_lane_count, host_speed) if self.port_dict[lport]['appl'] < 1: + helper_logger.log_error("---- shalvi ---- inside if self.port_dict[lport]['appl'] < 1") self.log_error("{}: no suitable app for the port appl {} host_lane_count {} " "host_speed {}".format(lport, appl, host_lane_count, host_speed)) self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_FAILED @@ -1943,6 +1950,7 @@ def task_worker(self): self.port_dict[lport]['host_lanes_mask'] = self.get_cmis_host_lanes_mask(api, appl, host_lane_count, subport) if self.port_dict[lport]['host_lanes_mask'] <= 0: + helper_logger.log_error("---- shalvi ---- Inside if self.port_dict[lport]['host_lanes_mask'] <= 0") self.log_error("{}: Invalid lane mask received - host_lane_count {} subport {} " "appl {}!".format(lport, host_lane_count, subport, appl)) self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_FAILED @@ -1957,6 +1965,7 @@ def task_worker(self): 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: + helper_logger.log_error("---- shalvi ---- Inside if self.port_dict[lport]['media_lanes_mask'] <= 0") self.log_error("{}: Invalid media lane mask received - media_lane_count {} " "media_lane_assignment_options {} subport {}" " appl {}!".format(lport, media_lane_count, media_lane_assignment_options, subport, appl)) @@ -1967,6 +1976,7 @@ def task_worker(self): if self.port_dict[lport]['host_tx_ready'] != 'true' or \ self.port_dict[lport]['admin_status'] != 'up': + helper_logger.log_error("---- shalvi ---- Inside self.port_dict[lport]['host_tx_ready'] != 'true' or ...") self.log_notice("{} Forcing Tx laser OFF".format(lport)) # Force DataPath re-init api.tx_disable_channel(media_lanes_mask, True) @@ -1991,21 +2001,26 @@ def task_worker(self): # force datapath re-initialization if 0 != freq and freq != api.get_laser_config_freq(): need_update = True - - if not need_update: - # No application updates - self.log_notice("{}: no CMIS application update required...READY".format(lport)) - self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_READY - continue + + #TODO: uncomment below lines + #if not need_update: + # # No application updates + # helper_logger.log_error("---- shalvi ---- inside if not need_update") + # self.log_notice("{}: no CMIS application update required...READY".format(lport)) + # self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_READY + # continue self.log_notice("{}: force Datapath reinit".format(lport)) self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_DEINIT elif state == self.CMIS_STATE_DP_DEINIT: # D.2.2 Software Deinitialization + helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_DP_DEINIT") api.set_datapath_deinit(host_lanes_mask) # D.1.3 Software Configuration and Initialization media_lanes_mask = self.port_dict[lport]['media_lanes_mask'] + #TODO: uncomment below lines if not api.tx_disable_channel(media_lanes_mask, True): + helper_logger.log_error("---- shalvi ---- inside 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 @@ -2022,16 +2037,20 @@ def task_worker(self): # Explicit control bit to apply custom Host SI settings. # It will be set to 1 and applied via set_application if # custom SI settings is applicable + helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_AP_CONF") ec = 0 # TODO: Use fine grained time when the CMIS memory map is available if not self.check_module_state(api, ['ModuleReady']): + helper_logger.log_error("---- shalvi ---- inside if not self.check_module_state(api, ['ModuleReady'])") if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'ModuleReady'".format(lport)) self.force_cmis_reinit(lport, retries + 1) continue - + + #TODO: uncomment below lines if not self.check_datapath_state(api, host_lanes_mask, ['DataPathDeactivated']): + helper_logger.log_error("---- shalvi ---- inside if not self.check_datapath_state(api, host_lanes_mask, ['DataPathDeactivated'])") if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'DataPathDeactivated state'".format(lport)) self.force_cmis_reinit(lport, retries + 1) @@ -2039,40 +2058,56 @@ def task_worker(self): if api.is_coherent_module(): # For ZR module, configure the laser frequency when Datapath is in Deactivated state + helper_logger.log_error("---- shalvi ---- inside if api.is_coherent_module()") freq = self.port_dict[lport]['laser_freq'] if 0 != freq: if 1 != self.configure_laser_frequency(api, lport, freq): self.log_error("{} failed to configure laser frequency {} GHz".format(lport, freq)) else: self.log_notice("{} configured laser frequency {} GHz".format(lport, freq)) - + + helper_logger.log_error("---- shalvi ---- AP_CONF: Starting staging custom SI settings") # Stage custom SI settings if optics_si_parser.optics_si_present(): optics_si_dict = {} # Apply module SI settings if applicable lane_speed = int(speed/1000)//host_lane_count + helper_logger.log_error(f"---- shalvi ---- AP_CONF: pport = {pport}, lane_speed = {lane_speed}") optics_si_dict = optics_si_parser.fetch_optics_si_setting(pport, lane_speed, sfp) - + + helper_logger.log_error("---- shalvi ---- AP_CONF: optics_si_settings.json content:") + for key, sub_dict in optics_si_dict.items(): + helper_logger.log_error(f"---- shalvi ---- ~~~~~ {key} ~~~~~") + for sub_key, value in sub_dict.items(): + helper_logger.log_error(f"---- shalvi ---- ~~~~~ {sub_key}: {str(value)} ~~~~~") + if optics_si_dict: + helper_logger.log_error("---- shalvi ---- AP_CONF: inside if optics_si_dict") self.log_notice("{}: Apply Optics SI found for Vendor: {} PN: {} lane speed: {}G". format(lport, api.get_manufacturer(), api.get_model(), lane_speed)) if not api.stage_custom_si_settings(host_lanes_mask, optics_si_dict): + helper_logger.log_error("---- shalvi ---- AP_CONF: inside if not api.stage_custom_si_settings()") self.log_notice("{}: unable to stage custom SI settings ".format(lport)) self.force_cmis_reinit(lport, retries + 1) continue - + + self.log_notice(f"---- shalvi ---- after if not api.stage_custom_si_settings") + # Set Explicit control bit to apply Custom Host SI settings ec = 1 # D.1.3 Software Configuration and Initialization api.set_application(host_lanes_mask, appl, ec) if not api.scs_apply_datapath_init(host_lanes_mask): + helper_logger.log_error("---- shalvi ---- AP_CONF: inside if not api.scs_apply_datapath_init()") self.log_notice("{}: unable to set application and stage DP init".format(lport)) self.force_cmis_reinit(lport, retries + 1) continue self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_INIT + helper_logger.log_error("---- shalvi ---- AP_CONF: Moving to the next state") elif state == self.CMIS_STATE_DP_INIT: + helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_DP_INIT") if not self.check_config_error(api, host_lanes_mask, ['ConfigSuccess']): if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'ConfigSuccess'".format(lport)) @@ -2103,6 +2138,7 @@ def task_worker(self): self.port_dict[lport]['cmis_expired'] = now + datetime.timedelta(seconds=dpInitDuration) self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_TXON elif state == self.CMIS_STATE_DP_TXON: + helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_DP_TXON") if not self.check_datapath_state(api, host_lanes_mask, ['DataPathInitialized']): if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'DataPathInitialized'".format(lport)) @@ -2115,6 +2151,7 @@ def task_worker(self): 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: + helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_DP_ACTIVATE") if not self.check_datapath_state(api, host_lanes_mask, ['DataPathActivated']): if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'DataPathActivated'".format(lport)) @@ -3067,6 +3104,7 @@ def get_state_port_tbl(self, asic_id): def main(): + helper_logger.log_error(f"---- shalvi ---- starting xcvrd") parser = argparse.ArgumentParser() parser.add_argument('--skip_cmis_mgr', action='store_true') @@ -3077,3 +3115,6 @@ def main(): if __name__ == '__main__': main() + + + diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py index fff418563..1871437f6 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py @@ -10,6 +10,7 @@ helper_logger = logger.Logger(SYSLOG_IDENTIFIER) def get_optics_si_settings_value(physical_port, lane_speed, key, vendor_name_str): + helper_logger.log_info("---- shalvi ---- optics_si_parser.get_optics_si_settings_value(): Entered optics_si_parser") GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' PORT_MEDIA_SETTINGS_KEY = 'PORT_MEDIA_SETTINGS' DEFAULT_KEY = 'Default' @@ -103,7 +104,9 @@ def get_module_vendor_key(physical_port, sfp): return vendor_name.upper().strip() + '-' + vendor_pn.upper().strip(), vendor_name.upper().strip() def fetch_optics_si_setting(physical_port, lane_speed, sfp): + helper_logger.log_info("---- shalvi ---- optics_si_parser.fetch_optics_si_setting(): Entered function") if not g_optics_si_dict: + helper_logger.log_info("---- shalvi ---- optics_si_parser.fetch_optics_si_setting(): missing dict") return optics_si = {} @@ -135,3 +138,4 @@ def optics_si_present(): return True return False + From 30bd3e438a477092c58f317e08960110ebeac8da Mon Sep 17 00:00:00 2001 From: tshalvi Date: Thu, 21 Sep 2023 12:01:39 +0000 Subject: [PATCH 03/39] pre-arrangement commit with temporary logs --- sonic-xcvrd/xcvrd/xcvrd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index fbf03f770..7e91a44ec 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -976,7 +976,7 @@ def get_gaui_key(physical_port, port_speed, lane_count): appl_dict = None #TODO: instead of this neted if, just initialize gaui_key with None at the begining - #TODO: rename gaui_key to lane_speed_key + #TODO: rename gaui_key to lane_speed_key if type(api) == CmisApi: appl_dict = api.get_application_advertisement() helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {physical_port} ---> appl_dict = {appl_dict}") From abddbcaa102a734b9440345d5fb5e6b8807f51ef Mon Sep 17 00:00:00 2001 From: tshalvi Date: Fri, 22 Sep 2023 08:35:40 +0000 Subject: [PATCH 04/39] platform-daemon code to support port SI configuration for the Independent Module feature --- sonic-xcvrd/xcvrd/xcvrd.py | 201 ++++--------------------------------- 1 file changed, 22 insertions(+), 179 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 7e91a44ec..502dd5e10 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -34,7 +34,6 @@ except ImportError as e: - helper_logger.log_error("---- shalvi ---- EXCEPTION 1") raise ImportError(str(e) + " - required module not found") # @@ -119,7 +118,7 @@ -#TODO: remove this function. It is duplicated from CMIS thread +#TODO: This function is duplicated from the CMIS thread. Need to have one merged function out of the CMIS context def get_cmis_application_desired(api, host_lane_count, speed): """ Get the CMIS application code that matches the specified host side configurations @@ -135,55 +134,23 @@ def get_cmis_application_desired(api, host_lane_count, speed): Returns: Integer, the transceiver-specific application code """ - - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: api = {api}") - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(api) = {type(api)}") - # (api.split('.'[-1])).split()[0] - app_found = False if speed == 0 or host_lane_count == 0: return 0 appl_code = 0 - # if api == sonic_platform_base.sonic_xcvr.api.public.c_cmis.CmisApi: if type(api) == CmisApi: - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: inside if type(api) == CmisApi") appl_dict = api.get_application_advertisement() - helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: appl_dict == {appl_dict}") for c in appl_dict.keys(): - helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: c == {c}") d = appl_dict[c] - helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: d == {d}") - - helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: d.lane_count = {d.get('host_lane_count')} ~~~ lane_count = {host_lane_count}") - helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: d.speed = {get_interface_speed(d.get('host_electrical_interface_id'))} ~~~ speed = {speed}") - if d.get('host_lane_count') != host_lane_count: - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: inside if d.get('host_lane_count') != host_lane_count") - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(get_interface_speed(d.get('host_electrical_interface_id'))) = {type(get_interface_speed(d.get('host_electrical_interface_id')))}") - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(speed) = {type(speed)}") continue if get_interface_speed(d.get('host_electrical_interface_id')) != speed: - helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: inside if get_interface_speed(d.get('host_electrical_interface_id')) != speed") - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(get_interface_speed(d.get('host_electrical_interface_id'))) = {type(get_interface_speed(d.get('host_electrical_interface_id')))}") - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: type(speed) = {type(speed)}") continue - helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: found something") appl_code = c app_found = True - result_index = appl_code & 0xf - # helper_logger.log_error(f"---- tomer2 ---- get_cmis_application_desired: result_index = {result_index}") - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: appl_dict[result_index] = {appl_dict[result_index]}") - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: appl_dict[result_index]['host_electrical_interface_id'] = {appl_dict[result_index]['host_electrical_interface_id']}") - - - # helper_logger.log_error(f"---- tomer2 ---- get_cmis_application_desired: appl_dict[result_index] = {appl_dict[result_index]}") - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: gaui_key_returned = {appl_dict[result_index].get('host_lane_count')}") - # helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: gaui_key_returned = {appl_dict[result_index].get('host_lane_count')}") - - helper_logger.log_error(f"---- tomer ---- get_cmis_application_desired: gaui_key_returned = {appl_dict[result_index].get('host_electrical_interface_id')}") break if app_found: @@ -192,43 +159,7 @@ def get_cmis_application_desired(api, host_lane_count, speed): return None -# #TODO: remove this function. It is duplicated from CMIS thread -# def get_cmis_application_desired(api, host_lane_count, speed): -# """ -# Get the CMIS application code that matches the specified host side configurations - -# Args: -# api: -# XcvrApi object -# host_lane_count: -# Number of lanes on the host side -# speed: -# Integer, the port speed of the host interface - -# Returns: -# Integer, the transceiver-specific application code -# """ - -# if speed == 0 or host_lane_count == 0: -# return 0 - -# appl_code = 0 -# if type(api) == CmisApi: -# appl_dict = api.get_application_advertisement() -# for c in appl_dict.keys(): -# d = appl_dict[c] -# if d.get('host_lane_count') != host_lane_count: -# continue -# if get_interface_speed(d.get('host_electrical_interface_id')) != speed: -# continue -# appl_code = c -# break - -# return (appl_code & 0xf) - -# return None - -#TODO: remove this function. It is duplicated from CMIS thread +#TODO: This function is duplicated from the CMIS thread. Need to have one merged function out of the CMIS context def get_interface_speed(ifname): """ Get the port speed from the host interface name @@ -960,6 +891,7 @@ def get_media_settings_value(physical_port, key): +#TODO: update the implementation of this method after getting answers from Prince (probably replacing CONFIG_DB with APP_DB) def get_speed_and_lane_count(port, cfg_port_tbl): port_speed, lane_count = -1, -1 found, port_info = cfg_port_tbl.get(port) @@ -969,25 +901,19 @@ def get_speed_and_lane_count(port, cfg_port_tbl): lane_count = len(lanes.split(',')) return port_speed, lane_count -def get_gaui_key(physical_port, port_speed, lane_count): + +def get_lane_speed_key(physical_port, port_speed, lane_count): sfp = platform_chassis.get_sfp(physical_port) api = sfp.get_xcvr_api() speed_index = get_cmis_application_desired(api, int(lane_count), int(port_speed)) - appl_dict = None - #TODO: instead of this neted if, just initialize gaui_key with None at the begining - #TODO: rename gaui_key to lane_speed_key + appl_adv_dict, lane_speed_key = None, None if type(api) == CmisApi: - appl_dict = api.get_application_advertisement() - helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {physical_port} ---> appl_dict = {appl_dict}") - if speed_index is None: - gaui_key = None - else: - gaui_key = SI_PER_SPEED_INDICATION_STR + (appl_dict[speed_index].get('host_electrical_interface_id')).split()[0] - else: - gaui_key = None - return gaui_key + appl_adv_dict = api.get_application_advertisement() + if speed_index is not None: + lane_speed_key = SI_PER_SPEED_INDICATION_STR + (appl_adv_dict[speed_index].get('host_electrical_interface_id')).split()[0] + return lane_speed_key def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count): @@ -1034,9 +960,9 @@ def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_cou media_key += '-' + '*' - gaui_key = get_gaui_key(physical_port, port_speed, lane_count) + lane_speed_key = get_lane_speed_key(physical_port, port_speed, lane_count) - return [vendor_key, media_key, gaui_key] + return [vendor_key, media_key, lane_speed_key] @@ -1100,36 +1026,16 @@ def get_media_val_str(num_logical_ports, lane_dict, logical_idx): def notify_media_setting(logical_port_name, transceiver_dict, app_port_tbl, cfg_port_tbl, port_mapping): - - - helper_logger.log_error(f"---- tomer ---- notify_media_setting(): entered notify_media_setting()") - - - helper_logger.log_error(f"---- tomer ---- notify_media_setting(): logical_port_name = {logical_port_name}") - - # port_speed, lane_count = -1, -1 - # found, port_info = cfg_port_tbl.get(logical_port_name) - # if found and 'speed' in dict(port_info) and 'lanes' in dict(port_info): - # port_speed = dict(port_info).get('speed', '-1') - # lanes = dict(port_info).get('lanes', '-1') - # lane_count = len(lanes.split(',')) - port_speed, lane_count = get_speed_and_lane_count(logical_port_name, cfg_port_tbl) - - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): port_speed = {port_speed}") - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): lane_count = {lane_count}") - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): lanes = {lanes}") - - if not g_dict: - helper_logger.log_error(f"---- tomer ---- g_dict is None") return + port_speed, lane_count = get_speed_and_lane_count(logical_port_name, cfg_port_tbl) + ganged_port = False ganged_member_num = 1 physical_port_list = port_mapping.logical_port_name_to_physical_port_list(logical_port_name) if physical_port_list is None: - helper_logger.log_error(f"---- tomer ---- notify_media_setting(): No physical ports found for logical port {logical_port_name}") helper_logger.log_error("Error: No physical ports found for logical port '{}'".format(logical_port_name)) return PHYSICAL_PORT_NOT_EXIST @@ -1137,35 +1043,6 @@ def notify_media_setting(logical_port_name, transceiver_dict, ganged_port = True for physical_port in physical_port_list: - - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): inside loop: physical_port = {physical_port}") - # sfp = platform_chassis.get_sfp(physical_port) - # api = sfp.get_xcvr_api() - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> api = {api}") - - # speed_index = get_cmis_application_desired(api, int(lane_count), int(port_speed)) - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> final speed_index = {speed_index}") - - # appl_dict = None - # if type(api) == CmisApi: - # appl_dict = api.get_application_advertisement() - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> appl_dict = {appl_dict}") - # if speed_index is None: - # gaui_key = None - # else: - # gaui_key = (appl_dict[speed_index].get('host_electrical_interface_id')).split()[0] - # else: - # gaui_key = None - - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> final gaui_key = {gaui_key}") - - # gaui_from_fnction = get_gaui_key(physical_port, port_speed, lane_count) - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} --> final gaui_key from function = {gaui_from_fnction}") - - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") - - - logical_port_list = port_mapping.get_physical_to_logical(physical_port) num_logical_ports = len(logical_port_list) logical_idx = logical_port_list.index(logical_port_name) @@ -1179,18 +1056,11 @@ def notify_media_setting(logical_port_name, transceiver_dict, port_name = get_physical_port_name(logical_port_name, ganged_member_num, ganged_port) - helper_logger.log_error(f"---- tomer ---- notify_media_setting(): physical port_name = {port_name}") - ganged_member_num += 1 key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) - helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} ---> whole_key = {key}") + helper_logger.log_debug("Retrieving media settings for port {} using the following keys: {}".format(logical_port_name, key)) media_dict = get_media_settings_value(physical_port, key) - helper_logger.log_error(f"---- tomer ---- notify_media_setting(): {logical_port_name} ---> whole_value = {media_dict}") - - # helper_logger.log_error(f"---- tomer ---- key = {key}") - # helper_logger.log_error(f"---- tomer ---- value = {media_dict}") - if len(media_dict) == 0: helper_logger.log_error("Error in obtaining media setting for {}".format(logical_port_name)) @@ -1199,6 +1069,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, fvs = swsscommon.FieldValuePairs(len(media_dict)) index = 0 + helper_logger.log_debug("Storing in Application DB the following media settings for port {}:".format(logical_port_name)) for media_key in media_dict: if type(media_dict[media_key]) is dict: media_val_str = get_media_val_str(num_logical_ports, @@ -1206,12 +1077,10 @@ def notify_media_setting(logical_port_name, transceiver_dict, logical_idx) else: media_val_str = media_dict[media_key] + helper_logger.log_debug("{}:({},{}) ".format(index, str(media_key), str(media_val_str))) fvs[index] = (str(media_key), str(media_val_str)) index += 1 - - # helper_logger.log_error(f"---- tomer ---- notify_media_setting(): ~~~~ writing pair to APP_DB: ~~~~ {port_name} --> {fvs.fv_dict}") - app_port_tbl.set(port_name, fvs) @@ -1816,14 +1685,12 @@ def wait_for_port_config_done(self, namespace): break def task_worker(self): - helper_logger.log_error("---- shalvi ---- Entered CMIS task_worker") self.xcvr_table_helper = XcvrTableHelper(self.namespaces) self.log_notice("Waiting for PortConfigDone...") for namespace in self.namespaces: self.wait_for_port_config_done(namespace) - helper_logger.log_error("---- shalvi ---- received PortConfigDone") # APPL_DB for CONFIG updates, and STATE_DB for insertion/removal sel, asic_context = port_mapping.subscribe_port_update_event(self.namespaces, helper_logger) @@ -1932,14 +1799,12 @@ def task_worker(self): continue try: - helper_logger.log_error("---- shalvi ---- Starting CMIS state machine") + self.log_notice("Starting CMIS state machine...") # CMIS state transitions if state == self.CMIS_STATE_INSERTED: - helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_INSERTED") self.port_dict[lport]['appl'] = self.get_cmis_application_desired(api, host_lane_count, host_speed) if self.port_dict[lport]['appl'] < 1: - helper_logger.log_error("---- shalvi ---- inside if self.port_dict[lport]['appl'] < 1") self.log_error("{}: no suitable app for the port appl {} host_lane_count {} " "host_speed {}".format(lport, appl, host_lane_count, host_speed)) self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_FAILED @@ -1950,7 +1815,6 @@ def task_worker(self): self.port_dict[lport]['host_lanes_mask'] = self.get_cmis_host_lanes_mask(api, appl, host_lane_count, subport) if self.port_dict[lport]['host_lanes_mask'] <= 0: - helper_logger.log_error("---- shalvi ---- Inside if self.port_dict[lport]['host_lanes_mask'] <= 0") self.log_error("{}: Invalid lane mask received - host_lane_count {} subport {} " "appl {}!".format(lport, host_lane_count, subport, appl)) self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_FAILED @@ -1965,7 +1829,6 @@ def task_worker(self): 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: - helper_logger.log_error("---- shalvi ---- Inside if self.port_dict[lport]['media_lanes_mask'] <= 0") self.log_error("{}: Invalid media lane mask received - media_lane_count {} " "media_lane_assignment_options {} subport {}" " appl {}!".format(lport, media_lane_count, media_lane_assignment_options, subport, appl)) @@ -1976,7 +1839,6 @@ def task_worker(self): if self.port_dict[lport]['host_tx_ready'] != 'true' or \ self.port_dict[lport]['admin_status'] != 'up': - helper_logger.log_error("---- shalvi ---- Inside self.port_dict[lport]['host_tx_ready'] != 'true' or ...") self.log_notice("{} Forcing Tx laser OFF".format(lport)) # Force DataPath re-init api.tx_disable_channel(media_lanes_mask, True) @@ -2013,14 +1875,11 @@ def task_worker(self): self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_DEINIT elif state == self.CMIS_STATE_DP_DEINIT: # D.2.2 Software Deinitialization - helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_DP_DEINIT") api.set_datapath_deinit(host_lanes_mask) # D.1.3 Software Configuration and Initialization media_lanes_mask = self.port_dict[lport]['media_lanes_mask'] - #TODO: uncomment below lines if not api.tx_disable_channel(media_lanes_mask, True): - helper_logger.log_error("---- shalvi ---- inside 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 @@ -2037,20 +1896,16 @@ def task_worker(self): # Explicit control bit to apply custom Host SI settings. # It will be set to 1 and applied via set_application if # custom SI settings is applicable - helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_AP_CONF") ec = 0 # TODO: Use fine grained time when the CMIS memory map is available if not self.check_module_state(api, ['ModuleReady']): - helper_logger.log_error("---- shalvi ---- inside if not self.check_module_state(api, ['ModuleReady'])") if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'ModuleReady'".format(lport)) self.force_cmis_reinit(lport, retries + 1) continue - #TODO: uncomment below lines if not self.check_datapath_state(api, host_lanes_mask, ['DataPathDeactivated']): - helper_logger.log_error("---- shalvi ---- inside if not self.check_datapath_state(api, host_lanes_mask, ['DataPathDeactivated'])") if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'DataPathDeactivated state'".format(lport)) self.force_cmis_reinit(lport, retries + 1) @@ -2058,7 +1913,6 @@ def task_worker(self): if api.is_coherent_module(): # For ZR module, configure the laser frequency when Datapath is in Deactivated state - helper_logger.log_error("---- shalvi ---- inside if api.is_coherent_module()") freq = self.port_dict[lport]['laser_freq'] if 0 != freq: if 1 != self.configure_laser_frequency(api, lport, freq): @@ -2066,48 +1920,40 @@ def task_worker(self): else: self.log_notice("{} configured laser frequency {} GHz".format(lport, freq)) - helper_logger.log_error("---- shalvi ---- AP_CONF: Starting staging custom SI settings") + helper_logger.log_debug("Starting to stage custom SI settings") # Stage custom SI settings if optics_si_parser.optics_si_present(): optics_si_dict = {} # Apply module SI settings if applicable lane_speed = int(speed/1000)//host_lane_count - helper_logger.log_error(f"---- shalvi ---- AP_CONF: pport = {pport}, lane_speed = {lane_speed}") optics_si_dict = optics_si_parser.fetch_optics_si_setting(pport, lane_speed, sfp) - helper_logger.log_error("---- shalvi ---- AP_CONF: optics_si_settings.json content:") + helper_logger.log_debug("SI values for the connected module found in optics_si_settings.json:") for key, sub_dict in optics_si_dict.items(): - helper_logger.log_error(f"---- shalvi ---- ~~~~~ {key} ~~~~~") + helper_logger.log_debug("{}".format(key)) for sub_key, value in sub_dict.items(): - helper_logger.log_error(f"---- shalvi ---- ~~~~~ {sub_key}: {str(value)} ~~~~~") + helper_logger.log_debug("{}: {}".format(sub_key, str(value))) if optics_si_dict: - helper_logger.log_error("---- shalvi ---- AP_CONF: inside if optics_si_dict") self.log_notice("{}: Apply Optics SI found for Vendor: {} PN: {} lane speed: {}G". format(lport, api.get_manufacturer(), api.get_model(), lane_speed)) if not api.stage_custom_si_settings(host_lanes_mask, optics_si_dict): - helper_logger.log_error("---- shalvi ---- AP_CONF: inside if not api.stage_custom_si_settings()") self.log_notice("{}: unable to stage custom SI settings ".format(lport)) self.force_cmis_reinit(lport, retries + 1) continue - self.log_notice(f"---- shalvi ---- after if not api.stage_custom_si_settings") - # Set Explicit control bit to apply Custom Host SI settings ec = 1 # D.1.3 Software Configuration and Initialization api.set_application(host_lanes_mask, appl, ec) if not api.scs_apply_datapath_init(host_lanes_mask): - helper_logger.log_error("---- shalvi ---- AP_CONF: inside if not api.scs_apply_datapath_init()") self.log_notice("{}: unable to set application and stage DP init".format(lport)) self.force_cmis_reinit(lport, retries + 1) continue self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_INIT - helper_logger.log_error("---- shalvi ---- AP_CONF: Moving to the next state") elif state == self.CMIS_STATE_DP_INIT: - helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_DP_INIT") if not self.check_config_error(api, host_lanes_mask, ['ConfigSuccess']): if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'ConfigSuccess'".format(lport)) @@ -2138,7 +1984,6 @@ def task_worker(self): self.port_dict[lport]['cmis_expired'] = now + datetime.timedelta(seconds=dpInitDuration) self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_TXON elif state == self.CMIS_STATE_DP_TXON: - helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_DP_TXON") if not self.check_datapath_state(api, host_lanes_mask, ['DataPathInitialized']): if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'DataPathInitialized'".format(lport)) @@ -2151,7 +1996,6 @@ def task_worker(self): 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: - helper_logger.log_error("---- shalvi ---- In state: CMIS_STATE_DP_ACTIVATE") if not self.check_datapath_state(api, host_lanes_mask, ['DataPathActivated']): if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'DataPathActivated'".format(lport)) @@ -3104,7 +2948,6 @@ def get_state_port_tbl(self, asic_id): def main(): - helper_logger.log_error(f"---- shalvi ---- starting xcvrd") parser = argparse.ArgumentParser() parser.add_argument('--skip_cmis_mgr', action='store_true') From f088df634fb80bb0e41af5f09f24ba9f492c83ac Mon Sep 17 00:00:00 2001 From: tshalvi Date: Fri, 22 Sep 2023 08:51:05 +0000 Subject: [PATCH 05/39] refactoring and removing redundant spaces --- sonic-xcvrd/xcvrd/xcvrd.py | 163 +------------------------------------ 1 file changed, 3 insertions(+), 160 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 502dd5e10..20ace73b5 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -99,11 +99,7 @@ # Global chassis object based on new platform api platform_chassis = None - - -SI_PER_SPEED_INDICATION_STR = "speed:" - - +LANE_SPEED_KEY_PREFIX = "speed:" # Global logger instance for helper functions and classes # TODO: Refactor so that we only need the logger inherited @@ -115,9 +111,6 @@ # - - - #TODO: This function is duplicated from the CMIS thread. Need to have one merged function out of the CMIS context def get_cmis_application_desired(api, host_lane_count, speed): """ @@ -191,11 +184,6 @@ def get_interface_speed(ifname): return speed - - - - - # Get physical port name @@ -668,129 +656,8 @@ def check_port_in_range(range_str, physical_port): return True return False - - - -# original -# def get_media_settings_value(physical_port, key): -# GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' -# PORT_MEDIA_SETTINGS_KEY = 'PORT_MEDIA_SETTINGS' -# DEFAULT_KEY = 'Default' -# RANGE_SEPARATOR = '-' -# COMMA_SEPARATOR = ',' -# media_dict = {} -# default_dict = {} -# # Keys under global media settings can be a list or range or list of ranges -# # of physical port numbers. Below are some examples -# # 1-32 -# # 1,2,3,4,5 -# # 1-4,9-12 -# if GLOBAL_MEDIA_SETTINGS_KEY in g_dict: -# for keys in g_dict[GLOBAL_MEDIA_SETTINGS_KEY]: -# if COMMA_SEPARATOR in keys: -# port_list = keys.split(COMMA_SEPARATOR) -# for port in port_list: -# if RANGE_SEPARATOR in port: -# if check_port_in_range(port, physical_port): -# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] -# break -# elif str(physical_port) == port: -# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] -# break -# elif RANGE_SEPARATOR in keys: -# if check_port_in_range(keys, physical_port): -# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] -# # If there is a match in the global profile for a media type, -# # fetch those values -# if key[0] in media_dict: -# return media_dict[key[0]] -# elif key[1] in media_dict: -# return media_dict[key[1]] -# elif DEFAULT_KEY in media_dict: -# default_dict = media_dict[DEFAULT_KEY] -# media_dict = {} -# if PORT_MEDIA_SETTINGS_KEY in g_dict: -# for keys in g_dict[PORT_MEDIA_SETTINGS_KEY]: -# if int(keys) == physical_port: -# media_dict = g_dict[PORT_MEDIA_SETTINGS_KEY][keys] -# break -# if len(media_dict) == 0: -# if len(default_dict) != 0: -# return default_dict -# else: -# helper_logger.log_error("Error: No values for physical port '{}'".format(physical_port)) -# return {} -# if key[0] in media_dict: -# return media_dict[key[0]] -# elif key[1] in media_dict: -# return media_dict[key[1]] -# elif DEFAULT_KEY in media_dict: -# return media_dict[DEFAULT_KEY] -# elif len(default_dict) != 0: -# return default_dict -# else: -# if len(default_dict) != 0: -# return default_dict -# return {} - - def is_si_per_speed_supported(media_dict): - #SI_PER_SPEED_INDICATION_STR = "speed:" - return SI_PER_SPEED_INDICATION_STR in list(media_dict.keys())[0] - - -# Before session with Prince # TODO: delete -# def get_media_settings_value(physical_port, key): -# GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' -# PORT_MEDIA_SETTINGS_KEY = 'PORT_MEDIA_SETTINGS' -# DEFAULT_KEY = 'Default' -# RANGE_SEPARATOR = '-' -# COMMA_SEPARATOR = ',' -# media_dict = {} -# default_dict = {} -# # Keys under global media settings can be a list or range or list of ranges -# # of physical port numbers. Below are some examples -# # 1-32 -# # 1,2,3,4,5 -# # 1-4,9-12 -# if GLOBAL_MEDIA_SETTINGS_KEY in g_dict: -# for keys in g_dict[GLOBAL_MEDIA_SETTINGS_KEY]: -# if COMMA_SEPARATOR in keys: -# port_list = keys.split(COMMA_SEPARATOR) -# for port in port_list: -# if RANGE_SEPARATOR in port: -# if check_port_in_range(port, physical_port): -# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] -# break -# elif str(physical_port) == port: -# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] -# break -# elif RANGE_SEPARATOR in keys: -# if check_port_in_range(keys, physical_port): -# media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] -# # If there is a match in the global profile for a media type, -# # fetch those values -# if key[0] in media_dict: -# return media_dict[key[0]] -# elif key[1] in media_dict: -# if is_si_per_speed_supported(media_dict[key[1]]): -# if key[2] in media_dict[key[1]]: -# return media_dict[key[1]][key[2]] -# else: -# return {} -# else: -# return media_dict[key[1]] -# elif DEFAULT_KEY in media_dict: - - - - - - - - - - + return LANE_SPEED_KEY_PREFIX in list(media_dict.keys())[0] def get_media_settings_value(physical_port, key): GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' @@ -887,10 +754,6 @@ def get_media_settings_value(physical_port, key): return {} - - - - #TODO: update the implementation of this method after getting answers from Prince (probably replacing CONFIG_DB with APP_DB) def get_speed_and_lane_count(port, cfg_port_tbl): port_speed, lane_count = -1, -1 @@ -911,7 +774,7 @@ def get_lane_speed_key(physical_port, port_speed, lane_count): if type(api) == CmisApi: appl_adv_dict = api.get_application_advertisement() if speed_index is not None: - lane_speed_key = SI_PER_SPEED_INDICATION_STR + (appl_adv_dict[speed_index].get('host_electrical_interface_id')).split()[0] + lane_speed_key = LANE_SPEED_KEY_PREFIX + (appl_adv_dict[speed_index].get('host_electrical_interface_id')).split()[0] return lane_speed_key @@ -965,17 +828,6 @@ def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_cou return [vendor_key, media_key, lane_speed_key] - - - - - - - - - - - def get_media_val_str_from_dict(media_dict): LANE_STR = 'lane' LANE_SEPARATOR = ',' @@ -1020,9 +872,6 @@ def get_media_val_str(num_logical_ports, lane_dict, logical_idx): return media_val_str - - - def notify_media_setting(logical_port_name, transceiver_dict, app_port_tbl, cfg_port_tbl, port_mapping): @@ -1084,12 +933,6 @@ def notify_media_setting(logical_port_name, transceiver_dict, app_port_tbl.set(port_name, fvs) - - - - - - def waiting_time_compensation_with_sleep(time_start, time_to_wait): time_now = time.time() time_diff = time_now - time_start From d3f9653a904edc4966142723d2e6af6c3b96cab5 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Fri, 22 Sep 2023 08:54:48 +0000 Subject: [PATCH 06/39] removed redundant spaces --- sonic-xcvrd/xcvrd/xcvrd.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 20ace73b5..c8a9fb290 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -29,10 +29,8 @@ from .xcvrd_utilities import port_mapping from .xcvrd_utilities import optics_si_parser - from sonic_platform_base.sonic_xcvr.api.public.c_cmis import CmisApi - except ImportError as e: raise ImportError(str(e) + " - required module not found") From 62fea72a2ea878c55e3fad83fcfde65ae6c28fbc Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 26 Sep 2023 11:58:07 +0000 Subject: [PATCH 07/39] Removing redundant comments and spaces --- sonic-xcvrd/tests/test_xcvrd.py | 1 - sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py | 3 --- 2 files changed, 4 deletions(-) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index cea88f4f5..a3adf5823 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -1635,4 +1635,3 @@ def wait_until(total_wait_time, interval, call_back, *args, **kwargs): time.sleep(interval) wait_time += interval return False - diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py index 1871437f6..101c12784 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py @@ -10,7 +10,6 @@ helper_logger = logger.Logger(SYSLOG_IDENTIFIER) def get_optics_si_settings_value(physical_port, lane_speed, key, vendor_name_str): - helper_logger.log_info("---- shalvi ---- optics_si_parser.get_optics_si_settings_value(): Entered optics_si_parser") GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' PORT_MEDIA_SETTINGS_KEY = 'PORT_MEDIA_SETTINGS' DEFAULT_KEY = 'Default' @@ -104,9 +103,7 @@ def get_module_vendor_key(physical_port, sfp): return vendor_name.upper().strip() + '-' + vendor_pn.upper().strip(), vendor_name.upper().strip() def fetch_optics_si_setting(physical_port, lane_speed, sfp): - helper_logger.log_info("---- shalvi ---- optics_si_parser.fetch_optics_si_setting(): Entered function") if not g_optics_si_dict: - helper_logger.log_info("---- shalvi ---- optics_si_parser.fetch_optics_si_setting(): missing dict") return optics_si = {} From f43df1076919fe6d1209f4891a0f1fa552b4b48e Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 26 Sep 2023 12:08:15 +0000 Subject: [PATCH 08/39] removed redundant spaces and removed optics_si_settings.json from commit --- sonic-xcvrd/tests/optics_si_settings.json | 437 +++++++++--------- sonic-xcvrd/xcvrd/xcvrd.py | 3 - .../xcvrd/xcvrd_utilities/optics_si_parser.py | 1 - 3 files changed, 218 insertions(+), 223 deletions(-) diff --git a/sonic-xcvrd/tests/optics_si_settings.json b/sonic-xcvrd/tests/optics_si_settings.json index 295bb7a69..2b9defc81 100644 --- a/sonic-xcvrd/tests/optics_si_settings.json +++ b/sonic-xcvrd/tests/optics_si_settings.json @@ -1,223 +1,222 @@ { - "GLOBAL_MEDIA_SETTINGS": { - "0-31": { - "50G_SPEED": { - "Default": { - "OutputEqPreCursorTargetRx": { - "OutputEqPreCursorTargetRx1": 0, - "OutputEqPreCursorTargetRx2": 0, - "OutputEqPreCursorTargetRx3": 0, - "OutputEqPreCursorTargetRx4": 0, - "OutputEqPreCursorTargetRx5": 0, - "OutputEqPreCursorTargetRx6": 0, - "OutputEqPreCursorTargetRx7": 0, - "OutputEqPreCursorTargetRx8": 0 - }, - "OutputEqPostCursorTargetRx": { - "OutputEqPostCursorTargetRx1": 0, - "OutputEqPostCursorTargetRx2": 0, - "OutputEqPostCursorTargetRx3": 0, - "OutputEqPostCursorTargetRx4": 0, - "OutputEqPostCursorTargetRx5": 0, - "OutputEqPostCursorTargetRx6": 0, - "OutputEqPostCursorTargetRx7": 0, - "OutputEqPostCursorTargetRx8": 0 - }, - "OutputAmplitudeTargetRx": { - "OutputAmplitudeTargetRx1":0, - "OutputAmplitudeTargetRx2":0, - "OutputAmplitudeTargetRx3":0, - "OutputAmplitudeTargetRx4":0, - "OutputAmplitudeTargetRx5":0, - "OutputAmplitudeTargetRx6":0, - "OutputAmplitudeTargetRx7":0, - "OutputAmplitudeTargetRx8":0 - } - } + "GLOBAL_MEDIA_SETTINGS":{ + "0-31":{ + "100G_SPEED":{ + "CREDO-CAC82X321M2MC0HW":{ + "OutputEqPreCursorTargetRx":{ + "OutputEqPreCursorTargetRx1":3, + "OutputEqPreCursorTargetRx2":3, + "OutputEqPreCursorTargetRx3":3, + "OutputEqPreCursorTargetRx4":3, + "OutputEqPreCursorTargetRx5":3, + "OutputEqPreCursorTargetRx6":3, + "OutputEqPreCursorTargetRx7":3, + "OutputEqPreCursorTargetRx8":3 + }, + "OutputEqPostCursorTargetRx":{ + "OutputEqPostCursorTargetRx1":0, + "OutputEqPostCursorTargetRx2":0, + "OutputEqPostCursorTargetRx3":0, + "OutputEqPostCursorTargetRx4":0, + "OutputEqPostCursorTargetRx5":0, + "OutputEqPostCursorTargetRx6":0, + "OutputEqPostCursorTargetRx7":0, + "OutputEqPostCursorTargetRx8":0 + }, + "OutputAmplitudeTargetRx":{ + "OutputAmplitudeTargetRx1":0, + "OutputAmplitudeTargetRx2":0, + "OutputAmplitudeTargetRx3":0, + "OutputAmplitudeTargetRx4":0, + "OutputAmplitudeTargetRx5":0, + "OutputAmplitudeTargetRx6":0, + "OutputAmplitudeTargetRx7":0, + "OutputAmplitudeTargetRx8":0 + } + } + } } - } - }, - "PORT_MEDIA_SETTINGS": { - "0": { - "50G_SPEED": { - "Default": { - "OutputEqPreCursorTargetRx": { - "OutputEqPreCursorTargetRx1": 3, - "OutputEqPreCursorTargetRx2": 3, - "OutputEqPreCursorTargetRx3": 3, - "OutputEqPreCursorTargetRx4": 3, - "OutputEqPreCursorTargetRx5": 3, - "OutputEqPreCursorTargetRx6": 3, - "OutputEqPreCursorTargetRx7": 3, - "OutputEqPreCursorTargetRx8": 3 - }, - "OutputEqPostCursorTargetRx": { - "OutputEqPostCursorTargetRx1": 0, - "OutputEqPostCursorTargetRx2": 0, - "OutputEqPostCursorTargetRx3": 0, - "OutputEqPostCursorTargetRx4": 0, - "OutputEqPostCursorTargetRx5": 0, - "OutputEqPostCursorTargetRx6": 0, - "OutputEqPostCursorTargetRx7": 0, - "OutputEqPostCursorTargetRx8": 0 - }, - "OutputAmplitudeTargetRx": { - "OutputAmplitudeTargetRx1": 0, - "OutputAmplitudeTargetRx2": 0, - "OutputAmplitudeTargetRx3": 0, - "OutputAmplitudeTargetRx4": 0, - "OutputAmplitudeTargetRx5": 0, - "OutputAmplitudeTargetRx6": 0, - "OutputAmplitudeTargetRx7": 0, - "OutputAmplitudeTargetRx8": 0 - } - } + }, + "PORT_MEDIA_SETTINGS":{ + "0":{ + "100G_SPEED":{ + "CREDO-CAC82X321M2MC0HW":{ + "OutputEqPreCursorTargetRx":{ + "OutputEqPreCursorTargetRx1":3, + "OutputEqPreCursorTargetRx2":3, + "OutputEqPreCursorTargetRx3":3, + "OutputEqPreCursorTargetRx4":3, + "OutputEqPreCursorTargetRx5":3, + "OutputEqPreCursorTargetRx6":3, + "OutputEqPreCursorTargetRx7":3, + "OutputEqPreCursorTargetRx8":3 + }, + "OutputEqPostCursorTargetRx":{ + "OutputEqPostCursorTargetRx1":0, + "OutputEqPostCursorTargetRx2":0, + "OutputEqPostCursorTargetRx3":0, + "OutputEqPostCursorTargetRx4":0, + "OutputEqPostCursorTargetRx5":0, + "OutputEqPostCursorTargetRx6":0, + "OutputEqPostCursorTargetRx7":0, + "OutputEqPostCursorTargetRx8":0 + }, + "OutputAmplitudeTargetRx":{ + "OutputAmplitudeTargetRx1":0, + "OutputAmplitudeTargetRx2":0, + "OutputAmplitudeTargetRx3":0, + "OutputAmplitudeTargetRx4":0, + "OutputAmplitudeTargetRx5":0, + "OutputAmplitudeTargetRx6":0, + "OutputAmplitudeTargetRx7":0, + "OutputAmplitudeTargetRx8":0 + } + } + } + }, + "1":{ + "100G_SPEED":{ + "Default":{ + "OutputEqPreCursorTargetRx":{ + "OutputEqPreCursorTargetRx1":3, + "OutputEqPreCursorTargetRx2":3, + "OutputEqPreCursorTargetRx3":3, + "OutputEqPreCursorTargetRx4":3, + "OutputEqPreCursorTargetRx5":3, + "OutputEqPreCursorTargetRx6":3, + "OutputEqPreCursorTargetRx7":3, + "OutputEqPreCursorTargetRx8":3 + }, + "OutputEqPostCursorTargetRx":{ + "OutputEqPostCursorTargetRx1":0, + "OutputEqPostCursorTargetRx2":0, + "OutputEqPostCursorTargetRx3":0, + "OutputEqPostCursorTargetRx4":0, + "OutputEqPostCursorTargetRx5":0, + "OutputEqPostCursorTargetRx6":0, + "OutputEqPostCursorTargetRx7":0, + "OutputEqPostCursorTargetRx8":0 + }, + "OutputAmplitudeTargetRx":{ + "OutputAmplitudeTargetRx1":1, + "OutputAmplitudeTargetRx2":1, + "OutputAmplitudeTargetRx3":1, + "OutputAmplitudeTargetRx4":1, + "OutputAmplitudeTargetRx5":1, + "OutputAmplitudeTargetRx6":1, + "OutputAmplitudeTargetRx7":1, + "OutputAmplitudeTargetRx8":1 + } + } + } + }, + "10":{ + "100G_SPEED":{ + "Default":{ + "OutputEqPreCursorTargetRx":{ + "OutputEqPreCursorTargetRx1":3, + "OutputEqPreCursorTargetRx2":3, + "OutputEqPreCursorTargetRx3":3, + "OutputEqPreCursorTargetRx4":3, + "OutputEqPreCursorTargetRx5":3, + "OutputEqPreCursorTargetRx6":3, + "OutputEqPreCursorTargetRx7":3, + "OutputEqPreCursorTargetRx8":3 + }, + "OutputEqPostCursorTargetRx":{ + "OutputEqPostCursorTargetRx1":0, + "OutputEqPostCursorTargetRx2":0, + "OutputEqPostCursorTargetRx3":0, + "OutputEqPostCursorTargetRx4":0, + "OutputEqPostCursorTargetRx5":0, + "OutputEqPostCursorTargetRx6":0, + "OutputEqPostCursorTargetRx7":0, + "OutputEqPostCursorTargetRx8":0 + }, + "OutputAmplitudeTargetRx":{ + "OutputAmplitudeTargetRx1":1, + "OutputAmplitudeTargetRx2":1, + "OutputAmplitudeTargetRx3":1, + "OutputAmplitudeTargetRx4":1, + "OutputAmplitudeTargetRx5":1, + "OutputAmplitudeTargetRx6":1, + "OutputAmplitudeTargetRx7":1, + "OutputAmplitudeTargetRx8":1 + } + } + } + }, + "11":{ + "100G_SPEED":{ + "Default":{ + "OutputEqPreCursorTargetRx":{ + "OutputEqPreCursorTargetRx1":3, + "OutputEqPreCursorTargetRx2":3, + "OutputEqPreCursorTargetRx3":3, + "OutputEqPreCursorTargetRx4":3, + "OutputEqPreCursorTargetRx5":3, + "OutputEqPreCursorTargetRx6":3, + "OutputEqPreCursorTargetRx7":3, + "OutputEqPreCursorTargetRx8":3 + }, + "OutputEqPostCursorTargetRx":{ + "OutputEqPostCursorTargetRx1":0, + "OutputEqPostCursorTargetRx2":0, + "OutputEqPostCursorTargetRx3":0, + "OutputEqPostCursorTargetRx4":0, + "OutputEqPostCursorTargetRx5":0, + "OutputEqPostCursorTargetRx6":0, + "OutputEqPostCursorTargetRx7":0, + "OutputEqPostCursorTargetRx8":0 + }, + "OutputAmplitudeTargetRx":{ + "OutputAmplitudeTargetRx1":1, + "OutputAmplitudeTargetRx2":1, + "OutputAmplitudeTargetRx3":1, + "OutputAmplitudeTargetRx4":1, + "OutputAmplitudeTargetRx5":1, + "OutputAmplitudeTargetRx6":1, + "OutputAmplitudeTargetRx7":1, + "OutputAmplitudeTargetRx8":1 + } + } + } + }, + "12":{ + "100G_SPEED":{ + "Default":{ + "OutputEqPreCursorTargetRx":{ + "OutputEqPreCursorTargetRx1":3, + "OutputEqPreCursorTargetRx2":3, + "OutputEqPreCursorTargetRx3":3, + "OutputEqPreCursorTargetRx4":3, + "OutputEqPreCursorTargetRx5":3, + "OutputEqPreCursorTargetRx6":3, + "OutputEqPreCursorTargetRx7":3, + "OutputEqPreCursorTargetRx8":3 + }, + "OutputEqPostCursorTargetRx":{ + "OutputEqPostCursorTargetRx1":0, + "OutputEqPostCursorTargetRx2":0, + "OutputEqPostCursorTargetRx3":0, + "OutputEqPostCursorTargetRx4":0, + "OutputEqPostCursorTargetRx5":0, + "OutputEqPostCursorTargetRx6":0, + "OutputEqPostCursorTargetRx7":0, + "OutputEqPostCursorTargetRx8":0 + }, + "OutputAmplitudeTargetRx":{ + "OutputAmplitudeTargetRx1":1, + "OutputAmplitudeTargetRx2":1, + "OutputAmplitudeTargetRx3":1, + "OutputAmplitudeTargetRx4":1, + "OutputAmplitudeTargetRx5":1, + "OutputAmplitudeTargetRx6":1, + "OutputAmplitudeTargetRx7":1, + "OutputAmplitudeTargetRx8":1 + } + } + } } - }, - "1": { - "50G_SPEED": { - "Default": { - "OutputEqPreCursorTargetRx": { - "OutputEqPreCursorTargetRx1": 3, - "OutputEqPreCursorTargetRx2": 3, - "OutputEqPreCursorTargetRx3": 3, - "OutputEqPreCursorTargetRx4": 3, - "OutputEqPreCursorTargetRx5": 3, - "OutputEqPreCursorTargetRx6": 3, - "OutputEqPreCursorTargetRx7": 3, - "OutputEqPreCursorTargetRx8": 3 - }, - "OutputEqPostCursorTargetRx": { - "OutputEqPostCursorTargetRx1": 0, - "OutputEqPostCursorTargetRx2": 0, - "OutputEqPostCursorTargetRx3": 0, - "OutputEqPostCursorTargetRx4": 0, - "OutputEqPostCursorTargetRx5": 0, - "OutputEqPostCursorTargetRx6": 0, - "OutputEqPostCursorTargetRx7": 0, - "OutputEqPostCursorTargetRx8": 0 - }, - "OutputAmplitudeTargetRx": { - "OutputAmplitudeTargetRx1": 1, - "OutputAmplitudeTargetRx2": 1, - "OutputAmplitudeTargetRx3": 1, - "OutputAmplitudeTargetRx4": 1, - "OutputAmplitudeTargetRx5": 1, - "OutputAmplitudeTargetRx6": 1, - "OutputAmplitudeTargetRx7": 1, - "OutputAmplitudeTargetRx8": 1 - } - } - } - }, - "10": { - "50G_SPEED": { - "Default": { - "OutputEqPreCursorTargetRx": { - "OutputEqPreCursorTargetRx1": 3, - "OutputEqPreCursorTargetRx2": 3, - "OutputEqPreCursorTargetRx3": 3, - "OutputEqPreCursorTargetRx4": 3, - "OutputEqPreCursorTargetRx5": 3, - "OutputEqPreCursorTargetRx6": 3, - "OutputEqPreCursorTargetRx7": 3, - "OutputEqPreCursorTargetRx8": 3 - }, - "OutputEqPostCursorTargetRx": { - "OutputEqPostCursorTargetRx1": 0, - "OutputEqPostCursorTargetRx2": 0, - "OutputEqPostCursorTargetRx3": 0, - "OutputEqPostCursorTargetRx4": 0, - "OutputEqPostCursorTargetRx5": 0, - "OutputEqPostCursorTargetRx6": 0, - "OutputEqPostCursorTargetRx7": 0, - "OutputEqPostCursorTargetRx8": 0 - }, - "OutputAmplitudeTargetRx": { - "OutputAmplitudeTargetRx1": 1, - "OutputAmplitudeTargetRx2": 1, - "OutputAmplitudeTargetRx3": 1, - "OutputAmplitudeTargetRx4": 1, - "OutputAmplitudeTargetRx5": 1, - "OutputAmplitudeTargetRx6": 1, - "OutputAmplitudeTargetRx7": 1, - "OutputAmplitudeTargetRx8": 1 - } - } - } - }, - "11": { - "50G_SPEED": { - "Default": { - "OutputEqPreCursorTargetRx": { - "OutputEqPreCursorTargetRx1": 3, - "OutputEqPreCursorTargetRx2": 3, - "OutputEqPreCursorTargetRx3": 3, - "OutputEqPreCursorTargetRx4": 3, - "OutputEqPreCursorTargetRx5": 3, - "OutputEqPreCursorTargetRx6": 3, - "OutputEqPreCursorTargetRx7": 3, - "OutputEqPreCursorTargetRx8": 3 - }, - "OutputEqPostCursorTargetRx": { - "OutputEqPostCursorTargetRx1": 0, - "OutputEqPostCursorTargetRx2": 0, - "OutputEqPostCursorTargetRx3": 0, - "OutputEqPostCursorTargetRx4": 0, - "OutputEqPostCursorTargetRx5": 0, - "OutputEqPostCursorTargetRx6": 0, - "OutputEqPostCursorTargetRx7": 0, - "OutputEqPostCursorTargetRx8": 0 - }, - "OutputAmplitudeTargetRx": { - "OutputAmplitudeTargetRx1": 1, - "OutputAmplitudeTargetRx2": 1, - "OutputAmplitudeTargetRx3": 1, - "OutputAmplitudeTargetRx4": 1, - "OutputAmplitudeTargetRx5": 1, - "OutputAmplitudeTargetRx6": 1, - "OutputAmplitudeTargetRx7": 1, - "OutputAmplitudeTargetRx8": 1 - } - } - } - }, - "12": { - "50G_SPEED": { - "Default": { - "OutputEqPreCursorTargetRx": { - "OutputEqPreCursorTargetRx1": 3, - "OutputEqPreCursorTargetRx2": 3, - "OutputEqPreCursorTargetRx3": 3, - "OutputEqPreCursorTargetRx4": 3, - "OutputEqPreCursorTargetRx5": 3, - "OutputEqPreCursorTargetRx6": 3, - "OutputEqPreCursorTargetRx7": 3, - "OutputEqPreCursorTargetRx8": 3 - }, - "OutputEqPostCursorTargetRx": { - "OutputEqPostCursorTargetRx1": 0, - "OutputEqPostCursorTargetRx2": 0, - "OutputEqPostCursorTargetRx3": 0, - "OutputEqPostCursorTargetRx4": 0, - "OutputEqPostCursorTargetRx5": 0, - "OutputEqPostCursorTargetRx6": 0, - "OutputEqPostCursorTargetRx7": 0, - "OutputEqPostCursorTargetRx8": 0 - }, - "OutputAmplitudeTargetRx": { - "OutputAmplitudeTargetRx1": 1, - "OutputAmplitudeTargetRx2": 1, - "OutputAmplitudeTargetRx3": 1, - "OutputAmplitudeTargetRx4": 1, - "OutputAmplitudeTargetRx5": 1, - "OutputAmplitudeTargetRx6": 1, - "OutputAmplitudeTargetRx7": 1, - "OutputAmplitudeTargetRx8": 1 - } - } - } - } - } + } } - diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index c8a9fb290..621e99200 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -2799,6 +2799,3 @@ def main(): if __name__ == '__main__': main() - - - diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py index 101c12784..fff418563 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/optics_si_parser.py @@ -135,4 +135,3 @@ def optics_si_present(): return True return False - From 5d3b5c0fb94d6e8694bca41637e68a0038212030 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 26 Sep 2023 12:14:37 +0000 Subject: [PATCH 09/39] Replacing wrong print with the relevant log --- sonic-xcvrd/xcvrd/xcvrd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 621e99200..c87ead2e1 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -722,7 +722,7 @@ def get_media_settings_value(physical_port, key): if len(default_dict) != 0: return default_dict else: - print("Error: No values for physical port '{}'".format(physical_port)) + helper_logger.log_error("Error: No values for physical port '{}'".format(physical_port)) return {} if key[0] in media_dict: From d186d88b383dd58de19ac0ca989a48a531656de3 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 26 Sep 2023 12:21:19 +0000 Subject: [PATCH 10/39] removing redundant spaces and comments --- sonic-xcvrd/xcvrd/xcvrd.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index c87ead2e1..1e8a1fdbc 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -1527,11 +1527,10 @@ def wait_for_port_config_done(self, namespace): def task_worker(self): self.xcvr_table_helper = XcvrTableHelper(self.namespaces) - + self.log_notice("Waiting for PortConfigDone...") for namespace in self.namespaces: - self.wait_for_port_config_done(namespace) - + self.wait_for_port_config_done(namespace) # APPL_DB for CONFIG updates, and STATE_DB for insertion/removal sel, asic_context = port_mapping.subscribe_port_update_event(self.namespaces, helper_logger) @@ -1745,7 +1744,7 @@ def task_worker(self): self.log_notice("{}: timeout for 'ModuleReady'".format(lport)) self.force_cmis_reinit(lport, retries + 1) continue - + if not self.check_datapath_state(api, host_lanes_mask, ['DataPathDeactivated']): if (expired is not None) and (expired <= now): self.log_notice("{}: timeout for 'DataPathDeactivated state'".format(lport)) @@ -1782,7 +1781,7 @@ def task_worker(self): self.log_notice("{}: unable to stage custom SI settings ".format(lport)) self.force_cmis_reinit(lport, retries + 1) continue - + # Set Explicit control bit to apply Custom Host SI settings ec = 1 @@ -2490,7 +2489,6 @@ def on_add_logical_port(self, port_change_event): else: post_port_dom_threshold_info_to_db(port_change_event.port_name, self.port_mapping, dom_threshold_tbl) notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) - #notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.port_mapping) else: status = sfp_status_helper.SFP_STATUS_REMOVED if not status else status update_port_transceiver_status_table_sw(port_change_event.port_name, status_tbl, status, error_description) @@ -2516,7 +2514,6 @@ def retry_eeprom_reading(self): rc = post_port_sfp_info_to_db(logical_port, self.port_mapping, self.xcvr_table_helper.get_intf_tbl(asic_index), transceiver_dict) if rc != SFP_EEPROM_NOT_READY: post_port_dom_threshold_info_to_db(logical_port, self.port_mapping, self.xcvr_table_helper.get_dom_threshold_tbl(asic_index)) - # notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.port_mapping) notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) transceiver_dict.clear() retry_success_set.add(logical_port) From 6f8b658ff7bca834c9fa60a4f6eafc6629108117 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 26 Sep 2023 12:28:55 +0000 Subject: [PATCH 11/39] Removed redundant spaces and comments --- sonic-xcvrd/xcvrd/xcvrd.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 1e8a1fdbc..b400cd05c 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -1527,10 +1527,10 @@ def wait_for_port_config_done(self, namespace): def task_worker(self): self.xcvr_table_helper = XcvrTableHelper(self.namespaces) - + self.log_notice("Waiting for PortConfigDone...") for namespace in self.namespaces: - self.wait_for_port_config_done(namespace) + self.wait_for_port_config_done(namespace) # APPL_DB for CONFIG updates, and STATE_DB for insertion/removal sel, asic_context = port_mapping.subscribe_port_update_event(self.namespaces, helper_logger) @@ -1704,13 +1704,11 @@ def task_worker(self): if 0 != freq and freq != api.get_laser_config_freq(): need_update = True - #TODO: uncomment below lines - #if not need_update: - # # No application updates - # helper_logger.log_error("---- shalvi ---- inside if not need_update") - # self.log_notice("{}: no CMIS application update required...READY".format(lport)) - # self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_READY - # continue + if not need_update: + # No application updates + self.log_notice("{}: no CMIS application update required...READY".format(lport)) + self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_READY + continue self.log_notice("{}: force Datapath reinit".format(lport)) self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_DP_DEINIT elif state == self.CMIS_STATE_DP_DEINIT: From 6525e3398e12f580711a7a174156d3f208bdbea2 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 26 Sep 2023 12:31:52 +0000 Subject: [PATCH 12/39] Removed redundant spaces --- sonic-xcvrd/xcvrd/xcvrd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index b400cd05c..e47ebd72f 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -1703,7 +1703,7 @@ def task_worker(self): # force datapath re-initialization if 0 != freq and freq != api.get_laser_config_freq(): need_update = True - + if not need_update: # No application updates self.log_notice("{}: no CMIS application update required...READY".format(lport)) From ad4a4e0a57768eddee329d673d003e89cdcf824f Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 26 Sep 2023 18:23:52 +0000 Subject: [PATCH 13/39] Removed TODOs and redudant spaces --- sonic-xcvrd/xcvrd/xcvrd.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index e47ebd72f..729322c4d 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -109,7 +109,6 @@ # -#TODO: This function is duplicated from the CMIS thread. Need to have one merged function out of the CMIS context def get_cmis_application_desired(api, host_lane_count, speed): """ Get the CMIS application code that matches the specified host side configurations @@ -150,7 +149,6 @@ def get_cmis_application_desired(api, host_lane_count, speed): return None -#TODO: This function is duplicated from the CMIS thread. Need to have one merged function out of the CMIS context def get_interface_speed(ifname): """ Get the port speed from the host interface name @@ -752,7 +750,6 @@ def get_media_settings_value(physical_port, key): return {} -#TODO: update the implementation of this method after getting answers from Prince (probably replacing CONFIG_DB with APP_DB) def get_speed_and_lane_count(port, cfg_port_tbl): port_speed, lane_count = -1, -1 found, port_info = cfg_port_tbl.get(port) @@ -820,9 +817,7 @@ def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_cou else: media_key += '-' + '*' - lane_speed_key = get_lane_speed_key(physical_port, port_speed, lane_count) - return [vendor_key, media_key, lane_speed_key] @@ -904,7 +899,6 @@ 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) helper_logger.log_debug("Retrieving media settings for port {} using the following keys: {}".format(logical_port_name, key)) media_dict = get_media_settings_value(physical_port, key) @@ -1703,7 +1697,7 @@ def task_worker(self): # force datapath re-initialization if 0 != freq and freq != api.get_laser_config_freq(): need_update = True - + if not need_update: # No application updates self.log_notice("{}: no CMIS application update required...READY".format(lport)) From 88b40b9e0475f44d8da93633fddcbdc45dd8ed20 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 1 Oct 2023 10:49:05 +0000 Subject: [PATCH 14/39] Fixes for existing unit tests --- sonic-xcvrd/tests/test_xcvrd.py | 45 ++++++++++++++++++++++++++++----- sonic-xcvrd/xcvrd/xcvrd.py | 10 +++++--- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index a3adf5823..8cec76d53 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -428,7 +428,27 @@ def test_init_port_sfp_status_tbl(self): task = SfpStateUpdateTask(DEFAULT_NAMESPACE, port_mapping, stop_event, sfp_error_event) task._init_port_sfp_status_tbl(port_mapping, xcvr_table_helper, stop_event) - def test_get_media_settings_key(self): + @patch('xcvrd.xcvrd.platform_chassis') + @patch('xcvrd.xcvrd.is_cmis_api', MagicMock(return_value=True)) + def test_get_media_settings_key(self, mock_chassis): + mock_sfp = MagicMock() + mock_chassis.get_sfp = MagicMock(return_value=mock_sfp) + mock_api = MagicMock() + mock_sfp.get_xcvr_api = MagicMock(return_value=mock_api) + + mock_app_adv_value ={ + 1: {'host_electrical_interface_id': '400G CR8', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 8, 'host_lane_count': 8, 'host_lane_assignment_options': 1}, + 2: {'host_electrical_interface_id': '200GBASE-CR4 (Clause 136)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, + 3: {'host_electrical_interface_id': '100GBASE-CR2 (Clause 136)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 2, 'host_lane_count': 2, 'host_lane_assignment_options': 85}, + 4: {'host_electrical_interface_id': '100GBASE-CR4 (Clause 92)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, + 5: {'host_electrical_interface_id': '50GBASE-CR (Clause 126)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 1, 'host_lane_count': 1, 'host_lane_assignment_options': 255}, + 6: {'host_electrical_interface_id': '40GBASE-CR4 (Clause 85)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, + 7: {'host_electrical_interface_id': '25GBASE-CR CA-N (Clause 110)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 1, 'host_lane_count': 1, 'host_lane_assignment_options': 255}, + 8: {'host_electrical_interface_id': '1000BASE -CX(Clause 39)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 1, 'host_lane_count': 1, 'host_lane_assignment_options': 255} + } + + mock_api.get_application_advertisement = MagicMock(return_value=mock_app_adv_value) + xcvr_info_dict = { 0: { 'manufacturer': 'Molex', @@ -441,27 +461,39 @@ def test_get_media_settings_key(self): } # Test a good 'specification_compliance' value - result = get_media_settings_key(0, xcvr_info_dict) - assert result == ['MOLEX-1064141421', 'QSFP+-10GBase-SR-255M'] + result = get_media_settings_key(0, xcvr_info_dict, 100000, 2) + assert result == ['MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'] # Test a bad 'specification_compliance' value xcvr_info_dict[0]['specification_compliance'] = 'N/A' - result = get_media_settings_key(0, xcvr_info_dict) - assert result == ['MOLEX-1064141421', 'QSFP+-*'] + result = get_media_settings_key(0, xcvr_info_dict, 100000, 2) + assert result == ['MOLEX-1064141421', 'QSFP+-*', 'speed:100GBASE-CR2'] # TODO: Ensure that error message was logged @patch('xcvrd.xcvrd.g_dict', media_settings_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) + @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) + @patch('xcvrd.xcvrd.XcvrTableHelper.get_cfg_port_tbl', MagicMock()) + @patch('xcvrd.xcvrd.get_media_settings_key', MagicMock(return_value=['MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'])) + @patch('xcvrd.xcvrd.get_speed_and_lane_count', MagicMock(return_value=(100000, 2))) def test_notify_media_setting(self): self._check_notify_media_setting(1) @patch('xcvrd.xcvrd.g_dict', media_settings_with_comma_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) + @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) + @patch('xcvrd.xcvrd.XcvrTableHelper.get_cfg_port_tbl', MagicMock()) + @patch('xcvrd.xcvrd.get_media_settings_key', MagicMock(return_value=['MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'])) + @patch('xcvrd.xcvrd.get_speed_and_lane_count', MagicMock(return_value=(100000, 2))) def test_notify_media_setting_with_comma(self): self._check_notify_media_setting(1) self._check_notify_media_setting(6) def _check_notify_media_setting(self, index): + 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: { @@ -477,7 +509,7 @@ def _check_notify_media_setting(self, index): port_mapping = PortMapping() port_change_event = PortChangeEvent('Ethernet0', index, 0, PortChangeEvent.PORT_ADD) port_mapping.handle_port_change_event(port_change_event) - notify_media_setting(logical_port_name, xcvr_info_dict, app_port_tbl, port_mapping) + notify_media_setting(logical_port_name, xcvr_info_dict, app_port_tbl, mock_cfg_table, port_mapping) @patch('xcvrd.xcvrd_utilities.optics_si_parser.g_optics_si_dict', optics_si_settings_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) @@ -1168,6 +1200,7 @@ def test_SfpStateUpdateTask_task_run_stop(self): @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) @patch('xcvrd.xcvrd.post_port_sfp_info_to_db') + @patch('xcvrd.xcvrd.XcvrTableHelper.get_cfg_port_tbl', MagicMock()) def test_SfpStateUpdateTask_retry_eeprom_reading(self, mock_post_sfp_info): mock_table = MagicMock() mock_table.get = MagicMock(return_value=(False, None)) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 729322c4d..c18c91cc6 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -109,6 +109,10 @@ # +def is_cmis_api(api): + return type(api) == CmisApi + + def get_cmis_application_desired(api, host_lane_count, speed): """ Get the CMIS application code that matches the specified host side configurations @@ -130,7 +134,7 @@ def get_cmis_application_desired(api, host_lane_count, speed): return 0 appl_code = 0 - if type(api) == CmisApi: + if is_cmis_api(api): appl_dict = api.get_application_advertisement() for c in appl_dict.keys(): d = appl_dict[c] @@ -766,7 +770,7 @@ def get_lane_speed_key(physical_port, port_speed, lane_count): speed_index = get_cmis_application_desired(api, int(lane_count), int(port_speed)) appl_adv_dict, lane_speed_key = None, None - if type(api) == CmisApi: + if is_cmis_api(api): appl_adv_dict = api.get_application_advertisement() if speed_index is not None: lane_speed_key = LANE_SPEED_KEY_PREFIX + (appl_adv_dict[speed_index].get('host_electrical_interface_id')).split()[0] @@ -2480,7 +2484,7 @@ def on_add_logical_port(self, port_change_event): self.retry_eeprom_set.add(port_change_event.port_name) else: post_port_dom_threshold_info_to_db(port_change_event.port_name, self.port_mapping, dom_threshold_tbl) - notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) + notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.xcvr_table_helper.get_cfg_port_tbl(port_change_event.asic_id), self.port_mapping) else: status = sfp_status_helper.SFP_STATUS_REMOVED if not status else status update_port_transceiver_status_table_sw(port_change_event.port_name, status_tbl, status, error_description) From 2b4fe20d1da996d83d2bcc2795c097adb923e667 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Wed, 4 Oct 2023 15:08:01 +0000 Subject: [PATCH 15/39] Fixes after CR with comments --- sonic-xcvrd/xcvrd/xcvrd.py | 211 +++++++++++++++++++++---------------- 1 file changed, 123 insertions(+), 88 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index c18c91cc6..c544c0714 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -24,6 +24,7 @@ from sonic_py_common import daemon_base, device_info, logger from sonic_py_common import multi_asic from swsscommon import swsscommon + from swsscommon.swsscommon import ConfigDBConnector from .xcvrd_utilities import sfp_status_helper from .xcvrd_utilities import port_mapping @@ -128,23 +129,23 @@ def get_cmis_application_desired(api, host_lane_count, speed): Returns: Integer, the transceiver-specific application code """ - app_found = False if speed == 0 or host_lane_count == 0: - return 0 + return None - appl_code = 0 + appl_code = None + app_found = False if is_cmis_api(api): appl_dict = api.get_application_advertisement() - for c in appl_dict.keys(): - d = appl_dict[c] - if d.get('host_lane_count') != host_lane_count: + for index in appl_dict.keys(): + app_info = appl_dict[index] + if app_info.get('host_lane_count') != host_lane_count: continue - if get_interface_speed(d.get('host_electrical_interface_id')) != speed: + if get_interface_speed(app_info.get('host_electrical_interface_id')) != speed: continue - appl_code = c + appl_code = index app_found = True - result_index = appl_code & 0xf + # result_index = appl_code & 0xf break if app_found: @@ -181,6 +182,8 @@ def get_interface_speed(ifname): speed = 10000 elif '1000BASE' in ifname: speed = 1000 + else: + helper_logger.log_error("No interface speed found for: '{}'".format(ifname)) return speed @@ -693,17 +696,17 @@ def get_media_settings_value(physical_port, key): # If there is a match in the global profile for a media type, # fetch those values - if key[0] in media_dict: + if key[0] in media_dict: # key[0] = vendor_key (e.g: 'AMPHENOL-1234') if is_si_per_speed_supported(media_dict[key[0]]): - if key[2] in media_dict[key[0]]: + if key[2] is not None and key[2] in media_dict[key[0]]: # key[2] = lane_speed_key (e.g: 'speed:400GAUI-8') return media_dict[key[0]][key[2]] else: return {} else: return media_dict[key[0]] - elif key[1] in media_dict: + elif key[1] in media_dict: # key[1] = media_key (e.g: 'QSFP28-40GBASE-CR4-1M') if is_si_per_speed_supported(media_dict[key[1]]): - if key[2] in media_dict[key[1]]: + if key[2] is not None and key[2] in media_dict[key[1]]: return media_dict[key[1]][key[2]] else: return {} @@ -729,7 +732,7 @@ def get_media_settings_value(physical_port, key): if key[0] in media_dict: if is_si_per_speed_supported(media_dict[key[0]]): - if key[2] in media_dict[key[0]]: + if key[2] is not None and key[2] in media_dict[key[0]]: return media_dict[key[0]][key[2]] else: return {} @@ -737,7 +740,7 @@ def get_media_settings_value(physical_port, key): return media_dict[key[0]] elif key[1] in media_dict: if is_si_per_speed_supported(media_dict[key[1]]): - if key[2] in media_dict[key[1]]: + if key[2] is not None and key[2] in media_dict[key[1]]: return media_dict[key[1]][key[2]] else: return {} @@ -754,26 +757,41 @@ def get_media_settings_value(physical_port, key): return {} + def get_speed_and_lane_count(port, cfg_port_tbl): - port_speed, lane_count = -1, -1 + port_speed, lane_count = '0', '0' found, port_info = cfg_port_tbl.get(port) - if found and 'speed' in dict(port_info) and 'lanes' in dict(port_info): - port_speed = dict(port_info).get('speed', '-1') - lanes = dict(port_info).get('lanes', '-1') + port_info_dict = dict(port_info) + if found and 'speed' in port_info_dict and 'lanes' in port_info_dict: + port_speed = port_info_dict['speed'] + lanes = port_info_dict['lanes'] lane_count = len(lanes.split(',')) return port_speed, lane_count +# def get_speed_and_lane_count(port, cfg_port_tbl): +# port_speed, lane_count = -1, -1 +# found, port_info = cfg_port_tbl.get(port) +# port_info_dict = dict(port_info) +# if found and 'speed' in port_info_dict and 'lanes' in port_info_dict: +# port_speed = port_info_dict.get('speed', '-1') +# lanes = port_info_dict.get('lanes', '-1') +# lane_count = len(lanes.split(',')) +# return port_speed, lane_count + def get_lane_speed_key(physical_port, port_speed, lane_count): sfp = platform_chassis.get_sfp(physical_port) api = sfp.get_xcvr_api() - speed_index = get_cmis_application_desired(api, int(lane_count), int(port_speed)) + # app_id = get_cmis_application_desired(api, int(lane_count), int(port_speed)) - appl_adv_dict, lane_speed_key = None, None + lane_speed_key = None if is_cmis_api(api): appl_adv_dict = api.get_application_advertisement() - if speed_index is not None: - lane_speed_key = LANE_SPEED_KEY_PREFIX + (appl_adv_dict[speed_index].get('host_electrical_interface_id')).split()[0] + app_id = get_cmis_application_desired(api, int(lane_count), int(port_speed)) + if app_id: + host_electrical_interface_id = appl_adv_dict[app_id].get('host_electrical_interface_id') + if host_electrical_interface_id: + lane_speed_key = LANE_SPEED_KEY_PREFIX + host_electrical_interface_id.split()[0] return lane_speed_key @@ -905,6 +923,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, ganged_member_num += 1 key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) helper_logger.log_debug("Retrieving media settings for port {} using the following keys: {}".format(logical_port_name, key)) + #TODO: check if we need to add here: "if suppoerted " media_dict = get_media_settings_value(physical_port, key) if len(media_dict) == 0: @@ -1094,66 +1113,66 @@ def on_port_update_event(self, port_change_event): else: self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_REMOVED - def get_interface_speed(self, ifname): - """ - Get the port speed from the host interface name - - Args: - ifname: String, interface name - - Returns: - Integer, the port speed if success otherwise 0 - """ - # see HOST_ELECTRICAL_INTERFACE of sff8024.py - speed = 0 - if '400G' in ifname: - speed = 400000 - elif '200G' in ifname: - speed = 200000 - elif '100G' in ifname or 'CAUI-4' in ifname: - speed = 100000 - elif '50G' in ifname or 'LAUI-2' in ifname: - speed = 50000 - elif '40G' in ifname or 'XLAUI' in ifname or 'XLPPI' in ifname: - speed = 40000 - elif '25G' in ifname: - speed = 25000 - elif '10G' in ifname or 'SFI' in ifname or 'XFI' in ifname: - speed = 10000 - elif '1000BASE' in ifname: - speed = 1000 - return speed - - def get_cmis_application_desired(self, api, host_lane_count, speed): - """ - Get the CMIS application code that matches the specified host side configurations - - Args: - api: - XcvrApi object - host_lane_count: - Number of lanes on the host side - speed: - Integer, the port speed of the host interface - - Returns: - Integer, the transceiver-specific application code - """ - if speed == 0 or host_lane_count == 0: - return 0 - - appl_code = 0 - appl_dict = api.get_application_advertisement() - for c in appl_dict.keys(): - d = appl_dict[c] - if d.get('host_lane_count') != host_lane_count: - continue - if self.get_interface_speed(d.get('host_electrical_interface_id')) != speed: - continue - appl_code = c - break - - return (appl_code & 0xf) + # def get_interface_speed(self, ifname): + # """ + # Get the port speed from the host interface name + + # Args: + # ifname: String, interface name + + # Returns: + # Integer, the port speed if success otherwise 0 + # """ + # # see HOST_ELECTRICAL_INTERFACE of sff8024.py + # speed = 0 + # if '400G' in ifname: + # speed = 400000 + # elif '200G' in ifname: + # speed = 200000 + # elif '100G' in ifname or 'CAUI-4' in ifname: + # speed = 100000 + # elif '50G' in ifname or 'LAUI-2' in ifname: + # speed = 50000 + # elif '40G' in ifname or 'XLAUI' in ifname or 'XLPPI' in ifname: + # speed = 40000 + # elif '25G' in ifname: + # speed = 25000 + # elif '10G' in ifname or 'SFI' in ifname or 'XFI' in ifname: + # speed = 10000 + # elif '1000BASE' in ifname: + # speed = 1000 + # return speed + + # def get_cmis_application_desired(self, api, host_lane_count, speed): + # """ + # Get the CMIS application code that matches the specified host side configurations + + # Args: + # api: + # XcvrApi object + # host_lane_count: + # Number of lanes on the host side + # speed: + # Integer, the port speed of the host interface + + # Returns: + # Integer, the transceiver-specific application code + # """ + # if speed == 0 or host_lane_count == 0: + # return 0 + + # appl_code = 0 + # appl_dict = api.get_application_advertisement() + # for c in appl_dict.keys(): + # d = appl_dict[c] + # if d.get('host_lane_count') != host_lane_count: + # continue + # if self.get_interface_speed(d.get('host_electrical_interface_id')) != speed: + # continue + # appl_code = c + # break + + # return (appl_code & 0xf) def get_cmis_dp_init_duration_secs(self, api): return api.get_datapath_init_duration()/1000 @@ -1640,9 +1659,11 @@ def task_worker(self): self.log_notice("Starting CMIS state machine...") # CMIS state transitions if state == self.CMIS_STATE_INSERTED: - self.port_dict[lport]['appl'] = self.get_cmis_application_desired(api, - host_lane_count, host_speed) - if self.port_dict[lport]['appl'] < 1: + # self.port_dict[lport]['appl'] = self.get_cmis_application_desired(api, + # host_lane_count, host_speed) + self.port_dict[lport]['appl'] = get_cmis_application_desired(api, host_lane_count, host_speed) + # if self.port_dict[lport]['appl'] < 1: + if self.port_dict[lport]['appl'] is None: self.log_error("{}: no suitable app for the port appl {} host_lane_count {} " "host_speed {}".format(lport, appl, host_lane_count, host_speed)) self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_FAILED @@ -1756,7 +1777,6 @@ def task_worker(self): else: self.log_notice("{} configured laser frequency {} GHz".format(lport, freq)) - helper_logger.log_debug("Starting to stage custom SI settings") # Stage custom SI settings if optics_si_parser.optics_si_present(): optics_si_dict = {} @@ -1764,7 +1784,7 @@ def task_worker(self): lane_speed = int(speed/1000)//host_lane_count optics_si_dict = optics_si_parser.fetch_optics_si_setting(pport, lane_speed, sfp) - helper_logger.log_debug("SI values for the connected module found in optics_si_settings.json:") + helper_logger.log_debug("Read SI parameters for port {} from optics_si_settings.json vendor file:".format(lport)) for key, sub_dict in optics_si_dict.items(): helper_logger.log_debug("{}".format(key)) for sub_key, value in sub_dict.items(): @@ -2578,6 +2598,18 @@ def load_media_settings(self): with open(media_settings_file_path, "r") as media_file: g_dict = json.load(media_file) + # def create_speeds_cache(self): + # table_name = 'PORT' + # config_db = ConfigDBConnector() + # config_db.connect() + # table_data = config_db.get_table(table_name) + # port_ids = config_db.get_keys(table_name) + # self.log_notice("TOMER: table_data = {}".format(table_data)) + # self.log_notice("TOMER: port_ids = {}".format(port_ids)) + # speeds_cache = {key: value['speed'] for key, value in table_data.items()} + # return speeds_cache + + # Initialize daemon def init(self): global platform_sfputil @@ -2624,6 +2656,9 @@ def init(self): self.load_media_settings() optics_si_parser.load_optics_si_settings() + # speeds_cache = self.create_speeds_cache() + # pdb.set_trace() + # Make sure this daemon started after all port configured self.log_notice("XCVRD INIT: Wait for port config is done") for namespace in self.namespaces: From a2479051489cd01e873f419824f5c4a45ece28c5 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Wed, 4 Oct 2023 15:25:45 +0000 Subject: [PATCH 16/39] Removing redundant comments --- sonic-xcvrd/xcvrd/xcvrd.py | 92 -------------------------------------- 1 file changed, 92 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index c544c0714..2f55a8d9e 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -24,7 +24,6 @@ from sonic_py_common import daemon_base, device_info, logger from sonic_py_common import multi_asic from swsscommon import swsscommon - from swsscommon.swsscommon import ConfigDBConnector from .xcvrd_utilities import sfp_status_helper from .xcvrd_utilities import port_mapping @@ -145,7 +144,6 @@ def get_cmis_application_desired(api, host_lane_count, speed): continue appl_code = index app_found = True - # result_index = appl_code & 0xf break if app_found: @@ -757,7 +755,6 @@ def get_media_settings_value(physical_port, key): return {} - def get_speed_and_lane_count(port, cfg_port_tbl): port_speed, lane_count = '0', '0' found, port_info = cfg_port_tbl.get(port) @@ -768,21 +765,10 @@ def get_speed_and_lane_count(port, cfg_port_tbl): lane_count = len(lanes.split(',')) return port_speed, lane_count -# def get_speed_and_lane_count(port, cfg_port_tbl): -# port_speed, lane_count = -1, -1 -# found, port_info = cfg_port_tbl.get(port) -# port_info_dict = dict(port_info) -# if found and 'speed' in port_info_dict and 'lanes' in port_info_dict: -# port_speed = port_info_dict.get('speed', '-1') -# lanes = port_info_dict.get('lanes', '-1') -# lane_count = len(lanes.split(',')) -# return port_speed, lane_count - def get_lane_speed_key(physical_port, port_speed, lane_count): sfp = platform_chassis.get_sfp(physical_port) api = sfp.get_xcvr_api() - # app_id = get_cmis_application_desired(api, int(lane_count), int(port_speed)) lane_speed_key = None if is_cmis_api(api): @@ -923,7 +909,6 @@ def notify_media_setting(logical_port_name, transceiver_dict, ganged_member_num += 1 key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) helper_logger.log_debug("Retrieving media settings for port {} using the following keys: {}".format(logical_port_name, key)) - #TODO: check if we need to add here: "if suppoerted " media_dict = get_media_settings_value(physical_port, key) if len(media_dict) == 0: @@ -1113,66 +1098,6 @@ def on_port_update_event(self, port_change_event): else: self.port_dict[lport]['cmis_state'] = self.CMIS_STATE_REMOVED - # def get_interface_speed(self, ifname): - # """ - # Get the port speed from the host interface name - - # Args: - # ifname: String, interface name - - # Returns: - # Integer, the port speed if success otherwise 0 - # """ - # # see HOST_ELECTRICAL_INTERFACE of sff8024.py - # speed = 0 - # if '400G' in ifname: - # speed = 400000 - # elif '200G' in ifname: - # speed = 200000 - # elif '100G' in ifname or 'CAUI-4' in ifname: - # speed = 100000 - # elif '50G' in ifname or 'LAUI-2' in ifname: - # speed = 50000 - # elif '40G' in ifname or 'XLAUI' in ifname or 'XLPPI' in ifname: - # speed = 40000 - # elif '25G' in ifname: - # speed = 25000 - # elif '10G' in ifname or 'SFI' in ifname or 'XFI' in ifname: - # speed = 10000 - # elif '1000BASE' in ifname: - # speed = 1000 - # return speed - - # def get_cmis_application_desired(self, api, host_lane_count, speed): - # """ - # Get the CMIS application code that matches the specified host side configurations - - # Args: - # api: - # XcvrApi object - # host_lane_count: - # Number of lanes on the host side - # speed: - # Integer, the port speed of the host interface - - # Returns: - # Integer, the transceiver-specific application code - # """ - # if speed == 0 or host_lane_count == 0: - # return 0 - - # appl_code = 0 - # appl_dict = api.get_application_advertisement() - # for c in appl_dict.keys(): - # d = appl_dict[c] - # if d.get('host_lane_count') != host_lane_count: - # continue - # if self.get_interface_speed(d.get('host_electrical_interface_id')) != speed: - # continue - # appl_code = c - # break - - # return (appl_code & 0xf) def get_cmis_dp_init_duration_secs(self, api): return api.get_datapath_init_duration()/1000 @@ -1659,10 +1584,7 @@ def task_worker(self): self.log_notice("Starting CMIS state machine...") # CMIS state transitions if state == self.CMIS_STATE_INSERTED: - # self.port_dict[lport]['appl'] = self.get_cmis_application_desired(api, - # host_lane_count, host_speed) self.port_dict[lport]['appl'] = get_cmis_application_desired(api, host_lane_count, host_speed) - # if self.port_dict[lport]['appl'] < 1: if self.port_dict[lport]['appl'] is None: self.log_error("{}: no suitable app for the port appl {} host_lane_count {} " "host_speed {}".format(lport, appl, host_lane_count, host_speed)) @@ -2598,17 +2520,6 @@ def load_media_settings(self): with open(media_settings_file_path, "r") as media_file: g_dict = json.load(media_file) - # def create_speeds_cache(self): - # table_name = 'PORT' - # config_db = ConfigDBConnector() - # config_db.connect() - # table_data = config_db.get_table(table_name) - # port_ids = config_db.get_keys(table_name) - # self.log_notice("TOMER: table_data = {}".format(table_data)) - # self.log_notice("TOMER: port_ids = {}".format(port_ids)) - # speeds_cache = {key: value['speed'] for key, value in table_data.items()} - # return speeds_cache - # Initialize daemon def init(self): @@ -2656,9 +2567,6 @@ def init(self): self.load_media_settings() optics_si_parser.load_optics_si_settings() - # speeds_cache = self.create_speeds_cache() - # pdb.set_trace() - # Make sure this daemon started after all port configured self.log_notice("XCVRD INIT: Wait for port config is done") for namespace in self.namespaces: From 3ac3f1fefc6bc25c7de1afe57787ad2f7bfb5cb5 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Wed, 4 Oct 2023 15:33:09 +0000 Subject: [PATCH 17/39] Removing redundant spaces --- sonic-xcvrd/xcvrd/xcvrd.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 2f55a8d9e..9185e338c 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -1698,7 +1698,7 @@ def task_worker(self): self.log_error("{} failed to configure laser frequency {} GHz".format(lport, freq)) else: self.log_notice("{} configured laser frequency {} GHz".format(lport, freq)) - + # Stage custom SI settings if optics_si_parser.optics_si_present(): optics_si_dict = {} @@ -2520,7 +2520,6 @@ def load_media_settings(self): with open(media_settings_file_path, "r") as media_file: g_dict = json.load(media_file) - # Initialize daemon def init(self): global platform_sfputil From ffc026fd0a1e1be7097fbb635e8e8948800ce065 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Wed, 4 Oct 2023 22:01:46 +0000 Subject: [PATCH 18/39] Fixing existing tests after merging duplicated function get_cmis_application_desired() --- sonic-xcvrd/tests/test_xcvrd.py | 4 +++- sonic-xcvrd/xcvrd/xcvrd.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index 8cec76d53..dda5377e1 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -792,6 +792,7 @@ def get_application(lane): assert task.is_cmis_application_update_required(mock_xcvr_api, app_new, host_lanes_mask) == expected + @patch('xcvrd.xcvrd.is_cmis_api', MagicMock(return_value=True)) @pytest.mark.parametrize("host_lane_count, speed, subport, expected", [ (8, 400000, 0, 0xFF), (4, 100000, 1, 0xF), @@ -835,7 +836,7 @@ def get_host_lane_assignment_option_side_effect(app): stop_event = threading.Event() task = CmisManagerTask(DEFAULT_NAMESPACE, port_mapping, stop_event) - appl = task.get_cmis_application_desired(mock_xcvr_api, host_lane_count, speed) + appl = get_cmis_application_desired(mock_xcvr_api, host_lane_count, speed) assert task.get_cmis_host_lanes_mask(mock_xcvr_api, appl, host_lane_count, subport) == expected def test_CmisManagerTask_post_port_active_apsel_to_db(self): @@ -926,6 +927,7 @@ def test_CmisManagerTask_post_port_active_apsel_to_db(self): @patch('xcvrd.xcvrd_utilities.port_mapping.handle_port_update_event', MagicMock()) @patch('xcvrd.xcvrd._wrapper_get_sfp_type', MagicMock(return_value='QSFP_DD')) @patch('xcvrd.xcvrd.CmisManagerTask.wait_for_port_config_done', MagicMock()) + @patch('xcvrd.xcvrd.is_cmis_api', MagicMock(return_value=True)) def test_CmisManagerTask_task_worker(self, mock_chassis): mock_xcvr_api = MagicMock() mock_xcvr_api.set_datapath_deinit = MagicMock(return_value=True) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 9185e338c..e16fa10f1 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -1132,7 +1132,7 @@ def get_cmis_host_lanes_mask(self, api, appl, host_lane_count, subport): """ host_lanes_mask = 0 - if appl < 1 or host_lane_count <= 0 or subport < 0: + if appl is None or host_lane_count <= 0 or subport < 0: self.log_error("Invalid input to get host lane mask - appl {} host_lane_count {} " "subport {}!".format(appl, host_lane_count, subport)) return host_lanes_mask From 6b88870691e8edd411a18f94871ea3dda3131319 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 8 Oct 2023 09:34:10 +0000 Subject: [PATCH 19/39] Fixes after PR #2 --- sonic-xcvrd/xcvrd/xcvrd.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index e16fa10f1..8db0b4858 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -756,7 +756,7 @@ def get_media_settings_value(physical_port, key): def get_speed_and_lane_count(port, cfg_port_tbl): - port_speed, lane_count = '0', '0' + port_speed, lane_count = '0', 0 found, port_info = cfg_port_tbl.get(port) port_info_dict = dict(port_info) if found and 'speed' in port_info_dict and 'lanes' in port_info_dict: @@ -774,7 +774,7 @@ def get_lane_speed_key(physical_port, port_speed, lane_count): if is_cmis_api(api): appl_adv_dict = api.get_application_advertisement() app_id = get_cmis_application_desired(api, int(lane_count), int(port_speed)) - if app_id: + if app_id and app_id in appl_adv_dict: host_electrical_interface_id = appl_adv_dict[app_id].get('host_electrical_interface_id') if host_electrical_interface_id: lane_speed_key = LANE_SPEED_KEY_PREFIX + host_electrical_interface_id.split()[0] @@ -826,7 +826,7 @@ def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_cou media_key += '-' + '*' lane_speed_key = get_lane_speed_key(physical_port, port_speed, lane_count) - return [vendor_key, media_key, lane_speed_key] + return (vendor_key, media_key, lane_speed_key) def get_media_val_str_from_dict(media_dict): @@ -1581,7 +1581,7 @@ def task_worker(self): continue try: - self.log_notice("Starting CMIS state machine...") + self.log_debug("Starting CMIS state machine for port {}".format(lport)) # CMIS state transitions if state == self.CMIS_STATE_INSERTED: self.port_dict[lport]['appl'] = get_cmis_application_desired(api, host_lane_count, host_speed) From 9d86e5976000490e43926974529b9808228df741 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Wed, 11 Oct 2023 08:49:30 +0000 Subject: [PATCH 20/39] Fixed tuple-instead-of-list test issue --- sonic-xcvrd/tests/test_xcvrd.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index dda5377e1..6f3f9de71 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -462,19 +462,19 @@ def test_get_media_settings_key(self, mock_chassis): # Test a good 'specification_compliance' value result = get_media_settings_key(0, xcvr_info_dict, 100000, 2) - assert result == ['MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'] + assert result == ('MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2') # Test a bad 'specification_compliance' value xcvr_info_dict[0]['specification_compliance'] = 'N/A' result = get_media_settings_key(0, xcvr_info_dict, 100000, 2) - assert result == ['MOLEX-1064141421', 'QSFP+-*', 'speed:100GBASE-CR2'] + assert result == ('MOLEX-1064141421', 'QSFP+-*', 'speed:100GBASE-CR2') # TODO: Ensure that error message was logged @patch('xcvrd.xcvrd.g_dict', media_settings_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) @patch('xcvrd.xcvrd.XcvrTableHelper.get_cfg_port_tbl', MagicMock()) - @patch('xcvrd.xcvrd.get_media_settings_key', MagicMock(return_value=['MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'])) + @patch('xcvrd.xcvrd.get_media_settings_key', MagicMock(return_value=('MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'))) @patch('xcvrd.xcvrd.get_speed_and_lane_count', MagicMock(return_value=(100000, 2))) def test_notify_media_setting(self): self._check_notify_media_setting(1) @@ -483,7 +483,7 @@ def test_notify_media_setting(self): @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) @patch('xcvrd.xcvrd.XcvrTableHelper.get_cfg_port_tbl', MagicMock()) - @patch('xcvrd.xcvrd.get_media_settings_key', MagicMock(return_value=['MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'])) + @patch('xcvrd.xcvrd.get_media_settings_key', MagicMock(return_value=('MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'))) @patch('xcvrd.xcvrd.get_speed_and_lane_count', MagicMock(return_value=(100000, 2))) def test_notify_media_setting_with_comma(self): self._check_notify_media_setting(1) From c2ac376dc9f863e004f40b75dad9c6fdad7e5269 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Wed, 11 Oct 2023 17:23:45 +0000 Subject: [PATCH 21/39] Refactoring for the function get_cmis_application_desired() --- sonic-xcvrd/xcvrd/xcvrd.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 8db0b4858..7418a17f2 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -132,23 +132,15 @@ def get_cmis_application_desired(api, host_lane_count, speed): if speed == 0 or host_lane_count == 0: return None - appl_code = None - app_found = False - if is_cmis_api(api): - appl_dict = api.get_application_advertisement() - for index in appl_dict.keys(): - app_info = appl_dict[index] - if app_info.get('host_lane_count') != host_lane_count: - continue - if get_interface_speed(app_info.get('host_electrical_interface_id')) != speed: - continue - appl_code = index - app_found = True - break + if not is_cmis_api(api): + return None + + appl_dict = api.get_application_advertisement() + for index, app_info in appl_dict.items(): + if (app_info.get('host_lane_count') == host_lane_count and + get_interface_speed(app_info.get('host_electrical_interface_id')) == speed): + return (index & 0xf) - if app_found: - return (appl_code & 0xf) - return None From 404e6ffdb3efe8bc19102a96fbe853590fe05d0b Mon Sep 17 00:00:00 2001 From: tshalvi Date: Thu, 12 Oct 2023 07:40:48 +0000 Subject: [PATCH 22/39] Removing log --- sonic-xcvrd/xcvrd/xcvrd.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 7418a17f2..42f706b40 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -1573,7 +1573,6 @@ def task_worker(self): continue try: - self.log_debug("Starting CMIS state machine for port {}".format(lport)) # CMIS state transitions if state == self.CMIS_STATE_INSERTED: self.port_dict[lport]['appl'] = get_cmis_application_desired(api, host_lane_count, host_speed) From 1a7bd24ce027666d8d23d19caabf069c2c56f8e6 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Mon, 16 Oct 2023 13:27:22 +0000 Subject: [PATCH 23/39] Moving media_settings.json functionality to a separate file and updating xcvrd accordingly --- sonic-xcvrd/xcvrd/xcvrd.py | 310 +---------------- .../xcvrd_utilities/media_settings_parser.py | 328 ++++++++++++++++++ 2 files changed, 334 insertions(+), 304 deletions(-) create mode 100644 sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index 42f706b40..a0daeeb62 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -27,6 +27,7 @@ from .xcvrd_utilities import sfp_status_helper from .xcvrd_utilities import port_mapping + from .xcvrd_utilities import media_settings_parser from .xcvrd_utilities import optics_si_parser from sonic_platform_base.sonic_xcvr.api.public.c_cmis import CmisApi @@ -97,8 +98,6 @@ # Global chassis object based on new platform api platform_chassis = None -LANE_SPEED_KEY_PREFIX = "speed:" - # Global logger instance for helper functions and classes # TODO: Refactor so that we only need the logger inherited # by DaemonXcvrd @@ -639,292 +638,6 @@ def del_port_sfp_dom_info_from_db(logical_port_name, port_mapping, int_tbl, dom_ sys.exit(NOT_IMPLEMENTED_ERROR) -def check_port_in_range(range_str, physical_port): - RANGE_SEPARATOR = '-' - - range_list = range_str.split(RANGE_SEPARATOR) - start_num = int(range_list[0].strip()) - end_num = int(range_list[1].strip()) - if start_num <= physical_port <= end_num: - return True - return False - -def is_si_per_speed_supported(media_dict): - return LANE_SPEED_KEY_PREFIX in list(media_dict.keys())[0] - -def get_media_settings_value(physical_port, key): - GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' - PORT_MEDIA_SETTINGS_KEY = 'PORT_MEDIA_SETTINGS' - DEFAULT_KEY = 'Default' - RANGE_SEPARATOR = '-' - COMMA_SEPARATOR = ',' - media_dict = {} - default_dict = {} - - # Keys under global media settings can be a list or range or list of ranges - # of physical port numbers. Below are some examples - # 1-32 - # 1,2,3,4,5 - # 1-4,9-12 - - if GLOBAL_MEDIA_SETTINGS_KEY in g_dict: - for keys in g_dict[GLOBAL_MEDIA_SETTINGS_KEY]: - if COMMA_SEPARATOR in keys: - port_list = keys.split(COMMA_SEPARATOR) - for port in port_list: - if RANGE_SEPARATOR in port: - if check_port_in_range(port, physical_port): - media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] - break - elif str(physical_port) == port: - media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] - break - - elif RANGE_SEPARATOR in keys: - if check_port_in_range(keys, physical_port): - media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] - - # If there is a match in the global profile for a media type, - # fetch those values - if key[0] in media_dict: # key[0] = vendor_key (e.g: 'AMPHENOL-1234') - if is_si_per_speed_supported(media_dict[key[0]]): - if key[2] is not None and key[2] in media_dict[key[0]]: # key[2] = lane_speed_key (e.g: 'speed:400GAUI-8') - return media_dict[key[0]][key[2]] - else: - return {} - else: - return media_dict[key[0]] - elif key[1] in media_dict: # key[1] = media_key (e.g: 'QSFP28-40GBASE-CR4-1M') - if is_si_per_speed_supported(media_dict[key[1]]): - if key[2] is not None and key[2] in media_dict[key[1]]: - return media_dict[key[1]][key[2]] - else: - return {} - else: - return media_dict[key[1]] - elif DEFAULT_KEY in media_dict: - default_dict = media_dict[DEFAULT_KEY] - - media_dict = {} - - if PORT_MEDIA_SETTINGS_KEY in g_dict: - for keys in g_dict[PORT_MEDIA_SETTINGS_KEY]: - if int(keys) == physical_port: - media_dict = g_dict[PORT_MEDIA_SETTINGS_KEY][keys] - break - - if len(media_dict) == 0: - if len(default_dict) != 0: - return default_dict - else: - helper_logger.log_error("Error: No values for physical port '{}'".format(physical_port)) - return {} - - if key[0] in media_dict: - if is_si_per_speed_supported(media_dict[key[0]]): - if key[2] is not None and key[2] in media_dict[key[0]]: - return media_dict[key[0]][key[2]] - else: - return {} - else: - return media_dict[key[0]] - elif key[1] in media_dict: - if is_si_per_speed_supported(media_dict[key[1]]): - if key[2] is not None and key[2] in media_dict[key[1]]: - return media_dict[key[1]][key[2]] - else: - return {} - else: - return media_dict[key[1]] - elif DEFAULT_KEY in media_dict: - return media_dict[DEFAULT_KEY] - elif len(default_dict) != 0: - return default_dict - else: - if len(default_dict) != 0: - return default_dict - - return {} - - -def get_speed_and_lane_count(port, cfg_port_tbl): - port_speed, lane_count = '0', 0 - found, port_info = cfg_port_tbl.get(port) - port_info_dict = dict(port_info) - if found and 'speed' in port_info_dict and 'lanes' in port_info_dict: - port_speed = port_info_dict['speed'] - lanes = port_info_dict['lanes'] - lane_count = len(lanes.split(',')) - return port_speed, lane_count - - -def get_lane_speed_key(physical_port, port_speed, lane_count): - sfp = platform_chassis.get_sfp(physical_port) - api = sfp.get_xcvr_api() - - lane_speed_key = None - if is_cmis_api(api): - appl_adv_dict = api.get_application_advertisement() - app_id = get_cmis_application_desired(api, int(lane_count), int(port_speed)) - if app_id and app_id in appl_adv_dict: - host_electrical_interface_id = appl_adv_dict[app_id].get('host_electrical_interface_id') - if host_electrical_interface_id: - lane_speed_key = LANE_SPEED_KEY_PREFIX + host_electrical_interface_id.split()[0] - - return lane_speed_key - - -def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count): - sup_compliance_str = '10/40G Ethernet Compliance Code' - sup_len_str = 'Length Cable Assembly(m)' - vendor_name_str = transceiver_dict[physical_port]['manufacturer'] - vendor_pn_str = transceiver_dict[physical_port]['model'] - vendor_key = vendor_name_str.upper() + '-' + vendor_pn_str - - media_len = '' - if transceiver_dict[physical_port]['cable_type'] == sup_len_str: - media_len = transceiver_dict[physical_port]['cable_length'] - - media_compliance_dict_str = transceiver_dict[physical_port]['specification_compliance'] - media_compliance_code = '' - media_type = '' - media_key = '' - media_compliance_dict = {} - - try: - if _wrapper_get_sfp_type(physical_port) == 'QSFP_DD': - media_compliance_code = media_compliance_dict_str - else: - media_compliance_dict = ast.literal_eval(media_compliance_dict_str) - if sup_compliance_str in media_compliance_dict: - media_compliance_code = media_compliance_dict[sup_compliance_str] - except ValueError as e: - helper_logger.log_error("Invalid value for port {} 'specification_compliance': {}".format(physical_port, media_compliance_dict_str)) - - media_type = transceiver_dict[physical_port]['type_abbrv_name'] - - if len(media_type) != 0: - media_key += media_type - if len(media_compliance_code) != 0: - media_key += '-' + media_compliance_code - if _wrapper_get_sfp_type(physical_port) == 'QSFP_DD': - if media_compliance_code == "passive_copper_media_interface": - if media_len != 0: - media_key += '-' + str(media_len) + 'M' - else: - if media_len != 0: - media_key += '-' + str(media_len) + 'M' - else: - media_key += '-' + '*' - - lane_speed_key = get_lane_speed_key(physical_port, port_speed, lane_count) - return (vendor_key, media_key, lane_speed_key) - - -def get_media_val_str_from_dict(media_dict): - LANE_STR = 'lane' - LANE_SEPARATOR = ',' - - media_str = '' - tmp_dict = {} - - for keys in media_dict: - lane_num = int(keys.strip()[len(LANE_STR):]) - tmp_dict[lane_num] = media_dict[keys] - - for key in range(0, len(tmp_dict)): - media_str += tmp_dict[key] - if key != list(tmp_dict.keys())[-1]: - media_str += LANE_SEPARATOR - return media_str - - -def get_media_val_str(num_logical_ports, lane_dict, logical_idx): - LANE_STR = 'lane' - - logical_media_dict = {} - num_lanes_on_port = len(lane_dict) - - # The physical ports has more than one logical port meaning it is - # in breakout mode. So fetch the corresponding lanes from the file - media_val_str = '' - if (num_logical_ports > 1) and \ - (num_lanes_on_port >= num_logical_ports): - num_lanes_per_logical_port = num_lanes_on_port//num_logical_ports - start_lane = logical_idx * num_lanes_per_logical_port - - for lane_idx in range(start_lane, start_lane + - num_lanes_per_logical_port): - lane_idx_str = LANE_STR + str(lane_idx) - logical_lane_idx_str = LANE_STR + str(lane_idx - start_lane) - logical_media_dict[logical_lane_idx_str] = lane_dict[lane_idx_str] - - media_val_str = get_media_val_str_from_dict(logical_media_dict) - else: - media_val_str = get_media_val_str_from_dict(lane_dict) - return media_val_str - - -def notify_media_setting(logical_port_name, transceiver_dict, - app_port_tbl, cfg_port_tbl, port_mapping): - - if not g_dict: - return - - port_speed, lane_count = get_speed_and_lane_count(logical_port_name, cfg_port_tbl) - - ganged_port = False - ganged_member_num = 1 - - physical_port_list = port_mapping.logical_port_name_to_physical_port_list(logical_port_name) - if physical_port_list is None: - helper_logger.log_error("Error: No physical ports found for logical port '{}'".format(logical_port_name)) - return PHYSICAL_PORT_NOT_EXIST - - if len(physical_port_list) > 1: - ganged_port = True - - for physical_port in physical_port_list: - logical_port_list = port_mapping.get_physical_to_logical(physical_port) - num_logical_ports = len(logical_port_list) - logical_idx = logical_port_list.index(logical_port_name) - if not _wrapper_get_presence(physical_port): - helper_logger.log_info("Media {} presence not detected during notify".format(physical_port)) - continue - if physical_port not in transceiver_dict: - helper_logger.log_error("Media {} eeprom not populated in transceiver dict".format(physical_port)) - continue - - port_name = get_physical_port_name(logical_port_name, - ganged_member_num, ganged_port) - - ganged_member_num += 1 - key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) - helper_logger.log_debug("Retrieving media settings for port {} using the following keys: {}".format(logical_port_name, key)) - media_dict = get_media_settings_value(physical_port, key) - - if len(media_dict) == 0: - helper_logger.log_error("Error in obtaining media setting for {}".format(logical_port_name)) - return - - fvs = swsscommon.FieldValuePairs(len(media_dict)) - - index = 0 - helper_logger.log_debug("Storing in Application DB the following media settings for port {}:".format(logical_port_name)) - for media_key in media_dict: - if type(media_dict[media_key]) is dict: - media_val_str = get_media_val_str(num_logical_ports, - media_dict[media_key], - logical_idx) - else: - media_val_str = media_dict[media_key] - helper_logger.log_debug("{}:({},{}) ".format(index, str(media_key), str(media_val_str))) - fvs[index] = (str(media_key), str(media_val_str)) - index += 1 - - app_port_tbl.set(port_name, fvs) - - def waiting_time_compensation_with_sleep(time_start, time_to_wait): time_now = time.time() time_diff = time_now - time_start @@ -1996,7 +1709,7 @@ def _post_port_sfp_info_and_dom_thr_to_db_once(self, port_mapping, xcvr_table_he # Do not notify media settings during warm reboot to avoid dataplane traffic impact if is_warm_start == False: - notify_media_setting(logical_port_name, transceiver_dict, xcvr_table_helper.get_app_port_tbl(asic_index), xcvr_table_helper.get_cfg_port_tbl(asic_index), port_mapping) + media_settings_parser.notify_media_setting(logical_port_name, transceiver_dict, xcvr_table_helper.get_app_port_tbl(asic_index), xcvr_table_helper.get_cfg_port_tbl(asic_index), port_mapping) transceiver_dict.clear() else: retry_eeprom_set.add(logical_port_name) @@ -2218,7 +1931,7 @@ def task_worker(self, stopping_event, sfp_error_event): if rc != SFP_EEPROM_NOT_READY: post_port_dom_threshold_info_to_db(logical_port, self.port_mapping, self.xcvr_table_helper.get_dom_threshold_tbl(asic_index)) - notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) + media_settings_parser.notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) transceiver_dict.clear() elif value == sfp_status_helper.SFP_STATUS_REMOVED: helper_logger.log_notice("{}: Got SFP removed event".format(logical_port)) @@ -2417,7 +2130,7 @@ def on_add_logical_port(self, port_change_event): self.retry_eeprom_set.add(port_change_event.port_name) else: post_port_dom_threshold_info_to_db(port_change_event.port_name, self.port_mapping, dom_threshold_tbl) - notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.xcvr_table_helper.get_cfg_port_tbl(port_change_event.asic_id), self.port_mapping) + media_settings_parser.notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.xcvr_table_helper.get_cfg_port_tbl(port_change_event.asic_id), self.port_mapping) else: status = sfp_status_helper.SFP_STATUS_REMOVED if not status else status update_port_transceiver_status_table_sw(port_change_event.port_name, status_tbl, status, error_description) @@ -2443,7 +2156,7 @@ def retry_eeprom_reading(self): rc = post_port_sfp_info_to_db(logical_port, self.port_mapping, self.xcvr_table_helper.get_intf_tbl(asic_index), transceiver_dict) if rc != SFP_EEPROM_NOT_READY: post_port_dom_threshold_info_to_db(logical_port, self.port_mapping, self.xcvr_table_helper.get_dom_threshold_tbl(asic_index)) - notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) + media_settings_parser.notify_media_setting(logical_port, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(asic_index), self.xcvr_table_helper.get_cfg_port_tbl(asic_index), self.port_mapping) transceiver_dict.clear() retry_success_set.add(logical_port) # Update retry EEPROM set @@ -2499,17 +2212,6 @@ def wait_for_port_config_done(self, namespace): if key in ["PortConfigDone", "PortInitDone"]: break - def load_media_settings(self): - global g_dict - (platform_path, _) = device_info.get_paths_to_platform_and_hwsku_dirs() - - media_settings_file_path = os.path.join(platform_path, "media_settings.json") - if not os.path.isfile(media_settings_file_path): - self.log_info("xcvrd: No media file exists") - return {} - - with open(media_settings_file_path, "r") as media_file: - g_dict = json.load(media_file) # Initialize daemon def init(self): @@ -2554,7 +2256,7 @@ def init(self): if is_fast_reboot_enabled(): self.log_info("Skip loading media_settings.json and optics_si_settings.json in case of fast-reboot") else: - self.load_media_settings() + media_settings_parser.load_media_settings() optics_si_parser.load_optics_si_settings() # Make sure this daemon started after all port configured diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py new file mode 100644 index 000000000..14f764be0 --- /dev/null +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -0,0 +1,328 @@ +import json +import os +import ast + +from sonic_py_common import device_info, logger +from swsscommon import swsscommon +from xcvrd import xcvrd + +g_dict = {} + +LANE_SPEED_KEY_PREFIX = "speed:" +VENDOR_KEY = 'vendor_key' +MEDIA_KEY = 'media_key' +LANE_SPEED_KEY = 'lane_speed_key' +SYSLOG_IDENTIFIER = "xcvrd" +helper_logger = logger.Logger(SYSLOG_IDENTIFIER) + + +def load_media_settings(): + global g_dict + (platform_path, _) = device_info.get_paths_to_platform_and_hwsku_dirs() + + media_settings_file_path = os.path.join(platform_path, "media_settings.json") + if not os.path.isfile(media_settings_file_path): + helper_logger.log_info("xcvrd: No media file exists") + return {} + + with open(media_settings_file_path, "r") as media_file: + g_dict = json.load(media_file) + + +def media_settings_present(): + if g_dict: + return True + return False + + +def get_lane_speed_key(physical_port, port_speed, lane_count): + sfp = xcvrd.platform_chassis.get_sfp(physical_port) + api = sfp.get_xcvr_api() + + lane_speed_key = None + if xcvrd.is_cmis_api(api): + appl_adv_dict = api.get_application_advertisement() + app_id = xcvrd.get_cmis_application_desired(api, int(lane_count), int(port_speed)) + if app_id and app_id in appl_adv_dict: + host_electrical_interface_id = appl_adv_dict[app_id].get('host_electrical_interface_id') + if host_electrical_interface_id: + lane_speed_key = LANE_SPEED_KEY_PREFIX + host_electrical_interface_id.split()[0] + + return lane_speed_key + + +def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count): + sup_compliance_str = '10/40G Ethernet Compliance Code' + sup_len_str = 'Length Cable Assembly(m)' + vendor_name_str = transceiver_dict[physical_port]['manufacturer'] + vendor_pn_str = transceiver_dict[physical_port]['model'] + vendor_key = vendor_name_str.upper() + '-' + vendor_pn_str + + media_len = '' + if transceiver_dict[physical_port]['cable_type'] == sup_len_str: + media_len = transceiver_dict[physical_port]['cable_length'] + + media_compliance_dict_str = transceiver_dict[physical_port]['specification_compliance'] + media_compliance_code = '' + media_type = '' + media_key = '' + media_compliance_dict = {} + + try: + if xcvrd._wrapper_get_sfp_type(physical_port) == 'QSFP_DD': + media_compliance_code = media_compliance_dict_str + else: + media_compliance_dict = ast.literal_eval(media_compliance_dict_str) + if sup_compliance_str in media_compliance_dict: + media_compliance_code = media_compliance_dict[sup_compliance_str] + except ValueError as e: + helper_logger.log_error("Invalid value for port {} 'specification_compliance': {}".format(physical_port, media_compliance_dict_str)) + + media_type = transceiver_dict[physical_port]['type_abbrv_name'] + + if len(media_type) != 0: + media_key += media_type + if len(media_compliance_code) != 0: + media_key += '-' + media_compliance_code + if xcvrd._wrapper_get_sfp_type(physical_port) == 'QSFP_DD': + if media_compliance_code == "passive_copper_media_interface": + if media_len != 0: + media_key += '-' + str(media_len) + 'M' + else: + if media_len != 0: + media_key += '-' + str(media_len) + 'M' + else: + media_key += '-' + '*' + + lane_speed_key = get_lane_speed_key(physical_port, port_speed, lane_count) + # return (vendor_key, media_key, lane_speed_key) + return { + VENDOR_KEY: vendor_key, + MEDIA_KEY: media_key, + LANE_SPEED_KEY: lane_speed_key + } + + +def is_si_per_speed_supported(media_dict): + return LANE_SPEED_KEY_PREFIX in list(media_dict.keys())[0] + + +def check_port_in_range(range_str, physical_port): + RANGE_SEPARATOR = '-' + + range_list = range_str.split(RANGE_SEPARATOR) + start_num = int(range_list[0].strip()) + end_num = int(range_list[1].strip()) + if start_num <= physical_port <= end_num: + return True + return False + + +def get_media_val_str_from_dict(media_dict): + LANE_STR = 'lane' + LANE_SEPARATOR = ',' + + media_str = '' + tmp_dict = {} + + for keys in media_dict: + lane_num = int(keys.strip()[len(LANE_STR):]) + tmp_dict[lane_num] = media_dict[keys] + + for key in range(0, len(tmp_dict)): + media_str += tmp_dict[key] + if key != list(tmp_dict.keys())[-1]: + media_str += LANE_SEPARATOR + return media_str + + +def get_media_val_str(num_logical_ports, lane_dict, logical_idx): + LANE_STR = 'lane' + + logical_media_dict = {} + num_lanes_on_port = len(lane_dict) + + # The physical ports has more than one logical port meaning it is + # in breakout mode. So fetch the corresponding lanes from the file + media_val_str = '' + if (num_logical_ports > 1) and \ + (num_lanes_on_port >= num_logical_ports): + num_lanes_per_logical_port = num_lanes_on_port//num_logical_ports + start_lane = logical_idx * num_lanes_per_logical_port + + for lane_idx in range(start_lane, start_lane + + num_lanes_per_logical_port): + lane_idx_str = LANE_STR + str(lane_idx) + logical_lane_idx_str = LANE_STR + str(lane_idx - start_lane) + logical_media_dict[logical_lane_idx_str] = lane_dict[lane_idx_str] + + media_val_str = get_media_val_str_from_dict(logical_media_dict) + else: + media_val_str = get_media_val_str_from_dict(lane_dict) + return media_val_str + + +def get_media_settings_value(physical_port, key): + GLOBAL_MEDIA_SETTINGS_KEY = 'GLOBAL_MEDIA_SETTINGS' + PORT_MEDIA_SETTINGS_KEY = 'PORT_MEDIA_SETTINGS' + DEFAULT_KEY = 'Default' + RANGE_SEPARATOR = '-' + COMMA_SEPARATOR = ',' + media_dict = {} + default_dict = {} + + # Keys under global media settings can be a list or range or list of ranges + # of physical port numbers. Below are some examples + # 1-32 + # 1,2,3,4,5 + # 1-4,9-12 + + if GLOBAL_MEDIA_SETTINGS_KEY in g_dict: + for keys in g_dict[GLOBAL_MEDIA_SETTINGS_KEY]: + if COMMA_SEPARATOR in keys: + port_list = keys.split(COMMA_SEPARATOR) + for port in port_list: + if RANGE_SEPARATOR in port: + if check_port_in_range(port, physical_port): + media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] + break + elif str(physical_port) == port: + media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] + break + + elif RANGE_SEPARATOR in keys: + if check_port_in_range(keys, physical_port): + media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] + + # If there is a match in the global profile for a media type, + # fetch those values + if key[VENDOR_KEY] in media_dict: # e.g: 'AMPHENOL-1234' + if is_si_per_speed_supported(media_dict[key[VENDOR_KEY]]): + if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[VENDOR_KEY]]: # e.g: 'speed:400GAUI-8' + return media_dict[key[VENDOR_KEY]][key[LANE_SPEED_KEY]] + else: + return {} + else: + return media_dict[key[VENDOR_KEY]] + elif key[MEDIA_KEY] in media_dict: # e.g: 'QSFP28-40GBASE-CR4-1M' + if is_si_per_speed_supported(media_dict[key[MEDIA_KEY]]): + if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[MEDIA_KEY]]: + return media_dict[key[MEDIA_KEY]][key[LANE_SPEED_KEY]] + else: + return {} + else: + return media_dict[key[MEDIA_KEY]] + elif DEFAULT_KEY in media_dict: + default_dict = media_dict[DEFAULT_KEY] + + media_dict = {} + + if PORT_MEDIA_SETTINGS_KEY in g_dict: + for keys in g_dict[PORT_MEDIA_SETTINGS_KEY]: + if int(keys) == physical_port: + media_dict = g_dict[PORT_MEDIA_SETTINGS_KEY][keys] + break + + if len(media_dict) == 0: + if len(default_dict) != 0: + return default_dict + else: + helper_logger.log_error("Error: No values for physical port '{}'".format(physical_port)) + return {} + + if key[0] in media_dict: + if is_si_per_speed_supported(media_dict[key[0]]): + if key[2] is not None and key[2] in media_dict[key[0]]: + return media_dict[key[0]][key[2]] + else: + return {} + else: + return media_dict[key[0]] + elif key[1] in media_dict: + if is_si_per_speed_supported(media_dict[key[1]]): + if key[2] is not None and key[2] in media_dict[key[1]]: + return media_dict[key[1]][key[2]] + else: + return {} + else: + return media_dict[key[1]] + elif DEFAULT_KEY in media_dict: + return media_dict[DEFAULT_KEY] + elif len(default_dict) != 0: + return default_dict + else: + if len(default_dict) != 0: + return default_dict + + return {} + + +def get_speed_and_lane_count(port, cfg_port_tbl): + port_speed, lane_count = '0', 0 + found, port_info = cfg_port_tbl.get(port) + port_info_dict = dict(port_info) + if found and 'speed' in port_info_dict and 'lanes' in port_info_dict: + port_speed = port_info_dict['speed'] + lanes = port_info_dict['lanes'] + lane_count = len(lanes.split(',')) + return port_speed, lane_count + + +def notify_media_setting(logical_port_name, transceiver_dict, + app_port_tbl, cfg_port_tbl, port_mapping): + + if not media_settings_present(): + return + + port_speed, lane_count = get_speed_and_lane_count(logical_port_name, cfg_port_tbl) + + ganged_port = False + ganged_member_num = 1 + + physical_port_list = port_mapping.logical_port_name_to_physical_port_list(logical_port_name) + if physical_port_list is None: + helper_logger.log_error("Error: No physical ports found for logical port '{}'".format(logical_port_name)) + return PHYSICAL_PORT_NOT_EXIST + + if len(physical_port_list) > 1: + ganged_port = True + + for physical_port in physical_port_list: + logical_port_list = port_mapping.get_physical_to_logical(physical_port) + num_logical_ports = len(logical_port_list) + logical_idx = logical_port_list.index(logical_port_name) + if not xcvrd._wrapper_get_presence(physical_port): + helper_logger.log_info("Media {} presence not detected during notify".format(physical_port)) + continue + if physical_port not in transceiver_dict: + helper_logger.log_error("Media {} eeprom not populated in transceiver dict".format(physical_port)) + continue + + port_name = xcvrd.get_physical_port_name(logical_port_name, + ganged_member_num, ganged_port) + + ganged_member_num += 1 + key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) + helper_logger.log_error("Retrieving media settings for port {} using the following keys: {}".format(logical_port_name, key)) + media_dict = get_media_settings_value(physical_port, key) + + if len(media_dict) == 0: + helper_logger.log_error("Error in obtaining media setting for {}".format(logical_port_name)) + return + + fvs = swsscommon.FieldValuePairs(len(media_dict)) + + index = 0 + helper_logger.log_error("Storing in Application DB the following media settings for port {}:".format(logical_port_name)) + for media_key in media_dict: + if type(media_dict[media_key]) is dict: + media_val_str = get_media_val_str(num_logical_ports, + media_dict[media_key], + logical_idx) + else: + media_val_str = media_dict[media_key] + helper_logger.log_error("{}:({},{}) ".format(index, str(media_key), str(media_val_str))) + fvs[index] = (str(media_key), str(media_val_str)) + index += 1 + + app_port_tbl.set(port_name, fvs) From a78b4aa05166fd1e2cd9d40fd2d1931b4cefa940 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 17 Oct 2023 09:02:12 +0000 Subject: [PATCH 24/39] Updating xcvrd test to work with media_settings_parser and moved the function check_port_in_range() from media_settings_parser back to xcvrd as optics_si_parser also uses it --- sonic-xcvrd/tests/test_xcvrd.py | 28 +++++++++++-------- sonic-xcvrd/xcvrd/xcvrd.py | 11 ++++++++ .../xcvrd_utilities/media_settings_parser.py | 15 ++-------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index 6f3f9de71..4d36b3c1c 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -1,6 +1,7 @@ #from unittest.mock import DEFAULT from xcvrd.xcvrd_utilities.port_mapping import * from xcvrd.xcvrd_utilities.sfp_status_helper import * +from xcvrd.xcvrd_utilities.media_settings_parser import * from xcvrd.xcvrd_utilities.optics_si_parser import * from xcvrd.xcvrd import * import pytest @@ -461,21 +462,21 @@ def test_get_media_settings_key(self, mock_chassis): } # Test a good 'specification_compliance' value - result = get_media_settings_key(0, xcvr_info_dict, 100000, 2) - assert result == ('MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2') + result = media_settings_parser.get_media_settings_key(0, xcvr_info_dict, 100000, 2) + assert result == { 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP+-10GBase-SR-255M', 'lane_speed_key': 'speed:100GBASE-CR2' } # Test a bad 'specification_compliance' value xcvr_info_dict[0]['specification_compliance'] = 'N/A' - result = get_media_settings_key(0, xcvr_info_dict, 100000, 2) - assert result == ('MOLEX-1064141421', 'QSFP+-*', 'speed:100GBASE-CR2') + result = media_settings_parser.get_media_settings_key(0, xcvr_info_dict, 100000, 2) + assert result == { 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP+-*', 'lane_speed_key': 'speed:100GBASE-CR2' } # TODO: Ensure that error message was logged @patch('xcvrd.xcvrd.g_dict', media_settings_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) @patch('xcvrd.xcvrd.XcvrTableHelper.get_cfg_port_tbl', MagicMock()) - @patch('xcvrd.xcvrd.get_media_settings_key', MagicMock(return_value=('MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'))) - @patch('xcvrd.xcvrd.get_speed_and_lane_count', MagicMock(return_value=(100000, 2))) + @patch('xcvrd.xcvrd_utilities.media_settings_parser.get_media_settings_key', MagicMock(return_value={ 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP+-10GBase-SR-255M', 'lane_speed_key': 'speed:100GBASE-CR2' })) + @patch('xcvrd.xcvrd_utilities.media_settings_parser.get_speed_and_lane_count', MagicMock(return_value=(100000, 2))) def test_notify_media_setting(self): self._check_notify_media_setting(1) @@ -483,8 +484,8 @@ def test_notify_media_setting(self): @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) @patch('xcvrd.xcvrd.XcvrTableHelper.get_cfg_port_tbl', MagicMock()) - @patch('xcvrd.xcvrd.get_media_settings_key', MagicMock(return_value=('MOLEX-1064141421', 'QSFP+-10GBase-SR-255M', 'speed:100GBASE-CR2'))) - @patch('xcvrd.xcvrd.get_speed_and_lane_count', MagicMock(return_value=(100000, 2))) + @patch('xcvrd.xcvrd_utilities.media_settings_parser.get_media_settings_key', MagicMock(return_value={ 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP+-10GBase-SR-255M', 'lane_speed_key': 'speed:100GBASE-CR2' })) + @patch('xcvrd.xcvrd_utilities.media_settings_parser.get_speed_and_lane_count', MagicMock(return_value=(100000, 2))) def test_notify_media_setting_with_comma(self): self._check_notify_media_setting(1) self._check_notify_media_setting(6) @@ -509,7 +510,7 @@ def _check_notify_media_setting(self, index): port_mapping = PortMapping() port_change_event = PortChangeEvent('Ethernet0', index, 0, PortChangeEvent.PORT_ADD) port_mapping.handle_port_change_event(port_change_event) - notify_media_setting(logical_port_name, xcvr_info_dict, app_port_tbl, mock_cfg_table, port_mapping) + media_settings_parser.notify_media_setting(logical_port_name, xcvr_info_dict, app_port_tbl, mock_cfg_table, port_mapping) @patch('xcvrd.xcvrd_utilities.optics_si_parser.g_optics_si_dict', optics_si_settings_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) @@ -792,6 +793,7 @@ def get_application(lane): assert task.is_cmis_application_update_required(mock_xcvr_api, app_new, host_lanes_mask) == expected + @patch('xcvrd.xcvrd.is_cmis_api', MagicMock(return_value=True)) @pytest.mark.parametrize("host_lane_count, speed, subport, expected", [ (8, 400000, 0, 0xFF), @@ -839,6 +841,7 @@ def get_host_lane_assignment_option_side_effect(app): appl = get_cmis_application_desired(mock_xcvr_api, host_lane_count, speed) assert task.get_cmis_host_lanes_mask(mock_xcvr_api, appl, host_lane_count, subport) == expected + def test_CmisManagerTask_post_port_active_apsel_to_db(self): mock_xcvr_api = MagicMock() mock_xcvr_api.get_active_apsel_hostlane = MagicMock(side_effect=[ @@ -922,6 +925,7 @@ def test_CmisManagerTask_post_port_active_apsel_to_db(self): ret = task.post_port_active_apsel_to_db(mock_xcvr_api, lport, host_lanes_mask) assert int_tbl.getKeys() == [] + @patch('xcvrd.xcvrd.platform_chassis') @patch('xcvrd.xcvrd_utilities.port_mapping.subscribe_port_update_event', MagicMock(return_value=(None, None))) @patch('xcvrd.xcvrd_utilities.port_mapping.handle_port_update_event', MagicMock()) @@ -1263,7 +1267,7 @@ def test_SfpStateUpdateTask_mapping_event_from_change_event(self): @patch('xcvrd.xcvrd.SfpStateUpdateTask._mapping_event_from_change_event') @patch('xcvrd.xcvrd._wrapper_get_transceiver_change_event') @patch('xcvrd.xcvrd.del_port_sfp_dom_info_from_db') - @patch('xcvrd.xcvrd.notify_media_setting') + @patch('xcvrd.xcvrd_utilities.media_settings_parser.notify_media_setting') @patch('xcvrd.xcvrd.post_port_dom_threshold_info_to_db') @patch('xcvrd.xcvrd.post_port_sfp_info_to_db') @patch('xcvrd.xcvrd.update_port_transceiver_status_table_sw') @@ -1359,7 +1363,7 @@ def test_SfpStateUpdateTask_task_worker(self, mock_del_status_hw, @patch('xcvrd.xcvrd.XcvrTableHelper') @patch('xcvrd.xcvrd._wrapper_get_presence') - @patch('xcvrd.xcvrd.notify_media_setting') + @patch('xcvrd.xcvrd_utilities.media_settings_parser.notify_media_setting') @patch('xcvrd.xcvrd.post_port_dom_threshold_info_to_db') @patch('xcvrd.xcvrd.post_port_sfp_info_to_db') @patch('xcvrd.xcvrd.update_port_transceiver_status_table_sw') @@ -1632,7 +1636,7 @@ def test_check_port_in_range(self): def test_get_media_val_str_from_dict(self): media_dict = {'lane0': '1', 'lane1': '2'} - media_str = get_media_val_str_from_dict(media_dict) + media_str = media_settings_parser.get_media_val_str_from_dict(media_dict) assert media_str == '1,2' def test_get_media_val_str(self): diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index a0daeeb62..bd59329fc 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -638,6 +638,17 @@ def del_port_sfp_dom_info_from_db(logical_port_name, port_mapping, int_tbl, dom_ sys.exit(NOT_IMPLEMENTED_ERROR) +def check_port_in_range(range_str, physical_port): + RANGE_SEPARATOR = '-' + + range_list = range_str.split(RANGE_SEPARATOR) + start_num = int(range_list[0].strip()) + end_num = int(range_list[1].strip()) + if start_num <= physical_port <= end_num: + return True + return False + + def waiting_time_compensation_with_sleep(time_start, time_to_wait): time_now = time.time() time_diff = time_now - time_start diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py index 14f764be0..a5724922e 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -107,17 +107,6 @@ def is_si_per_speed_supported(media_dict): return LANE_SPEED_KEY_PREFIX in list(media_dict.keys())[0] -def check_port_in_range(range_str, physical_port): - RANGE_SEPARATOR = '-' - - range_list = range_str.split(RANGE_SEPARATOR) - start_num = int(range_list[0].strip()) - end_num = int(range_list[1].strip()) - if start_num <= physical_port <= end_num: - return True - return False - - def get_media_val_str_from_dict(media_dict): LANE_STR = 'lane' LANE_SEPARATOR = ',' @@ -183,7 +172,7 @@ def get_media_settings_value(physical_port, key): port_list = keys.split(COMMA_SEPARATOR) for port in port_list: if RANGE_SEPARATOR in port: - if check_port_in_range(port, physical_port): + if xcvrd.check_port_in_range(port, physical_port): media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] break elif str(physical_port) == port: @@ -191,7 +180,7 @@ def get_media_settings_value(physical_port, key): break elif RANGE_SEPARATOR in keys: - if check_port_in_range(keys, physical_port): + if xcvrd.check_port_in_range(keys, physical_port): media_dict = g_dict[GLOBAL_MEDIA_SETTINGS_KEY][keys] # If there is a match in the global profile for a media type, From de9922848f139db1718b718230ddb767180e6a7e Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 17 Oct 2023 09:06:19 +0000 Subject: [PATCH 25/39] Changed some logs in media_settings_parser from log_error to log_debug --- sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py index a5724922e..52a4b9f38 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -292,7 +292,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, ganged_member_num += 1 key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) - helper_logger.log_error("Retrieving media settings for port {} using the following keys: {}".format(logical_port_name, key)) + helper_logger.log_debug("Retrieving media settings for port {} using the following keys: {}".format(logical_port_name, key)) media_dict = get_media_settings_value(physical_port, key) if len(media_dict) == 0: @@ -302,7 +302,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, fvs = swsscommon.FieldValuePairs(len(media_dict)) index = 0 - helper_logger.log_error("Storing in Application DB the following media settings for port {}:".format(logical_port_name)) + helper_logger.log_debug("Storing in Application DB the following media settings for port {}:".format(logical_port_name)) for media_key in media_dict: if type(media_dict[media_key]) is dict: media_val_str = get_media_val_str(num_logical_ports, @@ -310,7 +310,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, logical_idx) else: media_val_str = media_dict[media_key] - helper_logger.log_error("{}:({},{}) ".format(index, str(media_key), str(media_val_str))) + helper_logger.log_debug("{}:({},{}) ".format(index, str(media_key), str(media_val_str))) fvs[index] = (str(media_key), str(media_val_str)) index += 1 From 50ad9b23c67d2dee77d26136144c8576edb5d20a Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 22 Oct 2023 15:59:19 +0000 Subject: [PATCH 26/39] Adding a docstring to describe media_settings_parser's functionality --- sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py index 52a4b9f38..779395e7d 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -1,3 +1,7 @@ +""" +This parser is responsible for parsing the ASIC side SerDes custom SI settings. +""" + import json import os import ast From 08a80ee2eb43a3d070ad34f4f22b5ae4c0116680 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Thu, 26 Oct 2023 09:40:05 +0000 Subject: [PATCH 27/39] Added new unit test - test_get_speed_and_lane_count --- sonic-xcvrd/tests/test_xcvrd.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index 4d36b3c1c..cadf062a8 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -471,6 +471,19 @@ def test_get_media_settings_key(self, mock_chassis): assert result == { 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP+-*', 'lane_speed_key': 'speed:100GBASE-CR2' } # TODO: Ensure that error message was logged + @pytest.mark.parametrize("data_found, data, expected", [ + (True, [('speed', '400000'), ('lanes', '1,2,3,4,5,6,7,8'), ('mtu', '9100')], ('400000', 8)), + (True, [('lanes', '1,2,3,4,5,6,7,8'), ('mtu', '9100')], ('0', 0)), + (True, [('speed', '400000'), ('mtu', '9100')], ('0', 0)), + (False, [], ('0', 0)) + ]) + def test_get_speed_and_lane_count(self, data_found, data, expected): + cfg_port_tbl = MagicMock() + cfg_port_tbl.get = MagicMock(return_value=(data_found, data)) + port = MagicMock() + + assert media_settings_parser.get_speed_and_lane_count(port, cfg_port_tbl) == expected + @patch('xcvrd.xcvrd.g_dict', media_settings_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) From 0690bf5c8ac6f90acf00ece6886a09863986f09e Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 29 Oct 2023 10:02:52 +0000 Subject: [PATCH 28/39] Added new unit test to meet coverage reqirement (test_is_si_per_speed_supported() and test_get_interface_speed()) --- sonic-xcvrd/tests/test_xcvrd.py | 74 +++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index cadf062a8..5032c2047 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -484,6 +484,61 @@ def test_get_speed_and_lane_count(self, data_found, data, expected): assert media_settings_parser.get_speed_and_lane_count(port, cfg_port_tbl) == expected + def test_is_si_per_speed_supported(self): + media_dict = { + 'speed:400G-GAUI-4':{ + 'main':{ + 'lane0': '0x00000000', + 'lane1': '0x00000000', + 'lane2': '0x00000000', + 'lane3': '0x00000000', + 'lane4': '0x00000000', + 'lane5': '0x00000000', + 'lane6': '0x00000000', + 'lane7': '0x00000000' + } + }, + 'speed:400GAUI-8':{ + 'post1':{ + 'lane0': '0x00000000', + 'lane1': '0x00000000', + 'lane2': '0x00000000', + 'lane3': '0x00000000', + 'lane4': '0x00000000', + 'lane5': '0x00000000', + 'lane6': '0x00000000', + 'lane7': '0x00000000' + } + } + } + result = is_si_per_speed_supported(media_dict) + assert result == True + + media_dict = { + 'main':{ + 'lane0': '0x00000000', + 'lane1': '0x00000000', + 'lane2': '0x00000000', + 'lane3': '0x00000000', + 'lane4': '0x00000000', + 'lane5': '0x00000000', + 'lane6': '0x00000000', + 'lane7': '0x00000000' + }, + 'post1':{ + 'lane0': '0x00000000', + 'lane1': '0x00000000', + 'lane2': '0x00000000', + 'lane3': '0x00000000', + 'lane4': '0x00000000', + 'lane5': '0x00000000', + 'lane6': '0x00000000', + 'lane7': '0x00000000' + } + } + result = is_si_per_speed_supported(media_dict) + assert result == False + @patch('xcvrd.xcvrd.g_dict', media_settings_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) @@ -806,6 +861,25 @@ def get_application(lane): assert task.is_cmis_application_update_required(mock_xcvr_api, app_new, host_lanes_mask) == expected + @pytest.mark.parametrize("ifname, expected", [ + ('400G CR8', 400000), + ('200GBASE-CR4 (Clause 136)', 200000), + ('100GBASE-CR2 (Clause 136)', 100000), + ('CAUI-4 C2M (Annex 83E)', 100000), + ('50GBASE-CR', 50000), + ('LAUI-2 C2M (Annex 135C)', 50000), + ('40GBASE-CR4 (Clause 85)', 40000), + ('XLAUI C2M (Annex 83B)', 40000), + ('XLPPI (Annex 86A)', 40000), + ('25GBASE-CR CA-N (Clause 110)', 25000), + ('10GBASE-CX4 (Clause 54)', 10000), + ('SFI (SFF-8431)', 10000), + ('XFI (SFF INF-8071i)', 10000), + ('1000BASE -CX(Clause 39)', 1000), + ('Unknown Interface', 0) + ]) + def test_get_interface_speed(self, ifname, expected): + assert get_interface_speed(ifname) == expected @patch('xcvrd.xcvrd.is_cmis_api', MagicMock(return_value=True)) @pytest.mark.parametrize("host_lane_count, speed, subport, expected", [ From f6ec4f38db31c084c4222e094b1e32693c00d0eb Mon Sep 17 00:00:00 2001 From: tshalvi Date: Mon, 6 Nov 2023 19:50:22 +0000 Subject: [PATCH 29/39] Updated CMIS module verification with the new method is_cmis_api() --- .../xcvrd/xcvrd_utilities/media_settings_parser.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py index 779395e7d..cc2c5c227 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -73,7 +73,9 @@ def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_cou media_compliance_dict = {} try: - if xcvrd._wrapper_get_sfp_type(physical_port) == 'QSFP_DD': + sfp = xcvrd.platform_chassis.get_sfp(physical_port) + api = sfp.get_xcvr_api() + if xcvrd.is_cmis_api(api): media_compliance_code = media_compliance_dict_str else: media_compliance_dict = ast.literal_eval(media_compliance_dict_str) @@ -88,7 +90,9 @@ def get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_cou media_key += media_type if len(media_compliance_code) != 0: media_key += '-' + media_compliance_code - if xcvrd._wrapper_get_sfp_type(physical_port) == 'QSFP_DD': + sfp = xcvrd.platform_chassis.get_sfp(physical_port) + api = sfp.get_xcvr_api() + if xcvrd.is_cmis_api(api): if media_compliance_code == "passive_copper_media_interface": if media_len != 0: media_key += '-' + str(media_len) + 'M' From 1ff6b55c45fecf7011a5fa3e8e1023e8ce6ba70f Mon Sep 17 00:00:00 2001 From: tshalvi Date: Tue, 7 Nov 2023 09:05:06 +0000 Subject: [PATCH 30/39] Updated the test for get_media_settings_key() after the latest changes in media_settings_parser --- sonic-xcvrd/tests/test_xcvrd.py | 49 +++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index 5032c2047..ddf8b1f03 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -430,25 +430,13 @@ def test_init_port_sfp_status_tbl(self): task._init_port_sfp_status_tbl(port_mapping, xcvr_table_helper, stop_event) @patch('xcvrd.xcvrd.platform_chassis') - @patch('xcvrd.xcvrd.is_cmis_api', MagicMock(return_value=True)) - def test_get_media_settings_key(self, mock_chassis): + @patch('xcvrd.xcvrd.is_cmis_api') + def test_get_media_settings_key(self, mock_is_cmis_api, mock_chassis): mock_sfp = MagicMock() mock_chassis.get_sfp = MagicMock(return_value=mock_sfp) mock_api = MagicMock() mock_sfp.get_xcvr_api = MagicMock(return_value=mock_api) - - mock_app_adv_value ={ - 1: {'host_electrical_interface_id': '400G CR8', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 8, 'host_lane_count': 8, 'host_lane_assignment_options': 1}, - 2: {'host_electrical_interface_id': '200GBASE-CR4 (Clause 136)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, - 3: {'host_electrical_interface_id': '100GBASE-CR2 (Clause 136)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 2, 'host_lane_count': 2, 'host_lane_assignment_options': 85}, - 4: {'host_electrical_interface_id': '100GBASE-CR4 (Clause 92)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, - 5: {'host_electrical_interface_id': '50GBASE-CR (Clause 126)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 1, 'host_lane_count': 1, 'host_lane_assignment_options': 255}, - 6: {'host_electrical_interface_id': '40GBASE-CR4 (Clause 85)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, - 7: {'host_electrical_interface_id': '25GBASE-CR CA-N (Clause 110)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 1, 'host_lane_count': 1, 'host_lane_assignment_options': 255}, - 8: {'host_electrical_interface_id': '1000BASE -CX(Clause 39)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 1, 'host_lane_count': 1, 'host_lane_assignment_options': 255} - } - - mock_api.get_application_advertisement = MagicMock(return_value=mock_app_adv_value) + mock_is_cmis_api.return_value = False xcvr_info_dict = { 0: { @@ -463,14 +451,41 @@ def test_get_media_settings_key(self, mock_chassis): # Test a good 'specification_compliance' value result = media_settings_parser.get_media_settings_key(0, xcvr_info_dict, 100000, 2) - assert result == { 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP+-10GBase-SR-255M', 'lane_speed_key': 'speed:100GBASE-CR2' } + assert result == { 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP+-10GBase-SR-255M', 'lane_speed_key': None } # Test a bad 'specification_compliance' value xcvr_info_dict[0]['specification_compliance'] = 'N/A' result = media_settings_parser.get_media_settings_key(0, xcvr_info_dict, 100000, 2) - assert result == { 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP+-*', 'lane_speed_key': 'speed:100GBASE-CR2' } + assert result == { 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP+-*', 'lane_speed_key': None } # TODO: Ensure that error message was logged + mock_is_cmis_api.return_value = True + xcvr_info_dict = { + 0: { + 'manufacturer': 'Molex', + 'model': '1064141421', + 'cable_type': 'Length Cable Assembly(m)', + 'cable_length': '255', + 'specification_compliance': "sm_media_interface", + 'type_abbrv_name': 'QSFP-DD' + } + } + + mock_app_adv_value ={ + 1: {'host_electrical_interface_id': '400G CR8', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 8, 'host_lane_count': 8, 'host_lane_assignment_options': 1}, + 2: {'host_electrical_interface_id': '200GBASE-CR4 (Clause 136)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, + 3: {'host_electrical_interface_id': '100GBASE-CR2 (Clause 136)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 2, 'host_lane_count': 2, 'host_lane_assignment_options': 85}, + 4: {'host_electrical_interface_id': '100GBASE-CR4 (Clause 92)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, + 5: {'host_electrical_interface_id': '50GBASE-CR (Clause 126)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 1, 'host_lane_count': 1, 'host_lane_assignment_options': 255}, + 6: {'host_electrical_interface_id': '40GBASE-CR4 (Clause 85)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, + 7: {'host_electrical_interface_id': '25GBASE-CR CA-N (Clause 110)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 1, 'host_lane_count': 1, 'host_lane_assignment_options': 255}, + 8: {'host_electrical_interface_id': '1000BASE -CX(Clause 39)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 1, 'host_lane_count': 1, 'host_lane_assignment_options': 255} + } + + mock_api.get_application_advertisement = MagicMock(return_value=mock_app_adv_value) + result = media_settings_parser.get_media_settings_key(0, xcvr_info_dict, 100000, 2) + assert result == { 'vendor_key': 'MOLEX-1064141421', 'media_key': 'QSFP-DD-sm_media_interface', 'lane_speed_key': 'speed:100GBASE-CR2' } + @pytest.mark.parametrize("data_found, data, expected", [ (True, [('speed', '400000'), ('lanes', '1,2,3,4,5,6,7,8'), ('mtu', '9100')], ('400000', 8)), (True, [('lanes', '1,2,3,4,5,6,7,8'), ('mtu', '9100')], ('0', 0)), From 2b64b841905f859659defc088d1fbde2141b611c Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 12 Nov 2023 12:14:44 +0000 Subject: [PATCH 31/39] Refined Logs per CR Recommendations --- sonic-xcvrd/xcvrd/xcvrd.py | 9 ++++++--- .../xcvrd/xcvrd_utilities/media_settings_parser.py | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd.py b/sonic-xcvrd/xcvrd/xcvrd.py index bd59329fc..361a2874b 100644 --- a/sonic-xcvrd/xcvrd/xcvrd.py +++ b/sonic-xcvrd/xcvrd/xcvrd.py @@ -755,6 +755,9 @@ def __init__(self, namespaces, port_mapping, main_thread_stop_event, skip_cmis_m self.skip_cmis_mgr = skip_cmis_mgr self.namespaces = namespaces + def log_debug(self, message): + helper_logger.log_debug("CMIS: {}".format(message)) + def log_notice(self, message): helper_logger.log_notice("CMIS: {}".format(message)) @@ -1421,11 +1424,11 @@ def task_worker(self): lane_speed = int(speed/1000)//host_lane_count optics_si_dict = optics_si_parser.fetch_optics_si_setting(pport, lane_speed, sfp) - helper_logger.log_debug("Read SI parameters for port {} from optics_si_settings.json vendor file:".format(lport)) + self.log_debug("Read SI parameters for port {} from optics_si_settings.json vendor file:".format(lport)) for key, sub_dict in optics_si_dict.items(): - helper_logger.log_debug("{}".format(key)) + self.log_debug("{}".format(key)) for sub_key, value in sub_dict.items(): - helper_logger.log_debug("{}: {}".format(sub_key, str(value))) + self.log_debug("{}: {}".format(sub_key, str(value))) if optics_si_dict: self.log_notice("{}: Apply Optics SI found for Vendor: {} PN: {} lane speed: {}G". diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py index cc2c5c227..93d1b63d0 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -300,7 +300,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, ganged_member_num += 1 key = get_media_settings_key(physical_port, transceiver_dict, port_speed, lane_count) - helper_logger.log_debug("Retrieving media settings for port {} using the following keys: {}".format(logical_port_name, key)) + helper_logger.log_debug("Retrieving media settings for port {}, operating at a speed of {} with a lane count of {}, using the following lookup keys: {}".format(logical_port_name, port_speed, lane_count, key)) media_dict = get_media_settings_value(physical_port, key) if len(media_dict) == 0: @@ -310,7 +310,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, fvs = swsscommon.FieldValuePairs(len(media_dict)) index = 0 - helper_logger.log_debug("Storing in Application DB the following media settings for port {}:".format(logical_port_name)) + helper_logger.log_debug("Publishing ASIC-side 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: media_val_str = get_media_val_str(num_logical_ports, From be2938239b085225965a8b129ec33e58b484eee1 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 19 Nov 2023 07:55:59 +0000 Subject: [PATCH 32/39] Tomer: modified log level of the log printed when no data is found in media_settings.json, from leg_error to log_info --- sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py index 93d1b63d0..5b9979804 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -304,7 +304,7 @@ def notify_media_setting(logical_port_name, transceiver_dict, media_dict = get_media_settings_value(physical_port, key) if len(media_dict) == 0: - helper_logger.log_error("Error in obtaining media setting for {}".format(logical_port_name)) + helper_logger.log_info("Error in obtaining media setting for {}".format(logical_port_name)) return fvs = swsscommon.FieldValuePairs(len(media_dict)) From dde725becc3385ec436f2bb699b90e231f217e3c Mon Sep 17 00:00:00 2001 From: tshalvi Date: Mon, 20 Nov 2023 20:02:37 +0000 Subject: [PATCH 33/39] Added new unit tests for media_settings_parser.get_media_settings_value() --- sonic-xcvrd/tests/test_xcvrd.py | 21 +++++++++++++++++++ .../xcvrd/xcvrd_utilities/port_mapping.py | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index ddf8b1f03..ed6e35198 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -51,6 +51,15 @@ port_optics_si_settings['PORT_MEDIA_SETTINGS'] = optics_si_settings_with_comma_dict.pop('PORT_MEDIA_SETTINGS') optics_si_settings_with_comma_dict['GLOBAL_MEDIA_SETTINGS']['0-5,6,7-20,21-31'] = global_optics_si_settings +with open(os.path.join(test_path, 'media_settings_extended_format.json'), 'r') as f: + media_settings_extended_format_dict = json.load(f) + +media_settings_extended_with_lane_speed_trimmed_dict = copy.deepcopy(media_settings_extended_format_dict) +global_ports_module_lane_speed_1 = media_settings_extended_with_lane_speed_trimmed_dict['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-sm_media_interface'].pop('speed:400GAUI-8') +media_settings_extended_with_lane_speed_trimmed_dict['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-sm_media_interface'] = global_ports_module_lane_speed_1 +global_ports_module_lane_speed_2 = media_settings_extended_with_lane_speed_trimmed_dict['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-active_cable_media_interface'].pop('speed:100GAUI-2') +media_settings_extended_with_lane_speed_trimmed_dict['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-active_cable_media_interface'] = global_ports_module_lane_speed_2 + class TestXcvrdThreadException(object): @patch('xcvrd.xcvrd.platform_chassis', MagicMock()) @@ -554,6 +563,18 @@ def test_is_si_per_speed_supported(self): result = is_si_per_speed_supported(media_dict) assert result == False + @patch('xcvrd.xcvrd_utilities.media_settings_parser.g_dict', media_settings_extended_format_dict) + def test_get_media_settings_value_extended_json(self): + result = media_settings_parser.get_media_settings_value(7, {'vendor_key': 'Amphanol-1234', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}) + expected = {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}} + assert result == expected + + @patch('xcvrd.xcvrd_utilities.media_settings_parser.g_dict', media_settings_extended_with_lane_speed_trimmed_dict) + def test_get_media_settings_value_legacy_json(self): + result = media_settings_parser.get_media_settings_value(7, {'vendor_key': 'Amphanol-1234', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}) + expected = {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}} + assert result == expected + @patch('xcvrd.xcvrd.g_dict', media_settings_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) @patch('xcvrd.xcvrd.XcvrTableHelper', MagicMock()) diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/port_mapping.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/port_mapping.py index c7965f343..110ed329b 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/port_mapping.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/port_mapping.py @@ -253,6 +253,13 @@ def read_port_config_change(asic_context, port_mapping, logger, port_change_even port_change_event = PortChangeEvent(key, new_physical_index, asic_context[port_tbl], PortChangeEvent.PORT_ADD) port_change_event_handler(port_change_event) + else: + if port_speed_cache['index'] != fvp['speed']: + # need to somehow call to notify_media_settings() + + + + elif op == swsscommon.DEL_COMMAND: if port_mapping.is_logical_port(key): port_change_event = PortChangeEvent(key, From 721b29ce0546afab85d61cf2cc544064e434ee26 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Mon, 20 Nov 2023 20:06:29 +0000 Subject: [PATCH 34/39] Added a new json for used in some unit test --- .../tests/media_settings_extended_format.json | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 sonic-xcvrd/tests/media_settings_extended_format.json diff --git a/sonic-xcvrd/tests/media_settings_extended_format.json b/sonic-xcvrd/tests/media_settings_extended_format.json new file mode 100644 index 000000000..dd51f3501 --- /dev/null +++ b/sonic-xcvrd/tests/media_settings_extended_format.json @@ -0,0 +1,60 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "0-31": { + "QSFP-DD-sm_media_interface": { + "speed:400GAUI-8": { + "idriver": { + "lane0": "0x0000003c", + "lane1": "0x0000003c", + "lane2": "0x0000003c", + "lane3": "0x0000003c", + "lane4": "0x0000003c", + "lane5": "0x0000003c", + "lane6": "0x0000003c", + "lane7": "0x0000003c" + }, + "pre1": { + "lane0": "0x00000002", + "lane1": "0x00000002", + "lane2": "0x00000002", + "lane3": "0x00000002", + "lane4": "0x00000002", + "lane5": "0x00000002", + "lane6": "0x00000002", + "lane7": "0x00000002" + }, + "ob_m2lp": { + "lane0": "0x0000000e", + "lane1": "0x0000000e", + "lane2": "0x0000000e", + "lane3": "0x0000000e", + "lane4": "0x0000000e", + "lane5": "0x0000000e", + "lane6": "0x0000000e", + "lane7": "0x0000000e" + } + } + }, + "QSFP-DD-active_cable_media_interface":{ + "speed:100GAUI-2": { + "pre1": { + "lane0": "0x00000002", + "lane1": "0x00000002" + }, + "main": { + "lane0": "0x00000020", + "lane1": "0x00000020" + }, + "post1": { + "lane0": "0x00000006", + "lane1": "0x00000006" + }, + "regn_bfm1n": { + "lane0": "0x000000aa", + "lane1": "0x000000aa" + } + } + } + } + } +} \ No newline at end of file From fac5bb22917f3133bfe9ac91036c456dcdb0fdd1 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Mon, 20 Nov 2023 20:17:06 +0000 Subject: [PATCH 35/39] Revert redundant changes in port_mapping (pushed by mistake) --- sonic-xcvrd/xcvrd/xcvrd_utilities/port_mapping.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/port_mapping.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/port_mapping.py index 110ed329b..c7965f343 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/port_mapping.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/port_mapping.py @@ -253,13 +253,6 @@ def read_port_config_change(asic_context, port_mapping, logger, port_change_even port_change_event = PortChangeEvent(key, new_physical_index, asic_context[port_tbl], PortChangeEvent.PORT_ADD) port_change_event_handler(port_change_event) - else: - if port_speed_cache['index'] != fvp['speed']: - # need to somehow call to notify_media_settings() - - - - elif op == swsscommon.DEL_COMMAND: if port_mapping.is_logical_port(key): port_change_event = PortChangeEvent(key, From 0c386aa8b9fd403e4b5ea2da3e0e8068b102c731 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 26 Nov 2023 14:19:02 +0000 Subject: [PATCH 36/39] Fixed the indexes used for lookup in media_settings.json --- .../xcvrd_utilities/media_settings_parser.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py index 5b9979804..2a27422dc 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -227,22 +227,22 @@ def get_media_settings_value(physical_port, key): helper_logger.log_error("Error: No values for physical port '{}'".format(physical_port)) return {} - if key[0] in media_dict: - if is_si_per_speed_supported(media_dict[key[0]]): - if key[2] is not None and key[2] in media_dict[key[0]]: - return media_dict[key[0]][key[2]] + if key[VENDOR_KEY] in media_dict: + if is_si_per_speed_supported(media_dict[key[VENDOR_KEY]]): + if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[VENDOR_KEY]]: + return media_dict[key[VENDOR_KEY]][key[LANE_SPEED_KEY]] else: return {} else: - return media_dict[key[0]] - elif key[1] in media_dict: - if is_si_per_speed_supported(media_dict[key[1]]): - if key[2] is not None and key[2] in media_dict[key[1]]: - return media_dict[key[1]][key[2]] + return media_dict[key[VENDOR_KEY]] + elif key[MEDIA_KEY] in media_dict: + if is_si_per_speed_supported(media_dict[key[MEDIA_KEY]]): + if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[MEDIA_KEY]]: + return media_dict[key[MEDIA_KEY]][key[LANE_SPEED_KEY]] else: return {} else: - return media_dict[key[1]] + return media_dict[key[MEDIA_KEY]] elif DEFAULT_KEY in media_dict: return media_dict[DEFAULT_KEY] elif len(default_dict) != 0: From b5c8c0a94dd0909899dccbcb9b1d766150b3b5e1 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 26 Nov 2023 14:40:49 +0000 Subject: [PATCH 37/39] Added a unit test: test_get_media_settings_value() --- sonic-xcvrd/tests/test_xcvrd.py | 103 +++++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index ed6e35198..eff8e9393 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -54,11 +54,65 @@ with open(os.path.join(test_path, 'media_settings_extended_format.json'), 'r') as f: media_settings_extended_format_dict = json.load(f) -media_settings_extended_with_lane_speed_trimmed_dict = copy.deepcopy(media_settings_extended_format_dict) -global_ports_module_lane_speed_1 = media_settings_extended_with_lane_speed_trimmed_dict['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-sm_media_interface'].pop('speed:400GAUI-8') -media_settings_extended_with_lane_speed_trimmed_dict['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-sm_media_interface'] = global_ports_module_lane_speed_1 -global_ports_module_lane_speed_2 = media_settings_extended_with_lane_speed_trimmed_dict['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-active_cable_media_interface'].pop('speed:100GAUI-2') -media_settings_extended_with_lane_speed_trimmed_dict['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-active_cable_media_interface'] = global_ports_module_lane_speed_2 + +# Creating instances of media_settings.json for testing purposes +# Each instance represents a different possible structure for media_settings.json. +media_settings_global_range_media_key_lane_speed_si = copy.deepcopy(media_settings_extended_format_dict) + +media_settings_global_range_media_key_si = copy.deepcopy(media_settings_extended_format_dict) +media_settings_global_range_media_key_si['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-sm_media_interface'] = media_settings_global_range_media_key_si['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-sm_media_interface'].pop('speed:400GAUI-8') +media_settings_global_range_media_key_si['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-active_cable_media_interface'] = media_settings_global_range_media_key_si['GLOBAL_MEDIA_SETTINGS']['0-31']['QSFP-DD-active_cable_media_interface'].pop('speed:100GAUI-2') + +media_settings_global_range_vendor_key_lane_speed_si = copy.deepcopy(media_settings_extended_format_dict) +media_settings_global_range_vendor_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS']['0-31']['AMPHANOL-1234'] = media_settings_global_range_vendor_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS']['0-31'].pop('QSFP-DD-sm_media_interface') +media_settings_global_range_vendor_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS']['0-31']['AMPHANOL-5678'] = media_settings_global_range_vendor_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS']['0-31'].pop('QSFP-DD-active_cable_media_interface') + +media_settings_global_range_vendor_key_si = copy.deepcopy(media_settings_global_range_vendor_key_lane_speed_si) +media_settings_global_range_vendor_key_si['GLOBAL_MEDIA_SETTINGS']['0-31']['AMPHANOL-1234'] = media_settings_global_range_vendor_key_si['GLOBAL_MEDIA_SETTINGS']['0-31']['AMPHANOL-1234'].pop('speed:400GAUI-8') +media_settings_global_range_vendor_key_si['GLOBAL_MEDIA_SETTINGS']['0-31']['AMPHANOL-5678'] = media_settings_global_range_vendor_key_si['GLOBAL_MEDIA_SETTINGS']['0-31']['AMPHANOL-5678'].pop('speed:100GAUI-2') + +media_settings_global_list_media_key_lane_speed_si = copy.deepcopy(media_settings_extended_format_dict) +new_key = str(','.join([str(i) for i in range(32)])) +media_settings_global_list_media_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS'][new_key] = media_settings_global_list_media_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS'].pop('0-31') + +media_settings_global_list_media_key_si = copy.deepcopy(media_settings_global_range_media_key_si) +media_settings_global_list_media_key_si['GLOBAL_MEDIA_SETTINGS'][new_key] = media_settings_global_list_media_key_si['GLOBAL_MEDIA_SETTINGS'].pop('0-31') + +media_settings_global_list_of_ranges_media_key_lane_speed_si = copy.deepcopy(media_settings_extended_format_dict) +media_settings_global_list_of_ranges_media_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS']['0-15,16-31'] = media_settings_global_list_of_ranges_media_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS'].pop('0-31') + +media_settings_global_list_of_ranges_media_key_si = copy.deepcopy(media_settings_global_range_media_key_si) +media_settings_global_list_of_ranges_media_key_si['GLOBAL_MEDIA_SETTINGS']['0-15,16-31'] = media_settings_global_list_of_ranges_media_key_si['GLOBAL_MEDIA_SETTINGS'].pop('0-31') + +media_settings_global_list_of_ranges_media_key_lane_speed_si_with_default_section = copy.deepcopy(media_settings_extended_format_dict) +media_settings_global_list_of_ranges_media_key_lane_speed_si_with_default_section['GLOBAL_MEDIA_SETTINGS']['0-31']['Default'] = {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}} + +media_settings_port_media_key_lane_speed_si = copy.deepcopy(media_settings_extended_format_dict) +media_settings_port_media_key_lane_speed_si['PORT_MEDIA_SETTINGS'] = {'7': media_settings_port_media_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS'].pop('0-31')} +del media_settings_port_media_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS'] + +media_settings_port_media_key_si = copy.deepcopy(media_settings_port_media_key_lane_speed_si) +media_settings_port_media_key_si['PORT_MEDIA_SETTINGS']['7']["QSFP-DD-sm_media_interface"] = media_settings_port_media_key_si['PORT_MEDIA_SETTINGS']['7']["QSFP-DD-sm_media_interface"].pop("speed:400GAUI-8") +media_settings_port_media_key_si['PORT_MEDIA_SETTINGS']['7']["QSFP-DD-active_cable_media_interface"] = media_settings_port_media_key_si['PORT_MEDIA_SETTINGS']['7']["QSFP-DD-active_cable_media_interface"].pop("speed:100GAUI-2") + +media_settings_port_vendor_key_lane_speed_si = copy.deepcopy(media_settings_port_media_key_lane_speed_si) +media_settings_port_vendor_key_lane_speed_si['PORT_MEDIA_SETTINGS']['7']['AMPHANOL-1234'] = media_settings_port_vendor_key_lane_speed_si['PORT_MEDIA_SETTINGS']['7'].pop('QSFP-DD-sm_media_interface') +media_settings_port_vendor_key_lane_speed_si['PORT_MEDIA_SETTINGS']['7']['AMPHANOL-5678'] = media_settings_port_vendor_key_lane_speed_si['PORT_MEDIA_SETTINGS']['7'].pop('QSFP-DD-active_cable_media_interface') + +media_settings_port_vendor_key_si = copy.deepcopy(media_settings_port_vendor_key_lane_speed_si) +media_settings_port_vendor_key_si['PORT_MEDIA_SETTINGS']['7']['AMPHANOL-1234'] = media_settings_port_vendor_key_si['PORT_MEDIA_SETTINGS']['7']['AMPHANOL-1234'].pop('speed:400GAUI-8') +media_settings_port_vendor_key_si['PORT_MEDIA_SETTINGS']['7']['AMPHANOL-5678'] = media_settings_port_vendor_key_si['PORT_MEDIA_SETTINGS']['7']['AMPHANOL-5678'].pop('speed:100GAUI-2') + +media_settings_global_default_port_media_key_lane_speed_si = copy.deepcopy(media_settings_extended_format_dict) +port_media_settings_data = {'7': media_settings_global_default_port_media_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS'].pop('0-31')} +media_settings_global_default_port_media_key_lane_speed_si['GLOBAL_MEDIA_SETTINGS'] = {'0-31': {'Default': {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}}}} +media_settings_global_default_port_media_key_lane_speed_si['PORT_MEDIA_SETTINGS'] = port_media_settings_data + +media_settings_port_default_media_key_lane_speed_si = copy.deepcopy(media_settings_port_media_key_lane_speed_si) +media_settings_port_default_media_key_lane_speed_si['PORT_MEDIA_SETTINGS']['7']['Default'] = {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}} + +media_settings_empty = {} + class TestXcvrdThreadException(object): @@ -563,17 +617,34 @@ def test_is_si_per_speed_supported(self): result = is_si_per_speed_supported(media_dict) assert result == False - @patch('xcvrd.xcvrd_utilities.media_settings_parser.g_dict', media_settings_extended_format_dict) - def test_get_media_settings_value_extended_json(self): - result = media_settings_parser.get_media_settings_value(7, {'vendor_key': 'Amphanol-1234', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}) - expected = {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}} - assert result == expected - - @patch('xcvrd.xcvrd_utilities.media_settings_parser.g_dict', media_settings_extended_with_lane_speed_trimmed_dict) - def test_get_media_settings_value_legacy_json(self): - result = media_settings_parser.get_media_settings_value(7, {'vendor_key': 'Amphanol-1234', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}) - expected = {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}} - assert result == expected + @pytest.mark.parametrize("media_settings_dict, port, key, expected", [ + (media_settings_global_range_media_key_lane_speed_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_global_range_media_key_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'UNKOWN'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_global_range_vendor_key_lane_speed_si, 7, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'UNKOWN', 'lane_speed_key': 'speed:100GAUI-2'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_global_range_vendor_key_lane_speed_si, 7, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'UNKOWN', 'lane_speed_key': 'MISSING'}, {}), + (media_settings_global_range_vendor_key_si, 7, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'UNKOWN', 'lane_speed_key': 'UNKOWN'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_global_list_media_key_lane_speed_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_global_list_media_key_lane_speed_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'MISSING'}, {}), + (media_settings_global_list_media_key_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'UNKOWN'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_global_list_of_ranges_media_key_lane_speed_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_global_list_of_ranges_media_key_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'UNKOWN'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_global_default_port_media_key_lane_speed_si, 6, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'UNKOWN', 'lane_speed_key': 'speed:100GAUI-2'}, {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}}), + (media_settings_port_vendor_key_lane_speed_si, -1, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'UNKOWN', 'lane_speed_key': 'speed:100GAUI-2'}, {}), + (media_settings_port_media_key_lane_speed_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_port_media_key_lane_speed_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'MISSING'}, {}), + (media_settings_port_media_key_si, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'UNKOWN'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_port_vendor_key_lane_speed_si, 7, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'UNKOWN', 'lane_speed_key': 'speed:100GAUI-2'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_port_vendor_key_lane_speed_si, 7, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'UNKOWN', 'lane_speed_key': 'MISSING'}, {}), + (media_settings_port_vendor_key_si, 7, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'UNKOWN', 'lane_speed_key': 'UNKOWN'}, {'pre1': {'lane0': '0x00000002', 'lane1': '0x00000002'}, 'main': {'lane0': '0x00000020', 'lane1': '0x00000020'}, 'post1': {'lane0': '0x00000006', 'lane1': '0x00000006'}, 'regn_bfm1n': {'lane0': '0x000000aa', 'lane1': '0x000000aa'}}), + (media_settings_port_default_media_key_lane_speed_si, 7, {'vendor_key': 'MISSING', 'media_key': 'MISSING', 'lane_speed_key': 'MISSING'}, {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}}), + (media_settings_global_default_port_media_key_lane_speed_si, 7, {'vendor_key': 'MISSING', 'media_key': 'MISSING', 'lane_speed_key': 'MISSING'}, {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}}), + (media_settings_global_list_of_ranges_media_key_lane_speed_si_with_default_section, 7, {'vendor_key': 'MISSING', 'media_key': 'MISSING', 'lane_speed_key': 'MISSING'}, {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}}), + (media_settings_empty, 7, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}, {}) + ]) + def test_get_media_settings_value(self, media_settings_dict, port, key, expected): + with patch('xcvrd.xcvrd_utilities.media_settings_parser.g_dict', media_settings_dict): + result = media_settings_parser.get_media_settings_value(port, key) + assert result == expected @patch('xcvrd.xcvrd.g_dict', media_settings_dict) @patch('xcvrd.xcvrd._wrapper_get_presence', MagicMock(return_value=True)) From 6d0142be9aca31f2579552bc96d0c7678ab727c8 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 26 Nov 2023 18:47:23 +0000 Subject: [PATCH 38/39] Added new unit test - test_load_media_settings --- sonic-xcvrd/tests/test_xcvrd.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index eff8e9393..97b97902f 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -492,6 +492,15 @@ def test_init_port_sfp_status_tbl(self): task = SfpStateUpdateTask(DEFAULT_NAMESPACE, port_mapping, stop_event, sfp_error_event) task._init_port_sfp_status_tbl(port_mapping, xcvr_table_helper, stop_event) + @patch('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs', MagicMock()) + def test_load_media_settings(self, mock_platform_dir_path): + mock_platform_dir_path.return_value = ('/invalid/path', None) + assert media_settings_parser.load_media_settings() == {} + + mock_platform_dir_path.return_value = (test_path, None) + media_settings_parser.load_media_settings() + assert media_settings_parser.g_dict == media_settings_dict + @patch('xcvrd.xcvrd.platform_chassis') @patch('xcvrd.xcvrd.is_cmis_api') def test_get_media_settings_key(self, mock_is_cmis_api, mock_chassis): From cc91f93f1abe4ad5db7382d15790ddd87c9d4930 Mon Sep 17 00:00:00 2001 From: tshalvi Date: Sun, 26 Nov 2023 20:14:29 +0000 Subject: [PATCH 39/39] Fix for load_media_settings tests --- sonic-xcvrd/tests/test_xcvrd.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index 97b97902f..36b93c0b3 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -492,15 +492,10 @@ def test_init_port_sfp_status_tbl(self): task = SfpStateUpdateTask(DEFAULT_NAMESPACE, port_mapping, stop_event, sfp_error_event) task._init_port_sfp_status_tbl(port_mapping, xcvr_table_helper, stop_event) - @patch('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs', MagicMock()) - def test_load_media_settings(self, mock_platform_dir_path): - mock_platform_dir_path.return_value = ('/invalid/path', None) + @patch('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs', MagicMock(return_value=('/invalid/path', None))) + def test_load_media_settings_missing_file(self): assert media_settings_parser.load_media_settings() == {} - mock_platform_dir_path.return_value = (test_path, None) - media_settings_parser.load_media_settings() - assert media_settings_parser.g_dict == media_settings_dict - @patch('xcvrd.xcvrd.platform_chassis') @patch('xcvrd.xcvrd.is_cmis_api') def test_get_media_settings_key(self, mock_is_cmis_api, mock_chassis):