14fe767acSJie Hai /* SPDX-License-Identifier: BSD-3-Clause 24fe767acSJie Hai * Copyright(c) 2010-2017 Intel Corporation 34fe767acSJie Hai */ 44fe767acSJie Hai 54fe767acSJie Hai #include <ctype.h> 64fe767acSJie Hai #include <stdlib.h> 74fe767acSJie Hai 84fe767acSJie Hai #include <rte_kvargs.h> 94fe767acSJie Hai #include <rte_telemetry.h> 104fe767acSJie Hai 114fe767acSJie Hai #include "rte_ethdev.h" 124fe767acSJie Hai #include "ethdev_driver.h" 134fe767acSJie Hai #include "sff_telemetry.h" 14a590d564SJie Hai #include "rte_tm.h" 154fe767acSJie Hai 1685576ba6SJie Hai static const struct { 1785576ba6SJie Hai uint32_t capa; 1885576ba6SJie Hai const char *name; 1985576ba6SJie Hai } rte_eth_fec_capa_name[] = { 2085576ba6SJie Hai { RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC), "off" }, 2185576ba6SJie Hai { RTE_ETH_FEC_MODE_CAPA_MASK(AUTO), "auto" }, 2285576ba6SJie Hai { RTE_ETH_FEC_MODE_CAPA_MASK(BASER), "baser" }, 2385576ba6SJie Hai { RTE_ETH_FEC_MODE_CAPA_MASK(RS), "rs" }, 2485576ba6SJie Hai { RTE_ETH_FEC_MODE_CAPA_MASK(LLRS), "llrs" }, 2585576ba6SJie Hai }; 2685576ba6SJie Hai 274fe767acSJie Hai static int 286ca32611SJie Hai eth_dev_parse_port_params(const char *params, uint16_t *port_id, 296ca32611SJie Hai char **end_param, bool has_next) 306ca32611SJie Hai { 316ca32611SJie Hai uint64_t pi; 326ca32611SJie Hai 336ca32611SJie Hai if (params == NULL || strlen(params) == 0 || 346ca32611SJie Hai !isdigit(*params) || port_id == NULL) 356ca32611SJie Hai return -EINVAL; 366ca32611SJie Hai 376ca32611SJie Hai pi = strtoul(params, end_param, 0); 386ca32611SJie Hai if (**end_param != '\0' && !has_next) 390e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(NOTICE, 400e21c7c0SDavid Marchand "Extra parameters passed to ethdev telemetry command, ignoring"); 416ca32611SJie Hai 426ca32611SJie Hai if (pi >= UINT16_MAX || !rte_eth_dev_is_valid_port(pi)) 436ca32611SJie Hai return -EINVAL; 446ca32611SJie Hai 456ca32611SJie Hai *port_id = (uint16_t)pi; 466ca32611SJie Hai 476ca32611SJie Hai return 0; 486ca32611SJie Hai } 496ca32611SJie Hai 506ca32611SJie Hai static int 514fe767acSJie Hai eth_dev_handle_port_list(const char *cmd __rte_unused, 524fe767acSJie Hai const char *params __rte_unused, 534fe767acSJie Hai struct rte_tel_data *d) 544fe767acSJie Hai { 554fe767acSJie Hai int port_id; 564fe767acSJie Hai 574fe767acSJie Hai rte_tel_data_start_array(d, RTE_TEL_INT_VAL); 584fe767acSJie Hai RTE_ETH_FOREACH_DEV(port_id) 594fe767acSJie Hai rte_tel_data_add_array_int(d, port_id); 604fe767acSJie Hai return 0; 614fe767acSJie Hai } 624fe767acSJie Hai 634fe767acSJie Hai static void 644fe767acSJie Hai eth_dev_add_port_queue_stats(struct rte_tel_data *d, uint64_t *q_stats, 654fe767acSJie Hai const char *stat_name) 664fe767acSJie Hai { 674fe767acSJie Hai int q; 684fe767acSJie Hai struct rte_tel_data *q_data = rte_tel_data_alloc(); 694fe767acSJie Hai if (q_data == NULL) 704fe767acSJie Hai return; 714fe767acSJie Hai rte_tel_data_start_array(q_data, RTE_TEL_UINT_VAL); 724fe767acSJie Hai for (q = 0; q < RTE_ETHDEV_QUEUE_STAT_CNTRS; q++) 734fe767acSJie Hai rte_tel_data_add_array_uint(q_data, q_stats[q]); 744fe767acSJie Hai rte_tel_data_add_dict_container(d, stat_name, q_data, 0); 754fe767acSJie Hai } 764fe767acSJie Hai 774fe767acSJie Hai static int 784fe767acSJie Hai eth_dev_parse_hide_zero(const char *key, const char *value, void *extra_args) 794fe767acSJie Hai { 804fe767acSJie Hai RTE_SET_USED(key); 814fe767acSJie Hai 824fe767acSJie Hai if (value == NULL) 834fe767acSJie Hai return -1; 844fe767acSJie Hai 854fe767acSJie Hai if (strcmp(value, "true") == 0) 864fe767acSJie Hai *(bool *)extra_args = true; 874fe767acSJie Hai else if (strcmp(value, "false") == 0) 884fe767acSJie Hai *(bool *)extra_args = false; 894fe767acSJie Hai else 904fe767acSJie Hai return -1; 914fe767acSJie Hai 924fe767acSJie Hai return 0; 934fe767acSJie Hai } 944fe767acSJie Hai 954fe767acSJie Hai #define ADD_DICT_STAT(stats, s) rte_tel_data_add_dict_uint(d, #s, stats.s) 964fe767acSJie Hai 974fe767acSJie Hai static int 984fe767acSJie Hai eth_dev_handle_port_stats(const char *cmd __rte_unused, 994fe767acSJie Hai const char *params, 1004fe767acSJie Hai struct rte_tel_data *d) 1014fe767acSJie Hai { 1024fe767acSJie Hai struct rte_eth_stats stats; 1036ca32611SJie Hai uint16_t port_id; 1046ca32611SJie Hai char *end_param; 1056ca32611SJie Hai int ret; 1064fe767acSJie Hai 1076ca32611SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 1086ca32611SJie Hai if (ret < 0) 1096ca32611SJie Hai return ret; 1104fe767acSJie Hai 1114fe767acSJie Hai ret = rte_eth_stats_get(port_id, &stats); 1124fe767acSJie Hai if (ret < 0) 1134fe767acSJie Hai return -1; 1144fe767acSJie Hai 1154fe767acSJie Hai rte_tel_data_start_dict(d); 1164fe767acSJie Hai ADD_DICT_STAT(stats, ipackets); 1174fe767acSJie Hai ADD_DICT_STAT(stats, opackets); 1184fe767acSJie Hai ADD_DICT_STAT(stats, ibytes); 1194fe767acSJie Hai ADD_DICT_STAT(stats, obytes); 1204fe767acSJie Hai ADD_DICT_STAT(stats, imissed); 1214fe767acSJie Hai ADD_DICT_STAT(stats, ierrors); 1224fe767acSJie Hai ADD_DICT_STAT(stats, oerrors); 1234fe767acSJie Hai ADD_DICT_STAT(stats, rx_nombuf); 1244fe767acSJie Hai eth_dev_add_port_queue_stats(d, stats.q_ipackets, "q_ipackets"); 1254fe767acSJie Hai eth_dev_add_port_queue_stats(d, stats.q_opackets, "q_opackets"); 1264fe767acSJie Hai eth_dev_add_port_queue_stats(d, stats.q_ibytes, "q_ibytes"); 1274fe767acSJie Hai eth_dev_add_port_queue_stats(d, stats.q_obytes, "q_obytes"); 1284fe767acSJie Hai eth_dev_add_port_queue_stats(d, stats.q_errors, "q_errors"); 1294fe767acSJie Hai 1304fe767acSJie Hai return 0; 1314fe767acSJie Hai } 1324fe767acSJie Hai 1334fe767acSJie Hai static int 1344fe767acSJie Hai eth_dev_handle_port_xstats(const char *cmd __rte_unused, 1354fe767acSJie Hai const char *params, 1364fe767acSJie Hai struct rte_tel_data *d) 1374fe767acSJie Hai { 1384fe767acSJie Hai const char *const valid_keys[] = { "hide_zero", NULL }; 1394fe767acSJie Hai struct rte_eth_xstat *eth_xstats; 1404fe767acSJie Hai struct rte_eth_xstat_name *xstat_names; 1414fe767acSJie Hai struct rte_kvargs *kvlist; 1424fe767acSJie Hai bool hide_zero = false; 1436ca32611SJie Hai uint16_t port_id; 1444fe767acSJie Hai char *end_param; 1456ca32611SJie Hai int num_xstats; 1464fe767acSJie Hai int i, ret; 1474fe767acSJie Hai 1486ca32611SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, true); 1496ca32611SJie Hai if (ret < 0) 1506ca32611SJie Hai return ret; 1514fe767acSJie Hai 1524fe767acSJie Hai if (*end_param != '\0') { 1534fe767acSJie Hai kvlist = rte_kvargs_parse(end_param, valid_keys); 1544fe767acSJie Hai ret = rte_kvargs_process(kvlist, NULL, eth_dev_parse_hide_zero, &hide_zero); 1554fe767acSJie Hai if (kvlist == NULL || ret != 0) 1560e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(NOTICE, 1570e21c7c0SDavid Marchand "Unknown extra parameters passed to ethdev telemetry command, ignoring"); 1584fe767acSJie Hai rte_kvargs_free(kvlist); 1594fe767acSJie Hai } 1604fe767acSJie Hai 1614fe767acSJie Hai num_xstats = rte_eth_xstats_get(port_id, NULL, 0); 1624fe767acSJie Hai if (num_xstats < 0) 1634fe767acSJie Hai return -1; 1644fe767acSJie Hai 1654fe767acSJie Hai /* use one malloc for both names and stats */ 1664fe767acSJie Hai eth_xstats = malloc((sizeof(struct rte_eth_xstat) + 1674fe767acSJie Hai sizeof(struct rte_eth_xstat_name)) * num_xstats); 1684fe767acSJie Hai if (eth_xstats == NULL) 1694fe767acSJie Hai return -1; 1704fe767acSJie Hai xstat_names = (void *)ð_xstats[num_xstats]; 1714fe767acSJie Hai 1724fe767acSJie Hai ret = rte_eth_xstats_get_names(port_id, xstat_names, num_xstats); 1734fe767acSJie Hai if (ret < 0 || ret > num_xstats) { 1744fe767acSJie Hai free(eth_xstats); 1754fe767acSJie Hai return -1; 1764fe767acSJie Hai } 1774fe767acSJie Hai 1784fe767acSJie Hai ret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats); 1794fe767acSJie Hai if (ret < 0 || ret > num_xstats) { 1804fe767acSJie Hai free(eth_xstats); 1814fe767acSJie Hai return -1; 1824fe767acSJie Hai } 1834fe767acSJie Hai 1844fe767acSJie Hai rte_tel_data_start_dict(d); 1854fe767acSJie Hai for (i = 0; i < num_xstats; i++) { 1864fe767acSJie Hai if (hide_zero && eth_xstats[i].value == 0) 1874fe767acSJie Hai continue; 1884fe767acSJie Hai rte_tel_data_add_dict_uint(d, xstat_names[i].name, 1894fe767acSJie Hai eth_xstats[i].value); 1904fe767acSJie Hai } 1914fe767acSJie Hai free(eth_xstats); 1924fe767acSJie Hai return 0; 1934fe767acSJie Hai } 1944fe767acSJie Hai 1954fe767acSJie Hai #ifndef RTE_EXEC_ENV_WINDOWS 1964fe767acSJie Hai static int 1974fe767acSJie Hai eth_dev_handle_port_dump_priv(const char *cmd __rte_unused, 1984fe767acSJie Hai const char *params, 1994fe767acSJie Hai struct rte_tel_data *d) 2004fe767acSJie Hai { 2014fe767acSJie Hai char *buf, *end_param; 2026ca32611SJie Hai uint16_t port_id; 2036ca32611SJie Hai int ret; 2044fe767acSJie Hai FILE *f; 2054fe767acSJie Hai 2066ca32611SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 2076ca32611SJie Hai if (ret < 0) 2086ca32611SJie Hai return ret; 2094fe767acSJie Hai 2104fe767acSJie Hai buf = calloc(RTE_TEL_MAX_SINGLE_STRING_LEN, sizeof(char)); 2114fe767acSJie Hai if (buf == NULL) 2124fe767acSJie Hai return -ENOMEM; 2134fe767acSJie Hai 2144fe767acSJie Hai f = fmemopen(buf, RTE_TEL_MAX_SINGLE_STRING_LEN - 1, "w+"); 2154fe767acSJie Hai if (f == NULL) { 2164fe767acSJie Hai free(buf); 2174fe767acSJie Hai return -EINVAL; 2184fe767acSJie Hai } 2194fe767acSJie Hai 2204fe767acSJie Hai ret = rte_eth_dev_priv_dump(port_id, f); 2214fe767acSJie Hai fclose(f); 2224fe767acSJie Hai if (ret == 0) { 2234fe767acSJie Hai rte_tel_data_start_dict(d); 2244fe767acSJie Hai rte_tel_data_string(d, buf); 2254fe767acSJie Hai } 2264fe767acSJie Hai 2274fe767acSJie Hai free(buf); 2284fe767acSJie Hai return 0; 2294fe767acSJie Hai } 2304fe767acSJie Hai #endif /* !RTE_EXEC_ENV_WINDOWS */ 2314fe767acSJie Hai 2324fe767acSJie Hai static int 2334fe767acSJie Hai eth_dev_handle_port_link_status(const char *cmd __rte_unused, 2344fe767acSJie Hai const char *params, 2354fe767acSJie Hai struct rte_tel_data *d) 2364fe767acSJie Hai { 2374fe767acSJie Hai static const char *status_str = "status"; 2384fe767acSJie Hai struct rte_eth_link link; 2396ca32611SJie Hai uint16_t port_id; 2404fe767acSJie Hai char *end_param; 2416ca32611SJie Hai int ret; 2424fe767acSJie Hai 2436ca32611SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 2446ca32611SJie Hai if (ret < 0) 2456ca32611SJie Hai return ret; 2464fe767acSJie Hai 2474fe767acSJie Hai ret = rte_eth_link_get_nowait(port_id, &link); 2484fe767acSJie Hai if (ret < 0) 2494fe767acSJie Hai return -1; 2504fe767acSJie Hai 2514fe767acSJie Hai rte_tel_data_start_dict(d); 2524fe767acSJie Hai if (!link.link_status) { 2534fe767acSJie Hai rte_tel_data_add_dict_string(d, status_str, "DOWN"); 2544fe767acSJie Hai return 0; 2554fe767acSJie Hai } 2564fe767acSJie Hai rte_tel_data_add_dict_string(d, status_str, "UP"); 2574fe767acSJie Hai rte_tel_data_add_dict_uint(d, "speed", link.link_speed); 2584fe767acSJie Hai rte_tel_data_add_dict_string(d, "duplex", 2594fe767acSJie Hai (link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ? 2604fe767acSJie Hai "full-duplex" : "half-duplex"); 2614fe767acSJie Hai return 0; 2624fe767acSJie Hai } 2634fe767acSJie Hai 264aea48618SJie Hai static void 265aea48618SJie Hai eth_dev_parse_rx_offloads(uint64_t offload, struct rte_tel_data *d) 266aea48618SJie Hai { 267aea48618SJie Hai uint64_t i; 268aea48618SJie Hai 269aea48618SJie Hai rte_tel_data_start_array(d, RTE_TEL_STRING_VAL); 270aea48618SJie Hai for (i = 0; i < CHAR_BIT * sizeof(offload); i++) { 271aea48618SJie Hai if ((offload & RTE_BIT64(i)) != 0) 272aea48618SJie Hai rte_tel_data_add_array_string(d, 273aea48618SJie Hai rte_eth_dev_rx_offload_name(offload & RTE_BIT64(i))); 274aea48618SJie Hai } 275aea48618SJie Hai } 276aea48618SJie Hai 277aea48618SJie Hai static void 278aea48618SJie Hai eth_dev_parse_tx_offloads(uint64_t offload, struct rte_tel_data *d) 279aea48618SJie Hai { 280aea48618SJie Hai uint64_t i; 281aea48618SJie Hai 282aea48618SJie Hai rte_tel_data_start_array(d, RTE_TEL_STRING_VAL); 283aea48618SJie Hai for (i = 0; i < CHAR_BIT * sizeof(offload); i++) { 284aea48618SJie Hai if ((offload & RTE_BIT64(i)) != 0) 285aea48618SJie Hai rte_tel_data_add_array_string(d, 286aea48618SJie Hai rte_eth_dev_tx_offload_name(offload & RTE_BIT64(i))); 287aea48618SJie Hai } 288aea48618SJie Hai } 289aea48618SJie Hai 2904fe767acSJie Hai static int 2914fe767acSJie Hai eth_dev_handle_port_info(const char *cmd __rte_unused, 2924fe767acSJie Hai const char *params, 2934fe767acSJie Hai struct rte_tel_data *d) 2944fe767acSJie Hai { 295aea48618SJie Hai struct rte_tel_data *rx_offload, *tx_offload; 2964fe767acSJie Hai struct rte_tel_data *rxq_state, *txq_state; 2974b5f5fa9SJie Hai char fw_version[RTE_TEL_MAX_STRING_LEN]; 2984fe767acSJie Hai char mac_addr[RTE_ETHER_ADDR_FMT_SIZE]; 2994fe767acSJie Hai struct rte_eth_dev *eth_dev; 3006ca32611SJie Hai uint16_t port_id; 3014fe767acSJie Hai char *end_param; 3026ca32611SJie Hai int ret; 3036ca32611SJie Hai int i; 3044fe767acSJie Hai 3056ca32611SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 3066ca32611SJie Hai if (ret < 0) 3076ca32611SJie Hai return ret; 3084fe767acSJie Hai 3094fe767acSJie Hai eth_dev = &rte_eth_devices[port_id]; 3104fe767acSJie Hai 3114fe767acSJie Hai rxq_state = rte_tel_data_alloc(); 312aea48618SJie Hai if (rxq_state == NULL) 3134fe767acSJie Hai return -ENOMEM; 3144fe767acSJie Hai 3154fe767acSJie Hai txq_state = rte_tel_data_alloc(); 316aea48618SJie Hai if (txq_state == NULL) 317aea48618SJie Hai goto free_rxq_state; 318aea48618SJie Hai 319aea48618SJie Hai rx_offload = rte_tel_data_alloc(); 320aea48618SJie Hai if (rx_offload == NULL) 321aea48618SJie Hai goto free_txq_state; 322aea48618SJie Hai 323aea48618SJie Hai tx_offload = rte_tel_data_alloc(); 324aea48618SJie Hai if (tx_offload == NULL) 325aea48618SJie Hai goto free_rx_offload; 3264fe767acSJie Hai 3274fe767acSJie Hai rte_tel_data_start_dict(d); 3284fe767acSJie Hai rte_tel_data_add_dict_string(d, "name", eth_dev->data->name); 3294b5f5fa9SJie Hai 3304b5f5fa9SJie Hai if (rte_eth_dev_fw_version_get(port_id, fw_version, 3314b5f5fa9SJie Hai RTE_TEL_MAX_STRING_LEN) == 0) 3324b5f5fa9SJie Hai rte_tel_data_add_dict_string(d, "fw_version", fw_version); 3334b5f5fa9SJie Hai 3344fe767acSJie Hai rte_tel_data_add_dict_int(d, "state", eth_dev->state); 3354fe767acSJie Hai rte_tel_data_add_dict_int(d, "nb_rx_queues", 3364fe767acSJie Hai eth_dev->data->nb_rx_queues); 3374fe767acSJie Hai rte_tel_data_add_dict_int(d, "nb_tx_queues", 3384fe767acSJie Hai eth_dev->data->nb_tx_queues); 3394fe767acSJie Hai rte_tel_data_add_dict_int(d, "port_id", eth_dev->data->port_id); 3404fe767acSJie Hai rte_tel_data_add_dict_int(d, "mtu", eth_dev->data->mtu); 3414fe767acSJie Hai rte_tel_data_add_dict_uint(d, "rx_mbuf_size_min", 3424fe767acSJie Hai eth_dev->data->min_rx_buf_size); 3434fe767acSJie Hai rte_ether_format_addr(mac_addr, sizeof(mac_addr), 3444fe767acSJie Hai eth_dev->data->mac_addrs); 3454fe767acSJie Hai rte_tel_data_add_dict_string(d, "mac_addr", mac_addr); 3464fe767acSJie Hai rte_tel_data_add_dict_int(d, "promiscuous", 3474fe767acSJie Hai eth_dev->data->promiscuous); 3484fe767acSJie Hai rte_tel_data_add_dict_int(d, "scattered_rx", 3494fe767acSJie Hai eth_dev->data->scattered_rx); 3504fe767acSJie Hai rte_tel_data_add_dict_int(d, "all_multicast", 3514fe767acSJie Hai eth_dev->data->all_multicast); 3524fe767acSJie Hai rte_tel_data_add_dict_int(d, "dev_started", eth_dev->data->dev_started); 3534fe767acSJie Hai rte_tel_data_add_dict_int(d, "lro", eth_dev->data->lro); 3544fe767acSJie Hai rte_tel_data_add_dict_int(d, "dev_configured", 3554fe767acSJie Hai eth_dev->data->dev_configured); 3564fe767acSJie Hai 3574fe767acSJie Hai rte_tel_data_start_array(rxq_state, RTE_TEL_INT_VAL); 3584fe767acSJie Hai for (i = 0; i < eth_dev->data->nb_rx_queues; i++) 3594fe767acSJie Hai rte_tel_data_add_array_int(rxq_state, 3604fe767acSJie Hai eth_dev->data->rx_queue_state[i]); 3614fe767acSJie Hai 3624fe767acSJie Hai rte_tel_data_start_array(txq_state, RTE_TEL_INT_VAL); 3634fe767acSJie Hai for (i = 0; i < eth_dev->data->nb_tx_queues; i++) 3644fe767acSJie Hai rte_tel_data_add_array_int(txq_state, 3654fe767acSJie Hai eth_dev->data->tx_queue_state[i]); 3664fe767acSJie Hai 3674fe767acSJie Hai rte_tel_data_add_dict_container(d, "rxq_state", rxq_state, 0); 3684fe767acSJie Hai rte_tel_data_add_dict_container(d, "txq_state", txq_state, 0); 3694fe767acSJie Hai rte_tel_data_add_dict_int(d, "numa_node", eth_dev->data->numa_node); 3704fe767acSJie Hai rte_tel_data_add_dict_uint_hex(d, "dev_flags", 3714fe767acSJie Hai eth_dev->data->dev_flags, 0); 372aea48618SJie Hai 373aea48618SJie Hai eth_dev_parse_rx_offloads(eth_dev->data->dev_conf.rxmode.offloads, 374aea48618SJie Hai rx_offload); 375aea48618SJie Hai rte_tel_data_add_dict_container(d, "rx_offloads", rx_offload, 0); 376aea48618SJie Hai eth_dev_parse_tx_offloads(eth_dev->data->dev_conf.txmode.offloads, 377aea48618SJie Hai tx_offload); 378aea48618SJie Hai rte_tel_data_add_dict_container(d, "tx_offloads", tx_offload, 0); 379aea48618SJie Hai 3804fe767acSJie Hai rte_tel_data_add_dict_uint_hex(d, "ethdev_rss_hf", 3814fe767acSJie Hai eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf, 0); 3824fe767acSJie Hai 3834fe767acSJie Hai return 0; 384aea48618SJie Hai 385aea48618SJie Hai free_rx_offload: 386aea48618SJie Hai rte_tel_data_free(rx_offload); 387aea48618SJie Hai free_txq_state: 388aea48618SJie Hai rte_tel_data_free(txq_state); 389aea48618SJie Hai free_rxq_state: 390aea48618SJie Hai rte_tel_data_free(rxq_state); 391aea48618SJie Hai 392aea48618SJie Hai return -ENOMEM; 3934fe767acSJie Hai } 3944fe767acSJie Hai 3956732ae1cSDengdui Huang static int 3966732ae1cSDengdui Huang eth_dev_handle_port_macs(const char *cmd __rte_unused, 3976732ae1cSDengdui Huang const char *params, 3986732ae1cSDengdui Huang struct rte_tel_data *d) 3996732ae1cSDengdui Huang { 4006732ae1cSDengdui Huang char mac_addr[RTE_ETHER_ADDR_FMT_SIZE]; 4016732ae1cSDengdui Huang struct rte_eth_dev_info dev_info; 4026732ae1cSDengdui Huang struct rte_eth_dev *eth_dev; 4036732ae1cSDengdui Huang uint16_t port_id; 4046732ae1cSDengdui Huang char *end_param; 4056732ae1cSDengdui Huang uint32_t i; 4066732ae1cSDengdui Huang int ret; 4076732ae1cSDengdui Huang 4086732ae1cSDengdui Huang ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 4096732ae1cSDengdui Huang if (ret < 0) 4106732ae1cSDengdui Huang return ret; 4116732ae1cSDengdui Huang 4126732ae1cSDengdui Huang ret = rte_eth_dev_info_get(port_id, &dev_info); 4136732ae1cSDengdui Huang if (ret != 0) 4146732ae1cSDengdui Huang return ret; 4156732ae1cSDengdui Huang 4166732ae1cSDengdui Huang eth_dev = &rte_eth_devices[port_id]; 4176732ae1cSDengdui Huang rte_tel_data_start_array(d, RTE_TEL_STRING_VAL); 4186732ae1cSDengdui Huang for (i = 0; i < dev_info.max_mac_addrs; i++) { 4196732ae1cSDengdui Huang if (rte_is_zero_ether_addr(ð_dev->data->mac_addrs[i])) 4206732ae1cSDengdui Huang continue; 4216732ae1cSDengdui Huang 4226732ae1cSDengdui Huang rte_ether_format_addr(mac_addr, sizeof(mac_addr), 4236732ae1cSDengdui Huang ð_dev->data->mac_addrs[i]); 4246732ae1cSDengdui Huang rte_tel_data_add_array_string(d, mac_addr); 4256732ae1cSDengdui Huang } 4266732ae1cSDengdui Huang 4276732ae1cSDengdui Huang return 0; 4286732ae1cSDengdui Huang } 4296732ae1cSDengdui Huang 430499c8486SJie Hai static int 431499c8486SJie Hai eth_dev_handle_port_flow_ctrl(const char *cmd __rte_unused, 432499c8486SJie Hai const char *params, 433499c8486SJie Hai struct rte_tel_data *d) 434499c8486SJie Hai { 435499c8486SJie Hai struct rte_eth_fc_conf fc_conf; 436499c8486SJie Hai uint16_t port_id; 437499c8486SJie Hai char *end_param; 438499c8486SJie Hai bool rx_fc_en; 439499c8486SJie Hai bool tx_fc_en; 440499c8486SJie Hai int ret; 441499c8486SJie Hai 442499c8486SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 443499c8486SJie Hai if (ret < 0) 444499c8486SJie Hai return ret; 445499c8486SJie Hai 446499c8486SJie Hai ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf); 447499c8486SJie Hai if (ret != 0) { 4480e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 4490e21c7c0SDavid Marchand "Failed to get flow ctrl info, ret = %d", ret); 450499c8486SJie Hai return ret; 451499c8486SJie Hai } 452499c8486SJie Hai 453499c8486SJie Hai rx_fc_en = fc_conf.mode == RTE_ETH_FC_RX_PAUSE || 454499c8486SJie Hai fc_conf.mode == RTE_ETH_FC_FULL; 455499c8486SJie Hai tx_fc_en = fc_conf.mode == RTE_ETH_FC_TX_PAUSE || 456499c8486SJie Hai fc_conf.mode == RTE_ETH_FC_FULL; 457499c8486SJie Hai 458499c8486SJie Hai rte_tel_data_start_dict(d); 459499c8486SJie Hai rte_tel_data_add_dict_uint_hex(d, "high_waterline", fc_conf.high_water, 0); 460499c8486SJie Hai rte_tel_data_add_dict_uint_hex(d, "low_waterline", fc_conf.low_water, 0); 461499c8486SJie Hai rte_tel_data_add_dict_uint_hex(d, "pause_time", fc_conf.pause_time, 0); 462499c8486SJie Hai rte_tel_data_add_dict_string(d, "send_xon", fc_conf.send_xon ? "on" : "off"); 463499c8486SJie Hai rte_tel_data_add_dict_string(d, "mac_ctrl_frame_fwd", 464499c8486SJie Hai fc_conf.mac_ctrl_frame_fwd ? "on" : "off"); 465499c8486SJie Hai rte_tel_data_add_dict_string(d, "rx_pause", rx_fc_en ? "on" : "off"); 466499c8486SJie Hai rte_tel_data_add_dict_string(d, "tx_pause", tx_fc_en ? "on" : "off"); 467499c8486SJie Hai rte_tel_data_add_dict_string(d, "autoneg", fc_conf.autoneg ? "on" : "off"); 468499c8486SJie Hai 469499c8486SJie Hai return 0; 470499c8486SJie Hai } 471499c8486SJie Hai 472f38f6265SJie Hai static int 473f38f6265SJie Hai ethdev_parse_queue_params(const char *params, bool is_rx, 474f38f6265SJie Hai uint16_t *port_id, uint16_t *queue_id) 475f38f6265SJie Hai { 476f38f6265SJie Hai struct rte_eth_dev *dev; 477f38f6265SJie Hai const char *qid_param; 478f38f6265SJie Hai uint16_t nb_queues; 479f38f6265SJie Hai char *end_param; 480f38f6265SJie Hai uint64_t qid; 481f38f6265SJie Hai int ret; 482f38f6265SJie Hai 483f38f6265SJie Hai ret = eth_dev_parse_port_params(params, port_id, &end_param, true); 484f38f6265SJie Hai if (ret < 0) 485f38f6265SJie Hai return ret; 486f38f6265SJie Hai 487f38f6265SJie Hai dev = &rte_eth_devices[*port_id]; 488f38f6265SJie Hai nb_queues = is_rx ? dev->data->nb_rx_queues : dev->data->nb_tx_queues; 489f38f6265SJie Hai if (nb_queues == 1 && *end_param == '\0') 490f38f6265SJie Hai qid = 0; 491f38f6265SJie Hai else { 492f38f6265SJie Hai qid_param = strtok(end_param, ","); 493f38f6265SJie Hai if (!qid_param || strlen(qid_param) == 0 || !isdigit(*qid_param)) 494f38f6265SJie Hai return -EINVAL; 495f38f6265SJie Hai 496f38f6265SJie Hai qid = strtoul(qid_param, &end_param, 0); 497f38f6265SJie Hai } 498f38f6265SJie Hai if (*end_param != '\0') 4990e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(NOTICE, 5000e21c7c0SDavid Marchand "Extra parameters passed to ethdev telemetry command, ignoring"); 501f38f6265SJie Hai 502f38f6265SJie Hai if (qid >= UINT16_MAX) 503f38f6265SJie Hai return -EINVAL; 504f38f6265SJie Hai 505f38f6265SJie Hai *queue_id = qid; 506f38f6265SJie Hai return 0; 507f38f6265SJie Hai } 508f38f6265SJie Hai 509f38f6265SJie Hai static int 510f38f6265SJie Hai eth_dev_add_burst_mode(uint16_t port_id, uint16_t queue_id, 511f38f6265SJie Hai bool is_rx, struct rte_tel_data *d) 512f38f6265SJie Hai { 513f38f6265SJie Hai struct rte_eth_burst_mode mode; 514f38f6265SJie Hai int ret; 515f38f6265SJie Hai 516f38f6265SJie Hai if (is_rx) 517f38f6265SJie Hai ret = rte_eth_rx_burst_mode_get(port_id, queue_id, &mode); 518f38f6265SJie Hai else 519f38f6265SJie Hai ret = rte_eth_tx_burst_mode_get(port_id, queue_id, &mode); 520f38f6265SJie Hai 521f38f6265SJie Hai if (ret == -ENOTSUP) 522f38f6265SJie Hai return 0; 523f38f6265SJie Hai 524f38f6265SJie Hai if (ret != 0) { 5250e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 5260e21c7c0SDavid Marchand "Failed to get burst mode for port %u", port_id); 527f38f6265SJie Hai return ret; 528f38f6265SJie Hai } 529f38f6265SJie Hai 530f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "burst_flags", mode.flags); 531f38f6265SJie Hai rte_tel_data_add_dict_string(d, "burst_mode", mode.info); 532f38f6265SJie Hai return 0; 533f38f6265SJie Hai } 534f38f6265SJie Hai 535f38f6265SJie Hai static int 536f38f6265SJie Hai eth_dev_handle_port_rxq(const char *cmd __rte_unused, 537f38f6265SJie Hai const char *params, 538f38f6265SJie Hai struct rte_tel_data *d) 539f38f6265SJie Hai { 540f38f6265SJie Hai struct rte_eth_thresh *rx_thresh; 541f38f6265SJie Hai struct rte_eth_rxconf *rxconf; 542f38f6265SJie Hai struct rte_eth_rxq_info qinfo; 543f38f6265SJie Hai struct rte_tel_data *offload; 544f38f6265SJie Hai uint16_t port_id, queue_id; 545f38f6265SJie Hai int ret; 546f38f6265SJie Hai 547f38f6265SJie Hai ret = ethdev_parse_queue_params(params, true, &port_id, &queue_id); 548f38f6265SJie Hai if (ret != 0) 549f38f6265SJie Hai return ret; 550f38f6265SJie Hai 551f38f6265SJie Hai ret = rte_eth_rx_queue_info_get(port_id, queue_id, &qinfo); 552f38f6265SJie Hai if (ret != 0) 553f38f6265SJie Hai return ret; 554f38f6265SJie Hai 555f38f6265SJie Hai rte_tel_data_start_dict(d); 556f38f6265SJie Hai rte_tel_data_add_dict_string(d, "mempool_name", qinfo.mp->name); 557f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "socket_id", qinfo.mp->socket_id); 558f38f6265SJie Hai 559f38f6265SJie Hai rx_thresh = &qinfo.conf.rx_thresh; 560f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "host_threshold", rx_thresh->hthresh); 561f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "prefetch_threshold", rx_thresh->pthresh); 562f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "writeback_threshold", rx_thresh->wthresh); 563f38f6265SJie Hai 564f38f6265SJie Hai rxconf = &qinfo.conf; 565f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "free_threshold", rxconf->rx_free_thresh); 566f38f6265SJie Hai rte_tel_data_add_dict_string(d, "rx_drop_en", 567f38f6265SJie Hai rxconf->rx_drop_en == 0 ? "off" : "on"); 568f38f6265SJie Hai rte_tel_data_add_dict_string(d, "deferred_start", 569f38f6265SJie Hai rxconf->rx_deferred_start == 0 ? "off" : "on"); 570f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "rx_nseg", rxconf->rx_nseg); 571f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "share_group", rxconf->share_group); 572f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "share_qid", rxconf->share_qid); 573f38f6265SJie Hai 574f38f6265SJie Hai offload = rte_tel_data_alloc(); 575f38f6265SJie Hai if (offload == NULL) 576f38f6265SJie Hai return -ENOMEM; 577f38f6265SJie Hai 578f38f6265SJie Hai eth_dev_parse_rx_offloads(rxconf->offloads, offload); 579f38f6265SJie Hai rte_tel_data_add_dict_container(d, "offloads", offload, 0); 580f38f6265SJie Hai 581f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "rx_nmempool", rxconf->rx_nmempool); 582f38f6265SJie Hai 583f38f6265SJie Hai rte_tel_data_add_dict_string(d, "scattered_rx", 584f38f6265SJie Hai qinfo.scattered_rx == 0 ? "off" : "on"); 585f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "queue_state", qinfo.queue_state); 586f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "nb_desc", qinfo.nb_desc); 587f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "rx_buf_size", qinfo.rx_buf_size); 588f38f6265SJie Hai rte_tel_data_add_dict_uint(d, "avail_thresh", qinfo.avail_thresh); 589f38f6265SJie Hai 590f38f6265SJie Hai ret = eth_dev_add_burst_mode(port_id, queue_id, true, d); 591f38f6265SJie Hai if (ret != 0) 592f38f6265SJie Hai rte_tel_data_free(offload); 593f38f6265SJie Hai 594f38f6265SJie Hai return ret; 595f38f6265SJie Hai } 596f38f6265SJie Hai 5971a479610SJie Hai static int 5981a479610SJie Hai eth_dev_handle_port_txq(const char *cmd __rte_unused, 5991a479610SJie Hai const char *params, 6001a479610SJie Hai struct rte_tel_data *d) 6011a479610SJie Hai { 6021a479610SJie Hai struct rte_eth_thresh *tx_thresh; 6031a479610SJie Hai struct rte_eth_txconf *txconf; 6041a479610SJie Hai struct rte_eth_txq_info qinfo; 6051a479610SJie Hai struct rte_tel_data *offload; 6061a479610SJie Hai uint16_t port_id, queue_id; 6071a479610SJie Hai int ret; 6081a479610SJie Hai 6091a479610SJie Hai ret = ethdev_parse_queue_params(params, false, &port_id, &queue_id); 6101a479610SJie Hai if (ret != 0) 6111a479610SJie Hai return ret; 6121a479610SJie Hai 6131a479610SJie Hai ret = rte_eth_tx_queue_info_get(port_id, queue_id, &qinfo); 6141a479610SJie Hai if (ret != 0) 6151a479610SJie Hai return ret; 6161a479610SJie Hai 6171a479610SJie Hai rte_tel_data_start_dict(d); 6181a479610SJie Hai tx_thresh = &qinfo.conf.tx_thresh; 6191a479610SJie Hai txconf = &qinfo.conf; 6201a479610SJie Hai rte_tel_data_add_dict_uint(d, "host_threshold", tx_thresh->hthresh); 6211a479610SJie Hai rte_tel_data_add_dict_uint(d, "prefetch_threshold", tx_thresh->pthresh); 6221a479610SJie Hai rte_tel_data_add_dict_uint(d, "writeback_threshold", tx_thresh->wthresh); 6231a479610SJie Hai rte_tel_data_add_dict_uint(d, "rs_threshold", txconf->tx_rs_thresh); 6241a479610SJie Hai rte_tel_data_add_dict_uint(d, "free_threshold", txconf->tx_free_thresh); 6251a479610SJie Hai rte_tel_data_add_dict_string(d, "deferred_start", 6261a479610SJie Hai txconf->tx_deferred_start == 0 ? "off" : "on"); 6271a479610SJie Hai 6281a479610SJie Hai offload = rte_tel_data_alloc(); 6291a479610SJie Hai if (offload == NULL) 6301a479610SJie Hai return -ENOMEM; 6311a479610SJie Hai 6321a479610SJie Hai eth_dev_parse_tx_offloads(txconf->offloads, offload); 6331a479610SJie Hai rte_tel_data_add_dict_container(d, "offloads", offload, 0); 6341a479610SJie Hai 6351a479610SJie Hai rte_tel_data_add_dict_uint(d, "queue_state", qinfo.queue_state); 6361a479610SJie Hai rte_tel_data_add_dict_uint(d, "nb_desc", qinfo.nb_desc); 6371a479610SJie Hai 6381a479610SJie Hai ret = eth_dev_add_burst_mode(port_id, queue_id, false, d); 6391a479610SJie Hai if (ret != 0) 6401a479610SJie Hai rte_tel_data_free(offload); 6411a479610SJie Hai 6421a479610SJie Hai return 0; 6431a479610SJie Hai } 6441a479610SJie Hai 64566f3e047SJie Hai static int 64666f3e047SJie Hai eth_dev_add_dcb_tc(struct rte_eth_dcb_info *dcb_info, struct rte_tel_data *d) 64766f3e047SJie Hai { 64866f3e047SJie Hai struct rte_tel_data *tcds[RTE_ETH_DCB_NUM_TCS] = {NULL}; 64966f3e047SJie Hai struct rte_eth_dcb_tc_queue_mapping *tcq; 65066f3e047SJie Hai char bw_percent[RTE_TEL_MAX_STRING_LEN]; 65166f3e047SJie Hai char name[RTE_TEL_MAX_STRING_LEN]; 65266f3e047SJie Hai struct rte_tel_data *tcd; 65366f3e047SJie Hai uint32_t i; 65466f3e047SJie Hai 65566f3e047SJie Hai for (i = 0; i < dcb_info->nb_tcs; i++) { 65666f3e047SJie Hai tcd = rte_tel_data_alloc(); 65766f3e047SJie Hai if (tcd == NULL) { 65866f3e047SJie Hai while (i-- > 0) 65966f3e047SJie Hai rte_tel_data_free(tcds[i]); 66066f3e047SJie Hai return -ENOMEM; 66166f3e047SJie Hai } 66266f3e047SJie Hai 66366f3e047SJie Hai tcds[i] = tcd; 66466f3e047SJie Hai rte_tel_data_start_dict(tcd); 66566f3e047SJie Hai 66666f3e047SJie Hai rte_tel_data_add_dict_uint(tcd, "priority", dcb_info->prio_tc[i]); 66766f3e047SJie Hai snprintf(bw_percent, RTE_TEL_MAX_STRING_LEN, 66866f3e047SJie Hai "%u%%", dcb_info->tc_bws[i]); 66966f3e047SJie Hai rte_tel_data_add_dict_string(tcd, "bw_percent", bw_percent); 67066f3e047SJie Hai 67166f3e047SJie Hai tcq = &dcb_info->tc_queue; 67266f3e047SJie Hai rte_tel_data_add_dict_uint(tcd, "rxq_base", tcq->tc_rxq[0][i].base); 67366f3e047SJie Hai rte_tel_data_add_dict_uint(tcd, "txq_base", tcq->tc_txq[0][i].base); 67466f3e047SJie Hai rte_tel_data_add_dict_uint(tcd, "nb_rxq", tcq->tc_rxq[0][i].nb_queue); 67566f3e047SJie Hai rte_tel_data_add_dict_uint(tcd, "nb_txq", tcq->tc_txq[0][i].nb_queue); 67666f3e047SJie Hai 67766f3e047SJie Hai snprintf(name, RTE_TEL_MAX_STRING_LEN, "tc%u", i); 67866f3e047SJie Hai rte_tel_data_add_dict_container(d, name, tcd, 0); 67966f3e047SJie Hai } 68066f3e047SJie Hai 68166f3e047SJie Hai return 0; 68266f3e047SJie Hai } 68366f3e047SJie Hai 68466f3e047SJie Hai static int 68566f3e047SJie Hai eth_dev_add_dcb_info(uint16_t port_id, struct rte_tel_data *d) 68666f3e047SJie Hai { 68766f3e047SJie Hai struct rte_eth_dcb_info dcb_info; 68866f3e047SJie Hai int ret; 68966f3e047SJie Hai 69066f3e047SJie Hai ret = rte_eth_dev_get_dcb_info(port_id, &dcb_info); 69166f3e047SJie Hai if (ret != 0) { 6920e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 6930e21c7c0SDavid Marchand "Failed to get dcb info, ret = %d", ret); 69466f3e047SJie Hai return ret; 69566f3e047SJie Hai } 69666f3e047SJie Hai 69766f3e047SJie Hai rte_tel_data_start_dict(d); 69866f3e047SJie Hai rte_tel_data_add_dict_uint(d, "tc_num", dcb_info.nb_tcs); 69966f3e047SJie Hai 70066f3e047SJie Hai if (dcb_info.nb_tcs > 0) 70166f3e047SJie Hai return eth_dev_add_dcb_tc(&dcb_info, d); 70266f3e047SJie Hai 70366f3e047SJie Hai return 0; 70466f3e047SJie Hai } 70566f3e047SJie Hai 70666f3e047SJie Hai static int 70766f3e047SJie Hai eth_dev_handle_port_dcb(const char *cmd __rte_unused, 70866f3e047SJie Hai const char *params, 70966f3e047SJie Hai struct rte_tel_data *d) 71066f3e047SJie Hai { 71166f3e047SJie Hai uint16_t port_id; 71266f3e047SJie Hai char *end_param; 71366f3e047SJie Hai int ret; 71466f3e047SJie Hai 71566f3e047SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 71666f3e047SJie Hai if (ret < 0) 71766f3e047SJie Hai return ret; 71866f3e047SJie Hai 71966f3e047SJie Hai return eth_dev_add_dcb_info(port_id, d); 72066f3e047SJie Hai } 72166f3e047SJie Hai 722fde1adbfSJie Hai static int 723fde1adbfSJie Hai eth_dev_add_rss_info(struct rte_eth_rss_conf *rss_conf, struct rte_tel_data *d) 724fde1adbfSJie Hai { 725fde1adbfSJie Hai const uint32_t key_len = rss_conf->rss_key_len * 2 + 1; 726fde1adbfSJie Hai char *rss_key; 727fde1adbfSJie Hai char key[3]; /* FF\0 */ 728fde1adbfSJie Hai uint32_t i; 729fde1adbfSJie Hai int ret; 730fde1adbfSJie Hai 731fde1adbfSJie Hai rss_key = malloc(key_len); 732fde1adbfSJie Hai if (rss_key == NULL) 733fde1adbfSJie Hai return -ENOMEM; 734fde1adbfSJie Hai 735fde1adbfSJie Hai rte_tel_data_start_dict(d); 736fde1adbfSJie Hai rte_tel_data_add_dict_uint_hex(d, "rss_hf", rss_conf->rss_hf, 0); 737fde1adbfSJie Hai rte_tel_data_add_dict_uint(d, "rss_key_len", rss_conf->rss_key_len); 738fde1adbfSJie Hai 739fde1adbfSJie Hai memset(rss_key, 0, key_len); 740fde1adbfSJie Hai for (i = 0; i < rss_conf->rss_key_len; i++) { 741fde1adbfSJie Hai ret = snprintf(key, 3, "%02x", rss_conf->rss_key[i]); 742fde1adbfSJie Hai if (ret < 0) 743fde1adbfSJie Hai goto free_rss_key; 744fde1adbfSJie Hai strlcat(rss_key, key, key_len); 745fde1adbfSJie Hai } 746fde1adbfSJie Hai ret = rte_tel_data_add_dict_string(d, "rss_key", rss_key); 747fde1adbfSJie Hai 748fde1adbfSJie Hai free_rss_key: 749fde1adbfSJie Hai free(rss_key); 750fde1adbfSJie Hai 751fde1adbfSJie Hai return ret; 752fde1adbfSJie Hai } 753fde1adbfSJie Hai 754fde1adbfSJie Hai static int 755fde1adbfSJie Hai eth_dev_handle_port_rss_info(const char *cmd __rte_unused, 756fde1adbfSJie Hai const char *params, 757fde1adbfSJie Hai struct rte_tel_data *d) 758fde1adbfSJie Hai { 759fde1adbfSJie Hai struct rte_eth_dev_info dev_info; 760fde1adbfSJie Hai struct rte_eth_rss_conf rss_conf; 761fde1adbfSJie Hai uint8_t key_len; 762fde1adbfSJie Hai uint16_t port_id; 763fde1adbfSJie Hai char *end_param; 764fde1adbfSJie Hai int ret; 765fde1adbfSJie Hai 766fde1adbfSJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 767fde1adbfSJie Hai if (ret < 0) 768fde1adbfSJie Hai return ret; 769fde1adbfSJie Hai 770fde1adbfSJie Hai ret = rte_eth_dev_info_get(port_id, &dev_info); 771fde1adbfSJie Hai if (ret != 0) { 7720e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 7730e21c7c0SDavid Marchand "Failed to get device info, ret = %d", ret); 774fde1adbfSJie Hai return ret; 775fde1adbfSJie Hai } 776fde1adbfSJie Hai 777fde1adbfSJie Hai key_len = dev_info.hash_key_size ? dev_info.hash_key_size : 40; 778fde1adbfSJie Hai rss_conf.rss_key_len = key_len; 779fde1adbfSJie Hai rss_conf.rss_key = malloc(key_len); 780fde1adbfSJie Hai if (rss_conf.rss_key == NULL) 781fde1adbfSJie Hai return -ENOMEM; 782fde1adbfSJie Hai 783fde1adbfSJie Hai ret = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf); 784fde1adbfSJie Hai if (ret != 0) { 785fde1adbfSJie Hai free(rss_conf.rss_key); 786fde1adbfSJie Hai return ret; 787fde1adbfSJie Hai } 788fde1adbfSJie Hai 789fde1adbfSJie Hai ret = eth_dev_add_rss_info(&rss_conf, d); 790fde1adbfSJie Hai free(rss_conf.rss_key); 791fde1adbfSJie Hai return ret; 792fde1adbfSJie Hai } 793fde1adbfSJie Hai 79485576ba6SJie Hai static const char * 79585576ba6SJie Hai eth_dev_fec_capa_to_string(uint32_t fec_capa) 79685576ba6SJie Hai { 79785576ba6SJie Hai uint32_t i; 79885576ba6SJie Hai 79985576ba6SJie Hai for (i = 0; i < RTE_DIM(rte_eth_fec_capa_name); i++) { 80085576ba6SJie Hai if ((fec_capa & rte_eth_fec_capa_name[i].capa) != 0) 80185576ba6SJie Hai return rte_eth_fec_capa_name[i].name; 80285576ba6SJie Hai } 80385576ba6SJie Hai 80485576ba6SJie Hai return "unknown"; 80585576ba6SJie Hai } 80685576ba6SJie Hai 80785576ba6SJie Hai static void 80885576ba6SJie Hai eth_dev_fec_capas_to_string(uint32_t fec_capa, char *fec_name, uint32_t len) 80985576ba6SJie Hai { 81085576ba6SJie Hai bool valid = false; 81185576ba6SJie Hai size_t count = 0; 81285576ba6SJie Hai uint32_t i; 81385576ba6SJie Hai 81485576ba6SJie Hai for (i = 0; i < RTE_DIM(rte_eth_fec_capa_name); i++) { 81585576ba6SJie Hai if ((fec_capa & rte_eth_fec_capa_name[i].capa) != 0) { 81685576ba6SJie Hai strlcat(fec_name, rte_eth_fec_capa_name[i].name, len); 81785576ba6SJie Hai count = strlcat(fec_name, " ", len); 81885576ba6SJie Hai valid = true; 81985576ba6SJie Hai } 82085576ba6SJie Hai } 82185576ba6SJie Hai 82285576ba6SJie Hai if (!valid) 82385576ba6SJie Hai count = snprintf(fec_name, len, "unknown "); 82485576ba6SJie Hai 82585576ba6SJie Hai if (count >= len) { 8260e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(WARNING, "FEC capa names may be truncated"); 82785576ba6SJie Hai count = len; 82885576ba6SJie Hai } 82985576ba6SJie Hai 83085576ba6SJie Hai fec_name[count - 1] = '\0'; 83185576ba6SJie Hai } 83285576ba6SJie Hai 83385576ba6SJie Hai static int 83485576ba6SJie Hai eth_dev_get_fec_capability(uint16_t port_id, struct rte_tel_data *d) 83585576ba6SJie Hai { 83685576ba6SJie Hai struct rte_eth_fec_capa *speed_fec_capa; 83785576ba6SJie Hai char fec_name[RTE_TEL_MAX_STRING_LEN]; 83885576ba6SJie Hai char speed[RTE_TEL_MAX_STRING_LEN]; 83985576ba6SJie Hai uint32_t capa_num; 84085576ba6SJie Hai uint32_t i, j; 84185576ba6SJie Hai int ret; 84285576ba6SJie Hai 84385576ba6SJie Hai ret = rte_eth_fec_get_capability(port_id, NULL, 0); 84485576ba6SJie Hai if (ret <= 0) 84585576ba6SJie Hai return ret == 0 ? -EINVAL : ret; 84685576ba6SJie Hai 84785576ba6SJie Hai capa_num = ret; 84885576ba6SJie Hai speed_fec_capa = calloc(capa_num, sizeof(struct rte_eth_fec_capa)); 84985576ba6SJie Hai if (speed_fec_capa == NULL) 85085576ba6SJie Hai return -ENOMEM; 85185576ba6SJie Hai 85285576ba6SJie Hai ret = rte_eth_fec_get_capability(port_id, speed_fec_capa, capa_num); 85385576ba6SJie Hai if (ret <= 0) { 85485576ba6SJie Hai ret = ret == 0 ? -EINVAL : ret; 85585576ba6SJie Hai goto out; 85685576ba6SJie Hai } 85785576ba6SJie Hai 85885576ba6SJie Hai for (i = 0; i < capa_num; i++) { 85985576ba6SJie Hai memset(fec_name, 0, RTE_TEL_MAX_STRING_LEN); 86085576ba6SJie Hai eth_dev_fec_capas_to_string(speed_fec_capa[i].capa, fec_name, 86185576ba6SJie Hai RTE_TEL_MAX_STRING_LEN); 86285576ba6SJie Hai 86385576ba6SJie Hai memset(speed, 0, RTE_TEL_MAX_STRING_LEN); 86485576ba6SJie Hai ret = snprintf(speed, RTE_TEL_MAX_STRING_LEN, "%s", 86585576ba6SJie Hai rte_eth_link_speed_to_str(speed_fec_capa[i].speed)); 86685576ba6SJie Hai if (ret < 0) 86785576ba6SJie Hai goto out; 86885576ba6SJie Hai 86985576ba6SJie Hai for (j = 0; j < strlen(speed); j++) { 87085576ba6SJie Hai if (speed[j] == ' ') 87185576ba6SJie Hai speed[j] = '_'; 87285576ba6SJie Hai } 87385576ba6SJie Hai 87485576ba6SJie Hai rte_tel_data_add_dict_string(d, speed, fec_name); 87585576ba6SJie Hai } 87685576ba6SJie Hai 87785576ba6SJie Hai out: 87885576ba6SJie Hai free(speed_fec_capa); 87985576ba6SJie Hai return ret > 0 ? 0 : ret; 88085576ba6SJie Hai } 88185576ba6SJie Hai 88285576ba6SJie Hai static int 88385576ba6SJie Hai eth_dev_handle_port_fec(const char *cmd __rte_unused, 88485576ba6SJie Hai const char *params, 88585576ba6SJie Hai struct rte_tel_data *d) 88685576ba6SJie Hai { 88785576ba6SJie Hai struct rte_tel_data *fec_capas; 88885576ba6SJie Hai uint32_t fec_mode; 88985576ba6SJie Hai uint16_t port_id; 89085576ba6SJie Hai char *end_param; 89185576ba6SJie Hai int ret; 89285576ba6SJie Hai 89385576ba6SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 89485576ba6SJie Hai if (ret < 0) 89585576ba6SJie Hai return ret; 89685576ba6SJie Hai 89785576ba6SJie Hai ret = rte_eth_fec_get(port_id, &fec_mode); 89885576ba6SJie Hai if (ret != 0) 89985576ba6SJie Hai return ret; 90085576ba6SJie Hai 90185576ba6SJie Hai rte_tel_data_start_dict(d); 90285576ba6SJie Hai rte_tel_data_add_dict_string(d, "fec_mode", 90385576ba6SJie Hai eth_dev_fec_capa_to_string(fec_mode)); 90485576ba6SJie Hai 90585576ba6SJie Hai fec_capas = rte_tel_data_alloc(); 90685576ba6SJie Hai if (fec_capas == NULL) 90785576ba6SJie Hai return -ENOMEM; 90885576ba6SJie Hai 90985576ba6SJie Hai rte_tel_data_start_dict(fec_capas); 91085576ba6SJie Hai ret = eth_dev_get_fec_capability(port_id, fec_capas); 91185576ba6SJie Hai if (ret != 0) { 91285576ba6SJie Hai rte_tel_data_free(fec_capas); 91385576ba6SJie Hai return ret; 91485576ba6SJie Hai } 91585576ba6SJie Hai 91685576ba6SJie Hai rte_tel_data_add_dict_container(d, "fec_capability", fec_capas, 0); 91785576ba6SJie Hai return 0; 91885576ba6SJie Hai } 91985576ba6SJie Hai 92019f39522SJie Hai static int 92119f39522SJie Hai eth_dev_add_vlan_id(int port_id, struct rte_tel_data *d) 92219f39522SJie Hai { 92319f39522SJie Hai struct rte_tel_data *vlan_blks[64] = {NULL}; 92419f39522SJie Hai uint16_t vlan_num, vidx, vbit, num_blks; 92519f39522SJie Hai char blk_name[RTE_TEL_MAX_STRING_LEN]; 92619f39522SJie Hai struct rte_vlan_filter_conf *vfc; 92719f39522SJie Hai struct rte_tel_data *vlan_blk; 92819f39522SJie Hai struct rte_tel_data *vd; 92919f39522SJie Hai uint64_t bit_width; 93019f39522SJie Hai uint64_t vlan_id; 93119f39522SJie Hai 93219f39522SJie Hai vd = rte_tel_data_alloc(); 93319f39522SJie Hai if (vd == NULL) 93419f39522SJie Hai return -ENOMEM; 93519f39522SJie Hai 93619f39522SJie Hai vfc = &rte_eth_devices[port_id].data->vlan_filter_conf; 93719f39522SJie Hai bit_width = CHAR_BIT * sizeof(uint64_t); 93819f39522SJie Hai vlan_num = 0; 93919f39522SJie Hai num_blks = 0; 94019f39522SJie Hai 94119f39522SJie Hai rte_tel_data_start_dict(vd); 94219f39522SJie Hai for (vidx = 0; vidx < RTE_DIM(vfc->ids); vidx++) { 94319f39522SJie Hai if (vfc->ids[vidx] == 0) 94419f39522SJie Hai continue; 94519f39522SJie Hai 94619f39522SJie Hai vlan_blk = rte_tel_data_alloc(); 94719f39522SJie Hai if (vlan_blk == NULL) 94819f39522SJie Hai goto free_all; 94919f39522SJie Hai 95019f39522SJie Hai vlan_blks[num_blks] = vlan_blk; 95119f39522SJie Hai num_blks++; 95219f39522SJie Hai snprintf(blk_name, RTE_TEL_MAX_STRING_LEN, "vlan_%"PRIu64"_to_%"PRIu64"", 95319f39522SJie Hai bit_width * vidx, bit_width * (vidx + 1) - 1); 95419f39522SJie Hai rte_tel_data_start_array(vlan_blk, RTE_TEL_UINT_VAL); 95519f39522SJie Hai rte_tel_data_add_dict_container(vd, blk_name, vlan_blk, 0); 95619f39522SJie Hai 95719f39522SJie Hai for (vbit = 0; vbit < bit_width; vbit++) { 95819f39522SJie Hai if ((vfc->ids[vidx] & RTE_BIT64(vbit)) == 0) 95919f39522SJie Hai continue; 96019f39522SJie Hai 96119f39522SJie Hai vlan_id = bit_width * vidx + vbit; 96219f39522SJie Hai rte_tel_data_add_array_uint(vlan_blk, vlan_id); 96319f39522SJie Hai vlan_num++; 96419f39522SJie Hai } 96519f39522SJie Hai } 96619f39522SJie Hai 96719f39522SJie Hai rte_tel_data_add_dict_uint(d, "vlan_num", vlan_num); 96819f39522SJie Hai rte_tel_data_add_dict_container(d, "vlan_ids", vd, 0); 96919f39522SJie Hai 97019f39522SJie Hai return 0; 97119f39522SJie Hai 97219f39522SJie Hai free_all: 97319f39522SJie Hai while (num_blks-- > 0) 97419f39522SJie Hai rte_tel_data_free(vlan_blks[num_blks]); 97519f39522SJie Hai 97619f39522SJie Hai rte_tel_data_free(vd); 97719f39522SJie Hai return -ENOMEM; 97819f39522SJie Hai } 97919f39522SJie Hai 98019f39522SJie Hai static int 98119f39522SJie Hai eth_dev_handle_port_vlan(const char *cmd __rte_unused, 98219f39522SJie Hai const char *params, 98319f39522SJie Hai struct rte_tel_data *d) 98419f39522SJie Hai { 98519f39522SJie Hai struct rte_eth_txmode *txmode; 98619f39522SJie Hai struct rte_eth_conf dev_conf; 98719f39522SJie Hai uint16_t port_id; 98819f39522SJie Hai int offload, ret; 98919f39522SJie Hai char *end_param; 99019f39522SJie Hai 99119f39522SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 99219f39522SJie Hai if (ret < 0) 99319f39522SJie Hai return ret; 99419f39522SJie Hai 99519f39522SJie Hai ret = rte_eth_dev_conf_get(port_id, &dev_conf); 99619f39522SJie Hai if (ret != 0) { 9970e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, 9980e21c7c0SDavid Marchand "Failed to get device configuration, ret = %d", ret); 99919f39522SJie Hai return ret; 100019f39522SJie Hai } 100119f39522SJie Hai 100219f39522SJie Hai txmode = &dev_conf.txmode; 100319f39522SJie Hai rte_tel_data_start_dict(d); 100419f39522SJie Hai rte_tel_data_add_dict_uint(d, "pvid", txmode->pvid); 100519f39522SJie Hai rte_tel_data_add_dict_uint(d, "hw_vlan_reject_tagged", 100619f39522SJie Hai txmode->hw_vlan_reject_tagged); 100719f39522SJie Hai rte_tel_data_add_dict_uint(d, "hw_vlan_reject_untagged", 100819f39522SJie Hai txmode->hw_vlan_reject_untagged); 100919f39522SJie Hai rte_tel_data_add_dict_uint(d, "hw_vlan_insert_pvid", 101019f39522SJie Hai txmode->hw_vlan_insert_pvid); 101119f39522SJie Hai 101219f39522SJie Hai offload = rte_eth_dev_get_vlan_offload(port_id); 101319f39522SJie Hai rte_tel_data_add_dict_string(d, "VLAN_STRIP", 101419f39522SJie Hai ((offload & RTE_ETH_VLAN_STRIP_OFFLOAD) != 0) ? "on" : "off"); 101519f39522SJie Hai rte_tel_data_add_dict_string(d, "VLAN_EXTEND", 101619f39522SJie Hai ((offload & RTE_ETH_VLAN_EXTEND_OFFLOAD) != 0) ? "on" : "off"); 101719f39522SJie Hai rte_tel_data_add_dict_string(d, "QINQ_STRIP", 101819f39522SJie Hai ((offload & RTE_ETH_QINQ_STRIP_OFFLOAD) != 0) ? "on" : "off"); 101919f39522SJie Hai rte_tel_data_add_dict_string(d, "VLAN_FILTER", 102019f39522SJie Hai ((offload & RTE_ETH_VLAN_FILTER_OFFLOAD) != 0) ? "on" : "off"); 102119f39522SJie Hai 102219f39522SJie Hai return eth_dev_add_vlan_id(port_id, d); 102319f39522SJie Hai } 102419f39522SJie Hai 1025a590d564SJie Hai static void 1026a590d564SJie Hai eth_dev_add_tm_caps(struct rte_tel_data *d, struct rte_tm_capabilities *cap) 1027a590d564SJie Hai { 1028a590d564SJie Hai rte_tel_data_add_dict_uint(d, "n_nodes_max", cap->n_nodes_max); 1029a590d564SJie Hai rte_tel_data_add_dict_uint(d, "n_levels_max", cap->n_levels_max); 1030a590d564SJie Hai rte_tel_data_add_dict_int(d, "non_leaf_nodes_identical", 1031a590d564SJie Hai cap->non_leaf_nodes_identical); 1032a590d564SJie Hai rte_tel_data_add_dict_int(d, "leaf_nodes_identical", 1033a590d564SJie Hai cap->leaf_nodes_identical); 1034a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_n_max", cap->shaper_n_max); 1035a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_private_n_max", 1036a590d564SJie Hai cap->shaper_private_n_max); 1037a590d564SJie Hai rte_tel_data_add_dict_int(d, "shaper_private_dual_rate_n_max", 1038a590d564SJie Hai cap->shaper_private_dual_rate_n_max); 1039a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_private_rate_min", 1040a590d564SJie Hai cap->shaper_private_rate_min); 1041a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_private_rate_max", 1042a590d564SJie Hai cap->shaper_private_rate_max); 1043a590d564SJie Hai rte_tel_data_add_dict_int(d, "shaper_private_packet_mode_supported", 1044a590d564SJie Hai cap->shaper_private_packet_mode_supported); 1045a590d564SJie Hai rte_tel_data_add_dict_int(d, "shaper_private_byte_mode_supported", 1046a590d564SJie Hai cap->shaper_private_byte_mode_supported); 1047a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_shared_n_max", 1048a590d564SJie Hai cap->shaper_shared_n_max); 1049a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_shared_n_nodes_per_shaper_max", 1050a590d564SJie Hai cap->shaper_shared_n_nodes_per_shaper_max); 1051a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_shared_n_shapers_per_node_max", 1052a590d564SJie Hai cap->shaper_shared_n_shapers_per_node_max); 1053a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_share_dual_rate_n_max", 1054a590d564SJie Hai cap->shaper_shared_dual_rate_n_max); 1055a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_shared_rate_min", 1056a590d564SJie Hai cap->shaper_shared_rate_min); 1057a590d564SJie Hai rte_tel_data_add_dict_uint(d, "shaper_shared_rate_max", 1058a590d564SJie Hai cap->shaper_shared_rate_max); 1059a590d564SJie Hai rte_tel_data_add_dict_int(d, "shaper_shared_packet_mode_supported", 1060a590d564SJie Hai cap->shaper_shared_packet_mode_supported); 1061a590d564SJie Hai rte_tel_data_add_dict_int(d, "shaper_shared_byte_mode_supported", 1062a590d564SJie Hai cap->shaper_shared_byte_mode_supported); 1063a590d564SJie Hai rte_tel_data_add_dict_int(d, "shaper_pkt_length_adjust_min", 1064a590d564SJie Hai cap->shaper_pkt_length_adjust_min); 1065a590d564SJie Hai rte_tel_data_add_dict_int(d, "shaper_pkt_length_adjust_max", 1066a590d564SJie Hai cap->shaper_pkt_length_adjust_max); 1067a590d564SJie Hai rte_tel_data_add_dict_uint(d, "sched_n_children_max", 1068a590d564SJie Hai cap->sched_n_children_max); 1069a590d564SJie Hai rte_tel_data_add_dict_uint(d, "sched_sp_n_priorities_max", 1070a590d564SJie Hai cap->sched_sp_n_priorities_max); 1071a590d564SJie Hai rte_tel_data_add_dict_uint(d, "sched_wfq_n_children_per_group_max", 1072a590d564SJie Hai cap->sched_wfq_n_children_per_group_max); 1073a590d564SJie Hai rte_tel_data_add_dict_uint(d, "sched_wfq_n_groups_max", 1074a590d564SJie Hai cap->sched_wfq_n_groups_max); 1075a590d564SJie Hai rte_tel_data_add_dict_uint(d, "sched_wfq_weight_max", 1076a590d564SJie Hai cap->sched_wfq_weight_max); 1077a590d564SJie Hai rte_tel_data_add_dict_int(d, "sched_wfq_packet_mode_supported", 1078a590d564SJie Hai cap->sched_wfq_packet_mode_supported); 1079a590d564SJie Hai rte_tel_data_add_dict_int(d, "sched_wfq_byte_mode_supported", 1080a590d564SJie Hai cap->sched_wfq_byte_mode_supported); 1081a590d564SJie Hai rte_tel_data_add_dict_int(d, "cman_wred_packet_mode_supported", 1082a590d564SJie Hai cap->cman_wred_packet_mode_supported); 1083a590d564SJie Hai rte_tel_data_add_dict_int(d, "cman_wred_byte_mode_supported", 1084a590d564SJie Hai cap->cman_wred_byte_mode_supported); 1085a590d564SJie Hai rte_tel_data_add_dict_int(d, "cman_head_drop_supported", 1086a590d564SJie Hai cap->cman_head_drop_supported); 1087a590d564SJie Hai rte_tel_data_add_dict_uint(d, "cman_wred_context_n_max", 1088a590d564SJie Hai cap->cman_wred_context_n_max); 1089a590d564SJie Hai rte_tel_data_add_dict_uint(d, "cman_wred_context_private_n_max", 1090a590d564SJie Hai cap->cman_wred_context_private_n_max); 1091a590d564SJie Hai rte_tel_data_add_dict_uint(d, "cman_wred_context_shared_n_max", 1092a590d564SJie Hai cap->cman_wred_context_shared_n_max); 1093a590d564SJie Hai rte_tel_data_add_dict_uint(d, "cman_wred_context_shared_n_nodes_per_context_max", 1094a590d564SJie Hai cap->cman_wred_context_shared_n_nodes_per_context_max); 1095a590d564SJie Hai rte_tel_data_add_dict_uint(d, "cman_wred_context_shared_n_contexts_per_node_max", 1096a590d564SJie Hai cap->cman_wred_context_shared_n_contexts_per_node_max); 1097a590d564SJie Hai rte_tel_data_add_dict_uint_hex(d, "dynamic_update", cap->dynamic_update_mask, 0); 1098a590d564SJie Hai rte_tel_data_add_dict_uint_hex(d, "stats_mask", cap->stats_mask, 0); 1099a590d564SJie Hai } 1100a590d564SJie Hai 1101a590d564SJie Hai static int 1102a590d564SJie Hai eth_dev_handle_port_tm_caps(const char *cmd __rte_unused, 1103a590d564SJie Hai const char *params, 1104a590d564SJie Hai struct rte_tel_data *d) 1105a590d564SJie Hai { 1106a590d564SJie Hai struct rte_tm_capabilities cap = {0}; 1107a590d564SJie Hai struct rte_tm_error error = {0}; 1108a590d564SJie Hai uint16_t port_id; 1109a590d564SJie Hai char *end_param; 1110a590d564SJie Hai int ret; 1111a590d564SJie Hai 1112a590d564SJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, false); 1113a590d564SJie Hai if (ret != 0) 1114a590d564SJie Hai return ret; 1115a590d564SJie Hai 1116a590d564SJie Hai ret = rte_tm_capabilities_get(port_id, &cap, &error); 1117a590d564SJie Hai if (ret != 0) { 11180e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "error: %s, error type: %u", 1119a590d564SJie Hai error.message ? error.message : "no stated reason", 1120a590d564SJie Hai error.type); 1121a590d564SJie Hai return ret; 1122a590d564SJie Hai } 1123a590d564SJie Hai 1124a590d564SJie Hai rte_tel_data_start_dict(d); 1125a590d564SJie Hai eth_dev_add_tm_caps(d, &cap); 1126a590d564SJie Hai 1127a590d564SJie Hai return 0; 1128a590d564SJie Hai } 1129a590d564SJie Hai 11309e7533aeSJie Hai static void 11319e7533aeSJie Hai eth_dev_add_tm_level_basic_caps(struct rte_tel_data *d, 11329e7533aeSJie Hai struct rte_tm_level_capabilities *cap) 11339e7533aeSJie Hai { 11349e7533aeSJie Hai rte_tel_data_add_dict_uint(d, "n_nodes_max", cap->n_nodes_max); 11359e7533aeSJie Hai rte_tel_data_add_dict_uint(d, "n_nodes_nonleaf_max", 11369e7533aeSJie Hai cap->n_nodes_nonleaf_max); 11379e7533aeSJie Hai rte_tel_data_add_dict_uint(d, "n_nodes_leaf_max", cap->n_nodes_leaf_max); 11389e7533aeSJie Hai rte_tel_data_add_dict_int(d, "non_leaf_nodes_identical", 11399e7533aeSJie Hai cap->non_leaf_nodes_identical); 11409e7533aeSJie Hai rte_tel_data_add_dict_int(d, "leaf_nodes_identical", 11419e7533aeSJie Hai cap->leaf_nodes_identical); 11429e7533aeSJie Hai } 11439e7533aeSJie Hai 11449e7533aeSJie Hai static void 11459e7533aeSJie Hai eth_dev_add_tm_level_nonleaf_caps(struct rte_tel_data *nonleaf, 11469e7533aeSJie Hai struct rte_tm_level_capabilities *cap) 11479e7533aeSJie Hai { 11489e7533aeSJie Hai rte_tel_data_add_dict_int(nonleaf, "shaper_private_supported", 11499e7533aeSJie Hai cap->nonleaf.shaper_private_supported); 11509e7533aeSJie Hai rte_tel_data_add_dict_int(nonleaf, "shaper_private_dual_rate_supported", 11519e7533aeSJie Hai cap->nonleaf.shaper_private_dual_rate_supported); 11529e7533aeSJie Hai rte_tel_data_add_dict_uint(nonleaf, "shaper_private_rate_min", 11539e7533aeSJie Hai cap->nonleaf.shaper_private_rate_min); 11549e7533aeSJie Hai rte_tel_data_add_dict_uint(nonleaf, "shaper_private_rate_max", 11559e7533aeSJie Hai cap->nonleaf.shaper_private_rate_max); 11569e7533aeSJie Hai rte_tel_data_add_dict_int(nonleaf, "shaper_private_packet_mode_supported", 11579e7533aeSJie Hai cap->nonleaf.shaper_private_packet_mode_supported); 11589e7533aeSJie Hai rte_tel_data_add_dict_int(nonleaf, "shaper_private_byte_mode_supported", 11599e7533aeSJie Hai cap->nonleaf.shaper_private_byte_mode_supported); 11609e7533aeSJie Hai rte_tel_data_add_dict_uint(nonleaf, "shaper_shared_n_max", 11619e7533aeSJie Hai cap->nonleaf.shaper_shared_n_max); 11629e7533aeSJie Hai rte_tel_data_add_dict_int(nonleaf, "shaper_shared_packet_mode_supported", 11639e7533aeSJie Hai cap->nonleaf.shaper_shared_packet_mode_supported); 11649e7533aeSJie Hai rte_tel_data_add_dict_int(nonleaf, "shaper_shared_byte_mode_supported", 11659e7533aeSJie Hai cap->nonleaf.shaper_shared_byte_mode_supported); 11669e7533aeSJie Hai rte_tel_data_add_dict_uint(nonleaf, "sched_n_children_max", 11679e7533aeSJie Hai cap->nonleaf.sched_n_children_max); 11689e7533aeSJie Hai rte_tel_data_add_dict_uint(nonleaf, "sched_sp_n_priorities_max", 11699e7533aeSJie Hai cap->nonleaf.sched_sp_n_priorities_max); 11709e7533aeSJie Hai rte_tel_data_add_dict_uint(nonleaf, "sched_wfq_n_children_per_group_max", 11719e7533aeSJie Hai cap->nonleaf.sched_wfq_n_children_per_group_max); 11729e7533aeSJie Hai rte_tel_data_add_dict_uint(nonleaf, "sched_wfq_n_groups_max", 11739e7533aeSJie Hai cap->nonleaf.sched_wfq_n_groups_max); 11749e7533aeSJie Hai rte_tel_data_add_dict_uint(nonleaf, "sched_wfq_weight_max", 11759e7533aeSJie Hai cap->nonleaf.sched_wfq_weight_max); 11769e7533aeSJie Hai rte_tel_data_add_dict_int(nonleaf, "sched_wfq_packet_mode_supported", 11779e7533aeSJie Hai cap->nonleaf.sched_wfq_packet_mode_supported); 11789e7533aeSJie Hai rte_tel_data_add_dict_int(nonleaf, "sched_wfq_byte_mode_supported", 11799e7533aeSJie Hai cap->nonleaf.sched_wfq_byte_mode_supported); 11809e7533aeSJie Hai rte_tel_data_add_dict_uint_hex(nonleaf, "stats_mask", 11819e7533aeSJie Hai cap->nonleaf.stats_mask, 0); 11829e7533aeSJie Hai } 11839e7533aeSJie Hai 11849e7533aeSJie Hai static void 11859e7533aeSJie Hai eth_dev_add_tm_level_leaf_caps(struct rte_tel_data *leaf, 11869e7533aeSJie Hai struct rte_tm_level_capabilities *cap) 11879e7533aeSJie Hai { 11889e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "shaper_private_supported", 11899e7533aeSJie Hai cap->leaf.shaper_private_supported); 11909e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "shaper_private_dual_rate_supported", 11919e7533aeSJie Hai cap->leaf.shaper_private_dual_rate_supported); 11929e7533aeSJie Hai rte_tel_data_add_dict_uint(leaf, "shaper_private_rate_min", 11939e7533aeSJie Hai cap->leaf.shaper_private_rate_min); 11949e7533aeSJie Hai rte_tel_data_add_dict_uint(leaf, "shaper_private_rate_max", 11959e7533aeSJie Hai cap->leaf.shaper_private_rate_max); 11969e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "shaper_private_packet_mode_supported", 11979e7533aeSJie Hai cap->leaf.shaper_private_packet_mode_supported); 11989e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "shaper_private_byte_mode_supported", 11999e7533aeSJie Hai cap->leaf.shaper_private_byte_mode_supported); 12009e7533aeSJie Hai rte_tel_data_add_dict_uint(leaf, "shaper_shared_n_max", 12019e7533aeSJie Hai cap->leaf.shaper_shared_n_max); 12029e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "shaper_shared_packet_mode_supported", 12039e7533aeSJie Hai cap->leaf.shaper_shared_packet_mode_supported); 12049e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "shaper_shared_byte_mode_supported", 12059e7533aeSJie Hai cap->leaf.shaper_shared_byte_mode_supported); 12069e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "cman_wred_packet_mode_supported", 12079e7533aeSJie Hai cap->leaf.cman_wred_packet_mode_supported); 12089e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "cman_wred_byte_mode_supported", 12099e7533aeSJie Hai cap->leaf.cman_wred_byte_mode_supported); 12109e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "cman_head_drop_supported", 12119e7533aeSJie Hai cap->leaf.cman_head_drop_supported); 12129e7533aeSJie Hai rte_tel_data_add_dict_int(leaf, "cman_wred_context_private_supported", 12139e7533aeSJie Hai cap->leaf.cman_wred_context_private_supported); 12149e7533aeSJie Hai rte_tel_data_add_dict_uint(leaf, "cman_wred_context_shared_n_max", 12159e7533aeSJie Hai cap->leaf.cman_wred_context_shared_n_max); 12169e7533aeSJie Hai rte_tel_data_add_dict_uint_hex(leaf, "stats_mask", 12179e7533aeSJie Hai cap->leaf.stats_mask, 0); 12189e7533aeSJie Hai } 12199e7533aeSJie Hai 12209e7533aeSJie Hai static int 12219e7533aeSJie Hai eth_dev_parse_tm_params(char *params, uint32_t *result) 12229e7533aeSJie Hai { 12239e7533aeSJie Hai const char *splited_param; 12249e7533aeSJie Hai uint64_t ret; 12259e7533aeSJie Hai 12269e7533aeSJie Hai splited_param = strtok(params, ","); 12279e7533aeSJie Hai if (!splited_param || strlen(splited_param) == 0 || !isdigit(*splited_param)) 12289e7533aeSJie Hai return -EINVAL; 12299e7533aeSJie Hai 12309e7533aeSJie Hai ret = strtoul(splited_param, ¶ms, 0); 12319e7533aeSJie Hai if (*params != '\0') 12320e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(NOTICE, 12330e21c7c0SDavid Marchand "Extra parameters passed to ethdev telemetry command, ignoring"); 12349e7533aeSJie Hai 12359e7533aeSJie Hai if (ret >= UINT32_MAX) 12369e7533aeSJie Hai return -EINVAL; 12379e7533aeSJie Hai 12389e7533aeSJie Hai *result = ret; 12399e7533aeSJie Hai return 0; 12409e7533aeSJie Hai } 12419e7533aeSJie Hai 12429e7533aeSJie Hai static int 12439e7533aeSJie Hai eth_dev_handle_port_tm_level_caps(const char *cmd __rte_unused, 12449e7533aeSJie Hai const char *params, 12459e7533aeSJie Hai struct rte_tel_data *d) 12469e7533aeSJie Hai { 12479e7533aeSJie Hai struct rte_tm_level_capabilities cap = {0}; 12489e7533aeSJie Hai struct rte_tm_error error = {0}; 12499e7533aeSJie Hai struct rte_tel_data *nonleaf; 12509e7533aeSJie Hai struct rte_tel_data *leaf; 12519e7533aeSJie Hai uint32_t level_id; 12529e7533aeSJie Hai uint16_t port_id; 12539e7533aeSJie Hai char *end_param; 12549e7533aeSJie Hai int ret; 12559e7533aeSJie Hai 12569e7533aeSJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, true); 12579e7533aeSJie Hai if (ret != 0) 12589e7533aeSJie Hai return ret; 12599e7533aeSJie Hai 12609e7533aeSJie Hai ret = eth_dev_parse_tm_params(end_param, &level_id); 12619e7533aeSJie Hai if (ret != 0) 12629e7533aeSJie Hai return ret; 12639e7533aeSJie Hai 12649e7533aeSJie Hai ret = rte_tm_level_capabilities_get(port_id, level_id, &cap, &error); 12659e7533aeSJie Hai if (ret != 0) { 12660e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(ERR, "error: %s, error type: %u", 12679e7533aeSJie Hai error.message ? error.message : "no stated reason", 12689e7533aeSJie Hai error.type); 12699e7533aeSJie Hai return ret; 12709e7533aeSJie Hai } 12719e7533aeSJie Hai 12729e7533aeSJie Hai rte_tel_data_start_dict(d); 12739e7533aeSJie Hai eth_dev_add_tm_level_basic_caps(d, &cap); 12749e7533aeSJie Hai 12759e7533aeSJie Hai nonleaf = rte_tel_data_alloc(); 12769e7533aeSJie Hai if (nonleaf == NULL) 12779e7533aeSJie Hai return -ENOMEM; 12789e7533aeSJie Hai 12799e7533aeSJie Hai rte_tel_data_start_dict(nonleaf); 12809e7533aeSJie Hai eth_dev_add_tm_level_nonleaf_caps(nonleaf, &cap); 12819e7533aeSJie Hai rte_tel_data_add_dict_container(d, "nonleaf_cap", nonleaf, 0); 12829e7533aeSJie Hai 12839e7533aeSJie Hai leaf = rte_tel_data_alloc(); 12849e7533aeSJie Hai if (leaf == NULL) { 12859e7533aeSJie Hai rte_tel_data_free(nonleaf); 12869e7533aeSJie Hai return -ENOMEM; 12879e7533aeSJie Hai } 12889e7533aeSJie Hai 12899e7533aeSJie Hai rte_tel_data_start_dict(leaf); 12909e7533aeSJie Hai eth_dev_add_tm_level_leaf_caps(leaf, &cap); 12919e7533aeSJie Hai rte_tel_data_add_dict_container(d, "leaf_cap", leaf, 0); 12929e7533aeSJie Hai 12939e7533aeSJie Hai return 0; 12949e7533aeSJie Hai } 12959e7533aeSJie Hai 129670b1ab3fSJie Hai static void 129770b1ab3fSJie Hai eth_dev_add_tm_node_basic_caps(struct rte_tel_data *node_data, 129870b1ab3fSJie Hai struct rte_tm_node_capabilities *capnode) 129970b1ab3fSJie Hai { 130070b1ab3fSJie Hai rte_tel_data_add_dict_int(node_data, "shaper_private_supported", 130170b1ab3fSJie Hai capnode->shaper_private_supported); 130270b1ab3fSJie Hai rte_tel_data_add_dict_int(node_data, "shaper_private_dual_rate_supported", 130370b1ab3fSJie Hai capnode->shaper_private_dual_rate_supported); 130470b1ab3fSJie Hai rte_tel_data_add_dict_uint(node_data, "shaper_private_rate_min", 130570b1ab3fSJie Hai capnode->shaper_private_rate_min); 130670b1ab3fSJie Hai rte_tel_data_add_dict_uint(node_data, "shaper_private_rate_max", 130770b1ab3fSJie Hai capnode->shaper_private_rate_max); 130870b1ab3fSJie Hai rte_tel_data_add_dict_int(node_data, "shaper_private_packet_mode_supported", 130970b1ab3fSJie Hai capnode->shaper_private_packet_mode_supported); 131070b1ab3fSJie Hai rte_tel_data_add_dict_int(node_data, "shaper_private_byte_mode_supported", 131170b1ab3fSJie Hai capnode->shaper_private_byte_mode_supported); 131270b1ab3fSJie Hai rte_tel_data_add_dict_uint(node_data, "shaper_shared_n_max", 131370b1ab3fSJie Hai capnode->shaper_shared_n_max); 131470b1ab3fSJie Hai rte_tel_data_add_dict_int(node_data, "shaper_shared_packet_mode_supported", 131570b1ab3fSJie Hai capnode->shaper_shared_packet_mode_supported); 131670b1ab3fSJie Hai rte_tel_data_add_dict_int(node_data, "shaper_shared_byte_mode_supported", 131770b1ab3fSJie Hai capnode->shaper_shared_byte_mode_supported); 131870b1ab3fSJie Hai rte_tel_data_add_dict_uint_hex(node_data, "stats_mask", 131970b1ab3fSJie Hai capnode->stats_mask, 0); 132070b1ab3fSJie Hai } 132170b1ab3fSJie Hai 132270b1ab3fSJie Hai static void 132370b1ab3fSJie Hai eth_dev_add_tm_type_node_caps(struct rte_tel_data *d, int is_leaf, 132470b1ab3fSJie Hai struct rte_tm_node_capabilities *cap) 132570b1ab3fSJie Hai { 132670b1ab3fSJie Hai rte_tel_data_add_dict_string(d, "node_type", 132770b1ab3fSJie Hai is_leaf == 0 ? "nonleaf" : "leaf"); 132870b1ab3fSJie Hai if (is_leaf == 0) { 132970b1ab3fSJie Hai rte_tel_data_add_dict_uint(d, "children_max", 133070b1ab3fSJie Hai cap->nonleaf.sched_n_children_max); 133170b1ab3fSJie Hai rte_tel_data_add_dict_uint(d, "priorities_max", 133270b1ab3fSJie Hai cap->nonleaf.sched_sp_n_priorities_max); 133370b1ab3fSJie Hai rte_tel_data_add_dict_uint(d, "sched_wfq_n_children_per_group_max", 133470b1ab3fSJie Hai cap->nonleaf.sched_wfq_n_children_per_group_max); 133570b1ab3fSJie Hai rte_tel_data_add_dict_uint(d, "sched_wfq_n_groups_max", 133670b1ab3fSJie Hai cap->nonleaf.sched_wfq_n_groups_max); 133770b1ab3fSJie Hai rte_tel_data_add_dict_uint(d, "sched_wfq_weight_max", 133870b1ab3fSJie Hai cap->nonleaf.sched_wfq_weight_max); 133970b1ab3fSJie Hai rte_tel_data_add_dict_int(d, "sched_wfq_packet_mode_supported", 134070b1ab3fSJie Hai cap->nonleaf.sched_wfq_packet_mode_supported); 134170b1ab3fSJie Hai rte_tel_data_add_dict_int(d, "sched_wfq_byte_mode_supported", 134270b1ab3fSJie Hai cap->nonleaf.sched_wfq_byte_mode_supported); 134370b1ab3fSJie Hai } else { 134470b1ab3fSJie Hai rte_tel_data_add_dict_int(d, "cman_wred_packet_mode_supported", 134570b1ab3fSJie Hai cap->leaf.cman_wred_packet_mode_supported); 134670b1ab3fSJie Hai rte_tel_data_add_dict_int(d, "cman_wred_byte_mode_supported", 134770b1ab3fSJie Hai cap->leaf.cman_wred_byte_mode_supported); 134870b1ab3fSJie Hai rte_tel_data_add_dict_int(d, "cman_head_drop_supported", 134970b1ab3fSJie Hai cap->leaf.cman_head_drop_supported); 135070b1ab3fSJie Hai rte_tel_data_add_dict_int(d, "cman_wred_context_private_supported", 135170b1ab3fSJie Hai cap->leaf.cman_wred_context_private_supported); 135270b1ab3fSJie Hai rte_tel_data_add_dict_uint(d, "cman_wred_context_shared_n_max", 135370b1ab3fSJie Hai cap->leaf.cman_wred_context_shared_n_max); 135470b1ab3fSJie Hai } 135570b1ab3fSJie Hai } 135670b1ab3fSJie Hai 135770b1ab3fSJie Hai static int 135870b1ab3fSJie Hai eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused, 135970b1ab3fSJie Hai const char *params, 136070b1ab3fSJie Hai struct rte_tel_data *d) 136170b1ab3fSJie Hai { 136270b1ab3fSJie Hai struct rte_tm_node_capabilities cap = {0}; 136370b1ab3fSJie Hai struct rte_tm_error error = {0}; 136470b1ab3fSJie Hai uint32_t node_id; 136570b1ab3fSJie Hai uint16_t port_id; 136670b1ab3fSJie Hai char *end_param; 136770b1ab3fSJie Hai int is_leaf; 136870b1ab3fSJie Hai int ret; 136970b1ab3fSJie Hai 137070b1ab3fSJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, true); 137170b1ab3fSJie Hai if (ret != 0) 137270b1ab3fSJie Hai return ret; 137370b1ab3fSJie Hai 137470b1ab3fSJie Hai ret = eth_dev_parse_tm_params(end_param, &node_id); 137570b1ab3fSJie Hai if (ret != 0) 137670b1ab3fSJie Hai return ret; 137770b1ab3fSJie Hai 137870b1ab3fSJie Hai ret = rte_tm_node_capabilities_get(port_id, node_id, &cap, &error); 137970b1ab3fSJie Hai if (ret != 0) 138070b1ab3fSJie Hai goto out; 138170b1ab3fSJie Hai 138270b1ab3fSJie Hai ret = rte_tm_node_type_get(port_id, node_id, &is_leaf, &error); 138370b1ab3fSJie Hai if (ret != 0) 138470b1ab3fSJie Hai goto out; 138570b1ab3fSJie Hai 138670b1ab3fSJie Hai rte_tel_data_start_dict(d); 138770b1ab3fSJie Hai eth_dev_add_tm_node_basic_caps(d, &cap); 138870b1ab3fSJie Hai eth_dev_add_tm_type_node_caps(d, is_leaf, &cap); 138970b1ab3fSJie Hai 139070b1ab3fSJie Hai return 0; 139170b1ab3fSJie Hai out: 13920e21c7c0SDavid Marchand RTE_ETHDEV_LOG_LINE(WARNING, "error: %s, error type: %u", 139370b1ab3fSJie Hai error.message ? error.message : "no stated reason", 139470b1ab3fSJie Hai error.type); 139570b1ab3fSJie Hai return ret; 139670b1ab3fSJie Hai } 139770b1ab3fSJie Hai 1398*d916d27eSJie Hai static void 1399*d916d27eSJie Hai eth_dev_add_reg_data(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info, 1400*d916d27eSJie Hai uint32_t idx) 1401*d916d27eSJie Hai { 1402*d916d27eSJie Hai if (reg_info->width == sizeof(uint32_t)) 1403*d916d27eSJie Hai rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name, 1404*d916d27eSJie Hai *((uint32_t *)reg_info->data + idx), 0); 1405*d916d27eSJie Hai else 1406*d916d27eSJie Hai rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name, 1407*d916d27eSJie Hai *((uint64_t *)reg_info->data + idx), 0); 1408*d916d27eSJie Hai } 1409*d916d27eSJie Hai 1410*d916d27eSJie Hai static int 1411*d916d27eSJie Hai eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info) 1412*d916d27eSJie Hai { 1413*d916d27eSJie Hai struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES]; 1414*d916d27eSJie Hai char group_name[RTE_TEL_MAX_STRING_LEN] = {0}; 1415*d916d27eSJie Hai struct rte_tel_data *group = NULL; 1416*d916d27eSJie Hai uint32_t grp_num = 0; 1417*d916d27eSJie Hai uint32_t i, max_cap; 1418*d916d27eSJie Hai int ret; 1419*d916d27eSJie Hai 1420*d916d27eSJie Hai rte_tel_data_start_dict(d); 1421*d916d27eSJie Hai rte_tel_data_add_dict_uint(d, "register_length", reg_info->length); 1422*d916d27eSJie Hai rte_tel_data_add_dict_uint(d, "register_width", reg_info->width); 1423*d916d27eSJie Hai rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0); 1424*d916d27eSJie Hai rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0); 1425*d916d27eSJie Hai 1426*d916d27eSJie Hai max_cap = (RTE_TEL_MAX_DICT_ENTRIES - 4) * RTE_TEL_MAX_DICT_ENTRIES; 1427*d916d27eSJie Hai if (reg_info->length > max_cap) { 1428*d916d27eSJie Hai RTE_ETHDEV_LOG_LINE(WARNING, 1429*d916d27eSJie Hai "Registers to be displayed are reduced from %u to %u due to limited capacity", 1430*d916d27eSJie Hai reg_info->length, max_cap); 1431*d916d27eSJie Hai reg_info->length = max_cap; 1432*d916d27eSJie Hai } 1433*d916d27eSJie Hai 1434*d916d27eSJie Hai for (i = 0; i < reg_info->length; i++) { 1435*d916d27eSJie Hai if (i % RTE_TEL_MAX_DICT_ENTRIES != 0) { 1436*d916d27eSJie Hai eth_dev_add_reg_data(group, reg_info, i); 1437*d916d27eSJie Hai continue; 1438*d916d27eSJie Hai } 1439*d916d27eSJie Hai 1440*d916d27eSJie Hai group = rte_tel_data_alloc(); 1441*d916d27eSJie Hai if (group == NULL) { 1442*d916d27eSJie Hai ret = -ENOMEM; 1443*d916d27eSJie Hai RTE_ETHDEV_LOG_LINE(WARNING, "No enough memory for group data"); 1444*d916d27eSJie Hai goto out; 1445*d916d27eSJie Hai } 1446*d916d27eSJie Hai groups[grp_num++] = group; 1447*d916d27eSJie Hai rte_tel_data_start_dict(group); 1448*d916d27eSJie Hai eth_dev_add_reg_data(group, reg_info, i); 1449*d916d27eSJie Hai } 1450*d916d27eSJie Hai 1451*d916d27eSJie Hai for (i = 0; i < grp_num; i++) { 1452*d916d27eSJie Hai snprintf(group_name, RTE_TEL_MAX_STRING_LEN, "group_%u", i); 1453*d916d27eSJie Hai rte_tel_data_add_dict_container(d, group_name, groups[i], 0); 1454*d916d27eSJie Hai } 1455*d916d27eSJie Hai return 0; 1456*d916d27eSJie Hai out: 1457*d916d27eSJie Hai for (i = 0; i < grp_num; i++) 1458*d916d27eSJie Hai rte_tel_data_free(groups[i]); 1459*d916d27eSJie Hai 1460*d916d27eSJie Hai return ret; 1461*d916d27eSJie Hai } 1462*d916d27eSJie Hai 1463*d916d27eSJie Hai static int 1464*d916d27eSJie Hai eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter) 1465*d916d27eSJie Hai { 1466*d916d27eSJie Hai struct rte_dev_reg_info reg_info; 1467*d916d27eSJie Hai int ret; 1468*d916d27eSJie Hai 1469*d916d27eSJie Hai memset(®_info, 0, sizeof(reg_info)); 1470*d916d27eSJie Hai reg_info.filter = filter; 1471*d916d27eSJie Hai 1472*d916d27eSJie Hai ret = rte_eth_dev_get_reg_info_ext(port_id, ®_info); 1473*d916d27eSJie Hai if (ret != 0) { 1474*d916d27eSJie Hai RTE_ETHDEV_LOG_LINE(ERR, "Failed to get device reg info: %d", ret); 1475*d916d27eSJie Hai return ret; 1476*d916d27eSJie Hai } 1477*d916d27eSJie Hai 1478*d916d27eSJie Hai reg_info.data = calloc(reg_info.length, reg_info.width); 1479*d916d27eSJie Hai if (reg_info.data == NULL) { 1480*d916d27eSJie Hai RTE_ETHDEV_LOG_LINE(ERR, "Failed to allocate memory for reg_info.data"); 1481*d916d27eSJie Hai return -ENOMEM; 1482*d916d27eSJie Hai } 1483*d916d27eSJie Hai 1484*d916d27eSJie Hai reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name)); 1485*d916d27eSJie Hai if (reg_info.names == NULL) { 1486*d916d27eSJie Hai RTE_ETHDEV_LOG_LINE(ERR, "Failed to allocate memory for reg_info.names"); 1487*d916d27eSJie Hai free(reg_info.data); 1488*d916d27eSJie Hai return -ENOMEM; 1489*d916d27eSJie Hai } 1490*d916d27eSJie Hai 1491*d916d27eSJie Hai ret = rte_eth_dev_get_reg_info_ext(port_id, ®_info); 1492*d916d27eSJie Hai if (ret != 0) { 1493*d916d27eSJie Hai RTE_ETHDEV_LOG_LINE(ERR, "Failed to get device reg info: %d", ret); 1494*d916d27eSJie Hai ret = -EINVAL; 1495*d916d27eSJie Hai goto out; 1496*d916d27eSJie Hai } 1497*d916d27eSJie Hai 1498*d916d27eSJie Hai ret = eth_dev_store_regs(d, ®_info); 1499*d916d27eSJie Hai out: 1500*d916d27eSJie Hai free(reg_info.data); 1501*d916d27eSJie Hai free(reg_info.names); 1502*d916d27eSJie Hai 1503*d916d27eSJie Hai return ret; 1504*d916d27eSJie Hai } 1505*d916d27eSJie Hai 1506*d916d27eSJie Hai static int 1507*d916d27eSJie Hai eth_dev_handle_port_regs(const char *cmd __rte_unused, 1508*d916d27eSJie Hai const char *params, 1509*d916d27eSJie Hai struct rte_tel_data *d) 1510*d916d27eSJie Hai { 1511*d916d27eSJie Hai char *filter, *end_param; 1512*d916d27eSJie Hai uint16_t port_id; 1513*d916d27eSJie Hai int ret; 1514*d916d27eSJie Hai 1515*d916d27eSJie Hai ret = eth_dev_parse_port_params(params, &port_id, &end_param, true); 1516*d916d27eSJie Hai if (ret != 0) 1517*d916d27eSJie Hai return ret; 1518*d916d27eSJie Hai 1519*d916d27eSJie Hai filter = strtok(end_param, ","); 1520*d916d27eSJie Hai if (filter != NULL && strlen(filter) == 0) 1521*d916d27eSJie Hai filter = NULL; 1522*d916d27eSJie Hai 1523*d916d27eSJie Hai return eth_dev_get_port_regs(port_id, d, filter); 1524*d916d27eSJie Hai } 1525*d916d27eSJie Hai 15266f96937dSRobin Jarry static int eth_dev_telemetry_do(const char *cmd, const char *params, void *arg, 15276f96937dSRobin Jarry struct rte_tel_data *d) 15286f96937dSRobin Jarry { 15296f96937dSRobin Jarry telemetry_cb fn = arg; 15306f96937dSRobin Jarry int ret; 15316f96937dSRobin Jarry 15326f96937dSRobin Jarry /* Protect against port removal while invoking callback, calling ethdev API. */ 15336f96937dSRobin Jarry rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); 15346f96937dSRobin Jarry ret = fn(cmd, params, d); 15356f96937dSRobin Jarry rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); 15366f96937dSRobin Jarry 15376f96937dSRobin Jarry return ret; 15386f96937dSRobin Jarry } 15396f96937dSRobin Jarry 15404fe767acSJie Hai RTE_INIT(ethdev_init_telemetry) 15414fe767acSJie Hai { 15426f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/list", 15436f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_list, 15444fe767acSJie Hai "Returns list of available ethdev ports. Takes no parameters"); 15456f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/stats", 15466f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_stats, 15474fe767acSJie Hai "Returns the common stats for a port. Parameters: int port_id"); 15486f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/xstats", 15496f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_xstats, 15504fe767acSJie Hai "Returns the extended stats for a port. Parameters: int port_id,hide_zero=true|false(Optional for indicates hide zero xstats)"); 15514fe767acSJie Hai #ifndef RTE_EXEC_ENV_WINDOWS 15526f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/dump_priv", 15536f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_dump_priv, 15544fe767acSJie Hai "Returns dump private information for a port. Parameters: int port_id"); 15554fe767acSJie Hai #endif 15566f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/link_status", 15576f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_link_status, 15584fe767acSJie Hai "Returns the link status for a port. Parameters: int port_id"); 15596f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/info", 15606f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_info, 15614fe767acSJie Hai "Returns the device info for a port. Parameters: int port_id"); 15626f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/module_eeprom", 15636f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_module_eeprom, 15644fe767acSJie Hai "Returns module EEPROM info with SFF specs. Parameters: int port_id"); 15656f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/macs", 15666f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_macs, 15676732ae1cSDengdui Huang "Returns the MAC addresses for a port. Parameters: int port_id"); 15686f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/flow_ctrl", 15696f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_flow_ctrl, 1570499c8486SJie Hai "Returns flow ctrl info for a port. Parameters: int port_id"); 15716f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/rx_queue", 15726f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_rxq, 1573f38f6265SJie Hai "Returns Rx queue info for a port. Parameters: int port_id, int queue_id (Optional if only one queue)"); 15746f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/tx_queue", 15756f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_txq, 15761a479610SJie Hai "Returns Tx queue info for a port. Parameters: int port_id, int queue_id (Optional if only one queue)"); 15776f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/dcb", 15786f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_dcb, 157966f3e047SJie Hai "Returns DCB info for a port. Parameters: int port_id"); 15806f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/rss_info", 15816f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_rss_info, 1582fde1adbfSJie Hai "Returns RSS info for a port. Parameters: int port_id"); 15836f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/fec", 15846f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_fec, 158585576ba6SJie Hai "Returns FEC info for a port. Parameters: int port_id"); 15866f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/vlan", 15876f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_vlan, 158819f39522SJie Hai "Returns VLAN info for a port. Parameters: int port_id"); 15896f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/tm_capability", 15906f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_tm_caps, 1591a590d564SJie Hai "Returns TM Capabilities info for a port. Parameters: int port_id"); 15926f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/tm_level_capability", 15936f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_tm_level_caps, 15949e7533aeSJie Hai "Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)"); 15956f96937dSRobin Jarry rte_telemetry_register_cmd_arg("/ethdev/tm_node_capability", 15966f96937dSRobin Jarry eth_dev_telemetry_do, eth_dev_handle_port_tm_node_caps, 159770b1ab3fSJie Hai "Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)"); 1598*d916d27eSJie Hai rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs, 1599*d916d27eSJie Hai "Returns all or filtered registers info for a port. Parameters: int port_id, string module_name (Optional if show all)"); 16004fe767acSJie Hai } 1601