diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 01f8b9f14..551ea8e76 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -1133,34 +1133,42 @@ def set_loopback_mode(self, loopback_mode, lane_mask = 0xff): loopback_capability = self.get_loopback_capability() if loopback_capability is None: return False + + status_host_input = self.xcvr_eeprom.read(consts.HOST_INPUT_LOOPBACK) + status_host_output = self.xcvr_eeprom.read(consts.HOST_OUTPUT_LOOPBACK) + status_media_input = self.xcvr_eeprom.read(consts.MEDIA_INPUT_LOOPBACK) + status_media_output = self.xcvr_eeprom.read(consts.MEDIA_OUTPUT_LOOPBACK) + if loopback_mode == 'none': status_host_input = self.xcvr_eeprom.write(consts.HOST_INPUT_LOOPBACK, 0) status_host_output = self.xcvr_eeprom.write(consts.HOST_OUTPUT_LOOPBACK, 0) status_media_input = self.xcvr_eeprom.write(consts.MEDIA_INPUT_LOOPBACK, 0) status_media_output = self.xcvr_eeprom.write(consts.MEDIA_OUTPUT_LOOPBACK, 0) return all([status_host_input, status_host_output, status_media_input, status_media_output]) - elif loopback_mode == 'host-side-input': - if loopback_capability['host_side_input_loopback_supported']: - return self.xcvr_eeprom.write(consts.HOST_INPUT_LOOPBACK, lane_mask) - else: - return False - elif loopback_mode == 'host-side-output': - if loopback_capability['host_side_output_loopback_supported']: - return self.xcvr_eeprom.write(consts.HOST_OUTPUT_LOOPBACK, lane_mask) - else: - return False - elif loopback_mode == 'media-side-input': - if loopback_capability['media_side_input_loopback_supported']: - return self.xcvr_eeprom.write(consts.MEDIA_INPUT_LOOPBACK, lane_mask) - else: - return False - elif loopback_mode == 'media-side-output': - if loopback_capability['media_side_output_loopback_supported']: - return self.xcvr_eeprom.write(consts.MEDIA_OUTPUT_LOOPBACK, lane_mask) - else: - return False else: - return False + if loopback_capability['simultaneous_host_media_loopback_supported'] is False: + if loopback_mode in ['host-side-input', 'host-side-output'] and \ + (status_media_input or status_media_output): + return False + + if loopback_mode in ['media-side-input', 'media-side-output'] and \ + (status_host_output or status_host_input): + return False + + if loopback_mode == 'host-side-input': + if loopback_capability['host_side_input_loopback_supported']: + return self.xcvr_eeprom.write(consts.HOST_INPUT_LOOPBACK, lane_mask) + elif loopback_mode == 'host-side-output': + if loopback_capability['host_side_output_loopback_supported']: + return self.xcvr_eeprom.write(consts.HOST_OUTPUT_LOOPBACK, lane_mask) + elif loopback_mode == 'media-side-input': + if loopback_capability['media_side_input_loopback_supported']: + return self.xcvr_eeprom.write(consts.MEDIA_INPUT_LOOPBACK, lane_mask) + elif loopback_mode == 'media-side-output': + if loopback_capability['media_side_output_loopback_supported']: + return self.xcvr_eeprom.write(consts.MEDIA_OUTPUT_LOOPBACK, lane_mask) + + return False def get_vdm(self, field_option=None): ''' diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index e1cc5c38c..33f40964b 100644 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -1057,31 +1057,36 @@ def test_get_loopback_capability(self, mock_response, expected): 'host_side_input_loopback_supported': True, 'host_side_output_loopback_supported': True, 'media_side_input_loopback_supported': True, - 'media_side_output_loopback_supported': True + 'media_side_output_loopback_supported': True, + 'simultaneous_host_media_loopback_supported': True }), ('host-side-input', { 'host_side_input_loopback_supported': True, 'host_side_output_loopback_supported': True, 'media_side_input_loopback_supported': True, - 'media_side_output_loopback_supported': True + 'media_side_output_loopback_supported': True, + 'simultaneous_host_media_loopback_supported': True }), ('host-side-output', { 'host_side_input_loopback_supported': True, 'host_side_output_loopback_supported': True, 'media_side_input_loopback_supported': True, - 'media_side_output_loopback_supported': True + 'media_side_output_loopback_supported': True, + 'simultaneous_host_media_loopback_supported': False }), ('media-side-input', { 'host_side_input_loopback_supported': True, 'host_side_output_loopback_supported': True, 'media_side_input_loopback_supported': True, - 'media_side_output_loopback_supported': True + 'media_side_output_loopback_supported': True, + 'simultaneous_host_media_loopback_supported': False }), ('media-side-output', { 'host_side_input_loopback_supported': True, 'host_side_output_loopback_supported': True, 'media_side_input_loopback_supported': True, - 'media_side_output_loopback_supported': True + 'media_side_output_loopback_supported': True, + 'simultaneous_host_media_loopback_supported': True }), ( 'none', None