From fa2fccf72f921b30465c62b6ea9de6d762352e36 Mon Sep 17 00:00:00 2001 From: mssonicbld <79238446+mssonicbld@users.noreply.github.com> Date: Wed, 22 Apr 2026 17:12:59 +0800 Subject: [PATCH 1/2] Convert SNR raw value to dB as per SAI definition (#1865) Convert SNR raw value to dB as raw / 256.0 as per the `sai_port_snr_values_t` SAI definition Both serialization and de-serialization is handled accordingly. Signed-off-by: Sonic Build Admin --- meta/SaiSerialize.cpp | 12 ++++++++---- unittest/meta/TestSaiSerialize.cpp | 4 ++-- unittest/syncd/TestPortPhyAttr.cpp | 14 ++++++++------ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/meta/SaiSerialize.cpp b/meta/SaiSerialize.cpp index bc12d744..bd482c3e 100644 --- a/meta/SaiSerialize.cpp +++ b/meta/SaiSerialize.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -1812,11 +1813,13 @@ std::string sai_serialize_port_snr_list( return j.dump(); } - // Create dictionary format: {"0": 3712, "1": 3840, ...} + // Convert raw U16 SNR (in 1/256 dB units) to dB value per SAI definition + // e.g., raw value 5248 represents 5248/256 = 20.50 dB (Two decimal precision) for (uint32_t i = 0; i < snr_list.count; ++i) { std::string lane_key = std::to_string(snr_list.list[i].lane); - j[lane_key] = snr_list.list[i].snr; + double dB = static_cast(snr_list.list[i].snr) / 256.0; + j[lane_key] = std::round(dB * 100.0) / 100.0; } return j.dump(); @@ -4616,14 +4619,15 @@ void sai_deserialize_port_snr_list( uint32_t idx = 0; for (auto it = j.begin(); it != j.end(); ++it, ++idx) { - if (!it.value().is_number_unsigned()) + if (!it.value().is_number()) { SWSS_LOG_ERROR("Invalid SNR value type for lane %s", it.key().c_str()); continue; } + // Convert dB value back to raw U16 (in 1/256 dB units) per SAI definition snr_list.list[idx].lane = static_cast(std::stoul(it.key())); - snr_list.list[idx].snr = it.value().get(); + snr_list.list[idx].snr = static_cast(std::round(it.value().get() * 256.0)); } } catch (const json::parse_error& e) diff --git a/unittest/meta/TestSaiSerialize.cpp b/unittest/meta/TestSaiSerialize.cpp index 6c3fb014..c16cede0 100644 --- a/unittest/meta/TestSaiSerialize.cpp +++ b/unittest/meta/TestSaiSerialize.cpp @@ -192,7 +192,7 @@ TEST(SaiSerialize, sai_serialize_port_snr_list) auto s = sai_serialize_attr_value(*meta, attr, false); - std::string expected = "{\"0\":3712,\"1\":3840,\"2\":4160}"; + std::string expected = "{\"0\":14.5,\"1\":15.0,\"2\":16.25}"; EXPECT_EQ(s, expected); } @@ -201,7 +201,7 @@ TEST(SaiSerialize, sai_serialize_port_snr_list) TEST(SaiSerialize, sai_deserialize_port_snr_list) { - std::string json_str = R"({"0":3712,"1":4032})"; + std::string json_str = R"({"0":14.5,"1":15.75})"; sai_port_snr_list_t snr_list; memset(&snr_list, 0, sizeof(snr_list)); diff --git a/unittest/syncd/TestPortPhyAttr.cpp b/unittest/syncd/TestPortPhyAttr.cpp index 686fb9f4..57fa2dd9 100644 --- a/unittest/syncd/TestPortPhyAttr.cpp +++ b/unittest/syncd/TestPortPhyAttr.cpp @@ -18,6 +18,7 @@ #include #include #include +#include using namespace saimeta; using namespace sairedis; @@ -247,16 +248,17 @@ TEST_F(TestPortPhyAttr, CollectDataAndValidateCountersDB) std::cout << "Actual rx_snr value: " << rxSnrValue << std::endl; - // Lane key is string, SNR value is number (no quotes around value) - // Validate all lanes (0-7) with SNR values: 145, 150, 155, 160, 165, 170, 175, 180 + // Lane key is string, SNR value is dB (raw_value / 256.0, rounded to 2 decimals) + // Validate all lanes (0-7) with raw SNR values: 145, 150, 155, 160, 165, 170, 175, 180 + // Converted to dB: 0.57, 0.59, 0.61, 0.63, 0.64, 0.66, 0.68, 0.7 for (uint32_t lane = 0; lane < MAX_LANES_PER_PORT; lane++) { - uint32_t expected_snr = 145 + (lane * 5); + uint32_t raw_snr = 145 + (lane * 5); + double dB = std::round(static_cast(raw_snr) / 256.0 * 100.0) / 100.0; std::ostringstream expected_entry; - expected_entry << "\"" << lane << "\":" << expected_snr; + expected_entry << "\"" << lane << "\":" << dB; EXPECT_TRUE(rxSnrValue.find(expected_entry.str()) != std::string::npos) - << "Lane " << lane << " SNR should be " << expected_snr - << " in format \"" << lane << "\":" << expected_snr + << "Lane " << lane << " SNR should be " << dB << " dB (raw " << raw_snr << ")" << "\nActual full value: " << rxSnrValue << "\nLooking for: " << expected_entry.str(); } From 19f8c67ca567bb1432c4b2c180f9548f55d21e0c Mon Sep 17 00:00:00 2001 From: mssonicbld <79238446+mssonicbld@users.noreply.github.com> Date: Thu, 23 Apr 2026 04:13:35 +0800 Subject: [PATCH 2/2] add ICMP echo stats count mode enum in VS (#1866) Add SAI_STATS_COUNT_MODE_PACKET_AND_BYTE and SAI_STATS_COUNT_MODE_PACKET attribute IDs for SAI_OBJECT_TYPE_ICMP_ECHO_SESSION object type It should fix PR failures in https://github.com/sonic-net/sonic-swss/pull/4156 Note: PR for 202511 created to avoid cherry-pick conflict https://github.com/sonic-net/sonic-sairedis/pull/1834 Signed-off-by: Sonic Build Admin --- vslib/SwitchStateBase.cpp | 22 ++++++++++++++++++++ vslib/SwitchStateBase.h | 3 +++ vslib/tests.cpp | 43 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/vslib/SwitchStateBase.cpp b/vslib/SwitchStateBase.cpp index 6b12ebf2..3c900039 100644 --- a/vslib/SwitchStateBase.cpp +++ b/vslib/SwitchStateBase.cpp @@ -4317,6 +4317,24 @@ sai_status_t SwitchStateBase::queryTamBindPointTypeCapability( return SAI_STATUS_SUCCESS; } +sai_status_t SwitchStateBase::queryIcmpEchoSessionStatsCountModeCapability( + _Inout_ sai_s32_list_t *enum_values_capability) +{ + SWSS_LOG_ENTER(); + + if (enum_values_capability->count < 2) + { + enum_values_capability->count = 2; + return SAI_STATUS_BUFFER_OVERFLOW; + } + + enum_values_capability->count = 2; + enum_values_capability->list[0] = SAI_STATS_COUNT_MODE_PACKET_AND_BYTE; + enum_values_capability->list[1] = SAI_STATS_COUNT_MODE_PACKET; + + return SAI_STATUS_SUCCESS; +} + sai_status_t SwitchStateBase::queryAttrEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, @@ -4368,6 +4386,10 @@ sai_status_t SwitchStateBase::queryAttrEnumValuesCapability( { return queryTamBindPointTypeCapability(enum_values_capability); } + else if (object_type == SAI_OBJECT_TYPE_ICMP_ECHO_SESSION && attr_id == SAI_ICMP_ECHO_SESSION_ATTR_STATS_COUNT_MODE) + { + return queryIcmpEchoSessionStatsCountModeCapability(enum_values_capability); + } return SAI_STATUS_NOT_SUPPORTED; } diff --git a/vslib/SwitchStateBase.h b/vslib/SwitchStateBase.h index afafc6a2..ea1b844b 100644 --- a/vslib/SwitchStateBase.h +++ b/vslib/SwitchStateBase.h @@ -785,6 +785,9 @@ namespace saivs virtual sai_status_t queryTamBindPointTypeCapability( _Inout_ sai_s32_list_t *enum_values_capability); + virtual sai_status_t queryIcmpEchoSessionStatsCountModeCapability( + _Inout_ sai_s32_list_t *enum_values_capability); + virtual sai_status_t queryPortAutonegFecOverrideSupportCapability( _Out_ sai_attr_capability_t *attr_capability); diff --git a/vslib/tests.cpp b/vslib/tests.cpp index cfef5866..1e801d4a 100644 --- a/vslib/tests.cpp +++ b/vslib/tests.cpp @@ -809,6 +809,47 @@ void test_supported_obj_types() } +void test_icmp_echo_session_stats_count_mode_capability() +{ + SWSS_LOG_ENTER(); + + sai_reinit(); + + sai_attribute_t attr; + sai_object_id_t switch_id; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + SUCCESS(sai_metadata_sai_switch_api->create_switch(&switch_id, 1, &attr)); + + int32_t small_list[1]; + sai_s32_list_t enum_values_capability; + enum_values_capability.count = 1; + enum_values_capability.list = small_list; + + ASSERT_TRUE(sai_query_attribute_enum_values_capability( + switch_id, + SAI_OBJECT_TYPE_ICMP_ECHO_SESSION, + SAI_ICMP_ECHO_SESSION_ATTR_STATS_COUNT_MODE, + &enum_values_capability) == SAI_STATUS_BUFFER_OVERFLOW); + ASSERT_TRUE(enum_values_capability.count == 2); + + int32_t values[2]; + enum_values_capability.count = 2; + enum_values_capability.list = values; + + SUCCESS(sai_query_attribute_enum_values_capability( + switch_id, + SAI_OBJECT_TYPE_ICMP_ECHO_SESSION, + SAI_ICMP_ECHO_SESSION_ATTR_STATS_COUNT_MODE, + &enum_values_capability)); + + ASSERT_TRUE(enum_values_capability.count == 2); + ASSERT_TRUE(enum_values_capability.list[0] == SAI_STATS_COUNT_MODE_PACKET_AND_BYTE); + ASSERT_TRUE(enum_values_capability.list[1] == SAI_STATS_COUNT_MODE_PACKET); +} + int main() { swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG); @@ -837,6 +878,8 @@ int main() test_set_stats_via_redis(); + test_icmp_echo_session_stats_count_mode_capability(); + // make proper uninitialize to close unittest thread sai_api_uninitialize();