From 2c4e89b5b67862eee9de9a19a896e6fe36720f6f Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 5 Jul 2023 18:54:43 -0700 Subject: [PATCH 01/42] Validate and apply module SI settings --- .../sonic_xcvr/api/public/cmis.py | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 36657ddd7..6d99c0560 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2097,6 +2097,116 @@ def set_application(self, channel, appl_code): # Apply DataPathInit return self.xcvr_eeprom.write("%s_%d" % (consts.STAGED_CTRL_APPLY_DPINIT_FIELD, 0), channel) + def set_module_si_settings(self, host_lanes_mask, appl, optics_si_dict): + # Read and cache the existing SCS0 TX CTRL data + si_settings = self.xcvr_eeprom.read(consts.STAGED_CTRL0_TX_CTRL_FIELD) + if si_settings is None: + return None + + # Replace the new values with cached SI values + for si_keys in optics_si_dict: + if si_keys in si_settings: + si_settings[si_keys] = optics_si_dict[si_keys] + + # Read and cache all the SI CTRL Advertisement + bit_0 = 0b00000001 + bit_1 = 0b00000010 + bit_2 = 0b00000100 + bit_3 = 0b00001000 + bit_4 = 0b00010000 + bit_5 = 0b00100000 + bit_6 = 0b01000000 + bit_7 = 0b10000000 + + # Module TX/RX Characteristic Advertisement Support Values + tx_input_eq_max_val = self.xcvr_eeprom.read(consts.TX_INPUT_EQ_MAX) + rx_output_amp_supported_val = self.xcvr_eeprom.read(consts.RX_OUTPUT_LEVEL_SUPPORT) + rx_output_eq_pre_max_val = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CURSOR_MAX) + rx_output_eq_post_max_val = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CURSOR_MAX) + + # TX/RX Control Advertisement Support + tx_si_ctrl_advt = self.xcvr_eeprom.read(consts.TX_SI_CTRL_ADVT) + rx_si_ctrl_advt = self.xcvr_eeprom.read(consts.RX_SI_CTRL_ADVT) + + tx_cdr_supported = tx_si_ctrl_advt & bit_0 + tx_input_eq_fixed_supported = (tx_si_ctrl_advt & bit_2) >> 2 + tx_input_adaptive_eq_supported = (tx_si_ctrl_advt & bit_3) >> 3 + tx_input_recall_buf1_supported = (tx_si_ctrl_advt & bit_5) >> 5 + tx_input_recall_buf2_supported = (tx_si_ctrl_advt & bit_6) >> 6 + + rx_cdr_supported = rx_si_ctrl_advt & bit_0 + rx_ouput_amp_ctrl_supported = (rx_si_ctrl_advt & bit_2) >> 2 + rx_output_eq_pre_ctrl_supported = (rx_si_ctrl_advt & bit_3) >> 3 + rx_output_eq_post_ctrl_supported = (rx_si_ctrl_advt & bit_4) >> 4 + + # Apply the SI settings if supported + for si_keys in si_settings: + if ((si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and rx_output_eq_pre_ctrl_supported) or + (si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and rx_output_eq_post_ctrl_supported) or + (si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and rx_ouput_amp_ctrl_supported) or + (si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and tx_input_eq_fixed_supported)): + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + lane = lane+1 + si_key_lane = "{}{}".format(si_keys, lane) + val = si_settings[si_keys][si_key_lane] + if ((si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and val <= rx_output_eq_pre_max_val) or + (si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and val <= rx_output_eq_post_max_val) or + (si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and val <= rx_output_amp_supported_val) or + (si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and val <= tx_input_eq_max_val)) : + if (lane%2) == 0: + pre_si_key_lane = "{}{}".format(si_keys, lane-1) + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + val = (val << 4) | pre_val + self.xcvr_eeprom.write(si_key_lane, val) + elif (si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and tx_input_recall_buf_supported): + val = 0 + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + si_key_lane = "{}{}".format(si_keys, lane+1) + si_val = si_settings[si_keys][si_key_lane] + lane %= (self.NUM_CHANNELS//2) + mask = ~(val << (lane*2)) + l_data = si_val << (lane*2) + val = (val & mask) | l_data + self.xcvr_eeprom.write(si_key_lane, val) + elif ((si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX and tx_input_adaptive_eq_supported) or + (si_keys == consts.CDR_ENABLE_TX and tx_cdr_supported) or + (si_keys == consts.CDR_ENABLE_RX and rx_cdr_supported)) : + val = 0 + # Read 1 byte data + for lane in range(self.NUM_CHANNELS): + si_key_lane = "{}{}".format(si_keys, lane+1) + data = self.xcvr_eeprom.read(si_key_lane) + val |= (data << lane) + # Write only applicable field + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + si_key_lane = "{}{}".format(si_keys, lane+1) + si_val = si_settings[si_keys][si_key_lane] + val &= ~(1 << lane) + val |= (si_val << lane) + self.xcvr_eeprom.write(si_key_lane, val) + + # Apply ApSel with EC = 1 + lane_first = -1 + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 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) + # set EC = 1 + data |= 0x1 + self.xcvr_eeprom.write(addr, data) + + # Apply DataPathInit + return self.xcvr_eeprom.write("%s_%d" % (consts.STAGED_CTRL_APPLY_DPINIT_FIELD, 0), host_lanes_mask) + def get_error_description(self): dp_state = self.get_datapath_state() conf_state = self.get_config_datapath_hostlane_status() From fe4f69ab81f4fba7e309201db272b080f0e66f39 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 5 Jul 2023 18:56:56 -0700 Subject: [PATCH 02/42] Update consts.py --- .../sonic_xcvr/fields/consts.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/sonic_platform_base/sonic_xcvr/fields/consts.py b/sonic_platform_base/sonic_xcvr/fields/consts.py index c638f19b6..6d8565758 100644 --- a/sonic_platform_base/sonic_xcvr/fields/consts.py +++ b/sonic_platform_base/sonic_xcvr/fields/consts.py @@ -299,6 +299,41 @@ STAGED_CTRL_APPLY_IMMEDIATE_FIELD = "Staged Control Set Apply Immediate" STAGED_CTRL_APSEL_FIELD = "Staged Control Set ApSel" +STAGED_CTRL0_TX_CTRL_FIELD = "Staged Control TX Control" + +TX_INPUT_EQ_MAX = "TXInputEqMax" +RX_OUTPUT_LEVEL_SUPPORT = "RX Output Level Supported" +RX_OUTPUT_LEVEL_0_SUPPORTED = "RXOutputLevel0Supported" +RX_OUTPUT_LEVEL_1_SUPPORTED = "RXOutputLevel1Supported" +RX_OUTPUT_LEVEL_2_SUPPORTED = "RXOutputLevel2Supported" +RX_OUTPUT_LEVEL_3_SUPPORTED = "RXOutputLevel3Supported" +RX_OUTPUT_EQ_PRE_CURSOR_MAX = "RXOutputEqPreCursorMax" +RX_OUTPUT_EQ_POST_CURSOR_MAX = "RXOutputEqPostCursorMax" + +SIGNAL_INTEGRITY_CTRL_ADVT_FIELD = "Signal Integrity Control Advertisement" +TX_SI_CTRL_ADVT = "TX SI Control Advertisement" +TX_CDR_SUPPORT_FIELD = "TXCDRSupported" +TX_CDR_BYPASS_CTRL_FIELD = "TXCDRBypassSupported" +TX_INPUT_EQ_FIXED_MANUAL_CTRL_SUPPORT_FIELD = "TXInputEqFixedManualSupported" +TX_INPUT_ADAPTIVE_EQ_SUPPORT_FIELD = "TXInputAdaptiveEqSupported" +TX_INPUT_EQ_FREEZE_SUPPORT_FIELD = "TXInputEqFreezeSupported" +TX_INPUT_EQ_RECALL_BUF_SUPPORT_FIELD = "TXInputEqRecallBufSupported" +RX_SI_CTRL_ADVT = "RX SI Control Advertisement" +RX_CDR_SUPPORT_FIELD = "RxCDRSupported" +RX_CDR_BYPASS_CTRL_FIELD = "RXCDRBypassSupported" +RX_OUTPUT_AMP_CTRL_SUPPORT_FIELD = "RXOutputAmpSupported" +RX_OUTPUT_EQ_CTRL_SUPPORT_FIELD = "RXOutputEQSupported" + +ACTIVE_CTRL_FIELD = "Active Control Set" +ADAPTIVE_INPUT_EQ_ENABLE_TX = "AdaptiveInputEqEnableTx" +ADAPTIVE_INPUT_EQ_RECALLED_TX = "AdaptiveInputEqRecalledTx" +FIXED_INPUT_EQ_TARGET_TX = "FixedInputEqTargetTx" +CDR_ENABLE_TX = "CDREnableTx" +CDR_ENABLE_RX = "CDREnableRx" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX = "OutputEqPreCursorTargetRx" +OUTPUT_EQ_POST_CURSOR_TARGET_RX = "OutputEqPostCursorTargetRx" +OUTPUT_AMPLITUDE_TARGET_RX = "OutputAmplitudeTargetRx" + # C-CMIS # Module configuration support fields From 94ac72ad54f2905cceb5566e5ffb488f5dae594b Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 5 Jul 2023 18:59:50 -0700 Subject: [PATCH 03/42] Update cmis.py --- .../sonic_xcvr/mem_maps/public/cmis.py | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) 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 512ed0776..b7c732407 100644 --- a/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py @@ -195,6 +195,21 @@ def __init__(self, codes): NumberRegField(consts.PAGE_SUPPORT_ADVT_FIELD, self.getaddr(0x1, 142), RegBitField(consts.VDM_SUPPORTED, 6), ), + NumberRegField(consts.TX_INPUT_EQ_MAX, self.getaddr(0x1, 153), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0 , 4)) + ), + NumberRegField(consts.RX_OUTPUT_LEVEL_SUPPORT, self.getaddr(0x1, 153), + RegBitField(consts.RX_OUTPUT_LEVEL_0_SUPPORTED, 4), + RegBitField(consts.RX_OUTPUT_LEVEL_1_SUPPORTED, 5), + RegBitField(consts.RX_OUTPUT_LEVEL_2_SUPPORTED, 6), + RegBitField(consts.RX_OUTPUT_LEVEL_3_SUPPORTED, 7), + ), + NumberRegField(consts.RX_OUTPUT_EQ_PRE_CURSOR_MAX, self.getaddr(0x1, 154), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (0 , 4)) + ), + NumberRegField(consts.RX_OUTPUT_EQ_POST_CURSOR_MAX, self.getaddr(0x1, 154), + *(RegBitField("Bit%d" % (bit), bit) for bit in range (4 , 8)) + ), NumberRegField(consts.CTRLS_ADVT_FIELD, self.getaddr(0x1, 155), RegBitField(consts.TX_DISABLE_SUPPORT_FIELD, 1), size=2, format=" Date: Fri, 7 Jul 2023 14:57:12 -0700 Subject: [PATCH 04/42] Fix build failures --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 6d99c0560..baf376a92 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2097,7 +2097,7 @@ def set_application(self, channel, appl_code): # Apply DataPathInit return self.xcvr_eeprom.write("%s_%d" % (consts.STAGED_CTRL_APPLY_DPINIT_FIELD, 0), channel) - def set_module_si_settings(self, host_lanes_mask, appl, optics_si_dict): + def set_module_si_settings(self, host_lanes_mask, appl_code, optics_si_dict): # Read and cache the existing SCS0 TX CTRL data si_settings = self.xcvr_eeprom.read(consts.STAGED_CTRL0_TX_CTRL_FIELD) if si_settings is None: @@ -2160,7 +2160,8 @@ def set_module_si_settings(self, host_lanes_mask, appl, optics_si_dict): pre_val = self.xcvr_eeprom.read(pre_si_key_lane) val = (val << 4) | pre_val self.xcvr_eeprom.write(si_key_lane, val) - elif (si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and tx_input_recall_buf_supported): + elif (si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and + (tx_input_recall_buf1_supported or tx_input_recall_buf2_supported)): val = 0 for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: From a0e6036c07f40eea2d96c989cdeb2e447bbf94a3 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 18 Jul 2023 01:00:13 -0700 Subject: [PATCH 05/42] Update test_cmis.py --- tests/sonic_xcvr/test_cmis.py | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index a3cb0b345..285d1d47b 100644 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -2215,6 +2215,55 @@ def test_set_application(self): self.api.set_application(0x7fffffff, 1) assert self.api.xcvr_eeprom.write.call_count == self.api.NUM_CHANNELS + 1 + def test_set_module_si_eq_pre_settings(self): + optics_si_eq_pre_dict = { "OutputEqPreCursorTargetRx":{ + "OutputEqPreCursorTargetRx1":3, "OutputEqPreCursorTargetRx2":3, "OutputEqPreCursorTargetRx3":3, "OutputEqPreCursorTargetRx4":3, + "OutputEqPreCursorTargetRx5":3, "OutputEqPreCursorTargetRx6":3, "OutputEqPreCursorTargetRx7":3, "OutputEqPreCursorTargetRx8":3 } + } + optics_si_dict = { "OutputEqPreCursorTargetRx":{ + "OutputEqPreCursorTargetRx1":2, "OutputEqPreCursorTargetRx2":2, "OutputEqPreCursorTargetRx3":2, "OutputEqPreCursorTargetRx4":2, + "OutputEqPreCursorTargetRx5":2, "OutputEqPreCursorTargetRx6":2, "OutputEqPreCursorTargetRx7":2, "OutputEqPreCursorTargetRx8":2 } + } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.write = MagicMock() + mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + self.api.xcvr_eeprom.read.side_effect = mock_resp + self.api.set_module_si_settings(0x01 , 1, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 1 + 1 + 1 + + def test_set_module_si_eq_en_settings(self): + optics_si_eq_en_dict = { "AdaptiveInputEqEnableTx":{ + "AdaptiveInputEqEnableTx1":0, "AdaptiveInputEqEnableTx2":0, "AdaptiveInputEqEnableTx3":0, "AdaptiveInputEqEnableTx4":0, + "AdaptiveInputEqEnableTx5":0, "AdaptiveInputEqEnableTx6":0, "AdaptiveInputEqEnableTx7":0, "AdaptiveInputEqEnableTx8":0 } + } + optics_si_dict = { "AdaptiveInputEqEnableTx":{ + "AdaptiveInputEqEnableTx1":1, "AdaptiveInputEqEnableTx2":1, "AdaptiveInputEqEnableTx3":1, "AdaptiveInputEqEnableTx4":1, + "AdaptiveInputEqEnableTx5":1, "AdaptiveInputEqEnableTx6":1, "AdaptiveInputEqEnableTx7":1, "AdaptiveInputEqEnableTx8":1 } + } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.write = MagicMock() + mock_resp = [optics_si_eq_en_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + self.api.xcvr_eeprom.read.side_effect = mock_resp + self.api.set_module_si_settings(0xff , 1, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 8 + 8 + 1 + + def test_set_module_si_eq_recall_settings(self): + optics_si_eq_recall_dict = { "AdaptiveInputEqRecalledTx":{ + "AdaptiveInputEqRecalledTx1":0, "AdaptiveInputEqRecalledTx2":0, "AdaptiveInputEqRecalledTx3":0, "AdaptiveInputEqRecalledTx4":0, + "AdaptiveInputEqRecalledTx5":0, "AdaptiveInputEqRecalledTx6":0, "AdaptiveInputEqRecalledTx7":0, "AdaptiveInputEqRecalledTx8":0 } + } + optics_si_dict = { "AdaptiveInputEqRecalledTx":{ + "AdaptiveInputEqRecalledTx1":1, "AdaptiveInputEqRecalledTx2":1, "AdaptiveInputEqRecalledTx3":1, "AdaptiveInputEqRecalledTx4":1, + "AdaptiveInputEqRecalledTx5":1, "AdaptiveInputEqRecalledTx6":1, "AdaptiveInputEqRecalledTx7":1, "AdaptiveInputEqRecalledTx8":1 } + } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.write = MagicMock() + mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + self.api.xcvr_eeprom.read.side_effect = mock_resp + self.api.set_module_si_settings(0x0f , 1, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 4 + 4 + 1 + def test_get_error_description(self): self.api.get_module_state = MagicMock() self.api.get_module_state.return_value = 'ModuleReady' From 7eb15648d2a4729144b0f346f4086a08af552e80 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 19 Jul 2023 02:03:02 -0700 Subject: [PATCH 06/42] Address review comments --- .../sonic_xcvr/api/public/cmis.py | 105 +++++++++++------- 1 file changed, 63 insertions(+), 42 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index baf376a92..e43f82128 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2097,7 +2097,51 @@ def set_application(self, channel, appl_code): # Apply DataPathInit return self.xcvr_eeprom.write("%s_%d" % (consts.STAGED_CTRL_APPLY_DPINIT_FIELD, 0), channel) + def get_tx_si_ctrl_advt_capability(self): + ''' + This function returns the module TX SI CTRL capability as advertised + ''' + if self.is_flat_memory(): + return None + + tx_si_ctrl_advt_res = self.xcvr_eeprom.read(consts.TX_SI_CTRL_ADVT) + if tx_si_ctrl_advt_res is None: + return None + + tx_si_ctrl_advt_capability = dict() + tx_si_ctrl_advt_capability['tx_input_recall_buf2_supported'] = bool((tx_si_ctrl_advt_res >> 6) & 0x1) + tx_si_ctrl_advt_capability['tx_input_recall_buf1_supported'] = bool((tx_si_ctrl_advt_res >> 5) & 0x1) + tx_si_ctrl_advt_capability['tx_input_adaptive_eq_supported'] = bool((tx_si_ctrl_advt_res >> 3) & 0x1) + tx_si_ctrl_advt_capability['tx_input_eq_fixed_supported'] = bool((tx_si_ctrl_advt_res >> 2) & 0x1) + tx_si_ctrl_advt_capability['tx_cdr_supported'] = bool((tx_si_ctrl_advt_res >> 0) & 0x1) + tx_si_ctrl_advt_capability['tx_input_eq_max_val'] = self.xcvr_eeprom.read(consts.TX_INPUT_EQ_MAX) + return tx_si_ctrl_advt_capability + + def get_rx_si_ctrl_advt_capability(self): + ''' + This function returns the module RX SI CTRL capability as advertised + ''' + if self.is_flat_memory(): + return None + + rx_si_ctrl_advt_res = self.xcvr_eeprom.read(consts.RX_SI_CTRL_ADVT) + if rx_si_ctrl_advt_res is None: + return None + + rx_si_ctrl_advt_capability = dict() + rx_si_ctrl_advt_capability['rx_output_eq_post_ctrl_supported'] = bool((rx_si_ctrl_advt_res >> 4) & 0x1) + rx_si_ctrl_advt_capability['rx_output_eq_pre_ctrl_supported'] = bool((rx_si_ctrl_advt_res >> 3) & 0x1) + rx_si_ctrl_advt_capability['rx_ouput_amp_ctrl_supported'] = bool((rx_si_ctrl_advt_res >> 2) & 0x1) + rx_si_ctrl_advt_capability['rx_cdr_supported'] = bool((rx_si_ctrl_advt_res >> 0) & 0x1) + rx_si_ctrl_advt_capability['rx_output_amp_supported_val'] = self.xcvr_eeprom.read(consts.RX_OUTPUT_LEVEL_SUPPORT) + rx_si_ctrl_advt_capability['rx_output_eq_pre_max_val'] = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CURSOR_MAX) + rx_si_ctrl_advt_capability['rx_output_eq_post_max_val'] = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CURSOR_MAX) + return rx_si_ctrl_advt_capability + def set_module_si_settings(self, host_lanes_mask, appl_code, optics_si_dict): + ''' + This function sets module SI settings after validating control advertisement flags and max values + ''' # Read and cache the existing SCS0 TX CTRL data si_settings = self.xcvr_eeprom.read(consts.STAGED_CTRL0_TX_CTRL_FIELD) if si_settings is None: @@ -2108,60 +2152,37 @@ def set_module_si_settings(self, host_lanes_mask, appl_code, optics_si_dict): if si_keys in si_settings: si_settings[si_keys] = optics_si_dict[si_keys] - # Read and cache all the SI CTRL Advertisement - bit_0 = 0b00000001 - bit_1 = 0b00000010 - bit_2 = 0b00000100 - bit_3 = 0b00001000 - bit_4 = 0b00010000 - bit_5 = 0b00100000 - bit_6 = 0b01000000 - bit_7 = 0b10000000 - - # Module TX/RX Characteristic Advertisement Support Values - tx_input_eq_max_val = self.xcvr_eeprom.read(consts.TX_INPUT_EQ_MAX) - rx_output_amp_supported_val = self.xcvr_eeprom.read(consts.RX_OUTPUT_LEVEL_SUPPORT) - rx_output_eq_pre_max_val = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CURSOR_MAX) - rx_output_eq_post_max_val = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CURSOR_MAX) - - # TX/RX Control Advertisement Support - tx_si_ctrl_advt = self.xcvr_eeprom.read(consts.TX_SI_CTRL_ADVT) - rx_si_ctrl_advt = self.xcvr_eeprom.read(consts.RX_SI_CTRL_ADVT) - - tx_cdr_supported = tx_si_ctrl_advt & bit_0 - tx_input_eq_fixed_supported = (tx_si_ctrl_advt & bit_2) >> 2 - tx_input_adaptive_eq_supported = (tx_si_ctrl_advt & bit_3) >> 3 - tx_input_recall_buf1_supported = (tx_si_ctrl_advt & bit_5) >> 5 - tx_input_recall_buf2_supported = (tx_si_ctrl_advt & bit_6) >> 6 - - rx_cdr_supported = rx_si_ctrl_advt & bit_0 - rx_ouput_amp_ctrl_supported = (rx_si_ctrl_advt & bit_2) >> 2 - rx_output_eq_pre_ctrl_supported = (rx_si_ctrl_advt & bit_3) >> 3 - rx_output_eq_post_ctrl_supported = (rx_si_ctrl_advt & bit_4) >> 4 + tx_si_ctrl_advt_capability = self.get_tx_si_ctrl_advt_capability() + if tx_si_ctrl_advt_capability is None: + return None + + rx_si_ctrl_advt_capability = self.get_rx_si_ctrl_advt_capability() + if rx_si_ctrl_advt_capability is None: + return None # Apply the SI settings if supported for si_keys in si_settings: - if ((si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and rx_output_eq_pre_ctrl_supported) or - (si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and rx_output_eq_post_ctrl_supported) or - (si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and rx_ouput_amp_ctrl_supported) or - (si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and tx_input_eq_fixed_supported)): + if ((si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and rx_si_ctrl_advt_capability['rx_output_eq_pre_ctrl_supported']) or + (si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and rx_si_ctrl_advt_capability['rx_output_eq_post_ctrl_supported']) or + (si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and rx_si_ctrl_advt_capability['rx_ouput_amp_ctrl_supported']) or + (si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and tx_si_ctrl_advt_capability['tx_input_eq_fixed_supported'])): for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: continue lane = lane+1 si_key_lane = "{}{}".format(si_keys, lane) val = si_settings[si_keys][si_key_lane] - if ((si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and val <= rx_output_eq_pre_max_val) or - (si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and val <= rx_output_eq_post_max_val) or - (si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and val <= rx_output_amp_supported_val) or - (si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and val <= tx_input_eq_max_val)) : + if ((si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and val <= rx_si_ctrl_advt_capability['rx_output_eq_pre_max_val']) or + (si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and val <= rx_si_ctrl_advt_capability['rx_output_eq_post_max_val']) or + (si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and val <= rx_si_ctrl_advt_capability['rx_output_amp_supported_val']) or + (si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and val <= tx_si_ctrl_advt_capability['tx_input_eq_max_val'])) : if (lane%2) == 0: pre_si_key_lane = "{}{}".format(si_keys, lane-1) pre_val = self.xcvr_eeprom.read(pre_si_key_lane) val = (val << 4) | pre_val self.xcvr_eeprom.write(si_key_lane, val) elif (si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and - (tx_input_recall_buf1_supported or tx_input_recall_buf2_supported)): + (tx_si_ctrl_advt_capability['tx_input_recall_buf1_supported'] or tx_si_ctrl_advt_capability['tx_input_recall_buf2_supported'])): val = 0 for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: @@ -2173,9 +2194,9 @@ def set_module_si_settings(self, host_lanes_mask, appl_code, optics_si_dict): l_data = si_val << (lane*2) val = (val & mask) | l_data self.xcvr_eeprom.write(si_key_lane, val) - elif ((si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX and tx_input_adaptive_eq_supported) or - (si_keys == consts.CDR_ENABLE_TX and tx_cdr_supported) or - (si_keys == consts.CDR_ENABLE_RX and rx_cdr_supported)) : + elif ((si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX and tx_si_ctrl_advt_capability['tx_input_adaptive_eq_supported']) or + (si_keys == consts.CDR_ENABLE_TX and tx_si_ctrl_advt_capability['tx_cdr_supported']) or + (si_keys == consts.CDR_ENABLE_RX and rx_si_ctrl_advt_capability['rx_cdr_supported'])) : val = 0 # Read 1 byte data for lane in range(self.NUM_CHANNELS): From b52254db2fc0eba956f4fccc9d03e5cdbafc0438 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 19 Jul 2023 02:04:37 -0700 Subject: [PATCH 07/42] Update cmis.py --- sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 b7c732407..b845d3c12 100644 --- a/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py @@ -483,8 +483,8 @@ def __init__(self, codes): RegBitField(consts.TX_INPUT_EQ_FIXED_MANUAL_CTRL_SUPPORT_FIELD, 2), RegBitField(consts.TX_INPUT_ADAPTIVE_EQ_SUPPORT_FIELD, 3), RegBitField(consts.TX_INPUT_EQ_FREEZE_SUPPORT_FIELD, 4), - RegBitField(consts.TX_INPUT_EQ_RECALL_BUF_SUPPORT_FIELD, 5), - RegBitField(consts.TX_INPUT_EQ_RECALL_BUF_SUPPORT_FIELD, 6), + RegBitField(consts.TX_INPUT_EQ_RECALL_BUF1_SUPPORT_FIELD, 5), + RegBitField(consts.TX_INPUT_EQ_RECALL_BUF2_SUPPORT_FIELD, 6), ), NumberRegField(consts.TX_INPUT_EQ_RECALL_BUF_SUPPORT_FIELD, self.getaddr(0x1, 161), *(RegBitField("Bit%d" % (bit), bit) for bit in range (5 , 7)) @@ -494,8 +494,8 @@ def __init__(self, codes): RegBitField(consts.RX_CDR_SUPPORT_FIELD, 0), RegBitField(consts.RX_CDR_BYPASS_CTRL_FIELD, 1), RegBitField(consts.RX_OUTPUT_AMP_CTRL_SUPPORT_FIELD, 2), - RegBitField(consts.RX_OUTPUT_EQ_CTRL_SUPPORT_FIELD, 3), - RegBitField(consts.RX_OUTPUT_EQ_CTRL_SUPPORT_FIELD, 4), + RegBitField(consts.RX_OUTPUT_EQ_PRE_CTRL_SUPPORT_FIELD, 3), + RegBitField(consts.RX_OUTPUT_EQ_POST_CTRL_SUPPORT_FIELD, 4), ), NumberRegField(consts.RX_OUTPUT_EQ_CTRL_SUPPORT_FIELD, self.getaddr(0x1, 162), *(RegBitField("Bit%d" % (bit), bit) for bit in range (3 , 5)) From deed9efce2e58406cd64a495de01f9a27307f1d2 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 19 Jul 2023 02:05:51 -0700 Subject: [PATCH 08/42] Update consts.py --- sonic_platform_base/sonic_xcvr/fields/consts.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sonic_platform_base/sonic_xcvr/fields/consts.py b/sonic_platform_base/sonic_xcvr/fields/consts.py index 6d8565758..dc8df6d32 100644 --- a/sonic_platform_base/sonic_xcvr/fields/consts.py +++ b/sonic_platform_base/sonic_xcvr/fields/consts.py @@ -317,11 +317,15 @@ TX_INPUT_EQ_FIXED_MANUAL_CTRL_SUPPORT_FIELD = "TXInputEqFixedManualSupported" TX_INPUT_ADAPTIVE_EQ_SUPPORT_FIELD = "TXInputAdaptiveEqSupported" TX_INPUT_EQ_FREEZE_SUPPORT_FIELD = "TXInputEqFreezeSupported" +TX_INPUT_EQ_RECALL_BUF1_SUPPORT_FIELD = "TXInputEqRecallBuf1Supported" +TX_INPUT_EQ_RECALL_BUF2_SUPPORT_FIELD = "TXInputEqRecallBuf2Supported" TX_INPUT_EQ_RECALL_BUF_SUPPORT_FIELD = "TXInputEqRecallBufSupported" RX_SI_CTRL_ADVT = "RX SI Control Advertisement" RX_CDR_SUPPORT_FIELD = "RxCDRSupported" RX_CDR_BYPASS_CTRL_FIELD = "RXCDRBypassSupported" RX_OUTPUT_AMP_CTRL_SUPPORT_FIELD = "RXOutputAmpSupported" +RX_OUTPUT_EQ_PRE_CTRL_SUPPORT_FIELD = "RXOutputEQPreSupported" +RX_OUTPUT_EQ_POST_CTRL_SUPPORT_FIELD = "RXOutputEQPostSupported" RX_OUTPUT_EQ_CTRL_SUPPORT_FIELD = "RXOutputEQSupported" ACTIVE_CTRL_FIELD = "Active Control Set" From 3a0204f7c444154097e7d9e43c36661d86160c9a Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 04:45:12 -0700 Subject: [PATCH 09/42] Create new APIs --- .../sonic_xcvr/api/public/cmis.py | 322 ++++++++++++------ 1 file changed, 213 insertions(+), 109 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index e43f82128..e905f4720 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2069,7 +2069,7 @@ def get_application(self, lane): return (appl & 0xf) - def set_application(self, channel, appl_code): + def set_application(self, channel, appl_code, ec): """ Update the selected application code to the specified lanes on the host side @@ -2092,56 +2092,229 @@ def set_application(self, channel, appl_code): lane_first = lane addr = "{}_{}_{}".format(consts.STAGED_CTRL_APSEL_FIELD, 0, lane + 1) data = (appl_code << 4) | (lane_first << 1) + #set EC bit + data|= ec self.xcvr_eeprom.write(addr, data) - # Apply DataPathInit + def stage_datapath_init(self, channel): + ''' + This function applies DataPathInit + ''' return self.xcvr_eeprom.write("%s_%d" % (consts.STAGED_CTRL_APPLY_DPINIT_FIELD, 0), channel) - def get_tx_si_ctrl_advt_capability(self): + def get_rx_output_amp_supported_val(self): ''' - This function returns the module TX SI CTRL capability as advertised + This function returns the supported RX output amp val ''' - if self.is_flat_memory(): - return None + return self.xcvr_eeprom.read(consts.RX_OUTPUT_LEVEL_SUPPORT) - tx_si_ctrl_advt_res = self.xcvr_eeprom.read(consts.TX_SI_CTRL_ADVT) - if tx_si_ctrl_advt_res is None: - return None + def get_rx_output_eq_pre_max_val(self): + ''' + This function returns the supported RX output eq pre cursor val + ''' + return self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CURSOR_MAX) - tx_si_ctrl_advt_capability = dict() - tx_si_ctrl_advt_capability['tx_input_recall_buf2_supported'] = bool((tx_si_ctrl_advt_res >> 6) & 0x1) - tx_si_ctrl_advt_capability['tx_input_recall_buf1_supported'] = bool((tx_si_ctrl_advt_res >> 5) & 0x1) - tx_si_ctrl_advt_capability['tx_input_adaptive_eq_supported'] = bool((tx_si_ctrl_advt_res >> 3) & 0x1) - tx_si_ctrl_advt_capability['tx_input_eq_fixed_supported'] = bool((tx_si_ctrl_advt_res >> 2) & 0x1) - tx_si_ctrl_advt_capability['tx_cdr_supported'] = bool((tx_si_ctrl_advt_res >> 0) & 0x1) - tx_si_ctrl_advt_capability['tx_input_eq_max_val'] = self.xcvr_eeprom.read(consts.TX_INPUT_EQ_MAX) - return tx_si_ctrl_advt_capability + def get_rx_output_eq_post_max_val(self): + ''' + This function returns the supported RX output eq post sursor val + ''' + return self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CURSOR_MAX) - def get_rx_si_ctrl_advt_capability(self): + def get_tx_input_eq_max_val(self): ''' - This function returns the module RX SI CTRL capability as advertised + This function returns the supported TX input eq val ''' - if self.is_flat_memory(): - return None + return self.xcvr_eeprom.read(consts.TX_INPUT_EQ_MAX) - rx_si_ctrl_advt_res = self.xcvr_eeprom.read(consts.RX_SI_CTRL_ADVT) - if rx_si_ctrl_advt_res is None: - return None + def get_tx_cdr_supported(self): + ''' + This function returns the supported TX CDR field + ''' + return self.xcvr_eeprom.read(consts.TX_CDR_SUPPORT_FIELD) + + def get_rx_cdr_supported(self): + ''' + This function returns the supported RX CDR field + ''' + return self.xcvr_eeprom.read(consts.RX_CDR_SUPPORT_FIELD) + + def get_tx_input_eq_fixed_supported(self): + ''' + This function returns the supported TX input eq field + ''' + return self.xcvr_eeprom.read(consts.TX_INPUT_EQ_FIXED_MANUAL_CTRL_SUPPORT_FIELD) + + def get_tx_input_adaptive_eq_supported(self): + ''' + This function returns the supported TX input adaptive eq field + ''' + return self.xcvr_eeprom.read(consts.TX_INPUT_ADAPTIVE_EQ_SUPPORT_FIELD) + + def get_tx_input_recall_buf1_supported(self): + ''' + This function returns the supported TX input recall buf1 field + ''' + return self.xcvr_eeprom.read(consts.TX_INPUT_EQ_RECALL_BUF1_SUPPORT_FIELD) + + def get_tx_input_recall_buf2_supported(self): + ''' + This function returns the supported TX input recall buf2 field + ''' + return self.xcvr_eeprom.read(consts.TX_INPUT_EQ_RECALL_BUF2_SUPPORT_FIELD) + + def get_rx_ouput_amp_ctrl_supported(self): + ''' + This function returns the supported RX output amp control field + ''' + return self.xcvr_eeprom.read(consts.RX_OUTPUT_AMP_CTRL_SUPPORT_FIELD) + + def get_rx_output_eq_pre_ctrl_supported(self): + ''' + This function returns the supported RX output eq pre control field + ''' + return self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CTRL_SUPPORT_FIELD) + + def get_rx_output_eq_post_ctrl_supported(self): + ''' + This function returns the supported RX output eq post control field + ''' + return self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CTRL_SUPPORT_FIELD) + + def nibble_read_modify_write(self, val, si_param, lane): + if (lane%2) == 0: + pre_si_key_lane = "{}{}".format(si_param, lane-1) + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + val = (val << 4) | pre_val + si_key_lane = "{}{}".format(si_param, lane) + self.xcvr_eeprom.write(si_key_lane, val) - rx_si_ctrl_advt_capability = dict() - rx_si_ctrl_advt_capability['rx_output_eq_post_ctrl_supported'] = bool((rx_si_ctrl_advt_res >> 4) & 0x1) - rx_si_ctrl_advt_capability['rx_output_eq_pre_ctrl_supported'] = bool((rx_si_ctrl_advt_res >> 3) & 0x1) - rx_si_ctrl_advt_capability['rx_ouput_amp_ctrl_supported'] = bool((rx_si_ctrl_advt_res >> 2) & 0x1) - rx_si_ctrl_advt_capability['rx_cdr_supported'] = bool((rx_si_ctrl_advt_res >> 0) & 0x1) - rx_si_ctrl_advt_capability['rx_output_amp_supported_val'] = self.xcvr_eeprom.read(consts.RX_OUTPUT_LEVEL_SUPPORT) - rx_si_ctrl_advt_capability['rx_output_eq_pre_max_val'] = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CURSOR_MAX) - rx_si_ctrl_advt_capability['rx_output_eq_post_max_val'] = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CURSOR_MAX) - return rx_si_ctrl_advt_capability + def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): + ''' + This function applies RX output eq pre cursor settings + ''' + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + lane = lane+1 + si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) + val = si_settings[consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX][si_key_lane] + if val <= get_rx_output_eq_pre_max_val(): + self.nibble_read_modify_write(val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) - def set_module_si_settings(self, host_lanes_mask, appl_code, optics_si_dict): + def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): ''' - This function sets module SI settings after validating control advertisement flags and max values + This function applies RX output eq pre cursor settings ''' + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + lane = lane+1 + si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) + val = si_settings[consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX][si_key_lane] + if val <= get_rx_output_eq_post_max_val(): + self.nibble_read_modify_write(val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) + + def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): + ''' + This function applies RX output amp settings + ''' + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + lane = lane+1 + si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) + val = si_settings[consts.OUTPUT_AMPLITUDE_TARGET_RX][si_key_lane] + if val <= get_rx_output_eq_post_max_val(): + self.nibble_read_modify_write(val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) + + def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): + ''' + This function applies fixed TX input si settings + ''' + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + lane = lane+1 + si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane) + val = si_settings[consts.FIXED_INPUT_EQ_TARGET_TX][si_key_lane] + if val <= get_rx_output_eq_post_max_val(): + self.nibble_read_modify_write(val, consts.FIXED_INPUT_EQ_TARGET_TX, lane) + + def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): + ''' + This function applies adaptive TX input recall si settings + ''' + val = 0 + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + si_key_lane = "{}{}".format(si_keys, lane+1) + si_val = si_settings[si_keys][si_key_lane] + lane %= (self.NUM_CHANNELS//2) + mask = ~(val << (lane*2)) + l_data = si_val << (lane*2) + val = (val & mask) | l_data + self.xcvr_eeprom.write(si_key_lane, val) + + def byte_read_modify_write(self, si_keys, host_lanes_mask, si_settings): + val = 0 + # Read 1 byte data + for lane in range(self.NUM_CHANNELS): + si_key_lane = "{}{}".format(si_keys, lane+1) + data = self.xcvr_eeprom.read(si_key_lane) + val |= (data << lane) + # Write only applicable field + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + si_key_lane = "{}{}".format(si_keys, lane+1) + si_val = si_settings[si_keys][si_key_lane] + val &= ~(1 << lane) + val |= (si_val << lane) + self.xcvr_eeprom.write(si_key_lane, val) + + def stage_adaptive_input_eq_enable_tx(self, host_lanes_mask, si_settings): + ''' + This function applies adaptive TX input enable si settings + ''' + self.byte_read_modify_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_settings) + + def stage_cdr_tx(self, host_lanes_mask, si_settings): + ''' + This function applies TX CDR si settings + ''' + self.byte_read_modify_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_settings) + + def stage_cdr_rx(self, host_lanes_mask, si_settings): + ''' + This function applies RX CDR si settings + ''' + self.byte_read_modify_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_settings) + + def stage_rx_si_settings(self, host_lanes_mask, si_settings): + for si_keys in si_settings: + if si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and self.get_rx_output_eq_pre_ctrl_supported(): + self.stage_output_eq_pre_cursor_target_rx(host_lanes_mask, si_settings) + elif si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and self.get_rx_output_eq_post_ctrl_supported(): + self.stage_output_eq_post_cursor_target_rx(host_lanes_mask, si_settings) + elif si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and self.get_rx_ouput_amp_ctrl_supported(): + self.stage_output_amp_target_rx(host_lanes_mask, si_settings) + elif si_keys == consts.CDR_ENABLE_RX and self.get_rx_cdr_supported(): + self.stage_cdr_tx(host_lanes_mask, si_settings) + + def stage_tx_si_settings(self, host_lanes_mask, si_settings): + for si_keys in si_settings: + if si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and self.get_tx_input_eq_fixed_supported(): + self.stage_fixed_input_target_tx(host_lanes_mask, si_settings) + elif si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and + (self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported()): + self.stage_adaptive_input_recall_tx(host_lanes_mask, si_settings) + elif si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX and self.get_tx_input_adaptive_eq_supported(): + self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings) + elif si_keys == consts.CDR_ENABLE_TX and self.get_tx_cdr_supported(): + self.stage_cdr_rx(host_lanes_mask, si_settings) + + def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): # Read and cache the existing SCS0 TX CTRL data si_settings = self.xcvr_eeprom.read(consts.STAGED_CTRL0_TX_CTRL_FIELD) if si_settings is None: @@ -2152,82 +2325,13 @@ def set_module_si_settings(self, host_lanes_mask, appl_code, optics_si_dict): if si_keys in si_settings: si_settings[si_keys] = optics_si_dict[si_keys] - tx_si_ctrl_advt_capability = self.get_tx_si_ctrl_advt_capability() - if tx_si_ctrl_advt_capability is None: - return None + # stage RX si settings + self.stage_rx_si_settings(host_lanes_mask, si_settings) - rx_si_ctrl_advt_capability = self.get_rx_si_ctrl_advt_capability() - if rx_si_ctrl_advt_capability is None: - return None + #stage TX si settings + self.stage_tx_si_settings(host_lanes_mask, si_settings) - # Apply the SI settings if supported - for si_keys in si_settings: - if ((si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and rx_si_ctrl_advt_capability['rx_output_eq_pre_ctrl_supported']) or - (si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and rx_si_ctrl_advt_capability['rx_output_eq_post_ctrl_supported']) or - (si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and rx_si_ctrl_advt_capability['rx_ouput_amp_ctrl_supported']) or - (si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and tx_si_ctrl_advt_capability['tx_input_eq_fixed_supported'])): - for lane in range(self.NUM_CHANNELS): - if ((1 << lane) & host_lanes_mask) == 0: - continue - lane = lane+1 - si_key_lane = "{}{}".format(si_keys, lane) - val = si_settings[si_keys][si_key_lane] - if ((si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and val <= rx_si_ctrl_advt_capability['rx_output_eq_pre_max_val']) or - (si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and val <= rx_si_ctrl_advt_capability['rx_output_eq_post_max_val']) or - (si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and val <= rx_si_ctrl_advt_capability['rx_output_amp_supported_val']) or - (si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and val <= tx_si_ctrl_advt_capability['tx_input_eq_max_val'])) : - if (lane%2) == 0: - pre_si_key_lane = "{}{}".format(si_keys, lane-1) - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) - val = (val << 4) | pre_val - self.xcvr_eeprom.write(si_key_lane, val) - elif (si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and - (tx_si_ctrl_advt_capability['tx_input_recall_buf1_supported'] or tx_si_ctrl_advt_capability['tx_input_recall_buf2_supported'])): - val = 0 - for lane in range(self.NUM_CHANNELS): - if ((1 << lane) & host_lanes_mask) == 0: - continue - si_key_lane = "{}{}".format(si_keys, lane+1) - si_val = si_settings[si_keys][si_key_lane] - lane %= (self.NUM_CHANNELS//2) - mask = ~(val << (lane*2)) - l_data = si_val << (lane*2) - val = (val & mask) | l_data - self.xcvr_eeprom.write(si_key_lane, val) - elif ((si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX and tx_si_ctrl_advt_capability['tx_input_adaptive_eq_supported']) or - (si_keys == consts.CDR_ENABLE_TX and tx_si_ctrl_advt_capability['tx_cdr_supported']) or - (si_keys == consts.CDR_ENABLE_RX and rx_si_ctrl_advt_capability['rx_cdr_supported'])) : - val = 0 - # Read 1 byte data - for lane in range(self.NUM_CHANNELS): - si_key_lane = "{}{}".format(si_keys, lane+1) - data = self.xcvr_eeprom.read(si_key_lane) - val |= (data << lane) - # Write only applicable field - for lane in range(self.NUM_CHANNELS): - if ((1 << lane) & host_lanes_mask) == 0: - continue - si_key_lane = "{}{}".format(si_keys, lane+1) - si_val = si_settings[si_keys][si_key_lane] - val &= ~(1 << lane) - val |= (si_val << lane) - self.xcvr_eeprom.write(si_key_lane, val) - - # Apply ApSel with EC = 1 - lane_first = -1 - for lane in range(self.NUM_CHANNELS): - if ((1 << lane) & host_lanes_mask) == 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) - # set EC = 1 - data |= 0x1 - self.xcvr_eeprom.write(addr, data) - - # Apply DataPathInit - return self.xcvr_eeprom.write("%s_%d" % (consts.STAGED_CTRL_APPLY_DPINIT_FIELD, 0), host_lanes_mask) + return True def get_error_description(self): dp_state = self.get_datapath_state() From d4e628d2c4c0aed1adc78e9a5da5c020417bcb6d Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 04:47:43 -0700 Subject: [PATCH 10/42] Add get_manufacturer API --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index e905f4720..ba47edc10 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -31,6 +31,12 @@ def __init__(self, xcvr_eeprom): self.vdm = CmisVdmApi(xcvr_eeprom) if not self.is_flat_memory() else None self.cdb = CmisCdbApi(xcvr_eeprom) if not self.is_flat_memory() else None + def get_manufacturer(self): + ''' + This function returns the manufacturer of the module + ''' + return self.xcvr_eeprom.read(consts.VENDOR_NAME_FIELD) + def get_model(self): ''' This function returns the part number of the module From 64e5b9097ca141dcb60249942a6289fd5411ee54 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 10:14:16 -0700 Subject: [PATCH 11/42] Update cmis.py --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index ba47edc10..a38128fd3 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2312,8 +2312,8 @@ def stage_tx_si_settings(self, host_lanes_mask, si_settings): for si_keys in si_settings: if si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and self.get_tx_input_eq_fixed_supported(): self.stage_fixed_input_target_tx(host_lanes_mask, si_settings) - elif si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and - (self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported()): + elif (si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and + (self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported())): self.stage_adaptive_input_recall_tx(host_lanes_mask, si_settings) elif si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX and self.get_tx_input_adaptive_eq_supported(): self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings) From 97fbabe3785f449b0edd38de0d081dd95a3d82c1 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 16:44:28 -0700 Subject: [PATCH 12/42] Update cmis.py --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index a38128fd3..0ccfb64ff 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2254,8 +2254,8 @@ def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: continue - si_key_lane = "{}{}".format(si_keys, lane+1) - si_val = si_settings[si_keys][si_key_lane] + si_key_lane = "{}{}".format(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, lane+1) + si_val = si_settings[consts.ADAPTIVE_INPUT_EQ_ENABLE_TX][si_key_lane] lane %= (self.NUM_CHANNELS//2) mask = ~(val << (lane*2)) l_data = si_val << (lane*2) From e7fe3c438ef0096b6c069e19ac4c3e902373da9c Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 17:23:16 -0700 Subject: [PATCH 13/42] Update cmis.py --- .../sonic_xcvr/api/public/cmis.py | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 0ccfb64ff..a5740310e 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2122,7 +2122,7 @@ def get_rx_output_eq_pre_max_val(self): def get_rx_output_eq_post_max_val(self): ''' - This function returns the supported RX output eq post sursor val + This function returns the supported RX output eq post cursor val ''' return self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CURSOR_MAX) @@ -2204,7 +2204,7 @@ def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) val = si_settings[consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX][si_key_lane] - if val <= get_rx_output_eq_pre_max_val(): + if val <= self.get_rx_output_eq_pre_max_val(): self.nibble_read_modify_write(val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): @@ -2217,7 +2217,7 @@ def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) val = si_settings[consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX][si_key_lane] - if val <= get_rx_output_eq_post_max_val(): + if val <= self.get_rx_output_eq_post_max_val(): self.nibble_read_modify_write(val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): @@ -2230,7 +2230,7 @@ def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) val = si_settings[consts.OUTPUT_AMPLITUDE_TARGET_RX][si_key_lane] - if val <= get_rx_output_eq_post_max_val(): + if val <= self.get_rx_output_amp_supported_val(): self.nibble_read_modify_write(val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): @@ -2243,7 +2243,7 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): lane = lane+1 si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane) val = si_settings[consts.FIXED_INPUT_EQ_TARGET_TX][si_key_lane] - if val <= get_rx_output_eq_post_max_val(): + if val <= self.get_tx_input_eq_max_val(): self.nibble_read_modify_write(val, consts.FIXED_INPUT_EQ_TARGET_TX, lane) def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): @@ -2254,8 +2254,8 @@ def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: continue - si_key_lane = "{}{}".format(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, lane+1) - si_val = si_settings[consts.ADAPTIVE_INPUT_EQ_ENABLE_TX][si_key_lane] + si_key_lane = "{}{}".format(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX, lane+1) + si_val = si_settings[consts.ADAPTIVE_INPUT_EQ_RECALLED_TX][si_key_lane] lane %= (self.NUM_CHANNELS//2) mask = ~(val << (lane*2)) l_data = si_val << (lane*2) @@ -2307,6 +2307,7 @@ def stage_rx_si_settings(self, host_lanes_mask, si_settings): self.stage_output_amp_target_rx(host_lanes_mask, si_settings) elif si_keys == consts.CDR_ENABLE_RX and self.get_rx_cdr_supported(): self.stage_cdr_tx(host_lanes_mask, si_settings) + return True def stage_tx_si_settings(self, host_lanes_mask, si_settings): for si_keys in si_settings: @@ -2319,12 +2320,13 @@ def stage_tx_si_settings(self, host_lanes_mask, si_settings): self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings) elif si_keys == consts.CDR_ENABLE_TX and self.get_tx_cdr_supported(): self.stage_cdr_rx(host_lanes_mask, si_settings) + return True def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): # Read and cache the existing SCS0 TX CTRL data si_settings = self.xcvr_eeprom.read(consts.STAGED_CTRL0_TX_CTRL_FIELD) if si_settings is None: - return None + return False # Replace the new values with cached SI values for si_keys in optics_si_dict: @@ -2332,10 +2334,12 @@ def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): si_settings[si_keys] = optics_si_dict[si_keys] # stage RX si settings - self.stage_rx_si_settings(host_lanes_mask, si_settings) + if not self.stage_rx_si_settings(host_lanes_mask, si_settings): + return False #stage TX si settings - self.stage_tx_si_settings(host_lanes_mask, si_settings) + if not self.stage_tx_si_settings(host_lanes_mask, si_settings) + return False return True From 858fbb00b0be560d91ed3b8d1a7b88f11aae2b1c Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 17:23:41 -0700 Subject: [PATCH 14/42] Apply suggestions from code review Co-authored-by: Prince George <45705344+prgeor@users.noreply.github.com> --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index a5740310e..2ad93c1f0 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2075,7 +2075,7 @@ def get_application(self, lane): return (appl & 0xf) - def set_application(self, channel, appl_code, ec): + def set_application(self, channel, appl_code, ec=0): """ Update the selected application code to the specified lanes on the host side From 36b5ad7264bf2e2de0347a5205ff760f94d318e3 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 18:10:26 -0700 Subject: [PATCH 15/42] Update cmis.py --- .../sonic_xcvr/api/public/cmis.py | 56 +++++++++++++------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 2ad93c1f0..c64fb5728 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2192,7 +2192,7 @@ def nibble_read_modify_write(self, val, si_param, lane): pre_val = self.xcvr_eeprom.read(pre_si_key_lane) val = (val << 4) | pre_val si_key_lane = "{}{}".format(si_param, lane) - self.xcvr_eeprom.write(si_key_lane, val) + return self.xcvr_eeprom.write(si_key_lane, val) def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): ''' @@ -2205,7 +2205,9 @@ def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) val = si_settings[consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX][si_key_lane] if val <= self.get_rx_output_eq_pre_max_val(): - self.nibble_read_modify_write(val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) + if not self.nibble_read_modify_write(val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane): + return False + return True def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): ''' @@ -2218,7 +2220,9 @@ def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) val = si_settings[consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX][si_key_lane] if val <= self.get_rx_output_eq_post_max_val(): - self.nibble_read_modify_write(val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) + if not self.nibble_read_modify_write(val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane): + return False + return True def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): ''' @@ -2231,7 +2235,9 @@ def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) val = si_settings[consts.OUTPUT_AMPLITUDE_TARGET_RX][si_key_lane] if val <= self.get_rx_output_amp_supported_val(): - self.nibble_read_modify_write(val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) + if not self.nibble_read_modify_write(val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane): + return False + return True def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): ''' @@ -2244,7 +2250,9 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane) val = si_settings[consts.FIXED_INPUT_EQ_TARGET_TX][si_key_lane] if val <= self.get_tx_input_eq_max_val(): - self.nibble_read_modify_write(val, consts.FIXED_INPUT_EQ_TARGET_TX, lane) + if not self.nibble_read_modify_write(val, consts.FIXED_INPUT_EQ_TARGET_TX, lane): + return False + return True def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): ''' @@ -2260,7 +2268,9 @@ def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): mask = ~(val << (lane*2)) l_data = si_val << (lane*2) val = (val & mask) | l_data - self.xcvr_eeprom.write(si_key_lane, val) + if not self.xcvr_eeprom.write(si_key_lane, val): + return False + return True def byte_read_modify_write(self, si_keys, host_lanes_mask, si_settings): val = 0 @@ -2277,49 +2287,59 @@ def byte_read_modify_write(self, si_keys, host_lanes_mask, si_settings): si_val = si_settings[si_keys][si_key_lane] val &= ~(1 << lane) val |= (si_val << lane) - self.xcvr_eeprom.write(si_key_lane, val) + if not self.xcvr_eeprom.write(si_key_lane, val): + return False + return True def stage_adaptive_input_eq_enable_tx(self, host_lanes_mask, si_settings): ''' This function applies adaptive TX input enable si settings ''' - self.byte_read_modify_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_settings) + return self.byte_read_modify_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_settings) def stage_cdr_tx(self, host_lanes_mask, si_settings): ''' This function applies TX CDR si settings ''' - self.byte_read_modify_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_settings) + return self.byte_read_modify_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_settings) def stage_cdr_rx(self, host_lanes_mask, si_settings): ''' This function applies RX CDR si settings ''' - self.byte_read_modify_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_settings) + return self.byte_read_modify_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_settings) def stage_rx_si_settings(self, host_lanes_mask, si_settings): for si_keys in si_settings: if si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and self.get_rx_output_eq_pre_ctrl_supported(): - self.stage_output_eq_pre_cursor_target_rx(host_lanes_mask, si_settings) + if not self.stage_output_eq_pre_cursor_target_rx(host_lanes_mask, si_settings): + return False elif si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and self.get_rx_output_eq_post_ctrl_supported(): - self.stage_output_eq_post_cursor_target_rx(host_lanes_mask, si_settings) + if not self.stage_output_eq_post_cursor_target_rx(host_lanes_mask, si_settings): + return False elif si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and self.get_rx_ouput_amp_ctrl_supported(): - self.stage_output_amp_target_rx(host_lanes_mask, si_settings) + if not self.stage_output_amp_target_rx(host_lanes_mask, si_settings): + return False elif si_keys == consts.CDR_ENABLE_RX and self.get_rx_cdr_supported(): - self.stage_cdr_tx(host_lanes_mask, si_settings) + if not self.stage_cdr_tx(host_lanes_mask, si_settings): + return False return True def stage_tx_si_settings(self, host_lanes_mask, si_settings): for si_keys in si_settings: if si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and self.get_tx_input_eq_fixed_supported(): - self.stage_fixed_input_target_tx(host_lanes_mask, si_settings) + if not self.stage_fixed_input_target_tx(host_lanes_mask, si_settings): + return False elif (si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and (self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported())): - self.stage_adaptive_input_recall_tx(host_lanes_mask, si_settings) + if not self.stage_adaptive_input_recall_tx(host_lanes_mask, si_settings): + return False elif si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX and self.get_tx_input_adaptive_eq_supported(): - self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings) + if not self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings): + return False elif si_keys == consts.CDR_ENABLE_TX and self.get_tx_cdr_supported(): - self.stage_cdr_rx(host_lanes_mask, si_settings) + if not self.stage_cdr_rx(host_lanes_mask, si_settings): + return False return True def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): From 321d58900393400d63ec8d37ac7b1084853dfccd Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 18:17:57 -0700 Subject: [PATCH 16/42] Update cmis.py --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index c64fb5728..42a75e915 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2340,7 +2340,7 @@ def stage_tx_si_settings(self, host_lanes_mask, si_settings): elif si_keys == consts.CDR_ENABLE_TX and self.get_tx_cdr_supported(): if not self.stage_cdr_rx(host_lanes_mask, si_settings): return False - return True + return True def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): # Read and cache the existing SCS0 TX CTRL data From ecb723b221fff252a918d821dd606a8fc8a1d5e8 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 18:24:27 -0700 Subject: [PATCH 17/42] Update cmis.py --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 42a75e915..68ce9476c 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2358,7 +2358,7 @@ def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): return False #stage TX si settings - if not self.stage_tx_si_settings(host_lanes_mask, si_settings) + if not self.stage_tx_si_settings(host_lanes_mask, si_settings): return False return True From ea1c1586f1895c5281b2cb9d0a5a11a0fb1c8f98 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 19:20:37 -0700 Subject: [PATCH 18/42] Fix failures identified with mock test --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 68ce9476c..dd1195e7c 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2321,7 +2321,7 @@ def stage_rx_si_settings(self, host_lanes_mask, si_settings): if not self.stage_output_amp_target_rx(host_lanes_mask, si_settings): return False elif si_keys == consts.CDR_ENABLE_RX and self.get_rx_cdr_supported(): - if not self.stage_cdr_tx(host_lanes_mask, si_settings): + if not self.stage_cdr_rx(host_lanes_mask, si_settings): return False return True @@ -2338,7 +2338,7 @@ def stage_tx_si_settings(self, host_lanes_mask, si_settings): if not self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings): return False elif si_keys == consts.CDR_ENABLE_TX and self.get_tx_cdr_supported(): - if not self.stage_cdr_rx(host_lanes_mask, si_settings): + if not self.stage_cdr_tx(host_lanes_mask, si_settings): return False return True From 6a35e0fba90039de91079dc0be3f34e437dc647f Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Tue, 25 Jul 2023 19:43:44 -0700 Subject: [PATCH 19/42] Update test_cmis.py --- tests/sonic_xcvr/test_cmis.py | 124 ++++++++++++++++++++++++++++------ 1 file changed, 104 insertions(+), 20 deletions(-) diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index 285d1d47b..69f0bd591 100644 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -2196,24 +2196,24 @@ 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.set_application(0x00, 1, 0) + assert self.api.xcvr_eeprom.write.call_count == 0 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.set_application(0x01, 1, 1) + assert self.api.xcvr_eeprom.write.call_count == 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.set_application(0x0f, 1, 1) + assert self.api.xcvr_eeprom.write.call_count == 4 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.set_application(0xff, 1, 1) + assert self.api.xcvr_eeprom.write.call_count == 8 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 + self.api.set_application(0x7fffffff, 1, 1) + assert self.api.xcvr_eeprom.write.call_count == self.api.NUM_CHANNELS def test_set_module_si_eq_pre_settings(self): optics_si_eq_pre_dict = { "OutputEqPreCursorTargetRx":{ @@ -2226,10 +2226,10 @@ def test_set_module_si_eq_pre_settings(self): } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff] self.api.xcvr_eeprom.read.side_effect = mock_resp - self.api.set_module_si_settings(0x01 , 1, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 1 + 1 + 1 + self.api.stage_custom_si_settings(0x01, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 1 def test_set_module_si_eq_en_settings(self): optics_si_eq_en_dict = { "AdaptiveInputEqEnableTx":{ @@ -2242,11 +2242,11 @@ def test_set_module_si_eq_en_settings(self): } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_en_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + mock_resp = [optics_si_eq_en_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] self.api.xcvr_eeprom.read.side_effect = mock_resp - self.api.set_module_si_settings(0xff , 1, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 8 + 8 + 1 + self.api.stage_custom_si_settings(0xff, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 8 def test_set_module_si_eq_recall_settings(self): optics_si_eq_recall_dict = { "AdaptiveInputEqRecalledTx":{ @@ -2259,10 +2259,94 @@ def test_set_module_si_eq_recall_settings(self): } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff] + self.api.xcvr_eeprom.read.side_effect = mock_resp + self.api.stage_custom_si_settings(0x0f, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 4 + + def test_set_module_si_eq_post_settings(self): + optics_si_eq_pre_dict = { "OutputEqPostCursorTargetRx":{ + "OutputEqPostCursorTargetRx1":3, "OutputEqPostCursorTargetRx2":3, "OutputEqPostCursorTargetRx3":3, "OutputEqPostCursorTargetRx4":3, + "OutputEqPosteCursorTargetRx5":3, "OutputEqPostCursorTargetRx6":3, "OutputEqPostCursorTargetRx7":3, "OutputEqPostCursorTargetRx8":3 } + } + optics_si_dict = { "OutputEqPostCursorTargetRx":{ + "OutputEqPostCursorTargetRx1":2, "OutputEqPostCursorTargetRx2":2, "OutputEqPostCursorTargetRx3":2, "OutputEqPostCursorTargetRx4":2, + "OutputEqPostCursorTargetRx5":2, "OutputEqPostCursorTargetRx6":2, "OutputEqPostCursorTargetRx7":2, "OutputEqPostCursorTargetRx8":2 } + } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.write = MagicMock() + mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff] + self.api.xcvr_eeprom.read.side_effect = mock_resp + self.api.stage_custom_si_settings(0x01, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 1 + + def test_set_module_si_fixed_en_settings(self): + optics_si_eq_en_dict = { "FixedInputEqTargetTx":{ + "FixedInputEqTargetTx1":0, "FixedInputEqTargetTx2":0, "FixedInputEqTargetTx3":0, "FixedInputEqTargetTx4":0, + "FixedInputEqTargetTx5":0, "FixedInputEqTargetTx6":0, "FixedInputEqTargetTx7":0, "FixedInputEqTargetTx8":0 } + } + optics_si_dict = { "FixedInputEqTargetTx":{ + "FixedInputEqTargetTx1":1, "FixedInputEqTargetTx2":1, "FixedInputEqTargetTx3":1, "FixedInputEqTargetTx4":1, + "FixedInputEqTargetTx5":1, "FixedInputEqTargetTx6":1, "FixedInputEqTargetTx7":1, "FixedInputEqTargetTx8":1 } + } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.write = MagicMock() + mock_resp = [optics_si_eq_en_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + self.api.xcvr_eeprom.read.side_effect = mock_resp + self.api.stage_custom_si_settings(0xff, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 8 + + def test_set_module_cdr_enable_tx_settings(self): + optics_si_eq_recall_dict = { "CDREnableTx":{ + "CDREnableTx1":0, "CDREnableTx2":0, "CDREnableTx3":0, "CDREnableTx4":0, + "CDREnableTx5":0, "CDREnableTx6":0, "CDREnableTx7":0, "CDREnableTx8":0 } + } + optics_si_dict = { "CDREnableTx":{ + "CDREnableTx1":1, "CDREnableTx2":1, "CDREnableTx3":1, "CDREnableTx4":1, + "CDREnableTx5":1, "CDREnableTx6":1, "CDREnableTx7":1, "CDREnableTx8":1 } + } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.write = MagicMock() + mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + self.api.xcvr_eeprom.read.side_effect = mock_resp + self.api.stage_custom_si_settings(0x0f, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 4 + + def test_set_module_cdr_enable_rx_settings(self): + optics_si_eq_pre_dict = { "CDREnableRx":{ + "CDREnableRx1":3, "CDREnableRx2":3, "CDREnableRx":3, "CDREnableRx4":3, + "CDREnableRx5":3, "CDREnableRx6":3, "CDREnableRx7":3, "CDREnableRx8":3 } + } + optics_si_dict = { "CDREnableRx":{ + "CDREnableRx1":2, "CDREnableRx2":2, "CDREnableRx3":2, "CDREnableRx4":2, + "CDREnableRx5":2, "CDREnableRx6":2, "CDREnableRx7":2, "CDREnableRx8":2 } + } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.write = MagicMock() + mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + self.api.xcvr_eeprom.read.side_effect = mock_resp + self.api.stage_custom_si_settings(0x01, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 1 + + def test_set_module_OutputAmplitudeTargetRx_settings(self): + optics_si_eq_recall_dict = { "OutputAmplitudeTargetRx":{ + "OutputAmplitudeTargetRx1":0, "OutputAmplitudeTargetRx2":0, "OutputAmplitudeTargetRx3":0, "OutputAmplitudeTargetRx4":0, + "OutputAmplitudeTargetRx5":0, "OutputAmplitudeTargetRx6":0, "OutputAmplitudeTargetRx7":0, "OutputAmplitudeTargetRx8":0 } + } + optics_si_dict = { "OutputAmplitudeTargetRx":{ + "OutputAmplitudeTargetRx1":1, "OutputAmplitudeTargetRx2":1, "OutputAmplitudeTargetRx3":1, "OutputAmplitudeTargetRx4":1, + "OutputAmplitudeTargetRx5":1, "OutputAmplitudeTargetRx6":1, "OutputAmplitudeTargetRx7":1, "OutputAmplitudeTargetRx8":1 } + } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.write = MagicMock() + mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] self.api.xcvr_eeprom.read.side_effect = mock_resp - self.api.set_module_si_settings(0x0f , 1, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 4 + 4 + 1 + self.api.stage_custom_si_settings(0x0f, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 4 def test_get_error_description(self): self.api.get_module_state = MagicMock() From 90826cd989c25f24b2097fdd78411b15330ff903 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 26 Jul 2023 00:50:50 -0700 Subject: [PATCH 20/42] Update cmis.py --- .../sonic_xcvr/api/public/cmis.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index dd1195e7c..9c42dc672 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2190,6 +2190,8 @@ def nibble_read_modify_write(self, val, si_param, lane): if (lane%2) == 0: pre_si_key_lane = "{}{}".format(si_param, lane-1) pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + if pre_val is None: + return False val = (val << 4) | pre_val si_key_lane = "{}{}".format(si_param, lane) return self.xcvr_eeprom.write(si_key_lane, val) @@ -2204,6 +2206,8 @@ def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) val = si_settings[consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX][si_key_lane] + if val is None: + return False if val <= self.get_rx_output_eq_pre_max_val(): if not self.nibble_read_modify_write(val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane): return False @@ -2219,6 +2223,8 @@ def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) val = si_settings[consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX][si_key_lane] + if val is None: + return False if val <= self.get_rx_output_eq_post_max_val(): if not self.nibble_read_modify_write(val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane): return False @@ -2234,6 +2240,8 @@ def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) val = si_settings[consts.OUTPUT_AMPLITUDE_TARGET_RX][si_key_lane] + if val is None: + return False if val <= self.get_rx_output_amp_supported_val(): if not self.nibble_read_modify_write(val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane): return False @@ -2249,6 +2257,8 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): lane = lane+1 si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane) val = si_settings[consts.FIXED_INPUT_EQ_TARGET_TX][si_key_lane] + if val is None: + return False if val <= self.get_tx_input_eq_max_val(): if not self.nibble_read_modify_write(val, consts.FIXED_INPUT_EQ_TARGET_TX, lane): return False @@ -2256,7 +2266,10 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): ''' - This function applies adaptive TX input recall si settings + This function applies adaptive TX input recall si settings. + In this function, we set 2 bits at a time for each lane. + We mask the lane bits (ex: bit 0 and 1 for lane 1; bit 2 and 3 for lane 2 .. etc), + previous lane values will be written each time we write 1 byte data with new lane values ''' val = 0 for lane in range(self.NUM_CHANNELS): @@ -2278,6 +2291,8 @@ def byte_read_modify_write(self, si_keys, host_lanes_mask, si_settings): for lane in range(self.NUM_CHANNELS): si_key_lane = "{}{}".format(si_keys, lane+1) data = self.xcvr_eeprom.read(si_key_lane) + if data is None: + return False val |= (data << lane) # Write only applicable field for lane in range(self.NUM_CHANNELS): From 720a0181ba5c8949bde1f886e0f245cfc711b7a6 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 26 Jul 2023 00:59:46 -0700 Subject: [PATCH 21/42] fix whitespace errors --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 9c42dc672..e073ebef7 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2173,7 +2173,7 @@ def get_rx_ouput_amp_ctrl_supported(self): This function returns the supported RX output amp control field ''' return self.xcvr_eeprom.read(consts.RX_OUTPUT_AMP_CTRL_SUPPORT_FIELD) - + def get_rx_output_eq_pre_ctrl_supported(self): ''' This function returns the supported RX output eq pre control field @@ -2228,7 +2228,7 @@ def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): if val <= self.get_rx_output_eq_post_max_val(): if not self.nibble_read_modify_write(val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane): return False - return True + return True def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): ''' @@ -2267,8 +2267,8 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): ''' This function applies adaptive TX input recall si settings. - In this function, we set 2 bits at a time for each lane. - We mask the lane bits (ex: bit 0 and 1 for lane 1; bit 2 and 3 for lane 2 .. etc), + In this function, we set 2 bits at a time for each lane. + We mask the lane bits (ex: bit 0 and 1 for lane 1; bit 2 and 3 for lane 2 .. etc), previous lane values will be written each time we write 1 byte data with new lane values ''' val = 0 From 1b2ccdbc88f176f70ce5a03ba20888a32354c247 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Thu, 27 Jul 2023 18:44:38 -0700 Subject: [PATCH 22/42] Address review comments Add return checks for some eeprom read/write modify Byte read/write and nibble read/write api --- .../sonic_xcvr/api/public/cmis.py | 168 ++++++++++++------ 1 file changed, 110 insertions(+), 58 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index e073ebef7..7aaa00896 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2108,88 +2108,133 @@ def stage_datapath_init(self, channel): ''' return self.xcvr_eeprom.write("%s_%d" % (consts.STAGED_CTRL_APPLY_DPINIT_FIELD, 0), channel) - def get_rx_output_amp_supported_val(self): + def get_rx_output_amp_max_val(self): ''' This function returns the supported RX output amp val ''' - return self.xcvr_eeprom.read(consts.RX_OUTPUT_LEVEL_SUPPORT) + rx_amp_max_val = self.xcvr_eeprom.read(consts.RX_OUTPUT_LEVEL_SUPPORT) + if rx_amp_max_val is None: + return None + return rx_amp_max_val def get_rx_output_eq_pre_max_val(self): ''' This function returns the supported RX output eq pre cursor val ''' - return self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CURSOR_MAX) + rx_pre_max_val = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CURSOR_MAX) + if rx_pre_max_val is None: + return None + return rx_pre_max_val def get_rx_output_eq_post_max_val(self): ''' This function returns the supported RX output eq post cursor val ''' - return self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CURSOR_MAX) + rx_post_max_val = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CURSOR_MAX) + if rx_post_max_val is None: + return None + return rx_post_max_val def get_tx_input_eq_max_val(self): ''' This function returns the supported TX input eq val ''' - return self.xcvr_eeprom.read(consts.TX_INPUT_EQ_MAX) + tx_input_max_val = self.xcvr_eeprom.read(consts.TX_INPUT_EQ_MAX) + if tx_input_max_val is None: + return None + return tx_input_max_val def get_tx_cdr_supported(self): ''' This function returns the supported TX CDR field ''' - return self.xcvr_eeprom.read(consts.TX_CDR_SUPPORT_FIELD) + tx_cdr_support = self.xcvr_eeprom.read(consts.TX_CDR_SUPPORT_FIELD) + if not tx_cdr_support or tx_cdr_support is None: + return False + return tx_cdr_support def get_rx_cdr_supported(self): ''' This function returns the supported RX CDR field ''' - return self.xcvr_eeprom.read(consts.RX_CDR_SUPPORT_FIELD) + rx_cdr_support = self.xcvr_eeprom.read(consts.RX_CDR_SUPPORT_FIELD) + if not rx_cdr_support or rx_cdr_support is None: + return False + return rx_cdr_support def get_tx_input_eq_fixed_supported(self): ''' This function returns the supported TX input eq field ''' - return self.xcvr_eeprom.read(consts.TX_INPUT_EQ_FIXED_MANUAL_CTRL_SUPPORT_FIELD) + tx_fixed_support = self.xcvr_eeprom.read(consts.TX_INPUT_EQ_FIXED_MANUAL_CTRL_SUPPORT_FIELD) + if not tx_fixed_support or tx_fixed_support is None: + return False + return tx_fixed_support def get_tx_input_adaptive_eq_supported(self): ''' This function returns the supported TX input adaptive eq field ''' - return self.xcvr_eeprom.read(consts.TX_INPUT_ADAPTIVE_EQ_SUPPORT_FIELD) + tx_adaptive_support = self.xcvr_eeprom.read(consts.TX_INPUT_ADAPTIVE_EQ_SUPPORT_FIELD) + if not tx_adaptive_support or tx_adaptive_support is None: + return False + return tx_adaptive_support def get_tx_input_recall_buf1_supported(self): ''' This function returns the supported TX input recall buf1 field ''' - return self.xcvr_eeprom.read(consts.TX_INPUT_EQ_RECALL_BUF1_SUPPORT_FIELD) + tx_recall_buf1_support = self.xcvr_eeprom.read(consts.TX_INPUT_EQ_RECALL_BUF1_SUPPORT_FIELD) + if not tx_recall_buf1_support or tx_recall_buf1_support is None: + return False + return tx_recall_buf1_support def get_tx_input_recall_buf2_supported(self): ''' This function returns the supported TX input recall buf2 field ''' - return self.xcvr_eeprom.read(consts.TX_INPUT_EQ_RECALL_BUF2_SUPPORT_FIELD) + tx_recall_buf2_support = self.xcvr_eeprom.read(consts.TX_INPUT_EQ_RECALL_BUF2_SUPPORT_FIELD) + if not tx_recall_buf2_support or tx_recall_buf2_support is None: + return False + return tx_recall_buf2_support - def get_rx_ouput_amp_ctrl_supported(self): + def get_rx_ouput_amp_ctrl_supported(self): ''' This function returns the supported RX output amp control field ''' - return self.xcvr_eeprom.read(consts.RX_OUTPUT_AMP_CTRL_SUPPORT_FIELD) + rx_amp_support = self.xcvr_eeprom.read(consts.RX_OUTPUT_AMP_CTRL_SUPPORT_FIELD) + if not rx_amp_support or rx_amp_support is None: + return False + return rx_amp_support def get_rx_output_eq_pre_ctrl_supported(self): ''' This function returns the supported RX output eq pre control field ''' - return self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CTRL_SUPPORT_FIELD) + rx_pre_support = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_PRE_CTRL_SUPPORT_FIELD) + if not rx_pre_support or rx_pre_support is None: + return False + return rx_pre_support def get_rx_output_eq_post_ctrl_supported(self): ''' This function returns the supported RX output eq post control field ''' - return self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CTRL_SUPPORT_FIELD) + rx_post_support = self.xcvr_eeprom.read(consts.RX_OUTPUT_EQ_POST_CTRL_SUPPORT_FIELD) + if not rx_post_support or rx_post_support is None: + return False + return rx_post_support + + def scs_nibble_read(self, si_param, lane): + si_key_lane = "{}{}".format(si_param, lane) + val = self.xcvr_eeprom.read(si_key_lane) + if val is None: + return None + return val - def nibble_read_modify_write(self, val, si_param, lane): + def scs_nibble_write(self, val, si_param, lane): if (lane%2) == 0: - pre_si_key_lane = "{}{}".format(si_param, lane-1) - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + pre_val = self.scs_nibble_read(si_param, lane-1) if pre_val is None: return False val = (val << 4) | pre_val @@ -2208,14 +2253,16 @@ def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): val = si_settings[consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX][si_key_lane] if val is None: return False - if val <= self.get_rx_output_eq_pre_max_val(): - if not self.nibble_read_modify_write(val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane): - return False + rx_pre_max_val = self.get_rx_output_eq_pre_max_val() + if rx_pre_max_val is None or val > rx_pre_max_val: + return False + if not self.scs_nibble_write(val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane): + return False return True def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): ''' - This function applies RX output eq pre cursor settings + This function applies RX output eq post cursor settings ''' for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: @@ -2225,9 +2272,11 @@ def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): val = si_settings[consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX][si_key_lane] if val is None: return False - if val <= self.get_rx_output_eq_post_max_val(): - if not self.nibble_read_modify_write(val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane): - return False + rx_post_max_val = self.get_rx_output_eq_post_max_val() + if rx_post_max_val is None or val > rx_post_max_val: + return False + if not self.scs_nibble_write(val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane): + return False return True def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): @@ -2242,9 +2291,11 @@ def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): val = si_settings[consts.OUTPUT_AMPLITUDE_TARGET_RX][si_key_lane] if val is None: return False - if val <= self.get_rx_output_amp_supported_val(): - if not self.nibble_read_modify_write(val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane): - return False + rx_amp_max_val = self.get_rx_output_amp_max_val() + if rx_amp_max_val is None or val > rx_amp_max_val: + return False + if not self.scs_nibble_write(val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane): + return False return True def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): @@ -2259,9 +2310,11 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): val = si_settings[consts.FIXED_INPUT_EQ_TARGET_TX][si_key_lane] if val is None: return False - if val <= self.get_tx_input_eq_max_val(): - if not self.nibble_read_modify_write(val, consts.FIXED_INPUT_EQ_TARGET_TX, lane): - return False + tx_fixed_input = self.get_tx_input_eq_max_val() + if tx_fixed_input is None or val > tx_fixed_input: + return False + if not self.scs_nibble_write(val, consts.FIXED_INPUT_EQ_TARGET_TX, lane): + return False return True def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): @@ -2269,7 +2322,7 @@ def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): This function applies adaptive TX input recall si settings. In this function, we set 2 bits at a time for each lane. We mask the lane bits (ex: bit 0 and 1 for lane 1; bit 2 and 3 for lane 2 .. etc), - previous lane values will be written each time we write 1 byte data with new lane values + and 1 byte data is written ''' val = 0 for lane in range(self.NUM_CHANNELS): @@ -2281,48 +2334,49 @@ def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): mask = ~(val << (lane*2)) l_data = si_val << (lane*2) val = (val & mask) | l_data - if not self.xcvr_eeprom.write(si_key_lane, val): - return False - return True + return self.xcvr_eeprom.write(si_key_lane, val) - def byte_read_modify_write(self, si_keys, host_lanes_mask, si_settings): - val = 0 - # Read 1 byte data - for lane in range(self.NUM_CHANNELS): - si_key_lane = "{}{}".format(si_keys, lane+1) - data = self.xcvr_eeprom.read(si_key_lane) - if data is None: - return False - val |= (data << lane) - # Write only applicable field + def scs_byte_read(self, si_keys): + si_byte_read = self.xcvr_eeprom.read(si_keys) + if si_byte_read is None: + return None + return si_byte_read + + def scs_byte_write(self, si_key, host_lanes_mask, si_settings): + val = self.scs_byte_read(si_key) + if val is None: + return False + si_val = si_settings[si_key] + if si_val is None: + return False + nibble_val = si_val & host_lanes_mask for lane in range(self.NUM_CHANNELS): - if ((1 << lane) & host_lanes_mask) == 0: + mask = (1 << lane) + if (mask & host_lanes_mask) == 0: continue - si_key_lane = "{}{}".format(si_keys, lane+1) - si_val = si_settings[si_keys][si_key_lane] - val &= ~(1 << lane) - val |= (si_val << lane) - if not self.xcvr_eeprom.write(si_key_lane, val): - return False - return True + if nibble_val: + val |= mask + else: + val &= ~mask + return self.xcvr_eeprom.write(si_key, val) def stage_adaptive_input_eq_enable_tx(self, host_lanes_mask, si_settings): ''' This function applies adaptive TX input enable si settings ''' - return self.byte_read_modify_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_settings) + return self.scs_byte_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_settings) def stage_cdr_tx(self, host_lanes_mask, si_settings): ''' This function applies TX CDR si settings ''' - return self.byte_read_modify_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_settings) + return self.scs_byte_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_settings) def stage_cdr_rx(self, host_lanes_mask, si_settings): ''' This function applies RX CDR si settings ''' - return self.byte_read_modify_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_settings) + return self.scs_byte_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_settings) def stage_rx_si_settings(self, host_lanes_mask, si_settings): for si_keys in si_settings: @@ -2362,7 +2416,6 @@ def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): si_settings = self.xcvr_eeprom.read(consts.STAGED_CTRL0_TX_CTRL_FIELD) if si_settings is None: return False - # Replace the new values with cached SI values for si_keys in optics_si_dict: if si_keys in si_settings: @@ -2375,7 +2428,6 @@ def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): #stage TX si settings if not self.stage_tx_si_settings(host_lanes_mask, si_settings): return False - return True def get_error_description(self): From 3d6570841aa7ca40babbca00b4b18da534338b4d Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Thu, 27 Jul 2023 18:46:23 -0700 Subject: [PATCH 23/42] Update cmis.py --- .../sonic_xcvr/mem_maps/public/cmis.py | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) 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 b845d3c12..f83c658d4 100644 --- a/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py @@ -504,12 +504,7 @@ def __init__(self, codes): ) self.STAGED_CTRL0_TX_CTRL = RegGroupField(consts.STAGED_CTRL0_TX_CTRL_FIELD, - RegGroupField(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, - *(NumberRegField("%s%d" % (consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, lane) , self.getaddr(0x10, 153), - RegBitField("Bit%d" % (lane-1), (lane-1)), ro=False - ) - for lane in range(1, 9)) - ), + NumberRegField(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, self.getaddr(0x10, 153), ro=False), RegGroupField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX, *(NumberRegField("%s%d" % (consts.ADAPTIVE_INPUT_EQ_RECALLED_TX, lane) , self.getaddr(0x10, 154 + int((lane-1)/4)), ro=False, *(RegBitField("Bit%d" % bit, bit) for bit in [range(6, 8), range(4, 6), range(2, 4), range(0, 2)][lane%4])) @@ -520,18 +515,8 @@ def __init__(self, codes): *(RegBitField("Bit%d" % bit, bit) for bit in [range(4, 8), range(0, 4)][lane%2])) for lane in range(1, 9)) ), - RegGroupField(consts.CDR_ENABLE_TX, - *(NumberRegField("%s%d" % (consts.CDR_ENABLE_TX, lane), self.getaddr(0x10, 160), - RegBitField("Bit%d" % (lane-1), (lane-1)), ro=False - ) - for lane in range(1, 9)) - ), - RegGroupField(consts.CDR_ENABLE_RX, - *(NumberRegField("%s%d" % (consts.CDR_ENABLE_RX, lane), self.getaddr(0x10, 161), - RegBitField("Bit%d" % (lane-1), (lane-1)), ro=False - ) - for lane in range(1, 9)) - ), + NumberRegField(consts.CDR_ENABLE_TX, self.getaddr(0x10, 160), ro=False), + NumberRegField(consts.CDR_ENABLE_RX, self.getaddr(0x10, 161), ro=False), RegGroupField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, *(NumberRegField("%s%d" % (consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) , self.getaddr(0x10, 162 + int((lane-1)/2)), ro=False, *(RegBitField("Bit%d" % bit, bit) for bit in [range(4, 8), range(0, 4)][lane%2])) From f552e27039982f22a4db6391c959550c3a39bf2b Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Thu, 27 Jul 2023 22:32:14 -0700 Subject: [PATCH 24/42] Fix build failures --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 7aaa00896..6fe7f4e31 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2198,7 +2198,7 @@ def get_tx_input_recall_buf2_supported(self): return False return tx_recall_buf2_support - def get_rx_ouput_amp_ctrl_supported(self): + def get_rx_ouput_amp_ctrl_supported(self): ''' This function returns the supported RX output amp control field ''' From 6db613c94a4a3f0bff9621af86f8a59efa801aaf Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Fri, 28 Jul 2023 00:21:17 -0700 Subject: [PATCH 25/42] Update test_cmis.py --- tests/sonic_xcvr/test_cmis.py | 45 ++++++++++------------------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index 69f0bd591..b2c2cf9f4 100644 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -2232,21 +2232,14 @@ def test_set_module_si_eq_pre_settings(self): assert self.api.xcvr_eeprom.write.call_count == 1 def test_set_module_si_eq_en_settings(self): - optics_si_eq_en_dict = { "AdaptiveInputEqEnableTx":{ - "AdaptiveInputEqEnableTx1":0, "AdaptiveInputEqEnableTx2":0, "AdaptiveInputEqEnableTx3":0, "AdaptiveInputEqEnableTx4":0, - "AdaptiveInputEqEnableTx5":0, "AdaptiveInputEqEnableTx6":0, "AdaptiveInputEqEnableTx7":0, "AdaptiveInputEqEnableTx8":0 } - } - optics_si_dict = { "AdaptiveInputEqEnableTx":{ - "AdaptiveInputEqEnableTx1":1, "AdaptiveInputEqEnableTx2":1, "AdaptiveInputEqEnableTx3":1, "AdaptiveInputEqEnableTx4":1, - "AdaptiveInputEqEnableTx5":1, "AdaptiveInputEqEnableTx6":1, "AdaptiveInputEqEnableTx7":1, "AdaptiveInputEqEnableTx8":1 } - } + optics_si_eq_en = { "AdaptiveInputEqEnableTx": 0 } + optics_si_dict = { "AdaptiveInputEqEnableTx": 255 } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_en_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + mock_resp = [optics_si_eq_en, 0xff, 0xff] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0xff, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 8 + assert self.api.xcvr_eeprom.write.call_count == 1 def test_set_module_si_eq_recall_settings(self): optics_si_eq_recall_dict = { "AdaptiveInputEqRecalledTx":{ @@ -2298,39 +2291,25 @@ def test_set_module_si_fixed_en_settings(self): assert self.api.xcvr_eeprom.write.call_count == 8 def test_set_module_cdr_enable_tx_settings(self): - optics_si_eq_recall_dict = { "CDREnableTx":{ - "CDREnableTx1":0, "CDREnableTx2":0, "CDREnableTx3":0, "CDREnableTx4":0, - "CDREnableTx5":0, "CDREnableTx6":0, "CDREnableTx7":0, "CDREnableTx8":0 } - } - optics_si_dict = { "CDREnableTx":{ - "CDREnableTx1":1, "CDREnableTx2":1, "CDREnableTx3":1, "CDREnableTx4":1, - "CDREnableTx5":1, "CDREnableTx6":1, "CDREnableTx7":1, "CDREnableTx8":1 } - } + optics_si_cdr_en_tx = { "CDREnableTx": 0 } + optics_si_dict = { "CDREnableTx": 255 } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + mock_resp = [optics_si_cdr_en_tx, 0xff, 0xff] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0x0f, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 4 + assert self.api.xcvr_eeprom.write.call_count == 1 def test_set_module_cdr_enable_rx_settings(self): - optics_si_eq_pre_dict = { "CDREnableRx":{ - "CDREnableRx1":3, "CDREnableRx2":3, "CDREnableRx":3, "CDREnableRx4":3, - "CDREnableRx5":3, "CDREnableRx6":3, "CDREnableRx7":3, "CDREnableRx8":3 } - } - optics_si_dict = { "CDREnableRx":{ - "CDREnableRx1":2, "CDREnableRx2":2, "CDREnableRx3":2, "CDREnableRx4":2, - "CDREnableRx5":2, "CDREnableRx6":2, "CDREnableRx7":2, "CDREnableRx8":2 } - } + optics_si_cdr_en_rx = { "CDREnableRx": 255 } + optics_si_dict = { "CDREnableRx": 255} self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + mock_resp = [optics_si_cdr_en_rx, 0xff, 0xff] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0x01, optics_si_dict) assert self.api.xcvr_eeprom.write.call_count == 1 - + def test_set_module_OutputAmplitudeTargetRx_settings(self): optics_si_eq_recall_dict = { "OutputAmplitudeTargetRx":{ "OutputAmplitudeTargetRx1":0, "OutputAmplitudeTargetRx2":0, "OutputAmplitudeTargetRx3":0, "OutputAmplitudeTargetRx4":0, From 4589203143579d539deded023006e49fc20f519b Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Fri, 28 Jul 2023 00:34:02 -0700 Subject: [PATCH 26/42] Update test_cmis.py --- tests/sonic_xcvr/test_cmis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index b2c2cf9f4..0e45c8ba0 100644 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -2255,7 +2255,7 @@ def test_set_module_si_eq_recall_settings(self): mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0x0f, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 4 + assert self.api.xcvr_eeprom.write.call_count == 1 def test_set_module_si_eq_post_settings(self): optics_si_eq_pre_dict = { "OutputEqPostCursorTargetRx":{ From ddc2f7c5b52ae1ce07cf88c2d299fde3f4838ad5 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 2 Aug 2023 01:22:24 -0700 Subject: [PATCH 27/42] Address review comments --- .../sonic_xcvr/api/public/cmis.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 6fe7f4e31..5545e8f84 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2329,23 +2329,14 @@ def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): if ((1 << lane) & host_lanes_mask) == 0: continue si_key_lane = "{}{}".format(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX, lane+1) - si_val = si_settings[consts.ADAPTIVE_INPUT_EQ_RECALLED_TX][si_key_lane] + si_val = 0x3 & si_settings[consts.ADAPTIVE_INPUT_EQ_RECALLED_TX][si_key_lane] lane %= (self.NUM_CHANNELS//2) mask = ~(val << (lane*2)) l_data = si_val << (lane*2) val = (val & mask) | l_data return self.xcvr_eeprom.write(si_key_lane, val) - def scs_byte_read(self, si_keys): - si_byte_read = self.xcvr_eeprom.read(si_keys) - if si_byte_read is None: - return None - return si_byte_read - - def scs_byte_write(self, si_key, host_lanes_mask, si_settings): - val = self.scs_byte_read(si_key) - if val is None: - return False + def scs_byte_write(self, si_key, host_lanes_mask, si_settings, val): si_val = si_settings[si_key] if si_val is None: return False @@ -2364,19 +2355,28 @@ def stage_adaptive_input_eq_enable_tx(self, host_lanes_mask, si_settings): ''' This function applies adaptive TX input enable si settings ''' - return self.scs_byte_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_settings) + val = self.xcvr_eeprom.read(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX) + if val is None: + return False + return self.scs_byte_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_settings, val) def stage_cdr_tx(self, host_lanes_mask, si_settings): ''' This function applies TX CDR si settings ''' - return self.scs_byte_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_settings) + val = self.xcvr_eeprom.read(consts.CDR_ENABLE_TX) + if val is None: + return False + return self.scs_byte_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_settings, val) def stage_cdr_rx(self, host_lanes_mask, si_settings): ''' This function applies RX CDR si settings ''' - return self.scs_byte_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_settings) + val = self.xcvr_eeprom.read(consts.CDR_ENABLE_RX) + if val is None: + return False + return self.scs_byte_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_settings, val) def stage_rx_si_settings(self, host_lanes_mask, si_settings): for si_keys in si_settings: From 79fde1470ebb92f7bbc0f91959a1c9235a42c6c2 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Thu, 3 Aug 2023 23:32:20 -0700 Subject: [PATCH 28/42] Address review comments Create separate TX/RX dict Add else case to handle unsupported TX/RX SI params Clean 2 bits read/write method --- .../sonic_xcvr/api/public/cmis.py | 196 ++++++++++++------ 1 file changed, 127 insertions(+), 69 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 5545e8f84..bd00dd965 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2225,18 +2225,11 @@ def get_rx_output_eq_post_ctrl_supported(self): return False return rx_post_support - def scs_nibble_read(self, si_param, lane): - si_key_lane = "{}{}".format(si_param, lane) - val = self.xcvr_eeprom.read(si_key_lane) - if val is None: - return None - return val - def scs_nibble_write(self, val, si_param, lane): + ''' + This function sets nibble data in byte data + '' if (lane%2) == 0: - pre_val = self.scs_nibble_read(si_param, lane-1) - if pre_val is None: - return False val = (val << 4) | pre_val si_key_lane = "{}{}".format(si_param, lane) return self.xcvr_eeprom.write(si_key_lane, val) @@ -2250,13 +2243,19 @@ def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): continue lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) - val = si_settings[consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX][si_key_lane] + val = si_settings[si_key_lane] if val is None: return False rx_pre_max_val = self.get_rx_output_eq_pre_max_val() if rx_pre_max_val is None or val > rx_pre_max_val: return False - if not self.scs_nibble_write(val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane): + pre_val = 0 + if (lane%2) == 0: + pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane-1) + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + if pre_val is None: + return False + if not self.scs_nibble_write(val, pre_val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane): return False return True @@ -2269,13 +2268,19 @@ def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): continue lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) - val = si_settings[consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX][si_key_lane] + val = si_settings[si_key_lane] if val is None: return False rx_post_max_val = self.get_rx_output_eq_post_max_val() if rx_post_max_val is None or val > rx_post_max_val: return False - if not self.scs_nibble_write(val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane): + pre_val = 0 + if (lane%2) == 0: + pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane-1) + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + if pre_val is None: + return False + if not self.scs_nibble_write(val, pre_val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane): return False return True @@ -2288,13 +2293,19 @@ def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): continue lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) - val = si_settings[consts.OUTPUT_AMPLITUDE_TARGET_RX][si_key_lane] + val = si_settings[si_key_lane] if val is None: return False rx_amp_max_val = self.get_rx_output_amp_max_val() if rx_amp_max_val is None or val > rx_amp_max_val: return False - if not self.scs_nibble_write(val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane): + pre_val = 0 + if (lane%2) == 0: + pre_si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane-1) + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + if pre_val is None: + return False + if not self.scs_nibble_write(val, pre_val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane): return False return True @@ -2307,39 +2318,52 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): continue lane = lane+1 si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane) - val = si_settings[consts.FIXED_INPUT_EQ_TARGET_TX][si_key_lane] + val = si_settings[si_key_lane] if val is None: return False tx_fixed_input = self.get_tx_input_eq_max_val() if tx_fixed_input is None or val > tx_fixed_input: return False - if not self.scs_nibble_write(val, consts.FIXED_INPUT_EQ_TARGET_TX, lane): + pre_val = 0 + if (lane%2) == 0: + pre_si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane-1) + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + if pre_val is None: + return False + if not self.scs_nibble_write(val, pre_val, consts.FIXED_INPUT_EQ_TARGET_TX, lane): return False return True - def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings): + def tx_recall_byte_write(self, si_param, pos, si_val_lane, tx_recall_val): + ''' + This function sets 2 bits in byte data based on lane number + ''' + mask = 0b11 + mask <<= pos + val = (tx_recall_val & ~mask) | (si_val_lane << pos) + return self.xcvr_eeprom.write(si_param, val) + + def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_key, si_val): ''' This function applies adaptive TX input recall si settings. - In this function, we set 2 bits at a time for each lane. - We mask the lane bits (ex: bit 0 and 1 for lane 1; bit 2 and 3 for lane 2 .. etc), - and 1 byte data is written + In this function, we read byte data and modify lane associated bits + (ex: bit 0 and 1 for lane 1; bit 2 and 3 for lane 2 .. etc) and write byte data ''' - val = 0 for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: continue - si_key_lane = "{}{}".format(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX, lane+1) - si_val = 0x3 & si_settings[consts.ADAPTIVE_INPUT_EQ_RECALLED_TX][si_key_lane] - lane %= (self.NUM_CHANNELS//2) - mask = ~(val << (lane*2)) - l_data = si_val << (lane*2) - val = (val & mask) | l_data - return self.xcvr_eeprom.write(si_key_lane, val) + lane %= 4 + tx_recall_val = self.xcvr_eeprom.read(si_key) + if tx_recall_val is None: + return False + pos = lane*2 + mask = 0b11 + si_val_lane = 0x3 & ((si_val >> pos) & mask) + if not self.tx_recall_byte_write(si_key, pos, si_val_lane, tx_recall_val): + return False + return True - def scs_byte_write(self, si_key, host_lanes_mask, si_settings, val): - si_val = si_settings[si_key] - if si_val is None: - return False + def scs_byte_write(self, si_key, host_lanes_mask, si_val, val): nibble_val = si_val & host_lanes_mask for lane in range(self.NUM_CHANNELS): mask = (1 << lane) @@ -2351,69 +2375,93 @@ def scs_byte_write(self, si_key, host_lanes_mask, si_settings, val): val &= ~mask return self.xcvr_eeprom.write(si_key, val) - def stage_adaptive_input_eq_enable_tx(self, host_lanes_mask, si_settings): + def stage_adaptive_input_eq_enable_tx(self, host_lanes_mask, si_val): ''' This function applies adaptive TX input enable si settings ''' + if si_val is None: + return False val = self.xcvr_eeprom.read(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX) if val is None: return False - return self.scs_byte_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_settings, val) + return self.scs_byte_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_val, val) - def stage_cdr_tx(self, host_lanes_mask, si_settings): + def stage_cdr_tx(self, host_lanes_mask, si_val): ''' This function applies TX CDR si settings ''' + if si_val is None: + return False val = self.xcvr_eeprom.read(consts.CDR_ENABLE_TX) if val is None: return False - return self.scs_byte_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_settings, val) + return self.scs_byte_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_val, val) - def stage_cdr_rx(self, host_lanes_mask, si_settings): + def stage_cdr_rx(self, host_lanes_mask, si_val): ''' This function applies RX CDR si settings ''' + if si_val is None: + return False val = self.xcvr_eeprom.read(consts.CDR_ENABLE_RX) if val is None: return False - return self.scs_byte_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_settings, val) + return self.scs_byte_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_val, val) def stage_rx_si_settings(self, host_lanes_mask, si_settings): for si_keys in si_settings: - if si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX and self.get_rx_output_eq_pre_ctrl_supported(): - if not self.stage_output_eq_pre_cursor_target_rx(host_lanes_mask, si_settings): - return False - elif si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX and self.get_rx_output_eq_post_ctrl_supported(): - if not self.stage_output_eq_post_cursor_target_rx(host_lanes_mask, si_settings): - return False - elif si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX and self.get_rx_ouput_amp_ctrl_supported(): - if not self.stage_output_amp_target_rx(host_lanes_mask, si_settings): - return False - elif si_keys == consts.CDR_ENABLE_RX and self.get_rx_cdr_supported(): - if not self.stage_cdr_rx(host_lanes_mask, si_settings): - return False + if si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX: + if self.get_rx_output_eq_pre_ctrl_supported(): + if not self.stage_output_eq_pre_cursor_target_rx(host_lanes_mask, si_settings[si_keys]): + return False + elif si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX: + if self.get_rx_output_eq_post_ctrl_supported(): + if not self.stage_output_eq_post_cursor_target_rx(host_lanes_mask, si_settings[si_keys]): + return False + elif si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX: + if self.get_rx_ouput_amp_ctrl_supported(): + if not self.stage_output_amp_target_rx(host_lanes_mask, si_settings[si_keys]): + return False + elif si_keys == consts.CDR_ENABLE_RX: + if self.get_rx_cdr_supported(): + if not self.stage_cdr_rx(host_lanes_mask, si_settings[si_keys]): + return False + else: + return False + return True def stage_tx_si_settings(self, host_lanes_mask, si_settings): for si_keys in si_settings: - if si_keys == consts.FIXED_INPUT_EQ_TARGET_TX and self.get_tx_input_eq_fixed_supported(): - if not self.stage_fixed_input_target_tx(host_lanes_mask, si_settings): - return False - elif (si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX and - (self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported())): - if not self.stage_adaptive_input_recall_tx(host_lanes_mask, si_settings): - return False - elif si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX and self.get_tx_input_adaptive_eq_supported(): - if not self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings): - return False - elif si_keys == consts.CDR_ENABLE_TX and self.get_tx_cdr_supported(): - if not self.stage_cdr_tx(host_lanes_mask, si_settings): - return False + if si_keys == consts.FIXED_INPUT_EQ_TARGET_TX: + if self.get_tx_input_eq_fixed_supported(): + if not self.stage_fixed_input_target_tx(host_lanes_mask, si_settings[si_keys]): + return False + elif si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX1_4 : + if ((host_lanes_mask & 0xf) and (self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported())): + if not self.stage_adaptive_input_recall_tx(host_lanes_mask, si_keys, si_settings[si_keys]): + return False + elif si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX5_8: + if ((host_lanes_mask & 0xf0) and (self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported())): + if not self.stage_adaptive_input_recall_tx(host_lanes_mask, si_keys, si_settings[si_keys]): + return False + elif si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX: + if self.get_tx_input_adaptive_eq_supported(): + if not self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings[si_keys]): + return False + elif si_keys == consts.CDR_ENABLE_TX: + if self.get_tx_cdr_supported(): + if not self.stage_cdr_tx(host_lanes_mask, si_settings[si_keys]): + return False + else: + return False + return True def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): - # Read and cache the existing SCS0 TX CTRL data - si_settings = self.xcvr_eeprom.read(consts.STAGED_CTRL0_TX_CTRL_FIELD) + # Read and cache the existing SCS0 TX/RX CTRL data + si_settings = self.xcvr_eeprom.read(consts.STAGED_CTRL0_TX_RX_CTRL_FIELD) + if si_settings is None: return False # Replace the new values with cached SI values @@ -2421,13 +2469,23 @@ def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): if si_keys in si_settings: si_settings[si_keys] = optics_si_dict[si_keys] + # Create TX/RX specific si_dict + rx_si_settings = {} + tx_si_settings = {} + for si_keys in si_settings: + if si_keys.endswith("Tx"): + tx_si_settings[si_keys] = si_settings[si_keys] + elif si_keys.endswith("Rx"): + rx_si_settings[si_keys] = si_settings[si_keys] + # stage RX si settings - if not self.stage_rx_si_settings(host_lanes_mask, si_settings): + if not self.stage_rx_si_settings(host_lanes_mask, rx_si_settings): return False #stage TX si settings - if not self.stage_tx_si_settings(host_lanes_mask, si_settings): + if not self.stage_tx_si_settings(host_lanes_mask, tx_si_settings): return False + return True def get_error_description(self): From 0b4bd11422ee2882072e2386d72f2680b8e730cb Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Thu, 3 Aug 2023 23:46:21 -0700 Subject: [PATCH 29/42] Update consts.py --- sonic_platform_base/sonic_xcvr/fields/consts.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/fields/consts.py b/sonic_platform_base/sonic_xcvr/fields/consts.py index dc8df6d32..a2682fafc 100644 --- a/sonic_platform_base/sonic_xcvr/fields/consts.py +++ b/sonic_platform_base/sonic_xcvr/fields/consts.py @@ -299,7 +299,7 @@ STAGED_CTRL_APPLY_IMMEDIATE_FIELD = "Staged Control Set Apply Immediate" STAGED_CTRL_APSEL_FIELD = "Staged Control Set ApSel" -STAGED_CTRL0_TX_CTRL_FIELD = "Staged Control TX Control" +STAGED_CTRL0_TX_RX_CTRL_FIELD = "Staged Control TX RX Control" TX_INPUT_EQ_MAX = "TXInputEqMax" RX_OUTPUT_LEVEL_SUPPORT = "RX Output Level Supported" @@ -330,7 +330,8 @@ ACTIVE_CTRL_FIELD = "Active Control Set" ADAPTIVE_INPUT_EQ_ENABLE_TX = "AdaptiveInputEqEnableTx" -ADAPTIVE_INPUT_EQ_RECALLED_TX = "AdaptiveInputEqRecalledTx" +ADAPTIVE_INPUT_EQ_RECALLED_TX1_4 = "AdaptiveInputEqRecalled_1_4_Tx" +ADAPTIVE_INPUT_EQ_RECALLED_TX5_8 = "AdaptiveInputEqRecalled_5_8_Tx" FIXED_INPUT_EQ_TARGET_TX = "FixedInputEqTargetTx" CDR_ENABLE_TX = "CDREnableTx" CDR_ENABLE_RX = "CDREnableRx" From 496d9d4d98e9198c05c7bde9aa87c85199141100 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Thu, 3 Aug 2023 23:47:36 -0700 Subject: [PATCH 30/42] Update cmis.py --- sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) 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 f83c658d4..2f12c9c13 100644 --- a/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py @@ -503,13 +503,10 @@ def __init__(self, codes): ) - self.STAGED_CTRL0_TX_CTRL = RegGroupField(consts.STAGED_CTRL0_TX_CTRL_FIELD, + self.STAGED_CTRL0_TX_RX_CTRL = RegGroupField(consts.STAGED_CTRL0_TX_RX_CTRL_FIELD, NumberRegField(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, self.getaddr(0x10, 153), ro=False), - RegGroupField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX, - *(NumberRegField("%s%d" % (consts.ADAPTIVE_INPUT_EQ_RECALLED_TX, lane) , self.getaddr(0x10, 154 + int((lane-1)/4)), ro=False, - *(RegBitField("Bit%d" % bit, bit) for bit in [range(6, 8), range(4, 6), range(2, 4), range(0, 2)][lane%4])) - for lane in range(1, 9)) - ), + NumberRegField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX1_4, self.getaddr(0x10, 154), ro=False), + NumberRegField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX5_8, self.getaddr(0x10, 155), ro=False), RegGroupField(consts.FIXED_INPUT_EQ_TARGET_TX, *(NumberRegField("%s%d" % (consts.FIXED_INPUT_EQ_TARGET_TX, lane) , self.getaddr(0x10, 156 + int((lane-1)/2)), ro=False, *(RegBitField("Bit%d" % bit, bit) for bit in [range(4, 8), range(0, 4)][lane%2])) From 22bcabd61fb07f388d4a7aafc3aa359ef4645799 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Thu, 3 Aug 2023 23:52:13 -0700 Subject: [PATCH 31/42] Update test_cmis.py --- tests/sonic_xcvr/test_cmis.py | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index 0e45c8ba0..198785918 100644 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -2226,10 +2226,11 @@ def test_set_module_si_eq_pre_settings(self): } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff] + mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] self.api.xcvr_eeprom.read.side_effect = mock_resp - self.api.stage_custom_si_settings(0x01, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 1 + self.api.stage_custom_si_settings(0xff, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 8 def test_set_module_si_eq_en_settings(self): optics_si_eq_en = { "AdaptiveInputEqEnableTx": 0 } @@ -2241,21 +2242,25 @@ def test_set_module_si_eq_en_settings(self): self.api.stage_custom_si_settings(0xff, optics_si_dict) assert self.api.xcvr_eeprom.write.call_count == 1 - def test_set_module_si_eq_recall_settings(self): - optics_si_eq_recall_dict = { "AdaptiveInputEqRecalledTx":{ - "AdaptiveInputEqRecalledTx1":0, "AdaptiveInputEqRecalledTx2":0, "AdaptiveInputEqRecalledTx3":0, "AdaptiveInputEqRecalledTx4":0, - "AdaptiveInputEqRecalledTx5":0, "AdaptiveInputEqRecalledTx6":0, "AdaptiveInputEqRecalledTx7":0, "AdaptiveInputEqRecalledTx8":0 } - } - optics_si_dict = { "AdaptiveInputEqRecalledTx":{ - "AdaptiveInputEqRecalledTx1":1, "AdaptiveInputEqRecalledTx2":1, "AdaptiveInputEqRecalledTx3":1, "AdaptiveInputEqRecalledTx4":1, - "AdaptiveInputEqRecalledTx5":1, "AdaptiveInputEqRecalledTx6":1, "AdaptiveInputEqRecalledTx7":1, "AdaptiveInputEqRecalledTx8":1 } - } + def test_set_module_si_eq_recall1_4_settings(self): + optics_si_eq_recall_dict = { "AdaptiveInputEqRecalled_1_4_Tx": 0} + optics_si_dict = { "AdaptiveInputEqRecalled_1_4_Tx":255 } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff] + mock_resp = [optics_si_eq_recall_dict, 0x0, 0xff, 0x55, 0x55, 0x55, 0x55] self.api.xcvr_eeprom.read.side_effect = mock_resp - self.api.stage_custom_si_settings(0x0f, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 1 + self.api.stage_custom_si_settings(0xf, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 4 + + def test_set_module_si_eq_recall5_8_settings(self): + optics_si_eq_recall_dict = { "AdaptiveInputEqRecalled_5_8_Tx": 0} + optics_si_dict = { "AdaptiveInputEqRecalled_5_8_Tx":255 } + self.api.xcvr_eeprom.read = MagicMock() + self.api.xcvr_eeprom.write = MagicMock() + mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff, 0xAA, 0xAA, 0xAA, 0xAA] + self.api.xcvr_eeprom.read.side_effect = mock_resp + self.api.stage_custom_si_settings(0xf0, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 4 def test_set_module_si_eq_post_settings(self): optics_si_eq_pre_dict = { "OutputEqPostCursorTargetRx":{ From 3dbfbca6e1804c3a856fe681621faa4149ce3c51 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Fri, 4 Aug 2023 00:05:05 -0700 Subject: [PATCH 32/42] Update cmis.py --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index bd00dd965..8a2e41aea 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2228,7 +2228,7 @@ def get_rx_output_eq_post_ctrl_supported(self): def scs_nibble_write(self, val, si_param, lane): ''' This function sets nibble data in byte data - '' + ''' if (lane%2) == 0: val = (val << 4) | pre_val si_key_lane = "{}{}".format(si_param, lane) From 55fb68552602451c51608db8ff54c7db1d053cb0 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Fri, 4 Aug 2023 00:51:37 -0700 Subject: [PATCH 33/42] Update cmis.py --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 8a2e41aea..1a4055fad 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2225,7 +2225,7 @@ def get_rx_output_eq_post_ctrl_supported(self): return False return rx_post_support - def scs_nibble_write(self, val, si_param, lane): + def scs_nibble_write(self, val, pre_val, si_param, lane): ''' This function sets nibble data in byte data ''' From 4917b2c00f2331077f05e13bacc9b5d6cd4be5e2 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Sun, 6 Aug 2023 14:50:32 -0700 Subject: [PATCH 34/42] Fix nibble write api --- .../sonic_xcvr/api/public/cmis.py | 52 ++++++++++++++----- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 1a4055fad..4a2aff4a5 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2230,7 +2230,13 @@ def scs_nibble_write(self, val, pre_val, si_param, lane): This function sets nibble data in byte data ''' if (lane%2) == 0: - val = (val << 4) | pre_val + pos = 4 + else: + pos = 0 + mask = 0b1111 + val &= mask + mask <<= pos + val = (pre_val & ~mask) | (val << pos) si_key_lane = "{}{}".format(si_param, lane) return self.xcvr_eeprom.write(si_key_lane, val) @@ -2252,9 +2258,14 @@ def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): pre_val = 0 if (lane%2) == 0: pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane-1) - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) - if pre_val is None: - return False + pre_pos = 0 + else: + pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane+1) + pre_pos = 4 + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + if pre_val is None: + return False + pre_val <<= pre_pos if not self.scs_nibble_write(val, pre_val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane): return False return True @@ -2277,9 +2288,14 @@ def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): pre_val = 0 if (lane%2) == 0: pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane-1) - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) - if pre_val is None: - return False + pre_pos = 0 + else: + pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane+1) + pre_pos = 4 + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + if pre_val is None: + return False + pre_val <<= pre_pos if not self.scs_nibble_write(val, pre_val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane): return False return True @@ -2302,9 +2318,14 @@ def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): pre_val = 0 if (lane%2) == 0: pre_si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane-1) - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) - if pre_val is None: - return False + pre_pos = 0 + else: + pre_si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane+1) + pre_pos = 4 + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + if pre_val is None: + return False + pre_val <<= pre_pos if not self.scs_nibble_write(val, pre_val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane): return False return True @@ -2327,9 +2348,14 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): pre_val = 0 if (lane%2) == 0: pre_si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane-1) - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) - if pre_val is None: - return False + pre_pos = 0 + else: + pre_si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane+1) + pre_pos = 4 + pre_val = self.xcvr_eeprom.read(pre_si_key_lane) + if pre_val is None: + return False + pre_val <<= pre_pos if not self.scs_nibble_write(val, pre_val, consts.FIXED_INPUT_EQ_TARGET_TX, lane): return False return True From adf976794059e8b6d58912e96f77d9ae08cf22bd Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Sun, 6 Aug 2023 15:45:03 -0700 Subject: [PATCH 35/42] Update cmis.py --- .../sonic_xcvr/api/public/cmis.py | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 4a2aff4a5..043de9ba9 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2244,16 +2244,16 @@ def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): ''' This function applies RX output eq pre cursor settings ''' + rx_pre_max_val = self.get_rx_output_eq_pre_max_val() + if rx_pre_max_val is None: + return False for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: continue lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) val = si_settings[si_key_lane] - if val is None: - return False - rx_pre_max_val = self.get_rx_output_eq_pre_max_val() - if rx_pre_max_val is None or val > rx_pre_max_val: + if val is None or val > rx_pre_max_val: return False pre_val = 0 if (lane%2) == 0: @@ -2274,16 +2274,16 @@ def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): ''' This function applies RX output eq post cursor settings ''' + rx_post_max_val = self.get_rx_output_eq_post_max_val() + if rx_post_max_val is None: + return False for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: continue lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) val = si_settings[si_key_lane] - if val is None: - return False - rx_post_max_val = self.get_rx_output_eq_post_max_val() - if rx_post_max_val is None or val > rx_post_max_val: + if val is None or val > rx_post_max_val: return False pre_val = 0 if (lane%2) == 0: @@ -2304,16 +2304,16 @@ def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): ''' This function applies RX output amp settings ''' + rx_amp_max_val = self.get_rx_output_amp_max_val() + if rx_amp_max_val is None: + return False for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: continue lane = lane+1 si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) val = si_settings[si_key_lane] - if val is None: - return False - rx_amp_max_val = self.get_rx_output_amp_max_val() - if rx_amp_max_val is None or val > rx_amp_max_val: + if val is None or val > rx_amp_max_val: return False pre_val = 0 if (lane%2) == 0: @@ -2334,16 +2334,16 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): ''' This function applies fixed TX input si settings ''' + tx_fixed_input = self.get_tx_input_eq_max_val() + if tx_fixed_input is None: + return False for lane in range(self.NUM_CHANNELS): if ((1 << lane) & host_lanes_mask) == 0: continue lane = lane+1 si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane) val = si_settings[si_key_lane] - if val is None: - return False - tx_fixed_input = self.get_tx_input_eq_max_val() - if tx_fixed_input is None or val > tx_fixed_input: + if val is None or val > tx_fixed_input: return False pre_val = 0 if (lane%2) == 0: From 038bc8c39fa322f3d060ba0667f7a7c10075df38 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Sun, 6 Aug 2023 16:03:36 -0700 Subject: [PATCH 36/42] Update test_cmis.py --- tests/sonic_xcvr/test_cmis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index 198785918..487d8d5ee 100644 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -2273,7 +2273,7 @@ def test_set_module_si_eq_post_settings(self): } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff] + mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff, 0xff] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0x01, optics_si_dict) assert self.api.xcvr_eeprom.write.call_count == 1 From 9f372e890647e5e020c63159db83ee84166e6b3d Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 9 Aug 2023 21:25:46 -0700 Subject: [PATCH 37/42] Remove byte read --- .../sonic_xcvr/api/public/cmis.py | 245 ++++++------------ 1 file changed, 73 insertions(+), 172 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 043de9ba9..e223df474 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2225,22 +2225,23 @@ def get_rx_output_eq_post_ctrl_supported(self): return False return rx_post_support - def scs_nibble_write(self, val, pre_val, si_param, lane): + def scs_lane_write(self, si_param, host_lanes_mask, si_settings_dict): ''' - This function sets nibble data in byte data + This function sets each lane val based on SI param ''' - if (lane%2) == 0: - pos = 4 - else: - pos = 0 - mask = 0b1111 - val &= mask - mask <<= pos - val = (pre_val & ~mask) | (val << pos) - si_key_lane = "{}{}".format(si_param, lane) - return self.xcvr_eeprom.write(si_key_lane, val) + for lane in range(self.NUM_CHANNELS): + if ((1 << lane) & host_lanes_mask) == 0: + continue + lane = lane+1 + si_param_lane = "{}{}".format(si_param, lane) + si_param_lane_val = si_settings_dict[si_param_lane] + if si_param_lane_val is None: + return False + if not self.xcvr_eeprom.write(si_param_lane, si_param_lane_val): + return False + return True - def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): + def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings_dict): ''' This function applies RX output eq pre cursor settings ''' @@ -2251,26 +2252,15 @@ def stage_output_eq_pre_cursor_target_rx(self, host_lanes_mask, si_settings): if ((1 << lane) & host_lanes_mask) == 0: continue lane = lane+1 - si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) - val = si_settings[si_key_lane] - if val is None or val > rx_pre_max_val: - return False - pre_val = 0 - if (lane%2) == 0: - pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane-1) - pre_pos = 0 - else: - pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane+1) - pre_pos = 4 - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) - if pre_val is None: + si_param_lane = "{}{}".format(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) + si_param_lane_val = si_settings_dict[si_param_lane] + if si_param_lane_val is None or si_param_lane_val > rx_pre_max_val: return False - pre_val <<= pre_pos - if not self.scs_nibble_write(val, pre_val, consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane): + if not self.xcvr_eeprom.write(si_param_lane, si_param_lane_val): return False return True - def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): + def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings_dict): ''' This function applies RX output eq post cursor settings ''' @@ -2281,26 +2271,15 @@ def stage_output_eq_post_cursor_target_rx(self, host_lanes_mask, si_settings): if ((1 << lane) & host_lanes_mask) == 0: continue lane = lane+1 - si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) - val = si_settings[si_key_lane] - if val is None or val > rx_post_max_val: + si_param_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) + si_param_lane_val = si_settings_dict[si_param_lane] + if si_param_lane_val is None or si_param_lane_val > rx_post_max_val: return False - pre_val = 0 - if (lane%2) == 0: - pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane-1) - pre_pos = 0 - else: - pre_si_key_lane = "{}{}".format(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane+1) - pre_pos = 4 - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) - if pre_val is None: - return False - pre_val <<= pre_pos - if not self.scs_nibble_write(val, pre_val, consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane): + if not self.xcvr_eeprom.write(si_param_lane, si_param_lane_val): return False return True - def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): + def stage_output_amp_target_rx(self, host_lanes_mask, si_settings_dict): ''' This function applies RX output amp settings ''' @@ -2311,26 +2290,15 @@ def stage_output_amp_target_rx(self, host_lanes_mask, si_settings): if ((1 << lane) & host_lanes_mask) == 0: continue lane = lane+1 - si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) - val = si_settings[si_key_lane] - if val is None or val > rx_amp_max_val: + si_param_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) + si_param_lane_val = si_settings_dict[si_param_lane] + if si_param_lane_val is None or si_param_lane_val > rx_amp_max_val: return False - pre_val = 0 - if (lane%2) == 0: - pre_si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane-1) - pre_pos = 0 - else: - pre_si_key_lane = "{}{}".format(consts.OUTPUT_AMPLITUDE_TARGET_RX, lane+1) - pre_pos = 4 - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) - if pre_val is None: - return False - pre_val <<= pre_pos - if not self.scs_nibble_write(val, pre_val, consts.OUTPUT_AMPLITUDE_TARGET_RX, lane): + if not self.xcvr_eeprom.write(si_param_lane, si_param_lane_val): return False return True - def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): + def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings_dict): ''' This function applies fixed TX input si settings ''' @@ -2341,143 +2309,86 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings): if ((1 << lane) & host_lanes_mask) == 0: continue lane = lane+1 - si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane) - val = si_settings[si_key_lane] - if val is None or val > tx_fixed_input: + si_param_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane) + si_param_lane_val = si_settings[si_param_lane] + if si_param_lane_val is None or si_param_lane_val > tx_fixed_input: return False - pre_val = 0 - if (lane%2) == 0: - pre_si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane-1) - pre_pos = 0 - else: - pre_si_key_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane+1) - pre_pos = 4 - pre_val = self.xcvr_eeprom.read(pre_si_key_lane) - if pre_val is None: - return False - pre_val <<= pre_pos - if not self.scs_nibble_write(val, pre_val, consts.FIXED_INPUT_EQ_TARGET_TX, lane): + if not self.xcvr_eeprom.write(si_param_lane, si_param_lane_val): return False return True - def tx_recall_byte_write(self, si_param, pos, si_val_lane, tx_recall_val): - ''' - This function sets 2 bits in byte data based on lane number - ''' - mask = 0b11 - mask <<= pos - val = (tx_recall_val & ~mask) | (si_val_lane << pos) - return self.xcvr_eeprom.write(si_param, val) - - def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_key, si_val): + def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings_dict): ''' This function applies adaptive TX input recall si settings. - In this function, we read byte data and modify lane associated bits - (ex: bit 0 and 1 for lane 1; bit 2 and 3 for lane 2 .. etc) and write byte data ''' - for lane in range(self.NUM_CHANNELS): - if ((1 << lane) & host_lanes_mask) == 0: - continue - lane %= 4 - tx_recall_val = self.xcvr_eeprom.read(si_key) - if tx_recall_val is None: - return False - pos = lane*2 - mask = 0b11 - si_val_lane = 0x3 & ((si_val >> pos) & mask) - if not self.tx_recall_byte_write(si_key, pos, si_val_lane, tx_recall_val): - return False - return True - - def scs_byte_write(self, si_key, host_lanes_mask, si_val, val): - nibble_val = si_val & host_lanes_mask - for lane in range(self.NUM_CHANNELS): - mask = (1 << lane) - if (mask & host_lanes_mask) == 0: - continue - if nibble_val: - val |= mask - else: - val &= ~mask - return self.xcvr_eeprom.write(si_key, val) + if si_settings_dict is None: + return False + return self.scs_lane_write(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX, host_lanes_mask, si_settings_dict) - def stage_adaptive_input_eq_enable_tx(self, host_lanes_mask, si_val): + def stage_adaptive_input_eq_enable_tx(self, host_lanes_mask, si_settings_dict): ''' This function applies adaptive TX input enable si settings ''' - if si_val is None: - return False - val = self.xcvr_eeprom.read(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX) - if val is None: + if si_settings_dict is None: return False - return self.scs_byte_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_val, val) + return self.scs_lane_write(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, host_lanes_mask, si_settings_dict) - def stage_cdr_tx(self, host_lanes_mask, si_val): + def stage_cdr_tx(self, host_lanes_mask, si_settings_dict): ''' This function applies TX CDR si settings ''' - if si_val is None: + if si_settings_dict is None: return False - val = self.xcvr_eeprom.read(consts.CDR_ENABLE_TX) - if val is None: - return False - return self.scs_byte_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_val, val) + return self.scs_lane_write(consts.CDR_ENABLE_TX, host_lanes_mask, si_settings_dict) - def stage_cdr_rx(self, host_lanes_mask, si_val): + def stage_cdr_rx(self, host_lanes_mask, si_settings_dict): ''' This function applies RX CDR si settings ''' - if si_val is None: - return False - val = self.xcvr_eeprom.read(consts.CDR_ENABLE_RX) - if val is None: + if si_settings_dict is None: return False - return self.scs_byte_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_val, val) + return self.scs_lane_write(consts.CDR_ENABLE_RX, host_lanes_mask, si_settings_dict) - def stage_rx_si_settings(self, host_lanes_mask, si_settings): - for si_keys in si_settings: - if si_keys == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX: + def stage_rx_si_settings(self, host_lanes_mask, si_settings_dict): + for si_param in si_settings_dict: + if si_param == consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX: if self.get_rx_output_eq_pre_ctrl_supported(): - if not self.stage_output_eq_pre_cursor_target_rx(host_lanes_mask, si_settings[si_keys]): + if not self.stage_output_eq_pre_cursor_target_rx(host_lanes_mask, si_settings_dict[si_param]): return False - elif si_keys == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX: + elif si_param == consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX: if self.get_rx_output_eq_post_ctrl_supported(): - if not self.stage_output_eq_post_cursor_target_rx(host_lanes_mask, si_settings[si_keys]): + if not self.stage_output_eq_post_cursor_target_rx(host_lanes_mask, si_settings_dict[si_param]): return False - elif si_keys == consts.OUTPUT_AMPLITUDE_TARGET_RX: + elif si_param == consts.OUTPUT_AMPLITUDE_TARGET_RX: if self.get_rx_ouput_amp_ctrl_supported(): - if not self.stage_output_amp_target_rx(host_lanes_mask, si_settings[si_keys]): + if not self.stage_output_amp_target_rx(host_lanes_mask, si_settings_dict[si_param]): return False - elif si_keys == consts.CDR_ENABLE_RX: + elif si_param == consts.CDR_ENABLE_RX: if self.get_rx_cdr_supported(): - if not self.stage_cdr_rx(host_lanes_mask, si_settings[si_keys]): + if not self.stage_cdr_rx(host_lanes_mask, si_settings_dict[si_param]): return False else: return False return True - def stage_tx_si_settings(self, host_lanes_mask, si_settings): - for si_keys in si_settings: - if si_keys == consts.FIXED_INPUT_EQ_TARGET_TX: + def stage_tx_si_settings(self, host_lanes_mask, si_settings_dict): + for si_param in si_settings_dict: + if si_param == consts.FIXED_INPUT_EQ_TARGET_TX: if self.get_tx_input_eq_fixed_supported(): - if not self.stage_fixed_input_target_tx(host_lanes_mask, si_settings[si_keys]): + if not self.stage_fixed_input_target_tx(host_lanes_mask, si_settings_dict[si_param]): return False - elif si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX1_4 : - if ((host_lanes_mask & 0xf) and (self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported())): - if not self.stage_adaptive_input_recall_tx(host_lanes_mask, si_keys, si_settings[si_keys]): + elif si_param == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX: + if self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported(): + if not self.stage_adaptive_input_recall_tx(host_lanes_mask, si_settings_dict[si_param]): return False - elif si_keys == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX5_8: - if ((host_lanes_mask & 0xf0) and (self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported())): - if not self.stage_adaptive_input_recall_tx(host_lanes_mask, si_keys, si_settings[si_keys]): - return False - elif si_keys == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX: + elif si_param == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX: if self.get_tx_input_adaptive_eq_supported(): - if not self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings[si_keys]): + if not self.stage_adaptive_input_eq_enable_tx(host_lanes_mask, si_settings_dict[si_param]): return False - elif si_keys == consts.CDR_ENABLE_TX: + elif si_param == consts.CDR_ENABLE_TX: if self.get_tx_cdr_supported(): - if not self.stage_cdr_tx(host_lanes_mask, si_settings[si_keys]): + if not self.stage_cdr_tx(host_lanes_mask, si_settings_dict[si_param]): return False else: return False @@ -2485,30 +2396,20 @@ def stage_tx_si_settings(self, host_lanes_mask, si_settings): return True def stage_custom_si_settings(self, host_lanes_mask, optics_si_dict): - # Read and cache the existing SCS0 TX/RX CTRL data - si_settings = self.xcvr_eeprom.read(consts.STAGED_CTRL0_TX_RX_CTRL_FIELD) - - if si_settings is None: - return False - # Replace the new values with cached SI values - for si_keys in optics_si_dict: - if si_keys in si_settings: - si_settings[si_keys] = optics_si_dict[si_keys] - # Create TX/RX specific si_dict rx_si_settings = {} tx_si_settings = {} - for si_keys in si_settings: - if si_keys.endswith("Tx"): - tx_si_settings[si_keys] = si_settings[si_keys] - elif si_keys.endswith("Rx"): - rx_si_settings[si_keys] = si_settings[si_keys] + for si_param in optics_si_dict: + if si_param.endswith("Tx"): + tx_si_settings[si_param] = optics_si_dict[si_param] + elif si_param.endswith("Rx"): + rx_si_settings[si_param] = optics_si_dict[si_param] # stage RX si settings if not self.stage_rx_si_settings(host_lanes_mask, rx_si_settings): return False - #stage TX si settings + # stage TX si settings if not self.stage_tx_si_settings(host_lanes_mask, tx_si_settings): return False From 51f1822ee6ccdc2f5f1ec435a2e0e9fb1db2ddf1 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 9 Aug 2023 21:28:46 -0700 Subject: [PATCH 38/42] Replace RegBitField with RegBitsField --- .../sonic_xcvr/mem_maps/public/cmis.py | 101 ++++++++++++++---- 1 file changed, 82 insertions(+), 19 deletions(-) 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 2f12c9c13..140faeafd 100644 --- a/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/mem_maps/public/cmis.py @@ -11,6 +11,7 @@ HexRegField, NumberRegField, RegBitField, + RegBitsField, RegGroupField, StringRegField, ) @@ -504,32 +505,94 @@ def __init__(self, codes): ) self.STAGED_CTRL0_TX_RX_CTRL = RegGroupField(consts.STAGED_CTRL0_TX_RX_CTRL_FIELD, - NumberRegField(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, self.getaddr(0x10, 153), ro=False), - NumberRegField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX1_4, self.getaddr(0x10, 154), ro=False), - NumberRegField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX5_8, self.getaddr(0x10, 155), ro=False), - RegGroupField(consts.FIXED_INPUT_EQ_TARGET_TX, - *(NumberRegField("%s%d" % (consts.FIXED_INPUT_EQ_TARGET_TX, lane) , self.getaddr(0x10, 156 + int((lane-1)/2)), ro=False, - *(RegBitField("Bit%d" % bit, bit) for bit in [range(4, 8), range(0, 4)][lane%2])) + NumberRegField(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX, self.getaddr(0x10, 153), + *(RegBitsField(consts.ADAPTIVE_INPUT_EQ_ENABLE_TX + str(lane), bitpos=(lane-1), ro=False, size=1) for lane in range(1, 9)) ), - NumberRegField(consts.CDR_ENABLE_TX, self.getaddr(0x10, 160), ro=False), - NumberRegField(consts.CDR_ENABLE_RX, self.getaddr(0x10, 161), ro=False), - RegGroupField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, - *(NumberRegField("%s%d" % (consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX, lane) , self.getaddr(0x10, 162 + int((lane-1)/2)), ro=False, - *(RegBitField("Bit%d" % bit, bit) for bit in [range(4, 8), range(0, 4)][lane%2])) - for lane in range(1, 9)) + NumberRegField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX1_4, self.getaddr(0x10, 154), + RegBitsField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX1, bitpos=0, ro=False, size=2), + RegBitsField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX2, bitpos=2, ro=False, size=2), + RegBitsField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX3, bitpos=4, ro=False, size=2), + RegBitsField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX4, bitpos=6, ro=False, size=2), ), - RegGroupField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, - *(NumberRegField("%s%d" % (consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX, lane) , self.getaddr(0x10, 166 + int((lane-1)/2)), ro=False, - *(RegBitField("Bit%d" % bit, bit) for bit in [range(4, 8), range(0, 4)][lane%2])) + NumberRegField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX5_8, self.getaddr(0x10, 155), + RegBitsField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX5, bitpos=0, ro=False, size=2), + RegBitsField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX6, bitpos=2, ro=False, size=2), + RegBitsField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX7, bitpos=4, ro=False, size=2), + RegBitsField(consts.ADAPTIVE_INPUT_EQ_RECALLED_TX8, bitpos=6, ro=False, size=2), + ), + NumberRegField(consts.FIXED_INPUT_EQ_TARGET_TX1_2, self.getaddr(0x10, 156), + RegBitsField(consts.FIXED_INPUT_EQ_TARGET_TX1, bitpos=0, ro=False, size=4), + RegBitsField(consts.FIXED_INPUT_EQ_TARGET_TX2, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.FIXED_INPUT_EQ_TARGET_TX3_4, self.getaddr(0x10, 157), + RegBitsField(consts.FIXED_INPUT_EQ_TARGET_TX3, bitpos=0, ro=False, size=4), + RegBitsField(consts.FIXED_INPUT_EQ_TARGET_TX4, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.FIXED_INPUT_EQ_TARGET_TX5_6, self.getaddr(0x10, 158), + RegBitsField(consts.FIXED_INPUT_EQ_TARGET_TX5, bitpos=0, ro=False, size=4), + RegBitsField(consts.FIXED_INPUT_EQ_TARGET_TX6, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.FIXED_INPUT_EQ_TARGET_TX7_8, self.getaddr(0x10, 159), + RegBitsField(consts.FIXED_INPUT_EQ_TARGET_TX7, bitpos=0, ro=False, size=4), + RegBitsField(consts.FIXED_INPUT_EQ_TARGET_TX8, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.CDR_ENABLE_TX, self.getaddr(0x10, 160), + *(RegBitsField(consts.CDR_ENABLE_TX + str(lane), bitpos=(lane-1), ro=False, size=1) for lane in range(1, 9)) ), - - RegGroupField(consts.OUTPUT_AMPLITUDE_TARGET_RX, - *(NumberRegField("%s%d" % (consts.OUTPUT_AMPLITUDE_TARGET_RX, lane) , self.getaddr(0x10, 170 + int((lane-1)/2)), ro=False, - *(RegBitField("Bit%d" % bit, bit) for bit in [range(4, 8), range(0, 4)][lane%2])) + NumberRegField(consts.CDR_ENABLE_RX, self.getaddr(0x10, 161), + *(RegBitsField(consts.CDR_ENABLE_RX + str(lane), bitpos=(lane-1), ro=False, size=1) for lane in range(1, 9)) ), + NumberRegField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX1_2, self.getaddr(0x10, 162), + RegBitsField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX1, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX2, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX3_4, self.getaddr(0x10, 163), + RegBitsField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX3, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX4, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX5_6, self.getaddr(0x10, 164), + RegBitsField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX5, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX6, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX7_8, self.getaddr(0x10, 165), + RegBitsField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX7, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_EQ_PRE_CURSOR_TARGET_RX8, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX1_2, self.getaddr(0x10, 166), + RegBitsField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX1, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX2, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX3_4, self.getaddr(0x10, 167), + RegBitsField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX3, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX4, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX5_6, self.getaddr(0x10, 168), + RegBitsField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX5, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX6, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX7_8, self.getaddr(0x10, 169), + RegBitsField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX7, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_EQ_POST_CURSOR_TARGET_RX8, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_AMPLITUDE_TARGET_RX1_2, self.getaddr(0x10, 170), + RegBitsField(consts.OUTPUT_AMPLITUDE_TARGET_RX1, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_AMPLITUDE_TARGET_RX2, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_AMPLITUDE_TARGET_RX3_4, self.getaddr(0x10, 171), + RegBitsField(consts.OUTPUT_AMPLITUDE_TARGET_RX3, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_AMPLITUDE_TARGET_RX4, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_AMPLITUDE_TARGET_RX5_6, self.getaddr(0x10, 172), + RegBitsField(consts.OUTPUT_AMPLITUDE_TARGET_RX5, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_AMPLITUDE_TARGET_RX6, bitpos=4, ro=False, size=4) + ), + NumberRegField(consts.OUTPUT_AMPLITUDE_TARGET_RX7_8, self.getaddr(0x10, 173), + RegBitsField(consts.OUTPUT_AMPLITUDE_TARGET_RX7, bitpos=0, ro=False, size=4), + RegBitsField(consts.OUTPUT_AMPLITUDE_TARGET_RX8, bitpos=4, ro=False, size=4) + ), ) # TODO: add remaining fields From 03c57ef66d5f18a059cb88b3fdee78dc6bac861a Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 9 Aug 2023 21:30:26 -0700 Subject: [PATCH 39/42] Update consts.py --- .../sonic_xcvr/fields/consts.py | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/fields/consts.py b/sonic_platform_base/sonic_xcvr/fields/consts.py index a2682fafc..e9e250a32 100644 --- a/sonic_platform_base/sonic_xcvr/fields/consts.py +++ b/sonic_platform_base/sonic_xcvr/fields/consts.py @@ -330,14 +330,71 @@ ACTIVE_CTRL_FIELD = "Active Control Set" ADAPTIVE_INPUT_EQ_ENABLE_TX = "AdaptiveInputEqEnableTx" -ADAPTIVE_INPUT_EQ_RECALLED_TX1_4 = "AdaptiveInputEqRecalled_1_4_Tx" -ADAPTIVE_INPUT_EQ_RECALLED_TX5_8 = "AdaptiveInputEqRecalled_5_8_Tx" +ADAPTIVE_INPUT_EQ_RECALLED_TX = "AdaptiveInputEqRecalledTx" +ADAPTIVE_INPUT_EQ_RECALLED_TX1_4 = "AdaptiveInputEqRecalledTx1_4" +ADAPTIVE_INPUT_EQ_RECALLED_TX1 = "AdaptiveInputEqRecalledTx1" +ADAPTIVE_INPUT_EQ_RECALLED_TX2 = "AdaptiveInputEqRecalledTx2" +ADAPTIVE_INPUT_EQ_RECALLED_TX3 = "AdaptiveInputEqRecalledTx3" +ADAPTIVE_INPUT_EQ_RECALLED_TX4 = "AdaptiveInputEqRecalledTx4" +ADAPTIVE_INPUT_EQ_RECALLED_TX5_8 = "AdaptiveInputEqRecalledTx5_8" +ADAPTIVE_INPUT_EQ_RECALLED_TX5 = "AdaptiveInputEqRecalledTx5" +ADAPTIVE_INPUT_EQ_RECALLED_TX6 = "AdaptiveInputEqRecalledTx6" +ADAPTIVE_INPUT_EQ_RECALLED_TX7 = "AdaptiveInputEqRecalledTx7" +ADAPTIVE_INPUT_EQ_RECALLED_TX8 = "AdaptiveInputEqRecalledTx8" FIXED_INPUT_EQ_TARGET_TX = "FixedInputEqTargetTx" +FIXED_INPUT_EQ_TARGET_TX1_2 = "FixedInputEqTargetTx1_2" +FIXED_INPUT_EQ_TARGET_TX1 = "FixedInputEqTargetTx1" +FIXED_INPUT_EQ_TARGET_TX2 = "FixedInputEqTargetTx2" +FIXED_INPUT_EQ_TARGET_TX3_4 = "FixedInputEqTargetTx3_4" +FIXED_INPUT_EQ_TARGET_TX3 = "FixedInputEqTargetTx3" +FIXED_INPUT_EQ_TARGET_TX4 = "FixedInputEqTargetTx4" +FIXED_INPUT_EQ_TARGET_TX5_6 = "FixedInputEqTargetTx5_6" +FIXED_INPUT_EQ_TARGET_TX5 = "FixedInputEqTargetTx5" +FIXED_INPUT_EQ_TARGET_TX6 = "FixedInputEqTargetTx6" +FIXED_INPUT_EQ_TARGET_TX7_8 = "FixedInputEqTargetTx7_8" +FIXED_INPUT_EQ_TARGET_TX7 = "FixedInputEqTargetTx7" +FIXED_INPUT_EQ_TARGET_TX8 = "FixedInputEqTargetTx8" CDR_ENABLE_TX = "CDREnableTx" CDR_ENABLE_RX = "CDREnableRx" OUTPUT_EQ_PRE_CURSOR_TARGET_RX = "OutputEqPreCursorTargetRx" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX1_2 = "OutputEqPreCursorTargetRx1_2" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX1 = "OutputEqPreCursorTargetRx1" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX2 = "OutputEqPreCursorTargetRx2" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX3_4 = "OutputEqPreCursorTargetRx3_4" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX3 = "OutputEqPreCursorTargetRx3" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX4 = "OutputEqPreCursorTargetRx4" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX5_6 = "OutputEqPreCursorTargetRx5_6" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX5 = "OutputEqPreCursorTargetRx5" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX6 = "OutputEqPreCursorTargetRx6" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX7_8 = "OutputEqPreCursorTargetRx7_8" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX7 = "OutputEqPreCursorTargetRx7" +OUTPUT_EQ_PRE_CURSOR_TARGET_RX8 = "OutputEqPreCursorTargetRx8" OUTPUT_EQ_POST_CURSOR_TARGET_RX = "OutputEqPostCursorTargetRx" +OUTPUT_EQ_POST_CURSOR_TARGET_RX1_2 = "OutputEqPostCursorTargetRx1_2" +OUTPUT_EQ_POST_CURSOR_TARGET_RX1 = "OutputEqPostCursorTargetRx1" +OUTPUT_EQ_POST_CURSOR_TARGET_RX2 = "OutputEqPostCursorTargetRx2" +OUTPUT_EQ_POST_CURSOR_TARGET_RX3_4 = "OutputEqPostCursorTargetRx3_4" +OUTPUT_EQ_POST_CURSOR_TARGET_RX3 = "OutputEqPostCursorTargetRx3" +OUTPUT_EQ_POST_CURSOR_TARGET_RX4 = "OutputEqPostCursorTargetRx4" +OUTPUT_EQ_POST_CURSOR_TARGET_RX5_6 = "OutputEqPostCursorTargetRx5_6" +OUTPUT_EQ_POST_CURSOR_TARGET_RX5 = "OutputEqPostCursorTargetRx5" +OUTPUT_EQ_POST_CURSOR_TARGET_RX6 = "OutputEqPostCursorTargetRx6" +OUTPUT_EQ_POST_CURSOR_TARGET_RX7_8 = "OutputEqPostCursorTargetRx7_8" +OUTPUT_EQ_POST_CURSOR_TARGET_RX7 = "OutputEqPostCursorTargetRx7" +OUTPUT_EQ_POST_CURSOR_TARGET_RX8 = "OutputEqPostCursorTargetRx8" OUTPUT_AMPLITUDE_TARGET_RX = "OutputAmplitudeTargetRx" +OUTPUT_AMPLITUDE_TARGET_RX1_2 = "OutputAmplitudeTargetRx1_2" +OUTPUT_AMPLITUDE_TARGET_RX1 = "OutputAmplitudeTargetRx1" +OUTPUT_AMPLITUDE_TARGET_RX2 = "OutputAmplitudeTargetRx2" +OUTPUT_AMPLITUDE_TARGET_RX3_4 = "OutputAmplitudeTargetRx3_4" +OUTPUT_AMPLITUDE_TARGET_RX3 = "OutputAmplitudeTargetRx3" +OUTPUT_AMPLITUDE_TARGET_RX4 = "OutputAmplitudeTargetRx4" +OUTPUT_AMPLITUDE_TARGET_RX5_6 = "OutputAmplitudeTargetRx5_6" +OUTPUT_AMPLITUDE_TARGET_RX5 = "OutputAmplitudeTargetRx5" +OUTPUT_AMPLITUDE_TARGET_RX6 = "OutputAmplitudeTargetRx6" +OUTPUT_AMPLITUDE_TARGET_RX7_8 = "OutputAmplitudeTargetRx7_8" +OUTPUT_AMPLITUDE_TARGET_RX7 = "OutputAmplitudeTargetRx7" +OUTPUT_AMPLITUDE_TARGET_RX8 = "OutputAmplitudeTargetRx8" # C-CMIS From b1532e7783db8caaec790570199168f90a0473af Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 9 Aug 2023 22:15:04 -0700 Subject: [PATCH 40/42] Fix build failure --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index e223df474..8689e8590 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2310,7 +2310,7 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings_dict): continue lane = lane+1 si_param_lane = "{}{}".format(consts.FIXED_INPUT_EQ_TARGET_TX, lane) - si_param_lane_val = si_settings[si_param_lane] + si_param_lane_val = si_settings_dict[si_param_lane] if si_param_lane_val is None or si_param_lane_val > tx_fixed_input: return False if not self.xcvr_eeprom.write(si_param_lane, si_param_lane_val): From a72fb7434f089b964ff0e1d2873fe970db6a94fc Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Wed, 9 Aug 2023 22:17:00 -0700 Subject: [PATCH 41/42] Update test_cmis.py --- tests/sonic_xcvr/test_cmis.py | 87 +++++++++++++---------------------- 1 file changed, 33 insertions(+), 54 deletions(-) diff --git a/tests/sonic_xcvr/test_cmis.py b/tests/sonic_xcvr/test_cmis.py index 487d8d5ee..5b072deb8 100644 --- a/tests/sonic_xcvr/test_cmis.py +++ b/tests/sonic_xcvr/test_cmis.py @@ -2216,118 +2216,97 @@ def test_set_application(self): assert self.api.xcvr_eeprom.write.call_count == self.api.NUM_CHANNELS def test_set_module_si_eq_pre_settings(self): - optics_si_eq_pre_dict = { "OutputEqPreCursorTargetRx":{ - "OutputEqPreCursorTargetRx1":3, "OutputEqPreCursorTargetRx2":3, "OutputEqPreCursorTargetRx3":3, "OutputEqPreCursorTargetRx4":3, - "OutputEqPreCursorTargetRx5":3, "OutputEqPreCursorTargetRx6":3, "OutputEqPreCursorTargetRx7":3, "OutputEqPreCursorTargetRx8":3 } - } optics_si_dict = { "OutputEqPreCursorTargetRx":{ "OutputEqPreCursorTargetRx1":2, "OutputEqPreCursorTargetRx2":2, "OutputEqPreCursorTargetRx3":2, "OutputEqPreCursorTargetRx4":2, "OutputEqPreCursorTargetRx5":2, "OutputEqPreCursorTargetRx6":2, "OutputEqPreCursorTargetRx7":2, "OutputEqPreCursorTargetRx8":2 } } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + mock_resp = [0x1, 0x7] self.api.xcvr_eeprom.read.side_effect = mock_resp - self.api.stage_custom_si_settings(0xff, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 8 + self.api.stage_custom_si_settings(0x01, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 1 def test_set_module_si_eq_en_settings(self): - optics_si_eq_en = { "AdaptiveInputEqEnableTx": 0 } - optics_si_dict = { "AdaptiveInputEqEnableTx": 255 } + optics_si_dict = { "AdaptiveInputEqEnableTx":{ + "AdaptiveInputEqEnableTx1": 2, "AdaptiveInputEqEnableTx2": 2, "AdaptiveInputEqEnableTx3": 2, "AdaptiveInputEqEnableTx4": 2, + "AdaptiveInputEqEnableTx5": 2, "AdaptiveInputEqEnableTx6": 2, "AdaptiveInputEqEnableTx7": 2, "AdaptiveInputEqEnableTx8": 2,} + } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_en, 0xff, 0xff] + mock_resp = [0x1, 0x3] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0xff, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 1 - - def test_set_module_si_eq_recall1_4_settings(self): - optics_si_eq_recall_dict = { "AdaptiveInputEqRecalled_1_4_Tx": 0} - optics_si_dict = { "AdaptiveInputEqRecalled_1_4_Tx":255 } - self.api.xcvr_eeprom.read = MagicMock() - self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_recall_dict, 0x0, 0xff, 0x55, 0x55, 0x55, 0x55] - self.api.xcvr_eeprom.read.side_effect = mock_resp - self.api.stage_custom_si_settings(0xf, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 4 + assert self.api.xcvr_eeprom.write.call_count == 8 - def test_set_module_si_eq_recall5_8_settings(self): - optics_si_eq_recall_dict = { "AdaptiveInputEqRecalled_5_8_Tx": 0} - optics_si_dict = { "AdaptiveInputEqRecalled_5_8_Tx":255 } + def test_set_module_si_eq_recall_settings(self): + optics_si_dict = { "AdaptiveInputEqRecalledTx":{ + "AdaptiveInputEqRecalledTx1":1, "AdaptiveInputEqRecalledTx2":1, "AdaptiveInputEqRecalledTx3":1, "AdaptiveInputEqRecalledTx4":1, + "AdaptiveInputEqRecalledTx5":1, "AdaptiveInputEqRecalledTx6":1, "AdaptiveInputEqRecalledTx7":1, "AdaptiveInputEqRecalledTx8":1 } + } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff, 0xAA, 0xAA, 0xAA, 0xAA] + mock_resp = [0x1] self.api.xcvr_eeprom.read.side_effect = mock_resp - self.api.stage_custom_si_settings(0xf0, optics_si_dict) + self.api.stage_custom_si_settings(0x0f, optics_si_dict) assert self.api.xcvr_eeprom.write.call_count == 4 def test_set_module_si_eq_post_settings(self): - optics_si_eq_pre_dict = { "OutputEqPostCursorTargetRx":{ - "OutputEqPostCursorTargetRx1":3, "OutputEqPostCursorTargetRx2":3, "OutputEqPostCursorTargetRx3":3, "OutputEqPostCursorTargetRx4":3, - "OutputEqPosteCursorTargetRx5":3, "OutputEqPostCursorTargetRx6":3, "OutputEqPostCursorTargetRx7":3, "OutputEqPostCursorTargetRx8":3 } - } optics_si_dict = { "OutputEqPostCursorTargetRx":{ "OutputEqPostCursorTargetRx1":2, "OutputEqPostCursorTargetRx2":2, "OutputEqPostCursorTargetRx3":2, "OutputEqPostCursorTargetRx4":2, "OutputEqPostCursorTargetRx5":2, "OutputEqPostCursorTargetRx6":2, "OutputEqPostCursorTargetRx7":2, "OutputEqPostCursorTargetRx8":2 } } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_pre_dict, 0xff, 0xff, 0xff] + mock_resp = [0x1, 0x7] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0x01, optics_si_dict) assert self.api.xcvr_eeprom.write.call_count == 1 def test_set_module_si_fixed_en_settings(self): - optics_si_eq_en_dict = { "FixedInputEqTargetTx":{ - "FixedInputEqTargetTx1":0, "FixedInputEqTargetTx2":0, "FixedInputEqTargetTx3":0, "FixedInputEqTargetTx4":0, - "FixedInputEqTargetTx5":0, "FixedInputEqTargetTx6":0, "FixedInputEqTargetTx7":0, "FixedInputEqTargetTx8":0 } - } optics_si_dict = { "FixedInputEqTargetTx":{ "FixedInputEqTargetTx1":1, "FixedInputEqTargetTx2":1, "FixedInputEqTargetTx3":1, "FixedInputEqTargetTx4":1, "FixedInputEqTargetTx5":1, "FixedInputEqTargetTx6":1, "FixedInputEqTargetTx7":1, "FixedInputEqTargetTx8":1 } } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_en_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + mock_resp = [0x1, 0x1] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0xff, optics_si_dict) assert self.api.xcvr_eeprom.write.call_count == 8 def test_set_module_cdr_enable_tx_settings(self): - optics_si_cdr_en_tx = { "CDREnableTx": 0 } - optics_si_dict = { "CDREnableTx": 255 } + optics_si_dict = { "CDREnableTx":{ + "CDREnableTx1":1, "CDREnableTx2":1, "CDREnableTx3":1, "CDREnableTx4":1, + "CDREnableTx5":0, "CDREnableTx6":0, "CDREnableTx7":0, "CDREnableTx8":0 } + } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_cdr_en_tx, 0xff, 0xff] + mock_resp = [0x1] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0x0f, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 1 + assert self.api.xcvr_eeprom.write.call_count == 4 def test_set_module_cdr_enable_rx_settings(self): - optics_si_cdr_en_rx = { "CDREnableRx": 255 } - optics_si_dict = { "CDREnableRx": 255} + optics_si_dict = { "CDREnableRx":{ + "CDREnableRx1":1, "CDREnableRx2":1, "CDREnableRx3":1, "CDREnableRx4":1, + "CDREnableRx5":0, "CDREnableRx6":0, "CDREnableRx7":0, "CDREnableRx8":0 } + } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_cdr_en_rx, 0xff, 0xff] + mock_resp = [0x1] self.api.xcvr_eeprom.read.side_effect = mock_resp - self.api.stage_custom_si_settings(0x01, optics_si_dict) - assert self.api.xcvr_eeprom.write.call_count == 1 - + self.api.stage_custom_si_settings(0xff, optics_si_dict) + assert self.api.xcvr_eeprom.write.call_count == 8 + def test_set_module_OutputAmplitudeTargetRx_settings(self): - optics_si_eq_recall_dict = { "OutputAmplitudeTargetRx":{ - "OutputAmplitudeTargetRx1":0, "OutputAmplitudeTargetRx2":0, "OutputAmplitudeTargetRx3":0, "OutputAmplitudeTargetRx4":0, - "OutputAmplitudeTargetRx5":0, "OutputAmplitudeTargetRx6":0, "OutputAmplitudeTargetRx7":0, "OutputAmplitudeTargetRx8":0 } - } optics_si_dict = { "OutputAmplitudeTargetRx":{ "OutputAmplitudeTargetRx1":1, "OutputAmplitudeTargetRx2":1, "OutputAmplitudeTargetRx3":1, "OutputAmplitudeTargetRx4":1, "OutputAmplitudeTargetRx5":1, "OutputAmplitudeTargetRx6":1, "OutputAmplitudeTargetRx7":1, "OutputAmplitudeTargetRx8":1 } } self.api.xcvr_eeprom.read = MagicMock() self.api.xcvr_eeprom.write = MagicMock() - mock_resp = [optics_si_eq_recall_dict, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + mock_resp = [0x1, 0x7] self.api.xcvr_eeprom.read.side_effect = mock_resp self.api.stage_custom_si_settings(0x0f, optics_si_dict) assert self.api.xcvr_eeprom.write.call_count == 4 From e3c19627f9bd64b8acdec4af409f41aba6eaa389 Mon Sep 17 00:00:00 2001 From: Anoop Kamath <115578705+AnoopKamath@users.noreply.github.com> Date: Fri, 11 Aug 2023 12:21:26 -0700 Subject: [PATCH 42/42] Update cmis.py --- sonic_platform_base/sonic_xcvr/api/public/cmis.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sonic_platform_base/sonic_xcvr/api/public/cmis.py b/sonic_platform_base/sonic_xcvr/api/public/cmis.py index 8689e8590..a677f32ff 100644 --- a/sonic_platform_base/sonic_xcvr/api/public/cmis.py +++ b/sonic_platform_base/sonic_xcvr/api/public/cmis.py @@ -2102,7 +2102,7 @@ def set_application(self, channel, appl_code, ec=0): data|= ec self.xcvr_eeprom.write(addr, data) - def stage_datapath_init(self, channel): + def scs_apply_datapath_init(self, channel): ''' This function applies DataPathInit ''' @@ -2317,7 +2317,7 @@ def stage_fixed_input_target_tx(self, host_lanes_mask, si_settings_dict): return False return True - def stage_adaptive_input_recall_tx(self, host_lanes_mask, si_settings_dict): + def stage_adaptive_input_eq_recall_tx(self, host_lanes_mask, si_settings_dict): ''' This function applies adaptive TX input recall si settings. ''' @@ -2380,7 +2380,7 @@ def stage_tx_si_settings(self, host_lanes_mask, si_settings_dict): return False elif si_param == consts.ADAPTIVE_INPUT_EQ_RECALLED_TX: if self.get_tx_input_recall_buf1_supported() or self.get_tx_input_recall_buf2_supported(): - if not self.stage_adaptive_input_recall_tx(host_lanes_mask, si_settings_dict[si_param]): + if not self.stage_adaptive_input_eq_recall_tx(host_lanes_mask, si_settings_dict[si_param]): return False elif si_param == consts.ADAPTIVE_INPUT_EQ_ENABLE_TX: if self.get_tx_input_adaptive_eq_supported():