From patchwork Tue May 30 09:05:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jie Hai X-Patchwork-Id: 127697 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 637CC42BE1; Tue, 30 May 2023 11:08:32 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2669D42D55; Tue, 30 May 2023 11:07:51 +0200 (CEST) Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by mails.dpdk.org (Postfix) with ESMTP id 3E30C42D17 for ; Tue, 30 May 2023 11:07:44 +0200 (CEST) Received: from kwepemi500020.china.huawei.com (unknown [172.30.72.55]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4QVmgJ0lGfzLpvK; Tue, 30 May 2023 17:04:44 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by kwepemi500020.china.huawei.com (7.221.188.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23; Tue, 30 May 2023 17:07:42 +0800 From: Jie Hai To: Thomas Monjalon , Ferruh Yigit , Andrew Rybchenko CC: , Subject: [PATCH 09/10] ethdev: support telemetry query FEC info Date: Tue, 30 May 2023 17:05:09 +0800 Message-ID: <20230530090510.56812-10-haijie1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20230530090510.56812-1-haijie1@huawei.com> References: <20230530090510.56812-1-haijie1@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To kwepemi500020.china.huawei.com (7.221.188.8) X-CFilter-Loop: Reflected X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch supports getting FEC information by telemetry. The command is like: --> /ethdev/fec,0 { "/ethdev/fec": { "fec_mode": "off", "fec_capability": { "10_Gbps": "off auto baser" } } } Signed-off-by: Jie Hai --- lib/ethdev/rte_ethdev.c | 145 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 6699b40d5e15..f7a84ae6c35d 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -160,6 +160,16 @@ enum { STAT_QMAP_RX }; +static const struct { + uint32_t capa; + const char *name; +} rte_eth_fec_capa_name[] = { + { RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC), "off" }, + { RTE_ETH_FEC_MODE_CAPA_MASK(AUTO), "auto" }, + { RTE_ETH_FEC_MODE_CAPA_MASK(BASER), "baser" }, + { RTE_ETH_FEC_MODE_CAPA_MASK(RS), "rs" }, +}; + int rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) { @@ -7516,6 +7526,139 @@ eth_dev_handle_port_rss_info(const char *cmd __rte_unused, return ret; } +static const char * +eth_dev_fec_capa_to_string(uint32_t fec_capa) +{ + uint32_t i; + + for (i = 0; i < RTE_DIM(rte_eth_fec_capa_name); i++) { + if ((fec_capa & rte_eth_fec_capa_name[i].capa) != 0) + return rte_eth_fec_capa_name[i].name; + } + + return "unknown"; +} + +static void +eth_dev_fec_capas_to_string(uint32_t fec_capa, char *fec_name, uint32_t len) +{ + bool valid = false; + size_t count = 0; + uint32_t i; + + for (i = 0; i < RTE_DIM(rte_eth_fec_capa_name); i++) { + if ((fec_capa & rte_eth_fec_capa_name[i].capa) != 0) { + strlcat(fec_name, rte_eth_fec_capa_name[i].name, len); + count = strlcat(fec_name, " ", len); + valid = true; + } + } + + if (!valid) + count = snprintf(fec_name, len, "unknown "); + + if (count >= len) { + RTE_ETHDEV_LOG(WARNING, "FEC capa names may be truncated\n"); + count = len; + } + + fec_name[count - 1] = '\0'; +} + +static int +eth_dev_get_fec_capability(uint16_t port_id, struct rte_tel_data *d) +{ + struct rte_eth_fec_capa *speed_fec_capa; + char fec_name[RTE_TEL_MAX_STRING_LEN]; + char speed[RTE_TEL_MAX_STRING_LEN]; + uint32_t capa_num; + uint32_t i, j; + int ret; + + ret = rte_eth_fec_get_capability(port_id, NULL, 0); + if (ret <= 0) + return ret == 0 ? -EINVAL : ret; + + capa_num = ret; + speed_fec_capa = calloc(capa_num, sizeof(struct rte_eth_fec_capa)); + if (speed_fec_capa == NULL) + return -ENOMEM; + + ret = rte_eth_fec_get_capability(port_id, speed_fec_capa, capa_num); + if (ret <= 0) { + ret = ret == 0 ? -EINVAL : ret; + goto out; + } + + for (i = 0; i < capa_num; i++) { + memset(fec_name, 0, RTE_TEL_MAX_STRING_LEN); + eth_dev_fec_capas_to_string(speed_fec_capa[i].capa, fec_name, + RTE_TEL_MAX_STRING_LEN); + + memset(speed, 0, RTE_TEL_MAX_STRING_LEN); + ret = snprintf(speed, RTE_TEL_MAX_STRING_LEN, "%s", + rte_eth_link_speed_to_str(speed_fec_capa[i].speed)); + if (ret < 0) + goto out; + + for (j = 0; j < strlen(speed); j++) { + if (speed[j] == ' ') + speed[j] = '_'; + } + + rte_tel_data_add_dict_string(d, speed, fec_name); + } + +out: + free(speed_fec_capa); + return ret > 0 ? 0 : ret; +} + +static int +eth_dev_handle_port_fec(const char *cmd __rte_unused, + const char *params, + struct rte_tel_data *d) +{ + struct rte_tel_data *fec_capas; + unsigned long port_id; + uint32_t fec_mode; + char *end_param; + int ret; + + if (params == NULL || strlen(params) == 0 || !isdigit(*params)) + return -EINVAL; + + port_id = strtoul(params, &end_param, 0); + if (*end_param != '\0') + RTE_ETHDEV_LOG(NOTICE, + "Extra parameters passed to ethdev telemetry command, ignoring\n"); + + if (port_id >= UINT16_MAX || !rte_eth_dev_is_valid_port(port_id)) + return -EINVAL; + + ret = rte_eth_fec_get(port_id, &fec_mode); + if (ret != 0) + return ret; + + rte_tel_data_start_dict(d); + rte_tel_data_add_dict_string(d, "fec_mode", + eth_dev_fec_capa_to_string(fec_mode)); + + fec_capas = rte_tel_data_alloc(); + if (fec_capas == NULL) + return -ENOMEM; + + rte_tel_data_start_dict(fec_capas); + ret = eth_dev_get_fec_capability(port_id, fec_capas); + if (ret != 0) { + rte_tel_data_free(fec_capas); + return ret; + } + + rte_tel_data_add_dict_container(d, "fec_capability", fec_capas, 0); + return 0; +} + RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO); RTE_INIT(ethdev_init_telemetry) @@ -7549,4 +7692,6 @@ RTE_INIT(ethdev_init_telemetry) "Returns DCB info for a port. Parameters: unsigned port_id"); rte_telemetry_register_cmd("/ethdev/rss_info", eth_dev_handle_port_rss_info, "Returns RSS info for a port. Parameters: unsigned port_id"); + rte_telemetry_register_cmd("/ethdev/fec", eth_dev_handle_port_fec, + "Returns FEC info for a port. Parameters: unsigned port_id"); }