--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ */
+
+#include <rte_log.h>
+#include <rte_ethdev.h>
+
+#include <rte_test.h>
+#include "test.h"
+
+
+static int32_t
+test_link_status_up_default(void)
+{
+ int ret = 0;
+ struct rte_eth_link link_status = {
+ .link_speed = ETH_SPEED_NUM_2_5G,
+ .link_status = ETH_LINK_UP,
+ .link_autoneg = ETH_LINK_AUTONEG,
+ .link_duplex = ETH_LINK_FULL_DUPLEX
+ };
+ char text[RTE_ETH_LINK_MAX_STR_LEN];
+
+ ret = rte_eth_link_to_str(text, sizeof(text), &link_status);
+ RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+ printf("Default link up #1: %s\n", text);
+ TEST_ASSERT_BUFFERS_ARE_EQUAL("Link up at 2.5 Gbps FDX Autoneg",
+ text, strlen(text), "Invalid default link status string");
+
+ link_status.link_duplex = ETH_LINK_HALF_DUPLEX;
+ link_status.link_autoneg = ETH_LINK_FIXED;
+ link_status.link_speed = ETH_SPEED_NUM_10M,
+ ret = rte_eth_link_to_str(text, sizeof(text), &link_status);
+ printf("Default link up #2: %s\n", text);
+ RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+ TEST_ASSERT_BUFFERS_ARE_EQUAL("Link up at 10 Mbps HDX Fixed",
+ text, strlen(text), "Invalid default link status "
+ "string with HDX");
+
+ link_status.link_speed = ETH_SPEED_NUM_UNKNOWN;
+ ret = rte_eth_link_to_str(text, sizeof(text), &link_status);
+ printf("Default link up #3: %s\n", text);
+ RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+ TEST_ASSERT_BUFFERS_ARE_EQUAL("Link up at Unknown HDX Fixed",
+ text, strlen(text), "Invalid default link status "
+ "string with HDX");
+
+ link_status.link_speed = ETH_SPEED_NUM_NONE;
+ ret = rte_eth_link_to_str(text, sizeof(text), &link_status);
+ printf("Default link up #3: %s\n", text);
+ RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+ TEST_ASSERT_BUFFERS_ARE_EQUAL("Link up at None HDX Fixed",
+ text, strlen(text), "Invalid default link status "
+ "string with HDX");
+
+ /* test max str len */
+ link_status.link_speed = ETH_SPEED_NUM_200G;
+ link_status.link_duplex = ETH_LINK_HALF_DUPLEX;
+ link_status.link_autoneg = ETH_LINK_AUTONEG;
+ ret = rte_eth_link_to_str(text, sizeof(text), &link_status);
+ printf("Default link up #4:len = %d, %s\n", ret, text);
+ RTE_TEST_ASSERT(ret < RTE_ETH_LINK_MAX_STR_LEN,
+ "String length exceeds max allowed value\n");
+ return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_down_default(void)
+{
+ int ret = 0;
+ struct rte_eth_link link_status = {
+ .link_speed = ETH_SPEED_NUM_2_5G,
+ .link_status = ETH_LINK_DOWN,
+ .link_autoneg = ETH_LINK_AUTONEG,
+ .link_duplex = ETH_LINK_FULL_DUPLEX
+ };
+ char text[RTE_ETH_LINK_MAX_STR_LEN];
+
+ ret = rte_eth_link_to_str(text, sizeof(text), &link_status);
+ RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+ TEST_ASSERT_BUFFERS_ARE_EQUAL("Link down",
+ text, strlen(text), "Invalid default link status string");
+
+ return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_invalid(void)
+{
+ int ret = 0;
+ struct rte_eth_link link_status = {
+ .link_speed = 55555,
+ .link_status = ETH_LINK_UP,
+ .link_autoneg = ETH_LINK_AUTONEG,
+ .link_duplex = ETH_LINK_FULL_DUPLEX
+ };
+ char text[RTE_ETH_LINK_MAX_STR_LEN];
+
+ ret = rte_eth_link_to_str(text, sizeof(text), &link_status);
+ RTE_TEST_ASSERT(ret < RTE_ETH_LINK_MAX_STR_LEN,
+ "Failed to format invalid string\n");
+ printf("invalid link up #1: len=%d %s\n", ret, text);
+ TEST_ASSERT_BUFFERS_ARE_EQUAL("Link up at Invalid FDX Autoneg",
+ text, strlen(text), "Incorrect invalid link status string");
+
+ return TEST_SUCCESS;
+}
+
+
+static int32_t
+test_link_speed_all_values(void)
+{
+ const char *speed;
+ uint32_t i;
+ struct link_speed_t {
+ const char *value;
+ uint32_t link_speed;
+ } speed_str_map[] = {
+ { "None", ETH_SPEED_NUM_NONE },
+ { "10 Mbps", ETH_SPEED_NUM_10M },
+ { "100 Mbps", ETH_SPEED_NUM_100M },
+ { "1 Gbps", ETH_SPEED_NUM_1G },
+ { "2.5 Gbps", ETH_SPEED_NUM_2_5G },
+ { "5 Gbps", ETH_SPEED_NUM_5G },
+ { "10 Gbps", ETH_SPEED_NUM_10G },
+ { "20 Gbps", ETH_SPEED_NUM_20G },
+ { "25 Gbps", ETH_SPEED_NUM_25G },
+ { "40 Gbps", ETH_SPEED_NUM_40G },
+ { "50 Gbps", ETH_SPEED_NUM_50G },
+ { "56 Gbps", ETH_SPEED_NUM_56G },
+ { "100 Gbps", ETH_SPEED_NUM_100G },
+ { "200 Gbps", ETH_SPEED_NUM_200G },
+ { "Unknown", ETH_SPEED_NUM_UNKNOWN },
+ { "Invalid", 50505 }
+ };
+
+ for (i = 0; i < sizeof(speed_str_map) / sizeof(struct link_speed_t);
+ i++) {
+ speed = rte_eth_link_speed_to_str(speed_str_map[i].link_speed);
+ TEST_ASSERT_BUFFERS_ARE_EQUAL(speed_str_map[i].value,
+ speed, strlen(speed_str_map[i].value),
+ "Invalid link speed string");
+ }
+ return TEST_SUCCESS;
+}
+
+static struct unit_test_suite link_status_testsuite = {
+ .suite_name = "link status formatting",
+ .setup = NULL,
+ .teardown = NULL,
+ .unit_test_cases = {
+ TEST_CASE(test_link_status_up_default),
+ TEST_CASE(test_link_status_down_default),
+ TEST_CASE(test_link_speed_all_values),
+ TEST_CASE(test_link_status_invalid),
+ TEST_CASES_END() /**< NULL terminate unit test array */
+ }
+};
+
+static int
+test_link_status(void)
+{
+ rte_log_set_global_level(RTE_LOG_DEBUG);
+ rte_log_set_level(RTE_LOGTYPE_EAL, RTE_LOG_DEBUG);
+
+ return unit_test_suite_runner(&link_status_testsuite);
+}
+
+REGISTER_TEST_COMMAND(ethdev_link_status, test_link_status);
return 0;
}
+const char *
+rte_eth_link_speed_to_str(uint32_t link_speed)
+{
+ switch (link_speed) {
+ case ETH_SPEED_NUM_NONE: return "None";
+ case ETH_SPEED_NUM_10M: return "10 Mbps";
+ case ETH_SPEED_NUM_100M: return "100 Mbps";
+ case ETH_SPEED_NUM_1G: return "1 Gbps";
+ case ETH_SPEED_NUM_2_5G: return "2.5 Gbps";
+ case ETH_SPEED_NUM_5G: return "5 Gbps";
+ case ETH_SPEED_NUM_10G: return "10 Gbps";
+ case ETH_SPEED_NUM_20G: return "20 Gbps";
+ case ETH_SPEED_NUM_25G: return "25 Gbps";
+ case ETH_SPEED_NUM_40G: return "40 Gbps";
+ case ETH_SPEED_NUM_50G: return "50 Gbps";
+ case ETH_SPEED_NUM_56G: return "56 Gbps";
+ case ETH_SPEED_NUM_100G: return "100 Gbps";
+ case ETH_SPEED_NUM_200G: return "200 Gbps";
+ case ETH_SPEED_NUM_UNKNOWN: return "Unknown";
+ default: return "Invalid";
+ }
+}
+
+int
+rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
+{
+ if (eth_link->link_status == ETH_LINK_DOWN)
+ return snprintf(str, len, "Link down");
+ else
+ return snprintf(str, len, "Link up at %s %s %s",
+ rte_eth_link_speed_to_str(eth_link->link_speed),
+ (eth_link->link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ "FDX" : "HDX",
+ (eth_link->link_autoneg == ETH_LINK_AUTONEG) ?
+ "Autoneg" : "Fixed");
+}
+
int
rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
{