From d5afcb054838cc9b6eb7a42f9057e649a0d186f7 Mon Sep 17 00:00:00 2001 From: Kroos Date: Wed, 10 Jun 2026 11:08:19 +0800 Subject: [PATCH] add cpo bailly rlm dom Signed-off-by: Kroos --- setup.py | 8 +- .../sonic_xcvr/api/bailly/bailly_api.py | 105 ------ .../api/{bailly => broadcom}/__init__.py | 0 .../sonic_xcvr/api/broadcom/bailly_rlm.py | 313 +++++++++++++++++ .../codes/{bailly => broadcom}/__init__.py | 0 .../bailly_rlm.py} | 1 - .../fields/{bailly => broadcom}/__init__.py | 0 .../bailly_rlm.py} | 14 + .../mem_maps/bailly/bailly_mem_map.py | 239 ------------- .../mem_maps/{bailly => broadcom}/__init__.py | 0 .../mem_maps/broadcom/bailly_rlm.py | 258 ++++++++++++++ tests/sonic_xcvr/test_bailly_cmis.py | 329 +++++++++++++++++- 12 files changed, 903 insertions(+), 364 deletions(-) delete mode 100644 sonic_platform_base/sonic_xcvr/api/bailly/bailly_api.py rename sonic_platform_base/sonic_xcvr/api/{bailly => broadcom}/__init__.py (100%) create mode 100644 sonic_platform_base/sonic_xcvr/api/broadcom/bailly_rlm.py rename sonic_platform_base/sonic_xcvr/codes/{bailly => broadcom}/__init__.py (100%) rename sonic_platform_base/sonic_xcvr/codes/{bailly/bailly_codes.py => broadcom/bailly_rlm.py} (95%) rename sonic_platform_base/sonic_xcvr/fields/{bailly => broadcom}/__init__.py (100%) rename sonic_platform_base/sonic_xcvr/fields/{bailly/bailly_consts.py => broadcom/bailly_rlm.py} (88%) delete mode 100644 sonic_platform_base/sonic_xcvr/mem_maps/bailly/bailly_mem_map.py rename sonic_platform_base/sonic_xcvr/mem_maps/{bailly => broadcom}/__init__.py (100%) create mode 100644 sonic_platform_base/sonic_xcvr/mem_maps/broadcom/bailly_rlm.py diff --git a/setup.py b/setup.py index ff177bab5..cb0d4360a 100644 --- a/setup.py +++ b/setup.py @@ -43,20 +43,20 @@ 'sonic_platform_base.sonic_xcvr', 'sonic_platform_base.sonic_xcvr.fields', 'sonic_platform_base.sonic_xcvr.fields.public', - 'sonic_platform_base.sonic_xcvr.fields.bailly', + 'sonic_platform_base.sonic_xcvr.fields.broadcom', 'sonic_platform_base.sonic_xcvr.mem_maps', 'sonic_platform_base.sonic_xcvr.mem_maps.public', - 'sonic_platform_base.sonic_xcvr.mem_maps.bailly', + 'sonic_platform_base.sonic_xcvr.mem_maps.broadcom', 'sonic_platform_base.sonic_xcvr.mem_maps.public.cmis', 'sonic_platform_base.sonic_xcvr.mem_maps.public.cmis.pages', 'sonic_platform_base.sonic_xcvr.mem_maps.public.cmis.elsfp', 'sonic_platform_base.sonic_xcvr.mem_maps.public.cmis.elsfp.pages', 'sonic_platform_base.sonic_xcvr.api', 'sonic_platform_base.sonic_xcvr.api.public', - 'sonic_platform_base.sonic_xcvr.api.bailly', + 'sonic_platform_base.sonic_xcvr.api.broadcom', 'sonic_platform_base.sonic_xcvr.codes', 'sonic_platform_base.sonic_xcvr.codes.public', - 'sonic_platform_base.sonic_xcvr.codes.bailly', + 'sonic_platform_base.sonic_xcvr.codes.broadcom', 'sonic_platform_base.sonic_xcvr.utils', 'sonic_platform_base.sonic_xcvr.api.credo', 'sonic_platform_base.sonic_xcvr.mem_maps.credo', diff --git a/sonic_platform_base/sonic_xcvr/api/bailly/bailly_api.py b/sonic_platform_base/sonic_xcvr/api/bailly/bailly_api.py deleted file mode 100644 index 7c1a2d450..000000000 --- a/sonic_platform_base/sonic_xcvr/api/bailly/bailly_api.py +++ /dev/null @@ -1,105 +0,0 @@ -""" - bailly_api.py - - Implementation of Micas Bailly CPO specific in addition to the CMIS specification. -""" -from ..public.cmis import CmisApi -from ...fields.bailly import bailly_consts - -class BaillyApi(CmisApi): - def __init__(self, xcvr_eeprom): - super(BaillyApi, self).__init__(xcvr_eeprom) - - def get_dpinit_pending(self): - ''' - Bailly not supported, return fake value. - ''' - dpinit_pending_dict = {} - for lane in range(self.NUM_CHANNELS): - key = "DPInitPending{}".format(lane + 1) - dpinit_pending_dict[key] = True - return dpinit_pending_dict - - def get_active_apsel_hostlane(self): - ''' - Bailly not supported Deinit, if it is deinit return fake value. - ''' - has_zero = False - current_map = {} - for lane in range(self.NUM_CHANNELS): - lane_key = 'ActiveAppSelLane{}'.format(lane + 1) - app_lane = self.get_application(lane) - current_map[lane_key] = app_lane - if app_lane == 0: - has_zero = True - - if has_zero: - return current_map - else: - normal = super().get_active_apsel_hostlane() - return normal - def _format_revision(self, revision): - if revision is None: - return None - return "{}.{}".format((revision >> 4) & 0xf, revision & 0xf) - - def get_transceiver_info(self): - info = super().get_transceiver_info() - if info is None: - return None - - els_info = self.get_els_info() - cpo_info = els_info.get("cpo_info") - vendor_info = els_info.get("vendor_info") - laser_power_mode = els_info.get("laser_power_mode") - if cpo_info is None and vendor_info is None and laser_power_mode is None: - return info - - if cpo_info is not None: - info.update({ - "els_identifier": cpo_info.get(bailly_consts.CPO_IDENTIFIER), - "els_revision": self._format_revision(cpo_info.get(bailly_consts.CPO_REVISION)), - "els_laser_grid_and_count": cpo_info.get(bailly_consts.LASER_GRID_AND_COUNT), - "els_laser_wavelength_grid": cpo_info.get(bailly_consts.LASER_WAVELENGTH_GRID), - "els_laser_count": cpo_info.get(bailly_consts.LASER_COUNT), - }) - - if vendor_info is not None: - info.update({ - "els_vendor_name": self._strip_str( - vendor_info.get(bailly_consts.VENDOR_NAME_ASCII_FIELD) - ), - "els_vendor_oui": vendor_info.get(bailly_consts.VENDOR_OUI_HEX_FIELD), - "els_vendor_pn": self._strip_str( - vendor_info.get(bailly_consts.VENDOR_PART_NUMBER_ASCII_FIELD) - ), - "els_vendor_rev": self._strip_str( - vendor_info.get(bailly_consts.VENDOR_REVISION_ASCII_FIELD) - ), - "els_vendor_sn": self._strip_str( - vendor_info.get(bailly_consts.VENDOR_SERIAL_NUMBER_ASCII_FIELD) - ), - "els_date_code": self._strip_str( - vendor_info.get(bailly_consts.DATE_CODE_FIELD) - ), - "els_max_power": vendor_info.get(bailly_consts.MAX_POWER_CONSUMPTION_FIELD), - }) - - if laser_power_mode is not None: - info.update({ - "els_laser_power_mode_control": laser_power_mode.get( - bailly_consts.LASER_POWER_MODE_CONTROL_BITS_FIELD - ), - }) - - return info - - def get_els_vendor_info(self): - return self.xcvr_eeprom.read(bailly_consts.CPO_VENDOR_INFO_FIELD) - - def get_els_info(self): - return { - "cpo_info": self.xcvr_eeprom.read(bailly_consts.CPO_INFO_FIELD), - "vendor_info": self.get_els_vendor_info(), - "laser_power_mode": self.xcvr_eeprom.read(bailly_consts.LASER_POWER_MODE_CONTROL_FIELD), - } diff --git a/sonic_platform_base/sonic_xcvr/api/bailly/__init__.py b/sonic_platform_base/sonic_xcvr/api/broadcom/__init__.py similarity index 100% rename from sonic_platform_base/sonic_xcvr/api/bailly/__init__.py rename to sonic_platform_base/sonic_xcvr/api/broadcom/__init__.py diff --git a/sonic_platform_base/sonic_xcvr/api/broadcom/bailly_rlm.py b/sonic_platform_base/sonic_xcvr/api/broadcom/bailly_rlm.py new file mode 100644 index 000000000..4e552919d --- /dev/null +++ b/sonic_platform_base/sonic_xcvr/api/broadcom/bailly_rlm.py @@ -0,0 +1,313 @@ +""" + bailly_rlm.py + + Implementation of Micas Bailly CPO specific in addition to the CMIS specification. +""" +from ..public.cmis import CmisApi +from ...fields.broadcom import bailly_rlm + + +RLM_XCVR_INFO_DEFAULT_DICT = { + "rlm_identifier": "N/A", + "rlm_revision": "N/A", + "rlm_laser_wavelength_grid": "N/A", + "rlm_laser_count": "N/A", + "rlm_vendor_name": "N/A", + "rlm_vendor_oui": "N/A", + "rlm_vendor_pn": "N/A", + "rlm_vendor_rev": "N/A", + "rlm_vendor_sn": "N/A", + "rlm_date_code": "N/A", + "rlm_max_power": "N/A", + "rlm_laser_power_mode_control": "N/A", +} + + +class BaillyApi(CmisApi): + RLM_THRESHOLD_FIELDS = { + "RLM_temphighalarm": bailly_rlm.RLM_TEMP_HIGH_ALARM_FIELD, + "RLM_templowalarm": bailly_rlm.RLM_TEMP_LOW_ALARM_FIELD, + "RLM_temphighwarning": bailly_rlm.RLM_TEMP_HIGH_WARNING_FIELD, + "RLM_templowwarning": bailly_rlm.RLM_TEMP_LOW_WARNING_FIELD, + "RLM_vcchighalarm": bailly_rlm.RLM_VCC_HIGH_ALARM_FIELD, + "RLM_vcclowalarm": bailly_rlm.RLM_VCC_LOW_ALARM_FIELD, + "RLM_vcchighwarning": bailly_rlm.RLM_VCC_HIGH_WARNING_FIELD, + "RLM_vcclowwarning": bailly_rlm.RLM_VCC_LOW_WARNING_FIELD, + "RLM_txpowerhighalarm": bailly_rlm.RLM_TX_POWER_HIGH_ALARM_FIELD, + "RLM_txpowerlowalarm": bailly_rlm.RLM_TX_POWER_LOW_ALARM_FIELD, + "RLM_txpowerhighwarning": bailly_rlm.RLM_TX_POWER_HIGH_WARNING_FIELD, + "RLM_txpowerlowwarning": bailly_rlm.RLM_TX_POWER_LOW_WARNING_FIELD, + "RLM_txbiashighalarm": bailly_rlm.RLM_TX_BIAS_HIGH_ALARM_FIELD, + "RLM_txbiashighwarning": bailly_rlm.RLM_TX_BIAS_HIGH_WARNING_FIELD, + } + def __init__(self, xcvr_eeprom): + super(BaillyApi, self).__init__(xcvr_eeprom) + + def get_dpinit_pending(self): + ''' + Bailly not supported, return fake value. + ''' + dpinit_pending_dict = {} + for lane in range(self.NUM_CHANNELS): + key = "DPInitPending{}".format(lane + 1) + dpinit_pending_dict[key] = True + return dpinit_pending_dict + + def get_active_apsel_hostlane(self): + ''' + Bailly not supported Deinit, if it is deinit return fake value. + ''' + has_zero = False + current_map = {} + for lane in range(self.NUM_CHANNELS): + lane_key = 'ActiveAppSelLane{}'.format(lane + 1) + app_lane = self.get_application(lane) + current_map[lane_key] = app_lane + if app_lane == 0: + has_zero = True + + if has_zero: + return current_map + else: + normal = super().get_active_apsel_hostlane() + return normal + + def _format_revision(self, revision): + if revision is None: + return None + return "{}.{}".format((revision >> 4) & 0xf, revision & 0xf) + + def _format_float(self, value): + if value is None: + return None + if isinstance(value, dict): + return None + return float("{:.3f}".format(value)) + + def get_rlm_temperature(self): + monitors = self.xcvr_eeprom.read(bailly_rlm.CPO_MODULE_MONITORS_FIELD) + if monitors is None: + return None + temperature = monitors.get(bailly_rlm.MODULE_TEMPERATURE_MONITOR) + return self._format_float(temperature) + + def _get_nested_monitor_value(self, monitors, group_field, value_field): + group = monitors.get(group_field) + if group is None: + return None + + value = group.get(value_field) + if isinstance(value, dict): + value = value.get(value_field) + return value + + def get_rlm_monitor_values(self): + monitors = self.xcvr_eeprom.read(bailly_rlm.CPO_MODULE_MONITORS_FIELD) + if monitors is None: + return None + + monitor_values = { + "RLM_temperature": self._format_float(monitors.get(bailly_rlm.MODULE_TEMPERATURE_MONITOR)), + "RLM_voltage": self._format_float(monitors.get(bailly_rlm.MODULE_SUPPLY_VOLTAGE_MONITOR)), + "RLM_tec_current": self._format_float(monitors.get(bailly_rlm.TEC_CURRENT_MONITOR)), + } + + return monitor_values + + def get_rlm_thresholds(self): + laser_power_mode = self.xcvr_eeprom.read(bailly_rlm.LASER_POWER_MODE_CONTROL_FIELD) + if laser_power_mode is None: + return None + + thresholds = laser_power_mode.get(bailly_rlm.THRESHOLD_VALUES_FIELD) + if thresholds is None: + return None + + return { + key: self._format_float(thresholds.get(field)) + for key, field in self.RLM_THRESHOLD_FIELDS.items() + } + + def get_rlm_temperature_thresholds(self): + thresholds = self.get_rlm_thresholds() + if thresholds is None: + return None + + return { + "temphighalarm": thresholds.get("RLM_temphighalarm"), + "templowalarm": thresholds.get("RLM_templowalarm"), + "temphighwarning": thresholds.get("RLM_temphighwarning"), + "templowwarning": thresholds.get("RLM_templowwarning"), + } + + def get_rlm_flags(self): + module_alarms = self.xcvr_eeprom.read(bailly_rlm.MODULE_ALARMS_FIELD) + if module_alarms is None: + return None + + flags = { + "RLM_tempHAlarm": module_alarms.get(bailly_rlm.TEMP_HIGH_ALARM_FLAG), + "RLM_tempLAlarm": module_alarms.get(bailly_rlm.TEMP_LOW_ALARM_FLAG), + "RLM_tempHWarn": module_alarms.get(bailly_rlm.TEMP_HIGH_WARN_FLAG), + "RLM_tempLWarn": module_alarms.get(bailly_rlm.TEMP_LOW_WARN_FLAG), + "RLM_vccHAlarm": module_alarms.get(bailly_rlm.VOLTAGE_HIGH_ALARM_FLAG), + "RLM_vccLAlarm": module_alarms.get(bailly_rlm.VOLTAGE_LOW_ALARM_FLAG), + "RLM_vccHWarn": module_alarms.get(bailly_rlm.VOLTAGE_HIGH_WARN_FLAG), + "RLM_vccLWarn": module_alarms.get(bailly_rlm.VOLTAGE_LOW_WARN_FLAG), + } + + return flags + + def get_rlm_status(self): + status = self.xcvr_eeprom.read(bailly_rlm.LASER_STATUS_FIELD) + if status is None: + return None + + return { + "RLM_module_low_power_state": status.get(bailly_rlm.MODULE_LOW_POWER_STATE), + "RLM_interrupt_status": status.get(bailly_rlm.INTL_INTERRUPT_STATUS), + } + def get_rlm_temperature_flags(self): + flags = self.get_rlm_flags() + if flags is None: + return None + + return { + "tempHAlarm": flags.get("RLM_tempHAlarm"), + "tempLAlarm": flags.get("RLM_tempLAlarm"), + "tempHWarn": flags.get("RLM_tempHWarn"), + "tempLWarn": flags.get("RLM_tempLWarn"), + } + + def get_transceiver_dom_real_value(self): + dom_info = super().get_transceiver_dom_real_value() + if dom_info is None: + dom_info = {} + + rlm_monitors = self.get_rlm_monitor_values() + if rlm_monitors is not None: + dom_info.update({ + key: value for key, value in rlm_monitors.items() + if value is not None + }) + + return dom_info + + def get_transceiver_dom_flags(self): + dom_flags = super().get_transceiver_dom_flags() + if dom_flags is None: + dom_flags = {} + + rlm_flags = self.get_rlm_flags() + if rlm_flags is not None: + dom_flags.update({ + key: value for key, value in rlm_flags.items() + if value is not None + }) + + return dom_flags + + def get_transceiver_status_flags(self): + status_flags = super().get_transceiver_status_flags() + if status_flags is None: + status_flags = {} + + rlm_flags = self.get_rlm_flags() + if rlm_flags is not None: + status_flags.update({ + key: value for key, value in rlm_flags.items() + if value is not None + }) + + rlm_status = self.get_rlm_status() + if rlm_status is not None: + status_flags.update({ + key: value for key, value in rlm_status.items() + if value is not None + }) + + return status_flags + + def get_transceiver_threshold_info(self): + threshold_info = super().get_transceiver_threshold_info() + if threshold_info is None: + threshold_info = {} + + rlm_thresholds = self.get_rlm_thresholds() + if rlm_thresholds is not None: + threshold_info.update({ + key: value for key, value in rlm_thresholds.items() + if value is not None + }) + + return threshold_info + + def get_transceiver_info(self): + info = super().get_transceiver_info() + if info is None: + return None + info.update(RLM_XCVR_INFO_DEFAULT_DICT) + + rlm_info = self.get_rlm_info() + cpo_info = rlm_info.get("cpo_info") + rlm_vendor_info = rlm_info.get("rlm_vendor_info") + laser_power_mode = rlm_info.get("laser_power_mode") + if cpo_info is None and rlm_vendor_info is None and laser_power_mode is None: + return info + + if cpo_info is not None: + info.update({ + "rlm_identifier": cpo_info.get(bailly_rlm.CPO_IDENTIFIER), + "rlm_revision": self._format_revision(cpo_info.get(bailly_rlm.CPO_REVISION)), + "rlm_laser_wavelength_grid": cpo_info.get(bailly_rlm.LASER_WAVELENGTH_GRID), + "rlm_laser_count": cpo_info.get(bailly_rlm.LASER_COUNT), + }) + + if rlm_vendor_info is not None: + info.update({ + "rlm_vendor_name": self._strip_str( + rlm_vendor_info.get(bailly_rlm.VENDOR_NAME_ASCII_FIELD) + ), + "rlm_vendor_oui": rlm_vendor_info.get(bailly_rlm.VENDOR_OUI_HEX_FIELD), + "rlm_vendor_pn": self._strip_str( + rlm_vendor_info.get(bailly_rlm.VENDOR_PART_NUMBER_ASCII_FIELD) + ), + "rlm_vendor_rev": self._strip_str( + rlm_vendor_info.get(bailly_rlm.VENDOR_REVISION_ASCII_FIELD) + ), + "rlm_vendor_sn": self._strip_str( + rlm_vendor_info.get(bailly_rlm.VENDOR_SERIAL_NUMBER_ASCII_FIELD) + ), + "rlm_date_code": self._strip_str( + rlm_vendor_info.get(bailly_rlm.DATE_CODE_FIELD) + ), + "rlm_max_power": rlm_vendor_info.get(bailly_rlm.MAX_POWER_CONSUMPTION_FIELD), + }) + + if laser_power_mode is not None: + info.update({ + "rlm_laser_power_mode_control": laser_power_mode.get( + bailly_rlm.LASER_POWER_MODE_CONTROL_BITS_FIELD + ), + }) + + return info + + def get_rlm_vendor_info(self): + return self.xcvr_eeprom.read(bailly_rlm.CPO_VENDOR_INFO_FIELD) + + def get_rlm_info(self): + return { + "cpo_info": self.xcvr_eeprom.read(bailly_rlm.CPO_INFO_FIELD), + "rlm_vendor_info": self.get_rlm_vendor_info(), + "laser_power_mode": self.xcvr_eeprom.read(bailly_rlm.LASER_POWER_MODE_CONTROL_FIELD), + } + + def get_rlm_laser_current(self): + return self.xcvr_eeprom.read(bailly_rlm.LASER_CURRENT_MONITOR_FIELD) + + def get_rlm_laser_voltage(self): + return self.xcvr_eeprom.read(bailly_rlm.LASER_VOLTAGE_MONITOR_FIELD) + + def get_rlm_laser_power(self): + return self.xcvr_eeprom.read(bailly_rlm.LASER_OPTICAL_POWER_MONITOR_FIELD) diff --git a/sonic_platform_base/sonic_xcvr/codes/bailly/__init__.py b/sonic_platform_base/sonic_xcvr/codes/broadcom/__init__.py similarity index 100% rename from sonic_platform_base/sonic_xcvr/codes/bailly/__init__.py rename to sonic_platform_base/sonic_xcvr/codes/broadcom/__init__.py diff --git a/sonic_platform_base/sonic_xcvr/codes/bailly/bailly_codes.py b/sonic_platform_base/sonic_xcvr/codes/broadcom/bailly_rlm.py similarity index 95% rename from sonic_platform_base/sonic_xcvr/codes/bailly/bailly_codes.py rename to sonic_platform_base/sonic_xcvr/codes/broadcom/bailly_rlm.py index 353cb4150..efe04fd2e 100644 --- a/sonic_platform_base/sonic_xcvr/codes/bailly/bailly_codes.py +++ b/sonic_platform_base/sonic_xcvr/codes/broadcom/bailly_rlm.py @@ -1,7 +1,6 @@ from ..public.cmis import CmisCodes class BaillyCodes(CmisCodes): - # Vendor specific implementation to be added here XCVR_IDENTIFIERS = { **CmisCodes.XCVR_IDENTIFIERS, 128: 'CPO Bailly', diff --git a/sonic_platform_base/sonic_xcvr/fields/bailly/__init__.py b/sonic_platform_base/sonic_xcvr/fields/broadcom/__init__.py similarity index 100% rename from sonic_platform_base/sonic_xcvr/fields/bailly/__init__.py rename to sonic_platform_base/sonic_xcvr/fields/broadcom/__init__.py diff --git a/sonic_platform_base/sonic_xcvr/fields/bailly/bailly_consts.py b/sonic_platform_base/sonic_xcvr/fields/broadcom/bailly_rlm.py similarity index 88% rename from sonic_platform_base/sonic_xcvr/fields/bailly/bailly_consts.py rename to sonic_platform_base/sonic_xcvr/fields/broadcom/bailly_rlm.py index a85c94371..152808bec 100644 --- a/sonic_platform_base/sonic_xcvr/fields/bailly/bailly_consts.py +++ b/sonic_platform_base/sonic_xcvr/fields/broadcom/bailly_rlm.py @@ -68,6 +68,20 @@ LASER_POWER_MODE_CONTROL_BITS_FIELD = "LaserPowerModeControlBits" CHANNEL_LASER_POWER_MODE_ENABLE = "Channel{}LaserPowerModeEnable" THRESHOLD_VALUES_FIELD = "ThresholdValues" +RLM_TEMP_HIGH_ALARM_FIELD = "RlmTempHighAlarm" +RLM_TEMP_LOW_ALARM_FIELD = "RlmTempLowAlarm" +RLM_TEMP_HIGH_WARNING_FIELD = "RlmTempHighWarning" +RLM_TEMP_LOW_WARNING_FIELD = "RlmTempLowWarning" +RLM_VCC_HIGH_ALARM_FIELD = "RlmVccHighAlarm" +RLM_VCC_LOW_ALARM_FIELD = "RlmVccLowAlarm" +RLM_VCC_HIGH_WARNING_FIELD = "RlmVccHighWarning" +RLM_VCC_LOW_WARNING_FIELD = "RlmVccLowWarning" +RLM_TX_POWER_HIGH_ALARM_FIELD = "RlmTxPowerHighAlarm" +RLM_TX_POWER_LOW_ALARM_FIELD = "RlmTxPowerLowAlarm" +RLM_TX_POWER_HIGH_WARNING_FIELD = "RlmTxPowerHighWarning" +RLM_TX_POWER_LOW_WARNING_FIELD = "RlmTxPowerLowWarning" +RLM_TX_BIAS_HIGH_ALARM_FIELD = "RlmTxBiasHighAlarm" +RLM_TX_BIAS_HIGH_WARNING_FIELD = "RlmTxBiasHighWarning" TEMP_HIGH_ALARM_MSB_FIELD = "TempHighAlarmMSB" TEMP_HIGH_ALARM_LSB_FIELD = "TempHighAlarmLSB" TEMP_LOW_ALARM_MSB_FIELD = "TempLowAlarmMSB" diff --git a/sonic_platform_base/sonic_xcvr/mem_maps/bailly/bailly_mem_map.py b/sonic_platform_base/sonic_xcvr/mem_maps/bailly/bailly_mem_map.py deleted file mode 100644 index f1fd09f7a..000000000 --- a/sonic_platform_base/sonic_xcvr/mem_maps/bailly/bailly_mem_map.py +++ /dev/null @@ -1,239 +0,0 @@ -""" - bailly_mem_map.py - - Implementation of XcvrMemMap for Bailly extending CMIS Rev 5.0 -""" - -from ..public.cmis import CmisMemMap -from ..public.cmis.pages.page import CmisPage -from ...fields.xcvr_field import ( - CodeRegField, - DateField, - HexRegField, - NumberRegField, - RegBitField, - RegBitsField, - RegGroupField, - StringRegField, -) -from ...fields.consts import * -from ...fields.bailly import bailly_consts - -class _BaillyElsControlPage(CmisPage): - """Bailly-specific fields on CMIS Page 0xB0h""" - def __init__(self, codes, page=0xB0, bank=0): - super().__init__(codes, page=page, bank=bank) - - self.fields[bailly_consts.CPO_INFO_FIELD] = [ - RegGroupField(bailly_consts.CPO_INFO_FIELD, - CodeRegField(bailly_consts.CPO_IDENTIFIER, self.getaddr(128), codes.XCVR_IDENTIFIERS), - NumberRegField(bailly_consts.CPO_REVISION, self.getaddr(129), format="B", size=1), - NumberRegField(bailly_consts.LASER_GRID_AND_COUNT, self.getaddr(130), size=1, format="B"), - CodeRegField(bailly_consts.LASER_WAVELENGTH_GRID, self.getaddr(130), - codes.LASER_WAVELENGTH_GRID, - RegBitField(bailly_consts.BIT4_FIELD, bitpos=4, ro=True) - ), - CodeRegField(bailly_consts.LASER_COUNT, self.getaddr(130), - codes.LASER_COUNT, - RegBitsField(bailly_consts.BITS0_3_FIELD, bitpos=0, size=4, ro=True) - ), - ) - ] - - self.fields[bailly_consts.LASER_CONTROL_FIELD] = [ - RegGroupField(bailly_consts.LASER_CONTROL_FIELD, - NumberRegField(bailly_consts.MODULE_LOW_POWER_CONTROL, self.getaddr(132), - RegBitField(bailly_consts.BIT0_FIELD, bitpos=0, ro=False), size=1, ro=False - ), - NumberRegField(bailly_consts.LASER_DISABLE_CONTROL_7_0, self.getaddr(133), format="B", size=1, ro=False), - NumberRegField(bailly_consts.LASER_DISABLE_CONTROL_15_8, self.getaddr(134), format="B", size=1, ro=False), - RegGroupField(bailly_consts.LASER_DISABLE_CONTROL_FIELD, - *(NumberRegField(bailly_consts.LASER_DISABLE_CONTROL.format(laser), - self.getaddr(133 + laser // 8), - RegBitField(bailly_consts.BIT_FIELD.format(laser % 8), bitpos=laser % 8, ro=False), - size=1, ro=False) - for laser in range(0, 16)) - ), - ) - ] - - self.fields[bailly_consts.LASER_STATUS_FIELD] = [ - RegGroupField(bailly_consts.LASER_STATUS_FIELD, - NumberRegField(bailly_consts.MODULE_STATE_AND_INTERRUPT, self.getaddr(131), size=1, format="B"), - CodeRegField(bailly_consts.MODULE_LOW_POWER_STATE, self.getaddr(131), - codes.POWER_MODE, - RegBitField(bailly_consts.BIT1_FIELD, bitpos=1) - ), - CodeRegField(bailly_consts.INTL_INTERRUPT_STATUS, self.getaddr(131), - codes.INTERRUPT_STATUS, - RegBitField(bailly_consts.BIT0_FIELD, bitpos=0) - ), - NumberRegField(bailly_consts.LASER_ACTIVE_STATUS_7_0, self.getaddr(135), format="B", size=1), - NumberRegField(bailly_consts.LASER_ACTIVE_STATUS_15_8, self.getaddr(136), format="B", size=1), - RegGroupField(bailly_consts.LASER_ACTIVE_STATUS_FIELD, - *(CodeRegField(bailly_consts.LASER_ACTIVE_STATUS.format(laser), - self.getaddr(135 + laser // 8), - codes.LASER_ACTIVE_STATUS, - RegBitField(bailly_consts.BIT_FIELD.format(laser % 8), bitpos=laser % 8), - size=1) - for laser in range(0, 16)) - ), - ) - ] - - self.fields[bailly_consts.MODULE_ALARMS_FIELD] = [ - RegGroupField(bailly_consts.MODULE_ALARMS_FIELD, - NumberRegField(bailly_consts.VCC_3V3_TEMPERATURE_WARNING_ALARM, self.getaddr(137), format="B", size=1), - RegBitField(bailly_consts.TEMP_HIGH_ALARM_FLAG, offset=self.getaddr(137), bitpos=0), - RegBitField(bailly_consts.TEMP_LOW_ALARM_FLAG, offset=self.getaddr(137), bitpos=1), - RegBitField(bailly_consts.TEMP_HIGH_WARN_FLAG, offset=self.getaddr(137), bitpos=2), - RegBitField(bailly_consts.TEMP_LOW_WARN_FLAG, offset=self.getaddr(137), bitpos=3), - RegBitField(bailly_consts.VOLTAGE_HIGH_ALARM_FLAG, offset=self.getaddr(137), bitpos=4), - RegBitField(bailly_consts.VOLTAGE_LOW_ALARM_FLAG, offset=self.getaddr(137), bitpos=5), - RegBitField(bailly_consts.VOLTAGE_HIGH_WARN_FLAG, offset=self.getaddr(137), bitpos=6), - RegBitField(bailly_consts.VOLTAGE_LOW_WARN_FLAG, offset=self.getaddr(137), bitpos=7), - NumberRegField(bailly_consts.LASER_BIAS_WARNING_7_0, self.getaddr(138), format="B", size=1), - NumberRegField(bailly_consts.LASER_BIAS_WARNING_15_8, self.getaddr(139), format="B", size=1), - RegGroupField(bailly_consts.LASER_BIAS_WARNING_FIELD, - *(NumberRegField(bailly_consts.LASER_BIAS_WARNING.format(laser), - self.getaddr(138 + laser // 8), - RegBitField(bailly_consts.BIT_FIELD.format(laser % 8), bitpos=laser % 8), - size=1) - for laser in range(0, 16)) - ), - NumberRegField(bailly_consts.LASER_BIAS_ALARM_7_0, self.getaddr(140), format="B", size=1), - NumberRegField(bailly_consts.LASER_BIAS_ALARM_15_8, self.getaddr(141), format="B", size=1), - RegGroupField(bailly_consts.LASER_BIAS_ALARM_FIELD, - *(NumberRegField(bailly_consts.LASER_BIAS_ALARM.format(laser), - self.getaddr(140 + laser // 8), - RegBitField(bailly_consts.BIT_FIELD.format(laser % 8), bitpos=laser % 8), - size=1) - for laser in range(0, 16)) - ), - ) - ] - - self.fields[bailly_consts.CPO_MODULE_MONITORS_FIELD] = [ - RegGroupField(bailly_consts.CPO_MODULE_MONITORS_FIELD, - NumberRegField(bailly_consts.MODULE_TEMPERATURE_MONITOR_MSB, self.getaddr(150), format="B", size=1), - NumberRegField(bailly_consts.MODULE_TEMPERATURE_MONITOR_LSB, self.getaddr(151), format="B", size=1), - NumberRegField(bailly_consts.MODULE_TEMPERATURE_MONITOR, self.getaddr(150), size=2, format=">h", scale=256.0), - NumberRegField(bailly_consts.MODULE_SUPPLY_VOLTAGE_MONITOR_MSB, self.getaddr(152), format="B", size=1), - NumberRegField(bailly_consts.MODULE_SUPPLY_VOLTAGE_MONITOR_LSB, self.getaddr(153), format="B", size=1), - NumberRegField(bailly_consts.MODULE_SUPPLY_VOLTAGE_MONITOR, self.getaddr(152), size=2, format=">H", scale=10000.0), - RegGroupField(bailly_consts.LASER_CURRENT_MONITOR_FIELD, - *(RegGroupField(bailly_consts.LASER_CURRENT_MONITOR.format(laser), - NumberRegField(bailly_consts.LASER_CURRENT_MONITOR_MSB.format(laser), self.getaddr(154 + 2 * laser), format="B", size=1), - NumberRegField(bailly_consts.LASER_CURRENT_MONITOR_LSB.format(laser), self.getaddr(155 + 2 * laser), format="B", size=1), - NumberRegField(bailly_consts.LASER_CURRENT_MONITOR.format(laser), self.getaddr(154 + 2 * laser), size=2, format=">H", scale=10.0), - ) for laser in range(0, 16)) - ), - RegGroupField(bailly_consts.LASER_VOLTAGE_MONITOR_FIELD, - *(NumberRegField(bailly_consts.LASER_VOLTAGE_MONITOR.format(laser), - self.getaddr(186 + laser), size=1, format="B", scale=100.0) - for laser in range(0, 16)) - ), - RegGroupField(bailly_consts.LASER_OPTICAL_POWER_MONITOR_FIELD, - *(RegGroupField(bailly_consts.LASER_OPTICAL_POWER_MONITOR.format(laser), - NumberRegField(bailly_consts.LASER_OPTICAL_POWER_MONITOR_MSB.format(laser), self.getaddr(203 + 2 * laser), format="B", size=1), - NumberRegField(bailly_consts.LASER_OPTICAL_POWER_MONITOR_LSB.format(laser), self.getaddr(204 + 2 * laser), format="B", size=1), - NumberRegField(bailly_consts.LASER_OPTICAL_POWER_MONITOR.format(laser), self.getaddr(203 + 2 * laser), size=2, format=">H", scale=100.0), - ) for laser in range(0, 16)) - ), - NumberRegField(bailly_consts.TEC_CURRENT_MONITOR_MSB, self.getaddr(250), format="B", size=1), - NumberRegField(bailly_consts.TEC_CURRENT_MONITOR_LSB, self.getaddr(251), format="B", size=1), - NumberRegField(bailly_consts.TEC_CURRENT_MONITOR, self.getaddr(250), size=2, format=">h", scale=327.67), - ) - ] - -class _BaillyElsInfoPage(CmisPage): - """Bailly-specific fields on CMIS Page 0xB1h""" - def __init__(self, codes, page=0xB1, bank=0): - super().__init__(codes, page=page, bank=bank) - - self.fields[bailly_consts.CPO_VENDOR_INFO_FIELD] = [ - RegGroupField(bailly_consts.CPO_VENDOR_INFO_FIELD, - StringRegField(bailly_consts.VENDOR_NAME_ASCII_FIELD, self.getaddr(129), size=16), - HexRegField(bailly_consts.VENDOR_OUI_HEX_FIELD, self.getaddr(145), size=3), - StringRegField(bailly_consts.VENDOR_PART_NUMBER_ASCII_FIELD, self.getaddr(148), size=16), - StringRegField(bailly_consts.VENDOR_REVISION_ASCII_FIELD, self.getaddr(164), size=2), - StringRegField(bailly_consts.VENDOR_SERIAL_NUMBER_ASCII_FIELD, self.getaddr(166), size=16), - StringRegField(bailly_consts.DATE_CODE_YY_FIELD, self.getaddr(182), size=2), - StringRegField(bailly_consts.DATE_CODE_MM_FIELD, self.getaddr(184), size=2), - StringRegField(bailly_consts.DATE_CODE_DD_FIELD, self.getaddr(186), size=2), - StringRegField(bailly_consts.DATE_CODE_LOT_FIELD, self.getaddr(188), size=2), - DateField(bailly_consts.DATE_CODE_FIELD, self.getaddr(182), size=8), - StringRegField(bailly_consts.CLEI_CODE_FIELD, self.getaddr(190), size=10), - NumberRegField(bailly_consts.MAX_POWER_CONSUMPTION_FIELD, self.getaddr(200), format="B", size=1, scale=4.0), - NumberRegField(bailly_consts.CHECKSUM_FIELD, self.getaddr(251), format="B", size=1), - ) - ] - -class _BaillyElsThresholdPage(CmisPage): - """Bailly-specific fields on CMIS Page 0xB2h""" - def __init__(self, codes, page=0xB2, bank=0): - super().__init__(codes, page=page, bank=bank) - - self.fields[bailly_consts.LASER_POWER_MODE_CONTROL_FIELD] = [ - RegGroupField(bailly_consts.LASER_POWER_MODE_CONTROL_FIELD, - NumberRegField(bailly_consts.LASER_POWER_MODE_CONTROL_BITS_FIELD, self.getaddr(128), format="B", size=1, ro=False, - *(RegBitField(bailly_consts.CHANNEL_LASER_POWER_MODE_ENABLE.format(channel), bitpos=channel, ro=False) - for channel in range(0, 8)) - ), - RegGroupField(bailly_consts.LASER_POWER_MODE_CONTROL_CHANNELS_FIELD, - *(NumberRegField(bailly_consts.CHANNEL_LASER_POWER_MODE_ENABLE.format(channel), - self.getaddr(128), - RegBitField(bailly_consts.BIT_FIELD.format(channel), bitpos=channel, ro=False), - size=1, ro=False) - for channel in range(0, 8)) - ), - RegGroupField(bailly_consts.THRESHOLD_VALUES_FIELD, - NumberRegField(bailly_consts.TEMP_HIGH_ALARM_MSB_FIELD, self.getaddr(162), format="B", size=1), - NumberRegField(bailly_consts.TEMP_HIGH_ALARM_LSB_FIELD, self.getaddr(163), format="B", size=1), - NumberRegField(bailly_consts.TEMP_LOW_ALARM_MSB_FIELD, self.getaddr(164), format="B", size=1), - NumberRegField(bailly_consts.TEMP_LOW_ALARM_LSB_FIELD, self.getaddr(165), format="B", size=1), - NumberRegField(bailly_consts.TEMP_HIGH_WARNING_MSB_FIELD, self.getaddr(166), format="B", size=1), - NumberRegField(bailly_consts.TEMP_HIGH_WARNING_LSB_FIELD, self.getaddr(167), format="B", size=1), - NumberRegField(bailly_consts.TEMP_LOW_WARNING_MSB_FIELD, self.getaddr(168), format="B", size=1), - NumberRegField(bailly_consts.TEMP_LOW_WARNING_LSB_FIELD, self.getaddr(169), format="B", size=1), - NumberRegField(bailly_consts.VCC_HIGH_ALARM_MSB_FIELD, self.getaddr(170), format="B", size=1), - NumberRegField(bailly_consts.VCC_HIGH_ALARM_LSB_FIELD, self.getaddr(171), format="B", size=1), - NumberRegField(bailly_consts.VCC_LOW_ALARM_MSB_FIELD, self.getaddr(172), format="B", size=1), - NumberRegField(bailly_consts.VCC_LOW_ALARM_LSB_FIELD, self.getaddr(173), format="B", size=1), - NumberRegField(bailly_consts.VCC_HIGH_WARNING_MSB_FIELD, self.getaddr(174), format="B", size=1), - NumberRegField(bailly_consts.VCC_HIGH_WARNING_LSB_FIELD, self.getaddr(175), format="B", size=1), - NumberRegField(bailly_consts.VCC_LOW_WARNING_MSB_FIELD, self.getaddr(176), format="B", size=1), - NumberRegField(bailly_consts.VCC_LOW_WARNING_LSB_FIELD, self.getaddr(177), format="B", size=1), - NumberRegField(bailly_consts.TX_POWER_HIGH_ALARM_MSB_FIELD, self.getaddr(178), format="B", size=1), - NumberRegField(bailly_consts.TX_POWER_HIGH_ALARM_LSB_FIELD, self.getaddr(179), format="B", size=1), - NumberRegField(bailly_consts.TX_POWER_LOW_ALARM_MSB_FIELD, self.getaddr(180), format="B", size=1), - NumberRegField(bailly_consts.TX_POWER_LOW_ALARM_LSB_FIELD, self.getaddr(181), format="B", size=1), - NumberRegField(bailly_consts.TX_POWER_HIGH_WARNING_MSB_FIELD, self.getaddr(182), format="B", size=1), - NumberRegField(bailly_consts.TX_POWER_HIGH_WARNING_LSB_FIELD, self.getaddr(183), format="B", size=1), - NumberRegField(bailly_consts.TX_POWER_LOW_WARNING_MSB_FIELD, self.getaddr(184), format="B", size=1), - NumberRegField(bailly_consts.TX_POWER_LOW_WARNING_LSB_FIELD, self.getaddr(185), format="B", size=1), - NumberRegField(bailly_consts.TX_BIAS_HIGH_ALARM_MSB_FIELD, self.getaddr(186), format="B", size=1), - NumberRegField(bailly_consts.TX_BIAS_HIGH_ALARM_LSB_FIELD, self.getaddr(187), format="B", size=1), - NumberRegField(bailly_consts.TX_BIAS_HIGH_WARNING_MSB_FIELD, self.getaddr(188), format="B", size=1), - NumberRegField(bailly_consts.TX_BIAS_HIGH_WARNING_LSB_FIELD, self.getaddr(189), format="B", size=1), - ), - NumberRegField(bailly_consts.CHECKSUM_FIELD, self.getaddr(255), format="B", size=1), - ) - ] - -# -------------------------- Bailly Main Memory Map Class -------------------------- -class BaillyMemMap(CmisMemMap): - def __init__(self, codes, bank=0, base_page=0): - self._bank = bank - self._base_page = base_page - super().__init__(codes, bank) - - ELS_CONTROL_PAGE = 0xB0 - ELS_INFO_PAGE = 0xB1 - ELS_THRESHOLD_PAGE = 0xB2 - - self.add_pages( - _BaillyElsControlPage(codes, ELS_CONTROL_PAGE + base_page), - _BaillyElsInfoPage(codes, ELS_INFO_PAGE + base_page), - _BaillyElsThresholdPage(codes, ELS_THRESHOLD_PAGE + base_page), - ) diff --git a/sonic_platform_base/sonic_xcvr/mem_maps/bailly/__init__.py b/sonic_platform_base/sonic_xcvr/mem_maps/broadcom/__init__.py similarity index 100% rename from sonic_platform_base/sonic_xcvr/mem_maps/bailly/__init__.py rename to sonic_platform_base/sonic_xcvr/mem_maps/broadcom/__init__.py diff --git a/sonic_platform_base/sonic_xcvr/mem_maps/broadcom/bailly_rlm.py b/sonic_platform_base/sonic_xcvr/mem_maps/broadcom/bailly_rlm.py new file mode 100644 index 000000000..78fe56958 --- /dev/null +++ b/sonic_platform_base/sonic_xcvr/mem_maps/broadcom/bailly_rlm.py @@ -0,0 +1,258 @@ +""" + bailly_rlm.py + + Implementation of XcvrMemMap for Bailly extending CMIS Rev 5.0 +""" + +from ..public.cmis import CmisMemMap +from ..public.cmis.pages.page import CmisPage +from ...fields.xcvr_field import ( + CodeRegField, + DateField, + HexRegField, + NumberRegField, + RegBitField, + RegBitsField, + RegGroupField, + StringRegField, +) +from ...fields.consts import * +from ...fields.broadcom import bailly_rlm + + +class _BaillyRlmControlPage(CmisPage): + """Bailly-specific fields on CMIS Page 0xB0h""" + + def __init__(self, codes, page=0xB0, bank=0): + super().__init__(codes, page=page, bank=bank) + + self.fields[bailly_rlm.CPO_INFO_FIELD] = [ + RegGroupField(bailly_rlm.CPO_INFO_FIELD, + CodeRegField(bailly_rlm.CPO_IDENTIFIER, self.getaddr(128), codes.XCVR_IDENTIFIERS), + NumberRegField(bailly_rlm.CPO_REVISION, self.getaddr(129), format="B", size=1), + NumberRegField(bailly_rlm.LASER_GRID_AND_COUNT, self.getaddr(130), size=1, format="B"), + CodeRegField(bailly_rlm.LASER_WAVELENGTH_GRID, self.getaddr(130), + codes.LASER_WAVELENGTH_GRID, + RegBitField(bailly_rlm.BIT4_FIELD, bitpos=4, ro=True) + ), + CodeRegField(bailly_rlm.LASER_COUNT, self.getaddr(130), + codes.LASER_COUNT, + RegBitsField(bailly_rlm.BITS0_3_FIELD, bitpos=0, size=4, ro=True) + ), + ) + ] + + self.fields[bailly_rlm.LASER_CONTROL_FIELD] = [ + RegGroupField(bailly_rlm.LASER_CONTROL_FIELD, + CodeRegField(bailly_rlm.MODULE_LOW_POWER_CONTROL, self.getaddr(132), + codes.POWER_MODE, + RegBitField(bailly_rlm.BIT0_FIELD, bitpos=0, ro=False) + ), + NumberRegField(bailly_rlm.LASER_DISABLE_CONTROL_7_0, self.getaddr(133), format="B", size=1, ro=False), + NumberRegField(bailly_rlm.LASER_DISABLE_CONTROL_15_8, self.getaddr(134), format="B", size=1, ro=False), + RegGroupField(bailly_rlm.LASER_DISABLE_CONTROL_FIELD, + *(CodeRegField(bailly_rlm.LASER_DISABLE_CONTROL.format(laser), + self.getaddr(133 + laser // 8), + codes.LASER_DISABLE_CONTROL, + RegBitField(bailly_rlm.BIT_FIELD.format(laser % 8), bitpos=laser % 8, ro=False), + ) + for laser in range(0, 16)) + ), + ) + ] + + self.fields[bailly_rlm.LASER_STATUS_FIELD] = [ + RegGroupField(bailly_rlm.LASER_STATUS_FIELD, + NumberRegField(bailly_rlm.MODULE_STATE_AND_INTERRUPT, self.getaddr(131), size=1, format="B"), + CodeRegField(bailly_rlm.MODULE_LOW_POWER_STATE, self.getaddr(131), + codes.POWER_MODE, + RegBitField(bailly_rlm.BIT1_FIELD, bitpos=1) + ), + CodeRegField(bailly_rlm.INTL_INTERRUPT_STATUS, self.getaddr(131), + codes.INTERRUPT_STATUS, + RegBitField(bailly_rlm.BIT0_FIELD, bitpos=0) + ), + NumberRegField(bailly_rlm.LASER_ACTIVE_STATUS_7_0, self.getaddr(135), format="B", size=1), + NumberRegField(bailly_rlm.LASER_ACTIVE_STATUS_15_8, self.getaddr(136), format="B", size=1), + RegGroupField(bailly_rlm.LASER_ACTIVE_STATUS_FIELD, + *(CodeRegField(bailly_rlm.LASER_ACTIVE_STATUS.format(laser), + self.getaddr(135 + laser // 8), + codes.LASER_ACTIVE_STATUS, + RegBitField(bailly_rlm.BIT_FIELD.format(laser % 8), bitpos=laser % 8), + size=1) + for laser in range(0, 16)) + ), + ) + ] + + self.fields[bailly_rlm.MODULE_ALARMS_FIELD] = [ + RegGroupField(bailly_rlm.MODULE_ALARMS_FIELD, + NumberRegField(bailly_rlm.VCC_3V3_TEMPERATURE_WARNING_ALARM, self.getaddr(137), format="B", size=1), + RegBitField(bailly_rlm.TEMP_HIGH_ALARM_FLAG, offset=self.getaddr(137), bitpos=0), + RegBitField(bailly_rlm.TEMP_LOW_ALARM_FLAG, offset=self.getaddr(137), bitpos=1), + RegBitField(bailly_rlm.TEMP_HIGH_WARN_FLAG, offset=self.getaddr(137), bitpos=2), + RegBitField(bailly_rlm.TEMP_LOW_WARN_FLAG, offset=self.getaddr(137), bitpos=3), + RegBitField(bailly_rlm.VOLTAGE_HIGH_ALARM_FLAG, offset=self.getaddr(137), bitpos=4), + RegBitField(bailly_rlm.VOLTAGE_LOW_ALARM_FLAG, offset=self.getaddr(137), bitpos=5), + RegBitField(bailly_rlm.VOLTAGE_HIGH_WARN_FLAG, offset=self.getaddr(137), bitpos=6), + RegBitField(bailly_rlm.VOLTAGE_LOW_WARN_FLAG, offset=self.getaddr(137), bitpos=7), + NumberRegField(bailly_rlm.LASER_BIAS_WARNING_7_0, self.getaddr(138), format="B", size=1), + NumberRegField(bailly_rlm.LASER_BIAS_WARNING_15_8, self.getaddr(139), format="B", size=1), + RegGroupField(bailly_rlm.LASER_BIAS_WARNING_FIELD, + *(NumberRegField(bailly_rlm.LASER_BIAS_WARNING.format(laser), + self.getaddr(138 + laser // 8), + RegBitField(bailly_rlm.BIT_FIELD.format(laser % 8), bitpos=laser % 8), + size=1) + for laser in range(0, 16)) + ), + NumberRegField(bailly_rlm.LASER_BIAS_ALARM_7_0, self.getaddr(140), format="B", size=1), + NumberRegField(bailly_rlm.LASER_BIAS_ALARM_15_8, self.getaddr(141), format="B", size=1), + RegGroupField(bailly_rlm.LASER_BIAS_ALARM_FIELD, + *(NumberRegField(bailly_rlm.LASER_BIAS_ALARM.format(laser), + self.getaddr(140 + laser // 8), + RegBitField(bailly_rlm.BIT_FIELD.format(laser % 8), bitpos=laser % 8), + size=1) + for laser in range(0, 16)) + ), + ) + ] + + self.fields[bailly_rlm.CPO_MODULE_MONITORS_FIELD] = [ + RegGroupField(bailly_rlm.CPO_MODULE_MONITORS_FIELD, + NumberRegField(bailly_rlm.MODULE_TEMPERATURE_MONITOR_MSB, self.getaddr(150), format="B", size=1), + NumberRegField(bailly_rlm.MODULE_TEMPERATURE_MONITOR_LSB, self.getaddr(151), format="B", size=1), + NumberRegField(bailly_rlm.MODULE_TEMPERATURE_MONITOR, self.getaddr(150), size=2, format=">h", scale=256.0), + NumberRegField(bailly_rlm.MODULE_SUPPLY_VOLTAGE_MONITOR_MSB, self.getaddr(152), format="B", size=1), + NumberRegField(bailly_rlm.MODULE_SUPPLY_VOLTAGE_MONITOR_LSB, self.getaddr(153), format="B", size=1), + NumberRegField(bailly_rlm.MODULE_SUPPLY_VOLTAGE_MONITOR, self.getaddr(152), size=2, format=">H", scale=10000.0), + RegGroupField(bailly_rlm.LASER_CURRENT_MONITOR_FIELD, + *(NumberRegField(bailly_rlm.LASER_CURRENT_MONITOR.format(laser), + self.getaddr(154 + 2 * laser), size=2, format=">H", scale=100.0) + for laser in range(0, 16)) + ), + RegGroupField(bailly_rlm.LASER_VOLTAGE_MONITOR_FIELD, + *(NumberRegField(bailly_rlm.LASER_VOLTAGE_MONITOR.format(laser), + self.getaddr(186 + laser), size=1, format="B", scale=100.0) + for laser in range(0, 16)) + ), + RegGroupField(bailly_rlm.LASER_OPTICAL_POWER_MONITOR_FIELD, + *(NumberRegField(bailly_rlm.LASER_OPTICAL_POWER_MONITOR.format(laser), + self.getaddr(203 + 2 * laser), size=2, format=">H", scale=100.0) + for laser in range(0, 16)) + ), + NumberRegField(bailly_rlm.TEC_CURRENT_MONITOR_MSB, self.getaddr(250), format="B", size=1), + NumberRegField(bailly_rlm.TEC_CURRENT_MONITOR_LSB, self.getaddr(251), format="B", size=1), + NumberRegField(bailly_rlm.TEC_CURRENT_MONITOR, self.getaddr(250), size=2, format=">h", scale=327.67), + ) + ] + + +class _BaillyRlmInfoPage(CmisPage): + """Bailly-specific fields on CMIS Page 0xB1h""" + + def __init__(self, codes, page=0xB1, bank=0): + super().__init__(codes, page=page, bank=bank) + + self.fields[bailly_rlm.CPO_VENDOR_INFO_FIELD] = [ + RegGroupField(bailly_rlm.CPO_VENDOR_INFO_FIELD, + StringRegField(bailly_rlm.VENDOR_NAME_ASCII_FIELD, self.getaddr(129), size=16), + HexRegField(bailly_rlm.VENDOR_OUI_HEX_FIELD, self.getaddr(145), size=3), + StringRegField(bailly_rlm.VENDOR_PART_NUMBER_ASCII_FIELD, self.getaddr(148), size=16), + StringRegField(bailly_rlm.VENDOR_REVISION_ASCII_FIELD, self.getaddr(164), size=2), + StringRegField(bailly_rlm.VENDOR_SERIAL_NUMBER_ASCII_FIELD, self.getaddr(166), size=16), + StringRegField(bailly_rlm.DATE_CODE_YY_FIELD, self.getaddr(182), size=2), + StringRegField(bailly_rlm.DATE_CODE_MM_FIELD, self.getaddr(184), size=2), + StringRegField(bailly_rlm.DATE_CODE_DD_FIELD, self.getaddr(186), size=2), + StringRegField(bailly_rlm.DATE_CODE_LOT_FIELD, self.getaddr(188), size=2), + DateField(bailly_rlm.DATE_CODE_FIELD, self.getaddr(182), size=8), + StringRegField(bailly_rlm.CLEI_CODE_FIELD, self.getaddr(190), size=10), + NumberRegField(bailly_rlm.MAX_POWER_CONSUMPTION_FIELD, self.getaddr(200), format="B", size=1, scale=4.0), + NumberRegField(bailly_rlm.CHECKSUM_FIELD, self.getaddr(251), format="B", size=1), + ) + ] + + +class _BaillyRlmThresholdPage(CmisPage): + """Bailly-specific fields on CMIS Page 0xB2h""" + + def __init__(self, codes, page=0xB2, bank=0): + super().__init__(codes, page=page, bank=bank) + + self.fields[bailly_rlm.LASER_POWER_MODE_CONTROL_FIELD] = [ + RegGroupField(bailly_rlm.LASER_POWER_MODE_CONTROL_FIELD, + NumberRegField(bailly_rlm.LASER_POWER_MODE_CONTROL_BITS_FIELD, self.getaddr(128), format="B", size=1, ro=False, + *(RegBitField(bailly_rlm.CHANNEL_LASER_POWER_MODE_ENABLE.format(channel), bitpos=channel, ro=False) + for channel in range(0, 8)) + ), + RegGroupField(bailly_rlm.LASER_POWER_MODE_CONTROL_CHANNELS_FIELD, + *(CodeRegField(bailly_rlm.CHANNEL_LASER_POWER_MODE_ENABLE.format(channel), + self.getaddr(128), + codes.LASER_POWER_MODE_ENABLE, + RegBitField(bailly_rlm.BIT_FIELD.format(channel), bitpos=channel, ro=False), + ) + for channel in range(0, 8)) + ), + RegGroupField(bailly_rlm.THRESHOLD_VALUES_FIELD, + NumberRegField(bailly_rlm.RLM_TEMP_HIGH_ALARM_FIELD, self.getaddr(162), size=2, format=">h", scale=256.0), + NumberRegField(bailly_rlm.TEMP_HIGH_ALARM_MSB_FIELD, self.getaddr(162), format="B", size=1), + NumberRegField(bailly_rlm.TEMP_HIGH_ALARM_LSB_FIELD, self.getaddr(163), format="B", size=1), + NumberRegField(bailly_rlm.RLM_TEMP_LOW_ALARM_FIELD, self.getaddr(164), size=2, format=">h", scale=256.0), + NumberRegField(bailly_rlm.TEMP_LOW_ALARM_MSB_FIELD, self.getaddr(164), format="B", size=1), + NumberRegField(bailly_rlm.TEMP_LOW_ALARM_LSB_FIELD, self.getaddr(165), format="B", size=1), + NumberRegField(bailly_rlm.RLM_TEMP_HIGH_WARNING_FIELD, self.getaddr(166), size=2, format=">h", scale=256.0), + NumberRegField(bailly_rlm.TEMP_HIGH_WARNING_MSB_FIELD, self.getaddr(166), format="B", size=1), + NumberRegField(bailly_rlm.TEMP_HIGH_WARNING_LSB_FIELD, self.getaddr(167), format="B", size=1), + NumberRegField(bailly_rlm.RLM_TEMP_LOW_WARNING_FIELD, self.getaddr(168), size=2, format=">h", scale=256.0), + NumberRegField(bailly_rlm.TEMP_LOW_WARNING_MSB_FIELD, self.getaddr(168), format="B", size=1), + NumberRegField(bailly_rlm.TEMP_LOW_WARNING_LSB_FIELD, self.getaddr(169), format="B", size=1), + NumberRegField(bailly_rlm.RLM_VCC_HIGH_ALARM_FIELD, self.getaddr(170), size=2, format=">H", scale=10000.0), + NumberRegField(bailly_rlm.VCC_HIGH_ALARM_MSB_FIELD, self.getaddr(170), format="B", size=1), + NumberRegField(bailly_rlm.VCC_HIGH_ALARM_LSB_FIELD, self.getaddr(171), format="B", size=1), + NumberRegField(bailly_rlm.RLM_VCC_LOW_ALARM_FIELD, self.getaddr(172), size=2, format=">H", scale=10000.0), + NumberRegField(bailly_rlm.VCC_LOW_ALARM_MSB_FIELD, self.getaddr(172), format="B", size=1), + NumberRegField(bailly_rlm.VCC_LOW_ALARM_LSB_FIELD, self.getaddr(173), format="B", size=1), + NumberRegField(bailly_rlm.RLM_VCC_HIGH_WARNING_FIELD, self.getaddr(174), size=2, format=">H", scale=10000.0), + NumberRegField(bailly_rlm.VCC_HIGH_WARNING_MSB_FIELD, self.getaddr(174), format="B", size=1), + NumberRegField(bailly_rlm.VCC_HIGH_WARNING_LSB_FIELD, self.getaddr(175), format="B", size=1), + NumberRegField(bailly_rlm.RLM_VCC_LOW_WARNING_FIELD, self.getaddr(176), size=2, format=">H", scale=10000.0), + NumberRegField(bailly_rlm.VCC_LOW_WARNING_MSB_FIELD, self.getaddr(176), format="B", size=1), + NumberRegField(bailly_rlm.VCC_LOW_WARNING_LSB_FIELD, self.getaddr(177), format="B", size=1), + NumberRegField(bailly_rlm.RLM_TX_POWER_HIGH_ALARM_FIELD, self.getaddr(178), size=2, format=">H", scale=100.0), + NumberRegField(bailly_rlm.TX_POWER_HIGH_ALARM_MSB_FIELD, self.getaddr(178), format="B", size=1), + NumberRegField(bailly_rlm.TX_POWER_HIGH_ALARM_LSB_FIELD, self.getaddr(179), format="B", size=1), + NumberRegField(bailly_rlm.RLM_TX_POWER_LOW_ALARM_FIELD, self.getaddr(180), size=2, format=">H", scale=100.0), + NumberRegField(bailly_rlm.TX_POWER_LOW_ALARM_MSB_FIELD, self.getaddr(180), format="B", size=1), + NumberRegField(bailly_rlm.TX_POWER_LOW_ALARM_LSB_FIELD, self.getaddr(181), format="B", size=1), + NumberRegField(bailly_rlm.RLM_TX_POWER_HIGH_WARNING_FIELD, self.getaddr(182), size=2, format=">H", scale=100.0), + NumberRegField(bailly_rlm.TX_POWER_HIGH_WARNING_MSB_FIELD, self.getaddr(182), format="B", size=1), + NumberRegField(bailly_rlm.TX_POWER_HIGH_WARNING_LSB_FIELD, self.getaddr(183), format="B", size=1), + NumberRegField(bailly_rlm.RLM_TX_POWER_LOW_WARNING_FIELD, self.getaddr(184), size=2, format=">H", scale=100.0), + NumberRegField(bailly_rlm.TX_POWER_LOW_WARNING_MSB_FIELD, self.getaddr(184), format="B", size=1), + NumberRegField(bailly_rlm.TX_POWER_LOW_WARNING_LSB_FIELD, self.getaddr(185), format="B", size=1), + NumberRegField(bailly_rlm.RLM_TX_BIAS_HIGH_ALARM_FIELD, self.getaddr(186), size=2, format=">H", scale=100.0), + NumberRegField(bailly_rlm.TX_BIAS_HIGH_ALARM_MSB_FIELD, self.getaddr(186), format="B", size=1), + NumberRegField(bailly_rlm.TX_BIAS_HIGH_ALARM_LSB_FIELD, self.getaddr(187), format="B", size=1), + NumberRegField(bailly_rlm.RLM_TX_BIAS_HIGH_WARNING_FIELD, self.getaddr(188), size=2, format=">H", scale=100.0), + NumberRegField(bailly_rlm.TX_BIAS_HIGH_WARNING_MSB_FIELD, self.getaddr(188), format="B", size=1), + NumberRegField(bailly_rlm.TX_BIAS_HIGH_WARNING_LSB_FIELD, self.getaddr(189), format="B", size=1), + ), + NumberRegField(bailly_rlm.CHECKSUM_FIELD, self.getaddr(255), format="B", size=1), + ) + ] + + +class BaillyMemMap(CmisMemMap): + def __init__(self, codes, bank=0, base_page=0): + self._bank = bank + self._base_page = base_page + super().__init__(codes, bank) + + RLM_CONTROL_PAGE = 0xB0 + RLM_INFO_PAGE = 0xB1 + RLM_THRESHOLD_PAGE = 0xB2 + + self.add_pages( + _BaillyRlmControlPage(codes, RLM_CONTROL_PAGE + base_page), + _BaillyRlmInfoPage(codes, RLM_INFO_PAGE + base_page), + _BaillyRlmThresholdPage(codes, RLM_THRESHOLD_PAGE + base_page), + ) diff --git a/tests/sonic_xcvr/test_bailly_cmis.py b/tests/sonic_xcvr/test_bailly_cmis.py index a5f06b3fc..84ef2de03 100644 --- a/tests/sonic_xcvr/test_bailly_cmis.py +++ b/tests/sonic_xcvr/test_bailly_cmis.py @@ -1,8 +1,8 @@ import pytest from unittest.mock import MagicMock, patch, Mock -from sonic_platform_base.sonic_xcvr.api.bailly.bailly_api import BaillyApi -from sonic_platform_base.sonic_xcvr.mem_maps.bailly.bailly_mem_map import BaillyMemMap -from sonic_platform_base.sonic_xcvr.codes.bailly.bailly_codes import BaillyCodes +from sonic_platform_base.sonic_xcvr.api.broadcom.bailly_rlm import BaillyApi +from sonic_platform_base.sonic_xcvr.mem_maps.broadcom.bailly_rlm import BaillyMemMap +from sonic_platform_base.sonic_xcvr.codes.broadcom.bailly_rlm import BaillyCodes from sonic_platform_base.sonic_xcvr.xcvr_eeprom import XcvrEeprom # Test BaillyCodes @@ -51,6 +51,12 @@ def test__format_revision_values(self): assert self.api._format_revision(0xF5) == "15.5" assert self.api._format_revision(0x00) == "0.0" + def test__format_float(self): + assert self.api._format_float(None) is None + assert self.api._format_float({"key": "value"}) is None + assert self.api._format_float(1.23456) == 1.235 + assert self.api._format_float(3.14159) == 3.142 + def test_get_active_apsel_hostlane_with_zero_returns_current_map(self): app_values = [1, 2, 0, 3, 4, 5, 6, 7] with patch.object(self.api, 'get_application', side_effect=app_values): @@ -69,17 +75,310 @@ def test_get_active_apsel_hostlane_no_zero_calls_parent(self): assert result == fake_parent mock_super.assert_called_once() - def test_get_transceiver_info(self): - with patch.object(self.api, 'get_els_info') as mock_els: - mock_els.return_value = {} - with patch('sonic_platform_base.sonic_xcvr.api.public.cmis.CmisApi.get_transceiver_info') as mock_super: - mock_super.return_value = {} - self.api.get_transceiver_info() - mock_super.assert_called_once() - mock_els.assert_called_once() + def test_get_rlm_temperature(self): + self.mock_eeprom.read.return_value = None + assert self.api.get_rlm_temperature() is None + + mock_monitors = { + 'MODULE_TEMPERATURE_MONITOR': 25.6789 + } + self.mock_eeprom.read.return_value = mock_monitors + with patch('sonic_platform_base.sonic_xcvr.api.broadcom.bailly_rlm.bailly_rlm.MODULE_TEMPERATURE_MONITOR', + 'MODULE_TEMPERATURE_MONITOR'): + assert self.api.get_rlm_temperature() == 25.679 + + def test__get_nested_monitor_value(self): + monitors = {} + assert self.api._get_nested_monitor_value(monitors, 'group', 'value') is None + + monitors = {'group': {}} + assert self.api._get_nested_monitor_value(monitors, 'group', 'value') is None + + monitors = {'group': {'value': {'value': 10.123}}} + assert self.api._get_nested_monitor_value(monitors, 'group', 'value') == 10.123 + + monitors = {'group': {'value': 20.456}} + assert self.api._get_nested_monitor_value(monitors, 'group', 'value') == 20.456 + + def test_get_rlm_monitor_values(self): + self.mock_eeprom.read.return_value = None + assert self.api.get_rlm_monitor_values() is None + + mock_monitors = { + 'MODULE_TEMPERATURE_MONITOR': 25.1234, + 'MODULE_SUPPLY_VOLTAGE_MONITOR': 3.3456, + 'TEC_CURRENT_MONITOR': None + } + self.mock_eeprom.read.return_value = mock_monitors + with patch.multiple('sonic_platform_base.sonic_xcvr.api.broadcom.bailly_rlm.bailly_rlm', + MODULE_TEMPERATURE_MONITOR='MODULE_TEMPERATURE_MONITOR', + MODULE_SUPPLY_VOLTAGE_MONITOR='MODULE_SUPPLY_VOLTAGE_MONITOR', + TEC_CURRENT_MONITOR='TEC_CURRENT_MONITOR'): + result = self.api.get_rlm_monitor_values() + assert result == { + "RLM_temperature": 25.123, + "RLM_voltage": 3.346, + "RLM_tec_current": None + } + + def test_get_rlm_thresholds(self): + """Test get_rlm_thresholds""" + self.mock_eeprom.read.return_value = {} + result = self.api.get_rlm_thresholds() + assert result is None + + def test_get_rlm_temperature_thresholds(self): + with patch.object(self.api, 'get_rlm_thresholds', return_value=None): + assert self.api.get_rlm_temperature_thresholds() is None + + mock_thresholds = { + "RLM_temphighalarm": 85.0, + "RLM_templowalarm": -5.0, + "RLM_temphighwarning": 75.0, + "RLM_templowwarning": 0.0, + "RLM_vcchighalarm": 3.6 + } + with patch.object(self.api, 'get_rlm_thresholds', return_value=mock_thresholds): + result = self.api.get_rlm_temperature_thresholds() + assert result == { + "temphighalarm": 85.0, + "templowalarm": -5.0, + "temphighwarning": 75.0, + "templowwarning": 0.0 + } + + def test_get_rlm_flags(self): + self.mock_eeprom.read.return_value = None + assert self.api.get_rlm_flags() is None + + mock_alarms = { + 'TEMP_HIGH_ALARM_FLAG': True, + 'TEMP_LOW_ALARM_FLAG': False, + 'TEMP_HIGH_WARN_FLAG': True, + 'TEMP_LOW_WARN_FLAG': False, + 'VOLTAGE_HIGH_ALARM_FLAG': True, + 'VOLTAGE_LOW_ALARM_FLAG': False, + 'VOLTAGE_HIGH_WARN_FLAG': True, + 'VOLTAGE_LOW_WARN_FLAG': False + } + self.mock_eeprom.read.return_value = mock_alarms + with patch.multiple('sonic_platform_base.sonic_xcvr.api.broadcom.bailly_rlm.bailly_rlm', + TEMP_HIGH_ALARM_FLAG='TEMP_HIGH_ALARM_FLAG', + TEMP_LOW_ALARM_FLAG='TEMP_LOW_ALARM_FLAG', + TEMP_HIGH_WARN_FLAG='TEMP_HIGH_WARN_FLAG', + TEMP_LOW_WARN_FLAG='TEMP_LOW_WARN_FLAG', + VOLTAGE_HIGH_ALARM_FLAG='VOLTAGE_HIGH_ALARM_FLAG', + VOLTAGE_LOW_ALARM_FLAG='VOLTAGE_LOW_ALARM_FLAG', + VOLTAGE_HIGH_WARN_FLAG='VOLTAGE_HIGH_WARN_FLAG', + VOLTAGE_LOW_WARN_FLAG='VOLTAGE_LOW_WARN_FLAG'): + result = self.api.get_rlm_flags() + assert result == { + "RLM_tempHAlarm": True, + "RLM_tempLAlarm": False, + "RLM_tempHWarn": True, + "RLM_tempLWarn": False, + "RLM_vccHAlarm": True, + "RLM_vccLAlarm": False, + "RLM_vccHWarn": True, + "RLM_vccLWarn": False + } - def test_get_els_info(self): - self.mock_eeprom.read.return_value = 0 - result = self.api.get_els_info() - assert isinstance(result, dict) + def test_get_rlm_temperature_flags(self): + with patch.object(self.api, 'get_rlm_flags', return_value=None): + assert self.api.get_rlm_temperature_flags() is None + mock_flags = { + "RLM_tempHAlarm": True, + "RLM_tempLAlarm": False, + "RLM_tempHWarn": True, + "RLM_tempLWarn": False, + "RLM_vccHAlarm": True + } + with patch.object(self.api, 'get_rlm_flags', return_value=mock_flags): + result = self.api.get_rlm_temperature_flags() + assert result == { + "tempHAlarm": True, + "tempLAlarm": False, + "tempHWarn": True, + "tempLWarn": False + } + + def test_get_transceiver_dom_real_value(self): + with patch.object(BaillyApi.__bases__[0], 'get_transceiver_dom_real_value', return_value=None): + # 测试 rlm_monitors 为 None + with patch.object(self.api, 'get_rlm_monitor_values', return_value=None): + assert self.api.get_transceiver_dom_real_value() == {} + + mock_rlm_monitors = { + "RLM_temperature": 25.123, + "RLM_voltage": 3.346, + "RLM_invalid": None + } + with patch.object(self.api, 'get_rlm_monitor_values', return_value=mock_rlm_monitors): + result = self.api.get_transceiver_dom_real_value() + assert result == { + "RLM_temperature": 25.123, + "RLM_voltage": 3.346 + } + + parent_dom = {"temp": 20.0} + with patch.object(BaillyApi.__bases__[0], 'get_transceiver_dom_real_value', return_value=parent_dom): + mock_rlm_monitors = {"RLM_temperature": 25.123} + with patch.object(self.api, 'get_rlm_monitor_values', return_value=mock_rlm_monitors): + result = self.api.get_transceiver_dom_real_value() + assert result == { + "temp": 20.0, + "RLM_temperature": 25.123 + } + + def test_get_transceiver_dom_flags(self): + with patch.object(BaillyApi.__bases__[0], 'get_transceiver_dom_flags', return_value=None): + with patch.object(self.api, 'get_rlm_flags', return_value=None): + assert self.api.get_transceiver_dom_flags() == {} + + mock_rlm_flags = { + "RLM_tempHAlarm": True, + "RLM_tempLAlarm": False, + "RLM_invalid": None + } + with patch.object(self.api, 'get_rlm_flags', return_value=mock_rlm_flags): + result = self.api.get_transceiver_dom_flags() + assert result == { + "RLM_tempHAlarm": True, + "RLM_tempLAlarm": False + } + + parent_flags = {"tx_fault": True} + with patch.object(BaillyApi.__bases__[0], 'get_transceiver_dom_flags', return_value=parent_flags): + mock_rlm_flags = {"RLM_tempHAlarm": True} + with patch.object(self.api, 'get_rlm_flags', return_value=mock_rlm_flags): + result = self.api.get_transceiver_dom_flags() + assert result == { + "tx_fault": True, + "RLM_tempHAlarm": True + } + + def test_get_transceiver_status_flags(self): + with patch.object(BaillyApi.__bases__[0], 'get_transceiver_status_flags', return_value=None): + with patch.object(self.api, 'get_rlm_flags', return_value=None): + with patch.object(self.api, 'get_rlm_status', return_value=None): + assert self.api.get_transceiver_status_flags() == {} + + mock_rlm_flags = { + "RLM_tempHAlarm": True, + "RLM_tempLAlarm": False, + "RLM_invalid": None + } + with patch.object(self.api, 'get_rlm_flags', return_value=mock_rlm_flags): + with patch.object(self.api, 'get_rlm_status', return_value=None): + result = self.api.get_transceiver_status_flags() + assert result == { + "RLM_tempHAlarm": True, + "RLM_tempLAlarm": False + } + + parent_flags = {"rx_los": True} + with patch.object(BaillyApi.__bases__[0], 'get_transceiver_status_flags', return_value=parent_flags): + mock_rlm_flags = {"RLM_tempHAlarm": True} + mock_rlm_status = { + "RLM_module_low_power_state": False, + "RLM_interrupt_status": True + } + with patch.object(self.api, 'get_rlm_flags', return_value=mock_rlm_flags): + with patch.object(self.api, 'get_rlm_status', return_value=mock_rlm_status): + result = self.api.get_transceiver_status_flags() + assert result == { + "rx_los": True, + "RLM_tempHAlarm": True, + "RLM_module_low_power_state": False, + "RLM_interrupt_status": True + } + + def test_get_transceiver_threshold_info(self): + with patch.object(BaillyApi.__bases__[0], 'get_transceiver_threshold_info', return_value=None): + with patch.object(self.api, 'get_rlm_thresholds', return_value=None): + assert self.api.get_transceiver_threshold_info() == {} + + mock_rlm_thresholds = { + "RLM_temphighalarm": 85.0, + "RLM_templowalarm": -5.0, + "RLM_invalid": None + } + with patch.object(self.api, 'get_rlm_thresholds', return_value=mock_rlm_thresholds): + result = self.api.get_transceiver_threshold_info() + assert result == { + "RLM_temphighalarm": 85.0, + "RLM_templowalarm": -5.0 + } + + parent_thresholds = {"temp_high_alarm": 80.0} + with patch.object(BaillyApi.__bases__[0], 'get_transceiver_threshold_info', return_value=parent_thresholds): + mock_rlm_thresholds = {"RLM_temphighalarm": 85.0} + with patch.object(self.api, 'get_rlm_thresholds', return_value=mock_rlm_thresholds): + result = self.api.get_transceiver_threshold_info() + assert result == { + "temp_high_alarm": 80.0, + "RLM_temphighalarm": 85.0 + } + + def test_get_rlm_vendor_info(self): + self.mock_eeprom.read.return_value = {"vendor_name": "test_vendor"} + with patch('sonic_platform_base.sonic_xcvr.api.broadcom.bailly_rlm.bailly_rlm.CPO_VENDOR_INFO_FIELD', + 'CPO_VENDOR_INFO_FIELD'): + result = self.api.get_rlm_vendor_info() + assert result == {"vendor_name": "test_vendor"} + self.mock_eeprom.read.assert_called_with('CPO_VENDOR_INFO_FIELD') + + def test_get_rlm_info(self): + mock_cpo_info = {"cpo_id": 123} + mock_vendor_info = {"vendor": "test"} + mock_laser_mode = {"power_mode": "high"} + + with patch.object(self.api, 'get_rlm_vendor_info', return_value=mock_vendor_info): + self.mock_eeprom.read.side_effect = [mock_cpo_info, mock_laser_mode] + + with patch.multiple('sonic_platform_base.sonic_xcvr.api.broadcom.bailly_rlm.bailly_rlm', + CPO_INFO_FIELD='CPO_INFO_FIELD', + LASER_POWER_MODE_CONTROL_FIELD='LASER_POWER_MODE_CONTROL_FIELD'): + result = self.api.get_rlm_info() + assert result == { + "cpo_info": mock_cpo_info, + "rlm_vendor_info": mock_vendor_info, + "laser_power_mode": mock_laser_mode + } + + def test_get_rlm_laser_current(self): + self.mock_eeprom.read.return_value = 50.0 + with patch('sonic_platform_base.sonic_xcvr.api.broadcom.bailly_rlm.bailly_rlm.LASER_CURRENT_MONITOR_FIELD', + 'LASER_CURRENT_MONITOR_FIELD'): + result = self.api.get_rlm_laser_current() + assert result == 50.0 + self.mock_eeprom.read.assert_called_with('LASER_CURRENT_MONITOR_FIELD') + + def test_get_rlm_laser_voltage(self): + self.mock_eeprom.read.return_value = 2.5 + with patch('sonic_platform_base.sonic_xcvr.api.broadcom.bailly_rlm.bailly_rlm.LASER_VOLTAGE_MONITOR_FIELD', + 'LASER_VOLTAGE_MONITOR_FIELD'): + result = self.api.get_rlm_laser_voltage() + assert result == 2.5 + self.mock_eeprom.read.assert_called_with('LASER_VOLTAGE_MONITOR_FIELD') + + def test_get_rlm_laser_power(self): + self.mock_eeprom.read.return_value = 10.0 + with patch('sonic_platform_base.sonic_xcvr.api.broadcom.bailly_rlm.bailly_rlm.LASER_OPTICAL_POWER_MONITOR_FIELD', + 'LASER_OPTICAL_POWER_MONITOR_FIELD'): + result = self.api.get_rlm_laser_power() + assert result == 10.0 + self.mock_eeprom.read.assert_called_with('LASER_OPTICAL_POWER_MONITOR_FIELD') + + def test_get_transceiver_info(self): + """Test get_transceiver_info combines parent and RLM info""" + with patch.object(self.api, 'get_rlm_info') as mock_get_rlm: + mock_get_rlm.return_value = { + "cpo_info": None, + "rlm_vendor_info": None, + "laser_power_mode": None + } + result = self.api.get_transceiver_info() + assert result is not None + assert isinstance(result, dict)