From 266a495837675006e00bed220d34c4127a2c0e75 Mon Sep 17 00:00:00 2001 From: Jitendra Sharma Date: Mon, 6 Mar 2023 15:46:51 +0000 Subject: [PATCH] [Sysman]: Add support for Fabric APIs Add support for Fabric APIs in new sysman design. This design is independent of level zero core. Related-To: LOCI-4091 Signed-off-by: Jitendra Sharma --- level_zero/api/sysman/CMakeLists.txt | 3 +- level_zero/api/sysman/zes_handles_struct.h | 13 + .../api/sysman/zes_sysman_api_entrypoints.h | 43 +- .../sysman/source/fabric_port/CMakeLists.txt | 24 + .../sysman/source/fabric_port/fabric_port.cpp | 64 ++ .../sysman/source/fabric_port/fabric_port.h | 64 ++ .../source/fabric_port/fabric_port_imp.cpp | 82 ++ .../source/fabric_port/fabric_port_imp.h | 51 + .../source/fabric_port/linux/CMakeLists.txt | 45 + .../fabric_port/linux/fabric_device_access.h | 47 + .../linux/fabric_device_access_imp.cpp | 254 +++++ .../linux/fabric_device_access_imp.h | 88 ++ .../linux/fabric_device_access_stub.cpp | 89 ++ .../linux/fabric_device_access_stub.h | 41 + .../fabric_port/linux/os_fabric_port_imp.cpp | 93 ++ .../fabric_port/linux/os_fabric_port_imp.h | 54 + .../linux/os_fabric_port_imp_prelim.cpp | 321 ++++++ .../linux/os_fabric_port_imp_prelim.h | 85 ++ .../source/fabric_port/os_fabric_port.h | 41 + .../source/fabric_port/windows/CMakeLists.txt | 21 + .../windows/os_fabric_port_imp.cpp | 76 ++ .../fabric_port/windows/os_fabric_port_imp.h | 45 + .../sysman/source/linux/nl_api/CMakeLists.txt | 24 + .../sysman/source/linux/nl_api/iaf_nl_api.cpp | 871 ++++++++++++++++ .../sysman/source/linux/nl_api/iaf_nl_api.h | 143 +++ .../sysman/source/linux/nl_api/nl_api.cpp | 260 +++++ .../sysman/source/linux/nl_api/nl_api.h | 140 +++ level_zero/sysman/source/sysman_device.cpp | 5 + level_zero/sysman/source/sysman_device.h | 4 + .../sysman/source/sysman_device_imp.cpp | 6 + level_zero/sysman/source/sysman_device_imp.h | 3 + .../sources/fabric_port/CMakeLists.txt | 11 + .../sources/fabric_port/linux/CMakeLists.txt | 30 + .../fabric_port/linux/mock_fabric_device.h | 80 ++ .../test_sysman_fabric_device_prelim.cpp | 387 +++++++ .../linux/test_sysman_fabric_port_prelim.cpp | 967 ++++++++++++++++++ .../linux/test_zes_fabric_port.cpp | 223 ++++ .../sources/linux/mock_sysman_fixture.h | 2 - .../sources/linux/nl_api/CMakeLists.txt | 33 + .../linux/nl_api/mock_iaf_nl_api_prelim.cpp | 277 +++++ .../linux/nl_api/mock_iaf_nl_api_prelim.h | 116 +++ .../linux/nl_api/mock_nl_api_prelim.cpp | 498 +++++++++ .../sources/linux/nl_api/mock_nl_api_prelim.h | 162 +++ .../sources/linux/nl_api/mock_nl_dll.cpp | 263 +++++ .../sources/linux/nl_api/mock_nl_dll.h | 68 ++ .../nl_api/test_sysman_iaf_nl_api_prelim.cpp | 964 +++++++++++++++++ .../linux/nl_api/test_sysman_nl_api.cpp | 210 ++++ .../source/sysman/fabric_port/fabric_port.h | 5 +- .../sysman/linux/mock_sysman_fixture.h | 3 + 49 files changed, 7385 insertions(+), 14 deletions(-) create mode 100644 level_zero/api/sysman/zes_handles_struct.h create mode 100644 level_zero/sysman/source/fabric_port/CMakeLists.txt create mode 100644 level_zero/sysman/source/fabric_port/fabric_port.cpp create mode 100644 level_zero/sysman/source/fabric_port/fabric_port.h create mode 100644 level_zero/sysman/source/fabric_port/fabric_port_imp.cpp create mode 100644 level_zero/sysman/source/fabric_port/fabric_port_imp.h create mode 100644 level_zero/sysman/source/fabric_port/linux/CMakeLists.txt create mode 100644 level_zero/sysman/source/fabric_port/linux/fabric_device_access.h create mode 100644 level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.cpp create mode 100644 level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.h create mode 100644 level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.cpp create mode 100644 level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.h create mode 100644 level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.cpp create mode 100644 level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.h create mode 100644 level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.cpp create mode 100644 level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.h create mode 100644 level_zero/sysman/source/fabric_port/os_fabric_port.h create mode 100644 level_zero/sysman/source/fabric_port/windows/CMakeLists.txt create mode 100644 level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.cpp create mode 100644 level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.h create mode 100644 level_zero/sysman/source/linux/nl_api/CMakeLists.txt create mode 100644 level_zero/sysman/source/linux/nl_api/iaf_nl_api.cpp create mode 100644 level_zero/sysman/source/linux/nl_api/iaf_nl_api.h create mode 100644 level_zero/sysman/source/linux/nl_api/nl_api.cpp create mode 100644 level_zero/sysman/source/linux/nl_api/nl_api.h create mode 100644 level_zero/sysman/test/unit_tests/sources/fabric_port/CMakeLists.txt create mode 100644 level_zero/sysman/test/unit_tests/sources/fabric_port/linux/CMakeLists.txt create mode 100644 level_zero/sysman/test/unit_tests/sources/fabric_port/linux/mock_fabric_device.h create mode 100644 level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_sysman_fabric_device_prelim.cpp create mode 100644 level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_sysman_fabric_port_prelim.cpp create mode 100644 level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_zes_fabric_port.cpp create mode 100644 level_zero/sysman/test/unit_tests/sources/linux/nl_api/CMakeLists.txt create mode 100644 level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.cpp create mode 100644 level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.h create mode 100644 level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.cpp create mode 100644 level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.h create mode 100644 level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.cpp create mode 100644 level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h create mode 100644 level_zero/sysman/test/unit_tests/sources/linux/nl_api/test_sysman_iaf_nl_api_prelim.cpp create mode 100644 level_zero/sysman/test/unit_tests/sources/linux/nl_api/test_sysman_nl_api.cpp diff --git a/level_zero/api/sysman/CMakeLists.txt b/level_zero/api/sysman/CMakeLists.txt index b687aaa436..8303081ec9 100644 --- a/level_zero/api/sysman/CMakeLists.txt +++ b/level_zero/api/sysman/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2020-2022 Intel Corporation +# Copyright (C) 2020-2023 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -8,5 +8,6 @@ set(L0_SYSMAN_API ${CMAKE_CURRENT_SOURCE_DIR}/ze_sysman_loader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/zes_sysman_api_entrypoints.h ${CMAKE_CURRENT_SOURCE_DIR}/zes_sysman_all_api_entrypoints.h + ${CMAKE_CURRENT_SOURCE_DIR}/zes_handles_struct.h ) set_property(GLOBAL PROPERTY L0_SYSMAN_API ${L0_SYSMAN_API}) diff --git a/level_zero/api/sysman/zes_handles_struct.h b/level_zero/api/sysman/zes_handles_struct.h new file mode 100644 index 0000000000..78b5ffe9e7 --- /dev/null +++ b/level_zero/api/sysman/zes_handles_struct.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include + +struct _zes_fabric_port_handle_t { + virtual ~_zes_fabric_port_handle_t() = default; +}; \ No newline at end of file diff --git a/level_zero/api/sysman/zes_sysman_api_entrypoints.h b/level_zero/api/sysman/zes_sysman_api_entrypoints.h index 984afe167a..7fb7e3a6df 100644 --- a/level_zero/api/sysman/zes_sysman_api_entrypoints.h +++ b/level_zero/api/sysman/zes_sysman_api_entrypoints.h @@ -6,6 +6,7 @@ */ #pragma once +#include "level_zero/core/source/driver/driver.h" #include "level_zero/core/source/driver/driver_handle.h" #include "level_zero/sysman/source/sysman_device.h" #include "level_zero/sysman/source/sysman_driver.h" @@ -413,43 +414,71 @@ ze_result_t zesDeviceEnumFabricPorts( zes_device_handle_t hDevice, uint32_t *pCount, zes_fabric_port_handle_t *phPort) { - return L0::SysmanDevice::fabricPortGet(hDevice, pCount, phPort); + if (L0::sysmanInitFromCore) { + return L0::SysmanDevice::fabricPortGet(hDevice, pCount, phPort); + } else { + return L0::Sysman::SysmanDevice::fabricPortGet(hDevice, pCount, phPort); + } } ze_result_t zesFabricPortGetProperties( zes_fabric_port_handle_t hPort, zes_fabric_port_properties_t *pProperties) { - return L0::FabricPort::fromHandle(hPort)->fabricPortGetProperties(pProperties); + if (L0::sysmanInitFromCore) { + return L0::FabricPort::fromHandle(hPort)->fabricPortGetProperties(pProperties); + } else { + return L0::Sysman::FabricPort::fromHandle(hPort)->fabricPortGetProperties(pProperties); + } } ze_result_t zesFabricPortGetLinkType( zes_fabric_port_handle_t hPort, zes_fabric_link_type_t *pLinkType) { - return L0::FabricPort::fromHandle(hPort)->fabricPortGetLinkType(pLinkType); + if (L0::sysmanInitFromCore) { + return L0::FabricPort::fromHandle(hPort)->fabricPortGetLinkType(pLinkType); + } else { + return L0::Sysman::FabricPort::fromHandle(hPort)->fabricPortGetLinkType(pLinkType); + } } ze_result_t zesFabricPortGetConfig( zes_fabric_port_handle_t hPort, zes_fabric_port_config_t *pConfig) { - return L0::FabricPort::fromHandle(hPort)->fabricPortGetConfig(pConfig); + if (L0::sysmanInitFromCore) { + return L0::FabricPort::fromHandle(hPort)->fabricPortGetConfig(pConfig); + } else { + return L0::Sysman::FabricPort::fromHandle(hPort)->fabricPortGetConfig(pConfig); + } } ze_result_t zesFabricPortSetConfig( zes_fabric_port_handle_t hPort, const zes_fabric_port_config_t *pConfig) { - return L0::FabricPort::fromHandle(hPort)->fabricPortSetConfig(pConfig); + if (L0::sysmanInitFromCore) { + return L0::FabricPort::fromHandle(hPort)->fabricPortSetConfig(pConfig); + } else { + return L0::Sysman::FabricPort::fromHandle(hPort)->fabricPortSetConfig(pConfig); + } } ze_result_t zesFabricPortGetState( zes_fabric_port_handle_t hPort, zes_fabric_port_state_t *pState) { - return L0::FabricPort::fromHandle(hPort)->fabricPortGetState(pState); + if (L0::sysmanInitFromCore) { + return L0::FabricPort::fromHandle(hPort)->fabricPortGetState(pState); + } else { + return L0::Sysman::FabricPort::fromHandle(hPort)->fabricPortGetState(pState); + } } ze_result_t zesFabricPortGetThroughput( zes_fabric_port_handle_t hPort, zes_fabric_port_throughput_t *pThroughput) { - return L0::FabricPort::fromHandle(hPort)->fabricPortGetThroughput(pThroughput); + if (L0::sysmanInitFromCore) { + return L0::FabricPort::fromHandle(hPort)->fabricPortGetThroughput(pThroughput); + } else { + return L0::Sysman::FabricPort::fromHandle(hPort)->fabricPortGetThroughput(pThroughput); + } } ze_result_t zesDeviceEnumTemperatureSensors( diff --git a/level_zero/sysman/source/fabric_port/CMakeLists.txt b/level_zero/sysman/source/fabric_port/CMakeLists.txt new file mode 100644 index 0000000000..e80f344ebd --- /dev/null +++ b/level_zero/sysman/source/fabric_port/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# Copyright (C) 2020-2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(L0_SRCS_SYSMAN_FABRICPORT + ${CMAKE_CURRENT_SOURCE_DIR}/fabric_port.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/fabric_port.h + ${CMAKE_CURRENT_SOURCE_DIR}/fabric_port_imp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/fabric_port_imp.h + ${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port.h +) + +target_sources(${L0_STATIC_LIB_NAME} + PRIVATE + ${L0_SRCS_SYSMAN_FABRICPORT} + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt +) + +add_subdirectories() + +# Make our source files visible to parent +set_property(GLOBAL PROPERTY L0_SRCS_SYSMAN_FABRICPORT ${L0_SRCS_SYSMAN_FABRICPORT}) diff --git a/level_zero/sysman/source/fabric_port/fabric_port.cpp b/level_zero/sysman/source/fabric_port/fabric_port.cpp new file mode 100644 index 0000000000..f039da8110 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/fabric_port.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/fabric_port/fabric_port.h" + +#include "shared/source/helpers/basic_math.h" +#include "shared/source/helpers/debug_helpers.h" + +#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h" + +namespace L0 { +namespace Sysman { + +FabricPortHandleContext::FabricPortHandleContext(OsSysman *pOsSysman) { + pFabricDevice = new FabricDeviceImp(pOsSysman); + UNRECOVERABLE_IF(nullptr == pFabricDevice); + handleList.clear(); +} + +FabricPortHandleContext::~FabricPortHandleContext() { + UNRECOVERABLE_IF(nullptr == pFabricDevice); + for (FabricPort *pFabricPort : handleList) { + delete pFabricPort; + } + handleList.clear(); + delete pFabricDevice; + pFabricDevice = nullptr; +} + +ze_result_t FabricPortHandleContext::init() { + UNRECOVERABLE_IF(nullptr == pFabricDevice); + uint32_t numPorts = pFabricDevice->getNumPorts(); + + for (uint32_t portNum = 0; portNum < numPorts; portNum++) { + FabricPort *pFabricPort = new FabricPortImp(pFabricDevice, portNum); + UNRECOVERABLE_IF(nullptr == pFabricPort); + handleList.push_back(pFabricPort); + } + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricPortHandleContext::fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) { + std::call_once(initFabricPortOnce, [this]() { + this->init(); + }); + uint32_t handleListSize = static_cast(handleList.size()); + uint32_t numToCopy = std::min(*pCount, handleListSize); + if (0 == *pCount || *pCount > handleListSize) { + *pCount = handleListSize; + } + if (nullptr != phPort) { + for (uint32_t i = 0; i < numToCopy; i++) { + phPort[i] = handleList[i]->toZesHandle(); + } + } + return ZE_RESULT_SUCCESS; +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/fabric_port.h b/level_zero/sysman/source/fabric_port/fabric_port.h new file mode 100644 index 0000000000..5a64c3c324 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/fabric_port.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "level_zero/api/sysman/zes_handles_struct.h" +#include + +#include +#include + +namespace L0 { +namespace Sysman { + +struct OsSysman; +class OsFabricDevice; + +class FabricDevice { + public: + virtual ~FabricDevice() = default; + virtual OsFabricDevice *getOsFabricDevice() = 0; + virtual uint32_t getNumPorts() = 0; +}; + +class FabricPort : _zes_fabric_port_handle_t { + public: + ~FabricPort() override = default; + virtual ze_result_t fabricPortGetProperties(zes_fabric_port_properties_t *pProperties) = 0; + virtual ze_result_t fabricPortGetLinkType(zes_fabric_link_type_t *pLinkType) = 0; + virtual ze_result_t fabricPortGetConfig(zes_fabric_port_config_t *pConfig) = 0; + virtual ze_result_t fabricPortSetConfig(const zes_fabric_port_config_t *pConfig) = 0; + virtual ze_result_t fabricPortGetState(zes_fabric_port_state_t *pState) = 0; + virtual ze_result_t fabricPortGetThroughput(zes_fabric_port_throughput_t *pThroughput) = 0; + virtual ze_result_t fabricPortGetErrorCounters(zes_fabric_port_error_counters_t *pErrors) = 0; + + inline zes_fabric_port_handle_t toZesHandle() { return this; } + + static FabricPort *fromHandle(zes_fabric_port_handle_t handle) { + return static_cast(handle); + } +}; + +struct FabricPortHandleContext : NEO::NonCopyableOrMovableClass { + FabricPortHandleContext(OsSysman *pOsSysman); + ~FabricPortHandleContext(); + + ze_result_t init(); + + ze_result_t fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort); + + FabricDevice *pFabricDevice = nullptr; + std::vector handleList = {}; + + private: + std::once_flag initFabricPortOnce; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/fabric_port_imp.cpp b/level_zero/sysman/source/fabric_port/fabric_port_imp.cpp new file mode 100644 index 0000000000..8b80986ce3 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/fabric_port_imp.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h" + +#include "shared/source/helpers/debug_helpers.h" + +#include + +namespace L0 { +namespace Sysman { + +uint32_t FabricDeviceImp::getNumPorts() { + UNRECOVERABLE_IF(nullptr == pOsFabricDevice); + return pOsFabricDevice->getNumPorts(); +} + +FabricDeviceImp::FabricDeviceImp(OsSysman *pOsSysman) { + pOsFabricDevice = OsFabricDevice::create(pOsSysman); + UNRECOVERABLE_IF(nullptr == pOsFabricDevice); +} + +FabricDeviceImp::~FabricDeviceImp() { + delete pOsFabricDevice; + pOsFabricDevice = nullptr; +} + +void fabricPortGetTimestamp(uint64_t ×tamp) { + std::chrono::time_point ts = std::chrono::steady_clock::now(); + timestamp = std::chrono::duration_cast(ts.time_since_epoch()).count(); +} + +ze_result_t FabricPortImp::fabricPortGetProperties(zes_fabric_port_properties_t *pProperties) { + return pOsFabricPort->getProperties(pProperties); +} + +ze_result_t FabricPortImp::fabricPortGetLinkType(zes_fabric_link_type_t *pLinkType) { + return pOsFabricPort->getLinkType(pLinkType); +} + +ze_result_t FabricPortImp::fabricPortGetConfig(zes_fabric_port_config_t *pConfig) { + return pOsFabricPort->getConfig(pConfig); +} + +ze_result_t FabricPortImp::fabricPortSetConfig(const zes_fabric_port_config_t *pConfig) { + return pOsFabricPort->setConfig(pConfig); +} + +ze_result_t FabricPortImp::fabricPortGetState(zes_fabric_port_state_t *pState) { + return pOsFabricPort->getState(pState); +} + +ze_result_t FabricPortImp::fabricPortGetErrorCounters(zes_fabric_port_error_counters_t *pErrors) { + return pOsFabricPort->getErrorCounters(pErrors); +} + +ze_result_t FabricPortImp::fabricPortGetThroughput(zes_fabric_port_throughput_t *pThroughput) { + fabricPortGetTimestamp(pThroughput->timestamp); + return pOsFabricPort->getThroughput(pThroughput); +} + +void FabricPortImp::init() { +} + +FabricPortImp::FabricPortImp(FabricDevice *pFabricDevice, uint32_t portNum) { + pOsFabricPort = OsFabricPort::create(pFabricDevice->getOsFabricDevice(), portNum); + UNRECOVERABLE_IF(nullptr == pOsFabricPort); + + init(); +} + +FabricPortImp::~FabricPortImp() { + delete pOsFabricPort; + pOsFabricPort = nullptr; +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/fabric_port_imp.h b/level_zero/sysman/source/fabric_port/fabric_port_imp.h new file mode 100644 index 0000000000..507d65c859 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/fabric_port_imp.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "level_zero/sysman/source/fabric_port/fabric_port.h" +#include "level_zero/sysman/source/fabric_port/os_fabric_port.h" +#include + +namespace L0 { +namespace Sysman { + +class FabricDeviceImp : public FabricDevice, NEO::NonCopyableOrMovableClass { + public: + FabricDeviceImp() = delete; + FabricDeviceImp(OsSysman *pOsSysman); + ~FabricDeviceImp() override; + uint32_t getNumPorts() override; + OsFabricDevice *getOsFabricDevice() override { return pOsFabricDevice; } + + protected: + OsFabricDevice *pOsFabricDevice = nullptr; +}; + +class FabricPortImp : public FabricPort, NEO::NonCopyableOrMovableClass { + public: + ze_result_t fabricPortGetProperties(zes_fabric_port_properties_t *pProperties) override; + ze_result_t fabricPortGetLinkType(zes_fabric_link_type_t *pLinkType) override; + ze_result_t fabricPortGetConfig(zes_fabric_port_config_t *pConfig) override; + ze_result_t fabricPortSetConfig(const zes_fabric_port_config_t *pConfig) override; + ze_result_t fabricPortGetState(zes_fabric_port_state_t *pState) override; + ze_result_t fabricPortGetThroughput(zes_fabric_port_throughput_t *pThroughput) override; + ze_result_t fabricPortGetErrorCounters(zes_fabric_port_error_counters_t *pErrors) override; + + FabricPortImp() = delete; + FabricPortImp(FabricDevice *pFabricDevice, uint32_t portNum); + ~FabricPortImp() override; + + protected: + void init(); + OsFabricPort *pOsFabricPort = nullptr; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/linux/CMakeLists.txt b/level_zero/sysman/source/fabric_port/linux/CMakeLists.txt new file mode 100644 index 0000000000..6fd66ce1f6 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/CMakeLists.txt @@ -0,0 +1,45 @@ +# +# Copyright (C) 2020-2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(L0_SRCS_SYSMAN_FABRICPORT_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt +) + +if(NEO_ENABLE_i915_PRELIM_DETECTION) + list(APPEND L0_SRCS_SYSMAN_FABRICPORT_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp_prelim.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp_prelim.h + ) + + if(LIBGENL_FOUND) + set(L0_SRCS_SYSMAN_FABRICPORT_LINUX_ACCESS + ${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access.h + ${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access_imp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access_imp.h + ) + else() + set(L0_SRCS_SYSMAN_FABRICPORT_LINUX_ACCESS + ${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access_stub.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access_stub.h + ) + endif() +else() + list(APPEND L0_SRCS_SYSMAN_FABRICPORT_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp.h + ) +endif() + +if(UNIX) + target_sources(${L0_STATIC_LIB_NAME} + PRIVATE + ${L0_SRCS_SYSMAN_FABRICPORT_LINUX} + ${L0_SRCS_SYSMAN_FABRICPORT_LINUX_ACCESS} + ) +endif() + +# Make our source files visible to parent +set_property(GLOBAL PROPERTY L0_SRCS_SYSMAN_FABRICPORT_LINUX ${L0_SRCS_SYSMAN_FABRICPORT_LINUX}) diff --git a/level_zero/sysman/source/fabric_port/linux/fabric_device_access.h b/level_zero/sysman/source/fabric_port/linux/fabric_device_access.h new file mode 100644 index 0000000000..05a68bb47f --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/fabric_device_access.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2022-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "level_zero/sysman/source/linux/fs_access.h" +#include "level_zero/zes_api.h" + +#include + +namespace L0 { +namespace Sysman { + +struct OsSysman; + +class FabricDeviceAccess : NEO::NonCopyableOrMovableClass { + public: + virtual ze_result_t getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) = 0; + virtual ze_result_t getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) = 0; + + virtual ze_result_t getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) = 0; + virtual ze_result_t getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) = 0; + virtual ze_result_t enablePortBeaconing(const zes_fabric_port_id_t portId) = 0; + virtual ze_result_t disablePortBeaconing(const zes_fabric_port_id_t portId) = 0; + virtual ze_result_t enable(const zes_fabric_port_id_t portId) = 0; + virtual ze_result_t disable(const zes_fabric_port_id_t portId) = 0; + virtual ze_result_t enableUsage(const zes_fabric_port_id_t portId) = 0; + virtual ze_result_t disableUsage(const zes_fabric_port_id_t portId) = 0; + virtual ze_result_t forceSweep() = 0; + virtual ze_result_t routingQuery(uint32_t &start, uint32_t &end) = 0; + + virtual ze_result_t getPorts(std::vector &ports) = 0; + virtual void getProperties(const zes_fabric_port_id_t portId, std::string &model, bool &onSubdevice, + uint32_t &subdeviceId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed) = 0; + + virtual ~FabricDeviceAccess() = default; + + static FabricDeviceAccess *create(OsSysman *pOsSysman); +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.cpp b/level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.cpp new file mode 100644 index 0000000000..821b18b54e --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2022-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.h" + +#include "level_zero/sysman/source/linux/os_sysman_imp.h" + +#include + +namespace L0 { +namespace Sysman { + +void FabricDeviceAccessNl::readIafPortStatus(zes_fabric_port_state_t &state, const IafPortState &iafPortState) { + + state.failureReasons = 0; + state.qualityIssues = 0; + switch (iafPortState.healthStatus) { + case IAF_FPORT_HEALTH_OFF: + state.status = ZES_FABRIC_PORT_STATUS_DISABLED; + break; + case IAF_FPORT_HEALTH_FAILED: + state.status = ZES_FABRIC_PORT_STATUS_FAILED; + if (1 == iafPortState.failed || 1 == iafPortState.isolated || 1 == iafPortState.linkDown) { + state.failureReasons |= ZES_FABRIC_PORT_FAILURE_FLAG_FAILED; + } + if (1 == iafPortState.didNotTrain) { + state.failureReasons |= ZES_FABRIC_PORT_FAILURE_FLAG_TRAINING_TIMEOUT; + } + if (1 == iafPortState.flapping) { + state.failureReasons |= ZES_FABRIC_PORT_FAILURE_FLAG_FLAPPING; + } + break; + case IAF_FPORT_HEALTH_DEGRADED: + state.status = ZES_FABRIC_PORT_STATUS_DEGRADED; + if (1 == iafPortState.lqi) { + state.qualityIssues |= ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_LINK_ERRORS; + } + if (1 == iafPortState.lwd || 1 == iafPortState.rate) { + state.qualityIssues |= ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_SPEED; + } + break; + case IAF_FPORT_HEALTH_HEALTHY: + state.status = ZES_FABRIC_PORT_STATUS_HEALTHY; + break; + default: + state.status = ZES_FABRIC_PORT_STATUS_UNKNOWN; + break; + } +} + +ze_result_t FabricDeviceAccessNl::getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) { + IafPortState iafPortState = {}; + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + ze_result_t result = pIafNlApi->fPortStatusQuery(iafPortId, iafPortState); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + readIafPortStatus(state, iafPortState); + + uint64_t guid; + uint8_t portNumber; + IafPortSpeed maxRxSpeed = {}; + IafPortSpeed maxTxSpeed = {}; + IafPortSpeed rxSpeed = {}; + IafPortSpeed txSpeed = {}; + + result = pIafNlApi->fportProperties(iafPortId, guid, portNumber, maxRxSpeed, maxTxSpeed, rxSpeed, txSpeed); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + readIafPortSpeed(state.rxSpeed, rxSpeed); + readIafPortSpeed(state.txSpeed, txSpeed); + + switch (state.status) { + case ZES_FABRIC_PORT_STATUS_HEALTHY: + case ZES_FABRIC_PORT_STATUS_DEGRADED: + case ZES_FABRIC_PORT_STATUS_FAILED: { + auto it = guidMap.find(guid); + + if (guidMap.end() == it) { + populateGuidMap(); + it = guidMap.find(guid); + } + if (guidMap.end() != it) { + state.remotePortId = it->second; + state.remotePortId.portNumber = portNumber; + } + } break; + default: + break; + } + return result; +} + +ze_result_t FabricDeviceAccessNl::getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) { + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + IafPortThroughPut iafThroughPut = {}; + ze_result_t result = pIafNlApi->getThroughput(iafPortId, iafThroughPut); + readIafPortThroughPut(througput, iafThroughPut); + return result; +} + +ze_result_t FabricDeviceAccessNl::getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) { + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portStateQuery(iafPortId, enabled); +} + +ze_result_t FabricDeviceAccessNl::getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) { + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portBeaconStateQuery(iafPortId, enabled); +} + +ze_result_t FabricDeviceAccessNl::enablePortBeaconing(const zes_fabric_port_id_t portId) { + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portBeaconEnable(iafPortId); +} + +ze_result_t FabricDeviceAccessNl::disablePortBeaconing(const zes_fabric_port_id_t portId) { + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portBeaconDisable(iafPortId); +} + +ze_result_t FabricDeviceAccessNl::enable(const zes_fabric_port_id_t portId) { + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portEnable(iafPortId); +} + +ze_result_t FabricDeviceAccessNl::disable(const zes_fabric_port_id_t portId) { + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portDisable(iafPortId); +} + +ze_result_t FabricDeviceAccessNl::enableUsage(const zes_fabric_port_id_t portId) { + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portUsageEnable(iafPortId); +} + +ze_result_t FabricDeviceAccessNl::disableUsage(const zes_fabric_port_id_t portId) { + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portUsageDisable(iafPortId); +} + +ze_result_t FabricDeviceAccessNl::forceSweep() { + return pIafNlApi->remRequest(); +} + +ze_result_t FabricDeviceAccessNl::routingQuery(uint32_t &start, uint32_t &end) { + return pIafNlApi->routingGenQuery(start, end); +} + +ze_result_t FabricDeviceAccessNl::getPorts(std::vector &ports) { + + std::vector iafPorts = {}; + std::string iafRealPath = {}; + pLinuxSysmanImp->getSysfsAccess().getRealPath(iafPath, iafRealPath); + ze_result_t result = pIafNlApi->getPorts(iafRealPath, iafPorts); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + + // Update fabricPorts + for (const auto &iafPort : iafPorts) { + Port port = {}; + readIafPort(port, iafPort); + fabricPorts.push_back(port); + } + + ports.clear(); + for (auto port : fabricPorts) { + ports.push_back(port.portId); + } + return ZE_RESULT_SUCCESS; +} + +void FabricDeviceAccessNl::getProperties(const zes_fabric_port_id_t portId, std::string &model, bool &onSubdevice, + uint32_t &subdeviceId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed) { + for (auto port : fabricPorts) { + UNRECOVERABLE_IF(portId.fabricId != port.portId.fabricId); + if (portId.attachId == port.portId.attachId && portId.portNumber == port.portId.portNumber) { + model = port.model; + onSubdevice = port.onSubdevice; + subdeviceId = port.portId.attachId; + maxRxSpeed = port.maxRxSpeed; + maxTxSpeed = port.maxTxSpeed; + return; + } + } +} + +ze_result_t FabricDeviceAccessNl::getAllFabricIds(std::vector &fabricIds) { + return pIafNlApi->deviceEnum(fabricIds); +} + +ze_result_t FabricDeviceAccessNl::getNumSubdevices(const uint32_t fabricId, uint32_t &numSubdevices) { + return pIafNlApi->fabricDeviceProperties(fabricId, numSubdevices); +} + +ze_result_t FabricDeviceAccessNl::getSubdevice(const uint32_t fabricId, const uint32_t subdevice, uint64_t &guid, std::vector &ports) { + return pIafNlApi->subdevicePropertiesGet(fabricId, subdevice, guid, ports); +} + +void FabricDeviceAccessNl::populateGuidMap() { + std::vector fabricIds; + + if (ZE_RESULT_SUCCESS != getAllFabricIds(fabricIds)) { + return; + } + for (auto fabricId : fabricIds) { + uint32_t numSubdevices = 0; + + if (ZE_RESULT_SUCCESS != getNumSubdevices(fabricId, numSubdevices)) { + return; + } + for (uint32_t subdevice = 0; subdevice < numSubdevices; subdevice++) { + uint64_t guid; + std::vector ports; + + if (ZE_RESULT_SUCCESS != getSubdevice(fabricId, subdevice, guid, ports)) { + return; + } + zes_fabric_port_id_t portId; + + portId.fabricId = fabricId; + portId.attachId = subdevice; + portId.portNumber = ports.size(); + guidMap[guid] = portId; + } + } + return; +} + +FabricDeviceAccessNl::FabricDeviceAccessNl(OsSysman *pOsSysman) { + pLinuxSysmanImp = static_cast(pOsSysman); + pIafNlApi = new IafNlApi; + UNRECOVERABLE_IF(nullptr == pIafNlApi); +} + +FabricDeviceAccessNl::~FabricDeviceAccessNl() { + if (nullptr != pIafNlApi) { + delete pIafNlApi; + pIafNlApi = nullptr; + } +} + +FabricDeviceAccess *FabricDeviceAccess::create(OsSysman *pOsSysman) { + return new FabricDeviceAccessNl(pOsSysman); +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.h b/level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.h new file mode 100644 index 0000000000..61f5ac6a04 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2022-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access.h" +#include "level_zero/sysman/source/linux/nl_api/iaf_nl_api.h" +#include "level_zero/sysman/source/linux/os_sysman_imp.h" + +namespace L0 { +namespace Sysman { + +struct Port { + bool onSubdevice; + zes_fabric_port_id_t portId; + std::string model; + zes_fabric_port_speed_t maxRxSpeed; + zes_fabric_port_speed_t maxTxSpeed; +}; + +class FabricDeviceAccessNl : public FabricDeviceAccess { + public: + FabricDeviceAccessNl() = delete; + FabricDeviceAccessNl(OsSysman *pOsSysman); + ~FabricDeviceAccessNl() override; + + ze_result_t getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) override; + ze_result_t getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) override; + + ze_result_t getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) override; + ze_result_t getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) override; + ze_result_t enablePortBeaconing(const zes_fabric_port_id_t portId) override; + ze_result_t disablePortBeaconing(const zes_fabric_port_id_t portId) override; + ze_result_t enable(const zes_fabric_port_id_t portId) override; + ze_result_t disable(const zes_fabric_port_id_t portId) override; + ze_result_t enableUsage(const zes_fabric_port_id_t portId) override; + ze_result_t disableUsage(const zes_fabric_port_id_t portId) override; + ze_result_t forceSweep() override; + ze_result_t routingQuery(uint32_t &start, uint32_t &end) override; + + ze_result_t getPorts(std::vector &ports) override; + void getProperties(const zes_fabric_port_id_t portId, std::string &model, bool &onSubdevice, + uint32_t &subdeviceId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed) override; + + private: + ze_result_t init(); + void populateGuidMap(); + ze_result_t getAllFabricIds(std::vector &fabricIds); + ze_result_t getNumSubdevices(const uint32_t fabricId, uint32_t &numSubdevices); + ze_result_t getSubdevice(const uint32_t fabricId, const uint32_t subdeviceId, uint64_t &guid, std::vector &ports); + + LinuxSysmanImp *pLinuxSysmanImp = nullptr; + void readIafPort(Port &port, const IafPort &iafPort) { + port.onSubdevice = iafPort.onSubdevice; + readIafPortId(port.portId, iafPort.portId); + port.model = iafPort.model; + readIafPortSpeed(port.maxRxSpeed, iafPort.maxRxSpeed); + readIafPortSpeed(port.maxTxSpeed, iafPort.maxTxSpeed); + } + void readIafPortStatus(zes_fabric_port_state_t &state, const IafPortState &iafPortState); + void readIafPortId(zes_fabric_port_id_t &portId, const IafPortId &iafPortId) { + portId.attachId = iafPortId.attachId; + portId.fabricId = iafPortId.fabricId; + portId.portNumber = iafPortId.portNumber; + } + void readIafPortSpeed(zes_fabric_port_speed_t &speed, const IafPortSpeed &iafPortspeed) { + speed.bitRate = iafPortspeed.bitRate; + speed.width = iafPortspeed.width; + } + + void readIafPortThroughPut(zes_fabric_port_throughput_t &throughPut, const IafPortThroughPut &iafPortThroughPut) { + // Timestamp is cpu timestamp + throughPut.rxCounter = iafPortThroughPut.rxCounter; + throughPut.txCounter = iafPortThroughPut.txCounter; + } + std::map guidMap = {}; + + protected: + IafNlApi *pIafNlApi = nullptr; + std::vector fabricPorts = {}; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.cpp b/level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.cpp new file mode 100644 index 0000000000..e4a6dbe509 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.h" + +#include "level_zero/sysman/source/linux/os_sysman_imp.h" + +namespace L0 { +namespace Sysman { + +ze_result_t FabricDeviceAccessStub::getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::enablePortBeaconing(const zes_fabric_port_id_t portId) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::disablePortBeaconing(const zes_fabric_port_id_t portId) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::enable(const zes_fabric_port_id_t portId) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::disable(const zes_fabric_port_id_t portId) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::enableUsage(const zes_fabric_port_id_t portId) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::disableUsage(const zes_fabric_port_id_t portId) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::forceSweep() { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::routingQuery(uint32_t &start, uint32_t &end) { + return ZE_RESULT_SUCCESS; +} + +ze_result_t FabricDeviceAccessStub::getPorts(std::vector &ports) { + return ZE_RESULT_SUCCESS; +} + +void FabricDeviceAccessStub::getProperties(const zes_fabric_port_id_t portId, std::string &model, bool &onSubdevice, + uint32_t &subdeviceId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed) { + model = ""; + onSubdevice = false; + subdeviceId = 0U; + maxRxSpeed.width = -1; + maxRxSpeed.bitRate = -1L; + maxTxSpeed.width = -1; + maxTxSpeed.bitRate = -1L; +} + +FabricDeviceAccessStub::FabricDeviceAccessStub(OsSysman *pOsSysman) { +} + +FabricDeviceAccessStub::~FabricDeviceAccessStub() { +} + +FabricDeviceAccess *FabricDeviceAccess::create(OsSysman *pOsSysman) { + return new FabricDeviceAccessStub(pOsSysman); +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.h b/level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.h new file mode 100644 index 0000000000..722939ef88 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access.h" + +namespace L0 { +namespace Sysman { + +class FabricDeviceAccessStub : public FabricDeviceAccess { + public: + FabricDeviceAccessStub() = delete; + FabricDeviceAccessStub(OsSysman *pOsSysman); + ~FabricDeviceAccessStub(); + + ze_result_t getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) override; + ze_result_t getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) override; + + ze_result_t getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) override; + ze_result_t getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) override; + ze_result_t enablePortBeaconing(const zes_fabric_port_id_t portId) override; + ze_result_t disablePortBeaconing(const zes_fabric_port_id_t portId) override; + ze_result_t enable(const zes_fabric_port_id_t portId) override; + ze_result_t disable(const zes_fabric_port_id_t portId) override; + ze_result_t enableUsage(const zes_fabric_port_id_t portId) override; + ze_result_t disableUsage(const zes_fabric_port_id_t portId) override; + ze_result_t forceSweep() override; + ze_result_t routingQuery(uint32_t &start, uint32_t &end) override; + + ze_result_t getPorts(std::vector &ports) override; + void getProperties(const zes_fabric_port_id_t portId, std::string &model, bool &onSubdevice, + uint32_t &subdeviceId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed) override; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.cpp b/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.cpp new file mode 100644 index 0000000000..9c91b4fc2a --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.h" + +#include + +namespace L0 { +namespace Sysman { + +uint32_t LinuxFabricDeviceImp::getNumPorts() { + return numPorts; +} + +LinuxFabricDeviceImp::LinuxFabricDeviceImp(OsSysman *pOsSysman) { +} + +LinuxFabricDeviceImp::~LinuxFabricDeviceImp() { +} + +ze_result_t LinuxFabricPortImp::getLinkType(zes_fabric_link_type_t *pLinkType) { + ::snprintf(pLinkType->desc, ZES_MAX_FABRIC_LINK_TYPE_SIZE, "%s", "SAMPLE LINK, VERBOSE"); + return ZE_RESULT_SUCCESS; +} + +ze_result_t LinuxFabricPortImp::getConfig(zes_fabric_port_config_t *pConfig) { + *pConfig = config; + return ZE_RESULT_SUCCESS; +} + +ze_result_t LinuxFabricPortImp::setConfig(const zes_fabric_port_config_t *pConfig) { + config = *pConfig; + return ZE_RESULT_SUCCESS; +} + +ze_result_t LinuxFabricPortImp::getState(zes_fabric_port_state_t *pState) { + pState->status = ZES_FABRIC_PORT_STATUS_UNKNOWN; + pState->qualityIssues = 0U; + pState->failureReasons = 0U; + pState->remotePortId.fabricId = 0U; + pState->remotePortId.attachId = 0U; + pState->remotePortId.portNumber = 0U; + pState->rxSpeed.bitRate = 0LU; + pState->rxSpeed.width = 0U; + pState->txSpeed.bitRate = 0LU; + pState->txSpeed.width = 0U; + return ZE_RESULT_SUCCESS; +} + +ze_result_t LinuxFabricPortImp::getThroughput(zes_fabric_port_throughput_t *pThroughput) { + pThroughput->rxCounter = 0LU; + pThroughput->txCounter = 0LU; + return ZE_RESULT_SUCCESS; +} + +ze_result_t LinuxFabricPortImp::getErrorCounters(zes_fabric_port_error_counters_t *pErrors) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFabricPortImp::getProperties(zes_fabric_port_properties_t *pProperties) { + ::snprintf(pProperties->model, ZES_MAX_FABRIC_PORT_MODEL_SIZE, "%s", this->model.c_str()); + pProperties->onSubdevice = false; + pProperties->subdeviceId = 0U; + pProperties->portId = this->portId; + pProperties->maxRxSpeed = this->maxRxSpeed; + pProperties->maxTxSpeed = this->maxTxSpeed; + return ZE_RESULT_SUCCESS; +} + +LinuxFabricPortImp::LinuxFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum) { + this->portNum = portNum; + model = std::string("EXAMPLE"); +} + +LinuxFabricPortImp::~LinuxFabricPortImp() { +} + +OsFabricDevice *OsFabricDevice::create(OsSysman *pOsSysman) { + LinuxFabricDeviceImp *pLinuxFabricDeviceImp = new LinuxFabricDeviceImp(pOsSysman); + return pLinuxFabricDeviceImp; +} + +OsFabricPort *OsFabricPort::create(OsFabricDevice *pOsFabricDevice, uint32_t portNum) { + LinuxFabricPortImp *pLinuxFabricPortImp = new LinuxFabricPortImp(pOsFabricDevice, portNum); + return pLinuxFabricPortImp; +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.h b/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.h new file mode 100644 index 0000000000..76e7006841 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h" +#include "level_zero/sysman/source/fabric_port/os_fabric_port.h" +#include "level_zero/sysman/source/linux/fs_access.h" + +namespace L0 { +namespace Sysman { + +class LinuxFabricDeviceImp : public OsFabricDevice, NEO::NonCopyableOrMovableClass { + public: + uint32_t getNumPorts() override; + + LinuxFabricDeviceImp() = delete; + LinuxFabricDeviceImp(OsSysman *pOsSysman); + ~LinuxFabricDeviceImp() override; + + private: + uint32_t numPorts = 0; +}; + +class LinuxFabricPortImp : public OsFabricPort, NEO::NonCopyableOrMovableClass { + public: + ze_result_t getProperties(zes_fabric_port_properties_t *pProperties) override; + ze_result_t getLinkType(zes_fabric_link_type_t *pLinkType) override; + ze_result_t getConfig(zes_fabric_port_config_t *pConfig) override; + ze_result_t setConfig(const zes_fabric_port_config_t *pConfig) override; + ze_result_t getState(zes_fabric_port_state_t *pState) override; + ze_result_t getThroughput(zes_fabric_port_throughput_t *pThroughput) override; + ze_result_t getErrorCounters(zes_fabric_port_error_counters_t *pErrors) override; + + LinuxFabricPortImp() = delete; + LinuxFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum); + ~LinuxFabricPortImp() override; + + private: + uint32_t portNum = 0; + std::string model = ""; + zes_fabric_port_id_t portId = {}; + zes_fabric_port_speed_t maxRxSpeed = {}; + zes_fabric_port_speed_t maxTxSpeed = {}; + zes_fabric_port_config_t config = {}; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.cpp b/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.cpp new file mode 100644 index 0000000000..731132a597 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2022-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.h" + +#include "shared/source/debug_settings/debug_settings_manager.h" +#include "shared/source/helpers/debug_helpers.h" + +#include "level_zero/sysman/source/linux/os_sysman_imp.h" + +#include + +namespace L0 { +namespace Sysman { + +uint32_t LinuxFabricDeviceImp::getNumPorts() { + pFabricDeviceAccess->getPorts(portIds); + return static_cast(portIds.size()); +} + +void LinuxFabricDeviceImp::getPortId(uint32_t portNumber, zes_fabric_port_id_t &portId) { + UNRECOVERABLE_IF(getNumPorts() <= portNumber); + portId = portIds[portNumber]; +} + +void LinuxFabricDeviceImp::getProperties(const zes_fabric_port_id_t portId, std::string &model, bool &onSubdevice, + uint32_t &subdeviceId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed) { + pFabricDeviceAccess->getProperties(portId, model, onSubdevice, subdeviceId, maxRxSpeed, maxTxSpeed); +} + +ze_result_t LinuxFabricDeviceImp::getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t *pState) { + return pFabricDeviceAccess->getState(portId, *pState); +} + +ze_result_t LinuxFabricDeviceImp::getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t *pThroughput) { + return pFabricDeviceAccess->getThroughput(portId, *pThroughput); +} + +ze_result_t LinuxFabricDeviceImp::getErrorCounters(const zes_fabric_port_id_t portId, zes_fabric_port_error_counters_t *pErrors) { + FsAccess *pFsAccess = &pLinuxSysmanImp->getFsAccess(); + SysfsAccess *pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess(); + std::string devicePciPath(""); + ze_result_t result = pSysfsAccess->getRealPath("device/", devicePciPath); + if (result != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "error@<%s> \n", __func__, result); + return result; + } + std::string path(""); + std::vector list; + result = pFsAccess->listDirectory(devicePciPath, list); + if (result != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "error@<%s> \n", __func__, result); + return result; + } + + for (auto entry : list) { + if ((entry.find("i915.iaf.") != std::string::npos) || + (entry.find("iaf.") != std::string::npos)) { + path = devicePciPath + "/" + entry; + break; + } + } + if (path.empty()) { + // This device does not have a fabric + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "error@<%s> \n", __func__); + return ZE_RESULT_ERROR_NOT_AVAILABLE; + } + std::string fabricFwErrorPath = path + "/sd." + std::to_string(portId.attachId); + std::string fabricLinkErrorPath = path + "/sd." + std::to_string(portId.attachId) + "/port." + std::to_string(portId.portNumber); + uint64_t linkErrorCount = 0; + std::string linkFailureFile = fabricLinkErrorPath + "/link_failures"; + result = pFsAccess->read(linkFailureFile, linkErrorCount); + if (result != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "error@<%s> \n", __func__, linkFailureFile.c_str(), result); + linkErrorCount = 0; + } + uint64_t linkDegradeCount = 0; + std::string linkDegradeFile = fabricLinkErrorPath + "/link_degrades"; + result = pFsAccess->read(linkDegradeFile, linkDegradeCount); + if (result != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "error@<%s> \n", __func__, linkDegradeFile.c_str(), result); + linkDegradeCount = 0; + } + uint64_t fwErrorCount = 0; + std::string fwErrorFile = fabricFwErrorPath + "/fw_error"; + result = pFsAccess->read(fwErrorFile, fwErrorCount); + if (result != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "error@<%s> \n", __func__, fwErrorFile.c_str(), result); + fwErrorCount = 0; + } + uint64_t fwCommErrorCount = 0; + std::string fwCommErrorFile = fabricFwErrorPath + "/fw_comm_errors"; + result = pFsAccess->read(fwCommErrorFile, fwCommErrorCount); + if (result != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "error@<%s> \n", __func__, fwCommErrorFile.c_str(), result); + fwCommErrorCount = 0; + } + pErrors->linkFailureCount = linkErrorCount; + pErrors->linkDegradeCount = linkDegradeCount; + pErrors->fwErrorCount = fwErrorCount; + pErrors->fwCommErrorCount = fwCommErrorCount; + return ZE_RESULT_SUCCESS; +} +ze_result_t LinuxFabricDeviceImp::performSweep() { + uint32_t start = 0U; + uint32_t end = 0U; + ze_result_t result = ZE_RESULT_SUCCESS; + + result = forceSweep(); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + result = routingQuery(start, end); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + while (end < start) { + uint32_t newStart; + result = routingQuery(newStart, end); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + } + return result; +} + +ze_result_t LinuxFabricDeviceImp::getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) { + return pFabricDeviceAccess->getPortEnabledState(portId, enabled); +} + +ze_result_t LinuxFabricDeviceImp::enablePort(const zes_fabric_port_id_t portId) { + ze_result_t result = enable(portId); + // usage should be enabled, but make sure in case of previous errors + enableUsage(portId); + return result; +} + +ze_result_t LinuxFabricDeviceImp::disablePort(const zes_fabric_port_id_t portId) { + ze_result_t result = ZE_RESULT_SUCCESS; + result = disableUsage(portId); + if (ZE_RESULT_SUCCESS == result) { + result = disable(portId); + if (ZE_RESULT_SUCCESS == result) { + return enableUsage(portId); + } + } + // Try not so leave port usage disabled on an error + enableUsage(portId); + return result; +} + +ze_result_t LinuxFabricDeviceImp::getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) { + return pFabricDeviceAccess->getPortBeaconState(portId, enabled); +} + +ze_result_t LinuxFabricDeviceImp::enablePortBeaconing(const zes_fabric_port_id_t portId) { + return pFabricDeviceAccess->enablePortBeaconing(portId); +} + +ze_result_t LinuxFabricDeviceImp::disablePortBeaconing(const zes_fabric_port_id_t portId) { + return pFabricDeviceAccess->disablePortBeaconing(portId); +} + +ze_result_t LinuxFabricDeviceImp::enable(const zes_fabric_port_id_t portId) { + ze_result_t result = ZE_RESULT_SUCCESS; + result = pFabricDeviceAccess->enable(portId); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + return performSweep(); +} + +ze_result_t LinuxFabricDeviceImp::disable(const zes_fabric_port_id_t portId) { + ze_result_t result = ZE_RESULT_SUCCESS; + result = pFabricDeviceAccess->disable(portId); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + return performSweep(); +} + +ze_result_t LinuxFabricDeviceImp::enableUsage(const zes_fabric_port_id_t portId) { + ze_result_t result = ZE_RESULT_SUCCESS; + result = pFabricDeviceAccess->enableUsage(portId); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + return performSweep(); +} + +ze_result_t LinuxFabricDeviceImp::disableUsage(const zes_fabric_port_id_t portId) { + ze_result_t result = ZE_RESULT_SUCCESS; + result = pFabricDeviceAccess->disableUsage(portId); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + return performSweep(); +} + +ze_result_t LinuxFabricDeviceImp::forceSweep() { + return pFabricDeviceAccess->forceSweep(); +} + +ze_result_t LinuxFabricDeviceImp::routingQuery(uint32_t &start, uint32_t &end) { + return pFabricDeviceAccess->routingQuery(start, end); +} + +LinuxFabricDeviceImp::LinuxFabricDeviceImp(OsSysman *pOsSysman) { + pFabricDeviceAccess = FabricDeviceAccess::create(pOsSysman); + UNRECOVERABLE_IF(nullptr == pFabricDeviceAccess); + pLinuxSysmanImp = static_cast(pOsSysman); +} + +LinuxFabricDeviceImp::~LinuxFabricDeviceImp() { + delete pFabricDeviceAccess; +} + +ze_result_t LinuxFabricPortImp::getLinkType(zes_fabric_link_type_t *pLinkType) { + ::snprintf(pLinkType->desc, ZES_MAX_FABRIC_LINK_TYPE_SIZE, "%s", "XeLink"); + return ZE_RESULT_SUCCESS; +} + +ze_result_t LinuxFabricPortImp::getConfig(zes_fabric_port_config_t *pConfig) { + ze_result_t result = ZE_RESULT_SUCCESS; + bool enabled = false; + result = pLinuxFabricDeviceImp->getPortEnabledState(portId, enabled); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + pConfig->enabled = enabled == true; + result = pLinuxFabricDeviceImp->getPortBeaconState(portId, enabled); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + pConfig->beaconing = enabled == true; + return result; +} + +ze_result_t LinuxFabricPortImp::setConfig(const zes_fabric_port_config_t *pConfig) { + ze_result_t result = ZE_RESULT_SUCCESS; + + bool enabled = false; + result = pLinuxFabricDeviceImp->getPortEnabledState(portId, enabled); + if (ZE_RESULT_SUCCESS == result && enabled != pConfig->enabled) { + if (pConfig->enabled) { + result = pLinuxFabricDeviceImp->enablePort(portId); + } else { + result = pLinuxFabricDeviceImp->disablePort(portId); + } + } + if (ZE_RESULT_SUCCESS != result) { + return result; + } + + bool beaconing = false; + result = pLinuxFabricDeviceImp->getPortBeaconState(portId, beaconing); + if (ZE_RESULT_SUCCESS == result && beaconing != pConfig->beaconing) { + if (pConfig->beaconing) { + result = pLinuxFabricDeviceImp->enablePortBeaconing(portId); + } else { + result = pLinuxFabricDeviceImp->disablePortBeaconing(portId); + } + } + return result; +} + +ze_result_t LinuxFabricPortImp::getState(zes_fabric_port_state_t *pState) { + return pLinuxFabricDeviceImp->getState(portId, pState); +} + +ze_result_t LinuxFabricPortImp::getThroughput(zes_fabric_port_throughput_t *pThroughput) { + return pLinuxFabricDeviceImp->getThroughput(portId, pThroughput); +} + +ze_result_t LinuxFabricPortImp::getErrorCounters(zes_fabric_port_error_counters_t *pErrors) { + return pLinuxFabricDeviceImp->getErrorCounters(portId, pErrors); +} + +ze_result_t LinuxFabricPortImp::getProperties(zes_fabric_port_properties_t *pProperties) { + ::snprintf(pProperties->model, ZES_MAX_FABRIC_PORT_MODEL_SIZE, "%s", this->model.c_str()); + pProperties->onSubdevice = this->onSubdevice; + pProperties->subdeviceId = this->subdeviceId; + pProperties->portId = this->portId; + pProperties->maxRxSpeed = this->maxRxSpeed; + pProperties->maxTxSpeed = this->maxTxSpeed; + return ZE_RESULT_SUCCESS; +} + +LinuxFabricPortImp::LinuxFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum) { + pLinuxFabricDeviceImp = static_cast(pOsFabricDevice); + this->portNum = portNum; + pLinuxFabricDeviceImp->getPortId(this->portNum, this->portId); + pLinuxFabricDeviceImp->getProperties(this->portId, this->model, this->onSubdevice, this->subdeviceId, this->maxRxSpeed, this->maxTxSpeed); +} + +LinuxFabricPortImp::~LinuxFabricPortImp() { +} + +OsFabricDevice *OsFabricDevice::create(OsSysman *pOsSysman) { + LinuxFabricDeviceImp *pLinuxFabricDeviceImp = new LinuxFabricDeviceImp(pOsSysman); + return pLinuxFabricDeviceImp; +} + +OsFabricPort *OsFabricPort::create(OsFabricDevice *pOsFabricDevice, uint32_t portNum) { + LinuxFabricPortImp *pLinuxFabricPortImp = new LinuxFabricPortImp(pOsFabricDevice, portNum); + return pLinuxFabricPortImp; +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.h b/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.h new file mode 100644 index 0000000000..5b2ef31a0e --- /dev/null +++ b/level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2022-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h" +#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access.h" +#include "level_zero/sysman/source/fabric_port/os_fabric_port.h" + +#include + +namespace L0 { +namespace Sysman { +class LinuxSysmanImp; +class LinuxFabricDeviceImp : public OsFabricDevice, NEO::NonCopyableOrMovableClass { + public: + uint32_t getNumPorts() override; + + ze_result_t performSweep(); + ze_result_t getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled); + ze_result_t enablePort(const zes_fabric_port_id_t portId); + ze_result_t disablePort(const zes_fabric_port_id_t portId); + ze_result_t getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled); + ze_result_t enablePortBeaconing(const zes_fabric_port_id_t portId); + ze_result_t disablePortBeaconing(const zes_fabric_port_id_t portId); + ze_result_t getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t *pState); + ze_result_t getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t *pThroughput); + ze_result_t getErrorCounters(const zes_fabric_port_id_t portId, zes_fabric_port_error_counters_t *pErrors); + + void getPortId(const uint32_t portNumber, zes_fabric_port_id_t &portId); + void getProperties(const zes_fabric_port_id_t portId, std::string &model, bool &onSubdevice, + uint32_t &subdeviceId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed); + + LinuxFabricDeviceImp() = delete; + LinuxFabricDeviceImp(OsSysman *pOsSysman); + ~LinuxFabricDeviceImp() override; + + private: + std::vector portIds = {}; + + ze_result_t forceSweep(); + ze_result_t routingQuery(uint32_t &start, uint32_t &end); + ze_result_t enable(const zes_fabric_port_id_t portId); + ze_result_t disable(const zes_fabric_port_id_t portId); + ze_result_t enableUsage(const zes_fabric_port_id_t portId); + ze_result_t disableUsage(const zes_fabric_port_id_t portId); + + protected: + LinuxSysmanImp *pLinuxSysmanImp = nullptr; + FabricDeviceAccess *pFabricDeviceAccess = nullptr; +}; + +class LinuxFabricPortImp : public OsFabricPort, NEO::NonCopyableOrMovableClass { + public: + ze_result_t getProperties(zes_fabric_port_properties_t *pProperties) override; + ze_result_t getLinkType(zes_fabric_link_type_t *pLinkType) override; + ze_result_t getConfig(zes_fabric_port_config_t *pConfig) override; + ze_result_t setConfig(const zes_fabric_port_config_t *pConfig) override; + ze_result_t getState(zes_fabric_port_state_t *pState) override; + ze_result_t getThroughput(zes_fabric_port_throughput_t *pThroughput) override; + ze_result_t getErrorCounters(zes_fabric_port_error_counters_t *pErrors) override; + + LinuxFabricPortImp() = delete; + LinuxFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum); + ~LinuxFabricPortImp() override; + + private: + LinuxFabricDeviceImp *pLinuxFabricDeviceImp = nullptr; + + uint32_t portNum = 0; + zes_fabric_port_id_t portId = {}; + std::string model = ""; + bool onSubdevice = false; + uint32_t subdeviceId; + zes_fabric_port_speed_t maxRxSpeed = {}; + zes_fabric_port_speed_t maxTxSpeed = {}; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/os_fabric_port.h b/level_zero/sysman/source/fabric_port/os_fabric_port.h new file mode 100644 index 0000000000..6ff0e763c5 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/os_fabric_port.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "level_zero/sysman/source/os_sysman.h" +#include + +namespace L0 { +namespace Sysman { + +class OsFabricDevice { + public: + virtual uint32_t getNumPorts() = 0; + + static OsFabricDevice *create(OsSysman *pOsSysman); + + virtual ~OsFabricDevice() = default; +}; + +class OsFabricPort { + public: + virtual ze_result_t getProperties(zes_fabric_port_properties_t *pProperties) = 0; + virtual ze_result_t getLinkType(zes_fabric_link_type_t *pLinkType) = 0; + virtual ze_result_t getConfig(zes_fabric_port_config_t *pConfig) = 0; + virtual ze_result_t setConfig(const zes_fabric_port_config_t *pConfig) = 0; + virtual ze_result_t getState(zes_fabric_port_state_t *pState) = 0; + virtual ze_result_t getThroughput(zes_fabric_port_throughput_t *pThroughput) = 0; + virtual ze_result_t getErrorCounters(zes_fabric_port_error_counters_t *pErrors) = 0; + + static OsFabricPort *create(OsFabricDevice *pOsFabricDevice, uint32_t portNum); + + virtual ~OsFabricPort() = default; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/windows/CMakeLists.txt b/level_zero/sysman/source/fabric_port/windows/CMakeLists.txt new file mode 100644 index 0000000000..d0218384b2 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/windows/CMakeLists.txt @@ -0,0 +1,21 @@ +# +# Copyright (C) 2020-2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(L0_SRCS_SYSMAN_FABRICPORT_WINDOWS + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp.h +) + +if(WIN32) + target_sources(${L0_STATIC_LIB_NAME} + PRIVATE + ${L0_SRCS_SYSMAN_FABRICPORT_WINDOWS} + ) +endif() + +## Make our source files visible to parent +set_property(GLOBAL PROPERTY L0_SRCS_SYSMAN_FABRICPORT_WINDOWS ${L0_SRCS_SYSMAN_FABRICPORT_WINDOWS}) diff --git a/level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.cpp b/level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.cpp new file mode 100644 index 0000000000..af589ade1a --- /dev/null +++ b/level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.h" + +#include + +namespace L0 { +namespace Sysman { + +uint32_t WddmFabricDeviceImp::getNumPorts() { + return numPorts; +} + +WddmFabricDeviceImp::WddmFabricDeviceImp(OsSysman *pOsSysman) { +} + +WddmFabricDeviceImp::~WddmFabricDeviceImp() { +} + +ze_result_t WddmFabricPortImp::getLinkType(zes_fabric_link_type_t *pLinkType) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t WddmFabricPortImp::getConfig(zes_fabric_port_config_t *pConfig) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t WddmFabricPortImp::setConfig(const zes_fabric_port_config_t *pConfig) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t WddmFabricPortImp::getState(zes_fabric_port_state_t *pState) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t WddmFabricPortImp::getThroughput(zes_fabric_port_throughput_t *pThroughput) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t WddmFabricPortImp::getErrorCounters(zes_fabric_port_error_counters_t *pErrors) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t WddmFabricPortImp::getProperties(zes_fabric_port_properties_t *pProperties) { + ::memset(pProperties->model, '\0', ZES_MAX_FABRIC_PORT_MODEL_SIZE); + pProperties->onSubdevice = false; + pProperties->subdeviceId = 0U; + ::memset(&pProperties->portId, '\0', sizeof(pProperties->portId)); + ::memset(&pProperties->maxRxSpeed, '\0', sizeof(pProperties->maxRxSpeed)); + ::memset(&pProperties->maxTxSpeed, '\0', sizeof(pProperties->maxTxSpeed)); + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +WddmFabricPortImp::WddmFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum) { +} + +WddmFabricPortImp::~WddmFabricPortImp() { +} + +OsFabricDevice *OsFabricDevice::create(OsSysman *pOsSysman) { + WddmFabricDeviceImp *pWddmFabricDeviceImp = new WddmFabricDeviceImp(pOsSysman); + return pWddmFabricDeviceImp; +} + +OsFabricPort *OsFabricPort::create(OsFabricDevice *pOsFabricDevice, uint32_t portNum) { + WddmFabricPortImp *pWddmFabricPortImp = new WddmFabricPortImp(pOsFabricDevice, portNum); + return pWddmFabricPortImp; +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.h b/level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.h new file mode 100644 index 0000000000..a3a6419022 --- /dev/null +++ b/level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h" +#include "level_zero/sysman/source/fabric_port/os_fabric_port.h" + +namespace L0 { +namespace Sysman { + +class WddmFabricDeviceImp : public OsFabricDevice, NEO::NonCopyableOrMovableClass { + public: + uint32_t getNumPorts() override; + + WddmFabricDeviceImp() = delete; + WddmFabricDeviceImp(OsSysman *pOsSysman); + ~WddmFabricDeviceImp() override; + + private: + uint32_t numPorts = 0; +}; + +class WddmFabricPortImp : public OsFabricPort, NEO::NonCopyableOrMovableClass { + public: + ze_result_t getProperties(zes_fabric_port_properties_t *pProperties) override; + ze_result_t getLinkType(zes_fabric_link_type_t *pLinkType) override; + ze_result_t getConfig(zes_fabric_port_config_t *pConfig) override; + ze_result_t setConfig(const zes_fabric_port_config_t *pConfig) override; + ze_result_t getState(zes_fabric_port_state_t *pState) override; + ze_result_t getThroughput(zes_fabric_port_throughput_t *pThroughput) override; + ze_result_t getErrorCounters(zes_fabric_port_error_counters_t *pErrors) override; + + WddmFabricPortImp() = delete; + WddmFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum); + ~WddmFabricPortImp() override; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/linux/nl_api/CMakeLists.txt b/level_zero/sysman/source/linux/nl_api/CMakeLists.txt new file mode 100644 index 0000000000..b8a60c044e --- /dev/null +++ b/level_zero/sysman/source/linux/nl_api/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# Copyright (C) 2020-2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(LIBGENL_FOUND) + set(L0_SRCS_SYSMAN_LINUX_NL_API + ${CMAKE_CURRENT_SOURCE_DIR}/nl_api.h + ${CMAKE_CURRENT_SOURCE_DIR}/nl_api.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/iaf_nl_api.h + ${CMAKE_CURRENT_SOURCE_DIR}/iaf_nl_api.cpp + ) +endif() + +if(UNIX) + target_sources(${L0_STATIC_LIB_NAME} + PRIVATE + ${L0_SRCS_SYSMAN_LINUX_NL_API} + ) +endif() + +# Make our source files visible to parent +set_property(GLOBAL PROPERTY L0_SRCS_SYSMAN_LINUX_NL_API ${L0_SRCS_SYSMAN_LINUX_NL_API}) diff --git a/level_zero/sysman/source/linux/nl_api/iaf_nl_api.cpp b/level_zero/sysman/source/linux/nl_api/iaf_nl_api.cpp new file mode 100644 index 0000000000..df7f69efe7 --- /dev/null +++ b/level_zero/sysman/source/linux/nl_api/iaf_nl_api.cpp @@ -0,0 +1,871 @@ +/* + * Copyright (C) 2022-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/linux/nl_api/iaf_nl_api.h" + +#include "shared/source/os_interface/linux/sys_calls.h" +#include "shared/source/utilities/directory.h" + +#include +#include +#include +#include +#include +#include + +namespace L0 { +namespace Sysman { + +extern "C" { + +// C linkage callback routines for Netlink +static int globalHandleMsg(struct nl_msg *msg, void *arg) { + IafNlApi *pIafNlApi = reinterpret_cast(arg); + return pIafNlApi->handleMsg(msg); +} + +static int globalNlOperation(struct nl_cache_ops *ops, struct genl_cmd *cmd, struct genl_info *info, void *arg) { + IafNlApi *pIafNlApi = reinterpret_cast(arg); + return pIafNlApi->nlOperation(ops, cmd, info); +} +} + +static const struct { + int id; + char *name; +} iafCmds[] = { + {.id = IAF_CMD_OP_DEVICE_ENUM, .name = const_cast("DEVICE_ENUM")}, + {.id = IAF_CMD_OP_PORT_ENABLE, .name = const_cast("PORT_ENABLE")}, + {.id = IAF_CMD_OP_PORT_DISABLE, .name = const_cast("PORT_DISABLE")}, + {.id = IAF_CMD_OP_PORT_STATE_QUERY, .name = const_cast("PORT_STATE_QUERY")}, + {.id = IAF_CMD_OP_PORT_USAGE_ENABLE, .name = const_cast("PORT_USAGE_ENABLE")}, + {.id = IAF_CMD_OP_PORT_USAGE_DISABLE, .name = const_cast("PORT_USAGE_DISABLE")}, + {.id = IAF_CMD_OP_PORT_USAGE_STATE_QUERY, .name = const_cast("PORT_USAGE_STATE_QUERY")}, + {.id = IAF_CMD_OP_PORT_BEACON_ENABLE, .name = const_cast("PORT_BEACON_ENABLE")}, + {.id = IAF_CMD_OP_PORT_BEACON_DISABLE, .name = const_cast("PORT_BEACON_DISABLE")}, + {.id = IAF_CMD_OP_PORT_BEACON_STATE_QUERY, .name = const_cast("PORT_BEACON_STATE_QUERY")}, + {.id = IAF_CMD_OP_PORT_ROUTED_QUERY, .name = const_cast("PORT_ROUTED_QUERY")}, + {.id = IAF_CMD_OP_REM_REQUEST, .name = const_cast("REM_REQUEST")}, + {.id = IAF_CMD_OP_ROUTING_GEN_QUERY, .name = const_cast("ROUTING_GEN_QUERY")}, + {.id = IAF_CMD_OP_FABRIC_DEVICE_PROPERTIES, .name = const_cast("FABRIC_DEVICE_PROPERTIES")}, + {.id = IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET, .name = const_cast("SUB_DEVICE_PROPERTIES_GET")}, + {.id = IAF_CMD_OP_FPORT_STATUS_QUERY, .name = const_cast("FPORT_STATUS_QUERY")}, + {.id = IAF_CMD_OP_SUB_DEVICE_TRAP_COUNT_QUERY, .name = const_cast("FPORT_EVENT_COUNT_QUERY")}, + {.id = IAF_CMD_OP_FPORT_PROPERTIES, .name = const_cast("FPORT_PROPERTIES")}, + {.id = IAF_CMD_OP_FPORT_XMIT_RECV_COUNTS, .name = const_cast("FPORT_XMIT_RECV_COUNTS")}, + {.id = 0, .name = nullptr}, +}; + +struct PortProperties { + uint64_t neighborGuid; + uint8_t neighborPortNumber; + int32_t enabledRxWidth; + int64_t enabledRxBitrate; + int32_t activeRxWidth; + int64_t activeRxBitrate; + int32_t enabledTxWidth; + int64_t enabledTxBitrate; + int32_t activeTxWidth; + int64_t activeTxBitrate; +}; + +struct Subdevice { + uint64_t guid; + std::vector ports; +}; + +struct Generation { + uint32_t start; + uint32_t end; +}; + +ze_result_t IafNlApi::allocMsg(const uint16_t cmdOp, struct nl_msg *&msg) { + msg = pNlApi->nlmsgAlloc(); + if (nullptr == msg) { + return ZE_RESULT_ERROR_UNKNOWN; + } + + if (nullptr == pNlApi->genlmsgPut(msg, NL_AUTO_PID, NL_AUTO_SEQ, familyId, 0, 0, cmdOp, 1)) { + pNlApi->nlmsgFree(msg); + msg = nullptr; + return ZE_RESULT_ERROR_UNKNOWN; + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::issueRequest(const uint16_t cmdOp, const uint32_t fabricId, const uint32_t attachId, const uint8_t portNumber, void *pOutput) { + ze_result_t result = init(); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + struct nl_msg *msg; + result = allocMsg(cmdOp, msg); + if (ZE_RESULT_SUCCESS == result) { + pNlApi->nlaPutU32(msg, IAF_ATTR_FABRIC_ID, fabricId); + pNlApi->nlaPutU8(msg, IAF_ATTR_SD_INDEX, attachId); + pNlApi->nlaPutU8(msg, IAF_ATTR_FABRIC_PORT_NUMBER, portNumber); + result = performTransaction(cmdOp, msg, pOutput); + } + cleanup(); + return result; +} + +ze_result_t IafNlApi::issueRequest(const uint16_t cmdOp, const uint32_t fabricId, const uint32_t attachId, void *pOutput) { + ze_result_t result = init(); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + struct nl_msg *msg; + result = allocMsg(cmdOp, msg); + if (ZE_RESULT_SUCCESS == result) { + pNlApi->nlaPutU32(msg, IAF_ATTR_FABRIC_ID, fabricId); + pNlApi->nlaPutU8(msg, IAF_ATTR_SD_INDEX, attachId); + result = performTransaction(cmdOp, msg, pOutput); + } + cleanup(); + return result; +} + +ze_result_t IafNlApi::issueRequest(const uint16_t cmdOp, const uint32_t fabricId, void *pOutput) { + ze_result_t result = init(); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + struct nl_msg *msg; + result = allocMsg(cmdOp, msg); + if (ZE_RESULT_SUCCESS == result) { + pNlApi->nlaPutU32(msg, IAF_ATTR_FABRIC_ID, fabricId); + result = performTransaction(cmdOp, msg, pOutput); + } + cleanup(); + return result; +} + +ze_result_t IafNlApi::issueRequest(const uint16_t cmdOp, void *pOutput) { + ze_result_t result = init(); + if (ZE_RESULT_SUCCESS != result) { + return result; + } + struct nl_msg *msg; + result = allocMsg(cmdOp, msg); + if (ZE_RESULT_SUCCESS == result) { + result = performTransaction(cmdOp, msg, pOutput); + } + cleanup(); + return result; +} + +ze_result_t IafNlApi::performTransaction(const uint16_t cmdOp, struct nl_msg *msg, void *pOutput) { + Operation *pOperation = new Operation(cmdOp, pOutput); + uint64_t context = reinterpret_cast(pOperation); + + pNlApi->nlaPutU64(msg, IAF_ATTR_CMD_OP_CONTEXT, context); + pNlApi->nlaPutU8(msg, IAF_ATTR_CMD_OP_MSG_TYPE, IAF_CMD_MSG_REQUEST); + + validContexts.push_back(context); + if (0 > pNlApi->nlSendAuto(nlSock, msg)) { + pOperation->done = true; + } + pNlApi->nlmsgFree(msg); + + while (!pOperation->done) { + int res = pNlApi->nlRecvmsgsDefault(nlSock); + if (0 > res) { + if (-NLE_PERM == res) { + pOperation->result = ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS; + } + pOperation->done = true; + } + } + validContexts.remove(context); + + ze_result_t result = pOperation->result; + delete pOperation; + return result; +} + +ze_result_t IafNlApi::handleResponse(const uint16_t cmdOp, struct genl_info *info, void *pOutput) { + switch (cmdOp) { + case IAF_CMD_OP_FPORT_STATUS_QUERY: + return fPortStatusQueryRsp(info, pOutput); + case IAF_CMD_OP_FPORT_XMIT_RECV_COUNTS: + return getThroughputRsp(info, pOutput); + case IAF_CMD_OP_PORT_STATE_QUERY: + return portStateQueryRsp(info, pOutput); + case IAF_CMD_OP_PORT_BEACON_STATE_QUERY: + return portBeaconStateQueryRsp(info, pOutput); + case IAF_CMD_OP_ROUTING_GEN_QUERY: + return routingGenQueryRsp(info, pOutput); + case IAF_CMD_OP_DEVICE_ENUM: + return deviceEnumRsp(info, pOutput); + case IAF_CMD_OP_FABRIC_DEVICE_PROPERTIES: + return fabricDevicePropertiesRsp(info, pOutput); + case IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET: + return subdevicePropertiesGetRsp(info, pOutput); + case IAF_CMD_OP_FPORT_PROPERTIES: + return fportPropertiesRsp(info, pOutput); + case IAF_CMD_OP_PORT_BEACON_ENABLE: + case IAF_CMD_OP_PORT_BEACON_DISABLE: + case IAF_CMD_OP_PORT_ENABLE: + case IAF_CMD_OP_PORT_DISABLE: + case IAF_CMD_OP_PORT_USAGE_ENABLE: + case IAF_CMD_OP_PORT_USAGE_DISABLE: + case IAF_CMD_OP_REM_REQUEST: + return ZE_RESULT_SUCCESS; + default: + return ZE_RESULT_ERROR_UNKNOWN; + } +} + +ze_result_t IafNlApi::fPortStatusQueryRsp(struct genl_info *info, void *pOutput) { + IafPortState *pState = reinterpret_cast(pOutput); + + const struct nlmsghdr *nlh = info->nlh; + auto nla = pNlApi->nlmsgAttrdata(nlh, GENL_HDRLEN); + auto rem = pNlApi->nlmsgAttrlen(nlh, GENL_HDRLEN); + for (; pNlApi->nlaOk(nla, rem); nla = pNlApi->nlaNext(nla, &(rem))) { + if (pNlApi->nlaType(nla) == IAF_ATTR_FABRIC_PORT) { + auto cur = (struct nlattr *)pNlApi->nlaData(nla); + auto rem = pNlApi->nlaLen(nla); + for (; pNlApi->nlaOk(cur, rem); cur = pNlApi->nlaNext(cur, &(rem))) { + switch (pNlApi->nlaType(cur)) { + case IAF_ATTR_FPORT_HEALTH: + pState->healthStatus = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FPORT_ISSUE_LQI: + pState->lqi = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FPORT_ISSUE_LWD: + pState->lwd = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FPORT_ISSUE_RATE: + pState->rate = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FPORT_ERROR_FAILED: + pState->failed = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FPORT_ERROR_ISOLATED: + pState->isolated = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FPORT_ERROR_FLAPPING: + pState->flapping = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FPORT_ERROR_LINK_DOWN: + pState->linkDown = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FPORT_ERROR_DID_NOT_TRAIN: + pState->didNotTrain = pNlApi->nlaGetU8(cur); + break; + default: + break; + } + } + } + } + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::getThroughputRsp(struct genl_info *info, void *pOutput) { + IafPortThroughPut *pThroughput = reinterpret_cast(pOutput); + pThroughput->txCounter = 0UL; + pThroughput->rxCounter = 0UL; + if (info->attrs[IAF_ATTR_FPORT_TX_BYTES]) { + pThroughput->txCounter = pNlApi->nlaGetU64(info->attrs[IAF_ATTR_FPORT_TX_BYTES]); + } + if (info->attrs[IAF_ATTR_FPORT_RX_BYTES]) { + pThroughput->rxCounter = pNlApi->nlaGetU64(info->attrs[IAF_ATTR_FPORT_RX_BYTES]); + } + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::portStateQueryRsp(struct genl_info *info, void *pOutput) { + bool *pEnabled = reinterpret_cast(pOutput); + const struct nlmsghdr *nlh = info->nlh; + + *pEnabled = false; + auto nla = pNlApi->nlmsgAttrdata(nlh, GENL_HDRLEN); + auto rem = pNlApi->nlmsgAttrlen(nlh, GENL_HDRLEN); + for (; pNlApi->nlaOk(nla, rem); nla = pNlApi->nlaNext(nla, &(rem))) { + if (pNlApi->nlaIsNested(nla)) { + auto cur = (struct nlattr *)pNlApi->nlaData(nla); + auto rem = pNlApi->nlaLen(nla); + for (; pNlApi->nlaOk(cur, rem); cur = pNlApi->nlaNext(cur, &(rem))) { + switch (pNlApi->nlaType(cur)) { + case IAF_ATTR_ENABLED_STATE: + *pEnabled = (0 != pNlApi->nlaGetU8(cur)); + break; + default: + break; + } + } + } + } + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::portBeaconStateQueryRsp(struct genl_info *info, void *pOutput) { + bool *pEnabled = reinterpret_cast(pOutput); + const struct nlmsghdr *nlh = info->nlh; + + *pEnabled = false; + auto nla = pNlApi->nlmsgAttrdata(nlh, GENL_HDRLEN); + auto rem = pNlApi->nlmsgAttrlen(nlh, GENL_HDRLEN); + for (; pNlApi->nlaOk(nla, rem); nla = pNlApi->nlaNext(nla, &(rem))) { + if (pNlApi->nlaIsNested(nla)) { + auto cur = (struct nlattr *)pNlApi->nlaData(nla); + auto rem = pNlApi->nlaLen(nla); + for (; pNlApi->nlaOk(cur, rem); cur = pNlApi->nlaNext(cur, &(rem))) { + switch (pNlApi->nlaType(cur)) { + case IAF_ATTR_ENABLED_STATE: + *pEnabled = (0 != pNlApi->nlaGetU8(cur)); + break; + default: + break; + } + } + } + } + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::routingGenQueryRsp(struct genl_info *info, void *pOutput) { + Generation *pGeneration = reinterpret_cast(pOutput); + if (info->attrs[IAF_ATTR_ROUTING_GEN_START]) { + pGeneration->start = pNlApi->nlaGetU32(info->attrs[IAF_ATTR_ROUTING_GEN_START]); + } + + if (info->attrs[IAF_ATTR_ROUTING_GEN_END]) { + pGeneration->end = pNlApi->nlaGetU32(info->attrs[IAF_ATTR_ROUTING_GEN_END]); + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::deviceEnumRsp(struct genl_info *info, void *pOutput) { + std::vector *pFabricIds = reinterpret_cast *>(pOutput); + const struct nlmsghdr *nlh = info->nlh; + + pFabricIds->clear(); + auto nla = pNlApi->nlmsgAttrdata(nlh, GENL_HDRLEN); + auto rem = pNlApi->nlmsgAttrlen(nlh, GENL_HDRLEN); + for (; pNlApi->nlaOk(nla, rem); nla = pNlApi->nlaNext(nla, &(rem))) { + if (pNlApi->nlaIsNested(nla)) { + auto cur = (struct nlattr *)pNlApi->nlaData(nla); + auto rem = pNlApi->nlaLen(nla); + for (; pNlApi->nlaOk(cur, rem); cur = pNlApi->nlaNext(cur, &(rem))) { + switch (pNlApi->nlaType(cur)) { + case IAF_ATTR_FABRIC_ID: + pFabricIds->push_back(pNlApi->nlaGetU32(cur)); + break; + default: + break; + } + } + } + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::fabricDevicePropertiesRsp(struct genl_info *info, void *pOutput) { + uint32_t *pNumSubdevices = reinterpret_cast(pOutput); + + *pNumSubdevices = 0; + if (info->attrs[IAF_ATTR_SUBDEVICE_COUNT]) { + *pNumSubdevices = pNlApi->nlaGetU8(info->attrs[IAF_ATTR_SUBDEVICE_COUNT]); + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::subdevicePropertiesGetRsp(struct genl_info *info, void *pOutput) { + Subdevice *pSubdevice = reinterpret_cast(pOutput); + const struct nlmsghdr *nlh = info->nlh; + + if (info->attrs[IAF_ATTR_GUID]) { + pSubdevice->guid = pNlApi->nlaGetU64(info->attrs[IAF_ATTR_GUID]); + } + + auto nla = pNlApi->nlmsgAttrdata(nlh, GENL_HDRLEN); + auto rem = pNlApi->nlmsgAttrlen(nlh, GENL_HDRLEN); + for (; pNlApi->nlaOk(nla, rem); nla = pNlApi->nlaNext(nla, &(rem))) { + if (pNlApi->nlaType(nla) == IAF_ATTR_FABRIC_PORT) { + uint8_t port = 0; + uint8_t type = IAF_FPORT_TYPE_DISCONNECTED; + + auto cur = (struct nlattr *)pNlApi->nlaData(nla); + auto rem = pNlApi->nlaLen(nla); + for (; pNlApi->nlaOk(cur, rem); cur = pNlApi->nlaNext(cur, &(rem))) { + switch (pNlApi->nlaType(cur)) { + case IAF_ATTR_FABRIC_PORT_NUMBER: + port = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FABRIC_PORT_TYPE: + type = pNlApi->nlaGetU8(cur); + break; + default: + break; + } + } + if (0 != port && IAF_FPORT_TYPE_DISCONNECTED != type) { + pSubdevice->ports.push_back(port); + } + } + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::fportPropertiesRsp(struct genl_info *info, void *pOutput) { + PortProperties *pPortProperties = reinterpret_cast(pOutput); + const struct nlmsghdr *nlh = info->nlh; + + auto nla = pNlApi->nlmsgAttrdata(nlh, GENL_HDRLEN); + auto rem = pNlApi->nlmsgAttrlen(nlh, GENL_HDRLEN); + for (; pNlApi->nlaOk(nla, rem); nla = pNlApi->nlaNext(nla, &(rem))) { + if (pNlApi->nlaType(nla) == IAF_ATTR_FABRIC_PORT) { + int32_t activeWidth = -1; + int32_t degradedRxWidth = -1; + int32_t degradedTxWidth = -1; + int64_t activeBitrate = -1; + int64_t maxBitrate = -1; + + auto cur = (struct nlattr *)pNlApi->nlaData(nla); + auto rem = pNlApi->nlaLen(nla); + for (; pNlApi->nlaOk(cur, rem); cur = pNlApi->nlaNext(cur, &(rem))) { + switch (pNlApi->nlaType(cur)) { + case IAF_ATTR_FPORT_NEIGHBOR_GUID: + pPortProperties->neighborGuid = pNlApi->nlaGetU64(cur); + break; + case IAF_ATTR_FPORT_NEIGHBOR_PORT_NUMBER: + pPortProperties->neighborPortNumber = pNlApi->nlaGetU8(cur); + break; + case IAF_ATTR_FPORT_LINK_WIDTH_ENABLED: + pPortProperties->enabledRxWidth = pPortProperties->enabledTxWidth = translateWidth(pNlApi->nlaGetU8(cur)); + break; + case IAF_ATTR_FPORT_LINK_WIDTH_ACTIVE: + activeWidth = translateWidth(pNlApi->nlaGetU8(cur)); + break; + case IAF_ATTR_FPORT_BPS_LINK_SPEED_ACTIVE: + activeBitrate = pNlApi->nlaGetU64(cur); + break; + case IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_RX_ACTIVE: + degradedRxWidth = translateWidth(pNlApi->nlaGetU8(cur)); + break; + case IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_TX_ACTIVE: + degradedTxWidth = translateWidth(pNlApi->nlaGetU8(cur)); + break; + case IAF_ATTR_FPORT_BPS_LINK_SPEED_MAX: + maxBitrate = pNlApi->nlaGetU64(cur); + break; + default: + break; + } + } + if (-1 != degradedRxWidth) { + pPortProperties->activeRxWidth = degradedRxWidth; + } else { + pPortProperties->activeRxWidth = activeWidth; + } + if (-1 != degradedTxWidth) { + pPortProperties->activeTxWidth = degradedTxWidth; + } else { + pPortProperties->activeTxWidth = activeWidth; + } + if (0 != activeBitrate) { + pPortProperties->activeRxBitrate = pPortProperties->activeTxBitrate = activeBitrate; + } + if (0 != maxBitrate) { + pPortProperties->enabledRxBitrate = pPortProperties->enabledTxBitrate = maxBitrate; + } + } + } + + return ZE_RESULT_SUCCESS; +} + +int32_t IafNlApi::translateWidth(uint8_t width) { + if (width & 0x8) { + return 4; + } + if (width & 0x4) { + return 3; + } + if (width & 0x2) { + return 2; + } + if (width & 0x1) { + return 1; + } + return -1; +} + +ze_result_t IafNlApi::fPortStatusQuery(const IafPortId portId, IafPortState &state) { + return issueRequest(IAF_CMD_OP_FPORT_STATUS_QUERY, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast(&state)); +} + +ze_result_t IafNlApi::getThroughput(const IafPortId portId, IafPortThroughPut &throughput) { + return issueRequest(IAF_CMD_OP_FPORT_XMIT_RECV_COUNTS, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast(&throughput)); +} + +ze_result_t IafNlApi::portStateQuery(const IafPortId portId, bool &enabled) { + return issueRequest(IAF_CMD_OP_PORT_STATE_QUERY, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast(&enabled)); +} + +ze_result_t IafNlApi::portBeaconStateQuery(const IafPortId portId, bool &enabled) { + return issueRequest(IAF_CMD_OP_PORT_BEACON_STATE_QUERY, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast(&enabled)); +} + +ze_result_t IafNlApi::portBeaconEnable(const IafPortId portId) { + return issueRequest(IAF_CMD_OP_PORT_BEACON_ENABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); +} + +ze_result_t IafNlApi::portBeaconDisable(const IafPortId portId) { + return issueRequest(IAF_CMD_OP_PORT_BEACON_DISABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); +} + +ze_result_t IafNlApi::portEnable(const IafPortId portId) { + return issueRequest(IAF_CMD_OP_PORT_ENABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); +} + +ze_result_t IafNlApi::portDisable(const IafPortId portId) { + return issueRequest(IAF_CMD_OP_PORT_DISABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); +} + +ze_result_t IafNlApi::portUsageEnable(const IafPortId portId) { + return issueRequest(IAF_CMD_OP_PORT_USAGE_ENABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); +} + +ze_result_t IafNlApi::portUsageDisable(const IafPortId portId) { + return issueRequest(IAF_CMD_OP_PORT_USAGE_DISABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); +} + +ze_result_t IafNlApi::remRequest() { + return issueRequest(IAF_CMD_OP_REM_REQUEST, nullptr); +} + +ze_result_t IafNlApi::routingGenQuery(uint32_t &start, uint32_t &end) { + Generation gen; + gen.start = gen.end = 0; + + ze_result_t result = issueRequest(IAF_CMD_OP_ROUTING_GEN_QUERY, reinterpret_cast(&gen)); + if (ZE_RESULT_SUCCESS == result) { + start = gen.start; + end = gen.end; + } + return result; +} + +ze_result_t IafNlApi::deviceEnum(std::vector &fabricIds) { + return issueRequest(IAF_CMD_OP_DEVICE_ENUM, reinterpret_cast(&fabricIds)); +} + +ze_result_t IafNlApi::fabricDeviceProperties(const uint32_t fabricId, uint32_t &numSubdevices) { + return issueRequest(IAF_CMD_OP_FABRIC_DEVICE_PROPERTIES, fabricId, reinterpret_cast(&numSubdevices)); +} + +ze_result_t IafNlApi::subdevicePropertiesGet(const uint32_t fabricId, const uint32_t attachId, uint64_t &guid, std::vector &ports) { + Subdevice sd; + sd.guid = 0; + sd.ports.clear(); + + ze_result_t result = issueRequest(IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET, fabricId, attachId, reinterpret_cast(&sd)); + if (ZE_RESULT_SUCCESS == result) { + guid = sd.guid; + ports = sd.ports; + } + return result; +} + +ze_result_t IafNlApi::fportProperties(const IafPortId portId, uint64_t &neighborGuid, uint8_t &neighborPortNumber, + IafPortSpeed &maxRxSpeed, IafPortSpeed &maxTxSpeed, + IafPortSpeed &rxSpeed, IafPortSpeed &txSpeed) { + PortProperties portProperties; + portProperties.neighborGuid = 0UL; + portProperties.neighborPortNumber = 0U; + portProperties.enabledRxWidth = -1; + portProperties.enabledRxBitrate = -1L; + portProperties.activeRxWidth = -1; + portProperties.activeRxBitrate = -1L; + portProperties.enabledTxWidth = -1; + portProperties.enabledTxBitrate = -1L; + portProperties.activeTxWidth = -1; + portProperties.activeTxBitrate = -1L; + + ze_result_t result = issueRequest(IAF_CMD_OP_FPORT_PROPERTIES, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast(&portProperties)); + if (ZE_RESULT_SUCCESS == result) { + neighborGuid = portProperties.neighborGuid; + neighborPortNumber = portProperties.neighborPortNumber; + maxRxSpeed.width = portProperties.enabledRxWidth; + maxRxSpeed.bitRate = portProperties.enabledRxBitrate; + rxSpeed.width = portProperties.activeRxWidth; + rxSpeed.bitRate = portProperties.activeRxBitrate; + maxTxSpeed.width = portProperties.enabledTxWidth; + maxTxSpeed.bitRate = portProperties.enabledTxBitrate; + txSpeed.width = portProperties.activeTxWidth; + txSpeed.bitRate = portProperties.activeTxBitrate; + } + return result; +} + +int IafNlApi::handleMsg(struct nl_msg *msg) { + return pNlApi->genlHandleMsg(msg, reinterpret_cast(this)); +} + +int IafNlApi::nlOperation(struct nl_cache_ops *ops, struct genl_cmd *cmd, struct genl_info *info) { + if (info->attrs[IAF_ATTR_CMD_OP_CONTEXT]) { + uint64_t context = pNlApi->nlaGetU64(info->attrs[IAF_ATTR_CMD_OP_CONTEXT]); + bool found = false; + for (auto i : validContexts) { + if (context == i) { + found = true; + break; + } + } + if (!found) { + return NL_STOP; + } + Operation *pOperation = reinterpret_cast(context); + if (cmd->c_id == pOperation->cmdOp && info->attrs[IAF_ATTR_CMD_OP_RESULT] && info->attrs[IAF_ATTR_CMD_OP_MSG_TYPE]) { + if ((pNlApi->nlaGetU8(info->attrs[IAF_ATTR_CMD_OP_MSG_TYPE]) == IAF_CMD_MSG_RESPONSE) && (pNlApi->nlaGetU8(info->attrs[IAF_ATTR_CMD_OP_RESULT]) == IAF_CMD_RSP_SUCCESS)) { + pOperation->result = handleResponse(pOperation->cmdOp, info, pOperation->pOutput); + } + } + pOperation->done = true; + } + return NL_OK; +} + +ze_result_t IafNlApi::init() { + if (!pNlApi) { + return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } + if (!initted) { + if (!pNlApi->loadEntryPoints()) { + pNlApi.reset(nullptr); + return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } + initted = true; + } + + int retval = pNlApi->genlRegisterFamily(&ops); + if (-NLE_EXIST == retval) { + // Temporary error + return ZE_RESULT_NOT_READY; + } else if (!retval) { + nlSock = pNlApi->nlSocketAlloc(); + if (nullptr != nlSock) { + if (!pNlApi->genlConnect(nlSock)) { + if (!pNlApi->genlOpsResolve(nlSock, &ops)) { + familyId = pNlApi->genlCtrlResolve(nlSock, std::string(ops.o_name).c_str()); + if (0 <= familyId) { + if (!pNlApi->nlSocketModifyCb(nlSock, NL_CB_VALID, NL_CB_CUSTOM, + globalHandleMsg, reinterpret_cast(this))) { + pNlApi->nlSocketDisableSeqCheck(nlSock); + return ZE_RESULT_SUCCESS; + } + } + } + } + pNlApi->nlSocketFree(nlSock); + nlSock = nullptr; + } + pNlApi->genlUnregisterFamily(&ops); + } + return ZE_RESULT_ERROR_UNKNOWN; +} + +void IafNlApi::cleanup() { + pNlApi->nlSocketFree(nlSock); + nlSock = nullptr; + pNlApi->genlUnregisterFamily(&ops); +} + +ze_result_t IafNlApi::initPorts(const uint32_t fabricId, std::vector &iafPorts) { + uint32_t numSubdevices; + + if (ZE_RESULT_SUCCESS != fabricDeviceProperties(fabricId, numSubdevices)) { + return ZE_RESULT_ERROR_UNKNOWN; + } + for (uint32_t subdevice = 0; subdevice < numSubdevices; subdevice++) { + uint64_t guid; + std::vector ports; + + if (ZE_RESULT_SUCCESS != subdevicePropertiesGet(fabricId, subdevice, guid, ports)) { + iafPorts.clear(); + return ZE_RESULT_ERROR_UNKNOWN; + } + for (auto port : ports) { + IafPort p = {}; + IafPortSpeed rxSpeed, txSpeed; + uint8_t neighbourPortNumber = 0; + uint64_t neighbourGuid = 0; + p.onSubdevice = numSubdevices > 1; + p.portId.fabricId = fabricId; + p.portId.attachId = subdevice; + p.portId.portNumber = port; + p.model = "XeLink"; + if (ZE_RESULT_SUCCESS != fportProperties(p.portId, neighbourGuid, neighbourPortNumber, + p.maxRxSpeed, p.maxTxSpeed, rxSpeed, txSpeed)) { + iafPorts.clear(); + return ZE_RESULT_ERROR_UNKNOWN; + } + iafPorts.push_back(p); + } + } + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::getPorts(const std::string &devicePciPath, std::vector &ports) { + + std::string path; + path.clear(); + std::vector list = NEO::Directory::getFiles(devicePciPath); + for (auto entry : list) { + if ((entry.find(iafDirectory) != std::string::npos) || + (entry.find(iafDirectoryLegacy) != std::string::npos)) { + path = entry + fabricIdFile; + break; + } + } + if (path.empty()) { + // This device does not have a fabric + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + std::string fabricIdStr(64, '\0'); + int fd = NEO::SysCalls::open(path.c_str(), O_RDONLY); + if (fd < 0) { + return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } + + ssize_t bytesRead = NEO::SysCalls::pread(fd, fabricIdStr.data(), fabricIdStr.size() - 1, 0); + NEO::SysCalls::close(fd); + if (bytesRead <= 0) { + return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } + unsigned long myFabricId = 0UL; + size_t end = 0; + myFabricId = std::stoul(fabricIdStr, &end, 16); + if (myFabricId > std::numeric_limits::max()) { + return ZE_RESULT_ERROR_UNKNOWN; + } + if (ZE_RESULT_SUCCESS != initPorts(static_cast(myFabricId), ports)) { + return ZE_RESULT_ERROR_UNKNOWN; + } + + return ZE_RESULT_SUCCESS; +} + +IafNlApi::IafNlApi() { + validContexts.clear(); + pNlApi.reset(new NlApi); + + memset(policy, 0, sizeof(nla_policy) * _IAF_ATTR_COUNT); + + policy[IAF_ATTR_CMD_OP_MSG_TYPE].type = NLA_U8; + policy[IAF_ATTR_CMD_OP_CONTEXT].type = NLA_U64; + policy[IAF_ATTR_CMD_OP_RESULT].type = NLA_U8; + policy[IAF_ATTR_FABRIC_ID].type = NLA_U32; + policy[IAF_ATTR_SD_INDEX].type = NLA_U8; + policy[IAF_ATTR_ENTRIES].type = NLA_U16; + policy[IAF_ATTR_FABRIC_DEVICE].type = NLA_NESTED; + policy[IAF_ATTR_DEV_NAME].type = NLA_NUL_STRING; + policy[IAF_ATTR_PARENT_DEV_NAME].type = NLA_NUL_STRING; + policy[IAF_ATTR_SOCKET_ID].type = NLA_U8; + policy[IAF_ATTR_PCI_SLOT_NUM].type = NLA_U8; + policy[IAF_ATTR_SUBDEVICE_COUNT].type = NLA_U8; + policy[IAF_ATTR_VERSION].type = NLA_U8; + policy[IAF_ATTR_PRODUCT_TYPE].type = NLA_U8; + policy[IAF_ATTR_SUB_DEVICE].type = NLA_NESTED; + policy[IAF_ATTR_GUID].type = NLA_U64; + policy[IAF_ATTR_EXTENDED_PORT_COUNT].type = NLA_U8; + policy[IAF_ATTR_FABRIC_PORT_COUNT].type = NLA_U8; + policy[IAF_ATTR_SWITCH_LIFETIME].type = NLA_U8; + policy[IAF_ATTR_ROUTING_MODE_SUPPORTED].type = NLA_U8; + policy[IAF_ATTR_ROUTING_MODE_ENABLED].type = NLA_U8; + policy[IAF_ATTR_EHHANCED_PORT_0_PRESENT].type = NLA_U8; + policy[IAF_ATTR_FABRIC_PORT].type = NLA_NESTED; + policy[IAF_ATTR_FABRIC_PORT_NUMBER].type = NLA_U8; + policy[IAF_ATTR_FABRIC_PORT_TYPE].type = NLA_U8; + policy[IAF_ATTR_BRIDGE_PORT_NUMBER].type = NLA_U8; + policy[IAF_ATTR_ENABLED_STATE].type = NLA_U8; + policy[IAF_ATTR_ROUTING_GEN_START].type = NLA_U32; + policy[IAF_ATTR_ROUTING_GEN_END].type = NLA_U32; + policy[IAF_ATTR_FPORT_HEALTH].type = NLA_U8; + policy[IAF_ATTR_FPORT_ISSUE_LQI].type = NLA_U8; + policy[IAF_ATTR_FPORT_ISSUE_LWD].type = NLA_U8; + policy[IAF_ATTR_FPORT_ISSUE_RATE].type = NLA_U8; + policy[IAF_ATTR_FPORT_ERROR_FAILED].type = NLA_U8; + policy[IAF_ATTR_FPORT_ERROR_ISOLATED].type = NLA_U8; + policy[IAF_ATTR_FPORT_ERROR_FLAPPING].type = NLA_U8; + policy[IAF_ATTR_FPORT_ERROR_LINK_DOWN].type = NLA_U8; + policy[IAF_ATTR_FPORT_ERROR_DID_NOT_TRAIN].type = NLA_U8; + policy[IAF_ATTR_SUB_DEVICE_TRAP_COUNT].type = NLA_U64; + policy[IAF_ATTR_FPORT_PM_PORT_STATE].type = NLA_U8; + policy[IAF_ATTR_FPORT_ROUTED].type = NLA_U8; + policy[IAF_ATTR_FPORT_LOGICAL_STATE].type = NLA_U8; + policy[IAF_ATTR_FPORT_PHYSICAL_STATE].type = NLA_U8; + policy[IAF_ATTR_FPORT_FID].type = NLA_U32; + policy[IAF_ATTR_FPORT_LINK_DOWN_COUNT].type = NLA_U32; + policy[IAF_ATTR_FPORT_NEIGHBOR_GUID].type = NLA_U64; + policy[IAF_ATTR_FPORT_PORT_ERROR_ACTION].type = NLA_U32; + policy[IAF_ATTR_FPORT_NEIGHBOR_PORT_NUMBER].type = NLA_U8; + policy[IAF_ATTR_FPORT_PORT_LINK_MODE_ACTIVE].type = NLA_U8; + policy[IAF_ATTR_FPORT_NEIGHBOR_LINK_DOWN_REASON].type = NLA_U8; + policy[IAF_ATTR_FPORT_H_O_Q_LIFETIME].type = NLA_U8; + policy[IAF_ATTR_FPORT_VL_CAP].type = NLA_U8; + policy[IAF_ATTR_FPORT_OPERATIONAL_VLS].type = NLA_U8; + policy[IAF_ATTR_FPORT_NEIGHBOR_MTU].type = NLA_U8; + policy[IAF_ATTR_FPORT_LTP_CRC_MODE_SUPPORTED].type = NLA_U8; + policy[IAF_ATTR_FPORT_LTP_CRC_MODE_ENABLED].type = NLA_U8; + policy[IAF_ATTR_FPORT_LTP_CRC_MODE_ACTIVE].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_WIDTH_SUPPORTED].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_WIDTH_ENABLED].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_WIDTH_ACTIVE].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_SPEED_SUPPORTED].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_SPEED_ENABLED].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_SPEED_ACTIVE].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_RX_ACTIVE].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_TX_ACTIVE].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_INIT_REASON].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_DOWN_REASON].type = NLA_U8; + policy[IAF_ATTR_FPORT_LQI_OFFLINE_DISABLED_REASON].type = NLA_U8; + policy[IAF_ATTR_FPORT_LQI_NEIGHBOR_NORMAL].type = NLA_U8; + policy[IAF_ATTR_FPORT_LINK_QUALITY_INDICATOR].type = NLA_U8; + policy[IAF_ATTR_FPORT_BPS_LINK_SPEED_ACTIVE].type = NLA_U64; + policy[IAF_ATTR_TIMESTAMP].type = NLA_U64; + policy[IAF_ATTR_FPORT_TX_BYTES].type = NLA_U64; + policy[IAF_ATTR_FPORT_RX_BYTES].type = NLA_U64; + policy[IAF_ATTR_FPORT_BPS_LINK_SPEED_MAX].type = NLA_U64; + policy[IAF_ATTR_FPORT_LQI_CHANGE_COUNT].type = NLA_U32; + + int i; + memset(cmds, 0, sizeof(genl_cmd) * _IAF_CMD_OP_COUNT); + for (i = 0; nullptr != iafCmds[i].name; i++) { + cmds[i].c_id = iafCmds[i].id; + cmds[i].c_name = iafCmds[i].name; + cmds[i].c_maxattr = _IAF_ATTR_COUNT - 1, + cmds[i].c_msg_parser = &globalNlOperation, + cmds[i].c_attr_policy = policy; + } + + ops.o_name = const_cast("iaf_ze"); + ops.o_hdrsize = 0U; + ops.o_cmds = cmds; + ops.o_ncmds = i; +} + +IafNlApi::~IafNlApi() { + if (nullptr != nlSock) { + pNlApi->nlSocketFree(nlSock); + nlSock = nullptr; + } +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/linux/nl_api/iaf_nl_api.h b/level_zero/sysman/source/linux/nl_api/iaf_nl_api.h new file mode 100644 index 0000000000..0533a1b1b0 --- /dev/null +++ b/level_zero/sysman/source/linux/nl_api/iaf_nl_api.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2022-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/sysman/source/linux/nl_api/nl_api.h" +#include + +#include "iaf/iaf_netlink.h" + +#include +#include +#include +#include +#include + +namespace L0 { +namespace Sysman { + +const std::string iafPath = "device/"; +const std::string iafDirectoryLegacy = "iaf."; +const std::string iafDirectory = "i915.iaf."; +const std::string fabricIdFile = "/iaf_fabric_id"; + +class IafNlApi; + +class Operation { + public: + uint16_t cmdOp; + bool done = false; + void *pOutput; + ze_result_t result = ZE_RESULT_ERROR_UNKNOWN; + Operation(uint16_t cmdOp, void *pOutput) : cmdOp(cmdOp), pOutput(pOutput) {} +}; + +struct IafPortId { + uint32_t fabricId = 0; + uint32_t attachId = 0; + uint8_t portNumber = 0; + + constexpr IafPortId(uint32_t fabricId, uint32_t attachId, uint32_t portNumber) : fabricId(fabricId), attachId(attachId), portNumber(portNumber) {} + IafPortId() = default; +}; + +struct IafPortSpeed { + int64_t bitRate = 0; + int32_t width = 0; +}; + +struct IafPortThroughPut { + uint64_t timestamp = 0; + uint64_t rxCounter = 0; + uint64_t txCounter = 0; +}; + +struct IafPortState { + uint8_t healthStatus = 0; + uint8_t lqi = 0; + uint8_t lwd = 0; + uint8_t rate = 0; + uint8_t failed = 0; + uint8_t isolated = 0; + uint8_t flapping = 0; + uint8_t linkDown = 0; + uint8_t didNotTrain = 0; +}; + +struct IafPort { + bool onSubdevice = false; + IafPortId portId = {}; + std::string model = {}; + IafPortSpeed maxRxSpeed = {}; + IafPortSpeed maxTxSpeed = {}; +}; + +class IafNlApi { + public: + IafNlApi(); + virtual ~IafNlApi(); + + MOCKABLE_VIRTUAL ze_result_t handleResponse(const uint16_t cmdOp, struct genl_info *info, void *pOutput); + MOCKABLE_VIRTUAL ze_result_t fPortStatusQuery(const IafPortId portId, IafPortState &state); + MOCKABLE_VIRTUAL ze_result_t getThroughput(const IafPortId portId, IafPortThroughPut &throughput); + MOCKABLE_VIRTUAL ze_result_t portStateQuery(const IafPortId portId, bool &enabled); + MOCKABLE_VIRTUAL ze_result_t portBeaconStateQuery(const IafPortId portId, bool &enabled); + MOCKABLE_VIRTUAL ze_result_t portBeaconEnable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portBeaconDisable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portEnable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portDisable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portUsageEnable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portUsageDisable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t remRequest(); + MOCKABLE_VIRTUAL ze_result_t routingGenQuery(uint32_t &start, uint32_t &end); + MOCKABLE_VIRTUAL ze_result_t deviceEnum(std::vector &fabricIds); + MOCKABLE_VIRTUAL ze_result_t fabricDeviceProperties(const uint32_t fabricId, uint32_t &numSubdevices); + MOCKABLE_VIRTUAL ze_result_t subdevicePropertiesGet(const uint32_t fabricId, const uint32_t attachId, uint64_t &guid, std::vector &ports); + MOCKABLE_VIRTUAL ze_result_t fportProperties(const IafPortId portId, uint64_t &neighborGuid, uint8_t &neighborPortNumber, + IafPortSpeed &maxRxSpeed, IafPortSpeed &maxTxSpeed, + IafPortSpeed &rxSpeed, IafPortSpeed &txSpeed); + MOCKABLE_VIRTUAL ze_result_t getPorts(const std::string &devicePciPath, std::vector &ports); + std::list validContexts = {}; + + int handleMsg(struct nl_msg *msg); + int nlOperation(struct nl_cache_ops *ops, struct genl_cmd *cmd, struct genl_info *info); + + protected: + std::unique_ptr pNlApi; + ze_result_t init(); + void cleanup(); + + private: + ze_result_t allocMsg(const uint16_t cmdOp, struct nl_msg *&msg); + ze_result_t issueRequest(const uint16_t cmdOp, const uint32_t fabricId, const uint32_t attachId, const uint8_t portNumber, void *pOutput); + ze_result_t issueRequest(const uint16_t cmdOp, const uint32_t fabricId, const uint32_t attachId, void *pOutput); + ze_result_t issueRequest(const uint16_t cmdOp, const uint32_t fabricId, void *pOutput); + ze_result_t issueRequest(const uint16_t cmdOp, void *pOutput); + ze_result_t performTransaction(const uint16_t cmdOp, struct nl_msg *msg, void *pOutput); + ze_result_t fPortStatusQueryRsp(struct genl_info *info, void *pOutput); + ze_result_t getThroughputRsp(struct genl_info *info, void *pOutput); + ze_result_t portStateQueryRsp(struct genl_info *info, void *pOutput); + ze_result_t portBeaconStateQueryRsp(struct genl_info *info, void *pOutput); + ze_result_t routingGenQueryRsp(struct genl_info *info, void *pOutput); + ze_result_t deviceEnumRsp(struct genl_info *info, void *pOutput); + ze_result_t fabricDevicePropertiesRsp(struct genl_info *info, void *pOutput); + ze_result_t subdevicePropertiesGetRsp(struct genl_info *info, void *pOutput); + ze_result_t fportPropertiesRsp(struct genl_info *info, void *pOutput); + ze_result_t initPorts(const uint32_t fabricId, std::vector &iafPorts); + int32_t translateWidth(uint8_t width); + + bool initted = false; + struct nl_sock *nlSock = nullptr; + int familyId = 0; + + struct nla_policy policy[_IAF_ATTR_COUNT] = {}; + struct genl_cmd cmds[_IAF_CMD_OP_COUNT] = {}; + struct genl_ops ops = {}; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/linux/nl_api/nl_api.cpp b/level_zero/sysman/source/linux/nl_api/nl_api.cpp new file mode 100644 index 0000000000..f0449d9ed3 --- /dev/null +++ b/level_zero/sysman/source/linux/nl_api/nl_api.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "nl_api.h" + +#include "shared/source/helpers/debug_helpers.h" +#include "shared/source/os_interface/os_library.h" + +namespace L0 { +namespace Sysman { + +static constexpr std::string_view libgenlFile = "libnl-genl-3.so.200"; +static constexpr std::string_view genlConnectRoutine = "genl_connect"; +static constexpr std::string_view genlCtrlResolveRoutine = "genl_ctrl_resolve"; +static constexpr std::string_view genlHandleMsgRoutine = "genl_handle_msg"; +static constexpr std::string_view genlmsgPutRoutine = "genlmsg_put"; +static constexpr std::string_view genlOpsResolveRoutine = "genl_ops_resolve"; +static constexpr std::string_view genlRegisterFamilyRoutine = "genl_register_family"; +static constexpr std::string_view genlUnregisterFamilyRoutine = "genl_unregister_family"; +static constexpr std::string_view nlRecvmsgsDefaultRoutine = "nl_recvmsgs_default"; +static constexpr std::string_view nlSendAutoRoutine = "nl_send_auto"; +static constexpr std::string_view nlSocketAllocRoutine = "nl_socket_alloc"; +static constexpr std::string_view nlSocketDisableSeqCheckRoutine = "nl_socket_disable_seq_check"; +static constexpr std::string_view nlSocketFreeRoutine = "nl_socket_free"; +static constexpr std::string_view nlSocketModifyCbRoutine = "nl_socket_modify_cb"; +static constexpr std::string_view nlaDataRoutine = "nla_data"; +static constexpr std::string_view nlaGetU32Routine = "nla_get_u32"; +static constexpr std::string_view nlaGetU64Routine = "nla_get_u64"; +static constexpr std::string_view nlaGetU8Routine = "nla_get_u8"; +static constexpr std::string_view nlaIsNestedRoutine = "nla_is_nested"; +static constexpr std::string_view nlaLenRoutine = "nla_len"; +static constexpr std::string_view nlaNextRoutine = "nla_next"; +static constexpr std::string_view nlaOkRoutine = "nla_ok"; +static constexpr std::string_view nlaPutU16Routine = "nla_put_u16"; +static constexpr std::string_view nlaPutU32Routine = "nla_put_u32"; +static constexpr std::string_view nlaPutU64Routine = "nla_put_u64"; +static constexpr std::string_view nlaPutU8Routine = "nla_put_u8"; +static constexpr std::string_view nlaTypeRoutine = "nla_type"; +static constexpr std::string_view nlmsgAllocRoutine = "nlmsg_alloc"; +static constexpr std::string_view nlmsgAttrdataRoutine = "nlmsg_attrdata"; +static constexpr std::string_view nlmsgAttrlenRoutine = "nlmsg_attrlen"; +static constexpr std::string_view nlmsgFreeRoutine = "nlmsg_free"; +static constexpr std::string_view nlmsgHdrRoutine = "nlmsg_hdr"; + +template +bool NlApi::getSymbolAddr(const std::string_view &name, T &sym) { + sym = reinterpret_cast(genlLibraryHandle->getProcAddress(std::string(name))); + return nullptr != sym; +} + +bool NlApi::loadEntryPoints() { + if (!isAvailable()) + return false; + + bool ok = true; + ok = getSymbolAddr(genlConnectRoutine, genlConnectEntry); + ok = ok && getSymbolAddr(genlCtrlResolveRoutine, genlCtrlResolveEntry); + ok = ok && getSymbolAddr(genlHandleMsgRoutine, genlHandleMsgEntry); + ok = ok && getSymbolAddr(genlmsgPutRoutine, genlmsgPutEntry); + ok = ok && getSymbolAddr(genlOpsResolveRoutine, genlOpsResolveEntry); + ok = ok && getSymbolAddr(genlRegisterFamilyRoutine, genlRegisterFamilyEntry); + ok = ok && getSymbolAddr(genlUnregisterFamilyRoutine, genlUnregisterFamilyEntry); + ok = ok && getSymbolAddr(nlRecvmsgsDefaultRoutine, nlRecvmsgsDefaultEntry); + ok = ok && getSymbolAddr(nlSendAutoRoutine, nlSendAutoEntry); + ok = ok && getSymbolAddr(nlSocketAllocRoutine, nlSocketAllocEntry); + ok = ok && getSymbolAddr(nlSocketDisableSeqCheckRoutine, nlSocketDisableSeqCheckEntry); + ok = ok && getSymbolAddr(nlSocketFreeRoutine, nlSocketFreeEntry); + ok = ok && getSymbolAddr(nlSocketModifyCbRoutine, nlSocketModifyCbEntry); + ok = ok && getSymbolAddr(nlaDataRoutine, nlaDataEntry); + ok = ok && getSymbolAddr(nlaGetU32Routine, nlaGetU32Entry); + ok = ok && getSymbolAddr(nlaGetU64Routine, nlaGetU64Entry); + ok = ok && getSymbolAddr(nlaGetU8Routine, nlaGetU8Entry); + ok = ok && getSymbolAddr(nlaIsNestedRoutine, nlaIsNestedEntry); + ok = ok && getSymbolAddr(nlaLenRoutine, nlaLenEntry); + ok = ok && getSymbolAddr(nlaNextRoutine, nlaNextEntry); + ok = ok && getSymbolAddr(nlaOkRoutine, nlaOkEntry); + ok = ok && getSymbolAddr(nlaPutU16Routine, nlaPutU16Entry); + ok = ok && getSymbolAddr(nlaPutU32Routine, nlaPutU32Entry); + ok = ok && getSymbolAddr(nlaPutU64Routine, nlaPutU64Entry); + ok = ok && getSymbolAddr(nlaPutU8Routine, nlaPutU8Entry); + ok = ok && getSymbolAddr(nlaTypeRoutine, nlaTypeEntry); + ok = ok && getSymbolAddr(nlmsgAllocRoutine, nlmsgAllocEntry); + ok = ok && getSymbolAddr(nlmsgAttrdataRoutine, nlmsgAttrdataEntry); + ok = ok && getSymbolAddr(nlmsgAttrlenRoutine, nlmsgAttrlenEntry); + ok = ok && getSymbolAddr(nlmsgFreeRoutine, nlmsgFreeEntry); + ok = ok && getSymbolAddr(nlmsgHdrRoutine, nlmsgHdrEntry); + + return ok; +} + +int NlApi::genlConnect(struct nl_sock *sock) { + UNRECOVERABLE_IF(nullptr == genlConnectEntry); + return (*genlConnectEntry)(sock); +} + +int NlApi::genlCtrlResolve(struct nl_sock *sock, const char *name) { + UNRECOVERABLE_IF(nullptr == genlCtrlResolveEntry); + return (*genlCtrlResolveEntry)(sock, name); +} + +int NlApi::genlHandleMsg(struct nl_msg *msg, void *arg) { + UNRECOVERABLE_IF(nullptr == genlHandleMsgEntry); + return (*genlHandleMsgEntry)(msg, arg); +} + +void *NlApi::genlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version) { + UNRECOVERABLE_IF(nullptr == genlmsgPutEntry); + return (*genlmsgPutEntry)(msg, port, seq, family, hdrlen, flags, cmd, version); +} + +int NlApi::genlOpsResolve(struct nl_sock *sock, struct genl_ops *ops) { + UNRECOVERABLE_IF(nullptr == genlOpsResolveEntry); + return (*genlOpsResolveEntry)(sock, ops); +} + +int NlApi::genlRegisterFamily(struct genl_ops *ops) { + UNRECOVERABLE_IF(nullptr == genlRegisterFamilyEntry); + return (*genlRegisterFamilyEntry)(ops); +} + +int NlApi::genlUnregisterFamily(struct genl_ops *ops) { + UNRECOVERABLE_IF(nullptr == genlUnregisterFamilyEntry); + return (*genlUnregisterFamilyEntry)(ops); +} + +int NlApi::nlRecvmsgsDefault(struct nl_sock *sock) { + UNRECOVERABLE_IF(nullptr == nlRecvmsgsDefaultEntry); + return (*nlRecvmsgsDefaultEntry)(sock); +} + +int NlApi::nlSendAuto(struct nl_sock *sock, struct nl_msg *msg) { + UNRECOVERABLE_IF(nullptr == nlSendAutoEntry); + return (*nlSendAutoEntry)(sock, msg); +} + +struct nl_sock *NlApi::nlSocketAlloc() { + UNRECOVERABLE_IF(nullptr == nlSocketAllocEntry); + return (*nlSocketAllocEntry)(); +} + +void NlApi::nlSocketDisableSeqCheck(struct nl_sock *sock) { + UNRECOVERABLE_IF(nullptr == nlSocketDisableSeqCheckEntry); + (*nlSocketDisableSeqCheckEntry)(sock); + return; +} + +void NlApi::nlSocketFree(struct nl_sock *sock) { + UNRECOVERABLE_IF(nullptr == nlSocketFreeEntry); + (*nlSocketFreeEntry)(sock); + return; +} + +int NlApi::nlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg) { + UNRECOVERABLE_IF(nullptr == nlSocketModifyCbEntry); + return (*nlSocketModifyCbEntry)(sock, type, kind, cb, arg); +} + +void *NlApi::nlaData(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaDataEntry); + return (*nlaDataEntry)(attr); +} + +uint32_t NlApi::nlaGetU32(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaGetU32Entry); + return (*nlaGetU32Entry)(attr); +} + +uint64_t NlApi::nlaGetU64(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaGetU64Entry); + return (*nlaGetU64Entry)(attr); +} + +uint8_t NlApi::nlaGetU8(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaGetU8Entry); + return (*nlaGetU8Entry)(attr); +} + +int NlApi::nlaIsNested(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaIsNestedEntry); + return (*nlaIsNestedEntry)(attr); +} + +int NlApi::nlaLen(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaLenEntry); + return (*nlaLenEntry)(attr); +} + +struct nlattr *NlApi::nlaNext(const struct nlattr *attr, int *remaining) { + UNRECOVERABLE_IF(nullptr == nlaNextEntry); + return (*nlaNextEntry)(attr, remaining); +} + +int NlApi::nlaOk(const struct nlattr *attr, int remaining) { + UNRECOVERABLE_IF(nullptr == nlaOkEntry); + return (*nlaOkEntry)(attr, remaining); +} + +int NlApi::nlaPutU16(struct nl_msg *msg, int id, uint16_t data) { + UNRECOVERABLE_IF(nullptr == nlaPutU16Entry); + return (*nlaPutU16Entry)(msg, id, data); +} + +int NlApi::nlaPutU32(struct nl_msg *msg, int id, uint32_t data) { + UNRECOVERABLE_IF(nullptr == nlaPutU32Entry); + return (*nlaPutU32Entry)(msg, id, data); +} + +int NlApi::nlaPutU64(struct nl_msg *msg, int id, uint64_t data) { + UNRECOVERABLE_IF(nullptr == nlaPutU64Entry); + return (*nlaPutU64Entry)(msg, id, data); +} + +int NlApi::nlaPutU8(struct nl_msg *msg, int id, uint8_t data) { + UNRECOVERABLE_IF(nullptr == nlaPutU8Entry); + return (*nlaPutU8Entry)(msg, id, data); +} + +int NlApi::nlaType(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaTypeEntry); + return (*nlaTypeEntry)(attr); +} + +struct nl_msg *NlApi::nlmsgAlloc() { + UNRECOVERABLE_IF(nullptr == nlmsgAllocEntry); + return (*nlmsgAllocEntry)(); +} + +struct nlattr *NlApi::nlmsgAttrdata(const struct nlmsghdr *hdr, int attr) { + UNRECOVERABLE_IF(nullptr == nlmsgAttrdataEntry); + return (*nlmsgAttrdataEntry)(hdr, attr); +} + +int NlApi::nlmsgAttrlen(const struct nlmsghdr *hdr, int attr) { + UNRECOVERABLE_IF(nullptr == nlmsgAttrlenEntry); + return (*nlmsgAttrlenEntry)(hdr, attr); +} + +void NlApi::nlmsgFree(struct nl_msg *msg) { + UNRECOVERABLE_IF(nullptr == nlmsgFreeEntry); + (*nlmsgFreeEntry)(msg); + return; +} + +struct nlmsghdr *NlApi::nlmsgHdr(struct nl_msg *msg) { + UNRECOVERABLE_IF(nullptr == nlmsgHdrEntry); + return (*nlmsgHdrEntry)(msg); +} + +NlApi::NlApi() { + genlLibraryHandle.reset(NEO::OsLibrary::load(std::string(libgenlFile))); +} + +NlApi::~NlApi() = default; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/linux/nl_api/nl_api.h b/level_zero/sysman/source/linux/nl_api/nl_api.h new file mode 100644 index 0000000000..76b60d2ea3 --- /dev/null +++ b/level_zero/sysman/source/linux/nl_api/nl_api.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace NEO { +class OsLibrary; +} // namespace NEO + +namespace L0 { +namespace Sysman { + +typedef int (*pGenlConnect)(struct nl_sock *); +typedef int (*pGenlCtrlResolve)(struct nl_sock *, const char *); +typedef int (*pGenlHandleMsg)(struct nl_msg *, void *); +typedef int (*pGenlOpsResolve)(struct nl_sock *, struct genl_ops *); +typedef int (*pGenlRegisterFamily)(struct genl_ops *); +typedef int (*pGenlUnregisterFamily)(struct genl_ops *); +typedef void *(*pGenlmsgPut)(struct nl_msg *, uint32_t, uint32_t, int, int, int, uint8_t, uint8_t); +typedef int (*pNlRecvmsgsDefault)(struct nl_sock *); +typedef int (*pNlSendAuto)(struct nl_sock *, struct nl_msg *); +typedef struct nl_sock *(*pNlSocketAlloc)(); +typedef void (*pNlSocketDisableSeqCheck)(struct nl_sock *); +typedef void (*pNlSocketFree)(struct nl_sock *); +typedef int (*pNlSocketModifyCb)(struct nl_sock *, enum nl_cb_type, enum nl_cb_kind, nl_recvmsg_msg_cb_t, void *); +typedef void *(*pNlaData)(const struct nlattr *); +typedef uint32_t (*pNlaGetU32)(const struct nlattr *); +typedef uint64_t (*pNlaGetU64)(const struct nlattr *); +typedef uint8_t (*pNlaGetU8)(const struct nlattr *); +typedef int (*pNlaIsNested)(const struct nlattr *); +typedef int (*pNlaLen)(const struct nlattr *); +typedef struct nlattr *(*pNlaNext)(const struct nlattr *, int *); +typedef int (*pNlaOk)(const struct nlattr *, int); +typedef int (*pNlaPutU16)(struct nl_msg *, int, uint16_t); +typedef int (*pNlaPutU32)(struct nl_msg *, int, uint32_t); +typedef int (*pNlaPutU64)(struct nl_msg *, int, uint64_t); +typedef int (*pNlaPutU8)(struct nl_msg *, int, uint8_t); +typedef int (*pNlaType)(const struct nlattr *); +typedef struct nl_msg *(*pNlmsgAlloc)(); +typedef struct nlattr *(*pNlmsgAttrdata)(const struct nlmsghdr *, int); +typedef int (*pNlmsgAttrlen)(const struct nlmsghdr *, int); +typedef void (*pNlmsgFree)(struct nl_msg *); +typedef struct nlmsghdr *(*pNlmsgHdr)(struct nl_msg *); + +class NlApi : public NEO::NonCopyableOrMovableClass { + public: + MOCKABLE_VIRTUAL int genlConnect(struct nl_sock *sock); + MOCKABLE_VIRTUAL int genlCtrlResolve(struct nl_sock *sock, const char *name); + MOCKABLE_VIRTUAL int genlHandleMsg(struct nl_msg *msg, void *arg); + MOCKABLE_VIRTUAL int genlOpsResolve(struct nl_sock *sock, struct genl_ops *ops); + MOCKABLE_VIRTUAL int genlRegisterFamily(struct genl_ops *ops); + MOCKABLE_VIRTUAL int genlUnregisterFamily(struct genl_ops *ops); + MOCKABLE_VIRTUAL void *genlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version); + MOCKABLE_VIRTUAL int nlRecvmsgsDefault(struct nl_sock *sock); + MOCKABLE_VIRTUAL int nlSendAuto(struct nl_sock *sock, struct nl_msg *msg); + MOCKABLE_VIRTUAL struct nl_sock *nlSocketAlloc(); + MOCKABLE_VIRTUAL void nlSocketDisableSeqCheck(struct nl_sock *sock); + MOCKABLE_VIRTUAL void nlSocketFree(struct nl_sock *sock); + MOCKABLE_VIRTUAL int nlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg); + MOCKABLE_VIRTUAL void *nlaData(const struct nlattr *attr); + MOCKABLE_VIRTUAL uint32_t nlaGetU32(const struct nlattr *attr); + MOCKABLE_VIRTUAL uint64_t nlaGetU64(const struct nlattr *attr); + MOCKABLE_VIRTUAL uint8_t nlaGetU8(const struct nlattr *attr); + MOCKABLE_VIRTUAL int nlaIsNested(const struct nlattr *attr); + MOCKABLE_VIRTUAL int nlaLen(const struct nlattr *attr); + MOCKABLE_VIRTUAL struct nlattr *nlaNext(const struct nlattr *attr, int *remaining); + MOCKABLE_VIRTUAL int nlaOk(const struct nlattr *attr, int remaining); + MOCKABLE_VIRTUAL int nlaPutU16(struct nl_msg *msg, int id, uint16_t data); + MOCKABLE_VIRTUAL int nlaPutU32(struct nl_msg *msg, int id, uint32_t data); + MOCKABLE_VIRTUAL int nlaPutU64(struct nl_msg *msg, int id, uint64_t data); + MOCKABLE_VIRTUAL int nlaPutU8(struct nl_msg *msg, int id, uint8_t data); + MOCKABLE_VIRTUAL int nlaType(const struct nlattr *attr); + MOCKABLE_VIRTUAL struct nl_msg *nlmsgAlloc(); + MOCKABLE_VIRTUAL struct nlattr *nlmsgAttrdata(const struct nlmsghdr *hdr, int attr); + MOCKABLE_VIRTUAL int nlmsgAttrlen(const struct nlmsghdr *hdr, int attr); + MOCKABLE_VIRTUAL void nlmsgFree(struct nl_msg *msg); + MOCKABLE_VIRTUAL struct nlmsghdr *nlmsgHdr(struct nl_msg *msg); + + bool isAvailable() { return nullptr != genlLibraryHandle.get(); } + + MOCKABLE_VIRTUAL bool loadEntryPoints(); + + NlApi(); + MOCKABLE_VIRTUAL ~NlApi(); + + protected: + template + bool getSymbolAddr(const std::string_view &name, T &sym); + + std::unique_ptr genlLibraryHandle; + + pGenlConnect genlConnectEntry = nullptr; + pGenlCtrlResolve genlCtrlResolveEntry = nullptr; + pGenlHandleMsg genlHandleMsgEntry = nullptr; + pGenlOpsResolve genlOpsResolveEntry = nullptr; + pGenlRegisterFamily genlRegisterFamilyEntry = nullptr; + pGenlUnregisterFamily genlUnregisterFamilyEntry = nullptr; + pGenlmsgPut genlmsgPutEntry = nullptr; + pNlRecvmsgsDefault nlRecvmsgsDefaultEntry = nullptr; + pNlSendAuto nlSendAutoEntry = nullptr; + pNlSocketAlloc nlSocketAllocEntry = nullptr; + pNlSocketDisableSeqCheck nlSocketDisableSeqCheckEntry = nullptr; + pNlSocketFree nlSocketFreeEntry = nullptr; + pNlSocketModifyCb nlSocketModifyCbEntry = nullptr; + pNlaData nlaDataEntry = nullptr; + pNlaGetU32 nlaGetU32Entry = nullptr; + pNlaGetU64 nlaGetU64Entry = nullptr; + pNlaGetU8 nlaGetU8Entry = nullptr; + pNlaIsNested nlaIsNestedEntry = nullptr; + pNlaLen nlaLenEntry = nullptr; + pNlaNext nlaNextEntry = nullptr; + pNlaOk nlaOkEntry = nullptr; + pNlaPutU16 nlaPutU16Entry = nullptr; + pNlaPutU32 nlaPutU32Entry = nullptr; + pNlaPutU64 nlaPutU64Entry = nullptr; + pNlaPutU8 nlaPutU8Entry = nullptr; + pNlaType nlaTypeEntry = nullptr; + pNlmsgAlloc nlmsgAllocEntry = nullptr; + pNlmsgAttrdata nlmsgAttrdataEntry = nullptr; + pNlmsgAttrlen nlmsgAttrlenEntry = nullptr; + pNlmsgFree nlmsgFreeEntry = nullptr; + pNlmsgHdr nlmsgHdrEntry = nullptr; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_device.cpp b/level_zero/sysman/source/sysman_device.cpp index 82084241bc..81ef67d23c 100644 --- a/level_zero/sysman/source/sysman_device.cpp +++ b/level_zero/sysman/source/sysman_device.cpp @@ -25,5 +25,10 @@ SysmanDevice *SysmanDevice::create(NEO::ExecutionEnvironment &executionEnvironme return pSysmanDevice; } +ze_result_t SysmanDevice::fabricPortGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_fabric_port_handle_t *phPort) { + auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice); + return pSysmanDevice->fabricPortGet(pCount, phPort); +} + } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/source/sysman_device.h b/level_zero/sysman/source/sysman_device.h index 092ec0a5cb..4922313d47 100644 --- a/level_zero/sysman/source/sysman_device.h +++ b/level_zero/sysman/source/sysman_device.h @@ -9,6 +9,7 @@ #include "shared/source/execution_environment/execution_environment.h" #include "level_zero/core/source/device/device.h" +#include "level_zero/sysman/source/fabric_port/fabric_port.h" #include #include @@ -22,6 +23,9 @@ struct SysmanDevice : _ze_device_handle_t { virtual ~SysmanDevice() = default; static SysmanDevice *create(NEO::ExecutionEnvironment &executionEnvironment, const uint32_t rootDeviceIndex); virtual const NEO::HardwareInfo &getHardwareInfo() const = 0; + + static ze_result_t fabricPortGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_fabric_port_handle_t *phPort); + virtual ze_result_t fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) = 0; }; } // namespace Sysman diff --git a/level_zero/sysman/source/sysman_device_imp.cpp b/level_zero/sysman/source/sysman_device_imp.cpp index 2588ee156d..510ec164be 100644 --- a/level_zero/sysman/source/sysman_device_imp.cpp +++ b/level_zero/sysman/source/sysman_device_imp.cpp @@ -21,11 +21,13 @@ SysmanDeviceImp::SysmanDeviceImp(NEO::ExecutionEnvironment *executionEnvironment this->executionEnvironment->incRefInternal(); pOsSysman = OsSysman::create(this); UNRECOVERABLE_IF(nullptr == pOsSysman); + pFabricPortHandleContext = new FabricPortHandleContext(pOsSysman); } SysmanDeviceImp::~SysmanDeviceImp() { executionEnvironment->decRefInternal(); freeResource(pOsSysman); + freeResource(pFabricPortHandleContext); } ze_result_t SysmanDeviceImp::init() { @@ -36,5 +38,9 @@ ze_result_t SysmanDeviceImp::init() { return result; } +ze_result_t SysmanDeviceImp::fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) { + return pFabricPortHandleContext->fabricPortGet(pCount, phPort); +} + } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/source/sysman_device_imp.h b/level_zero/sysman/source/sysman_device_imp.h index 728fdd960f..bb5b329ba6 100644 --- a/level_zero/sysman/source/sysman_device_imp.h +++ b/level_zero/sysman/source/sysman_device_imp.h @@ -35,6 +35,9 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass { NEO::ExecutionEnvironment *getExecutionEnvironment() const { return executionEnvironment; } uint32_t getRootDeviceIndex() const { return rootDeviceIndex; } + FabricPortHandleContext *pFabricPortHandleContext = nullptr; + ze_result_t fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) override; + private: NEO::ExecutionEnvironment *executionEnvironment = nullptr; const uint32_t rootDeviceIndex; diff --git a/level_zero/sysman/test/unit_tests/sources/fabric_port/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/fabric_port/CMakeLists.txt new file mode 100644 index 0000000000..ffeb6e3a80 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/fabric_port/CMakeLists.txt @@ -0,0 +1,11 @@ +# +# Copyright (C) 2020-2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt +) + +add_subdirectories() diff --git a/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/CMakeLists.txt new file mode 100644 index 0000000000..292801e411 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# Copyright (C) 2020-2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(L0_TESTS_SYSMAN_FABRICPORT_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt +) + +if(NEO_ENABLE_i915_PRELIM_DETECTION) + if(LIBGENL_FOUND) + list(APPEND L0_TESTS_SYSMAN_FABRICPORT_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_fabric_device_prelim.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_fabric_port_prelim.cpp + ) + endif() +else() + list(APPEND L0_TESTS_SYSMAN_FABRICPORT_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/test_zes_fabric_port.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_fabric_device.h + ) +endif() + +if(UNIX) + target_sources(${TARGET_NAME} + PRIVATE + ${L0_TESTS_SYSMAN_FABRICPORT_LINUX} + ) +endif() diff --git a/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/mock_fabric_device.h b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/mock_fabric_device.h new file mode 100644 index 0000000000..d22e989e37 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/mock_fabric_device.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/test/common/test_macros/mock_method_macros.h" + +#include "level_zero/sysman/source/fabric_port/fabric_port.h" +#include "level_zero/sysman/source/linux/fs_access.h" +#include "level_zero/sysman/source/linux/os_sysman_imp.h" + +#include "gmock/gmock.h" + +namespace L0 { +namespace ult { + +const uint32_t mockNumPorts = 2; +struct MockFabricDevice : public L0::Sysman::FabricDevice { + uint32_t getNumPorts() override { + return mockNumPorts; + } + + ADDMETHOD_NOBASE(getOsFabricDevice, L0::Sysman::OsFabricDevice *, nullptr, ()); + MockFabricDevice() = default; +}; + +class MockFabricFsAccess : public L0::Sysman::FsAccess { + public: + ze_result_t mockListDirectory = ZE_RESULT_SUCCESS; + ze_result_t canRead(const std::string file) override { + if (accessibleNodes.find(file) != accessibleNodes.end()) { + return ZE_RESULT_SUCCESS; + } + return ZE_RESULT_ERROR_UNKNOWN; + } + + ze_result_t listDirectory(const std::string path, std::vector &list) override { + list = accessibleDirectories; + return mockListDirectory; + } + + ~MockFabricFsAccess() override = default; + + ze_result_t read(const std::string file, uint64_t &val) override { + if (canRead(file) == ZE_RESULT_SUCCESS) { + val = accessibleNodes[file]; + return ZE_RESULT_SUCCESS; + } + return ZE_RESULT_ERROR_UNKNOWN; + } + + void setAccessibleNodes(std::map &nodes) { + accessibleNodes = nodes; + } + + void setAccessibleDirectories(std::vector &dirs) { + accessibleDirectories = dirs; + } + + private: + std::map accessibleNodes = {}; + std::vector accessibleDirectories = {}; +}; + +class MockFabricSysFsAccess : public L0::Sysman::SysfsAccess { + public: + ze_result_t getRealPath(const std::string path, std::string &buf) override { + buf.append("/mockRealPath"); + return mockRealPathStatus; + } + + ze_result_t mockRealPathStatus = ZE_RESULT_SUCCESS; +}; + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_sysman_fabric_device_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_sysman_fabric_device_prelim.cpp new file mode 100644 index 0000000000..4288a4c249 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_sysman_fabric_device_prelim.cpp @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include + +namespace L0 { +namespace ult { + +class PublicFabricDeviceAccessNl : public L0::Sysman::FabricDeviceAccessNl { + public: + using L0::Sysman::FabricDeviceAccessNl::fabricPorts; + using L0::Sysman::FabricDeviceAccessNl::pIafNlApi; +}; + +class SysmanFabricDeviceFixture : public SysmanDeviceFixture { + protected: + MockIafNlApi *pMockIafNlApi = nullptr; + L0::Sysman::FabricDeviceAccess *pFabricDeviceAccess = nullptr; + zes_fabric_port_id_t testPortId = {}; + + void SetUp() override { + SysmanDeviceFixture::SetUp(); + pFabricDeviceAccess = L0::Sysman::FabricDeviceAccess::create(pOsSysman); + PublicFabricDeviceAccessNl *pPublicFabricDeviceAccessNl = reinterpret_cast(pFabricDeviceAccess); + pMockIafNlApi = new MockIafNlApi; + delete pPublicFabricDeviceAccessNl->pIafNlApi; + pPublicFabricDeviceAccessNl->pIafNlApi = pMockIafNlApi; + pPublicFabricDeviceAccessNl->fabricPorts.clear(); + + setupDefaults(); + } + void TearDown() override { + delete pFabricDeviceAccess; + SysmanDeviceFixture::TearDown(); + } + + void setupDefaults(); +}; + +void SysmanFabricDeviceFixture::setupDefaults() { + testPortId.attachId = pMockIafNlApi->testPortId.attachId; + testPortId.fabricId = pMockIafNlApi->testPortId.fabricId; + testPortId.portNumber = pMockIafNlApi->testPortId.portNumber; +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWithoutIafNlApiWhenTearDownIsCalledThenNoSegfault) { + PublicFabricDeviceAccessNl *pPublicFabricDeviceAccessNl = reinterpret_cast(pFabricDeviceAccess); + EXPECT_NE(nullptr, pPublicFabricDeviceAccessNl); + delete pPublicFabricDeviceAccessNl->pIafNlApi; + pPublicFabricDeviceAccessNl->pIafNlApi = nullptr; +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetPortEnabledStateIsCalledReturnsEnabledTrue) { + bool enabled; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getPortEnabledState(testPortId, enabled)); + EXPECT_EQ(true, enabled); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetPortBeaconStateIsCalledReturnsEnabledTrue) { + bool enabled; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getPortBeaconState(testPortId, enabled)); + EXPECT_EQ(true, enabled); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenEnablePortBeaconingCalledReturnsSuccess) { + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->enablePortBeaconing(testPortId)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenDisablePortBeaconingCalledReturnsSuccess) { + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->disablePortBeaconing(testPortId)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenEnableCalledReturnsSuccess) { + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->enable(testPortId)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenDisableCalledReturnsSuccess) { + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->disable(testPortId)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenEnableUsageCalledReturnsSuccess) { + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->enableUsage(testPortId)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenDisableUsageCalledReturnsSuccess) { + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->disableUsage(testPortId)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenForceSweepCalledReturnsSuccess) { + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->forceSweep()); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenRoutingQueryCalledReturnsSuccess) { + uint32_t start = 0, end = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->routingQuery(start, end)); + EXPECT_EQ(pMockIafNlApi->genStart, start); + EXPECT_EQ(pMockIafNlApi->genEnd, end); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetPropertiesCalledThenAllPropertiesAreReturned) { + PublicFabricDeviceAccessNl *pPublicFabricDeviceAccessNl = reinterpret_cast(pFabricDeviceAccess); + + struct L0::Sysman::Port p; + pPublicFabricDeviceAccessNl->fabricPorts.clear(); + + // First port, wrong attachId + p.portId.fabricId = pMockIafNlApi->testPortId.fabricId; + p.portId.attachId = 0U; + p.portId.portNumber = pMockIafNlApi->testPortId.portNumber; + p.onSubdevice = false; + p.model = std::string("wrongPort"); + p.maxRxSpeed.bitRate = 1L; + p.maxRxSpeed.width = 1; + p.maxTxSpeed.bitRate = 1L; + p.maxTxSpeed.width = 1; + pPublicFabricDeviceAccessNl->fabricPorts.push_back(p); + + // Second port, wrong portNumber + p.portId.fabricId = pMockIafNlApi->testPortId.fabricId; + p.portId.attachId = pMockIafNlApi->testPortId.attachId; + p.portId.portNumber = 0U; + p.onSubdevice = false; + p.model = std::string("wrongPort"); + p.maxRxSpeed.bitRate = 2L; + p.maxRxSpeed.width = 2; + p.maxTxSpeed.bitRate = 2L; + p.maxTxSpeed.width = 2; + pPublicFabricDeviceAccessNl->fabricPorts.push_back(p); + + // Third port, is a match + p.portId.fabricId = pMockIafNlApi->testPortId.fabricId; + p.portId.attachId = pMockIafNlApi->testPortId.attachId; + p.portId.portNumber = pMockIafNlApi->testPortId.portNumber; + p.onSubdevice = true; + p.model = std::string("rightPort"); + p.maxRxSpeed.bitRate = 3L; + p.maxRxSpeed.width = 3; + p.maxTxSpeed.bitRate = 3L; + p.maxTxSpeed.width = 3; + pPublicFabricDeviceAccessNl->fabricPorts.push_back(p); + + std::string model = std::string(""); + bool onSubdevice = false; + uint32_t subdeviceId = 0U; + zes_fabric_port_speed_t maxRxSpeed = {.bitRate = -1L, .width = -1}; + zes_fabric_port_speed_t maxTxSpeed = {.bitRate = -1L, .width = -1}; + pFabricDeviceAccess->getProperties(testPortId, model, onSubdevice, subdeviceId, maxRxSpeed, maxTxSpeed); + EXPECT_EQ(p.model, model); + EXPECT_EQ(p.onSubdevice, onSubdevice); + EXPECT_EQ(p.portId.attachId, subdeviceId); + EXPECT_EQ(p.maxRxSpeed.bitRate, maxRxSpeed.bitRate); + EXPECT_EQ(p.maxRxSpeed.width, maxRxSpeed.width); + EXPECT_EQ(p.maxTxSpeed.bitRate, maxTxSpeed.bitRate); + EXPECT_EQ(p.maxTxSpeed.width, maxTxSpeed.width); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetThroughputCalledReturnsThroughputValues) { + zes_fabric_port_throughput_t throughput = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getThroughput(testPortId, throughput)); + EXPECT_EQ(throughput.rxCounter, pMockIafNlApi->rxCounter); + EXPECT_EQ(throughput.txCounter, pMockIafNlApi->txCounter); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledAndfPortStatusIsHealthyReturnsSuccess) { + zes_fabric_port_state_t state1 = {}; + state1.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES; + state1.pNext = nullptr; + + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state1)); + EXPECT_EQ(state1.stype, ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES); + EXPECT_EQ(state1.pNext, nullptr); + EXPECT_EQ(state1.status, ZES_FABRIC_PORT_STATUS_HEALTHY); + EXPECT_EQ(state1.qualityIssues, 0U); + EXPECT_EQ(state1.failureReasons, 0U); + EXPECT_EQ(state1.remotePortId.fabricId, pMockIafNlApi->testPortId.fabricId); + EXPECT_EQ(state1.remotePortId.attachId, pMockIafNlApi->testPortId.attachId); + EXPECT_EQ(state1.remotePortId.portNumber, pMockIafNlApi->testPortId.portNumber + 1); + EXPECT_EQ(state1.rxSpeed.bitRate, -1); + EXPECT_EQ(state1.rxSpeed.width, -1); + EXPECT_EQ(state1.txSpeed.bitRate, -1); + EXPECT_EQ(state1.txSpeed.width, -1); + + zes_fabric_port_state_t state2 = {}; + state2.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES; + state2.pNext = nullptr; + + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state2)); + EXPECT_EQ(state2.stype, ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES); + EXPECT_EQ(state2.pNext, nullptr); + EXPECT_EQ(state2.status, ZES_FABRIC_PORT_STATUS_HEALTHY); + EXPECT_EQ(state2.qualityIssues, 0U); + EXPECT_EQ(state2.failureReasons, 0U); + EXPECT_EQ(state2.remotePortId.fabricId, pMockIafNlApi->testPortId.fabricId); + EXPECT_EQ(state2.remotePortId.attachId, pMockIafNlApi->testPortId.attachId); + EXPECT_EQ(state2.remotePortId.portNumber, pMockIafNlApi->testPortId.portNumber + 1); + EXPECT_EQ(state2.rxSpeed.bitRate, -1); + EXPECT_EQ(state2.rxSpeed.width, -1); + EXPECT_EQ(state2.txSpeed.bitRate, -1); + EXPECT_EQ(state2.txSpeed.width, -1); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledAndfPortStatusIsDegradedReturnsSuccess) { + zes_fabric_port_state_t state = {}; + state.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES; + state.pNext = nullptr; + pMockIafNlApi->fPortStatus = ZES_FABRIC_PORT_STATUS_DEGRADED; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(state.stype, ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES); + EXPECT_EQ(state.pNext, nullptr); + EXPECT_EQ(state.status, ZES_FABRIC_PORT_STATUS_DEGRADED); + EXPECT_EQ(state.qualityIssues, 0U); + EXPECT_EQ(state.failureReasons, 0U); + EXPECT_EQ(state.remotePortId.fabricId, pMockIafNlApi->testPortId.fabricId); + EXPECT_EQ(state.remotePortId.attachId, pMockIafNlApi->testPortId.attachId); + EXPECT_EQ(state.remotePortId.portNumber, pMockIafNlApi->testPortId.portNumber + 1); + EXPECT_EQ(state.rxSpeed.bitRate, -1); + EXPECT_EQ(state.rxSpeed.width, -1); + EXPECT_EQ(state.txSpeed.bitRate, -1); + EXPECT_EQ(state.txSpeed.width, -1); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledAndfPortStatusIsFailedReturnsSuccess) { + zes_fabric_port_state_t state = {}; + state.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES; + state.pNext = nullptr; + pMockIafNlApi->fPortStatus = ZES_FABRIC_PORT_STATUS_FAILED; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(state.stype, ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES); + EXPECT_EQ(state.pNext, nullptr); + EXPECT_EQ(state.status, ZES_FABRIC_PORT_STATUS_FAILED); + EXPECT_EQ(state.qualityIssues, 0U); + EXPECT_EQ(state.failureReasons, 0U); + EXPECT_EQ(state.remotePortId.fabricId, pMockIafNlApi->testPortId.fabricId); + EXPECT_EQ(state.remotePortId.attachId, pMockIafNlApi->testPortId.attachId); + EXPECT_EQ(state.remotePortId.portNumber, pMockIafNlApi->testPortId.portNumber + 1); + EXPECT_EQ(state.rxSpeed.bitRate, -1); + EXPECT_EQ(state.rxSpeed.width, -1); + EXPECT_EQ(state.txSpeed.bitRate, -1); + EXPECT_EQ(state.txSpeed.width, -1); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledAndfPortStatusIsDisabledReturnsSuccess) { + zes_fabric_port_state_t state = {}; + state.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES; + state.pNext = nullptr; + pMockIafNlApi->fPortStatus = ZES_FABRIC_PORT_STATUS_DISABLED; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(state.stype, ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES); + EXPECT_EQ(state.pNext, nullptr); + EXPECT_EQ(state.status, ZES_FABRIC_PORT_STATUS_DISABLED); + EXPECT_EQ(state.qualityIssues, 0U); + EXPECT_EQ(state.failureReasons, 0U); + EXPECT_EQ(state.rxSpeed.bitRate, -1); + EXPECT_EQ(state.rxSpeed.width, -1); + EXPECT_EQ(state.txSpeed.bitRate, -1); + EXPECT_EQ(state.txSpeed.width, -1); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledAndfPortStatusIsUnknownReturnsSuccess) { + zes_fabric_port_state_t state = {}; + state.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES; + state.pNext = nullptr; + pMockIafNlApi->fPortStatus = ZES_FABRIC_PORT_STATUS_UNKNOWN; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(state.stype, ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES); + EXPECT_EQ(state.pNext, nullptr); + EXPECT_EQ(state.status, ZES_FABRIC_PORT_STATUS_UNKNOWN); + EXPECT_EQ(state.qualityIssues, 0U); + EXPECT_EQ(state.failureReasons, 0U); + EXPECT_EQ(state.remotePortId.fabricId, 0U); + EXPECT_EQ(state.remotePortId.attachId, 0U); + EXPECT_EQ(state.remotePortId.portNumber, 0U); + EXPECT_EQ(state.rxSpeed.bitRate, -1); + EXPECT_EQ(state.rxSpeed.width, -1); + EXPECT_EQ(state.txSpeed.bitRate, -1); + EXPECT_EQ(state.txSpeed.width, -1); +} + +TEST_F(SysmanFabricDeviceFixture, GivenPortStatusFailedWhenGetStateIsCalledThenVerifyFailureReasonsAreAsExpected) { + zes_fabric_port_state_t state = {}; + state.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES; + state.pNext = nullptr; + pMockIafNlApi->fPortStatus = ZES_FABRIC_PORT_STATUS_FAILED; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(state.status, ZES_FABRIC_PORT_STATUS_FAILED); + EXPECT_EQ(state.failureReasons, 0U); + + pMockIafNlApi->mockPortState.failed = 1; + pMockIafNlApi->mockPortState.isolated = 1; + pMockIafNlApi->mockPortState.linkDown = 1; + pMockIafNlApi->mockPortState.didNotTrain = 1; + pMockIafNlApi->mockPortState.flapping = 1; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(ZES_FABRIC_PORT_FAILURE_FLAG_FAILED, state.failureReasons & ZES_FABRIC_PORT_FAILURE_FLAG_FAILED); + EXPECT_EQ(ZES_FABRIC_PORT_FAILURE_FLAG_TRAINING_TIMEOUT, state.failureReasons & ZES_FABRIC_PORT_FAILURE_FLAG_TRAINING_TIMEOUT); + EXPECT_EQ(ZES_FABRIC_PORT_FAILURE_FLAG_FLAPPING, state.failureReasons & ZES_FABRIC_PORT_FAILURE_FLAG_FLAPPING); + + pMockIafNlApi->mockPortState.failed = 1; + pMockIafNlApi->mockPortState.isolated = 0; + pMockIafNlApi->mockPortState.linkDown = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(ZES_FABRIC_PORT_FAILURE_FLAG_FAILED, state.failureReasons & ZES_FABRIC_PORT_FAILURE_FLAG_FAILED); + + pMockIafNlApi->mockPortState.failed = 0; + pMockIafNlApi->mockPortState.isolated = 1; + pMockIafNlApi->mockPortState.linkDown = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(ZES_FABRIC_PORT_FAILURE_FLAG_FAILED, state.failureReasons & ZES_FABRIC_PORT_FAILURE_FLAG_FAILED); + + pMockIafNlApi->mockPortState.failed = 0; + pMockIafNlApi->mockPortState.isolated = 0; + pMockIafNlApi->mockPortState.linkDown = 1; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(ZES_FABRIC_PORT_FAILURE_FLAG_FAILED, state.failureReasons & ZES_FABRIC_PORT_FAILURE_FLAG_FAILED); +} + +TEST_F(SysmanFabricDeviceFixture, GivenPortStatusDegradedWhenGetStateIsCalledThenVerifyQualityIssuesAreAsExpected) { + zes_fabric_port_state_t state = {}; + state.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES; + state.pNext = nullptr; + pMockIafNlApi->fPortStatus = ZES_FABRIC_PORT_STATUS_DEGRADED; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(state.status, ZES_FABRIC_PORT_STATUS_DEGRADED); + EXPECT_EQ(state.failureReasons, 0U); + + pMockIafNlApi->mockPortState.lqi = 1; + pMockIafNlApi->mockPortState.lwd = 1; + pMockIafNlApi->mockPortState.rate = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_LINK_ERRORS, state.qualityIssues & ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_LINK_ERRORS); + EXPECT_EQ(ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_SPEED, state.qualityIssues & ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_SPEED); + + pMockIafNlApi->mockPortState.lwd = 0; + pMockIafNlApi->mockPortState.rate = 1; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); + EXPECT_EQ(ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_SPEED, state.qualityIssues & ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_SPEED); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledWhenFPortStatusQueryFailsReturnsError) { + pMockIafNlApi->mockfPortStatusQueryReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + zes_fabric_port_state_t state; + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pFabricDeviceAccess->getState(testPortId, state)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledWhenFPortPropertiesQueryFailsReturnsError) { + pMockIafNlApi->mockfportPropertiesReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + zes_fabric_port_state_t state; + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pFabricDeviceAccess->getState(testPortId, state)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledWhenDeviceEnumFailsThenGetStateReturnsSuccess) { + pMockIafNlApi->mockdeviceEnumReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + zes_fabric_port_state_t state; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledWhenFabricDevicePropertiesFailsThenGetStateReturnsSuccess) { + pMockIafNlApi->mockfabricDevicePropertiesReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + zes_fabric_port_state_t state; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetStateIsCalledWhenSubDevicePropertiesGetFailsThenGetStateReturnsSuccess) { + pMockIafNlApi->mocksubdevicePropertiesGetReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + zes_fabric_port_state_t state; + EXPECT_EQ(ZE_RESULT_SUCCESS, pFabricDeviceAccess->getState(testPortId, state)); +} + +TEST_F(SysmanFabricDeviceFixture, GivenFabricDeviceAccessNlWhenGetPortsCalledWithNoPortsAndInitMyPortGetNumSubDevicesFailsReturnsError) { + std::vector ports; + pMockIafNlApi->mockGetPortsResult = ZE_RESULT_ERROR_UNKNOWN; + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, pFabricDeviceAccess->getPorts(ports)); +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_sysman_fabric_port_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_sysman_fabric_port_prelim.cpp new file mode 100644 index 0000000000..cfd17700b9 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_sysman_fabric_port_prelim.cpp @@ -0,0 +1,967 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h" +#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.h" +#include "level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.h" +#include "level_zero/sysman/test/unit_tests/sources/fabric_port/linux/mock_fabric_device.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include + +namespace L0 { +namespace ult { + +constexpr auto maxNumPorts = 32u; + +class PublicFabricDeviceAccessNl : public L0::Sysman::FabricDeviceAccessNl { + public: + using L0::Sysman::FabricDeviceAccessNl::fabricPorts; + using L0::Sysman::FabricDeviceAccessNl::pIafNlApi; +}; + +class PublicLinuxFabricDeviceImp : public L0::Sysman::LinuxFabricDeviceImp { + public: + using L0::Sysman::LinuxFabricDeviceImp::pFabricDeviceAccess; +}; + +class PublicFabricDeviceImp : public L0::Sysman::FabricDeviceImp { + public: + using L0::Sysman::FabricDeviceImp::pOsFabricDevice; +}; + +class ZesFabricPortFixture : public SysmanDeviceFixture { + protected: + MockIafNlApi *pMockIafNlApi = nullptr; + L0::Sysman::FabricPortHandleContext *pFabricPortHandleContext = nullptr; + L0::Sysman::SysmanDevice *device = nullptr; + + void SetUp() override { + SysmanDeviceFixture::SetUp(); + + device = pSysmanDevice; + pFabricPortHandleContext = pSysmanDeviceImp->pFabricPortHandleContext; + if (nullptr != pFabricPortHandleContext->pFabricDevice) { + for (L0::Sysman::FabricPort *pFabricPort : pFabricPortHandleContext->handleList) { + delete pFabricPort; + } + pFabricPortHandleContext->handleList.clear(); + delete pFabricPortHandleContext->pFabricDevice; + pFabricPortHandleContext->pFabricDevice = nullptr; + } + pFabricPortHandleContext->pFabricDevice = new L0::Sysman::FabricDeviceImp(pOsSysman); + + PublicLinuxFabricDeviceImp *pPublicLinuxFabricDeviceImp = reinterpret_cast(pFabricPortHandleContext->pFabricDevice->getOsFabricDevice()); + PublicFabricDeviceAccessNl *pPublicFabricDeviceAccessNl = reinterpret_cast(pPublicLinuxFabricDeviceImp->pFabricDeviceAccess); + delete pPublicFabricDeviceAccessNl->pIafNlApi; + pMockIafNlApi = new MockIafNlApi; + pPublicFabricDeviceAccessNl->pIafNlApi = pMockIafNlApi; + pPublicFabricDeviceAccessNl->fabricPorts.clear(); + setupDefaults(); + } + void TearDown() override { + SysmanDeviceFixture::TearDown(); + } + + void setupDefaults(); +}; + +void ZesFabricPortFixture::setupDefaults() { + pMockIafNlApi->validateParams = false; +} + +TEST_F(ZesFabricPortFixture, GivenFabricDeviceImpValidatepOsFabricDevice) { + PublicFabricDeviceImp *pPublicFabricDeviceImp = reinterpret_cast(pFabricPortHandleContext->pFabricDevice); + PublicLinuxFabricDeviceImp *pPublicLinuxFabricDeviceImp = reinterpret_cast(pPublicFabricDeviceImp->pOsFabricDevice); + EXPECT_EQ(pFabricPortHandleContext->pFabricDevice->getOsFabricDevice(), pPublicLinuxFabricDeviceImp); +} + +TEST_F(ZesFabricPortFixture, GivenPortCountZeroAndValidHandlePtrWhenCallingZesFabricPortGetThenCountIsReturnedAndNoHandlesReturnedAndVerifyZesFabricPortGetCallSucceeds) { + uint32_t count = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumFabricPorts(device, &count, NULL)); + if (nullptr != pFabricPortHandleContext->pFabricDevice) { + for (L0::Sysman::FabricPort *pFabricPort : pFabricPortHandleContext->handleList) { + delete pFabricPort; + } + pFabricPortHandleContext->handleList.clear(); + } + + pMockIafNlApi->numPorts = 0U; + count = pMockIafNlApi->numPorts; + zes_fabric_port_handle_t handle = static_cast(0UL); + + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, &handle); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + EXPECT_EQ(handle, static_cast(0UL)); +} + +TEST_F(ZesFabricPortFixture, GivenPortCountCorrectWhenCallingZesFabricPortGetThenCountHandlesAreReturnedAndAndVerifyZesFabricPortGetCallSucceeds) { + pMockIafNlApi->numPorts = 1U; + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); +} + +TEST_F(ZesFabricPortFixture, GivenPortCountGreaterThanPortsWhenCallingZesFabricPortGetThenCorrectCountIsReturnedAndAndVerifyZesFabricPortGetCallSucceeds) { + uint32_t count = pMockIafNlApi->numPorts + 1U; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); +} + +TEST_F(ZesFabricPortFixture, GivenPortCounLessThanPortsWhenCallingZesFabricPortGetThenCountLessThenPortsHandlesAreReturned) { + uint32_t count = pMockIafNlApi->numPorts - 1U; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts - 1U); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetPropertiesThenZesFabricPortGetPropertiesCallSucceeds) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + zes_fabric_port_properties_t properties; + // Initialize values + properties.onSubdevice = true; + properties.subdeviceId = std::numeric_limits::max(); + std::memset(properties.model, std::numeric_limits::max(), ZES_MAX_FABRIC_PORT_MODEL_SIZE); + properties.portId.fabricId = std::numeric_limits::max(); + properties.portId.attachId = std::numeric_limits::max(); + properties.portId.portNumber = std::numeric_limits::max(); + properties.maxRxSpeed.bitRate = std::numeric_limits::max(); + properties.maxRxSpeed.width = std::numeric_limits::max(); + properties.maxTxSpeed.bitRate = std::numeric_limits::max(); + properties.maxTxSpeed.width = std::numeric_limits::max(); + + uint8_t portNumberIndex = pMockIafNlApi->testPortId.portNumber - 1U; + + if (1U == pMockIafNlApi->testPortId.attachId) { + portNumberIndex += pMockIafNlApi->portsPerSubdevice; + } + + result = zesFabricPortGetProperties(hPorts[portNumberIndex], &properties); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_TRUE(properties.onSubdevice); + EXPECT_EQ(pMockIafNlApi->testPortId.attachId, properties.subdeviceId); + EXPECT_STREQ("XeLink", properties.model); + EXPECT_EQ(pMockIafNlApi->testPortId.fabricId, properties.portId.fabricId); + EXPECT_EQ(pMockIafNlApi->testPortId.attachId, properties.portId.attachId); + EXPECT_EQ(pMockIafNlApi->testPortId.portNumber, properties.portId.portNumber); + EXPECT_EQ(-1L, properties.maxRxSpeed.bitRate); + EXPECT_EQ(-1, properties.maxRxSpeed.width); + EXPECT_EQ(-1L, properties.maxTxSpeed.bitRate); + EXPECT_EQ(-1, properties.maxTxSpeed.width); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetLinkTypeThenZesFabricPortGetLinkTypeCallSucceeds) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + for (auto i = 0U; i < count; i++) { + zes_fabric_link_type_t linkType; + result = zesFabricPortGetLinkType(hPorts[i], &linkType); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_STREQ("XeLink", linkType.desc); + } +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetConfigThenZesFabricPortGetConfigCallSucceeds) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + for (auto i = 0U; i < count; i++) { + pMockIafNlApi->portEnabled = false; + pMockIafNlApi->portBeaconing = false; + + zes_fabric_port_config_t getConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + + result = zesFabricPortGetConfig(hPorts[i], &getConfig); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_FALSE(getConfig.enabled); + EXPECT_FALSE(getConfig.beaconing); + } +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledTrueAndBeaconingTrueThenZesFabricPortGetConfigCallSucceeds) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + for (auto i = 0U; i < count; i++) { + pMockIafNlApi->portEnabled = false; + pMockIafNlApi->portBeaconing = false; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + + result = zesFabricPortSetConfig(hPorts[i], &setConfig); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + } + + for (auto i = 0U; i < count; i++) { + zes_fabric_port_config_t getConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = false, .beaconing = false}; + + result = zesFabricPortGetConfig(hPorts[i], &getConfig); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_TRUE(getConfig.enabled); + EXPECT_TRUE(getConfig.beaconing); + } +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledFalseAndBeaconingFalseThenZesFabricPortGetConfigCallSucceeds) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + for (auto i = 0U; i < count; i++) { + pMockIafNlApi->portEnabled = true; + pMockIafNlApi->portBeaconing = true; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = false, .beaconing = false}; + + result = zesFabricPortSetConfig(hPorts[i], &setConfig); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + } + + for (auto i = 0U; i < count; i++) { + zes_fabric_port_config_t getConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + + result = zesFabricPortGetConfig(hPorts[i], &getConfig); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_FALSE(getConfig.enabled); + EXPECT_FALSE(getConfig.beaconing); + } +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledAlreadyTrueAndBeaconingAlreadyTrueThenZesFabricPortGetConfigCallSucceeds) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + for (auto i = 0U; i < count; i++) { + pMockIafNlApi->portEnabled = true; + pMockIafNlApi->portBeaconing = true; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + + result = zesFabricPortSetConfig(hPorts[i], &setConfig); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + } + + for (auto i = 0U; i < count; i++) { + zes_fabric_port_config_t getConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + + result = zesFabricPortGetConfig(hPorts[i], &getConfig); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_TRUE(getConfig.enabled); + EXPECT_TRUE(getConfig.beaconing); + } +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledAlreadyTrueAndBeaconingAlreadyTrueAndGetPortBeaconStateFailsThenZesFabricPortGetConfigCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->portEnabled = true; + pMockIafNlApi->portBeaconing = true; + pMockIafNlApi->mockportBeaconStateQueryReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + result = zesFabricPortSetConfig(hPorts[0], &setConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledTrueAndBeaconingTrueAndEnablePortFailsThenZesFabricPortGetConfigCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->portEnabled = false; + pMockIafNlApi->portBeaconing = false; + pMockIafNlApi->mockportEnableReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + result = zesFabricPortSetConfig(hPorts[0], &setConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledFalseAndBeaconingFalseAndPortUsageDisableFailsThenZesFabricPortGetConfigCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->portEnabled = true; + pMockIafNlApi->portBeaconing = true; + pMockIafNlApi->mockportUsageDisableReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = false, .beaconing = false}; + result = zesFabricPortSetConfig(hPorts[0], &setConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledFalseAndBeaconingFalseAndDisableFailsThenZesFabricPortGetConfigCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->portEnabled = true; + pMockIafNlApi->portBeaconing = true; + pMockIafNlApi->mockportDisableReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = false, .beaconing = false}; + result = zesFabricPortSetConfig(hPorts[0], &setConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledFalseAndBeaconingFalseAndEnableUsageFailsThenZesFabricPortGetConfigCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->portEnabled = true; + pMockIafNlApi->portBeaconing = true; + pMockIafNlApi->mockportUsageEnableReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = false, .beaconing = false}; + result = zesFabricPortSetConfig(hPorts[0], &setConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledTrueAndBeaconingFalseAndEnableUsageFailsThenZesFabricPortGetConfigCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->portEnabled = false; + pMockIafNlApi->portBeaconing = true; + pMockIafNlApi->mockportStateQueryReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = false, .beaconing = false}; + result = zesFabricPortSetConfig(hPorts[0], &setConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledTrueAndBeaconingTrueAndForceSweepFailsThenZesFabricPortGetConfigCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->portEnabled = false; + pMockIafNlApi->portBeaconing = false; + pMockIafNlApi->mockremRequestReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + result = zesFabricPortSetConfig(hPorts[0], &setConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledTrueAndBeaconingTrueAndFirstRoutingQueryFailsThenZesFabricPortGetConfigCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->portEnabled = false; + pMockIafNlApi->portBeaconing = false; + pMockIafNlApi->mockroutingGenQueryReturnStatus.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + pMockIafNlApi->isRepeated = true; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + result = zesFabricPortSetConfig(hPorts[0], &setConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigAndEnabledTrueAndBeaconingTrueAndSecondRoutingQueryFailsThenZesFabricPortGetConfigCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->portEnabled = false; + pMockIafNlApi->portBeaconing = false; + pMockIafNlApi->mockroutingGenQueryReturnStatus.push_back(ZE_RESULT_SUCCESS); + pMockIafNlApi->mockroutingGenQueryReturnStatus.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + pMockIafNlApi->isRepeated = true; + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + result = zesFabricPortSetConfig(hPorts[0], &setConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenWhenCallingZesFabricPortGetConfigAndGetPortEnabledStateReturnsUnAvailableThenCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->mockportStateQueryReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + zes_fabric_port_config_t getConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + result = zesFabricPortGetConfig(hPorts[0], &getConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenWhenCallingZesFabricPortGetConfigAndGetPortBeaconStateReturnsUnAvailableThenCallFails) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + pMockIafNlApi->mockportBeaconStateQueryReturnStatus = ZE_RESULT_ERROR_NOT_AVAILABLE; + zes_fabric_port_config_t getConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + result = zesFabricPortGetConfig(hPorts[0], &getConfig); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetStateThenZesFabricPortGetStateCallSucceeds) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + uint8_t portNumberIndex = pMockIafNlApi->testPortId.portNumber - 1U; + + if (1U == pMockIafNlApi->testPortId.attachId) { + portNumberIndex += pMockIafNlApi->portsPerSubdevice; + } + + zes_fabric_port_state_t state = {}; + state.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES; + state.pNext = nullptr; + result = zesFabricPortGetState(hPorts[portNumberIndex], &state); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, state.stype); + EXPECT_EQ(nullptr, state.pNext); + EXPECT_EQ(pMockIafNlApi->fPortStatus, state.status); + EXPECT_EQ(0U, state.qualityIssues); + EXPECT_EQ(0U, state.failureReasons); + EXPECT_EQ(pMockIafNlApi->testPortId.fabricId, state.remotePortId.fabricId); + EXPECT_EQ(pMockIafNlApi->testPortId.attachId, state.remotePortId.attachId); + EXPECT_EQ(pMockIafNlApi->testPortId.portNumber + 1, state.remotePortId.portNumber); + EXPECT_EQ(-1L, state.rxSpeed.bitRate); + EXPECT_EQ(-1, state.rxSpeed.width); + EXPECT_EQ(-1L, state.txSpeed.bitRate); + EXPECT_EQ(-1, state.txSpeed.width); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetThroughputThenZesFabricPortGetThroughputCallSucceeds) { + uint32_t count = pMockIafNlApi->numPorts; + ASSERT_LE(count, maxNumPorts); + zes_fabric_port_handle_t hPorts[maxNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, pMockIafNlApi->numPorts); + + uint8_t portNumberIndex = pMockIafNlApi->testPortId.portNumber - 1U; + + if (1U == pMockIafNlApi->testPortId.attachId) { + portNumberIndex += pMockIafNlApi->portsPerSubdevice; + } + + zes_fabric_port_throughput_t throughput; + // Initialize values + throughput.timestamp = 0LU; + throughput.rxCounter = std::numeric_limits::max(); + throughput.txCounter = std::numeric_limits::max(); + + result = zesFabricPortGetThroughput(hPorts[portNumberIndex], &throughput); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + // Timestamp is not provided by IafNlApi + EXPECT_EQ(pMockIafNlApi->rxCounter, throughput.rxCounter); + EXPECT_EQ(pMockIafNlApi->txCounter, throughput.txCounter); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingzesFabricPortGetFabricErrorCountersWithLegacyPathAndCallSucceeds) { + VariableBackup backupFsAccess(&pLinuxSysmanImp->pFsAccess); + VariableBackup backupSysfsAccess(&pLinuxSysmanImp->pSysfsAccess); + auto pFsAccess = new MockFabricFsAccess; + auto pSysfsAccess = new MockFabricSysFsAccess; + pLinuxSysmanImp->pFsAccess = pFsAccess; + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_properties_t properties; + + result = zesFabricPortGetProperties(hPorts[0], &properties); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + std::string fabricLinkErrorPath = "/mockRealPath/iaf.5/sd." + std::to_string(properties.portId.attachId) + "/port." + std::to_string(properties.portId.portNumber); + std::string fabricFwErrorPath = "/mockRealPath/iaf.5/sd." + std::to_string(properties.portId.attachId); + std::vector dirs = {"driver", "drm", "iaf.5"}; + uint64_t mockLinkFailures = 401; + uint64_t mockLinkDegrades = 501; + uint64_t mockFwErrors = 301; + uint64_t mockFwCommErrors = 201; + std::map nodes = { + {fabricLinkErrorPath + "/link_failures", mockLinkFailures}, + {fabricLinkErrorPath + "/link_degrades", mockLinkDegrades}, + {fabricFwErrorPath + "/fw_error", mockFwErrors}, + {fabricFwErrorPath + "/fw_comm_errors", mockFwCommErrors}, + }; + static_cast(pFsAccess)->setAccessibleDirectories(dirs); + static_cast(pFsAccess)->setAccessibleNodes(nodes); + zes_fabric_port_error_counters_t errors; + + result = zesFabricPortGetFabricErrorCounters(hPorts[0], &errors); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(errors.linkFailureCount, mockLinkFailures); + EXPECT_EQ(errors.linkDegradeCount, mockLinkDegrades); + EXPECT_EQ(errors.fwErrorCount, mockFwErrors); + EXPECT_EQ(errors.fwCommErrorCount, mockFwCommErrors); + + delete pFsAccess; + delete pSysfsAccess; +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingzesFabricPortGetFabricErrorCountersCallSucceeds) { + VariableBackup backupFsAccess(&pLinuxSysmanImp->pFsAccess); + VariableBackup backupSysfsAccess(&pLinuxSysmanImp->pSysfsAccess); + auto pFsAccess = new MockFabricFsAccess; + auto pSysfsAccess = new MockFabricSysFsAccess; + pLinuxSysmanImp->pFsAccess = pFsAccess; + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_properties_t properties; + + result = zesFabricPortGetProperties(hPorts[0], &properties); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + std::string fabricLinkErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId) + "/port." + std::to_string(properties.portId.portNumber); + std::string fabricFwErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId); + std::vector dirs = {"i915.iaf.5", + "driver", "drm"}; + uint64_t mockLinkFailures = 401; + uint64_t mockLinkDegrades = 501; + uint64_t mockFwErrors = 301; + uint64_t mockFwCommErrors = 201; + std::map nodes = { + {fabricLinkErrorPath + "/link_failures", mockLinkFailures}, + {fabricLinkErrorPath + "/link_degrades", mockLinkDegrades}, + {fabricFwErrorPath + "/fw_error", mockFwErrors}, + {fabricFwErrorPath + "/fw_comm_errors", mockFwCommErrors}, + }; + static_cast(pFsAccess)->setAccessibleDirectories(dirs); + static_cast(pFsAccess)->setAccessibleNodes(nodes); + zes_fabric_port_error_counters_t errors; + + result = zesFabricPortGetFabricErrorCounters(hPorts[0], &errors); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(errors.linkFailureCount, mockLinkFailures); + EXPECT_EQ(errors.linkDegradeCount, mockLinkDegrades); + EXPECT_EQ(errors.fwErrorCount, mockFwErrors); + EXPECT_EQ(errors.fwCommErrorCount, mockFwCommErrors); + + delete pFsAccess; + delete pSysfsAccess; +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingzesFabricPortGetFabricErrorCountersAndGetRealPathFailsThenFailureIsReturned) { + VariableBackup backupFsAccess(&pLinuxSysmanImp->pFsAccess); + VariableBackup backupSysfsAccess(&pLinuxSysmanImp->pSysfsAccess); + auto pFsAccess = new MockFabricFsAccess; + auto pSysfsAccess = new MockFabricSysFsAccess; + pLinuxSysmanImp->pFsAccess = pFsAccess; + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + static_cast(pSysfsAccess)->mockRealPathStatus = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + zes_fabric_port_error_counters_t errors; + + result = zesFabricPortGetFabricErrorCounters(hPorts[0], &errors); + + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); + + delete pFsAccess; + delete pSysfsAccess; +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingzesFabricPortGetFabricErrorCountersAndListDirectoryFailsThenFailureIsReturned) { + VariableBackup backupFsAccess(&pLinuxSysmanImp->pFsAccess); + VariableBackup backupSysfsAccess(&pLinuxSysmanImp->pSysfsAccess); + auto pFsAccess = new MockFabricFsAccess; + auto pSysfsAccess = new MockFabricSysFsAccess; + pLinuxSysmanImp->pFsAccess = pFsAccess; + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + static_cast(pFsAccess)->mockListDirectory = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + zes_fabric_port_error_counters_t errors; + + result = zesFabricPortGetFabricErrorCounters(hPorts[0], &errors); + + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); + + delete pFsAccess; + delete pSysfsAccess; +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingzesFabricPortGetFabricErrorCountersAndIafDriverIsNotLoadedThenFailureIsReturned) { + VariableBackup backupFsAccess(&pLinuxSysmanImp->pFsAccess); + VariableBackup backupSysfsAccess(&pLinuxSysmanImp->pSysfsAccess); + auto pFsAccess = new MockFabricFsAccess; + auto pSysfsAccess = new MockFabricSysFsAccess; + pLinuxSysmanImp->pFsAccess = pFsAccess; + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_properties_t properties; + + result = zesFabricPortGetProperties(hPorts[0], &properties); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + std::string fabricLinkErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId) + "/port." + std::to_string(properties.portId.portNumber); + std::string fabricFwErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId); + std::vector dirs = {"driver", "drm"}; + uint64_t mockLinkFailures = 401; + uint64_t mockLinkDegrades = 501; + uint64_t mockFwErrors = 301; + uint64_t mockFwCommErrors = 201; + std::map nodes = { + {fabricLinkErrorPath + "/link_failures", mockLinkFailures}, + {fabricLinkErrorPath + "/link_degrades", mockLinkDegrades}, + {fabricFwErrorPath + "/fw_error", mockFwErrors}, + {fabricFwErrorPath + "/fw_comm_errors", mockFwCommErrors}, + }; + static_cast(pFsAccess)->setAccessibleDirectories(dirs); + static_cast(pFsAccess)->setAccessibleNodes(nodes); + zes_fabric_port_error_counters_t errors; + + result = zesFabricPortGetFabricErrorCounters(hPorts[0], &errors); + + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); + + delete pFsAccess; + delete pSysfsAccess; +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingzesFabricPortGetFabricErrorCountersAndLinkFailureSysfsNodeIsAbsentThenZeroLinkFailuresAreReturned) { + VariableBackup backupFsAccess(&pLinuxSysmanImp->pFsAccess); + VariableBackup backupSysfsAccess(&pLinuxSysmanImp->pSysfsAccess); + auto pFsAccess = new MockFabricFsAccess; + auto pSysfsAccess = new MockFabricSysFsAccess; + pLinuxSysmanImp->pFsAccess = pFsAccess; + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_properties_t properties; + + result = zesFabricPortGetProperties(hPorts[0], &properties); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + std::string fabricLinkErrorIncorrectPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId + 1) + "/port." + std::to_string(properties.portId.portNumber); + std::string fabricLinkErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId) + "/port." + std::to_string(properties.portId.portNumber); + std::string fabricFwErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId); + std::vector dirs = {"i915.iaf.5", + "driver", "drm"}; + uint64_t mockLinkFailures = 401; + uint64_t mockLinkDegrades = 501; + uint64_t mockFwErrors = 301; + uint64_t mockFwCommErrors = 201; + std::map nodes = { + {fabricLinkErrorIncorrectPath + "/link_failures", mockLinkFailures}, + {fabricLinkErrorPath + "/link_degrades", mockLinkDegrades}, + {fabricFwErrorPath + "/fw_error", mockFwErrors}, + {fabricFwErrorPath + "/fw_comm_errors", mockFwCommErrors}, + }; + static_cast(pFsAccess)->setAccessibleDirectories(dirs); + static_cast(pFsAccess)->setAccessibleNodes(nodes); + zes_fabric_port_error_counters_t errors; + + result = zesFabricPortGetFabricErrorCounters(hPorts[0], &errors); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(errors.linkFailureCount, 0u); + EXPECT_EQ(errors.linkDegradeCount, mockLinkDegrades); + EXPECT_EQ(errors.fwErrorCount, mockFwErrors); + EXPECT_EQ(errors.fwCommErrorCount, mockFwCommErrors); + + delete pFsAccess; + delete pSysfsAccess; +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingzesFabricPortGetFabricErrorCountersAndLinkDegradesSysfsNodeIsAbsentThenZeroLinkDegradesAreReturned) { + VariableBackup backupFsAccess(&pLinuxSysmanImp->pFsAccess); + VariableBackup backupSysfsAccess(&pLinuxSysmanImp->pSysfsAccess); + auto pFsAccess = new MockFabricFsAccess; + auto pSysfsAccess = new MockFabricSysFsAccess; + pLinuxSysmanImp->pFsAccess = pFsAccess; + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_properties_t properties; + + result = zesFabricPortGetProperties(hPorts[0], &properties); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + std::string fabricLinkErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId) + "/port." + std::to_string(properties.portId.portNumber); + std::string fabricLinkErrorIncorrectPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId + 1) + "/port." + std::to_string(properties.portId.portNumber); + std::string fabricFwErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId); + std::vector dirs = {"i915.iaf.5", + "driver", "drm"}; + uint64_t mockLinkFailures = 401; + uint64_t mockLinkDegrades = 501; + uint64_t mockFwErrors = 301; + uint64_t mockFwCommErrors = 201; + std::map nodes = { + {fabricLinkErrorPath + "/link_failures", mockLinkFailures}, + {fabricLinkErrorIncorrectPath + "/link_degrades", mockLinkDegrades}, + {fabricFwErrorPath + "/fw_error", mockFwErrors}, + {fabricFwErrorPath + "/fw_comm_errors", mockFwCommErrors}, + }; + + static_cast(pFsAccess)->setAccessibleDirectories(dirs); + static_cast(pFsAccess)->setAccessibleNodes(nodes); + zes_fabric_port_error_counters_t errors; + + result = zesFabricPortGetFabricErrorCounters(hPorts[0], &errors); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(errors.linkFailureCount, mockLinkFailures); + EXPECT_EQ(errors.linkDegradeCount, 0u); + EXPECT_EQ(errors.fwErrorCount, mockFwErrors); + EXPECT_EQ(errors.fwCommErrorCount, mockFwCommErrors); + + delete pFsAccess; + delete pSysfsAccess; +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingzesFabricPortGetFabricErrorCountersAndFwErrorSysfsNodeIsAbsentThenZeroFwErrorsAreReturned) { + VariableBackup backupFsAccess(&pLinuxSysmanImp->pFsAccess); + VariableBackup backupSysfsAccess(&pLinuxSysmanImp->pSysfsAccess); + auto pFsAccess = new MockFabricFsAccess; + auto pSysfsAccess = new MockFabricSysFsAccess; + pLinuxSysmanImp->pFsAccess = pFsAccess; + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_properties_t properties; + + result = zesFabricPortGetProperties(hPorts[0], &properties); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + std::string fabricLinkErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId) + "/port." + std::to_string(properties.portId.portNumber); + std::string fabricFwErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId); + std::string fabricFwErrorIncorrectPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId + 1); + std::vector dirs = {"i915.iaf.5", + "driver", "drm"}; + uint64_t mockLinkFailures = 401; + uint64_t mockLinkDegrades = 501; + uint64_t mockFwErrors = 301; + uint64_t mockFwCommErrors = 201; + std::map nodes = { + {fabricLinkErrorPath + "/link_failures", mockLinkFailures}, + {fabricLinkErrorPath + "/link_degrades", mockLinkDegrades}, + {fabricFwErrorIncorrectPath + "/fw_error", mockFwErrors}, + {fabricFwErrorPath + "/fw_comm_errors", mockFwCommErrors}, + }; + + static_cast(pFsAccess)->setAccessibleDirectories(dirs); + static_cast(pFsAccess)->setAccessibleNodes(nodes); + zes_fabric_port_error_counters_t errors; + + result = zesFabricPortGetFabricErrorCounters(hPorts[0], &errors); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(errors.linkFailureCount, mockLinkFailures); + EXPECT_EQ(errors.linkDegradeCount, mockLinkDegrades); + EXPECT_EQ(errors.fwErrorCount, 0u); + EXPECT_EQ(errors.fwCommErrorCount, mockFwCommErrors); + + delete pFsAccess; + delete pSysfsAccess; +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingzesFabricPortGetFabricErrorCountersAndFwCommErrorSysfsNodeIsAbsentThenZeroFwCommErrorsAreReturned) { + VariableBackup backupFsAccess(&pLinuxSysmanImp->pFsAccess); + VariableBackup backupSysfsAccess(&pLinuxSysmanImp->pSysfsAccess); + auto pFsAccess = new MockFabricFsAccess; + auto pSysfsAccess = new MockFabricSysFsAccess; + pLinuxSysmanImp->pFsAccess = pFsAccess; + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_properties_t properties; + + result = zesFabricPortGetProperties(hPorts[0], &properties); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + std::string fabricLinkErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId) + "/port." + std::to_string(properties.portId.portNumber); + std::string fabricFwErrorPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId); + std::string fabricFwErrorIncorrectPath = "/mockRealPath/i915.iaf.5/sd." + std::to_string(properties.portId.attachId + 1); + std::vector dirs = {"i915.iaf.5", + "driver", "drm"}; + uint64_t mockLinkFailures = 401; + uint64_t mockLinkDegrades = 501; + uint64_t mockFwErrors = 301; + uint64_t mockFwCommErrors = 201; + std::map nodes = { + {fabricLinkErrorPath + "/link_failures", mockLinkFailures}, + {fabricLinkErrorPath + "/link_degrades", mockLinkDegrades}, + {fabricFwErrorPath + "/fw_error", mockFwErrors}, + {fabricFwErrorIncorrectPath + "/fw_comm_errors", mockFwCommErrors}, + }; + static_cast(pFsAccess)->setAccessibleDirectories(dirs); + static_cast(pFsAccess)->setAccessibleNodes(nodes); + zes_fabric_port_error_counters_t errors; + + result = zesFabricPortGetFabricErrorCounters(hPorts[0], &errors); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(errors.linkFailureCount, mockLinkFailures); + EXPECT_EQ(errors.linkDegradeCount, mockLinkDegrades); + EXPECT_EQ(errors.fwErrorCount, mockFwErrors); + EXPECT_EQ(errors.fwCommErrorCount, 0u); + + delete pFsAccess; + delete pSysfsAccess; +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_zes_fabric_port.cpp b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_zes_fabric_port.cpp new file mode 100644 index 0000000000..8d5bf57e89 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/fabric_port/linux/test_zes_fabric_port.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/test/unit_tests/sources/fabric_port/linux/mock_fabric_device.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include + +namespace L0 { +namespace ult { + +class ZesFabricPortFixture : public SysmanDeviceFixture { + protected: + L0::Sysman::SysmanDevice *device = nullptr; + void SetUp() override { + SysmanDeviceFixture::SetUp(); + device = pSysmanDevice; + L0::Sysman::FabricPortHandleContext *pFabricPortHandleContext = pSysmanDeviceImp->pFabricPortHandleContext; + if (nullptr != pFabricPortHandleContext->pFabricDevice) { + for (L0::Sysman::FabricPort *pFabricPort : pFabricPortHandleContext->handleList) { + delete pFabricPort; + } + pFabricPortHandleContext->handleList.clear(); + delete pFabricPortHandleContext->pFabricDevice; + pFabricPortHandleContext->pFabricDevice = nullptr; + } + MockFabricDevice *mockFabricDevice = new MockFabricDevice(); + pFabricPortHandleContext->pFabricDevice = mockFabricDevice; + } + void TearDown() override { + SysmanDeviceFixture::TearDown(); + } +}; + +TEST_F(ZesFabricPortFixture, GivenPortCountZeroWhenCallingZesFabricPortGetThenCountIsReturnedAndVerifyZesFabricPortGetCallSucceeds) { + uint32_t count = 0U; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, NULL); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, mockNumPorts); +} + +TEST_F(ZesFabricPortFixture, GivenPortCountZeroAndValidHandlePtrWhenCallingZesFabricPortGetThenCountIsReturnedAndNoHandlesReturnedAndVerifyZesFabricPortGetCallSucceeds) { + uint32_t count = 0U; + zes_fabric_port_handle_t handle = static_cast(0UL); + + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, &handle); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, mockNumPorts); + EXPECT_EQ(handle, static_cast(0UL)); +} + +TEST_F(ZesFabricPortFixture, GivenPortCountCorrectWhenCallingZesFabricPortGetThenCountHandlesAreReturnedAndAndVerifyZesFabricPortGetCallSucceeds) { + uint32_t count = mockNumPorts; + zes_fabric_port_handle_t hPorts[mockNumPorts]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, mockNumPorts); +} + +TEST_F(ZesFabricPortFixture, GivenPortCountGreaterThanPortsWhenCallingZesFabricPortGetThenCorrectCountisReturnedAndAndVerifyZesFabricPortGetCallSucceeds) { + uint32_t count = mockNumPorts + 1U; + zes_fabric_port_handle_t hPorts[mockNumPorts + 1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, mockNumPorts); +} + +TEST_F(ZesFabricPortFixture, GivenPortCounLessThanPortsWhenCallingZesFabricPortGetThenCountLessTanPortsHandlesAreReturned) { + uint32_t count = mockNumPorts - 1U; + zes_fabric_port_handle_t hPorts[mockNumPorts - 1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, mockNumPorts - 1U); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetPropertiesThenZesFabricPortGetPropertiesCallSucceeds) { + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_properties_t properties; + // Initialize values + properties.onSubdevice = true; + properties.subdeviceId = std::numeric_limits::max(); + std::memset(properties.model, std::numeric_limits::max(), ZES_MAX_FABRIC_PORT_MODEL_SIZE); + properties.portId.fabricId = std::numeric_limits::max(); + properties.portId.attachId = std::numeric_limits::max(); + properties.portId.portNumber = std::numeric_limits::max(); + properties.maxRxSpeed.bitRate = std::numeric_limits::max(); + properties.maxRxSpeed.width = std::numeric_limits::max(); + properties.maxTxSpeed.bitRate = std::numeric_limits::max(); + properties.maxTxSpeed.width = std::numeric_limits::max(); + + result = zesFabricPortGetProperties(hPorts[0], &properties); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_FALSE(properties.onSubdevice); + EXPECT_EQ(0L, properties.subdeviceId); + EXPECT_STREQ("EXAMPLE", properties.model); + EXPECT_EQ(0U, properties.portId.fabricId); + EXPECT_EQ(0U, properties.portId.attachId); + EXPECT_EQ(0U, properties.portId.portNumber); + EXPECT_EQ(0L, properties.maxRxSpeed.bitRate); + EXPECT_EQ(0, properties.maxRxSpeed.width); + EXPECT_EQ(0L, properties.maxTxSpeed.bitRate); + EXPECT_EQ(0, properties.maxTxSpeed.width); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetLinkTypeThenZesFabricPortGetLinkTypeCallSucceeds) { + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_link_type_t linkType; + result = zesFabricPortGetLinkType(hPorts[0], &linkType); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_STREQ("SAMPLE LINK, VERBOSE", linkType.desc); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetConfigThenZesFabricPortGetConfigCallSucceeds) { + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_config_t getConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = true}; + result = zesFabricPortGetConfig(hPorts[0], &getConfig); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_FALSE(getConfig.enabled); + EXPECT_FALSE(getConfig.beaconing); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortSetConfigThenZesFabricPortGetConfigCallSucceeds) { + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_config_t setConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = true, .beaconing = false}; + result = zesFabricPortSetConfig(hPorts[0U], &setConfig); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + zes_fabric_port_config_t getConfig = {.stype = ZES_STRUCTURE_TYPE_FABRIC_PORT_PROPERTIES, .pNext = nullptr, .enabled = false, .beaconing = true}; + result = zesFabricPortGetConfig(hPorts[0], &getConfig); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_TRUE(getConfig.enabled); + EXPECT_FALSE(getConfig.beaconing); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetStateThenZesFabricPortGetStateCallSucceeds) { + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_state_t state; + result = zesFabricPortGetState(hPorts[0], &state); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(0U, state.status); + EXPECT_EQ(0U, state.qualityIssues); + EXPECT_EQ(0U, state.failureReasons); + EXPECT_EQ(0U, state.remotePortId.fabricId); + EXPECT_EQ(0U, state.remotePortId.attachId); + EXPECT_EQ(0U, state.remotePortId.portNumber); + EXPECT_EQ(0L, state.rxSpeed.bitRate); + EXPECT_EQ(0, state.rxSpeed.width); + EXPECT_EQ(0L, state.txSpeed.bitRate); + EXPECT_EQ(0, state.txSpeed.width); +} + +TEST_F(ZesFabricPortFixture, GivenValidFabricPortHandleWhenCallingZesFabricPortGetThroughputThenZesFabricPortGetThroughputCallSucceeds) { + uint32_t count = 1U; + zes_fabric_port_handle_t hPorts[1U]; + ze_result_t result = zesDeviceEnumFabricPorts(device, &count, hPorts); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(count, 1U); + + zes_fabric_port_throughput_t throughput; + // Initialize values + throughput.timestamp = 0LU; + throughput.rxCounter = std::numeric_limits::max(); + throughput.txCounter = std::numeric_limits::max(); + + result = zesFabricPortGetThroughput(hPorts[0], &throughput); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(0LU, throughput.timestamp); + EXPECT_EQ(0LU, throughput.rxCounter); + EXPECT_EQ(0LU, throughput.txCounter); +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h b/level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h index 854a2a3136..657f7ac975 100644 --- a/level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h +++ b/level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h @@ -75,7 +75,6 @@ class SysmanDeviceFixture : public ::testing::Test { PublicLinuxSysmanImp *pLinuxSysmanImp = nullptr; NEO::ExecutionEnvironment *execEnv = nullptr; std::unique_ptr driverHandle; - L0::Sysman::SysmanDevice *device = nullptr; const uint32_t numRootDevices = 1u; }; @@ -122,7 +121,6 @@ class SysmanMultiDeviceFixture : public ::testing::Test { PublicLinuxSysmanImp *pLinuxSysmanImp = nullptr; NEO::ExecutionEnvironment *execEnv = nullptr; std::unique_ptr driverHandle; - L0::Sysman::SysmanDevice *device = nullptr; const uint32_t numRootDevices = 4u; const uint32_t numSubDevices = 2u; DebugManagerStateRestore restorer; diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/CMakeLists.txt new file mode 100644 index 0000000000..45962c4952 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# Copyright (C) 2020-2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(UNIX) + if(LIBGENL_FOUND) + + set(L0_TESTS_SYSMAN_IAF_NLAPI_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_nl_api.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_nl_dll.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_nl_dll.h + ) + + if(NEO_ENABLE_i915_PRELIM_DETECTION) + list(APPEND L0_TESTS_SYSMAN_IAF_NLAPI_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_iaf_nl_api_prelim.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_nl_api_prelim.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_iaf_nl_api_prelim.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_nl_api_prelim.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_iaf_nl_api_prelim.h + ) + endif() + + target_sources(${TARGET_NAME} + PRIVATE + ${L0_TESTS_SYSMAN_IAF_NLAPI_LINUX} + ) + endif() + +endif() diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.cpp new file mode 100644 index 0000000000..a3002118f5 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2021-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.h" + +#include "level_zero/sysman/source/linux/nl_api/iaf_nl_api.h" + +namespace L0 { +namespace ult { + +ze_result_t MockIafNlApi::fPortStatusQuery(const L0::Sysman::IafPortId portId, L0::Sysman::IafPortState &state) { + if (mockfPortStatusQueryReturnStatus != ZE_RESULT_SUCCESS) { + return mockfPortStatusQueryReturnStatus; + } + + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + state = mockPortState; + + state.healthStatus = _IAF_FPORT_HEALTH_COUNT; + switch (fPortStatus) { + case ZES_FABRIC_PORT_STATUS_HEALTHY: + state.healthStatus = IAF_FPORT_HEALTH_HEALTHY; + break; + case ZES_FABRIC_PORT_STATUS_DEGRADED: + state.healthStatus = IAF_FPORT_HEALTH_DEGRADED; + break; + case ZES_FABRIC_PORT_STATUS_FAILED: + state.healthStatus = IAF_FPORT_HEALTH_FAILED; + break; + case ZES_FABRIC_PORT_STATUS_DISABLED: + state.healthStatus = IAF_FPORT_HEALTH_OFF; + break; + default: + break; + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::getThroughput(const L0::Sysman::IafPortId portId, L0::Sysman::IafPortThroughPut &throughput) { + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + // Timestamp is not provided by IafNlApi + throughput.rxCounter = rxCounter; + throughput.txCounter = txCounter; + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::portStateQuery(const L0::Sysman::IafPortId portId, bool &enabled) { + if (mockportStateQueryReturnStatus != ZE_RESULT_SUCCESS) { + return mockportStateQueryReturnStatus; + } + + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + enabled = portEnabled; + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::portBeaconStateQuery(const L0::Sysman::IafPortId portId, bool &enabled) { + if (mockportBeaconStateQueryReturnStatus != ZE_RESULT_SUCCESS) { + return mockportBeaconStateQueryReturnStatus; + } + + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + enabled = portBeaconing; + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::portBeaconEnable(const L0::Sysman::IafPortId portId) { + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + portBeaconing = true; + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::portBeaconDisable(const L0::Sysman::IafPortId portId) { + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + portBeaconing = false; + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::portEnable(const L0::Sysman::IafPortId portId) { + if (mockportEnableReturnStatus != ZE_RESULT_SUCCESS) { + return mockportEnableReturnStatus; + } + + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + portEnabled = true; + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::portDisable(const L0::Sysman::IafPortId portId) { + if (mockportDisableReturnStatus != ZE_RESULT_SUCCESS) { + return mockportDisableReturnStatus; + } + + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + portEnabled = false; + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::portUsageEnable(const L0::Sysman::IafPortId portId) { + if (mockportUsageEnableReturnStatus != ZE_RESULT_SUCCESS) { + return mockportUsageEnableReturnStatus; + } + + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::portUsageDisable(const L0::Sysman::IafPortId portId) { + if (mockportUsageDisableReturnStatus != ZE_RESULT_SUCCESS) { + return mockportUsageDisableReturnStatus; + } + + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::remRequest() { + if (mockremRequestReturnStatus != ZE_RESULT_SUCCESS) { + return mockremRequestReturnStatus; + } + + genStart += 5; + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::routingGenQuery(uint32_t &start, uint32_t &end) { + ze_result_t result = ZE_RESULT_SUCCESS; + if (!mockroutingGenQueryReturnStatus.empty()) { + result = mockroutingGenQueryReturnStatus.front(); + if (isRepeated != true || result == ZE_RESULT_SUCCESS) { + mockroutingGenQueryReturnStatus.erase(mockroutingGenQueryReturnStatus.begin()); + } + } + + start = genStart; + end = ++genEnd; + return result; +} + +ze_result_t MockIafNlApi::deviceEnum(std::vector &fabricIds) { + if (mockdeviceEnumReturnStatus != ZE_RESULT_SUCCESS) { + return mockdeviceEnumReturnStatus; + } + + fabricIds.clear(); + for (auto i = 0U; i < fabricIdCount; i++) { + fabricIds.push_back(testPortId.fabricId + i); + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::fabricDeviceProperties(const uint32_t fabricId, uint32_t &numSubdevices) { + if (mockfabricDevicePropertiesReturnStatus != ZE_RESULT_SUCCESS) { + return mockfabricDevicePropertiesReturnStatus; + } + + if (validateParams) { + EXPECT_NE(0U, fabricId); + } + + numSubdevices = subDeviceCount; + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::subdevicePropertiesGet(const uint32_t fabricId, const uint32_t attachId, uint64_t &guid, std::vector &ports) { + if (mocksubdevicePropertiesGetReturnStatus != ZE_RESULT_SUCCESS) { + return mocksubdevicePropertiesGetReturnStatus; + } + + if (validateParams) { + EXPECT_NE(0U, fabricId); + EXPECT_LT(attachId, 2U); + } + + ports.clear(); + for (auto i = 0U; i < 8U; i++) { + ports.push_back(i + 1); + } + + guid = constructGuid(fabricId, attachId); + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MockIafNlApi::fportProperties(const L0::Sysman::IafPortId portId, uint64_t &neighborGuid, uint8_t &neighborPortNumber, + L0::Sysman::IafPortSpeed &maxRxSpeed, L0::Sysman::IafPortSpeed &maxTxSpeed, + L0::Sysman::IafPortSpeed &rxSpeed, L0::Sysman::IafPortSpeed &txSpeed) { + + if (mockfportPropertiesReturnStatus != ZE_RESULT_SUCCESS) { + return mockfportPropertiesReturnStatus; + } + + if (validateParams) { + EXPECT_EQ(portId.fabricId, testPortId.fabricId); + EXPECT_EQ(portId.attachId, testPortId.attachId); + EXPECT_EQ(portId.portNumber, testPortId.portNumber); + } + + neighborGuid = constructGuid(portId.fabricId, portId.attachId); + neighborPortNumber = portId.portNumber + 1; + maxRxSpeed.bitRate = -1; + maxRxSpeed.width = -1; + maxTxSpeed.bitRate = -1; + maxTxSpeed.width = -1; + rxSpeed.bitRate = -1; + rxSpeed.width = -1; + txSpeed.bitRate = -1; + txSpeed.width = -1; + + return ZE_RESULT_SUCCESS; +} + +} // namespace ult +} // namespace L0 \ No newline at end of file diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.h b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.h new file mode 100644 index 0000000000..a83b18ffd4 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_iaf_nl_api_prelim.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2021-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "level_zero/sysman/source/linux/nl_api/iaf_nl_api.h" + +#include "gmock/gmock.h" + +#include + +namespace L0 { +namespace ult { + +class MockIafNlApi : public L0::Sysman::IafNlApi { + public: + std::vector mockroutingGenQueryReturnStatus{}; + ze_result_t mockfPortStatusQueryReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockfportPropertiesReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockdeviceEnumReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockfabricDevicePropertiesReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mocksubdevicePropertiesGetReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockportBeaconStateQueryReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockportEnableReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockportUsageEnableReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockportUsageDisableReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockportDisableReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockportStateQueryReturnStatus = ZE_RESULT_SUCCESS; + ze_result_t mockremRequestReturnStatus = ZE_RESULT_SUCCESS; + bool isRepeated = false; + + ze_result_t getPorts(const std::string &devicePciPath, std::vector &ports) override { + + L0::Sysman::IafPort defaultPort; + defaultPort.onSubdevice = true; + defaultPort.portId.fabricId = testPortId.fabricId; + defaultPort.portId.attachId = testPortId.attachId; + defaultPort.portId.portNumber = testPortId.portNumber; + defaultPort.model = "XeLink"; + defaultPort.maxRxSpeed.width = -1; + defaultPort.maxRxSpeed.bitRate = -1; + defaultPort.maxTxSpeed.width = -1; + defaultPort.maxTxSpeed.bitRate = -1; + + if (mockPorts.size() == 0) { + for (uint32_t i = 0; i < numPorts; i++) { + mockPorts.push_back(defaultPort); + } + } + + ports = mockPorts; + return mockGetPortsResult; + } + + ze_result_t fPortStatusQuery(const L0::Sysman::IafPortId portId, L0::Sysman::IafPortState &state) override; + ze_result_t getThroughput(const L0::Sysman::IafPortId portId, L0::Sysman::IafPortThroughPut &throughput) override; + ze_result_t portStateQuery(const L0::Sysman::IafPortId portId, bool &enabled) override; + ze_result_t portBeaconStateQuery(const L0::Sysman::IafPortId portId, bool &enabled) override; + ze_result_t portBeaconEnable(const L0::Sysman::IafPortId portId) override; + ze_result_t portBeaconDisable(const L0::Sysman::IafPortId portId) override; + ze_result_t portEnable(const L0::Sysman::IafPortId portId) override; + ze_result_t portDisable(const L0::Sysman::IafPortId portId) override; + ze_result_t portUsageEnable(const L0::Sysman::IafPortId portId) override; + ze_result_t portUsageDisable(const L0::Sysman::IafPortId portId) override; + ze_result_t remRequest() override; + ze_result_t routingGenQuery(uint32_t &start, uint32_t &end) override; + ze_result_t deviceEnum(std::vector &fabricIds) override; + ze_result_t fabricDeviceProperties(const uint32_t fabricId, uint32_t &numSubdevices) override; + ze_result_t subdevicePropertiesGet(const uint32_t fabricId, const uint32_t attachId, uint64_t &guid, std::vector &ports) override; + ze_result_t fportProperties(const L0::Sysman::IafPortId portId, uint64_t &neighborGuid, uint8_t &neighborPortNumber, + L0::Sysman::IafPortSpeed &maxRxSpeed, L0::Sysman::IafPortSpeed &maxTxSpeed, + L0::Sysman::IafPortSpeed &rxSpeed, L0::Sysman::IafPortSpeed &txSpeed) override; + + bool validateParams = true; + + static constexpr uint32_t defaultFabricId = 0x10000000U; + static constexpr L0::Sysman::IafPortId testPortId{defaultFabricId, 0x1U, 7}; + + static const uint32_t fabricIdCount = 6; + std::vector testFabricIds; + + uint32_t portsPerSubdevice = 8U; + uint32_t subDeviceCount = 2U; + uint32_t numPorts = subDeviceCount * portsPerSubdevice; + + uint64_t timeStamp = 100000000UL; + uint64_t rxCounter = 100000000UL; // Any non-zero, non-maxlongint value + uint64_t txCounter = 200000000UL; // Any non-zero, non-maxlongint value + + zes_fabric_port_status_t fPortStatus = ZES_FABRIC_PORT_STATUS_HEALTHY; + uint64_t constructGuid(const uint32_t fabricId, const uint32_t attachId) { + union { + uint32_t u32[2]; + uint64_t u64; + } s; + s.u32[0] = fabricId; + s.u32[1] = attachId; + return s.u64; + } + + bool portEnabled = true; + bool portBeaconing = true; + + uint32_t genStart = 0; + uint32_t genEnd = 0; + std::vector mockPorts = {}; + ze_result_t mockGetPortsResult = ZE_RESULT_SUCCESS; + L0::Sysman::IafPortState mockPortState = {}; +}; + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.cpp new file mode 100644 index 0000000000..8285378928 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.cpp @@ -0,0 +1,498 @@ +/* + * Copyright (C) 2021-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.h" + +#include "level_zero/sysman/source/linux/nl_api/iaf_nl_api.h" + +namespace L0 { +namespace ult { + +void MockNlApi::validateId(bool checkFabricId, bool checkAttachId, bool checkPortNumber) { + uint64_t fabricId = 0UL; + uint64_t attachId = 0UL; + uint64_t portNumber = 0UL; + if (checkFabricId) { + fabricId = MockNlApi::testPortId.fabricId; + EXPECT_EQ(attribs[IAF_ATTR_FABRIC_ID], fabricId); + } + if (checkAttachId) { + attachId = MockNlApi::testPortId.attachId; + EXPECT_EQ(attribs[IAF_ATTR_SD_INDEX], attachId); + } + if (checkPortNumber) { + portNumber = MockNlApi::testPortId.portNumber; + EXPECT_EQ(attribs[IAF_ATTR_FABRIC_PORT_NUMBER], portNumber); + } +} + +MyNlattr *MockNlApi::copyId(struct genl_info &info, MyNlattr *next, bool copyFabricId, bool copyAttachId, bool copyPortNumber) { + if (copyFabricId) { + next = addAttrib(info, next, IAF_ATTR_FABRIC_ID, attribs[IAF_ATTR_FABRIC_ID]); + } + if (copyAttachId) { + next = addAttrib(info, next, IAF_ATTR_SD_INDEX, attribs[IAF_ATTR_SD_INDEX]); + } + if (copyPortNumber) { + next = addAttrib(info, next, IAF_ATTR_FABRIC_PORT_NUMBER, attribs[IAF_ATTR_FABRIC_PORT_NUMBER]); + } + return next; +} + +MyNlattr *MockNlApi::addAttrib(struct genl_info &info, MyNlattr *next, uint16_t type, uint64_t content) { + next->type = type; + next->content = content; + if (nullptr == info.attrs[type]) { + info.attrs[type] = reinterpret_cast(next); + } + return next->addNext(); +} + +MyNlattr *MockNlApi::addNested(struct genl_info &info, MyNlattr *next, uint16_t type, MyNlattr *nested) { + next->type = type; + next->nested = nested; + return next->addNext(); +} + +MyNlattr *MockNlApi::addDefaultAttribs(struct genl_info &info, MyNlattr *next) { + if (true == cmdMakeContextNotPresent) { + cmdMakeContextNotPresent = false; + } else { + next = addAttrib(info, next, IAF_ATTR_CMD_OP_CONTEXT, cmdMakeContextNotMatch ? 0 : attribs[IAF_ATTR_CMD_OP_CONTEXT]); + } + + if (_IAF_CMD_MSG_TYPE_COUNT != cmdMsgType) { + next = addAttrib(info, next, IAF_ATTR_CMD_OP_MSG_TYPE, cmdMsgType); + } + + if (_IAF_CMD_RSP_COUNT != cmdRspRslt) { + next = addAttrib(info, next, IAF_ATTR_CMD_OP_RESULT, cmdRspRslt); + } + return next; +} + +MyNlattr *MockNlApi::addPort(struct genl_info &info, MyNlattr *next, zes_fabric_port_id_t *port) { + next = addAttrib(info, next, IAF_ATTR_FABRIC_ID, port->fabricId); + next = addAttrib(info, next, IAF_ATTR_SD_INDEX, port->attachId); + next = addAttrib(info, next, IAF_ATTR_FABRIC_PORT_NUMBER, port->portNumber); + return next; +} + +void *MockNlApi::genlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version) { + if (!mockGenlmsgPutReturnValue.empty()) { + void *returnPtr = mockGenlmsgPutReturnValue.front(); + if (isRepeated != true) { + mockGenlmsgPutReturnValue.erase(mockGenlmsgPutReturnValue.begin()); + } + return returnPtr; + } + + for (int i = 0; i < pOps->o_ncmds; i++) { + if (pOps->o_cmds[i].c_id == cmd) { + cmdIndex = i; + } + } + return &pOps->o_cmds[cmdIndex]; +} + +int MockNlApi::genlHandleMsg(struct nl_msg *msg, void *arg) { + struct genl_info info; + MyNlattr *head = new MyNlattr; + MyNlattr *next = head; + + info.attrs = new struct nlattr *[pOps->o_cmds[cmdIndex].c_maxattr]; + for (auto i = 0; i < pOps->o_cmds[cmdIndex].c_maxattr; i++) { + info.attrs[i] = nullptr; + } + next = addDefaultAttribs(info, next); + + switch (pOps->o_cmds[cmdIndex].c_id) { + case IAF_CMD_OP_FPORT_STATUS_QUERY: + validateId(true, true, true); + + for (auto i = 0U; i < 1; i++) { + MyNlattr *nested = new MyNlattr; + MyNlattr *nextNested = nested; + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_HEALTH, fportHealth); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_ISSUE_LQI, fportIssueLqi); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_ISSUE_LWD, fportIssueLwd); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_ISSUE_RATE, fportIssueRate); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_ERROR_FAILED, fportReasonFailed); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_ERROR_ISOLATED, fportReasonIsolated); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_ERROR_LINK_DOWN, fportReasonLinkDown); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_ERROR_FLAPPING, fportReasonFlapping); + addAttrib(info, nextNested, IAF_ATTR_FPORT_ERROR_DID_NOT_TRAIN, fportReasonDidNotTrain); + next = addNested(info, next, IAF_ATTR_FABRIC_PORT, nested); + } + break; + case IAF_CMD_OP_FABRIC_DEVICE_PROPERTIES: + validateId(true, false, false); + + if (true == addSubDeviceCount) { + addAttrib(info, next, IAF_ATTR_SUBDEVICE_COUNT, 2); + } + break; + case IAF_CMD_OP_FPORT_PROPERTIES: + validateId(true, false, false); + + for (auto i = 0U; i < 1; i++) { + MyNlattr *nested = new MyNlattr; + MyNlattr *nextNested = nested; + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_NEIGHBOR_GUID, testGuid); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_NEIGHBOR_PORT_NUMBER, testPortId.portNumber); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_LINK_WIDTH_ENABLED, useInvalidWidth ? 0 : linkWidth1x); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_LINK_WIDTH_ACTIVE, useInvalidWidth ? 0 : linkWidth2x); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_BPS_LINK_SPEED_ACTIVE, linkSpeed); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_RX_ACTIVE, useInvalidWidth ? 0 : linkWidth3x); + nextNested = addAttrib(info, nextNested, IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_TX_ACTIVE, useInvalidWidth ? 0 : linkWidth4x); + addAttrib(info, nextNested, IAF_ATTR_FPORT_BPS_LINK_SPEED_MAX, linkSpeed); + next = addNested(info, next, IAF_ATTR_FABRIC_PORT, nested); + } + break; + case IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET: + validateId(true, false, false); + + if (true == addGUID) { + next = addAttrib(info, next, IAF_ATTR_GUID, testGuid); + } + next = addAttrib(info, next, IAF_ATTR_EXTENDED_PORT_COUNT, 13); + next = addAttrib(info, next, IAF_ATTR_FABRIC_PORT_COUNT, 8); + next = addAttrib(info, next, IAF_ATTR_SWITCH_LIFETIME, 12); + next = addAttrib(info, next, IAF_ATTR_ROUTING_MODE_SUPPORTED, 1); + next = addAttrib(info, next, IAF_ATTR_ROUTING_MODE_ENABLED, 1); + next = addAttrib(info, next, IAF_ATTR_EHHANCED_PORT_0_PRESENT, 1); + for (auto i = addPortZeroAndTypeDisconnected ? 0U : 1U; i <= 8U; i++) { + MyNlattr *nested = new MyNlattr; + MyNlattr *nextNested = nested; + nextNested = addAttrib(info, nextNested, IAF_ATTR_FABRIC_PORT_NUMBER, i); + addAttrib(info, nextNested, IAF_ATTR_FABRIC_PORT_TYPE, addPortZeroAndTypeDisconnected ? IAF_FPORT_TYPE_DISCONNECTED : IAF_FPORT_TYPE_FIXED); + next = addNested(info, next, IAF_ATTR_FABRIC_PORT, nested); + } + for (auto i = 9U; i <= 12U; i++) { + next = addAttrib(info, next, IAF_ATTR_BRIDGE_PORT_NUMBER, i); + } + + break; + case IAF_CMD_OP_FPORT_XMIT_RECV_COUNTS: + validateId(true, true, true); + + if (true == addRxTxCounters) { + next = addAttrib(info, next, IAF_ATTR_FPORT_TX_BYTES, txCounter); + addAttrib(info, next, IAF_ATTR_FPORT_RX_BYTES, rxCounter); + } + break; + case IAF_CMD_OP_PORT_STATE_QUERY: + validateId(true, true, true); + + for (auto i = 0U; i < 1; i++) { + MyNlattr *nested = new MyNlattr; + MyNlattr *nextNested = nested; + nextNested = addAttrib(info, nextNested, IAF_ATTR_FABRIC_PORT_NUMBER, testPortId.portNumber); + addAttrib(info, nextNested, IAF_ATTR_ENABLED_STATE, 1); + next = addNested(info, next, IAF_ATTR_FABRIC_PORT, nested); + } + break; + case IAF_CMD_OP_PORT_BEACON_STATE_QUERY: + validateId(true, true, true); + + for (auto i = 0U; i < 1; i++) { + MyNlattr *nested = new MyNlattr; + MyNlattr *nextNested = nested; + addAttrib(info, nextNested, IAF_ATTR_ENABLED_STATE, 1); + next = addNested(info, next, IAF_ATTR_FABRIC_PORT, nested); + } + break; + case IAF_CMD_OP_ROUTING_GEN_QUERY: + validateId(false, false, false); + + if (true == addRoutingGenStartEnd) { + next = addAttrib(info, next, IAF_ATTR_ROUTING_GEN_START, genStart); + addAttrib(info, next, IAF_ATTR_ROUTING_GEN_END, genEnd); + } + break; + case IAF_CMD_OP_DEVICE_ENUM: + validateId(false, false, false); + + next = addAttrib(info, next, IAF_ATTR_ENTRIES, testFabricIds.size()); + for (auto i = 0U; i < testFabricIds.size(); i++) { + MyNlattr *nested = new MyNlattr; + MyNlattr *nextNested = nested; + nextNested = addAttrib(info, nextNested, IAF_ATTR_FABRIC_ID, testFabricIds[i]); + nextNested = addAttrib(info, nextNested, IAF_ATTR_DEV_NAME, 0UL); + nextNested = addAttrib(info, nextNested, IAF_ATTR_PARENT_DEV_NAME, 0UL); + nextNested = addAttrib(info, nextNested, IAF_ATTR_SOCKET_ID, 0UL); + nextNested = addAttrib(info, nextNested, IAF_ATTR_PCI_SLOT_NUM, 0UL); + nextNested = addAttrib(info, nextNested, IAF_ATTR_SUBDEVICE_COUNT, 0UL); + nextNested = addAttrib(info, nextNested, IAF_ATTR_VERSION, 0UL); + addAttrib(info, nextNested, IAF_ATTR_PRODUCT_TYPE, 0UL); + next = addNested(info, next, IAF_ATTR_FABRIC_DEVICE, nested); + } + break; + case IAF_CMD_OP_PORT_BEACON_ENABLE: + case IAF_CMD_OP_PORT_BEACON_DISABLE: + case IAF_CMD_OP_PORT_ENABLE: + case IAF_CMD_OP_PORT_DISABLE: + case IAF_CMD_OP_PORT_USAGE_ENABLE: + case IAF_CMD_OP_PORT_USAGE_DISABLE: + validateId(true, true, true); + copyId(info, next, true, true, true); + break; + case IAF_CMD_OP_REM_REQUEST: + validateId(false, false, false); + break; + } + + info.nlh = reinterpret_cast(head); + bool succeeded = false; + if (0 == (pOps->o_cmds[cmdIndex].c_msg_parser)(reinterpret_cast(this), &pOps->o_cmds[cmdIndex], &info, arg)) { + succeeded = true; + } + + delete head; + delete info.attrs; + if (succeeded) { + return NLE_SUCCESS; + } else { + return -NLE_FAILURE; + } +} + +int MockNlApi::genlOpsResolve(struct nl_sock *sock, struct genl_ops *ops) { + + int returnValue = 0; + if (!mockGenlOpsResolveReturnValue.empty()) { + returnValue = mockGenlOpsResolveReturnValue.front(); + if (isRepeated != true) { + mockGenlOpsResolveReturnValue.erase(mockGenlOpsResolveReturnValue.begin()); + } + return returnValue; + } + + EXPECT_EQ(0U, ops->o_hdrsize); + EXPECT_NE(nullptr, ops->o_cmds); + + attribs.clear(); + pOps = ops; + + return returnValue; +} + +int MockNlApi::genlCtrlResolve(struct nl_sock *sock, const char *name) { + int returnValue = 0; + if (!mockGenCtrlResolveReturnValue.empty()) { + returnValue = mockGenCtrlResolveReturnValue.front(); + if (isRepeated != true) { + mockGenCtrlResolveReturnValue.erase(mockGenCtrlResolveReturnValue.begin()); + } + } + return returnValue; +} + +int MockNlApi::nlRecvmsgsDefault(struct nl_sock *sock) { + int returnValue = 0; + if (!mockNlRecvmsgsDefaultReturnValue.empty()) { + returnValue = mockNlRecvmsgsDefaultReturnValue.front(); + if (isRepeated != true) { + mockNlRecvmsgsDefaultReturnValue.erase(mockNlRecvmsgsDefaultReturnValue.begin()); + } + return returnValue; + } + + struct nl_msg *msg = nlmsgAlloc(); + returnValue = myCallback(msg, myArgP); + nlmsgFree(msg); + return returnValue; +} + +void *MockNlApi::nlaData(const struct nlattr *attr) { + const MyNlattr *pAttr = reinterpret_cast(attr); + return pAttr->nested; +} + +uint32_t MockNlApi::nlaGetU32(const struct nlattr *attr) { + const MyNlattr *pAttr = reinterpret_cast(attr); + return pAttr->content & 0xFFFFFFFFUL; +} + +uint64_t MockNlApi::nlaGetU64(const struct nlattr *attr) { + const MyNlattr *pAttr = reinterpret_cast(attr); + return pAttr->content; +} + +uint8_t MockNlApi::nlaGetU8(const struct nlattr *attr) { + const MyNlattr *pAttr = reinterpret_cast(attr); + return pAttr->content & 0xFFUL; +} + +int MockNlApi::nlaIsNested(const struct nlattr *attr) { + const MyNlattr *pAttr = reinterpret_cast(attr); + return nullptr != pAttr->nested; +} + +int MockNlApi::nlaLen(const struct nlattr *attr) { + if (nullptr == attr) + return 0; + const MyNlattr *pAttr = reinterpret_cast(attr); + return sizeof(MyNlattr) + nlaLen(reinterpret_cast(pAttr->next)) + nlaLen(reinterpret_cast(pAttr->nested)); +} + +struct nlattr *MockNlApi::nlaNext(const struct nlattr *attr, int *remaining) { + const MyNlattr *pAttr = reinterpret_cast(attr); + *remaining = nlaLen(reinterpret_cast(pAttr->next)); + return reinterpret_cast(pAttr->next); +} + +int MockNlApi::nlaOk(const struct nlattr *attr, int remaining) { + return nullptr != attr; +} + +int MockNlApi::nlaPutU16(struct nl_msg *msg, int id, uint16_t data) { + EXPECT_EQ(attribs.end(), attribs.find(id)); + EXPECT_EQ(NLA_U16, pOps->o_cmds[cmdIndex].c_attr_policy[id].type); + attribs[id] = data; + return 0; +} + +int MockNlApi::nlaPutU32(struct nl_msg *msg, int id, uint32_t data) { + EXPECT_EQ(attribs.end(), attribs.find(id)); + EXPECT_EQ(NLA_U32, pOps->o_cmds[cmdIndex].c_attr_policy[id].type); + attribs[id] = data; + return 0; +} + +int MockNlApi::nlaPutU64(struct nl_msg *msg, int id, uint64_t data) { + EXPECT_EQ(attribs.end(), attribs.find(id)); + EXPECT_EQ(NLA_U64, pOps->o_cmds[cmdIndex].c_attr_policy[id].type); + attribs[id] = data; + return 0; +} + +int MockNlApi::nlaPutU8(struct nl_msg *msg, int id, uint8_t data) { + EXPECT_EQ(attribs.end(), attribs.find(id)); + EXPECT_EQ(NLA_U8, pOps->o_cmds[cmdIndex].c_attr_policy[id].type); + attribs[id] = data; + return 0; +} + +int MockNlApi::nlaType(const struct nlattr *attr) { + const MyNlattr *pAttr = reinterpret_cast(attr); + return pAttr->type; +} + +struct nl_msg *MockNlApi::nlmsgAlloc() { + struct nl_msg *returnPtr = nullptr; + if (!mockNlmsgAllocReturnValue.empty()) { + returnPtr = mockNlmsgAllocReturnValue.front(); + if (isRepeated != true) { + mockNlmsgAllocReturnValue.erase(mockNlmsgAllocReturnValue.begin()); + } + + return returnPtr; + } + + return reinterpret_cast(new char[128]); +} + +struct nlattr *MockNlApi::nlmsgAttrdata(const struct nlmsghdr *hdr, int attr) { + return reinterpret_cast(const_cast(hdr)); +} + +int MockNlApi::nlmsgAttrlen(const struct nlmsghdr *hdr, int attr) { + return nlaLen(nlmsgAttrdata(hdr, attr)); +} + +void MockNlApi::nlmsgFree(struct nl_msg *msg) { + delete reinterpret_cast(msg); // NOLINT(clang-analyzer-unix.MismatchedDeallocator) +} + +int MockNlApi::nlSendAuto(struct nl_sock *sock, struct nl_msg *msg) { + int returnValue = 0; + if (!mockNlSendAutoReturnValue.empty()) { + returnValue = mockNlSendAutoReturnValue.front(); + mockNlSendAutoReturnValue.erase(mockNlSendAutoReturnValue.begin()); + } + return returnValue; +} + +bool MockNlApi::loadEntryPoints() { + bool returnValue = true; + if (!mockLoadEntryPointsReturnValue.empty()) { + returnValue = mockLoadEntryPointsReturnValue.front(); + if (isRepeated != true) { + mockLoadEntryPointsReturnValue.erase(mockLoadEntryPointsReturnValue.begin()); + } + } + return returnValue; +} + +int MockNlApi::genlRegisterFamily(struct genl_ops *ops) { + int returnValue = 0; + if (!mockGenlRegisterFamilyReturnValue.empty()) { + returnValue = mockGenlRegisterFamilyReturnValue.front(); + if (!mockGenlRegisterFamilyArgumentValue.empty()) { + pOps = mockGenlRegisterFamilyArgumentValue.front(); + } + + if (isMockGenlRegisterFamilyRepeatedCall.front() != true) { + if (!mockGenlRegisterFamilyArgumentValue.empty()) { + mockGenlRegisterFamilyArgumentValue.erase(mockGenlRegisterFamilyArgumentValue.begin()); + } + mockGenlRegisterFamilyReturnValue.erase(mockGenlRegisterFamilyReturnValue.begin()); + isMockGenlRegisterFamilyRepeatedCall.erase(isMockGenlRegisterFamilyRepeatedCall.begin()); + } + } + return returnValue; +} + +struct nl_sock *MockNlApi::nlSocketAlloc() { + struct nl_sock *returnPtr = nullptr; + if (!mockNlSocketAllocReturnValue.empty()) { + returnPtr = mockNlSocketAllocReturnValue.front(); + if (isRepeated != true) { + mockNlSocketAllocReturnValue.erase(mockNlSocketAllocReturnValue.begin()); + } + } + return returnPtr; +} + +int MockNlApi::genlConnect(struct nl_sock *sock) { + int returnValue = 0; + if (!mockGenlConnectReturnValue.empty()) { + returnValue = mockGenlConnectReturnValue.front(); + if (isRepeated != true) { + mockGenlConnectReturnValue.erase(mockGenlConnectReturnValue.begin()); + } + } + return returnValue; +} + +int MockNlApi::nlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg) { + int returnValue = 0; + myCallback = cb; + myArgP = arg; + if (!mockNlSocketModifyCbReturnValue.empty()) { + returnValue = mockNlSocketModifyCbReturnValue.front(); + if (isRepeated != true) { + mockNlSocketModifyCbReturnValue.erase(mockNlSocketModifyCbReturnValue.begin()); + } + } + return returnValue; +} + +int MockNlApi::genlUnregisterFamily(struct genl_ops *ops) { + int returnValue = 0; + if (!mockGenlUnregisterFamilyReturnValue.empty()) { + returnValue = mockGenlUnregisterFamilyReturnValue.front(); + if (isRepeated != true) { + mockGenlUnregisterFamilyReturnValue.erase(mockGenlUnregisterFamilyReturnValue.begin()); + } + } + return returnValue; +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.h b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.h new file mode 100644 index 0000000000..703d0bf4ed --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2021-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/test/common/test_macros/mock_method_macros.h" + +#include "level_zero/sysman/source/linux/nl_api/iaf_nl_api.h" +#include "level_zero/sysman/source/linux/nl_api/nl_api.h" + +#include "gmock/gmock.h" + +#include + +namespace L0 { +namespace ult { + +class MyNlattr { + public: + uint16_t type = NLA_UNSPEC; + uint64_t content; + MyNlattr *next = nullptr; + MyNlattr *nested = nullptr; + MyNlattr *addNext() { + next = new MyNlattr; + return next; + } + MyNlattr() = default; + ~MyNlattr() { + if (nested) + delete nested; + if (next) + delete next; + } +}; + +class MockNlApi : public L0::Sysman::NlApi { + public: + std::vector mockNlSocketAllocReturnValue{}; + std::vector mockGenlRegisterFamilyArgumentValue{}; + std::vector mockNlmsgAllocReturnValue{}; + std::vector mockGenlmsgPutReturnValue{}; + std::vector mockGenlRegisterFamilyReturnValue{}; + std::vector mockGenlConnectReturnValue{}; + std::vector mockGenlOpsResolveReturnValue{}; + std::vector mockGenCtrlResolveReturnValue{}; + std::vector mockNlSocketModifyCbReturnValue{}; + std::vector mockNlRecvmsgsDefaultReturnValue{}; + std::vector mockGenlUnregisterFamilyReturnValue{}; + std::vector mockNlSendAutoReturnValue{}; + std::vector mockLoadEntryPointsReturnValue{}; + std::vector isMockGenlRegisterFamilyRepeatedCall{}; + bool isRepeated = false; + + int genlUnregisterFamily(struct genl_ops *ops) override; + int genlHandleMsg(struct nl_msg *msg, void *arg) override; + int genlOpsResolve(struct nl_sock *sock, struct genl_ops *ops) override; + int genlCtrlResolve(struct nl_sock *sock, const char *name) override; + void *genlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version) override; + int nlRecvmsgsDefault(struct nl_sock *sock) override; + void *nlaData(const struct nlattr *attr) override; + uint32_t nlaGetU32(const struct nlattr *attr) override; + uint64_t nlaGetU64(const struct nlattr *attr) override; + uint8_t nlaGetU8(const struct nlattr *attr) override; + int nlaIsNested(const struct nlattr *attr) override; + int nlaLen(const struct nlattr *attr) override; + struct nlattr *nlaNext(const struct nlattr *attr, int *remaining) override; + int nlaOk(const struct nlattr *attr, int remaining) override; + int nlaPutU16(struct nl_msg *msg, int id, uint16_t data) override; + int nlaPutU32(struct nl_msg *msg, int id, uint32_t data) override; + int nlaPutU64(struct nl_msg *msg, int id, uint64_t data) override; + int nlaPutU8(struct nl_msg *msg, int id, uint8_t data) override; + int nlaType(const struct nlattr *attr) override; + struct nl_msg *nlmsgAlloc() override; + struct nlattr *nlmsgAttrdata(const struct nlmsghdr *hdr, int attr) override; + int nlmsgAttrlen(const struct nlmsghdr *hdr, int attr) override; + void nlmsgFree(struct nl_msg *msg) override; + int nlSendAuto(struct nl_sock *sock, struct nl_msg *msg) override; + bool loadEntryPoints() override; + int genlRegisterFamily(struct genl_ops *ops) override; + struct nl_sock *nlSocketAlloc() override; + int genlConnect(struct nl_sock *sock) override; + int nlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg) override; + + ADDMETHOD_NOBASE(nlmsgHdr, struct nlmsghdr *, nullptr, (struct nl_msg * msg)); + ADDMETHOD_NOBASE_VOIDRETURN(nlSocketDisableSeqCheck, (struct nl_sock * sock)); + ADDMETHOD_NOBASE_VOIDRETURN(nlSocketFree, (struct nl_sock * sock)); + + MockNlApi() = default; + ~MockNlApi() override = default; + + nl_recvmsg_msg_cb_t myCallback; + void *myArgP; + + static constexpr L0::Sysman::IafPortId testPortId{0x10000000U, 0x1U, 7}; + const uint64_t testGuid = 0x1234567887654321; + + const uint8_t linkSpeed12g = 1; + const uint8_t linkSpeed25g = 2; + const uint8_t linkSpeed53g = 4; + const uint8_t linkSpeed90g = 8; + + const uint8_t linkWidth1x = 1; + const uint8_t linkWidth2x = 2; + const uint8_t linkWidth3x = 4; + const uint8_t linkWidth4x = 8; + + bool useInvalidWidth = false; + uint8_t linkSpeed = linkSpeed90g; + bool addRxTxCounters = true; + bool addRoutingGenStartEnd = true; + bool addSubDeviceCount = true; + bool addGUID = true; + bool addPortZeroAndTypeDisconnected = false; + enum iaf_fport_health fportHealth = IAF_FPORT_HEALTH_HEALTHY; + uint8_t fportIssueLqi = 0; + uint8_t fportIssueLwd = 0; + uint8_t fportIssueRate = 0; + uint8_t fportReasonFailed = 0; + uint8_t fportReasonIsolated = 0; + uint8_t fportReasonLinkDown = 0; + uint8_t fportReasonDidNotTrain = 0; + uint8_t fportReasonFlapping = 0; + + const uint8_t testLinkWidthUnknown = -1; + const uint8_t testLinkWidth1x = 1; + const uint8_t testLinkWidth2x = 2; + const uint8_t testLinkWidth3x = 3; + const uint8_t testLinkWidth4x = 4; + + uint32_t genStart = 1U; // Any non-zero, non-maxint value + uint32_t genEnd = 2U; // Any non-zero, non-maxint value + + uint64_t rxCounter = 100000000UL; // Any non-zero, non-maxlongint value + uint64_t txCounter = 200000000UL; // Any non-zero, non-maxlongint value + + bool cmdMakeContextNotPresent = false; + bool cmdMakeContextNotMatch = false; + uint8_t cmdMsgType = IAF_CMD_MSG_RESPONSE; + uint8_t cmdRspRslt = IAF_CMD_RSP_SUCCESS; + + std::vector testFabricIds; + + private: + int cmdIndex = 0; + std::map attribs; + struct genl_ops *pOps = nullptr; + + void validateId(bool checkFabricId, bool checkAttachId, bool checkPortNumber); + MyNlattr *copyId(struct genl_info &info, MyNlattr *next, bool checkFabricId, bool checkAttachId, bool checkPortNumber); + MyNlattr *addAttrib(struct genl_info &info, MyNlattr *next, uint16_t type, uint64_t content); + MyNlattr *addNested(struct genl_info &info, MyNlattr *next, uint16_t type, MyNlattr *nested); + MyNlattr *addDefaultAttribs(struct genl_info &info, MyNlattr *next); + MyNlattr *addPort(struct genl_info &info, MyNlattr *next, zes_fabric_port_id_t *port); +}; + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.cpp b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.cpp new file mode 100644 index 0000000000..441a294bd3 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.cpp @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h" + +#include + +namespace L0 { +namespace ult { + +extern "C" { +static int mockCallback(struct nl_msg *msg, void *arg) { + return NL_OK; +} +} + +struct nl_sock MockNlDll::mockNlSock; +struct nl_msg MockNlDll::mockNlMsg; +struct nlmsghdr MockNlDll::mockNlmsghdr; +struct nlattr MockNlDll::mockNlattr; +struct nlattr MockNlDll::mockNextNlattr; +struct genl_ops MockNlDll::mockGenlOps; +nl_recvmsg_msg_cb_t MockNlDll::mockCb = mockCallback; + +extern "C" { +int mockGenlConnect(struct nl_sock *sock) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + return 0; +} + +int mockGenlCtrlResolve(struct nl_sock *sock, const char *name) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + EXPECT_FALSE(strcmp(MockNlDll::mockFamilyName, name)); + return 0; +} + +int mockGenlHandleMsg(struct nl_msg *msg, void *arg) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockArgP, arg); + return 0; +} + +void *mockGenlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockFamilyId, family); + EXPECT_EQ(MockNlDll::mockPort, port); + EXPECT_EQ(MockNlDll::mockSeq, seq); + EXPECT_EQ(MockNlDll::mockCmd, cmd); + EXPECT_EQ(MockNlDll::mockHdrlen, hdrlen); + EXPECT_EQ(MockNlDll::mockFlags, flags); + EXPECT_EQ(MockNlDll::mockVersion, version); + return msg; +} + +int mockGenlOpsResolve(struct nl_sock *sock, struct genl_ops *ops) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + EXPECT_EQ(&MockNlDll::mockGenlOps, ops); + return 0; +} + +int mockGenlRegisterFamily(struct genl_ops *ops) { + EXPECT_EQ(&MockNlDll::mockGenlOps, ops); + return 0; +} + +int mockGenlUnregisterFamily(struct genl_ops *ops) { + EXPECT_EQ(&MockNlDll::mockGenlOps, ops); + return 0; +} + +struct nl_sock *mockNlSocketAlloc() { + return &MockNlDll::mockNlSock; +} + +void mockNlSocketDisableSeqCheck(struct nl_sock *sock) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + return; +} + +void mockNlSocketFree(struct nl_sock *sock) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + return; +} + +int mockNlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + EXPECT_EQ(MockNlDll::mockCbType, type); + EXPECT_EQ(MockNlDll::mockCbKind, kind); + EXPECT_EQ(MockNlDll::mockCb, cb); + EXPECT_EQ(MockNlDll::mockArgP, arg); + return 0; +} + +int mockNlRecvmsgsDefault(struct nl_sock *sock) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + return 0; +} + +int mockNlSendAuto(struct nl_sock *sock, struct nl_msg *msg) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + return 0; +} + +void *mockNlaData(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return &MockNlDll::mockNlattr; +} + +uint32_t mockNlaGetU32(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockU32Val; +} + +uint64_t mockNlaGetU64(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockU64Val; +} + +uint8_t mockNlaGetU8(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockU8Val; +} + +int mockNlaIsNested(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return 0; +} + +int mockNlaLen(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockAttrLen; +} + +struct nlattr *mockNlaNext(const struct nlattr *attr, int *remaining) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + EXPECT_EQ(MockNlDll::mockRemainBefore, *remaining); + *remaining = MockNlDll::mockRemainAfter; + return &MockNlDll::mockNextNlattr; +} + +int mockNlaOk(const struct nlattr *attr, int remaining) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + EXPECT_EQ(MockNlDll::mockRemainBefore, remaining); + return 0; +} + +int mockNlaPutU16(struct nl_msg *msg, int type, uint16_t data) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockType, type); + EXPECT_EQ(MockNlDll::mockU16Val, data); + return 0; +} + +int mockNlaPutU32(struct nl_msg *msg, int type, uint32_t data) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockType, type); + EXPECT_EQ(MockNlDll::mockU32Val, data); + return 0; +} + +int mockNlaPutU64(struct nl_msg *msg, int type, uint64_t data) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockType, type); + EXPECT_EQ(MockNlDll::mockU64Val, data); + return 0; +} + +int mockNlaPutU8(struct nl_msg *msg, int type, uint8_t data) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockType, type); + EXPECT_EQ(MockNlDll::mockU8Val, data); + return 0; +} + +int mockNlaType(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockType; +} + +struct nl_msg *mockNlmsgAlloc() { + return &MockNlDll::mockNlMsg; +} + +void mockNlmsgFree(struct nl_msg *msg) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + return; +} + +struct nlattr *mockNlmsgAttrdata(const struct nlmsghdr *hdr, int attr) { + EXPECT_EQ(&MockNlDll::mockNlmsghdr, hdr); + EXPECT_EQ(MockNlDll::mockAttr, attr); + return &MockNlDll::mockNlattr; +} + +int mockNlmsgAttrlen(const struct nlmsghdr *hdr, int attr) { + EXPECT_EQ(&MockNlDll::mockNlmsghdr, hdr); + EXPECT_EQ(MockNlDll::mockAttr, attr); + return MockNlDll::mockAttrLen; +} + +struct nlmsghdr *mockNlmsgHdr(struct nl_msg *msg) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + return &MockNlDll::mockNlmsghdr; +} +} + +MockNlDll::MockNlDll() { + funcMap["genl_connect"] = reinterpret_cast(&mockGenlConnect); + funcMap["genl_ctrl_resolve"] = reinterpret_cast(&mockGenlCtrlResolve); + funcMap["genl_handle_msg"] = reinterpret_cast(&mockGenlHandleMsg); + funcMap["genlmsg_put"] = reinterpret_cast(&mockGenlmsgPut); + funcMap["genl_ops_resolve"] = reinterpret_cast(&mockGenlOpsResolve); + funcMap["genl_register_family"] = reinterpret_cast(&mockGenlRegisterFamily); + funcMap["genl_unregister_family"] = reinterpret_cast(&mockGenlUnregisterFamily); + funcMap["nl_recvmsgs_default"] = reinterpret_cast(&mockNlRecvmsgsDefault); + funcMap["nl_send_auto"] = reinterpret_cast(&mockNlSendAuto); + funcMap["nl_socket_alloc"] = reinterpret_cast(&mockNlSocketAlloc); + funcMap["nl_socket_disable_seq_check"] = reinterpret_cast(&mockNlSocketDisableSeqCheck); + funcMap["nl_socket_free"] = reinterpret_cast(&mockNlSocketFree); + funcMap["nl_socket_modify_cb"] = reinterpret_cast(&mockNlSocketModifyCb); + funcMap["nla_data"] = reinterpret_cast(&mockNlaData); + funcMap["nla_get_u32"] = reinterpret_cast(&mockNlaGetU32); + funcMap["nla_get_u64"] = reinterpret_cast(&mockNlaGetU64); + funcMap["nla_get_u8"] = reinterpret_cast(&mockNlaGetU8); + funcMap["nla_is_nested"] = reinterpret_cast(&mockNlaIsNested); + funcMap["nla_len"] = reinterpret_cast(&mockNlaLen); + funcMap["nla_next"] = reinterpret_cast(&mockNlaNext); + funcMap["nla_ok"] = reinterpret_cast(&mockNlaOk); + funcMap["nla_put_u16"] = reinterpret_cast(&mockNlaPutU16); + funcMap["nla_put_u32"] = reinterpret_cast(&mockNlaPutU32); + funcMap["nla_put_u64"] = reinterpret_cast(&mockNlaPutU64); + funcMap["nla_put_u8"] = reinterpret_cast(&mockNlaPutU8); + funcMap["nla_type"] = reinterpret_cast(&mockNlaType); + funcMap["nlmsg_alloc"] = reinterpret_cast(&mockNlmsgAlloc); + funcMap["nlmsg_attrdata"] = reinterpret_cast(&mockNlmsgAttrdata); + funcMap["nlmsg_attrlen"] = reinterpret_cast(&mockNlmsgAttrlen); + funcMap["nlmsg_free"] = reinterpret_cast(&mockNlmsgFree); + funcMap["nlmsg_hdr"] = reinterpret_cast(&mockNlmsgHdr); +} + +void *MockNlDll::getProcAddress(const std::string &procName) { + auto it = funcMap.find(procName); + if (funcMap.end() == it) { + return nullptr; + } else { + return it->second; + } +} + +void MockNlDll::deleteEntryPoint(const std::string &procName) { + auto it = funcMap.find(procName); + if (funcMap.end() != it) { + funcMap.erase(it); + } +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h new file mode 100644 index 0000000000..a1ac5a0f31 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/os_interface/os_library.h" + +#include "level_zero/sysman/source/linux/nl_api/nl_api.h" + +#include "gmock/gmock.h" + +// Define opaque types so variables can be allocated +struct nl_sock { +}; + +struct nl_msg { +}; + +namespace L0 { +namespace ult { + +class MockNlDll : public NEO::OsLibrary { + public: + bool isLoaded() override { return false; } + void *getProcAddress(const std::string &procName) override; + + void deleteEntryPoint(const std::string &procName); + + MockNlDll(); + + static struct nl_sock mockNlSock; + static struct nl_msg mockNlMsg; + static struct nlmsghdr mockNlmsghdr; + static struct nlattr mockNlattr; + static struct nlattr mockNextNlattr; + static struct genl_ops mockGenlOps; + static nl_recvmsg_msg_cb_t mockCb; + + constexpr static int mockFamilyId = 0x2020; + constexpr static char mockFamilyName[] = "TestName"; + constexpr static void *mockArgP = nullptr; + constexpr static uint32_t mockPort = NL_AUTO_PID; + constexpr static uint32_t mockSeq = NL_AUTO_SEQ; + constexpr static int mockHdrlen = NLMSG_HDRLEN; + constexpr static int mockFlags = 0; + constexpr static uint8_t mockCmd = 1; + constexpr static uint8_t mockVersion = 2; + constexpr static int mockType = 3; + constexpr static uint8_t mockU8Val = 0x7fU; + constexpr static uint16_t mockU16Val = 0x7fffU; + constexpr static uint32_t mockU32Val = 0x7fffffffU; + constexpr static uint64_t mockU64Val = 0x7fffffffffffffffUL; + constexpr static int mockAttr = 4; + constexpr static int mockAttrLen = 8; + constexpr static int mockRemainBefore = 20; + constexpr static int mockRemainAfter = 16; + constexpr static enum nl_cb_type mockCbType = NL_CB_VALID; + constexpr static enum nl_cb_kind mockCbKind = NL_CB_CUSTOM; + + private: + std::map funcMap; +}; + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/test_sysman_iaf_nl_api_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/test_sysman_iaf_nl_api_prelim.cpp new file mode 100644 index 0000000000..d968523380 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/test_sysman_iaf_nl_api_prelim.cpp @@ -0,0 +1,964 @@ +/* + * Copyright (C) 2021-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/common/helpers/variable_backup.h" +#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h" + +#include "level_zero/sysman/source/linux/nl_api/iaf_nl_api.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_api_prelim.h" + +#include "gmock/gmock.h" + +#include +#include + +extern bool sysmanUltsEnable; +struct nl_sock { +}; + +namespace NEO { +extern std::map> directoryFilesMap; +} + +namespace L0 { +namespace ult { + +class PublicIafNlApi : public L0::Sysman::IafNlApi { + public: + using IafNlApi::cleanup; + using IafNlApi::init; + using IafNlApi::pNlApi; +}; + +class SysmanIafNlApiFixture : public ::testing::Test { + protected: + PublicIafNlApi testIafNlApi; + + void SetUp() override { + if (!sysmanUltsEnable) { + GTEST_SKIP(); + } + auto mockNlApi = std::make_unique(); + + testIafNlApi.pNlApi = std::move(mockNlApi); + } + void TearDown() override { + } + void setupExpectCommand(uint16_t cmd, uint32_t fabricId, uint32_t attachId, uint8_t portId); + void setupExpectCommand(uint16_t cmd, uint32_t fabricId, uint32_t attachId); + void setupExpectCommand(uint16_t cmd, uint32_t fabricId); + void setupExpectCommand(uint16_t cmd); + void setupExpectInit(); + void setupExpectCleanup(); + void setupExpectInitMultiple(); + void setupExpectCleanupMultiple(); + + public: + struct nl_sock nlSock; + struct genl_ops *pOps; + static const char *iafFamilyName; +}; + +const char *SysmanIafNlApiFixture::iafFamilyName = "iaf_ze"; + +void SysmanIafNlApiFixture::setupExpectCommand(uint16_t cmd, uint32_t fabricId, uint32_t attachId, uint8_t portNumber) { + setupExpectCommand(cmd, fabricId, attachId); +} + +void SysmanIafNlApiFixture::setupExpectCommand(uint16_t cmd, uint32_t fabricId, uint32_t attachId) { + setupExpectCommand(cmd, fabricId); +} + +void SysmanIafNlApiFixture::setupExpectCommand(uint16_t cmd, uint32_t fabricId) { + setupExpectCommand(cmd); +} + +void SysmanIafNlApiFixture::setupExpectCommand(uint16_t cmd) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockNlSendAutoReturnValue.push_back(0); +} + +void SysmanIafNlApiFixture::setupExpectInit() { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyArgumentValue.push_back(pOps); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + pMockNlApi->mockNlSocketAllocReturnValue.push_back(&nlSock); + pMockNlApi->mockGenlConnectReturnValue.push_back(0); + pMockNlApi->mockGenCtrlResolveReturnValue.push_back(0); + pMockNlApi->mockNlSocketModifyCbReturnValue.push_back(0); +} + +void SysmanIafNlApiFixture::setupExpectInitMultiple() { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyArgumentValue.push_back(pOps); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(true); + pMockNlApi->mockNlSocketAllocReturnValue.push_back(&nlSock); + pMockNlApi->mockGenlConnectReturnValue.push_back(0); + pMockNlApi->mockGenCtrlResolveReturnValue.push_back(0); + pMockNlApi->mockNlSocketModifyCbReturnValue.push_back(0); + pMockNlApi->isRepeated = true; +} + +void SysmanIafNlApiFixture::setupExpectCleanupMultiple() { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockGenlUnregisterFamilyReturnValue.push_back(0); + pMockNlApi->isRepeated = true; +} + +void SysmanIafNlApiFixture::setupExpectCleanup() { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockGenlUnregisterFamilyReturnValue.push_back(0); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenLoadEntryPointsFailsThenInitRepeatedlyReturnsDependencyUnavailable) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(false); + EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, testIafNlApi.init()); + EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, testIafNlApi.init()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGenlRegisterFamilyFailesWithExistThenInitReturnsNotReady) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(-NLE_EXIST); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + EXPECT_EQ(ZE_RESULT_NOT_READY, testIafNlApi.init()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGenlRegisterFamilyFailesWithAnyOtherErrorInitReturnsErrorUnknown) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(-NLE_FAILURE); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.init()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenNlSocketAllocFailsThenInitReturnsErrorUnknown) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + pMockNlApi->mockNlSocketAllocReturnValue.push_back(nullptr); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.init()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGenlConnectFailsThenInitReturnsErrorUnknown) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + pMockNlApi->mockNlSocketAllocReturnValue.push_back(&nlSock); + pMockNlApi->mockGenlConnectReturnValue.push_back(-1); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.init()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGenlOpsResolveFailsThenInitReturnsErrorUnknown) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + pMockNlApi->mockNlSocketAllocReturnValue.push_back(&nlSock); + pMockNlApi->mockGenlConnectReturnValue.push_back(0); + pMockNlApi->mockGenlOpsResolveReturnValue.push_back(-1); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.init()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGenlCtrlResolveFailsThenInitReturnsErrorUnknown) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + pMockNlApi->mockNlSocketAllocReturnValue.push_back(&nlSock); + pMockNlApi->mockGenlConnectReturnValue.push_back(0); + pMockNlApi->mockGenlOpsResolveReturnValue.push_back(0); + pMockNlApi->mockGenCtrlResolveReturnValue.push_back(-1); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.init()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenNlSocketModifyCbFailsThenInitReturnsErrorUnknown) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + pMockNlApi->mockNlSocketAllocReturnValue.push_back(&nlSock); + pMockNlApi->mockGenlConnectReturnValue.push_back(0); + pMockNlApi->mockGenlOpsResolveReturnValue.push_back(0); + pMockNlApi->mockGenCtrlResolveReturnValue.push_back(0); + pMockNlApi->mockNlSocketModifyCbReturnValue.push_back(-1); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.init()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenAllNlApisReturnSuccessThenInitReturnsSuccess) { + setupExpectInit(); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.init()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenInitSucceedsThenCleanupSucceeds) { + setupExpectInit(); + setupExpectCleanup(); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.init()); + testIafNlApi.cleanup(); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenInitCalledMultipleTimesThenLoadEntryPointsOnlyCalledOnce) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(true); + pMockNlApi->mockGenlRegisterFamilyArgumentValue.push_back(pOps); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(true); + pMockNlApi->mockNlSocketAllocReturnValue.push_back(&nlSock); + pMockNlApi->mockGenlConnectReturnValue.push_back(0); + pMockNlApi->mockGenlOpsResolveReturnValue.push_back(0); + pMockNlApi->mockGenCtrlResolveReturnValue.push_back(0); + pMockNlApi->mockNlSocketModifyCbReturnValue.push_back(0); + pMockNlApi->isRepeated = true; + + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.init()); + testIafNlApi.cleanup(); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.init()); + testIafNlApi.cleanup(); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledThenReturnSuccess) { + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_REM_REQUEST); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndInitFailsThenErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(false); + + EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndNlmsgAllocFailsThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockNlmsgAllocReturnValue.push_back(nullptr); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenCallingHandleResponseWithInvalidCommandThenUnknownErrorReturned) { + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.handleResponse(_IAF_CMD_OP_COUNT + 1, nullptr, nullptr)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndPerformTransactionRecvmsgsDefaultFailedThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockNlSendAutoReturnValue.push_back(0); + pMockNlApi->mockNlRecvmsgsDefaultReturnValue.push_back(-NLE_FAILURE); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndPerformTransactionRecvmsgsDefaulFailsWith_NLE_PERM_ThenInsufficientPermissionsReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockNlSendAutoReturnValue.push_back(0); + pMockNlApi->mockNlRecvmsgsDefaultReturnValue.push_back(-NLE_PERM); + EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndNlOperationFailsWhenResponseTypeNotResponseThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_REM_REQUEST); + pMockNlApi->cmdMsgType = IAF_CMD_MSG_REQUEST; + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndNlOperationFailsWhenOpResultNotSuccessThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_REM_REQUEST); + pMockNlApi->cmdRspRslt = IAF_CMD_RSP_FAILURE; + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndNlOperationFailsWhenResponseTypeNotPresentThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_REM_REQUEST); + pMockNlApi->cmdMsgType = _IAF_CMD_MSG_TYPE_COUNT; + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndNlOperationFailsWhenOpResultNotPresentThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_REM_REQUEST); + pMockNlApi->cmdRspRslt = _IAF_CMD_RSP_COUNT; + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndPerformTransactionNlSendAutoFailedThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockNlSendAutoReturnValue.push_back(-1); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndNlOperationFailsWhenMakeContextNotMatchThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_REM_REQUEST); + pMockNlApi->cmdMakeContextNotMatch = true; + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndNlOperationFailsWhenMakeContextNotPresentThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->cmdMakeContextNotPresent = true; + pMockNlApi->mockNlSendAutoReturnValue.push_back(0); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndAllocMsgFailsWhenGenlmsgPutReturnNullPtrThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockGenlmsgPutReturnValue.push_back(nullptr); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRemRequestCalledAndUnexpectedCmdCompletesThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockGenlmsgPutReturnValue.push_back(pMockNlApi); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.remRequest()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortBeaconEnableCalledThenReturnSuccess) { + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_PORT_BEACON_ENABLE, MockNlApi::testPortId.fabricId, MockNlApi::testPortId.attachId, MockNlApi::testPortId.portNumber); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.portBeaconEnable(MockNlApi::testPortId)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortBeaconDisableCalledThenReturnSuccess) { + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_PORT_BEACON_DISABLE, MockNlApi::testPortId.fabricId, MockNlApi::testPortId.attachId, MockNlApi::testPortId.portNumber); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.portBeaconDisable(MockNlApi::testPortId)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortEnableCalledThenReturnSuccess) { + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_PORT_ENABLE, MockNlApi::testPortId.fabricId, MockNlApi::testPortId.attachId, MockNlApi::testPortId.portNumber); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.portEnable(MockNlApi::testPortId)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortDisableCalledThenReturnSuccess) { + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_PORT_DISABLE, MockNlApi::testPortId.fabricId, MockNlApi::testPortId.attachId, MockNlApi::testPortId.portNumber); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.portDisable(MockNlApi::testPortId)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortUsageEnableCalledThenReturnSuccess) { + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_PORT_USAGE_ENABLE, MockNlApi::testPortId.fabricId, MockNlApi::testPortId.attachId, MockNlApi::testPortId.portNumber); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.portUsageEnable(MockNlApi::testPortId)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortUsageDisableCalledThenReturnSuccess) { + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_PORT_USAGE_DISABLE, MockNlApi::testPortId.fabricId, MockNlApi::testPortId.attachId, MockNlApi::testPortId.portNumber); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.portUsageDisable(MockNlApi::testPortId)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRoutingGenQueryCalledThenBeginAndEndReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_ROUTING_GEN_QUERY); + uint32_t start = std::numeric_limits::max(), end = std::numeric_limits::max(); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.routingGenQuery(start, end)); + EXPECT_EQ(pMockNlApi->genStart, start); + EXPECT_EQ(pMockNlApi->genEnd, end); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRoutingGenQueryCalledAndStartAndEndNotPresentThenStartAndEndZeroReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_ROUTING_GEN_QUERY); + uint32_t start = std::numeric_limits::max(), end = std::numeric_limits::max(); + pMockNlApi->addRoutingGenStartEnd = false; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.routingGenQuery(start, end)); + EXPECT_EQ(0U, start); + EXPECT_EQ(0U, end); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRoutingGenQueryCalledAndLoadEntryPointsFailsThenErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(false); + uint32_t start = std::numeric_limits::max(), end = std::numeric_limits::max(); + EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, testIafNlApi.routingGenQuery(start, end)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenRoutingGenQueryCalledAndNlmsgAllocFailsThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockNlmsgAllocReturnValue.push_back(nullptr); + uint32_t start = std::numeric_limits::max(), end = std::numeric_limits::max(); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.routingGenQuery(start, end)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGetThroughputCalledThenRxCounterAndTxCounterReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_FPORT_XMIT_RECV_COUNTS, pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, pMockNlApi->testPortId.portNumber); + L0::Sysman::IafPortThroughPut throughput; + throughput.txCounter = std::numeric_limits::max(); + throughput.rxCounter = std::numeric_limits::max(); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.getThroughput(MockNlApi::testPortId, throughput)); + EXPECT_EQ(pMockNlApi->txCounter, throughput.txCounter); + EXPECT_EQ(pMockNlApi->rxCounter, throughput.rxCounter); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGetThroughputCalledAndRxAndTxCountersNotPresentThenRxAndTxCountersOfZeroReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_FPORT_XMIT_RECV_COUNTS, pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, pMockNlApi->testPortId.portNumber); + L0::Sysman::IafPortThroughPut throughput; + throughput.txCounter = std::numeric_limits::max(); + throughput.rxCounter = std::numeric_limits::max(); + pMockNlApi->addRxTxCounters = false; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.getThroughput(pMockNlApi->testPortId, throughput)); + EXPECT_EQ(0U, throughput.txCounter); + EXPECT_EQ(0U, throughput.rxCounter); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenDeviceEnumCalledThenFabricIdsReturned) { + std::vector fabricIds; + + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_DEVICE_ENUM); + fabricIds.clear(); + MockNlApi *mockNlApi = static_cast(testIafNlApi.pNlApi.get()); + mockNlApi->testFabricIds.clear(); + mockNlApi->testFabricIds.push_back(mockNlApi->testPortId.fabricId); + mockNlApi->testFabricIds.push_back(mockNlApi->testPortId.fabricId + 1U); + mockNlApi->testFabricIds.push_back(mockNlApi->testPortId.fabricId + 2U); + mockNlApi->testFabricIds.push_back(mockNlApi->testPortId.fabricId + 3U); + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.deviceEnum(fabricIds)); + EXPECT_EQ(mockNlApi->testFabricIds.size(), fabricIds.size()); + for (auto i = 0U; i < mockNlApi->testFabricIds.size(); i++) { + EXPECT_EQ(mockNlApi->testFabricIds.at(i), fabricIds.at(i)); + } +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFPortStatusQueryCalledThenPortStateReturned) { + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_FPORT_STATUS_QUERY, MockNlApi::testPortId.fabricId, + MockNlApi::testPortId.attachId, MockNlApi::testPortId.portNumber); + L0::Sysman::IafPortState state = {}; + + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.fPortStatusQuery(MockNlApi::testPortId, state)); + EXPECT_EQ(IAF_FPORT_HEALTH_HEALTHY, static_cast(state.healthStatus)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFabricDevicePropertiesCalledThenSubDeviceCountReturned) { + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_FABRIC_DEVICE_PROPERTIES, MockNlApi::testPortId.fabricId); + uint32_t numSubDevices = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.fabricDeviceProperties(MockNlApi::testPortId.fabricId, numSubDevices)); + EXPECT_EQ(2U, numSubDevices); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFabricDevicePropertiesCalledAndSubDeviceCountNotPresentThenZeroSubDevicesReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_FABRIC_DEVICE_PROPERTIES, pMockNlApi->testPortId.fabricId); + uint32_t numSubDevices = 0; + pMockNlApi->addSubDeviceCount = false; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.fabricDeviceProperties(MockNlApi::testPortId.fabricId, numSubDevices)); + EXPECT_EQ(0U, numSubDevices); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFabricDevicePropertiesCalledAndLoadEntryPointsFailsThenErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(false); + + uint32_t numSubDevices = 0; + EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, testIafNlApi.fabricDeviceProperties(MockNlApi::testPortId.fabricId, numSubDevices)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFabricDevicePropertiesCalledAndNlmsgAllocFailsThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockNlmsgAllocReturnValue.push_back(nullptr); + uint32_t numSubDevices = 0; + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.fabricDeviceProperties(MockNlApi::testPortId.fabricId, numSubDevices)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFportPropertiesCalledThenPropertiesReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_FPORT_PROPERTIES, pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, pMockNlApi->testPortId.portNumber); + uint64_t neighborGuid; + uint8_t neighborPortNumber; + L0::Sysman::IafPortSpeed maxRxSpeed; + L0::Sysman::IafPortSpeed maxTxSpeed; + L0::Sysman::IafPortSpeed rxSpeed; + L0::Sysman::IafPortSpeed txSpeed; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.fportProperties(pMockNlApi->testPortId, neighborGuid, neighborPortNumber, + maxRxSpeed, maxTxSpeed, rxSpeed, txSpeed)); + EXPECT_EQ(neighborGuid, pMockNlApi->testGuid); + EXPECT_EQ(neighborPortNumber, pMockNlApi->testPortId.portNumber); + EXPECT_EQ(maxRxSpeed.bitRate, pMockNlApi->linkSpeed90g); + EXPECT_EQ(maxRxSpeed.width, pMockNlApi->testLinkWidth1x); + EXPECT_EQ(maxTxSpeed.bitRate, pMockNlApi->linkSpeed90g); + EXPECT_EQ(maxTxSpeed.width, pMockNlApi->testLinkWidth1x); + EXPECT_EQ(rxSpeed.bitRate, pMockNlApi->linkSpeed90g); + EXPECT_EQ(rxSpeed.width, pMockNlApi->testLinkWidth3x); + EXPECT_EQ(txSpeed.bitRate, pMockNlApi->linkSpeed90g); + EXPECT_EQ(txSpeed.width, pMockNlApi->testLinkWidth4x); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFportPropertiesCalledAndInvalidWidthAndBitRate0DetectedThenNegativeOneReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_FPORT_PROPERTIES, pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, pMockNlApi->testPortId.portNumber); + uint64_t neighborGuid; + uint8_t neighborPortNumber; + L0::Sysman::IafPortSpeed maxRxSpeed; + L0::Sysman::IafPortSpeed maxTxSpeed; + L0::Sysman::IafPortSpeed rxSpeed; + L0::Sysman::IafPortSpeed txSpeed; + pMockNlApi->useInvalidWidth = true; + pMockNlApi->linkSpeed = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.fportProperties(pMockNlApi->testPortId, neighborGuid, neighborPortNumber, + maxRxSpeed, maxTxSpeed, rxSpeed, txSpeed)); + EXPECT_EQ(neighborGuid, pMockNlApi->testGuid); + EXPECT_EQ(neighborPortNumber, pMockNlApi->testPortId.portNumber); + EXPECT_EQ(maxRxSpeed.bitRate, -1); + EXPECT_EQ(maxRxSpeed.width, -1); + EXPECT_EQ(maxTxSpeed.bitRate, -1); + EXPECT_EQ(maxTxSpeed.width, -1); + EXPECT_EQ(rxSpeed.bitRate, -1); + EXPECT_EQ(rxSpeed.width, -1); + EXPECT_EQ(txSpeed.bitRate, -1); + EXPECT_EQ(txSpeed.width, -1); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFportPropertiesCalledAndLoadEntryPointsFailsThenErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(false); + + uint64_t neighborGuid; + uint8_t neighborPortNumber; + L0::Sysman::IafPortSpeed maxRxSpeed; + L0::Sysman::IafPortSpeed maxTxSpeed; + L0::Sysman::IafPortSpeed rxSpeed; + L0::Sysman::IafPortSpeed txSpeed; + EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, testIafNlApi.fportProperties(pMockNlApi->testPortId, neighborGuid, neighborPortNumber, + maxRxSpeed, maxTxSpeed, rxSpeed, txSpeed)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFportPropertiesCalledAndNlmsgAllocFailsThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockNlmsgAllocReturnValue.push_back(nullptr); + uint64_t neighborGuid; + uint8_t neighborPortNumber; + L0::Sysman::IafPortSpeed maxRxSpeed; + L0::Sysman::IafPortSpeed maxTxSpeed; + L0::Sysman::IafPortSpeed rxSpeed; + L0::Sysman::IafPortSpeed txSpeed; + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.fportProperties(pMockNlApi->testPortId, neighborGuid, neighborPortNumber, + maxRxSpeed, maxTxSpeed, rxSpeed, txSpeed)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortBeaconStateQueryCalledThenPortBeaconStateReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_PORT_BEACON_STATE_QUERY, pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, pMockNlApi->testPortId.portNumber); + bool enabled = false; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.portBeaconStateQuery(pMockNlApi->testPortId, enabled)); + EXPECT_EQ(true, enabled); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortSubDevicePropertiesGetCalledThenGuidAndPortsReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET, pMockNlApi->testPortId.fabricId, pMockNlApi->testPortId.attachId); + uint64_t guid = 0; + std::vector ports; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.subdevicePropertiesGet(pMockNlApi->testPortId.fabricId, pMockNlApi->testPortId.attachId, + guid, ports)); + EXPECT_EQ(guid, pMockNlApi->testGuid); + EXPECT_EQ(8U, ports.size()); + for (auto i = 0U; i < ports.size(); i++) { + EXPECT_EQ(ports.at(i), i + 1); + } +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortSubDevicePropertiesGetCalledAndGuidNotPresentThenGuidIsZeroAndPortsReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET, pMockNlApi->testPortId.fabricId, pMockNlApi->testPortId.attachId); + uint64_t guid = pMockNlApi->testGuid; + std::vector ports; + pMockNlApi->addGUID = false; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.subdevicePropertiesGet(pMockNlApi->testPortId.fabricId, pMockNlApi->testPortId.attachId, + guid, ports)); + EXPECT_EQ(0U, guid); + EXPECT_EQ(8U, ports.size()); + for (auto i = 0U; i < ports.size(); i++) { + EXPECT_EQ(ports.at(i), i + 1); + } +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortSubDevicePropertiesGetCalledAndAddPortZeroAndTypeDisconnectedThenGuidAndZeroPortsReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET, pMockNlApi->testPortId.fabricId, pMockNlApi->testPortId.attachId); + uint64_t guid = 0; + std::vector ports; + pMockNlApi->addPortZeroAndTypeDisconnected = true; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.subdevicePropertiesGet(pMockNlApi->testPortId.fabricId, pMockNlApi->testPortId.attachId, + guid, ports)); + EXPECT_EQ(guid, pMockNlApi->testGuid); + EXPECT_EQ(0U, ports.size()); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortSubDevicePropertiesGetCalledAndLoadEntryPointsFailsThenErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockLoadEntryPointsReturnValue.push_back(false); + + uint64_t guid = 0; + std::vector ports; + EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, testIafNlApi.subdevicePropertiesGet(pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, guid, ports)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortSubDevicePropertiesGetAndNlmsgAllocFailsThenUnknownErrorReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + pMockNlApi->mockNlmsgAllocReturnValue.push_back(nullptr); + uint64_t guid = 0; + std::vector ports; + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, testIafNlApi.subdevicePropertiesGet(pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, guid, ports)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenPortStateQueryCalledThenPortStateReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_PORT_STATE_QUERY, pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, pMockNlApi->testPortId.portNumber); + bool enabled = false; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.portStateQuery(pMockNlApi->testPortId, enabled)); + EXPECT_EQ(true, enabled); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFPortStatusQueryCalledAndHeathIsOutOfRangeThenPortStatusUnknownReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_FPORT_STATUS_QUERY, pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, pMockNlApi->testPortId.portNumber); + L0::Sysman::IafPortState state = {}; + pMockNlApi->fportHealth = _IAF_FPORT_HEALTH_COUNT; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.fPortStatusQuery(pMockNlApi->testPortId, state)); + EXPECT_EQ(_IAF_FPORT_HEALTH_COUNT, static_cast(state.healthStatus)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenFPortStatusQueryCalledAndPortHealthOffThenPortStatusDisabledReturned) { + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + setupExpectInit(); + setupExpectCleanup(); + setupExpectCommand(IAF_CMD_OP_FPORT_STATUS_QUERY, pMockNlApi->testPortId.fabricId, + pMockNlApi->testPortId.attachId, pMockNlApi->testPortId.portNumber); + L0::Sysman::IafPortState state = {}; + pMockNlApi->fportHealth = IAF_FPORT_HEALTH_OFF; + EXPECT_EQ(ZE_RESULT_SUCCESS, testIafNlApi.fPortStatusQuery(pMockNlApi->testPortId, state)); + EXPECT_EQ(IAF_FPORT_HEALTH_OFF, static_cast(state.healthStatus)); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWithLegacyIafPortsWhenGetPortsIsCalledValidPortsAreReturned) { + NEO::directoryFilesMap.insert({"/sys/class/drm/card1/device/", {"iaf.0"}}); + + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int { + std::vector supportedFiles = { + "/sys/class/drm/card1/device/iaf.0/iaf_fabric_id", + }; + + auto itr = std::find(supportedFiles.begin(), supportedFiles.end(), std::string(pathname)); + if (itr != supportedFiles.end()) { + return static_cast(std::distance(supportedFiles.begin(), itr)) + 1; + } + return 0; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::string fabricId("0x10000000"); + memcpy(buf, fabricId.c_str(), fabricId.size()); + return fabricId.size(); + }); + + setupExpectInitMultiple(); + setupExpectCleanupMultiple(); + + std::vector ports; + ze_result_t result = testIafNlApi.getPorts("/sys/class/drm/card1/device/", ports); + EXPECT_EQ(result, ZE_RESULT_SUCCESS); + NEO::directoryFilesMap.clear(); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGetPortsIsCalledValidPortsAreReturned) { + NEO::directoryFilesMap.insert({"/sys/class/drm/card1/device/", {"i915.iaf.0"}}); + + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int { + return 1; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::string fabricId("0x10000000"); + memcpy(buf, fabricId.c_str(), fabricId.size()); + return fabricId.size(); + }); + + setupExpectInitMultiple(); + setupExpectCleanupMultiple(); + + std::vector ports; + + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->addSubDeviceCount = false; + ze_result_t result = testIafNlApi.getPorts("/sys/class/drm/card1/device/", ports); + EXPECT_EQ(result, ZE_RESULT_SUCCESS); + NEO::directoryFilesMap.clear(); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafDirectoryIsUnavailableWhenGetPortsIsCalledThenUnSupportedFeatureIsReturned) { + NEO::directoryFilesMap.insert({"/sys/class/drm/card1/device/", {"iafX.0"}}); + setupExpectInitMultiple(); + setupExpectCleanupMultiple(); + + std::vector ports; + + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->addSubDeviceCount = false; + ze_result_t result = testIafNlApi.getPorts("/sys/class/drm/card1/device/", ports); + EXPECT_EQ(result, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); + NEO::directoryFilesMap.clear(); +} + +TEST_F(SysmanIafNlApiFixture, GivenOpeningFabricIdFileFailsWhenGetPortsIsCalledThenDependencyUnavailableIsReturned) { + NEO::directoryFilesMap.insert({"/sys/class/drm/card1/device/", {"iaf.0"}}); + + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int { + return -1; + }); + + setupExpectInitMultiple(); + setupExpectCleanupMultiple(); + + std::vector ports; + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->addSubDeviceCount = false; + ze_result_t result = testIafNlApi.getPorts("/sys/class/drm/card1/device/", ports); + EXPECT_EQ(result, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE); + NEO::directoryFilesMap.clear(); +} + +TEST_F(SysmanIafNlApiFixture, GivenReadingFabricIdFileFailsWhenGetPortsIsCalledThenDependencyUnavailableIsReturned) { + NEO::directoryFilesMap.insert({"/sys/class/drm/card1/device/", {"iaf.0"}}); + + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int { + return 1; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + return 0; + }); + + setupExpectInitMultiple(); + setupExpectCleanupMultiple(); + + std::vector ports; + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->addSubDeviceCount = false; + ze_result_t result = testIafNlApi.getPorts("/sys/class/drm/card1/device/", ports); + EXPECT_EQ(result, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE); + NEO::directoryFilesMap.clear(); +} + +TEST_F(SysmanIafNlApiFixture, GivenIncorrectValueInFabricIdFileFailsWhenGetPortsIsCalledThenUnknownErrorIsReturned) { + NEO::directoryFilesMap.insert({"/sys/class/drm/card1/device/", {"iaf.0"}}); + + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int { + return 1; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::string fabricId("0xFFFFFFFFFF"); + memcpy(buf, fabricId.c_str(), fabricId.size()); + return fabricId.size(); + }); + + setupExpectInitMultiple(); + setupExpectCleanupMultiple(); + + std::vector ports; + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->addSubDeviceCount = false; + ze_result_t result = testIafNlApi.getPorts("/sys/class/drm/card1/device/", ports); + EXPECT_EQ(result, ZE_RESULT_ERROR_UNKNOWN); + NEO::directoryFilesMap.clear(); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGetPortsIsCalledAndfabricDevicePropertiesReturnsFailureThenUnknownErrorIsReturned) { + NEO::directoryFilesMap.insert({"/sys/class/drm/card1/device/", {"iaf.0"}}); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int { + return 1; + }); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::string fabricId("0x10000000"); + memcpy(buf, fabricId.c_str(), fabricId.size()); + return fabricId.size(); + }); + + setupExpectInitMultiple(); + setupExpectCleanupMultiple(); + + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockGenlRegisterFamilyArgumentValue.clear(); + pMockNlApi->mockGenlRegisterFamilyReturnValue.clear(); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.clear(); + + std::vector ports; + + pMockNlApi->mockGenlRegisterFamilyArgumentValue.push_back(pOps); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(-6); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(true); + + ze_result_t result = testIafNlApi.getPorts("/sys/class/drm/card1/device/", ports); + EXPECT_EQ(result, ZE_RESULT_ERROR_UNKNOWN); + NEO::directoryFilesMap.clear(); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGetPortsIsCalledAndSubdevicePropertiesGetReturnsFailureThenUnknownErrorIsReturned) { + NEO::directoryFilesMap.insert({"/sys/class/drm/card1/device/", {"iaf.0"}}); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int { + return 1; + }); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::string fabricId("0x10000000"); + memcpy(buf, fabricId.c_str(), fabricId.size()); + return fabricId.size(); + }); + + setupExpectInitMultiple(); + setupExpectCleanupMultiple(); + + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockGenlRegisterFamilyArgumentValue.clear(); + pMockNlApi->mockGenlRegisterFamilyReturnValue.clear(); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.clear(); + + std::vector ports; + + // Override the registerfamily to return error + pMockNlApi->mockGenlRegisterFamilyArgumentValue.push_back(pOps); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + + pMockNlApi->mockGenlRegisterFamilyArgumentValue.push_back(pOps); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(-6); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(true); + ze_result_t result = testIafNlApi.getPorts("/sys/class/drm/card1/device/", ports); + EXPECT_EQ(result, ZE_RESULT_ERROR_UNKNOWN); + NEO::directoryFilesMap.clear(); +} + +TEST_F(SysmanIafNlApiFixture, GivenIafNlApiWhenGetPortsIsCalledAndFportPropertiesReturnsFailureThenUnknownErrorIsReturned) { + NEO::directoryFilesMap.insert({"/sys/class/drm/card1/device/", {"iaf.0"}}); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int { + return 1; + }); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::string fabricId("0x10000000"); + memcpy(buf, fabricId.c_str(), fabricId.size()); + return fabricId.size(); + }); + + setupExpectInitMultiple(); + setupExpectCleanupMultiple(); + + MockNlApi *pMockNlApi = static_cast(testIafNlApi.pNlApi.get()); + pMockNlApi->mockGenlRegisterFamilyArgumentValue.clear(); + pMockNlApi->mockGenlRegisterFamilyReturnValue.clear(); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.clear(); + + std::vector ports; + + // Override the registerfamily to return error + pMockNlApi->mockGenlRegisterFamilyArgumentValue.push_back(pOps); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + + pMockNlApi->mockGenlRegisterFamilyArgumentValue.push_back(pOps); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(0); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(false); + + pMockNlApi->mockGenlRegisterFamilyArgumentValue.push_back(pOps); + pMockNlApi->mockGenlRegisterFamilyReturnValue.push_back(-6); + pMockNlApi->isMockGenlRegisterFamilyRepeatedCall.push_back(true); + + ze_result_t result = testIafNlApi.getPorts("/sys/class/drm/card1/device/", ports); + EXPECT_EQ(result, ZE_RESULT_ERROR_UNKNOWN); + NEO::directoryFilesMap.clear(); +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/test_sysman_nl_api.cpp b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/test_sysman_nl_api.cpp new file mode 100644 index 0000000000..dabf953e66 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/test_sysman_nl_api.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2020-2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h" + +namespace L0 { +namespace ult { + +class PublicNlApi : public L0::Sysman::NlApi { + public: + using L0::Sysman::NlApi::genlLibraryHandle; +}; + +class SysmanNlApiFixture : public ::testing::Test { + protected: + PublicNlApi testNlApi; + + void SetUp() override { + auto mockNlDll = std::make_unique(); + + testNlApi.genlLibraryHandle = std::move(mockNlDll); + EXPECT_TRUE(testNlApi.loadEntryPoints()); + } + void TearDown() override { + } + bool testLoadEntryPointsWithMissingFunction(const std::string &procName) { + PublicNlApi localNlApi; + auto mockNlDll = std::make_unique(); + mockNlDll->deleteEntryPoint(procName); + localNlApi.genlLibraryHandle = std::move(mockNlDll); + + return localNlApi.loadEntryPoints(); + } + + public: + static const int testAttr; +}; +const int SysmanNlApiFixture::testAttr = 1; + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenMissingDllEntryPointThenVerifyLoadEntryPointsFails) { + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_connect")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_ctrl_resolve")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_handle_msg")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genlmsg_put")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_ops_resolve")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_register_family")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_unregister_family")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_recvmsgs_default")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_send_auto")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_socket_alloc")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_socket_disable_seq_check")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_socket_free")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_socket_modify_cb")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_data")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_get_u32")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_get_u64")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_get_u8")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_is_nested")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_len")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_next")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_ok")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_put_u16")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_put_u32")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_put_u64")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_put_u8")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_type")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_alloc")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_attrdata")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_attrlen")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_free")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_hdr")); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenMissingDllHandleThenVerifyLoadEntryPointsFails) { + testNlApi.genlLibraryHandle.reset(); + EXPECT_FALSE(testNlApi.loadEntryPoints()); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlConnectReturnsZero) { + EXPECT_EQ(0, testNlApi.genlConnect(&MockNlDll::mockNlSock)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlCtrlReturnsZero) { + EXPECT_EQ(0, testNlApi.genlCtrlResolve(&MockNlDll::mockNlSock, const_cast(MockNlDll::mockFamilyName))); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlHandleMsgReturnsZero) { + EXPECT_EQ(0, testNlApi.genlHandleMsg(&MockNlDll::mockNlMsg, MockNlDll::mockArgP)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlmsgPutReturnsValidPointer) { + EXPECT_NE(nullptr, testNlApi.genlmsgPut(&MockNlDll::mockNlMsg, MockNlDll::mockPort, MockNlDll::mockSeq, MockNlDll::mockFamilyId, MockNlDll::mockHdrlen, MockNlDll::mockFlags, MockNlDll::mockCmd, MockNlDll::mockVersion)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlOpsResolveReturnsZero) { + EXPECT_EQ(0, testNlApi.genlOpsResolve(&MockNlDll::mockNlSock, &MockNlDll::mockGenlOps)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlRegisterFamilyReturnsZero) { + EXPECT_EQ(0, testNlApi.genlRegisterFamily(&MockNlDll::mockGenlOps)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlUnregisterFamilyReturnsZero) { + EXPECT_EQ(0, testNlApi.genlUnregisterFamily(&MockNlDll::mockGenlOps)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlSocketAllocReturnsValidPointer) { + EXPECT_EQ(&MockNlDll::mockNlSock, testNlApi.nlSocketAlloc()); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlSocketDisableSeqCheckCompletesSuccessfully) { + testNlApi.nlSocketDisableSeqCheck(&MockNlDll::mockNlSock); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlSocketFreeCompletesSuccessfully) { + testNlApi.nlSocketFree(&MockNlDll::mockNlSock); +} + +TEST_F(SysmanNlApiFixture, GivenValidNlSockWhenCallingNlSocketModifyCbThenVerifyNlSocketModifyCbReturnsZero) { + EXPECT_EQ(0, testNlApi.nlSocketModifyCb(&MockNlDll::mockNlSock, MockNlDll::mockCbType, MockNlDll::mockCbKind, MockNlDll::mockCb, MockNlDll::mockArgP)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlRecvmsgsDefaultReturnsZero) { + EXPECT_EQ(0, testNlApi.nlRecvmsgsDefault(&MockNlDll::mockNlSock)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlSendAutoReturnsZero) { + EXPECT_EQ(0, testNlApi.nlSendAuto(&MockNlDll::mockNlSock, &MockNlDll::mockNlMsg)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaDataReturnsValidPointer) { + EXPECT_NE(nullptr, testNlApi.nlaData(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaGetU32ReturnsValue) { + EXPECT_EQ(MockNlDll::mockU32Val, testNlApi.nlaGetU32(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaGetU64ReturnsValue) { + EXPECT_EQ(MockNlDll::mockU64Val, testNlApi.nlaGetU64(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaGetU8ReturnsValue) { + EXPECT_EQ(MockNlDll::mockU8Val, testNlApi.nlaGetU8(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaIsNestedReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaIsNested(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaLenReturnsValue) { + EXPECT_EQ(MockNlDll::mockAttrLen, testNlApi.nlaLen(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaNextReturnsZero) { + int remaining = MockNlDll::mockRemainBefore; + + EXPECT_EQ(&MockNlDll::mockNextNlattr, testNlApi.nlaNext(&MockNlDll::mockNlattr, &remaining)); + EXPECT_EQ(MockNlDll::mockRemainAfter, remaining); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaOkReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaOk(&MockNlDll::mockNlattr, MockNlDll::mockRemainBefore)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaPutU16ReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaPutU16(&MockNlDll::mockNlMsg, MockNlDll::mockType, MockNlDll::mockU16Val)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaPutU32ReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaPutU32(&MockNlDll::mockNlMsg, MockNlDll::mockType, MockNlDll::mockU32Val)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaPutU64ReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaPutU64(&MockNlDll::mockNlMsg, MockNlDll::mockType, MockNlDll::mockU64Val)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaPutU8ReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaPutU8(&MockNlDll::mockNlMsg, MockNlDll::mockType, MockNlDll::mockU8Val)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaTypeReturnsType) { + EXPECT_EQ(MockNlDll::mockType, testNlApi.nlaType(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgAllocReturnsNlMsg) { + EXPECT_EQ(&MockNlDll::mockNlMsg, testNlApi.nlmsgAlloc()); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgFreeReturnsSuccessfully) { + testNlApi.nlmsgFree(&MockNlDll::mockNlMsg); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgAttrdataReturnsNlattr) { + EXPECT_EQ(&MockNlDll::mockNlattr, testNlApi.nlmsgAttrdata(&MockNlDll::mockNlmsghdr, MockNlDll::mockAttr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgAttrlenReturnsLength) { + EXPECT_EQ(MockNlDll::mockAttrLen, testNlApi.nlmsgAttrlen(&MockNlDll::mockNlmsghdr, MockNlDll::mockAttr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgHdrReturnsNlmsghdr) { + EXPECT_EQ(&MockNlDll::mockNlmsghdr, testNlApi.nlmsgHdr(&MockNlDll::mockNlMsg)); +} +} // namespace ult +} // namespace L0 diff --git a/level_zero/tools/source/sysman/fabric_port/fabric_port.h b/level_zero/tools/source/sysman/fabric_port/fabric_port.h index 7bc5fdd7a9..a054ceabe6 100644 --- a/level_zero/tools/source/sysman/fabric_port/fabric_port.h +++ b/level_zero/tools/source/sysman/fabric_port/fabric_port.h @@ -8,15 +8,12 @@ #pragma once #include "shared/source/helpers/non_copyable_or_moveable.h" +#include "level_zero/api/sysman/zes_handles_struct.h" #include #include #include -struct _zes_fabric_port_handle_t { - virtual ~_zes_fabric_port_handle_t() = default; -}; - namespace L0 { struct OsSysman; diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h b/level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h index 99639b8f75..13ae222563 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h @@ -12,6 +12,7 @@ #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/source/os_interface/os_interface.h" +#include "level_zero/core/source/driver/driver.h" #include "level_zero/core/test/unit_tests/fixtures/device_fixture.h" #include "level_zero/tools/source/sysman/linux/os_sysman_driver_imp.h" #include "level_zero/tools/source/sysman/sysman.h" @@ -79,6 +80,7 @@ class SysmanDeviceFixture : public DeviceFixture, public ::testing::Test { } pSysmanDeviceImp->init(); + L0::sysmanInitFromCore = true; } void TearDown() override { if (!sysmanUltsEnable) { @@ -139,6 +141,7 @@ class SysmanMultiDeviceFixture : public MultiDeviceFixture, public ::testing::Te pSysmanDeviceImp->init(); subDeviceCount = numSubDevices; + L0::sysmanInitFromCore = true; } void TearDown() override { if (!sysmanUltsEnable) {