From 94919de3407728d8806aa513939f4955d6c82d07 Mon Sep 17 00:00:00 2001 From: "Dante (Kuo-Jung) Su" Date: Tue, 7 Dec 2021 21:26:15 +0800 Subject: [PATCH] [sfp-refactoring] Initial support for CMIS application initialization (#219) --- .../sonic_xcvr/api/public/cmis.py | 204 +++++++++++++++- .../sonic_xcvr/api/public/cmisCDB.py | 2 +- .../sonic_xcvr/fields/consts.py | 7 + .../sonic_xcvr/mem_maps/public/cmis.py | 222 ++++++++++++++++++ .../sonic_xcvr/sfp_optoe_base.py | 22 ++ tests/sonic_xcvr/test_cmis.py | 151 +++++++++++- 6 files changed, 601 insertions(+), 7 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index d065f219dedf..e03622d6b88c 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -9,6 +9,8 @@ from ..xcvr_api import XcvrApi import logging +from ...codes.public.cmis import CmisCodes +from ...codes.public.sff8024 import Sff8024 from ...fields import consts from ..xcvr_api import XcvrApi from .cmisCDB import CmisCdbApi @@ -50,6 +52,12 @@ def get_module_type(self): ''' return self.xcvr_eeprom.read(consts.ID_FIELD) + def get_module_type_abbreviation(self): + ''' + This function returns the SFF8024Identifier (module type / form-factor). Table 4-1 in SFF-8024 Rev4.6 + ''' + return self.xcvr_eeprom.read(consts.ID_ABBRV_FIELD) + def get_connector_type(self): ''' This function returns module connector. Table 4-3 in SFF-8024 Rev4.6 @@ -134,10 +142,10 @@ def get_transceiver_info(self): "nominal_bit_rate": 0, # Not supported "specification_compliance": admin_info[consts.MEDIA_TYPE_FIELD], "vendor_date": admin_info[consts.VENDOR_DATE_FIELD], - "vendor_oui": admin_info[consts.VENDOR_OUI_FIELD], - # TODO - "application_advertisement": "N/A", + "vendor_oui": admin_info[consts.VENDOR_OUI_FIELD] } + appl_advt = self.get_application_advertisement() + xcvr_info['application_advertisement'] = str(appl_advt) if len(appl_advt) > 0 else 'N/A' xcvr_info['host_electrical_interface'] = self.get_host_electrical_interface() xcvr_info['media_interface_code'] = self.get_module_media_interface() xcvr_info['host_lane_count'] = self.get_host_lane_count() @@ -876,6 +884,24 @@ def reset_module(self, reset = False): else: return True + def reset(self): + """ + Reset SFP and return all user module settings to their default state. + + Returns: + A boolean, True if successful, False if not + """ + if self.reset_module(True): + # minimum waiting time for the TWI to be functional again + time.sleep(2) + # buffer time + for retries in range(5): + state = self.get_module_state() + if state in ['ModuleReady', 'ModuleLowPwr']: + return True + time.sleep(1) + return False + def get_lpmode(self): ''' Retrieves Low power module status @@ -1745,4 +1771,176 @@ def get_transceiver_loopback(self): for lane in range(1, self.NUM_CHANNELS+1): trans_loopback['host_input_loopback_lane%d' % lane] = 'N/A' return trans_loopback + + def set_datapath_init(self, channel): + """ + Put the CMIS datapath into the initialized state + + Args: + channel: + Integer, a bitmask of the lanes on the host side + e.g. 0x5 for lane 0 and lane 2. + + Returns: + Boolean, true if success otherwise false + """ + cmis_major = self.xcvr_eeprom.read(consts.CMIS_MAJOR_REVISION) + data = self.xcvr_eeprom.read(consts.DATAPATH_DEINIT_FIELD) + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & channel) == 0: + continue + if cmis_major >= 4: # CMIS v4 onwards + data &= ~(1 << lane) + else: # CMIS v3 + data |= (1 << lane) + self.xcvr_eeprom.write(consts.DATAPATH_DEINIT_FIELD, data) + + def set_datapath_deinit(self, channel): + """ + Put the CMIS datapath into the de-initialized state + + Args: + channel: + Integer, a bitmask of the lanes on the host side + e.g. 0x5 for lane 0 and lane 2. + + Returns: + Boolean, true if success otherwise false + """ + cmis_major = self.xcvr_eeprom.read(consts.CMIS_MAJOR_REVISION) + data = self.xcvr_eeprom.read(consts.DATAPATH_DEINIT_FIELD) + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & channel) == 0: + continue + if cmis_major >= 4: # CMIS v4 onwards + data |= (1 << lane) + else: # CMIS v3 + data &= ~(1 << lane) + self.xcvr_eeprom.write(consts.DATAPATH_DEINIT_FIELD, data) + + def get_application_advertisement(self): + """ + Get the application advertisement of the CMIS transceiver + + Returns: + Dictionary, the application advertisement + """ + map = { + Sff8024.MODULE_MEDIA_TYPE[1]: consts.MODULE_MEDIA_INTERFACE_850NM, + Sff8024.MODULE_MEDIA_TYPE[2]: consts.MODULE_MEDIA_INTERFACE_SM, + Sff8024.MODULE_MEDIA_TYPE[3]: consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, + Sff8024.MODULE_MEDIA_TYPE[4]: consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, + Sff8024.MODULE_MEDIA_TYPE[5]: consts.MODULE_MEDIA_INTERFACE_BASE_T + } + + ret = {} + dic = self.xcvr_eeprom.read(consts.APPLS_ADVT_FIELD) + for app in range(1, 16): + buf = {} + + key = "{}_{}".format(consts.HOST_ELECTRICAL_INTERFACE, app) + val = dic.get(key) + if val in [None, 'Unknown', 'Undefined']: + break + buf['host_electrical_interface_id'] = val + + prefix = map.get(self.xcvr_eeprom.read(consts.MEDIA_TYPE_FIELD)) + if prefix is None: + break + key = "{}_{}".format(prefix, app) + val = dic.get(key) + if val in [None, 'Unknown', 'Undefined']: + break + buf['module_media_interface_id'] = val + + key = "{}_{}".format(consts.MEDIA_LANE_COUNT, app) + val = dic.get(key) + if val is None: + break + buf['media_lane_count'] = val + + key = "{}_{}".format(consts.HOST_LANE_COUNT, app) + val = dic.get(key) + if val is None: + break + buf['host_lane_count'] = val + + key = "{}_{}".format(consts.HOST_LANE_ASSIGNMENT_OPTION, app) + val = dic.get(key) + if val is None: + break + buf['host_lane_assignment_options'] = val + + ret[app] = buf + return ret + + def get_application(self, lane): + """ + Get the CMIS selected application code of a host lane + + Args: + lane: + Integer, the zero-based lane id on the host side + + Returns: + Integer, the transceiver-specific application code + """ + appl = 0 + if lane in range(self.NUM_CHANNELS) and not self.is_flat_memory(): + name = "{}_{}_{}".format(consts.STAGED_CTRL_APSEL_FIELD, 0, lane + 1) + appl = self.xcvr_eeprom.read(name) >> 4 + + return (appl & 0xf) + + def set_application(self, channel, appl_code): + """ + Update the selected application code to the specified lanes on the host side + + Args: + channel: + Integer, a bitmask of the lanes on the host side + e.g. 0x5 for lane 0 and lane 2. + appl_code: + Integer, the desired application code + + Returns: + Boolean, true if success otherwise false + """ + # Update the application selection + lane_first = -1 + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & channel) == 0: + continue + if lane_first < 0: + lane_first = lane + addr = "{}_{}_{}".format(consts.STAGED_CTRL_APSEL_FIELD, 0, lane + 1) + data = (appl_code << 4) | (lane_first << 1) + self.xcvr_eeprom.write(addr, data) + + # Apply DataPathInit + return self.xcvr_eeprom.write("%s_%d" % (consts.STAGED_CTRL_APPLY_DPINIT_FIELD, 0), channel) + + def get_error_description(self): + dp_state = self.get_datapath_state() + conf_state = self.get_config_datapath_hostlane_status() + for lane in range(self.NUM_CHANNELS): + name = "{}_{}_{}".format(consts.STAGED_CTRL_APSEL_FIELD, 0, lane + 1) + appl = self.xcvr_eeprom.read(name) + if (appl is None) or ((appl >> 4) == 0): + continue + + name = "DP{}State".format(lane + 1) + if dp_state[name] != CmisCodes.DATAPATH_STATE[4]: + return dp_state[name] + + name = "ConfigStatusLane{}".format(lane + 1) + if conf_state[name] != CmisCodes.CONFIG_STATUS[1]: + return conf_state[name] + + state = self.get_module_state() + if state != CmisCodes.MODULE_STATE[3]: + return state + + return None + # TODO: other XcvrApi methods diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmisCDB.py b/sonic_platform_base/sonic_xcvr/api/public/cmisCDB.py index ad321ad302d7..c3a9c1e157c2 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmisCDB.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmisCDB.py @@ -26,7 +26,7 @@ def __init__(self, xcvr_eeprom): super(CmisCdbApi, self).__init__(xcvr_eeprom) self.cdb_instance_supported = self.xcvr_eeprom.read(consts.CDB_SUPPORT) self.failed_status_dict = self.xcvr_eeprom.mem_map.codes.CDB_FAIL_STATUS - assert self.cdb_instance_supported != 0 + #assert self.cdb_instance_supported != 0 def cdb1_chkflags(self): ''' diff --git a/sonic_platform_base/sonic_xcvr/fields/consts.py b/sonic_platform_base/sonic_xcvr/fields/consts.py index a675dddb168c..bf8205d92047 100644 --- a/sonic_platform_base/sonic_xcvr/fields/consts.py +++ b/sonic_platform_base/sonic_xcvr/fields/consts.py @@ -270,6 +270,7 @@ TRANS_CONFIG_FIELD = "TransceiverConfig" MODULE_LEVEL_CONTROL = "ModuleControl" +APPLS_ADVT_FIELD = "Applications Advertisement" CTRLS_ADVT_FIELD = "Supported Controls Advertisement" FLAGS_ADVT_FIELD = "Supported Flags Advertisement" PAGE_SUPPORT_ADVT_FIELD = "Supported Pages Advertisement" @@ -278,6 +279,7 @@ LANE_MON_ADVT_FIELD = "Supported Lane Monitor Advertisement" LANE_DATAPATH_CTRL_FIELD = "Lane Control and Data Path Control" LANE_DATAPATH_STATUS_FIELD = "Lane Status and Data Path Status" +DATAPATH_DEINIT_FIELD = "Data Path Deinit" LEN_MULT_FIELD = "LengthMultiplier" MAX_POWER_FIELD = "MaxPower" MGMT_CHAR_FIELD = "Management Characteristics" @@ -285,6 +287,11 @@ MODULE_CHAR_ADVT_FIELD = "Module Characteristics Advertising" +STAGED_CTRL_FIELD = "Staged Control Set" +STAGED_CTRL_APPLY_DPINIT_FIELD = "Staged Control Set Apply DataPathInit" +STAGED_CTRL_APPLY_IMMEDIATE_FIELD = "Staged Control Set Apply Immediate" +STAGED_CTRL_APSEL_FIELD = "Staged Control Set ApSel" + # C-CMIS # Module configuration support fields diff --git a/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py b/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py index 2586ee662189..3d8459b77f1f 100644 --- a/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py @@ -51,6 +51,216 @@ def __init__(self, codes): ), CodeRegField(consts.CONNECTOR_FIELD, self.getaddr(0x0, 203), self.codes.CONNECTORS), + + RegGroupField(consts.APPLS_ADVT_FIELD, + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 1), self.getaddr(0x0, 86 + 4 * (1 - 1)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 2), self.getaddr(0x0, 86 + 4 * (2 - 1)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 3), self.getaddr(0x0, 86 + 4 * (3 - 1)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 4), self.getaddr(0x0, 86 + 4 * (4 - 1)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 5), self.getaddr(0x0, 86 + 4 * (5 - 1)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 6), self.getaddr(0x0, 86 + 4 * (6 - 1)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 7), self.getaddr(0x0, 86 + 4 * (7 - 1)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 8), self.getaddr(0x0, 86 + 4 * (8 - 1)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 9), self.getaddr(0x1, 223 + 4 * (9 - 9)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 10), self.getaddr(0x1, 223 + 4 * (10 - 9)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 11), self.getaddr(0x1, 223 + 4 * (11 - 9)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 12), self.getaddr(0x1, 223 + 4 * (12 - 9)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 13), self.getaddr(0x1, 223 + 4 * (13 - 9)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 14), self.getaddr(0x1, 223 + 4 * (14 - 9)), self.codes.HOST_ELECTRICAL_INTERFACE), + CodeRegField("%s_%d" % (consts.HOST_ELECTRICAL_INTERFACE, 15), self.getaddr(0x1, 223 + 4 * (15 - 9)), self.codes.HOST_ELECTRICAL_INTERFACE), + + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 1), self.getaddr(0x0, 87 + 4 * (1 - 1)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 2), self.getaddr(0x0, 87 + 4 * (2 - 1)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 3), self.getaddr(0x0, 87 + 4 * (3 - 1)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 4), self.getaddr(0x0, 87 + 4 * (4 - 1)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 5), self.getaddr(0x0, 87 + 4 * (5 - 1)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 6), self.getaddr(0x0, 87 + 4 * (6 - 1)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 7), self.getaddr(0x0, 87 + 4 * (7 - 1)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 8), self.getaddr(0x0, 87 + 4 * (8 - 1)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 9), self.getaddr(0x1, 224 + 4 * (9 - 9)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 10), self.getaddr(0x1, 224 + 4 * (10 - 9)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 11), self.getaddr(0x1, 224 + 4 * (11 - 9)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 12), self.getaddr(0x1, 224 + 4 * (12 - 9)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 13), self.getaddr(0x1, 224 + 4 * (13 - 9)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 14), self.getaddr(0x1, 224 + 4 * (14 - 9)), self.codes.NM_850_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_850NM, 15), self.getaddr(0x1, 224 + 4 * (15 - 9)), self.codes.NM_850_MEDIA_INTERFACE), + + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 1), self.getaddr(0x0, 87 + 4 * (1 - 1)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 2), self.getaddr(0x0, 87 + 4 * (2 - 1)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 3), self.getaddr(0x0, 87 + 4 * (3 - 1)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 4), self.getaddr(0x0, 87 + 4 * (4 - 1)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 5), self.getaddr(0x0, 87 + 4 * (5 - 1)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 6), self.getaddr(0x0, 87 + 4 * (6 - 1)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 7), self.getaddr(0x0, 87 + 4 * (7 - 1)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 8), self.getaddr(0x0, 87 + 4 * (8 - 1)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 9), self.getaddr(0x1, 224 + 4 * (9 - 9)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 10), self.getaddr(0x1, 224 + 4 * (10 - 9)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 11), self.getaddr(0x1, 224 + 4 * (11 - 9)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 12), self.getaddr(0x1, 224 + 4 * (12 - 9)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 13), self.getaddr(0x1, 224 + 4 * (13 - 9)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 14), self.getaddr(0x1, 224 + 4 * (14 - 9)), self.codes.SM_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_SM, 15), self.getaddr(0x1, 224 + 4 * (15 - 9)), self.codes.SM_MEDIA_INTERFACE), + + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 1), self.getaddr(0x0, 87 + 4 * (1 - 1)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 2), self.getaddr(0x0, 87 + 4 * (2 - 1)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 3), self.getaddr(0x0, 87 + 4 * (3 - 1)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 4), self.getaddr(0x0, 87 + 4 * (4 - 1)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 5), self.getaddr(0x0, 87 + 4 * (5 - 1)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 6), self.getaddr(0x0, 87 + 4 * (6 - 1)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 7), self.getaddr(0x0, 87 + 4 * (7 - 1)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 8), self.getaddr(0x0, 87 + 4 * (8 - 1)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 9), self.getaddr(0x1, 224 + 4 * (9 - 9)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 10), self.getaddr(0x1, 224 + 4 * (10 - 9)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 11), self.getaddr(0x1, 224 + 4 * (11 - 9)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 12), self.getaddr(0x1, 224 + 4 * (12 - 9)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 13), self.getaddr(0x1, 224 + 4 * (13 - 9)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 14), self.getaddr(0x1, 224 + 4 * (14 - 9)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_PASSIVE_COPPER, 15), self.getaddr(0x1, 224 + 4 * (15 - 9)), self.codes.PASSIVE_COPPER_MEDIA_INTERFACE), + + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 1), self.getaddr(0x0, 87 + 4 * (1 - 1)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 2), self.getaddr(0x0, 87 + 4 * (2 - 1)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 3), self.getaddr(0x0, 87 + 4 * (3 - 1)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 4), self.getaddr(0x0, 87 + 4 * (4 - 1)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 5), self.getaddr(0x0, 87 + 4 * (5 - 1)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 6), self.getaddr(0x0, 87 + 4 * (6 - 1)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 7), self.getaddr(0x0, 87 + 4 * (7 - 1)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 8), self.getaddr(0x0, 87 + 4 * (8 - 1)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 9), self.getaddr(0x1, 224 + 4 * (9 - 9)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 10), self.getaddr(0x1, 224 + 4 * (10 - 9)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 11), self.getaddr(0x1, 224 + 4 * (11 - 9)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 12), self.getaddr(0x1, 224 + 4 * (12 - 9)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 13), self.getaddr(0x1, 224 + 4 * (13 - 9)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 14), self.getaddr(0x1, 224 + 4 * (14 - 9)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_ACTIVE_CABLE, 15), self.getaddr(0x1, 224 + 4 * (15 - 9)), self.codes.ACTIVE_CABLE_MEDIA_INTERFACE), + + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 1), self.getaddr(0x0, 87 + 4 * (1 - 1)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 2), self.getaddr(0x0, 87 + 4 * (2 - 1)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 3), self.getaddr(0x0, 87 + 4 * (3 - 1)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 4), self.getaddr(0x0, 87 + 4 * (4 - 1)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 5), self.getaddr(0x0, 87 + 4 * (5 - 1)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 6), self.getaddr(0x0, 87 + 4 * (6 - 1)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 7), self.getaddr(0x0, 87 + 4 * (7 - 1)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 8), self.getaddr(0x0, 87 + 4 * (8 - 1)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 9), self.getaddr(0x1, 224 + 4 * (9 - 9)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 10), self.getaddr(0x1, 224 + 4 * (10 - 9)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 11), self.getaddr(0x1, 224 + 4 * (11 - 9)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 12), self.getaddr(0x1, 224 + 4 * (12 - 9)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 13), self.getaddr(0x1, 224 + 4 * (13 - 9)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 14), self.getaddr(0x1, 224 + 4 * (14 - 9)), self.codes.BASE_T_MEDIA_INTERFACE), + CodeRegField("%s_%d" % (consts.MODULE_MEDIA_INTERFACE_BASE_T, 15), self.getaddr(0x1, 224 + 4 * (15 - 9)), self.codes.BASE_T_MEDIA_INTERFACE), + + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 1), self.getaddr(0x0, 88 + 4 * (1 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 2), self.getaddr(0x0, 88 + 4 * (2 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 3), self.getaddr(0x0, 88 + 4 * (3 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 4), self.getaddr(0x0, 88 + 4 * (4 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 5), self.getaddr(0x0, 88 + 4 * (5 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 6), self.getaddr(0x0, 88 + 4 * (6 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 7), self.getaddr(0x0, 88 + 4 * (7 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 8), self.getaddr(0x0, 88 + 4 * (8 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 9), self.getaddr(0x1, 225 + 4 * (9 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 10), self.getaddr(0x1, 225 + 4 * (10 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 11), self.getaddr(0x1, 225 + 4 * (11 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 12), self.getaddr(0x1, 225 + 4 * (12 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 13), self.getaddr(0x1, 225 + 4 * (13 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 14), self.getaddr(0x1, 225 + 4 * (14 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + NumberRegField("%s_%d" % (consts.MEDIA_LANE_COUNT, 15), self.getaddr(0x1, 225 + 4 * (15 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0, 4)) + ), + + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 1), self.getaddr(0x0, 88 + 4 * (1 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 2), self.getaddr(0x0, 88 + 4 * (2 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 3), self.getaddr(0x0, 88 + 4 * (3 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 4), self.getaddr(0x0, 88 + 4 * (4 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 5), self.getaddr(0x0, 88 + 4 * (5 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 6), self.getaddr(0x0, 88 + 4 * (6 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 7), self.getaddr(0x0, 88 + 4 * (7 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 8), self.getaddr(0x0, 88 + 4 * (8 - 1)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 9), self.getaddr(0x1, 225 + 4 * (9 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 10), self.getaddr(0x1, 225 + 4 * (10 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 11), self.getaddr(0x1, 225 + 4 * (11 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 12), self.getaddr(0x1, 225 + 4 * (12 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 13), self.getaddr(0x1, 225 + 4 * (13 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 14), self.getaddr(0x1, 225 + 4 * (14 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + NumberRegField("%s_%d" % (consts.HOST_LANE_COUNT, 15), self.getaddr(0x1, 225 + 4 * (15 - 9)), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4, 8)) + ), + + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 1), self.getaddr(0x0, 89 + 4 * (1 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 2), self.getaddr(0x0, 89 + 4 * (2 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 3), self.getaddr(0x0, 89 + 4 * (3 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 4), self.getaddr(0x0, 89 + 4 * (4 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 5), self.getaddr(0x0, 89 + 4 * (5 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 6), self.getaddr(0x0, 89 + 4 * (6 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 7), self.getaddr(0x0, 89 + 4 * (7 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 8), self.getaddr(0x0, 89 + 4 * (8 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 9), self.getaddr(0x1, 226 + 4 * (9 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 10), self.getaddr(0x1, 226 + 4 * (10 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 11), self.getaddr(0x1, 226 + 4 * (11 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 12), self.getaddr(0x1, 226 + 4 * (12 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 13), self.getaddr(0x1, 226 + 4 * (13 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 14), self.getaddr(0x1, 226 + 4 * (14 - 1)), format="B", size=1), + NumberRegField("%s_%d" % (consts.HOST_LANE_ASSIGNMENT_OPTION, 15), self.getaddr(0x1, 226 + 4 * (15 - 1)), format="B", size=1), + + *(NumberRegField("%s_%d" % (consts.MEDIA_LANE_ASSIGNMENT_OPTION, app), self.getaddr(0x1, 176 + (app - 1)), format="B", size=1) + for app in range(1, 16)) + ), + CodeRegField(consts.HOST_ELECTRICAL_INTERFACE, self.getaddr(0x0, 86), self.codes.HOST_ELECTRICAL_INTERFACE), CodeRegField(consts.MEDIA_TYPE_FIELD, self.getaddr(0x0, 85), self.codes.MODULE_MEDIA_TYPE), CodeRegField(consts.MODULE_MEDIA_INTERFACE_850NM, self.getaddr(0x0, 87), self.codes.NM_850_MEDIA_INTERFACE), @@ -170,6 +380,7 @@ def __init__(self, codes): ) self.LANE_DATAPATH_CTRL = RegGroupField(consts.LANE_DATAPATH_CTRL_FIELD, + NumberRegField(consts.DATAPATH_DEINIT_FIELD, self.getaddr(0x10, 128), ro=False), NumberRegField(consts.TX_DISABLE_FIELD, self.getaddr(0x10, 130), ro=False) ) @@ -365,6 +576,17 @@ def __init__(self, codes): NumberRegField(consts.CDB_RPL_LENGTH, self.getaddr(0x9f, 134), size=1, ro=False), NumberRegField(consts.CDB_RPL_CHKCODE, self.getaddr(0x9f, 135), size=1, ro=False), ) + + self.STAGED_CTRL0 = RegGroupField("%s_%d" % (consts.STAGED_CTRL_FIELD, 0), + NumberRegField("%s_%d" % (consts.STAGED_CTRL_APPLY_DPINIT_FIELD, 0), + self.getaddr(0x10, 143), ro=False), + NumberRegField("%s_%d" % (consts.STAGED_CTRL_APPLY_IMMEDIATE_FIELD, 0), + self.getaddr(0x10, 144), ro=False), + *(NumberRegField("%s_%d_%d" % (consts.STAGED_CTRL_APSEL_FIELD, 0, lane), + self.getaddr(0x10, 144 + lane), ro=False) + for lane in range(1, 9)) + ) + # TODO: add remaining fields def getaddr(self, page, offset, page_size=128): diff --git a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py index 8290224562ae..4bc62967b86d 100644 --- a/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py +++ b/sonic_platform_base/sonic_xcvr/sfp_optoe_base.py @@ -187,3 +187,25 @@ def write_eeprom(self, offset, num_bytes, write_buffer): except (OSError, IOError): return False return True + + def reset(self): + """ + Reset SFP and return all user module settings to their default state. + + Returns: + A boolean, True if successful, False if not + """ + api = self.get_xcvr_api() + return api.reset() if api is not None else False + + def get_error_description(self): + """ + Retrives the error descriptions of the SFP module + + Returns: + String that represents the current error descriptions of vendor specific errors + In case there are multiple errors, they should be joined by '|', + like: "Bad EEPROM|Unsupported cable" + """ + api = self.get_xcvr_api() + return api.get_error_description() if api is not None else None diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index 2c0d730d3eb8..bfda0361926a 100644 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -4,7 +4,8 @@ from sonic_platform_base.sonic_xcvr.mem_maps.public.cmis import CmisMemMap from sonic_platform_base.sonic_xcvr.xcvr_eeprom import XcvrEeprom from sonic_platform_base.sonic_xcvr.codes.public.cmis import CmisCodes -from sonic_platform_base.sonic_xcvr.fields.consts import LENGTH_ASSEMBLY_FIELD, LEN_MULT_FIELD +from sonic_platform_base.sonic_xcvr.codes.public.sff8024 import Sff8024 +from sonic_platform_base.sonic_xcvr.fields import consts class TestCmis(object): codes = CmisCodes @@ -825,6 +826,17 @@ def test_get_supported_power_config(self, mock_response, expected): def test_reset_module(self): self.api.reset_module(True) + def test_reset(self): + self.api.xcvr_eeprom.write = MagicMock() + self.api.get_module_state = MagicMock() + self.api.get_module_state.return_value = 'ModuleReady' + result = self.api.reset() + assert result + assert self.api.xcvr_eeprom.write.call_count == 1 + kall = self.api.xcvr_eeprom.write.call_args + assert kall is not None + assert kall[0] == (consts.MODULE_LEVEL_CONTROL, 0x8) + def test_set_low_power(self): self.api.is_flat_memory = MagicMock() self.api.is_flat_memory.return_value = False @@ -1132,6 +1144,8 @@ def test_get_transceiver_info(self, mock_response, expected): self.api.get_module_media_type.return_value = mock_response[13] self.api.get_module_hardware_revision = MagicMock() self.api.get_module_hardware_revision.return_value = '0.0' + self.api.is_flat_memory = MagicMock() + self.api.is_flat_memory.return_value = False result = self.api.get_transceiver_info() assert result == expected @@ -1884,9 +1898,140 @@ def test_get_transceiver_loopback(self, mock_response, expected): assert result == expected def test_cable_len(self): - cable_len_field = self.mem_map.get_field(LENGTH_ASSEMBLY_FIELD) + cable_len_field = self.mem_map.get_field(consts.LENGTH_ASSEMBLY_FIELD) data = bytearray([0xFF]) - dep = {LEN_MULT_FIELD: 0b11} + dep = {consts.LEN_MULT_FIELD: 0b11} decoded = cable_len_field.decode(data, **dep) assert decoded == 6300 + def test_set_datapath_init(self): + self.api.xcvr_eeprom.write = MagicMock() + self.api.xcvr_eeprom.read = MagicMock() + + self.api.xcvr_eeprom.read.side_effect = [0x3, 0x00] + self.api.set_datapath_init(0xff) + kall = self.api.xcvr_eeprom.write.call_args + assert kall is not None + assert kall[0] == (consts.DATAPATH_DEINIT_FIELD, 0xff) + + self.api.xcvr_eeprom.read.side_effect = [0x4, 0x00] + self.api.set_datapath_init(0xff) + kall = self.api.xcvr_eeprom.write.call_args + assert kall is not None + assert kall[0] == (consts.DATAPATH_DEINIT_FIELD, 0x00) + + def test_set_datapath_deinit(self): + self.api.xcvr_eeprom.write = MagicMock() + self.api.xcvr_eeprom.read = MagicMock() + + self.api.xcvr_eeprom.read.side_effect = [0x3, 0x00] + self.api.set_datapath_deinit(0xff) + kall = self.api.xcvr_eeprom.write.call_args + assert kall is not None + assert kall[0] == (consts.DATAPATH_DEINIT_FIELD, 0x00) + + self.api.xcvr_eeprom.read.side_effect = [0x4, 0x00] + self.api.set_datapath_deinit(0xff) + kall = self.api.xcvr_eeprom.write.call_args + assert kall is not None + assert kall[0] == (consts.DATAPATH_DEINIT_FIELD, 0xff) + + def test_get_application_advertisement(self): + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.read.side_effect = [ + { + consts.HOST_ELECTRICAL_INTERFACE + "_1": "400GAUI-8 C2M (Annex 120E)", + consts.MODULE_MEDIA_INTERFACE_SM + "_1": "400GBASE-DR4 (Cl 124)", + consts.MEDIA_LANE_COUNT + "_1": 4, + consts.HOST_LANE_COUNT + "_1": 8, + consts.HOST_LANE_ASSIGNMENT_OPTION + "_1": 0x01 + }, + Sff8024.MODULE_MEDIA_TYPE[2] + ] + result = self.api.get_application_advertisement() + + assert len(result) == 1 + assert result[1]['host_electrical_interface_id'] == '400GAUI-8 C2M (Annex 120E)' + assert result[1]['module_media_interface_id'] == '400GBASE-DR4 (Cl 124)' + assert result[1]['host_lane_count'] == 8 + assert result[1]['media_lane_count'] == 4 + assert result[1]['host_lane_assignment_options'] == 0x01 + + def test_get_application(self): + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.read.return_value = 0x20 + + self.api.is_flat_memory = MagicMock() + self.api.is_flat_memory.return_value = False + appl = self.api.get_application(0) + assert appl == 2 + + appl = self.api.get_application(2) + assert appl == 2 + + appl = self.api.get_application(self.api.NUM_CHANNELS) + assert appl == 0 + + self.api.is_flat_memory.return_value = True + appl = self.api.get_application(0) + assert appl == 0 + + appl = self.api.get_application(2) + assert appl == 0 + + appl = self.api.get_application(self.api.NUM_CHANNELS) + assert appl == 0 + + def test_set_application(self): + self.api.xcvr_eeprom.write = MagicMock() + + self.api.xcvr_eeprom.write.call_count = 0 + self.api.set_application(0x00, 1) + assert self.api.xcvr_eeprom.write.call_count == 1 + + self.api.xcvr_eeprom.write.call_count = 0 + self.api.set_application(0x01, 1) + assert self.api.xcvr_eeprom.write.call_count == 1 + 1 + + self.api.xcvr_eeprom.write.call_count = 0 + self.api.set_application(0x0f, 1) + assert self.api.xcvr_eeprom.write.call_count == 4 + 1 + + self.api.xcvr_eeprom.write.call_count = 0 + self.api.set_application(0xff, 1) + assert self.api.xcvr_eeprom.write.call_count == 8 + 1 + + self.api.xcvr_eeprom.write.call_count = 0 + self.api.set_application(0x7fffffff, 1) + assert self.api.xcvr_eeprom.write.call_count == self.api.NUM_CHANNELS + 1 + + def test_get_error_description(self): + self.api.get_module_state = MagicMock() + self.api.get_module_state.return_value = 'ModuleReady' + self.api.get_datapath_state = MagicMock() + self.api.get_datapath_state.return_value = { + 'DP1State': 'DataPathActivated', + 'DP2State': 'DataPathActivated', + 'DP3State': 'DataPathActivated', + 'DP4State': 'DataPathActivated', + 'DP5State': 'DataPathActivated', + 'DP6State': 'DataPathActivated', + 'DP7State': 'DataPathActivated', + 'DP8State': 'DataPathActivated' + } + self.api.get_config_datapath_hostlane_status = MagicMock() + self.api.get_config_datapath_hostlane_status.return_value = { + 'ConfigStatusLane1': 'ConfigSuccess', + 'ConfigStatusLane2': 'ConfigSuccess', + 'ConfigStatusLane3': 'ConfigSuccess', + 'ConfigStatusLane4': 'ConfigSuccess', + 'ConfigStatusLane5': 'ConfigSuccess', + 'ConfigStatusLane6': 'ConfigSuccess', + 'ConfigStatusLane7': 'ConfigSuccess', + 'ConfigStatusLane8': 'ConfigSuccess' + } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.read.return_value = 0x10 + + result = self.api.get_error_description() + assert result is None