diff --git a/.gitmodules b/.gitmodules index 383455ec62b..b4079382363 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,7 +9,7 @@ url = https://github.com/sonic-net/sonic-sairedis [submodule "sonic-swss"] path = src/sonic-swss - url = https://github.com/sonic-net/sonic-swss + url = https://github.com/nvidia-sonic/sonic-swss [submodule "src/p4c-bm/p4c-bm"] path = platform/p4/p4c-bm/p4c-bm url = https://github.com/krambn/p4c-bm @@ -30,7 +30,7 @@ url = https://github.com/p4lang/ptf.git [submodule "src/sonic-utilities"] path = src/sonic-utilities - url = https://github.com/sonic-net/sonic-utilities + url = https://github.com/nvidia-sonic/sonic-utilities [submodule "platform/broadcom/sonic-platform-modules-arista"] path = platform/broadcom/sonic-platform-modules-arista url = https://github.com/aristanetworks/sonic diff --git a/build_image.sh b/build_image.sh index 2ef9be09756..41433a15724 100755 --- a/build_image.sh +++ b/build_image.sh @@ -162,6 +162,10 @@ elif [ "$IMAGE_TYPE" = "raw" ]; then echo "The raw image is in $OUTPUT_RAW_IMAGE" elif [ "$IMAGE_TYPE" = "kvm" ]; then + if [ "$TARGET_MACHINE" = "mellanox" ]; then + echo "Enable Mellanox KVM build" + export MLNX_KVM_IMAGE="yes" + fi generate_device_list "./installer/platforms_asic" diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 2e1e716b0a9..2742cb3dcac 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -1070,6 +1070,7 @@ declare -rA FW_FILE_MAP=( \ [$MLNX_SPC2_FW_FILE]="fw-SPC2.mfa" \ [$MLNX_SPC3_FW_FILE]="fw-SPC3.mfa" \ [$MLNX_SPC4_FW_FILE]="fw-SPC4.mfa" \ + [$MLNX_SPC5_FW_FILE]="fw-SPC5.mfa" \ ) sudo mkdir -p $FILESYSTEM_ROOT/$PLATFORM_DIR/fw/asic/ sudo mkdir -p $FILESYSTEM_ROOT_ETC/mlnx/ diff --git a/install_sonic.py b/install_sonic.py index 2397a6d6164..f0dd434c537 100755 --- a/install_sonic.py +++ b/install_sonic.py @@ -5,21 +5,66 @@ import sys import time +class OnieInterface: + """ONiE Telnet Interface""" + + #KEY_UP = '\x1b[A' + KEY_DOWN = '\x1b[B' + #KEY_RIGHT = '\x1b[C' + #KEY_LEFT = '\x1b[D' + + ONIE_INSTALL_OS = 'ONIE: Install OS' + ONIE_CONSOLE = 'Please press Enter to activate this console' + ONIE_RESCUE = 'Rescue Mode Enabled' + ONIE_SHELL = 'ONIE:/ #' + ONIE_PROMPT = 'Do you still wish to install this image?' + + GRUB_SELECTION = 'The highlighted entry will be executed' + + INSTALL_CMD = [ + 'tmpdir=$(mktemp -d)', + 'mount LABEL=INSTALLER $tmpdir', + 'onie-nos-install $tmpdir/onie-installer.bin' + ] + + def __init__(self, telnet_session, arg_list): + self.args = arg_list + self.onie = telnet_session + + def wait_grub(self): + self.onie.expect([self.GRUB_SELECTION]) + + def embed_onie(self): + self.wait_grub() + self.onie.sendline(self.KEY_DOWN) + + def install_os(self): + self.onie.expect([self.ONIE_INSTALL_OS]) + self.wait_grub() + if self.args.f: # manual installation + # enable rescue mode + self.onie.sendline(self.KEY_DOWN) + self.onie.expect([self.ONIE_CONSOLE]) + self.onie.sendline() + self.onie.expect([self.ONIE_RESCUE]) + self.onie.expect([self.ONIE_SHELL]) + # install image + self.onie.sendline(' ; '.join(self.INSTALL_CMD)) + # handle unsupported platform + self.onie.expect([self.ONIE_PROMPT]) + self.onie.sendline('y') + else: # automatic discovery installation + self.onie.sendline() + def main(): parser = argparse.ArgumentParser(description='test_login cmdline parser') parser.add_argument('-p', type=int, default=9000, help='local port') + parser.add_argument('-f', action='store_true', help='force image installation') args = parser.parse_args() - #KEY_UP = '\x1b[A' - KEY_DOWN = '\x1b[B' - #KEY_RIGHT = '\x1b[C' - #KEY_LEFT = '\x1b[D' - - grub_selection = "The highlighted entry will be executed" - i = 0 while True: try: @@ -32,17 +77,16 @@ def main(): raise time.sleep(1) + onie = OnieInterface(p, args) + # select ONIE embed - p.expect(grub_selection) - p.sendline(KEY_DOWN) + onie.embed_onie() # select ONIE install - p.expect(['ONIE: Install OS']) - p.expect([grub_selection]) - p.sendline() + onie.install_os() # wait for grub, and exit - p.expect([grub_selection]) + onie.wait_grub() if __name__ == '__main__': diff --git a/platform/mellanox/fw.dep b/platform/mellanox/fw.dep index f57bad8eb9b..596cd6d1fd0 100644 --- a/platform/mellanox/fw.dep +++ b/platform/mellanox/fw.dep @@ -18,3 +18,7 @@ $(MLNX_SPC3_FW_FILE)_DEP_FILES := $(DEP_FILES) $(MLNX_SPC4_FW_FILE)_CACHE_MODE := GIT_CONTENT_SHA $(MLNX_SPC4_FW_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) $(MLNX_SPC4_FW_FILE)_DEP_FILES := $(DEP_FILES) + +$(MLNX_SPC5_FW_FILE)_CACHE_MODE := GIT_CONTENT_SHA +$(MLNX_SPC5_FW_FILE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(MLNX_SPC5_FW_FILE)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 47c1acae6c7..2d518d7dc37 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -21,10 +21,11 @@ MLNX_FW_BASE_PATH = $(MLNX_SDK_BASE_PATH) # Place an URL here to FW if you want to download FW instead MLNX_FW_BASE_URL = -SIMX_VERSION = 25.5-1026 +SIMX_VERSION = 25.5-1028 FW_FROM_URL = y +MLNX_FW_ASSETS_RELEASE_TAG = fw-2014.4040 MLNX_FW_ASSETS_RELEASE_TAG = fw-2014.4040 MLNX_FW_ASSETS_URL = $(MLNX_ASSETS_GITHUB_URL)/releases/download/$(MLNX_FW_ASSETS_RELEASE_TAG) @@ -32,27 +33,36 @@ ifeq ($(MLNX_FW_BASE_URL), ) MLNX_FW_BASE_URL = $(MLNX_FW_ASSETS_URL) endif +MLNX_SPC_FW_VERSION = 13.2014.4040 MLNX_SPC_FW_VERSION = 13.2014.4040 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) +MLNX_SPC2_FW_VERSION = 29.2014.4040 MLNX_SPC2_FW_VERSION = 29.2014.4040 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) +MLNX_SPC3_FW_VERSION = 30.2014.4040 MLNX_SPC3_FW_VERSION = 30.2014.4040 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) +MLNX_SPC4_FW_VERSION = 34.2014.4040 MLNX_SPC4_FW_VERSION = 34.2014.4040 MLNX_SPC4_FW_FILE = fw-SPC4-rel-$(subst .,_,$(MLNX_SPC4_FW_VERSION))-EVB.mfa $(MLNX_SPC4_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC4_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC4_FW_FILE) -MLNX_FW_FILES = $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_SPC3_FW_FILE) $(MLNX_SPC4_FW_FILE) +MLNX_SPC5_FW_VERSION = 37.2014.4040 +MLNX_SPC5_FW_FILE = fw-SPC5-rel-$(subst .,_,$(MLNX_SPC5_FW_VERSION))-EVB.mfa +$(MLNX_SPC5_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) +$(MLNX_SPC5_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC5_FW_FILE) + +MLNX_FW_FILES = $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_SPC3_FW_FILE) $(MLNX_SPC4_FW_FILE) $(MLNX_SPC5_FW_FILE) ifeq ($(FW_FROM_URL),n) SONIC_COPY_FILES += $(MLNX_FW_FILES) @@ -62,9 +72,10 @@ endif MLNX_FILES += $(MLNX_FW_FILES) -export MLNX_SPC_FW_VERSION MLNX_SPC2_FW_VERSION MLNX_SPC3_FW_VERSION MLNX_SPC4_FW_VERSION +export MLNX_SPC_FW_VERSION MLNX_SPC2_FW_VERSION MLNX_SPC3_FW_VERSION MLNX_SPC4_FW_VERSION MLNX_SPC5_FW_VERSION export SIMX_VERSION export MLNX_SPC_FW_FILE export MLNX_SPC2_FW_FILE export MLNX_SPC3_FW_FILE export MLNX_SPC4_FW_FILE +export MLNX_SPC5_FW_FILE diff --git a/platform/mellanox/kvm-image.dep b/platform/mellanox/kvm-image.dep new file mode 100644 index 00000000000..90111169a58 --- /dev/null +++ b/platform/mellanox/kvm-image.dep @@ -0,0 +1,2 @@ +# DPKG FRK +$(SONIC_KVM_IMAGE)_CACHE_MODE := none diff --git a/platform/mellanox/kvm-image.mk b/platform/mellanox/kvm-image.mk new file mode 100644 index 00000000000..6e2b85c6a9b --- /dev/null +++ b/platform/mellanox/kvm-image.mk @@ -0,0 +1,32 @@ +# +# SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES +# Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# sonic mellanox kvm image + +SONIC_KVM_IMAGE = sonic-mellanox.img.gz +$(SONIC_KVM_IMAGE)_MACHINE = mellanox +$(SONIC_KVM_IMAGE)_IMAGE_TYPE = kvm +$(SONIC_KVM_IMAGE)_INSTALLS += $(SX_KERNEL) $(KERNEL_MFT) $(MFT_OEM) $(MFT) $(MFT_FWTRACE_CFG) $(MLNX_HW_MANAGEMENT) $(MLNX_RSHIM) +$(SONIC_KVM_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +ifeq ($(INSTALL_DEBUG_TOOLS),y) +$(SONIC_KVM_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) +$(SONIC_KVM_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) +else +$(SONIC_KVM_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) +endif +$(SONIC_KVM_IMAGE)_FILES = $(MLNX_FILES) $(MLNX_CPLD_ARCHIVES) $(ONIE_RECOVERY_IMAGE) +SONIC_INSTALLERS += $(SONIC_KVM_IMAGE) diff --git a/platform/mellanox/mlnx-fw-upgrade.j2 b/platform/mellanox/mlnx-fw-upgrade.j2 index 3f156b8b2f9..3dea64730c5 100755 --- a/platform/mellanox/mlnx-fw-upgrade.j2 +++ b/platform/mellanox/mlnx-fw-upgrade.j2 @@ -50,6 +50,7 @@ declare -r SPC1_ASIC="spc1" declare -r SPC2_ASIC="spc2" declare -r SPC3_ASIC="spc3" declare -r SPC4_ASIC="spc4" +declare -r SPC5_ASIC="spc5" declare -r BF3_NIC="bf3" declare -r UNKN_ASIC="unknown" declare -r UNKN_MST="unknown" @@ -59,6 +60,7 @@ declare -rA FW_FILE_MAP=( \ [$SPC2_ASIC]="fw-SPC2.mfa" \ [$SPC3_ASIC]="fw-SPC3.mfa" \ [$SPC4_ASIC]="fw-SPC4.mfa" \ + [$SPC5_ASIC]="fw-SPC5.mfa" \ [$BF3_NIC]="fw-BF3.mfa" \ ) @@ -207,7 +209,7 @@ function GetMstDeviceType() { local -r asic_type=$(GetAsicType) case $asic_type in - ${SPC1_ASIC}|${SPC2_ASIC}|${SPC3_ASIC}|${SPC4_ASIC}) + ${SPC1_ASIC}|${SPC2_ASIC}|${SPC3_ASIC}|${SPC4_ASIC}|${SPC5_ASIC}) echo "Spectrum" return ${EXIT_SUCCESS} ;; @@ -256,6 +258,7 @@ function GetAsicType() { local -r SPC2_PRODUCT_ID="cf6c" local -r SPC3_PRODUCT_ID="cf70" local -r SPC4_PRODUCT_ID="cf80" + local -r SPC5_PRODUCT_ID="cf82" local -r BF3_PRODUCT_ID="a2dc" local -i QUERY_RETRY_COUNT="0" @@ -282,6 +285,9 @@ function GetAsicType() { elif echo $pcitree | grep "${VENDOR_ID}:${SPC4_PRODUCT_ID}" &>/dev/null; then echo "${SPC4_ASIC}" exit "${EXIT_SUCCESS}" + elif echo $pcitree | grep "${VENDOR_ID}:${SPC5_PRODUCT_ID}" &>/dev/null; then + echo "${SPC5_ASIC}" + exit "${EXIT_SUCCESS}" elif echo $pcitree | grep "${VENDOR_ID}:${BF3_PRODUCT_ID}" &>/dev/null; then echo "${BF3_NIC}" exit "${EXIT_SUCCESS}" diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index a811fd8fe51..307eae7164a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -861,47 +861,40 @@ def get_temperature_info(self): tuple: (temperature, warning_threshold, critical_threshold) """ try: + sw_control = self.is_sw_control() + if not sw_control: + return sw_control, None, None, None + sn_changed = self.reinit_if_sn_changed() - if not self.is_sw_control(): - # firmware control, read from sysfs - temp_file = f'/sys/module/sx_core/asic0/module{self.sdk_index}/temperature/input' - if not os.path.exists(temp_file): - logger.log_error(f'Failed to read from file {temp_file} - not exists') - temperature = None - else: - temperature = utils.read_int_from_file(temp_file, - log_func=None) - temperature = temperature / SFP_TEMPERATURE_SCALE if temperature is not None else None - else: - # software control, read from EEPROM - temperature = super().get_temperature() + # software control, read from EEPROM + temperature = super().get_temperature() if temperature is None: # Failed to read temperature, no need read threshold - return None, None, None + return sw_control, None, None, None elif temperature == 0.0: # Temperature is not supported, no need read threshold - return 0.0, 0.0, 0.0 + return sw_control, 0.0, 0.0, 0.0 else: if not sn_changed and self.temp_high_threshold is not None and self.temp_critical_threshold is not None: - return temperature, self.temp_high_threshold, self.temp_critical_threshold + return sw_control, temperature, self.temp_high_threshold, self.temp_critical_threshold else: # Read threshold from EEPROM api = self.get_xcvr_api() thresh_support = api.get_transceiver_thresholds_support() if thresh_support is None: # Failed to read threshold support field, no need read threshold - return temperature, None, None + return sw_control, temperature, None, None if thresh_support: # Read threshold from EEPROM self.temp_high_threshold = api.xcvr_eeprom.read(consts.TEMP_HIGH_WARNING_FIELD) self.temp_critical_threshold = api.xcvr_eeprom.read(consts.TEMP_HIGH_ALARM_FIELD) - return temperature, self.temp_high_threshold, self.temp_critical_threshold + return sw_control, temperature, self.temp_high_threshold, self.temp_critical_threshold else: # No threshold support, use default threshold - return temperature, 0.0, 0.0 + return sw_control, temperature, 0.0, 0.0 except: # module under initialization, return as temperature not supported - return 0.0, 0.0, 0.0 + return False, None, None, None def get_temperature(self): """Get SFP temperature @@ -1114,7 +1107,7 @@ def check_media_interface_technology(self, xcvr_api): xcvr_api (object): xcvr api object """ media_interface = self.read_eeprom(CMIS_MEDIA_INTERFACE_TECH_OFFSET, 1) - return media_interface[0] == 0x0F if media_interface else False + return media_interface[0] != 0x0F if media_interface else False def is_supported_for_software_control(self, xcvr_api): """Check if the api object supports software control diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py index 813c5e8eefb..436840a04eb 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_manager.py @@ -39,7 +39,7 @@ def initialize(cls): if not dpus_present and host_mgmt_mode: # Non smart switch behaviour has highest priority from .chassis import Chassis - cls.thermal_updater_task = thermal_updater.ThermalUpdater(sfp_list=Chassis.chassis_instance.get_all_sfps()) + cls.thermal_updater_task = thermal_updater.ThermalUpdater(sfp_list=Chassis.chassis_instance.get_all_sfps(), update_asic=False) elif dpus_present: from .chassis import Chassis dpus = Chassis.chassis_instance.get_all_modules() diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_updater.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_updater.py index daea80ba5d7..48ad612590e 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_updater.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_updater.py @@ -49,10 +49,11 @@ class ThermalUpdater: - def __init__(self, sfp_list): + def __init__(self, sfp_list, update_asic=True): self._sfp_list = sfp_list self._sfp_status = {} self._timer = utils.Timer() + self._update_asic = update_asic def load_tc_config(self): asic_poll_interval = 1 @@ -75,8 +76,9 @@ def load_tc_config(self): if sfp_poll_interval_config: sfp_poll_interval = int(sfp_poll_interval_config) / 2 - logger.log_notice(f'ASIC polling interval: {asic_poll_interval}') - self._timer.schedule(asic_poll_interval, self.update_asic) + if self._update_asic: + logger.log_notice(f'ASIC polling interval: {asic_poll_interval}') + self._timer.schedule(asic_poll_interval, self.update_asic) logger.log_notice(f'Module polling interval: {sfp_poll_interval}') self._timer.schedule(sfp_poll_interval, self.update_module) @@ -120,7 +122,9 @@ def update_single_module(self, sfp): presence = sfp.get_presence() pre_presence = self._sfp_status.get(sfp.sdk_index) if presence: - temperature, warning_thresh, critical_thresh = sfp.get_temperature_info() + sw_control, temperature, warning_thresh, critical_thresh = sfp.get_temperature_info() + if not sw_control: + return fault = ERROR_READ_THERMAL_DATA if (temperature is None or warning_thresh is None or critical_thresh is None) else 0 temperature = 0 if temperature is None else temperature * SFP_TEMPERATURE_SCALE warning_thresh = 0 if warning_thresh is None else warning_thresh * SFP_TEMPERATURE_SCALE diff --git a/platform/mellanox/mlnx-platform-api/tests/test_sfp.py b/platform/mellanox/mlnx-platform-api/tests/test_sfp.py index a533b122b82..a3efb395bce 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_sfp.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_sfp.py @@ -553,7 +553,6 @@ def test_get_temperature_info(self, mock_read_int, mock_super_get_temperature): sfp = SFP(0) sfp.reinit_if_sn_changed = mock.MagicMock(return_value=True) sfp.is_sw_control = mock.MagicMock(return_value=False) - sfp.is_sw_control.return_value = False mock_api = mock.MagicMock() mock_api.get_transceiver_thresholds_support = mock.MagicMock(return_value=True) mock_api.xcvr_eeprom = mock.MagicMock() @@ -567,31 +566,19 @@ def mock_read(field): mock_api.xcvr_eeprom.read = mock.MagicMock(side_effect=mock_read) sfp.get_xcvr_api = mock.MagicMock(return_value=mock_api) - with mock.patch('os.path.exists', mock.MagicMock(return_value=False)): - assert sfp.get_temperature_info() == (None, None, None) - - with mock.patch('os.path.exists', mock.MagicMock(return_value=True)): - mock_read_int.return_value = None - assert sfp.get_temperature_info() == (None, None, None) - - mock_read_int.return_value = 0.0 - assert sfp.get_temperature_info() == (0.0, 0.0, 0.0) - - mock_read_int.return_value = 448 - assert sfp.get_temperature_info() == (56.0, 75.0, 85.0) - - + assert sfp.get_temperature_info() == (False, None, None, None) + sfp.is_sw_control.return_value = True mock_super_get_temperature.return_value = 58.0 - assert sfp.get_temperature_info() == (58.0, 75.0, 85.0) + assert sfp.get_temperature_info() == (True, 58.0, 75.0, 85.0) mock_api.get_transceiver_thresholds_support.return_value = None - assert sfp.get_temperature_info() == (58.0, None, None) + assert sfp.get_temperature_info() == (True, 58.0, None, None) mock_api.get_transceiver_thresholds_support.return_value = False - assert sfp.get_temperature_info() == (58.0, 0.0, 0.0) + assert sfp.get_temperature_info() == (True, 58.0, 0.0, 0.0) sfp.reinit_if_sn_changed.return_value = False - assert sfp.get_temperature_info() == (58.0, 75.0, 85.0) + assert sfp.get_temperature_info() == (True, 58.0, 75.0, 85.0) sfp.is_sw_control.side_effect = Exception('') - assert sfp.get_temperature_info() == (0.0, 0.0, 0.0) + assert sfp.get_temperature_info() == (False, None, None, None) diff --git a/platform/mellanox/mlnx-platform-api/tests/test_thermal_manager.py b/platform/mellanox/mlnx-platform-api/tests/test_thermal_manager.py index 2f39b1cd1a8..fef7e081fd4 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_thermal_manager.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_thermal_manager.py @@ -40,7 +40,7 @@ def test_updater_init(self, mock_dpus_data, mock_management_mode, mock_chassis_i # Host mgmt mode, no DPUs are used for init mgr = ThermalManager() mgr.initialize() - mock_thermal.assert_called_once_with(sfp_list=['sfp1', 'sfp2']) + mock_thermal.assert_called_once_with(sfp_list=['sfp1', 'sfp2'], update_asic=False) mgr.deinitialize() mgr.thermal_updater_task.stop.assert_called_once() # Not initialized if no DPUs and not in host mgmt mode diff --git a/platform/mellanox/mlnx-platform-api/tests/test_thermal_updater.py b/platform/mellanox/mlnx-platform-api/tests/test_thermal_updater.py index 26e8b811df7..2b77f5db1ec 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_thermal_updater.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_thermal_updater.py @@ -95,12 +95,12 @@ def test_update_module(self): mock_sfp = mock.MagicMock() mock_sfp.sdk_index = 10 mock_sfp.get_presence = mock.MagicMock(return_value=True) - mock_sfp.get_temperature_info = mock.MagicMock(return_value=(55.0, 70.0, 80.0)) + mock_sfp.get_temperature_info = mock.MagicMock(return_value=(True, 55.0, 70.0, 80.0)) updater = ThermalUpdater([mock_sfp]) updater.update_module() hw_management_independent_mode_update.thermal_data_set_module.assert_called_once_with(0, 11, 55000, 80000, 70000, 0) - mock_sfp.get_temperature_info = mock.MagicMock(return_value=(0.0, 0.0, 0.0)) + mock_sfp.get_temperature_info = mock.MagicMock(return_value=(True, 0.0, 0.0, 0.0)) hw_management_independent_mode_update.reset_mock() updater.update_module() hw_management_independent_mode_update.thermal_data_set_module.assert_called_once_with(0, 11, 0, 0, 0, 0) diff --git a/platform/mellanox/onie.dep b/platform/mellanox/onie.dep new file mode 100644 index 00000000000..c1540b37b04 --- /dev/null +++ b/platform/mellanox/onie.dep @@ -0,0 +1,2 @@ +# DPKG FRK +$(ONIE_RECOVERY_IMAGE)_CACHE_MODE := none diff --git a/platform/mellanox/onie.mk b/platform/mellanox/onie.mk new file mode 100644 index 00000000000..5624fb7e899 --- /dev/null +++ b/platform/mellanox/onie.mk @@ -0,0 +1,22 @@ +# +# SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES +# Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +ONIE_RECOVERY_IMAGE = onie-recovery-x86_64-kvm_x86_64-r0.iso +$(ONIE_RECOVERY_IMAGE)_URL = "https://sonicstorage.blob.core.windows.net/public/onie/$(ONIE_RECOVERY_IMAGE)" + +SONIC_ONLINE_FILES += $(ONIE_RECOVERY_IMAGE) diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index 19e83b7c30c..e69b3359829 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -1,5 +1,6 @@ # -# Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. +# SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES +# Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,6 +27,8 @@ include $(PLATFORM_PATH)/docker-syncd-mlnx.mk include $(PLATFORM_PATH)/docker-syncd-mlnx-rpc.mk include $(PLATFORM_PATH)/docker-saiserver-mlnx.mk include $(PLATFORM_PATH)/one-image.mk +include $(PLATFORM_PATH)/onie.mk +include $(PLATFORM_PATH)/kvm-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/mlnx-ffb.mk include $(PLATFORM_PATH)/issu-version.mk @@ -39,6 +42,7 @@ include $(PLATFORM_PATH)/rshim.mk include $(PLATFORM_PATH)/mlnx-sonic-bfb-installer.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ + $(SONIC_KVM_IMAGE) \ $(DOCKER_FPM) # Inject mlnx sai into syncd diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index 66fc4e42770..c0882703505 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -38,7 +38,7 @@ prepare_installer_disk() { fallocate -l 4096M $INSTALLER_DISK - mkfs.vfat $INSTALLER_DISK + mkfs.vfat -n INSTALLER $INSTALLER_DISK tmpdir=$(mktemp -d) @@ -109,10 +109,21 @@ wait_kvm_ready echo "to kill kvm: sudo kill $kvm_pid" -./install_sonic.py +if [ "$MLNX_KVM_IMAGE" = "yes" ]; then + echo "Mellanox KVM build: use force image installation routine" + ./install_sonic.py -f +else + echo "Generic KVM build: use regular image installation routine" + ./install_sonic.py +fi kill $kvm_pid +if [ "$MLNX_KVM_IMAGE" = "yes" ]; then + echo "Skip SONiC boot for Mellanox KVM build" + exit 0 +fi + echo "Booting up SONiC" /usr/bin/kvm -m $MEM \ diff --git a/src/sonic-swss b/src/sonic-swss index e0d6f65fbc1..beab5bdc314 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit e0d6f65fbc197cf85d1f226d0dc2cc5dc8fb7fb2 +Subproject commit beab5bdc31464aaf38863771ca5737b523106db3 diff --git a/src/sonic-utilities b/src/sonic-utilities index 6ce5257459b..2d3847c3a33 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 6ce5257459b6d36496bc98a282b5d78c5be5b530 +Subproject commit 2d3847c3a3336af9faa9947d7b265b66fa6f701d